void UpdateSpectatorPos(long now) { if (now < specNextUpdate) { return; } var cam = GothicGlobals.Game.GetCameraVob(); var pos = new Vec3f(cam.Position).ClampToWorldLimits(); cam.SetPositionWorld(pos.X, pos.Y, pos.Z); if (now - specNextUpdate < TimeSpan.TicksPerSecond && pos.GetDistance(lastSpecPos) < 10) { return; } lastSpecPos = pos; PacketWriter stream = SetupStream(ClientMessages.SpecatorPosMessage); stream.WriteCompressedPosition(pos); Send(stream, NetPriority.Low, NetReliability.Unreliable); specNextUpdate = now + SpecPosUpdateInterval; }
protected virtual void UpdateGuidePos(long now) { if (now < guidedNextUpdate) { return; } Vec3f pos = this.Position; Angles ang = this.Angles; VobEnvironment env = this.Environment; if (now - guidedNextUpdate < TimeSpan.TicksPerSecond) { // nothing really changed, only update every second if (pos.GetDistance(guidedLastPos) < MinPositionDistance && !ang.DifferenceIsBigger(guidedLastAng, MinAnglesDifference) && env == guidedLastEnv) { return; } } guidedLastPos = pos; guidedLastAng = ang; guidedLastEnv = env; Messages.WritePosDirMessage(this, pos, ang, env); guidedNextUpdate = now + PosUpdateInterval; //this.ScriptObject.OnPosChanged(); }
bool DoHitDetection(Vec3f from, Vec3f to) { // fixme: expensive and also shitty check if (DetectHit(from)) // check last position { return(true); } float flownDist = from.GetDistance(to); if (flownDist < 20) { return(false); // flew a really short distance since last check } int interChecks = (int)(flownDist / GUCScripts.SmallestNPCRadius); if (interChecks > 1) { Vec3f dir = (to - from).Normalise(); float inc = flownDist / interChecks; for (int i = 1; i < interChecks; i++) { if (DetectHit(from + inc * dir)) { return(true); } } } return(DetectHit(to)); }
void UpdateGuidedNPCPosition(long now, long interval, float minPosDist, float minAngDist) { if (now < guidedNextUpdate) { return; } Vec3f pos = this.Position; Angles ang = this.Angles; VobEnvironment env = this.Environment; if (now - guidedNextUpdate < TimeSpan.TicksPerSecond) { // nothing really changed, only update every second if (guidedLastMovement == this.movement && pos.GetDistance(guidedLastPos) < minPosDist && !ang.DifferenceIsBigger(guidedLastAng, minAngDist) && env == guidedLastEnv) { return; } } guidedLastMovement = this.movement; guidedLastPos = pos; guidedLastAng = ang; guidedLastEnv = env; Messages.WritePosAngMessage(this, pos, ang, env); guidedNextUpdate = now + interval; //this.ScriptObject.OnPosChanged(); }
partial void pUpdatePos() { Vec3f curPos = GetPosition(); if (curPos.GetDistance(BaseInst.StartPosition) > 100000) { this.Despawn(); return; } if (DoHitDetection(BaseInst.LastPosition, curPos)) { this.Despawn(); } }
static void PrintPosition(bool down) { var hero = NPCInst.Hero; if (!down || hero == null) { return; } var pos = hero.GetPosition(); var ang = hero.GetAngles(); Log.Logger.Log(pos + " " + ang + " Distance to last: " + lastPos.GetDistance(pos)); System.IO.File.AppendAllText("positions.txt", string.Format(System.Globalization.CultureInfo.InvariantCulture, "{{ new Vec3f({0}f, {1}f, {2}f), new Angles({3}f, {4}f, {5}f) }},\n", pos.X, pos.Y, pos.Z, ang.Pitch, ang.Yaw, ang.Roll)); lastPos = pos; }
public void TryShoot(Vec3f start, Vec3f end) { if (Host.IsDead || !Host.IsAiming()) { return; } if (start.GetDistance(end) > 500000) // just in case { end = start + 500000 * (end - start).Normalise(); } var drawnWeapon = Host.GetDrawnWeapon(); if (drawnWeapon == null || !drawnWeapon.IsWepRanged) { return; } ItemInst ammo = drawnWeapon.ItemType == ItemTypes.WepBow ? Host.GetRightHand() : Host.GetLeftHand(); if (ammo == null || !ammo.IsAmmo) { return; } ProjInst inst = new ProjInst(ProjDef.Get <ProjDef>("arrow")) { Item = new ItemInst(ammo.Definition), Damage = drawnWeapon.Damage, Velocity = 0.0004f, Model = ammo.ModelDef }; end = end - (end - start).Normalise() * (ammo.ItemType == ItemTypes.AmmoBow ? 40 : 10); // so arrows' bodies aren't 90% inside walls Host.DoShoot(start, end, inst); int ammoCount = ammo.Amount - 1; if (ammoCount <= 0) { Host.UnequipItem(ammo); } ammo.SetAmount(ammo.Amount - 1); }
public override void Update(GuidedVob vob, long now) { if (Target == null) { return; } if (!Cast.Try(vob.ScriptObject, out NPCInst npc)) { throw new Exception("Vob used with GoToVobLookAtCommand is no NPC!"); } if (npc.IsDead) { return; } var gNpc = npc.BaseInst.gVob; gNpc.RbtTimer = 500; gNpc.RbtTargetVob = Target.BaseInst.gVob; gNpc.RbtBitfield = gNpc.RbtBitfield | (1 << 4); // stand when reached Target.GetPosition().SetGVec(gNpc.RbtTargetPos); gNpc.RbtMaxTargetDist = Distance * Distance; gNpc.RbtGotoFollowPosition(); Vec3f npcPos = npc.GetPosition(); Vec3f targetPos = Target.GetPosition(); if (npcPos.GetDistance(targetPos) <= Distance) { const float maxTurnFightSpeed = 0.08f; float bestYaw = Angles.GetYawFromAtVector(targetPos - npcPos); Angles curAngles = npc.GetAngles(); float yawDiff = Angles.Difference(bestYaw, curAngles.Yaw); curAngles.Yaw += Alg.Clamp(-maxTurnFightSpeed, yawDiff, maxTurnFightSpeed); npc.SetAngles(curAngles); } }
partial void pOnTick(long now) { long flyTime = now - startTime; if (flyTime <= 0) { this.SetPosition(startPos); } else { this.lastPos = this.pos; Vec3f curPos = GetTimedPosition(flyTime); if (curPos.GetDistance(startPos) >= destination.GetDistance(startPos)) { curPos = destination; } this.SetPosition(curPos); } }
private void ChangePosDir(Vec3f oldPos, Angles oldAng, NPCMovement oldMovement) { Vec3f pos = GetPosition(); var env = Environment; if (env.InAir) { if (pos.Y > highestY) { highestY = pos.Y; } } else if (highestY != 0) { float dmg = 0.14f * (highestY - pos.Y) - 135; if (dmg > 0) { Logger.Log("Damage: " + dmg); //this.SetHealth(this.HP - (int)dmg); highestY = 0; } } if (lastRegPos.GetDistance(pos) > 30.0f) { LastHitMove = GameTime.Ticks; lastRegPos = pos; } if (FightAnimation != null && CanCombo && Movement != NPCMovement.Stand) { // so the npc can instantly stop the attack and run into a direction ModelInst.StopAnimation(FightAnimation, false); } if (env.WaterLevel > 0.7f) { if (IsPlayer) { //var client = ((Arena.ArenaClient)this.Client); //client.KillCharacter(); //if (Arena.GameModes.Horde.HordeMode.IsActive && this.TeamID >= 0) //{ // Arena.GameModes.Horde.HordeMode.ActiveMode.RespawnClient(client); //} } else { SetHealth(0); } } if (env.InAir && !IsClimbing) { var aa = ModelInst.GetActiveAniFromLayer(1); if (aa != null) { ModelInst.StopAnimation(aa, false); } } CheckUnconsciousness(); }
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); } }
void ChangePosDir(Vec3f oldPos, Angles oldAng, NPCMovement oldMovement) { Vec3f pos = GetPosition(); var env = this.Environment; if (env.InAir) { if (pos.Y > highestY) { highestY = pos.Y; } } else if (highestY != 0) { float dmg = 0.14f * (highestY - pos.Y) - 135; if (dmg > 0) { Logger.Log("Damage: " + dmg); //this.SetHealth(this.HP - (int)dmg); highestY = 0; } } if (lastRegPos.GetDistance(pos) > 30.0f) { lastHitMoveTime = GameTime.Ticks; lastRegPos = pos; } if (this.FightAnimation != null && this.CanCombo && this.Movement != NPCMovement.Stand) { // so the npc can instantly stop the attack and run into a direction this.ModelInst.StopAnimation(this.fightAni, false); } if (Arena.GameModes.GameMode.ActiveMode != null && Cast.Try(this.Client, out Arena.ArenaClient ac) && ac.GMJoined) { var gm = Arena.GameModes.GameMode.ActiveMode; if (pos.GetDistancePlanar(Vec3f.Null) > gm.Scenario.MaxWorldDistance || pos.Y > gm.Scenario.MaxHeight || pos.Y < gm.Scenario.MaxDepth) { ac.KillCharacter(); } } if (env.WaterLevel > 0.7f) { if (this.IsPlayer) { var client = ((Arena.ArenaClient) this.Client); client.KillCharacter(); if (Arena.GameModes.Horde.HordeMode.IsActive && this.TeamID >= 0) { Arena.GameModes.Horde.HordeMode.ActiveMode.RespawnClient(client); } } else { this.SetHealth(0); } } if (env.InAir && !this.isClimbing) { var aa = this.ModelInst.GetActiveAniFromLayer(1); if (aa != null) { this.ModelInst.StopAnimation(aa, false); } } CheckUnconsciousness(); }