Example #1
0
        static void CalcRangedTrace(NPCInst npc, out Vec3f start, out Vec3f end)
        {
            Vec3f projStartPos;

            using (var matrix = Gothic.Types.zMat4.Create())
            {
                var weapon = npc.GetDrawnWeapon();
                var node   = (weapon == null || weapon.ItemType == ItemTypes.WepBow) ? oCNpc.NPCNodes.RightHand : oCNpc.NPCNodes.LeftHand;
                npc.BaseInst.gVob.GetTrafoModelNodeToWorld(node, matrix);
                projStartPos = (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;

            var camVob = GothicGlobals.Game.GetCameraVob();

            start = (Vec3f)camVob.Position;
            Vec3f ray = 500000f * (Vec3f)camVob.Direction;

            end = start + ray;

            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;
                    }

                    start = projStartPos;
                    ray   = end - start;

                    start.SetGVec(zStart);
                    ray.SetGVec(zRay);

                    if (gWorld.TraceRayNearestHit(zStart, zRay, traceType))
                    {
                        end = (Vec3f)gWorld.Raytrace_FoundIntersection;
                    }
                }
        }
Example #2
0
        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);
        }
Example #3
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);
            }
        }
Example #4
0
        void PlayerUpdate()
        {
            if (ArenaClient.DetectSchinken)
            {
                fwdTelHelper.Update(GameTime.Ticks);
                upTelHelper.Update(GameTime.Ticks);
            }

            NPCInst hero = ScriptClient.Client.Character;
            var     gAI  = hero.BaseInst.gAI;

            if (hero.IsDead || hero.IsUnconscious)
            {
                LookAround(hero);
                return;
            }

            zCAICamera.CurrentCam.BestAzimuth = 0;

            if (freeAim)
            {
                FreeAiming(hero);
                return;
            }

            DoTurning(hero);

            if (KeyBind.Action.IsPressed() && hero.IsInFightMode)
            {
                var enemy = PlayerFocus.GetFocusNPC();
                if (enemy == null || !enemy.IsSpawned || enemy.IsDead)
                {
                    PlayerFocus.SetLockedTarget(null); // updates for new target
                }
                PlayerFocus.SetLockedTarget(PlayerFocus.GetFocusNPC());
            }
            else
            {
                PlayerFocus.SetLockedTarget(null);
            }

            NPCMovement state = NPCMovement.Stand;

            if (!KeyBind.Action.IsPressed() || hero.Movement != NPCMovement.Stand)
            {
                if (KeyBind.MoveForward.IsPressed()) // move forward
                {
                    state = NPCMovement.Forward;
                }
                else if (KeyBind.MoveBack.IsPressed()) // move backward
                {
                    var drawnWeapon = hero.GetDrawnWeapon();
                    if (hero.IsInFightMode && (drawnWeapon == null || drawnWeapon.IsWepMelee))
                    {
                        if (dodgeLock.IsReady) // don't spam
                        {
                            if (IsWarmup())
                            {
                                return;
                            }

                            NPCInst.Requests.Attack(hero, FightMoves.Dodge);
                        }
                        return;
                    }
                    else
                    {
                        state = NPCMovement.Backward;
                    }
                }
                else if (KeyBind.MoveLeft.IsPressed()) // strafe left
                {
                    state = NPCMovement.Left;
                }
                else if (KeyBind.MoveRight.IsPressed()) // strafe right
                {
                    state = NPCMovement.Right;
                }
                else
                {
                    state = NPCMovement.Stand;
                }
            }

            if (nextStrafeChange > GameTime.Ticks)
            {
                state = hero.Movement;
            }

            if (state == NPCMovement.Forward)
            {   // FIXME: use only a better CheckEnoughSpaceMoveForward
                if (hero.Movement == NPCMovement.Stand && !gAI.CheckEnoughSpaceMoveForward(true))
                {
                    state = NPCMovement.Stand;
                }
                else
                {
                    gAI.CalcForceModelHalt();
                    if ((gAI.Bitfield0 & zCAIPlayer.Flags.ForceModelHalt) != 0)
                    {
                        gAI.Bitfield0 &= ~zCAIPlayer.Flags.ForceModelHalt;
                        state          = NPCMovement.Stand;
                    }
                }
            }
            else if (state == NPCMovement.Backward)
            {
                if (!gAI.CheckEnoughSpaceMoveBackward(true))
                {
                    state = NPCMovement.Stand;
                }
            }
            else if (state == NPCMovement.Left)
            {
                if (!gAI.CheckEnoughSpaceMoveLeft(true))
                {
                    state = NPCMovement.Stand;
                }
            }
            else if (state == NPCMovement.Right)
            {
                if (!gAI.CheckEnoughSpaceMoveRight(true))
                {
                    state = NPCMovement.Stand;
                }
            }

            if (state != NPCMovement.Stand && IsWarmup())
            {
                state = NPCMovement.Stand;
            }

            if (state == NPCMovement.Left || state == NPCMovement.Right || (state == NPCMovement.Forward && hero.IsInFightMode))
            {
                if (hero.Movement != state)
                {
                    nextStrafeChange = GameTime.Ticks + StrafeInterval;
                }
            }
            else
            {
                nextStrafeChange = 0;
            }

            hero.SetMovement(state);
        }