static void NPCInst_sOnNPCInstMove(NPCInst npc, Vec3f oldPos, Angles oldAng, NPCMovement oldMovement) { if (npc.IsDead || !npc.IsPlayer || npc.IsUnconscious) { return; } ArenaClient client = (ArenaClient)npc.Client; if (client.HordeClass == null) { return; } if (ActiveStandInst != null) { return; } foreach (var s in ActiveStands) { if (npc.GetPosition().GetDistance(s.Stand.Position) < s.Stand.Range) { StartStand(s); break; } } }
void DoUnconstuff(NPCInst hero) { if (hero?.Environment == null || hero?.BaseInst?.gAI == null) { return; } var env = hero.Environment; if (env.WaterLevel < 0.2f) { if (env.InAir) { return; } var gAi = hero.BaseInst.gAI; if (!gAi.CheckEnoughSpaceMoveForward(false)) { return; } if (!gAi.CheckEnoughSpaceMoveBackward(false)) { return; } if (!gAi.CheckEnoughSpaceMoveLeft(false)) { return; } if (!gAi.CheckEnoughSpaceMoveRight(false)) { return; } _LastValidPos = hero.GetPosition(); } else { if (!hero.IsUnconscious && env.WaterLevel > 0.3f && _SwimTimer.IsReady) { ScreenScrollText.AddText("Du kannst ja gar nicht schwimmen!?!"); } if (!hero.IsUnconscious) { _DoneUncon = false; } if (!_DoneUncon && hero.IsUnconscious) { hero.BaseInst.SetPhysics(false); var rb = WinApi.Process.ReadInt(hero.BaseInst.gVob.Address + 224); using (var vec = Vec3f.Null.CreateGVec()) WinApi.Process.THISCALL <WinApi.NullReturnCall>(rb, 0x5B66D0, vec); Vec3f.Null.SetGVec(hero.BaseInst.gAI.Velocity); hero.SetPosition(_LastValidPos); _DoneUncon = true; } } }
public void TryHelpUp(NPCInst target) { if (Host.IsDead || Host.Movement != NPCMovement.Stand || Host.ModelInst.IsInAnimation() || Host.Environment.InAir || Host.IsUnconscious || !target.IsUnconscious || target.GetPosition().GetDistance(Host.GetPosition()) > 300) { return; } float speed = 1.0f; this.Host.ModelInst.StartAniJob(Host.AniCatalog.Gestures.Plunder, speed); this.Host.DoVoice((VoiceCmd)(1 + this.Host.Guild)); target.LiftUnconsciousness(); OnHelpUp?.Invoke(this.Host); }
static void RequestShootAuto(NPCInst hero) { Vec3f start; using (var matrix = Gothic.Types.zMat4.Create()) { var weapon = hero.GetDrawnWeapon(); var node = (weapon == null || weapon.ItemType == ItemTypes.WepBow) ? oCNpc.NPCNodes.RightHand : oCNpc.NPCNodes.LeftHand; hero.BaseInst.gVob.GetTrafoModelNodeToWorld(node, matrix); start = (Vec3f)matrix.Position; } const zCWorld.zTraceRay traceType = zCWorld.zTraceRay.Ignore_Alpha | zCWorld.zTraceRay.Ignore_Projectiles | zCWorld.zTraceRay.Ignore_Vob_No_Collision | zCWorld.zTraceRay.Ignore_NPC; NPCInst enemy = PlayerFocus.GetFocusNPC(); Vec3f dir = enemy == null ? (Vec3f)hero.BaseInst.gVob.Direction : (enemy.GetPosition() - start).Normalise(); Vec3f ray = 500000f * dir; Vec3f end; using (var zStart = start.CreateGVec()) using (var zRay = ray.CreateGVec()) { var gWorld = GothicGlobals.Game.GetWorld(); if (gWorld.TraceRayNearestHit(zStart, zRay, traceType)) { end = (Vec3f)gWorld.Raytrace_FoundIntersection; } else { end = start + ray; } } NPCInst.Requests.Shoot(hero, start, end); }
static void Update() { NPCInst hero = currentPlayer; if (hero == null) { Deactivate(); return; } float maxYaw = Angles.Deg2Rad(60); bool fightMode = hero.IsInFightMode; ItemInst wep = hero.GetDrawnWeapon(); float maxRange = (fightMode && wep != null && wep.IsWepRanged) ? 3000 : 400; Vec3f heroPos = hero.GetPosition(); Angles heroAng = hero.GetAngles(); float bestFit = 2.0f; BaseVobInst bestVob = null; if (hero?.World?.BaseWorld != null) { hero.World.BaseWorld.ForEachVob(v => { BaseVobInst vob = (BaseVobInst)v.ScriptObject; if (vob == hero) { return; } bool hasPriority = false; if (fightMode) { if (!(vob is NPCInst npc)) { return; } if (npc.IsDead) { return; } if (bestVob != null) { NPCInst bestNPC = (NPCInst)bestVob; if (npc.IsUnconscious) { if (!bestNPC.IsUnconscious) { return; // alive targets are more important } } else { if (bestNPC.IsUnconscious) { hasPriority = true; } } if (npc.TeamID == hero.TeamID) { if (bestNPC.TeamID != hero.TeamID) { return; } } else { if (bestNPC.TeamID == hero.TeamID) { hasPriority = true; } } } } Vec3f targetPos; using (zVec3 z = zVec3.Create()) { vob.BaseInst.gVob.BBox3D.GetCenter(z); targetPos = (Vec3f)z; } float distance = heroPos.GetDistance(targetPos); if (distance > maxRange) { return; } float yaw = Angles.GetYawFromAtVector(targetPos - heroPos); yaw = Math.Abs(Angles.Difference(yaw, heroAng.Yaw)); if (yaw > maxYaw) { return; // target is not in front of hero } if (!CanSee(heroPos, targetPos, vob)) { return; } float fit = distance / maxRange + yaw / maxYaw; if (hasPriority || fit < bestFit) { bestVob = vob; bestFit = fit; } }); SetFocus(bestVob); } }
static void DoTurning(NPCInst hero) { if (hero.BaseInst.gAI.GetFoundLedge()) { return; } const float maxTurnFightSpeed = 0.07f; NPCInst enemy = PlayerFocus.LockedTarget; if (enemy != null) { Vec3f heroPos = hero.GetPosition(); Vec3f enemyPos = enemy.GetPosition(); float bestYaw = Angles.GetYawFromAtVector(enemyPos - heroPos); Angles curAngles = hero.GetAngles(); float yawDiff = Angles.Difference(bestYaw, curAngles.Yaw); curAngles.Yaw += Alg.Clamp(-maxTurnFightSpeed, yawDiff, maxTurnFightSpeed); hero.SetAngles(curAngles); CheckCombineAim(hero, enemyPos - heroPos); return; } const float maxLookupSpeed = 2f; float rotSpeed = 0; if (InputHandler.MouseDistY != 0) { rotSpeed = Alg.Clamp(-maxLookupSpeed, InputHandler.MouseDistY * 0.35f * MouseSpeed, maxLookupSpeed); if (hero.Environment.WaterLevel >= 1) { hero.BaseInst.gAI.DiveRotateX(rotSpeed); } else { var cam = zCAICamera.CurrentCam; cam.BestElevation = Alg.Clamp(-50, cam.BestElevation + rotSpeed, 85); } } // Fixme: do own turning const float maxTurnSpeed = 2f; if (!KeyBind.Action.IsPressed()) { float turn = 0; if (KeyBind.TurnLeft.IsPressed()) { turn = -maxTurnSpeed; } else if (KeyBind.TurnRight.IsPressed()) { turn = maxTurnSpeed; } else if (Math.Abs(InputHandler.MouseDistX) > ((rotSpeed > 0.5f && hero.Movement == NPCMovement.Stand) ? 18 : 2)) { turn = Alg.Clamp(-maxTurnSpeed, InputHandler.MouseDistX * 0.45f * MouseSpeed, maxTurnSpeed); } if (turn != 0) { hero.BaseInst.gAI.Turn(turn, !hero.ModelInst.IsInAnimation()); return; } } hero.BaseInst.gVob.AniCtrl.StopTurnAnis(); }