- 好友
- 0
- 在线时间
- 128 小时
- 最后登录
- 2025-4-1
见习骑士

- UID
- 2758789
- 第纳尔
- 2133
- 精华
- 0
- 互助
- 21
- 荣誉
- 1
- 贡献
- 0
- 魅力
- 201
- 注册时间
- 2016-7-18
 鲜花( 23)  鸡蛋( 0)
|
本帖最后由 路过的罗格 于 2025-3-30 08:25 编辑
演示视频
狗屎代码有点多,这次没法直接整合别人的代码,差点给我写死了。
先放一个演示的视频,以后上班摸鱼的时候再来写怎么做的。核心代码先丢上来,零散的等以后摸鱼。
具体教程继续等等,过两天辞完职再说,辞职还被扣那继续干一个星期也是服了
源码先丢出来,最近把之前卡住的东西给完成了,已经可以当一个常规的mod来发布了
链接:https://pan.baidu.com/s/18DiOFMymu2j8lRTvLNNIQw?pwd=wotw
使用的时候直接在OnMissionTick里调用AimShoot就行了
- public void AimShoot(Agent agent)//自瞄步骤1,选择射击目标agent
- {
- EquipmentIndex mainHandIndex1 = agent.GetWieldedItemIndex(Agent.HandIndex.MainHand);
- if (mainHandIndex1 == EquipmentIndex.None)
- {
- return ;
- }
- MissionWeapon mainHandEquipmentElement = agent.Equipment[mainHandIndex1];
- if (!mainHandEquipmentElement.CurrentUsageItem.IsRangedWeapon)
- {
- return;
- }
- Agent ShootAgent = agent;
- Agent vAgent=null;
- List<Agent> list1 = new List<Agent>();
- List<Agent> list2 = new List<Agent>();
- foreach (Agent ChooseAgent in agent.Mission.Agents)
- {
- if (!ChooseAgent.IsFriendOf(ShootAgent)&& ChooseAgent.IsHuman&& ChooseAgent.CurrentMortalityState!= MortalityState.Invulnerable)
- {
- list1.Add(ChooseAgent);
- }
- }
- foreach (Agent ChooseAgent in list1)
- {
- vAgent = ChooseAgent;
- EquipmentIndex mainHandIndex = ChooseAgent.GetWieldedItemIndex(Agent.HandIndex.OffHand);
- if (mainHandIndex == EquipmentIndex.None || vAgent.GetCurrentActionType(1) != Agent.ActionCodeType.DefendShield || isBehindTarget(ChooseAgent, ShootAgent))//如果左手为空或者没有顶盾或者处于身后
- {
- list2.Add(ChooseAgent);
- }
- }
- list1.Clear();
- //foreach (Agent ChooseAgent in list2)
- //{
- // vAgent = ChooseAgent;
- // if (agent.Mission.RayCastForClosestAgent(agent.GetEyeGlobalPosition(), ChooseAgent.Position, out var collisionDistance) == ChooseAgent)//射线检测,能看到这个agent
- // {
- // list1.Add(ChooseAgent);
- // }
- //}
- //list2.Clear();
- float len = float.MaxValue;
- foreach (Agent ChooseAgent in list2)
- {
- if ((ChooseAgent.Position - ShootAgent.Position).Length < len)
- {
- len = (ChooseAgent.Position - ShootAgent.Position).Length;
- vAgent = ChooseAgent;
- }
- }
- if (vAgent != null && AgentShotAgent(ShootAgent, vAgent) != 0)
- {
- //vAgent.SetTargetPosition(vAgent.Position.AsVec2);
- //vAgent.SetTargetPosition(ShootAgent.Position.AsVec2);
- ShootAgent.SetAttackState((int)Agent.ActionStage.AttackRelease);
- //ShootAgent.SetAttackState((int)Agent.ActionStage.AttackReady);
- return;
- }
- }
复制代码
|
- public static bool isBehindTarget(Agent agent1, Agent agent2)//2是否在1身后
- {
- Vec2 rel_pos = agent1.Position.AsVec2 - agent2.Position.AsVec2;
- Vec2 dir_1 = agent1.LookDirection.AsVec2;
- dir_1 = -dir_1;
- if (dir_1.x * rel_pos.x + dir_1.y * rel_pos.y < 0)
- {
- return true;
- }
- return false;
- }
复制代码
|
- public int AgentShotAgent(Agent agent, Agent vagent)//自瞄步骤2,决定实际射击的位置,添加预瞄功能
- {
- if (agent.Equipment != null && agent.Equipment[0].Item != null)
- {
- // 获取Agent主手中武器的Index索引
- EquipmentIndex mainHandIndex = agent.GetWieldedItemIndex(Agent.HandIndex.MainHand);
- if (mainHandIndex == EquipmentIndex.None)
- {
- return 0;
- }
- // EquipmentIndex转MissionWeapon
- MissionWeapon mainHandEquipmentElement = agent.Equipment[mainHandIndex];
- // 获取主手装备元素的修正后的导弹速度
- float baseSpeed = (float)mainHandEquipmentElement.GetModifiedMissileSpeedForCurrentUsage();
- bool ThrewMeleeWeapon;
- mainHandEquipmentElement = getMissionWeaponFromAgentInventory(agent, out ThrewMeleeWeapon);
- if (ThrewMeleeWeapon)
- { baseSpeed = -1; }
- Vec3 headPosition = agent.GetEyeGlobalPosition();
- Vec3 VheadPosition = vagent.GetEyeGlobalPosition();
- Vec3 VAgenSpeed=Vec3.Invalid;
- if (WoW_MissionSetting.WoW_Agents.TryGetValue(vagent.Index, out var data))
- {
- VAgenSpeed = data.speed.speed;
- }
- Vec3 shotDir = CalculateProjectileFiringSolution(headPosition, VheadPosition, baseSpeed, 9.81f);
- float timeOld = (headPosition - VheadPosition).AsVec2.Length / (baseSpeed * shotDir.AsVec2.Length);
- float timeNew = float.MaxValue;
- //VheadPosition.z -= 15 / 100f;
- //VheadPosition.y += 15 / 100f;
- while (TaleWorlds.Library.MathF.Abs(timeOld- timeNew)>0.001f)
- {
- timeNew = timeOld;
- Vec3 s= MultiplyVectorByScalar(VAgenSpeed,timeOld);
- //s = vagent.LookDirection.AsVec2 * VAgenSpeed.Length * timeOld;
- VheadPosition = vagent.GetEyeGlobalPosition()+s;
- shotDir = CalculateProjectileFiringSolution(headPosition, VheadPosition, baseSpeed, 9.81f);
- timeOld = (headPosition - VheadPosition).AsVec2.Length / (baseSpeed * shotDir.AsVec2.Length);
-
- }
- //GameEntity gameEntity = GameEntity.CreateEmpty(Mission.Current.Scene);
- //gameEntity.AddAllMeshesOfGameEntity(GameEntity.Instantiate(Mission.Current.Scene, "mangonel_mapicon_projectile", true));
- //gameEntity.SetLocalPosition(VheadPosition);
- int index = WoW_Scripts.FireProjectileFromAgentWithWeaponAtPosition(agent, agent.Equipment[mainHandIndex], mainHandEquipmentElement, headPosition, VheadPosition, baseSpeed);
- mainHandEquipmentElement.Amount = (short)(mainHandEquipmentElement.Amount - 1);
- return index;
- }
- return 0;
- }
复制代码
|
FireProjectileFromAgentWithWeaponAtPosition函数参考我以前的帖子,需要搭建一下完整的这个系统,不然除了投掷物外,其他远程的伤害有问题
- public static Vec3 CalculateProjectileFiringSolution(Vec3 start, Vec3 end, float speed, float gravity)//pos射击pos,弹道计算,输出射击角度。凑合
- {
- // 计算水平距离
- Vec2 horizontalDistance = new Vec2(end.x - start.x, end.y - start.y);
- float horizontalRange = horizontalDistance.Length;
- // 计算垂直距离,即高度差
- float verticalDistance = end.z - start.z;
- // 计算发射角度的可能解
- float speedSquared = speed * speed;
- float sqrtTerm = speedSquared * speedSquared - gravity * (gravity * horizontalRange * horizontalRange + 2 * verticalDistance * speedSquared);
- // 如果这个术语小于0,则没有实际的解决方案,因为速度不够以克服重力
- if (sqrtTerm < 0.0f)
- {
- // throw new InvalidOperationException("No valid firing solution for given parameters.");
- return Vec3.Invalid;
- }
- float sqrtValue = (float)Math.Sqrt(sqrtTerm);
- // 取两个可能的解中较小的一个(较高的一个将是较大的发射角)
- float angle = (float)Math.Atan2(speedSquared - sqrtValue, gravity * horizontalRange);
- // 将发射角转换为方向向量
- Vec3 firingSolution = new Vec3(horizontalDistance.x, horizontalDistance.y, 0);
- firingSolution.Normalize();
- firingSolution *= (float)Math.Cos(angle) * speed; // 水平速度分量
- firingSolution.z = (float)Math.Sin(angle) * speed; // 垂直速度分量
- firingSolution.Normalize();
- return firingSolution;
- }
复制代码
|
mission里
- foreach (Agent agent in Mission.Agents)//刷新位置和速度信息
- {
- if (WoW_Agents.TryGetValue(agent.Index, out var data))
- {
- data.speed.Tick(dt);
- }
- }
复制代码 自定义一个速度类,每个tick去刷新新旧位置来计算速度
- public class AgentSpeed
- {
- public Vec3 oldPos;
- public Vec3 newPos;
- public Agent agent;
- public Vec3 speed { get; set; }
- public AgentSpeed(Agent Nagent)
- {
- agent=Nagent;
- }
- public void Tick(float dt)
- {
- this.oldPos = this.newPos;
- this.newPos= this.agent.Position;
- this.speed = (this.newPos - this.oldPos) / dt;
- }
- }
复制代码
|
|
评分
-
查看全部评分
|