骑马与砍杀中文站论坛

 找回密码
 注册(Register!)

QQ登录

只需一步,快速开始

搜索
购买CDKEY 小黑盒加速器
查看: 743|回复: 9

[功能与代码] [骑砍2]编队内弹药数量共享,再也不旱的旱死,涝的涝死

[复制链接]

28

主题

223

回帖

180

积分

见习骑士

Rank: 3

UID
2758789
第纳尔
2118
精华
0
互助
19
荣誉
1
贡献
0
魅力
171
注册时间
2016-7-18
鲜花(18) 鸡蛋(0)
发表于 2024-4-27 13:51:14 | 显示全部楼层 |阅读模式
本帖最后由 路过的罗格 于 2024-4-27 13:52 编辑

Harmony的教程再拖拖,先把这个写好的功能发了


代码功能:任意agent在射击时,当剩余子弹数量过低时,从他所在的编队中弹药最多的那个单位身上,抢过来一个箭筒的弹药,以保证持续射击。避免有的射手位置不好,弹药用不出去,而有的射手射的太快没有弹药。
老样子,代码依旧是仍在继承了类似MissionLogic的类的复写的OnAgentShootMissile方法里
代码没有进行优化,存在比较多的人类迷惑行为,不过功能没问题,可能存在的卡死问题也修掉了(大概)
  1.             //获取自己当前武器的剩余弹药数量
  2.             int OwnCurrentAmmo = 0;
  3.             for (EquipmentIndex equipmentIndex = EquipmentIndex.WeaponItemBeginSlot; equipmentIndex < EquipmentIndex.ExtraWeaponSlot; equipmentIndex++)
  4.             {
  5.                 if (!shooterAgent.Equipment[equipmentIndex].IsEmpty && shooterAgent.Equipment[equipmentIndex].CurrentUsageItem.IsRangedWeapon)
  6.                 {
  7.                     OwnCurrentAmmo = shooterAgent.Equipment.GetAmmoAmount(equipmentIndex);
  8.                 }
  9.             }
  10.             //如果当前武器弹药数量过少
  11.             WoW_Agents.TryGetValue(shooterAgent.Index, out var v);//这行代码无视,有兴趣可以自己写一个agent的属性扩展,我这边加了一下cd,避免刚抢了别人弹药的agent又被别人抢弹药
  12.             if (OwnCurrentAmmo <= 3 && v.heavyStrikeSkillCD <= 0)
  13.             {
  14.                 //遍历自己队伍内的agent,抢过来一些弹药
  15.                 if (shooterAgent.Formation != null)//获取射击者的当前编队
  16.                 {
  17.                     int maxAmmoAmount = 0;
  18.                     Agent TAgent = null;
  19.                     EquipmentIndex TAgentEquipmentIndex = EquipmentIndex.None;
  20.                     WeaponClass shooterAgentWeaponClass = shooterAgent.Equipment[weaponIndex].CurrentUsageItem.AmmoClass;
  21.                     //先遍历整个编队,找到弹药最多的agent。然后获取这个agent的弹药进行转移
  22.                     int jishu = 0;
  23.                     List<Agent> list = new List<Agent>();
  24.                     shooterAgent.Formation.ApplyActionOnEachUnit(delegate (Agent agent) //遍历编队agent的函数,非常类似于1代的try_for_agents给感觉,甚至不能中途停下来(也可能是我不知道怎么让他中途停止)
  25.                     {

  26.                         if (!agent.IsMainAgent && agent != shooterAgent)
  27.                         {
  28.                             WoW_Agents.TryGetValue(agent.Index, out var vT);
  29.                             if (vT.heavyStrikeSkillDur > 0)//如果当前agent刚抢了别人的弹药,暂时不让他被抢
  30.                             {
  31.                                 return;
  32.                             }
  33.                             for (EquipmentIndex equipmentIndex = EquipmentIndex.WeaponItemBeginSlot; equipmentIndex < EquipmentIndex.ExtraWeaponSlot; equipmentIndex++)//遍历 物品栏
  34.                             {
  35.                                 //筛选出当前遍历的agent有没有和射击者agent相同类型的武器,避免弓手拿到弩箭之类的。同时筛选出弹药最多的目标。
  36.                                 if (!agent.Equipment[equipmentIndex].IsEmpty && shooterAgent.Equipment[weaponIndex].CurrentUsageItem.WeaponClass == agent.Equipment[equipmentIndex].CurrentUsageItem.WeaponClass && maxAmmoAmount < agent.Equipment.GetAmmoAmount(equipmentIndex))
  37.                                 {
  38.                                     maxAmmoAmount = agent.Equipment.GetAmmoAmount(equipmentIndex);
  39.                                     TAgent = agent;
  40.                                 }
  41.                             }
  42.                         }

  43.                         jishu++;
  44.                         list.Add(agent);
  45.                     }, null);
  46.                     int itemAmmoAmount = 0;
  47.                     //第二轮筛选,拿之前那个弹药最多的目标,找到他身上具体的哪个物品上弹药最多,一会从这个物品上扣弹药
  48.                     if (maxAmmoAmount > 0 && TAgent != null)
  49.                     {

  50.                         itemAmmoAmount = 0;
  51.                         for (EquipmentIndex equipmentIndex = EquipmentIndex.WeaponItemBeginSlot; equipmentIndex < EquipmentIndex.ExtraWeaponSlot; equipmentIndex++)
  52.                         {
  53.                             if (TAgent.Equipment[equipmentIndex].CurrentUsageItem != null && shooterAgentWeaponClass == TAgent.Equipment[equipmentIndex].CurrentUsageItem.WeaponClass)
  54.                             {
  55.                                 if (itemAmmoAmount < TAgent.Equipment[equipmentIndex].Amount)
  56.                                 {
  57.                                     itemAmmoAmount = TAgent.Equipment[equipmentIndex].Amount;
  58.                                     TAgentEquipmentIndex = equipmentIndex;
  59.                                 }
  60.                             }
  61.                         }
  62.                         WoW_Scripts.getMissionWeaponFromAgentInventory(shooterAgent, out var threwMeleeWeapon, out var equipmentIndex1);//自己写的一个函数,根据手持的武器,获取一个合适的弹药物品
  63.                         if (equipmentIndex1 == EquipmentIndex.None)
  64.                         { return; }
  65.                         //如果射击者有合适的弹药栏位可以填充,开始用狗屎代码填充那个物品的 数量
  66.                         int shootAgentMaxAmmo = shooterAgent.Equipment[equipmentIndex1].MaxAmmo;
  67.                         int agentAmmo = itemAmmoAmount;
  68.                         if ((agentAmmo - 3) > 0)
  69.                         {
  70.                             if (shootAgentMaxAmmo - OwnCurrentAmmo - (agentAmmo - 3) > 0)
  71.                             {
  72.                                 //射击者把目标的弹药全拿完了(留几根)
  73.                                 //shooterAgent.Equipment.SetAmountOfSlot(equipmentIndex1, (short)(OwnCurrentAmmo + agentAmmo - 3));
  74.                                 //TAgemt.Equipment.SetAmountOfSlot(TAgentEquipmentIndex, 3);

  75.                                 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
  76.                                 {
  77.                                     shooterAgent.SetWeaponAmountInSlot(equipmentIndex1, (short)(OwnCurrentAmmo + agentAmmo - 3), false);
  78.                                     TAgent.SetWeaponAmountInSlot(TAgentEquipmentIndex, (short)(3), false);
  79.                                     v.heavyStrikeSkillCD = 5;
  80.                                     v.heavyStrikeSkillDur = 10;
  81.                                     if (shooterAgent.IsFriendOf(Agent.Main))
  82.                                     {
  83.                                         InformationManager.DisplayMessage(new InformationMessage($"{shooterAgent.Name}{shooterAgent.Index}抢走了{TAgent.Name}{TAgent.Index}的{OwnCurrentAmmo + agentAmmo - 3}发弹药"));
  84.                                     }
  85.                                     shooterAgent.UpdateAgentProperties();
  86.                                     TAgent.UpdateAgentProperties();
  87.                                     return;
  88.                                 }
  89.                             }
  90.                             else
  91.                             {
  92.                                 //没拿完的话
  93.                                 //shooterAgent.Equipment.SetAmountOfSlot(equipmentIndex1, (short)(shootAgentMaxAmmo));
  94.                                 //TAgemt.Equipment.SetAmountOfSlot(TAgentEquipmentIndex, (short)(agentAmmo - shootAgentMaxAmmo));
  95.                                 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
  96.                                 {
  97.                                     shooterAgent.SetWeaponAmountInSlot(equipmentIndex1, (short)(shootAgentMaxAmmo), false);
  98.                                     TAgent.SetWeaponAmountInSlot(TAgentEquipmentIndex, (short)(agentAmmo - shootAgentMaxAmmo), false);
  99.                                     v.heavyStrikeSkillCD = 5;
  100.                                     v.heavyStrikeSkillDur = 10;
  101.                                     if (shooterAgent.IsFriendOf(Agent.Main))
  102.                                     {
  103.                                         InformationManager.DisplayMessage(new InformationMessage($"{shooterAgent.Name}{shooterAgent.Index}抢走了{TAgent.Name}{TAgent.Index}的{shootAgentMaxAmmo}发弹药"));
  104.                                     }
  105.                                     shooterAgent.UpdateAgentProperties();
  106.                                     TAgent.UpdateAgentProperties();
  107.                                     return;
  108.                                 }
  109.                             }
  110.                         }
  111.                     }
  112.                   
  113.                 }

  114.             }
复制代码
  1.         public static MissionWeapon getMissionWeaponFromAgentInventory(Agent agent, out bool ThrewMeleeWeapon,out EquipmentIndex EquipmentIndex)//参考agent当前手持的武器,从agent当前的武器栏中,获取合适的投射物
  2.         {
  3.             //因为missionweapon.ammoweapon会在武器装填时输出空值,所以还是重写一个弹药获取的代码
  4.             //现在是获取手上的武器后,依次遍历agent的武器栏位。如果遍历到的物品是手上武器的弹药,并且弹药数量大于0,则设置为一会addmissile的弹药。
  5.             //手上武器为近战时还要做个缺省值
  6.             ThrewMeleeWeapon = false;
  7.             EquipmentIndex = EquipmentIndex.None;
  8.             EquipmentIndex 备用index= EquipmentIndex.None;//如果弹药数量为空的话,弹药所在的index记录在这个位置,如果本身有弹药但是因为用完了的时候,输出这个位置
  9.             if (!agent.IsHuman||agent.GetWieldedItemIndex(Agent.HandIndex.MainHand)== EquipmentIndex.None)
  10.                 return MissionWeapon.Invalid;
  11.             MissionWeapon missionWeapon = agent.Equipment[agent.GetWieldedItemIndex(Agent.HandIndex.MainHand)];
  12.             if (agent.Equipment[agent.GetWieldedItemIndex(Agent.HandIndex.MainHand)].CurrentUsageItem.IsRangedWeapon)//手上的物品是远程武器
  13.             {
  14.                 for (EquipmentIndex equipmentIndex = EquipmentIndex.WeaponItemBeginSlot; equipmentIndex < EquipmentIndex.NumAllWeaponSlots; equipmentIndex++)//循环遍历武器栏位
  15.                 {

  16.                     if (!agent.Equipment[agent.GetWieldedItemIndex(Agent.HandIndex.MainHand)].IsEmpty && !agent.Equipment[equipmentIndex].IsEmpty)//如果手上的武器和遍历的物品非空
  17.                     {
  18.                         if (agent.Equipment[agent.GetWieldedItemIndex(Agent.HandIndex.MainHand)].Item.PrimaryWeapon.WeaponClass == WeaponClass.Crossbow)//如果手上的武器是弩
  19.                         {
  20.                             //先进行一次把射出的武器定位默认值
  21.                             // 获取ItemObject引用,这里使用了一个字符串ID来查找特定的武器。字符串是xml里item的id值。
  22.                             ItemObject weaponItem = Game.Current.ObjectManager.GetObject<ItemObject>("bolt_a");
  23.                             // 创建MissionWeapon实例
  24.                             missionWeapon = new MissionWeapon(weaponItem, null, null);
  25.                             if (agent.Equipment[equipmentIndex].Item.PrimaryWeapon.WeaponClass == WeaponClass.Bolt && agent.Equipment[equipmentIndex].Amount > 0)//如果遍历的物品是弩箭
  26.                             {
  27.                                 missionWeapon = agent.Equipment[equipmentIndex];//设定射出的投射物是这个弩箭
  28.                                 EquipmentIndex = equipmentIndex;
  29.                                 break;//退出遍历循环
  30.                             }
  31.                             else if (agent.Equipment[equipmentIndex].Item.PrimaryWeapon.WeaponClass == WeaponClass.Bolt)
  32.                             {
  33.                                 missionWeapon = agent.Equipment[equipmentIndex];//设定射出的投射物是这个弩箭
  34.                                 备用index = equipmentIndex;                           
  35.                             }
  36.                         }
  37.                         if (agent.Equipment[agent.GetWieldedItemIndex(Agent.HandIndex.MainHand)].Item.PrimaryWeapon.WeaponClass == WeaponClass.Bow)
  38.                         {
  39.                             ItemObject weaponItem = Game.Current.ObjectManager.GetObject<ItemObject>("arrow_emp_1_a");
  40.                             missionWeapon = new MissionWeapon(weaponItem, null, null);
  41.                             if (agent.Equipment[equipmentIndex].Item.PrimaryWeapon.WeaponClass == WeaponClass.Arrow && agent.Equipment[equipmentIndex].Amount > 0)
  42.                             {
  43.                                 missionWeapon = agent.Equipment[equipmentIndex];
  44.                                 EquipmentIndex = equipmentIndex;
  45.                                 break;
  46.                             }
  47.                             else if (agent.Equipment[equipmentIndex].Item.PrimaryWeapon.WeaponClass == WeaponClass.Arrow)
  48.                             {
  49.                                 missionWeapon = agent.Equipment[equipmentIndex];//设定射出的投射物是这个弩箭
  50.                                 备用index = equipmentIndex;                             
  51.                             }
  52.                         }
  53.                         if (agent.Equipment[agent.GetWieldedItemIndex(Agent.HandIndex.MainHand)].CurrentUsageItem.IsConsumable && agent.Equipment[equipmentIndex].CurrentUsageItem.IsRangedWeapon&& agent.Equipment[equipmentIndex].CurrentUsageItem.IsConsumable)
  54.                         {
  55.                             ItemObject weaponItem = Game.Current.ObjectManager.GetObject<ItemObject>("western_javelin_1_t2");
  56.                             missionWeapon = new MissionWeapon(weaponItem, null, null);
  57.                             if (agent.Equipment[equipmentIndex].Amount > 0 )
  58.                             {
  59.                                 missionWeapon = agent.Equipment[equipmentIndex];
  60.                                 EquipmentIndex = equipmentIndex;
  61.                                 break;
  62.                             }
  63.                             else
  64.                             {
  65.                                 missionWeapon = agent.Equipment[equipmentIndex];//设定射出的投射物是这个弩箭
  66.                                 备用index = equipmentIndex;                             
  67.                             }
  68.                         }
  69.                     }

  70.                 }
  71.             }
  72.             else//如果手上不是远程武器,也写了适配,默认射一个投矛。伤害的问题在伤害计算那边处理
  73.             {
  74.                 ItemObject weaponItem = Game.Current.ObjectManager.GetObject<ItemObject>("western_javelin_1_t2");
  75.                 missionWeapon = new MissionWeapon(weaponItem, null, null);
  76.                 ThrewMeleeWeapon = true;
  77.             }
  78.             if (备用index != EquipmentIndex.None&& EquipmentIndex==EquipmentIndex.None)
  79.             {
  80.                 EquipmentIndex = 备用index;
  81.             }
  82.             return missionWeapon;
  83.         }
复制代码

28

主题

4157

回帖

3131

积分

子爵[版主]

世纪风云制作组[程序]

圣殿骑士团[KT]
战团ID:Epig

中级术士

Rank: 7Rank: 7Rank: 7

UID
1706215
第纳尔
34958
精华
3
互助
157
荣誉
79
贡献
2005
魅力
207
注册时间
2013-12-8

骑砍中文站APP会员勋章原版正版勋章战团正版勋章火与剑正版勋章拿破仑正版勋章维京征服正版勋章汉匈决战正版勋章骑士美德之英勇勋章[杰出会员活跃勋章]骑士美德之仁慈勋章[杰出会员互助勋章]骑士美德之谦恭勋章[杰出会员财富勋章]骑士美德之公正勋章[杰出会员高级财富勋章]骑士美德之正义勋章[杰出会员荣誉勋章]骑士精神之文韬勋章杰出版主勋章骑士美德之奉献勋章骑士美德之高贵勋章骑砍中文站微博会员勋章骑砍中文站微信会员勋章骑友真人秀勋章汉匈决战荣誉用户勋章元老骑士勋章霸主正版勋章

鲜花(2039) 鸡蛋(904)
发表于 2024-4-28 14:39:33 | 显示全部楼层
不加上玩家吗?我记得战团如果直接提取玩家武器栏的话是没办法提取到用了多少,因为武器栏那里取出会初始化弹药量,所以很多mod的弹药都是自己写的独立系统,看你的代码霸王貌似是没有这个问题
童鞋们,欢迎来到骑马与砍杀学院,我是你们的科任老师,猪猪老师,由我来为童鞋们介绍以下课程:
1、人间五十年life50 2.0测试版
2、永恒世界4.5.5公测版
3、永恒世界网页端 UCP2.0
4、大逃杀1.0公测版
5、永恒世界4.5特别版
6、常见PY报错解决方案

28

主题

223

回帖

180

积分

见习骑士

Rank: 3

UID
2758789
第纳尔
2118
精华
0
互助
19
荣誉
1
贡献
0
魅力
171
注册时间
2016-7-18
鲜花(18) 鸡蛋(0)
 楼主| 发表于 2024-4-29 01:29:13 | 显示全部楼层
恶猪 发表于 2024-4-28 14:39
不加上玩家吗?我记得战团如果直接提取玩家武器栏的话是没办法提取到用了多少,因为武器栏那里取出会初始化 ...

这个代码对玩家不生效,因为是用shooterAgent.Formation来获取的编队信息,而玩家的编队一直是空(所以玩家吃不到队长加成,起码我现在看的效果是吃不到)。想让玩家生效的话可以直接走常规的遍历全部agent然后判断是否为友军 foreach (var agent1 in Mission.Agents){ if (agent1 != Agent.Main && !agent1.IsFriendOf(Agent.Main) && agent1.IsHuman)}

当前弹药数量2代有直接获取的方法,比如TAgent.Equipment[equipmentIndex].Amount是这个格子的物品还有多少剩余数量。shooterAgent.Equipment[equipmentIndex1].MaxAmmo是获取这个格子的最大数量

1

主题

16

回帖

30

积分

扈从

Rank: 2Rank: 2

UID
3524210
第纳尔
159
精华
0
互助
3
荣誉
1
贡献
0
魅力
0
注册时间
2023-6-7
鲜花(1) 鸡蛋(0)
发表于 6 天前 来自手机 | 显示全部楼层
很好的教程,使我的代码旋转来自: Android客户端

1

主题

16

回帖

30

积分

扈从

Rank: 2Rank: 2

UID
3524210
第纳尔
159
精华
0
互助
3
荣誉
1
贡献
0
魅力
0
注册时间
2023-6-7
鲜花(1) 鸡蛋(0)
发表于 6 天前 来自手机 | 显示全部楼层
mod萌新问个问题,战斗场景生成agent时候,生成玩家的代码在哪里,找了一下午没找到来自: Android客户端

28

主题

223

回帖

180

积分

见习骑士

Rank: 3

UID
2758789
第纳尔
2118
精华
0
互助
19
荣誉
1
贡献
0
魅力
171
注册时间
2016-7-18
鲜花(18) 鸡蛋(0)
 楼主| 发表于 5 天前 | 显示全部楼层
梧桐! 发表于 2024-5-3 23:59
mod萌新问个问题,战斗场景生成agent时候,生成玩家的代码在哪里,找了一下午没找到 ...


下面的方法,顺序是从下到上执行的。然后到这个位置赋值下来主玩家
屏幕截图 2024-05-04 005612.png

1

主题

16

回帖

30

积分

扈从

Rank: 2Rank: 2

UID
3524210
第纳尔
159
精华
0
互助
3
荣誉
1
贡献
0
魅力
0
注册时间
2023-6-7
鲜花(1) 鸡蛋(0)
发表于 5 天前 | 显示全部楼层
路过的罗格 发表于 2024-5-4 01:02
下面的方法,顺序是从下到上执行的。然后到这个位置赋值下来主玩家

...

感谢

1

主题

16

回帖

30

积分

扈从

Rank: 2Rank: 2

UID
3524210
第纳尔
159
精华
0
互助
3
荣誉
1
贡献
0
魅力
0
注册时间
2023-6-7
鲜花(1) 鸡蛋(0)
发表于 5 天前 | 显示全部楼层
路过的罗格 发表于 2024-5-4 01:02
下面的方法,顺序是从下到上执行的。然后到这个位置赋值下来主玩家

...

难顶, 还是没找到, 给玩家派发武器的那块逻辑

28

主题

223

回帖

180

积分

见习骑士

Rank: 3

UID
2758789
第纳尔
2118
精华
0
互助
19
荣誉
1
贡献
0
魅力
171
注册时间
2016-7-18
鲜花(18) 鸡蛋(0)
 楼主| 发表于 5 天前 | 显示全部楼层
本帖最后由 路过的罗格 于 2024-5-4 11:57 编辑
梧桐! 发表于 2024-5-4 10:22
难顶, 还是没找到, 给玩家派发武器的那块逻辑

设定武器在设定这个agent是不是玩家之前,在
TaleWorlds.MountAndBlade.dll!TaleWorlds.MountAndBlade.Mission.SpawnAgent(TaleWorlds.MountAndBlade.AgentBuildData agentBuildData, bool spawnFromAgentVisuals)
调用的
agent.InitializeMissionEquipment(agentBuildData.AgentOverridenSpawnMissionEquipment, agentBuildData.AgentBanner);
这个方法,会把传入的AgentBuildData agentBuildData的装备信息赋值给当前创建的这个agent

屏幕截图 2024-05-04 113857.png



派发的逻辑在上面,如果是要修改生成时装备的武器,建议在继承了MissionBehavior的类里复写OnAgentBuild方法进行调整

1

主题

16

回帖

30

积分

扈从

Rank: 2Rank: 2

UID
3524210
第纳尔
159
精华
0
互助
3
荣誉
1
贡献
0
魅力
0
注册时间
2023-6-7
鲜花(1) 鸡蛋(0)
发表于 5 天前 | 显示全部楼层
路过的罗格 发表于 2024-5-4 11:39
设定武器在设定这个agent是不是玩家之前,在
TaleWorlds.MountAndBlade.dll!TaleWorlds.MountAndBlade.Mis ...

好的好的, 我去试试
您需要登录后才可以回帖 登录 | 注册(Register!)

本版积分规则

Archiver|手机版|小黑屋|骑马与砍杀中文站

GMT+8, 2024-5-9 13:11 , Processed in 0.127242 second(s), 24 queries , Gzip On, MemCached On.

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表