コード例 #1
0
        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;
        }
コード例 #2
0
        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();
        }
コード例 #3
0
        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));
        }
コード例 #4
0
        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();
        }
コード例 #5
0
        partial void pUpdatePos()
        {
            Vec3f curPos = GetPosition();

            if (curPos.GetDistance(BaseInst.StartPosition) > 100000)
            {
                this.Despawn();
                return;
            }

            if (DoHitDetection(BaseInst.LastPosition, curPos))
            {
                this.Despawn();
            }
        }
コード例 #6
0
        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;
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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);
            }
        }
コード例 #9
0
        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);
            }
        }
コード例 #10
0
        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();
        }
コード例 #11
0
        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);
            }
        }
コード例 #12
0
        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();
        }