- 好友
- 0
- 在线时间
- 128 小时
- 最后登录
- 2024-12-25
见习骑士
- UID
- 2758789
- 第纳尔
- 2148
- 精华
- 0
- 互助
- 21
- 荣誉
- 1
- 贡献
- 0
- 魅力
- 201
- 注册时间
- 2016-7-18
鲜花( 22) 鸡蛋( 0)
|
本帖最后由 路过的罗格 于 2024-4-27 13:52 编辑
Harmony的教程再拖拖,先把这个写好的功能发了
代码功能:任意agent在射击时,当剩余子弹数量过低时,从他所在的编队中弹药最多的那个单位身上,抢过来一个箭筒的弹药,以保证持续射击。避免有的射手位置不好,弹药用不出去,而有的射手射的太快没有弹药。
老样子,代码依旧是仍在继承了类似MissionLogic的类的复写的OnAgentShootMissile方法里
代码没有进行优化,存在比较多的人类迷惑行为,不过功能没问题,可能存在的卡死问题也修掉了(大概)
- //获取自己当前武器的剩余弹药数量
- int OwnCurrentAmmo = 0;
- for (EquipmentIndex equipmentIndex = EquipmentIndex.WeaponItemBeginSlot; equipmentIndex < EquipmentIndex.ExtraWeaponSlot; equipmentIndex++)
- {
- if (!shooterAgent.Equipment[equipmentIndex].IsEmpty && shooterAgent.Equipment[equipmentIndex].CurrentUsageItem.IsRangedWeapon)
- {
- OwnCurrentAmmo = shooterAgent.Equipment.GetAmmoAmount(equipmentIndex);
- }
- }
- //如果当前武器弹药数量过少
- WoW_Agents.TryGetValue(shooterAgent.Index, out var v);//这行代码无视,有兴趣可以自己写一个agent的属性扩展,我这边加了一下cd,避免刚抢了别人弹药的agent又被别人抢弹药
- if (OwnCurrentAmmo <= 3 && v.heavyStrikeSkillCD <= 0)
- {
- //遍历自己队伍内的agent,抢过来一些弹药
- if (shooterAgent.Formation != null)//获取射击者的当前编队
- {
- int maxAmmoAmount = 0;
- Agent TAgent = null;
- EquipmentIndex TAgentEquipmentIndex = EquipmentIndex.None;
- WeaponClass shooterAgentWeaponClass = shooterAgent.Equipment[weaponIndex].CurrentUsageItem.AmmoClass;
- //先遍历整个编队,找到弹药最多的agent。然后获取这个agent的弹药进行转移
- int jishu = 0;
- List<Agent> list = new List<Agent>();
- shooterAgent.Formation.ApplyActionOnEachUnit(delegate (Agent agent) //遍历编队agent的函数,非常类似于1代的try_for_agents给感觉,甚至不能中途停下来(也可能是我不知道怎么让他中途停止)
- {
- if (!agent.IsMainAgent && agent != shooterAgent)
- {
- WoW_Agents.TryGetValue(agent.Index, out var vT);
- if (vT.heavyStrikeSkillDur > 0)//如果当前agent刚抢了别人的弹药,暂时不让他被抢
- {
- return;
- }
- for (EquipmentIndex equipmentIndex = EquipmentIndex.WeaponItemBeginSlot; equipmentIndex < EquipmentIndex.ExtraWeaponSlot; equipmentIndex++)//遍历 物品栏
- {
- //筛选出当前遍历的agent有没有和射击者agent相同类型的武器,避免弓手拿到弩箭之类的。同时筛选出弹药最多的目标。
- if (!agent.Equipment[equipmentIndex].IsEmpty && shooterAgent.Equipment[weaponIndex].CurrentUsageItem.WeaponClass == agent.Equipment[equipmentIndex].CurrentUsageItem.WeaponClass && maxAmmoAmount < agent.Equipment.GetAmmoAmount(equipmentIndex))
- {
- maxAmmoAmount = agent.Equipment.GetAmmoAmount(equipmentIndex);
- TAgent = agent;
- }
- }
- }
- jishu++;
- list.Add(agent);
- }, null);
- int itemAmmoAmount = 0;
- //第二轮筛选,拿之前那个弹药最多的目标,找到他身上具体的哪个物品上弹药最多,一会从这个物品上扣弹药
- if (maxAmmoAmount > 0 && TAgent != null)
- {
- itemAmmoAmount = 0;
- for (EquipmentIndex equipmentIndex = EquipmentIndex.WeaponItemBeginSlot; equipmentIndex < EquipmentIndex.ExtraWeaponSlot; equipmentIndex++)
- {
- if (TAgent.Equipment[equipmentIndex].CurrentUsageItem != null && shooterAgentWeaponClass == TAgent.Equipment[equipmentIndex].CurrentUsageItem.WeaponClass)
- {
- if (itemAmmoAmount < TAgent.Equipment[equipmentIndex].Amount)
- {
- itemAmmoAmount = TAgent.Equipment[equipmentIndex].Amount;
- TAgentEquipmentIndex = equipmentIndex;
- }
- }
- }
- WoW_Scripts.getMissionWeaponFromAgentInventory(shooterAgent, out var threwMeleeWeapon, out var equipmentIndex1);//自己写的一个函数,根据手持的武器,获取一个合适的弹药物品
- if (equipmentIndex1 == EquipmentIndex.None)
- { return; }
- //如果射击者有合适的弹药栏位可以填充,开始用狗屎代码填充那个物品的 数量
- int shootAgentMaxAmmo = shooterAgent.Equipment[equipmentIndex1].MaxAmmo;
- int agentAmmo = itemAmmoAmount;
- if ((agentAmmo - 3) > 0)
- {
- if (shootAgentMaxAmmo - OwnCurrentAmmo - (agentAmmo - 3) > 0)
- {
- //射击者把目标的弹药全拿完了(留几根)
- //shooterAgent.Equipment.SetAmountOfSlot(equipmentIndex1, (short)(OwnCurrentAmmo + agentAmmo - 3));
- //TAgemt.Equipment.SetAmountOfSlot(TAgentEquipmentIndex, 3);
- if (shooterAgent.Equipment[equipmentIndex1].Amount != OwnCurrentAmmo + agentAmmo - 3 && shooterAgent.Equipment[equipmentIndex1].Amount != 0 && OwnCurrentAmmo + agentAmmo - 3 != 0 && TAgent.Equipment[equipmentIndex1].Amount != 3 && TAgent.Equipment[equipmentIndex1].Amount != 0 && 3 != 0)//别问这是干啥的,问就是为了避免bug
- {
- shooterAgent.SetWeaponAmountInSlot(equipmentIndex1, (short)(OwnCurrentAmmo + agentAmmo - 3), false);
- TAgent.SetWeaponAmountInSlot(TAgentEquipmentIndex, (short)(3), false);
- v.heavyStrikeSkillCD = 5;
- v.heavyStrikeSkillDur = 10;
- if (shooterAgent.IsFriendOf(Agent.Main))
- {
- InformationManager.DisplayMessage(new InformationMessage($"{shooterAgent.Name}{shooterAgent.Index}抢走了{TAgent.Name}{TAgent.Index}的{OwnCurrentAmmo + agentAmmo - 3}发弹药"));
- }
- shooterAgent.UpdateAgentProperties();
- TAgent.UpdateAgentProperties();
- return;
- }
- }
- else
- {
- //没拿完的话
- //shooterAgent.Equipment.SetAmountOfSlot(equipmentIndex1, (short)(shootAgentMaxAmmo));
- //TAgemt.Equipment.SetAmountOfSlot(TAgentEquipmentIndex, (short)(agentAmmo - shootAgentMaxAmmo));
- if (shooterAgent.Equipment[equipmentIndex1].Amount != shootAgentMaxAmmo && shooterAgent.Equipment[equipmentIndex1].Amount != 0 && shootAgentMaxAmmo != 0 && TAgent.Equipment[equipmentIndex1].Amount != agentAmmo - shootAgentMaxAmmo && TAgent.Equipment[equipmentIndex1].Amount != 0 && agentAmmo - shootAgentMaxAmmo != 0)//别问这是干啥的,问就是为了避免bug
- {
- shooterAgent.SetWeaponAmountInSlot(equipmentIndex1, (short)(shootAgentMaxAmmo), false);
- TAgent.SetWeaponAmountInSlot(TAgentEquipmentIndex, (short)(agentAmmo - shootAgentMaxAmmo), false);
- v.heavyStrikeSkillCD = 5;
- v.heavyStrikeSkillDur = 10;
- if (shooterAgent.IsFriendOf(Agent.Main))
- {
- InformationManager.DisplayMessage(new InformationMessage($"{shooterAgent.Name}{shooterAgent.Index}抢走了{TAgent.Name}{TAgent.Index}的{shootAgentMaxAmmo}发弹药"));
- }
- shooterAgent.UpdateAgentProperties();
- TAgent.UpdateAgentProperties();
- return;
- }
- }
- }
- }
-
- }
- }
复制代码- public static MissionWeapon getMissionWeaponFromAgentInventory(Agent agent, out bool ThrewMeleeWeapon,out EquipmentIndex EquipmentIndex)//参考agent当前手持的武器,从agent当前的武器栏中,获取合适的投射物
- {
- //因为missionweapon.ammoweapon会在武器装填时输出空值,所以还是重写一个弹药获取的代码
- //现在是获取手上的武器后,依次遍历agent的武器栏位。如果遍历到的物品是手上武器的弹药,并且弹药数量大于0,则设置为一会addmissile的弹药。
- //手上武器为近战时还要做个缺省值
- ThrewMeleeWeapon = false;
- EquipmentIndex = EquipmentIndex.None;
- EquipmentIndex 备用index= EquipmentIndex.None;//如果弹药数量为空的话,弹药所在的index记录在这个位置,如果本身有弹药但是因为用完了的时候,输出这个位置
- if (!agent.IsHuman||agent.GetWieldedItemIndex(Agent.HandIndex.MainHand)== EquipmentIndex.None)
- return MissionWeapon.Invalid;
- MissionWeapon missionWeapon = agent.Equipment[agent.GetWieldedItemIndex(Agent.HandIndex.MainHand)];
- if (agent.Equipment[agent.GetWieldedItemIndex(Agent.HandIndex.MainHand)].CurrentUsageItem.IsRangedWeapon)//手上的物品是远程武器
- {
- for (EquipmentIndex equipmentIndex = EquipmentIndex.WeaponItemBeginSlot; equipmentIndex < EquipmentIndex.NumAllWeaponSlots; equipmentIndex++)//循环遍历武器栏位
- {
- if (!agent.Equipment[agent.GetWieldedItemIndex(Agent.HandIndex.MainHand)].IsEmpty && !agent.Equipment[equipmentIndex].IsEmpty)//如果手上的武器和遍历的物品非空
- {
- if (agent.Equipment[agent.GetWieldedItemIndex(Agent.HandIndex.MainHand)].Item.PrimaryWeapon.WeaponClass == WeaponClass.Crossbow)//如果手上的武器是弩
- {
- //先进行一次把射出的武器定位默认值
- // 获取ItemObject引用,这里使用了一个字符串ID来查找特定的武器。字符串是xml里item的id值。
- ItemObject weaponItem = Game.Current.ObjectManager.GetObject<ItemObject>("bolt_a");
- // 创建MissionWeapon实例
- missionWeapon = new MissionWeapon(weaponItem, null, null);
- if (agent.Equipment[equipmentIndex].Item.PrimaryWeapon.WeaponClass == WeaponClass.Bolt && agent.Equipment[equipmentIndex].Amount > 0)//如果遍历的物品是弩箭
- {
- missionWeapon = agent.Equipment[equipmentIndex];//设定射出的投射物是这个弩箭
- EquipmentIndex = equipmentIndex;
- break;//退出遍历循环
- }
- else if (agent.Equipment[equipmentIndex].Item.PrimaryWeapon.WeaponClass == WeaponClass.Bolt)
- {
- missionWeapon = agent.Equipment[equipmentIndex];//设定射出的投射物是这个弩箭
- 备用index = equipmentIndex;
- }
- }
- if (agent.Equipment[agent.GetWieldedItemIndex(Agent.HandIndex.MainHand)].Item.PrimaryWeapon.WeaponClass == WeaponClass.Bow)
- {
- ItemObject weaponItem = Game.Current.ObjectManager.GetObject<ItemObject>("arrow_emp_1_a");
- missionWeapon = new MissionWeapon(weaponItem, null, null);
- if (agent.Equipment[equipmentIndex].Item.PrimaryWeapon.WeaponClass == WeaponClass.Arrow && agent.Equipment[equipmentIndex].Amount > 0)
- {
- missionWeapon = agent.Equipment[equipmentIndex];
- EquipmentIndex = equipmentIndex;
- break;
- }
- else if (agent.Equipment[equipmentIndex].Item.PrimaryWeapon.WeaponClass == WeaponClass.Arrow)
- {
- missionWeapon = agent.Equipment[equipmentIndex];//设定射出的投射物是这个弩箭
- 备用index = equipmentIndex;
- }
- }
- if (agent.Equipment[agent.GetWieldedItemIndex(Agent.HandIndex.MainHand)].CurrentUsageItem.IsConsumable && agent.Equipment[equipmentIndex].CurrentUsageItem.IsRangedWeapon&& agent.Equipment[equipmentIndex].CurrentUsageItem.IsConsumable)
- {
- ItemObject weaponItem = Game.Current.ObjectManager.GetObject<ItemObject>("western_javelin_1_t2");
- missionWeapon = new MissionWeapon(weaponItem, null, null);
- if (agent.Equipment[equipmentIndex].Amount > 0 )
- {
- missionWeapon = agent.Equipment[equipmentIndex];
- EquipmentIndex = equipmentIndex;
- break;
- }
- else
- {
- missionWeapon = agent.Equipment[equipmentIndex];//设定射出的投射物是这个弩箭
- 备用index = equipmentIndex;
- }
- }
- }
- }
- }
- else//如果手上不是远程武器,也写了适配,默认射一个投矛。伤害的问题在伤害计算那边处理
- {
- ItemObject weaponItem = Game.Current.ObjectManager.GetObject<ItemObject>("western_javelin_1_t2");
- missionWeapon = new MissionWeapon(weaponItem, null, null);
- ThrewMeleeWeapon = true;
- }
- if (备用index != EquipmentIndex.None&& EquipmentIndex==EquipmentIndex.None)
- {
- EquipmentIndex = 备用index;
- }
- return missionWeapon;
- }
复制代码
|
|