Beispiel #1
0
            public override bool Think(edict_t self)
            {
                float[] forward = new float[] { 0, 0, 0 }, right = new float[] { 0, 0, 0 };
                float[] start   = new float[] { 0, 0, 0 };
                float[] dir     = new float[] { 0, 0, 0 };
                float[] vec     = new float[] { 0, 0, 0 };
                int     flash_number;

                if (self.s.frame == FRAME_attak2_8)
                {
                    flash_number = Defines.MZ2_SUPERTANK_ROCKET_1;
                }
                else if (self.s.frame == FRAME_attak2_11)
                {
                    flash_number = Defines.MZ2_SUPERTANK_ROCKET_2;
                }
                else
                {
                    flash_number = Defines.MZ2_SUPERTANK_ROCKET_3;
                }
                Math3D.AngleVectors(self.s.angles, forward, right, null);
                Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[flash_number], forward, right, start);
                Math3D.VectorCopy(self.enemy.s.origin, vec);
                vec[2] += self.enemy.viewheight;
                Math3D.VectorSubtract(vec, start, dir);
                Math3D.VectorNormalize(dir);
                Monster.Monster_fire_rocket(self, start, dir, 50, 500, flash_number);
                return(true);
            }
Beispiel #2
0
            public override bool Think(edict_t self)
            {
                float[] dir     = new float[] { 0, 0, 0 };
                float[] vec     = new float[] { 0, 0, 0 };
                float[] start   = new float[] { 0, 0, 0 };
                float[] forward = new float[] { 0, 0, 0 }, right = new float[] { 0, 0, 0 };
                int     flash_number;

                flash_number = Defines.MZ2_SUPERTANK_MACHINEGUN_1 + (self.s.frame - FRAME_attak1_1);
                dir[0]       = 0;
                dir[1]       = self.s.angles[1];
                dir[2]       = 0;
                Math3D.AngleVectors(dir, forward, right, null);
                Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[flash_number], forward, right, start);
                if (self.enemy != null)
                {
                    Math3D.VectorCopy(self.enemy.s.origin, vec);
                    Math3D.VectorMA(vec, 0, self.enemy.velocity, vec);
                    vec[2] += self.enemy.viewheight;
                    Math3D.VectorSubtract(vec, start, forward);
                    Math3D.VectorNormalize(forward);
                }

                Monster.Monster_fire_bullet(self, start, forward, 6, 4, Defines.DEFAULT_BULLET_HSPREAD, Defines.DEFAULT_BULLET_VSPREAD, flash_number);
                return(true);
            }
Beispiel #3
0
            public override bool Think(edict_t self)
            {
                float[] start   = new float[] { 0, 0, 0 };
                float[] forward = new float[] { 0, 0, 0 }, right = new float[] { 0, 0, 0 };
                float[] end     = new float[] { 0, 0, 0 };
                float[] dir     = new float[] { 0, 0, 0 };
                int     effect;

                if ((self.s.frame == FRAME_attack9) || (self.s.frame == FRAME_attack12))
                {
                    effect = Defines.EF_BLASTER;
                }
                else if ((self.s.frame == FRAME_attack19) || (self.s.frame == FRAME_attack22) || (self.s.frame == FRAME_attack25) || (self.s.frame == FRAME_attack28))
                {
                    effect = Defines.EF_HYPERBLASTER;
                }
                else
                {
                    effect = 0;
                }
                Math3D.AngleVectors(self.s.angles, forward, right, null);
                Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[Defines.MZ2_MEDIC_BLASTER_1], forward, right, start);
                Math3D.VectorCopy(self.enemy.s.origin, end);
                end[2] += self.enemy.viewheight;
                Math3D.VectorSubtract(end, start, dir);
                Monster.Monster_fire_blaster(self, start, dir, 2, 1000, Defines.MZ2_MEDIC_BLASTER_1, effect);
                return(true);
            }
Beispiel #4
0
            public override bool Think(edict_t self)
            {
                float[] start   = new float[] { 0, 0, 0 };
                float[] forward = new float[] { 0, 0, 0 }, right = new float[] { 0, 0, 0 };
                float[] aim     = new float[] { 0, 0, 0 };
                int     flash_number;

                if (self.s.frame == FRAME_attak105)
                {
                    flash_number = Defines.MZ2_GUNNER_GRENADE_1;
                }
                else if (self.s.frame == FRAME_attak108)
                {
                    flash_number = Defines.MZ2_GUNNER_GRENADE_2;
                }
                else if (self.s.frame == FRAME_attak111)
                {
                    flash_number = Defines.MZ2_GUNNER_GRENADE_3;
                }
                else
                {
                    flash_number = Defines.MZ2_GUNNER_GRENADE_4;
                }
                Math3D.AngleVectors(self.s.angles, forward, right, null);
                Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[flash_number], forward, right, start);
                Math3D.VectorCopy(forward, aim);
                Monster.Monster_fire_grenade(self, start, aim, 50, 600, flash_number);
                return(true);
            }
Beispiel #5
0
 public override bool Think(edict_t self)
 {
     float[] forward = new float[] { 0, 0, 0 }, right = new float[] { 0, 0, 0 };
     float[] start   = new float[] { 0, 0, 0 };
     float[] dir     = new float[] { 0, 0, 0 };
     float[] vec     = new float[] { 0, 0, 0 };
     Math3D.AngleVectors(self.s.angles, forward, right, null);
     Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[Defines.MZ2_BOSS2_ROCKET_1], forward, right, start);
     Math3D.VectorCopy(self.enemy.s.origin, vec);
     vec[2] += self.enemy.viewheight;
     Math3D.VectorSubtract(vec, start, dir);
     Math3D.VectorNormalize(dir);
     Monster.Monster_fire_rocket(self, start, dir, 50, 500, Defines.MZ2_BOSS2_ROCKET_1);
     Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[Defines.MZ2_BOSS2_ROCKET_2], forward, right, start);
     Math3D.VectorCopy(self.enemy.s.origin, vec);
     vec[2] += self.enemy.viewheight;
     Math3D.VectorSubtract(vec, start, dir);
     Math3D.VectorNormalize(dir);
     Monster.Monster_fire_rocket(self, start, dir, 50, 500, Defines.MZ2_BOSS2_ROCKET_2);
     Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[Defines.MZ2_BOSS2_ROCKET_3], forward, right, start);
     Math3D.VectorCopy(self.enemy.s.origin, vec);
     vec[2] += self.enemy.viewheight;
     Math3D.VectorSubtract(vec, start, dir);
     Math3D.VectorNormalize(dir);
     Monster.Monster_fire_rocket(self, start, dir, 50, 500, Defines.MZ2_BOSS2_ROCKET_3);
     Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[Defines.MZ2_BOSS2_ROCKET_4], forward, right, start);
     Math3D.VectorCopy(self.enemy.s.origin, vec);
     vec[2] += self.enemy.viewheight;
     Math3D.VectorSubtract(vec, start, dir);
     Math3D.VectorNormalize(dir);
     Monster.Monster_fire_rocket(self, start, dir, 50, 500, Defines.MZ2_BOSS2_ROCKET_4);
     return(true);
 }
Beispiel #6
0
 public override bool Think(edict_t self)
 {
     float[] start   = new float[] { 0, 0, 0 };
     float[] dir     = new float[] { 0, 0, 0 };
     float[] forward = new float[] { 0, 0, 0 }, right = new float[] { 0, 0, 0 };
     Math3D.AngleVectors(self.s.angles, forward, right, null);
     Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[Defines.MZ2_GLADIATOR_RAILGUN_1], forward, right, start);
     Math3D.VectorSubtract(self.pos1, start, dir);
     Math3D.VectorNormalize(dir);
     Monster.Monster_fire_railgun(self, start, dir, 50, 100, Defines.MZ2_GLADIATOR_RAILGUN_1);
     return(true);
 }
Beispiel #7
0
            public override bool Think(edict_t self)
            {
                float[] offset = new float[] { 0, 0, 0 }, start = new float[] { 0, 0, 0 }, f = new float[] { 0, 0, 0 }, r = new float[] { 0, 0, 0 }, end = new float[] { 0, 0, 0 }, dir = new float[] { 0, 0, 0 };
                trace_t tr;
                int     damage;

                Math3D.AngleVectors(self.s.angles, f, r, null);
                Math3D.VectorSet(offset, 24, 0, 6);
                Math3D.G_ProjectSource(self.s.origin, offset, f, r, start);
                Math3D.VectorCopy(self.enemy.s.origin, end);
                if (!Parasite_drain_attack_ok(start, end))
                {
                    end[2] = self.enemy.s.origin[2] + self.enemy.maxs[2] - 8;
                    if (!Parasite_drain_attack_ok(start, end))
                    {
                        end[2] = self.enemy.s.origin[2] + self.enemy.mins[2] + 8;
                        if (!Parasite_drain_attack_ok(start, end))
                        {
                            return(true);
                        }
                    }
                }

                Math3D.VectorCopy(self.enemy.s.origin, end);
                tr = GameBase.gi.Trace(start, null, null, end, self, Defines.MASK_SHOT);
                if (tr.ent != self.enemy)
                {
                    return(true);
                }
                if (self.s.frame == FRAME_drain03)
                {
                    damage = 5;
                    GameBase.gi.Sound(self.enemy, Defines.CHAN_AUTO, sound_impact, 1, Defines.ATTN_NORM, 0);
                }
                else
                {
                    if (self.s.frame == FRAME_drain04)
                    {
                        GameBase.gi.Sound(self, Defines.CHAN_WEAPON, sound_suck, 1, Defines.ATTN_NORM, 0);
                    }
                    damage = 2;
                }

                GameBase.gi.WriteByte(Defines.svc_temp_entity);
                GameBase.gi.WriteByte(Defines.TE_PARASITE_ATTACK);
                GameBase.gi.WriteShort(self.index);
                GameBase.gi.WritePosition(start);
                GameBase.gi.WritePosition(end);
                GameBase.gi.Multicast(self.s.origin, Defines.MULTICAST_PVS);
                Math3D.VectorSubtract(start, end, dir);
                GameCombat.T_Damage(self.enemy, self, self, dir, self.enemy.s.origin, Globals.vec3_origin, damage, 0, Defines.DAMAGE_NO_KNOCKBACK, Defines.MOD_UNKNOWN);
                return(true);
            }
Beispiel #8
0
 public override bool Think(edict_t self)
 {
     float[] forward = new float[] { 0, 0, 0 }, right = new float[] { 0, 0, 0 }, target = new float[] { 0, 0, 0 };
     float[] start   = new float[] { 0, 0, 0 };
     Math3D.AngleVectors(self.s.angles, forward, right, null);
     Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[Defines.MZ2_JORG_MACHINEGUN_L1], forward, right, start);
     Math3D.VectorMA(self.enemy.s.origin, -0.2F, self.enemy.velocity, target);
     target[2] += self.enemy.viewheight;
     Math3D.VectorSubtract(target, start, forward);
     Math3D.VectorNormalize(forward);
     Monster.Monster_fire_bullet(self, start, forward, 6, 4, Defines.DEFAULT_BULLET_HSPREAD, Defines.DEFAULT_BULLET_VSPREAD, Defines.MZ2_JORG_MACHINEGUN_L1);
     return(true);
 }
Beispiel #9
0
 public override bool Think(edict_t self)
 {
     float[] forward = new float[] { 0, 0, 0 }, right = new float[] { 0, 0, 0 };
     float[] start   = new float[] { 0, 0, 0 };
     float[] dir     = new float[] { 0, 0, 0 };
     float[] vec     = new float[] { 0, 0, 0 };
     Math3D.AngleVectors(self.s.angles, forward, right, null);
     Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[Defines.MZ2_JORG_BFG_1], forward, right, start);
     Math3D.VectorCopy(self.enemy.s.origin, vec);
     vec[2] += self.enemy.viewheight;
     Math3D.VectorSubtract(vec, start, dir);
     Math3D.VectorNormalize(dir);
     GameBase.gi.Sound(self, Defines.CHAN_VOICE, sound_attack2, 1, Defines.ATTN_NORM, 0);
     Monster.Monster_fire_bfg(self, start, dir, 50, 300, 100, 200, Defines.MZ2_JORG_BFG_1);
     return(true);
 }
Beispiel #10
0
            public override bool Think(edict_t self)
            {
                float[] start   = new float[] { 0, 0, 0 };
                float[] forward = new float[] { 0, 0, 0 }, right = new float[] { 0, 0, 0 };
                float[] target  = new float[] { 0, 0, 0 };
                float[] aim     = new float[] { 0, 0, 0 };
                int     flash_number;

                flash_number = Defines.MZ2_GUNNER_MACHINEGUN_1 + (self.s.frame - FRAME_attak216);
                Math3D.AngleVectors(self.s.angles, forward, right, null);
                Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[flash_number], forward, right, start);
                Math3D.VectorCopy(self.enemy.s.origin, target);
                Math3D.VectorMA(target, -0.2F, self.enemy.velocity, target);
                target[2] += self.enemy.viewheight;
                Math3D.VectorSubtract(target, start, aim);
                Math3D.VectorNormalize(aim);
                Monster.Monster_fire_bullet(self, start, aim, 3, 4, Defines.DEFAULT_BULLET_HSPREAD, Defines.DEFAULT_BULLET_VSPREAD, flash_number);
                return(true);
            }
Beispiel #11
0
 public override bool Think(edict_t self)
 {
     float[] forward = new float[] { 0, 0, 0 }, right = new float[] { 0, 0, 0 };
     float[] origin  = new float[] { 0, 0, 0 };
     float[] dir     = new float[] { 0, 0, 0 };
     float[] offset  = new float[] { 0, 0, 0 };
     Math3D.VectorSubtract(self.enemy.s.origin, self.s.origin, dir);
     Math3D.AngleVectors(self.s.angles, forward, right, null);
     Math3D.VectorSet(offset, 18.5F, -0.9F, 10F);
     Math3D.G_ProjectSource(self.s.origin, offset, forward, right, origin);
     GameBase.gi.Sound(self, Defines.CHAN_WEAPON, sound_attack2, 1, Defines.ATTN_NORM, 0);
     GameBase.gi.WriteByte(Defines.svc_temp_entity);
     GameBase.gi.WriteByte(Defines.TE_SPLASH);
     GameBase.gi.WriteByte(32);
     GameBase.gi.WritePosition(origin);
     GameBase.gi.WriteDir(dir);
     GameBase.gi.WriteByte(1);
     GameBase.gi.Multicast(origin, Defines.MULTICAST_PVS);
     GameCombat.T_Damage(self.enemy, self, self, dir, self.enemy.s.origin, Globals.vec3_origin, 5 + Lib.Rand() % 6, -10, Defines.DAMAGE_ENERGY, Defines.MOD_UNKNOWN);
     return(true);
 }
Beispiel #12
0
        static void Flyer_fire(edict_t self, int flash_number)
        {
            float[] start   = new float[] { 0, 0, 0 };
            float[] forward = new float[] { 0, 0, 0 }, right = new float[] { 0, 0, 0 };
            float[] end     = new float[] { 0, 0, 0 };
            float[] dir     = new float[] { 0, 0, 0 };
            int     effect;

            if ((self.s.frame == FRAME_attak204) || (self.s.frame == FRAME_attak207) || (self.s.frame == FRAME_attak210))
            {
                effect = Defines.EF_HYPERBLASTER;
            }
            else
            {
                effect = 0;
            }
            Math3D.AngleVectors(self.s.angles, forward, right, null);
            Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[flash_number], forward, right, start);
            Math3D.VectorCopy(self.enemy.s.origin, end);
            end[2] += self.enemy.viewheight;
            Math3D.VectorSubtract(end, start, dir);
            Monster.Monster_fire_blaster(self, start, dir, 1, 1000, flash_number, effect);
        }
Beispiel #13
0
            public override bool Think(edict_t self)
            {
                float[] start   = new float[] { 0, 0, 0 }, target = new float[] { 0, 0, 0 };
                float[] forward = new float[] { 0, 0, 0 }, right = new float[] { 0, 0, 0 };
                float[] vec     = new float[] { 0, 0, 0 };
                int     flash_number;

                if (self.s.frame == FRAME_attak111)
                {
                    flash_number = Defines.MZ2_INFANTRY_MACHINEGUN_1;
                    Math3D.AngleVectors(self.s.angles, forward, right, null);
                    Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[flash_number], forward, right, start);
                    if (self.enemy != null)
                    {
                        Math3D.VectorMA(self.enemy.s.origin, -0.2F, self.enemy.velocity, target);
                        target[2] += self.enemy.viewheight;
                        Math3D.VectorSubtract(target, start, forward);
                        Math3D.VectorNormalize(forward);
                    }
                    else
                    {
                        Math3D.AngleVectors(self.s.angles, forward, right, null);
                    }
                }
                else
                {
                    flash_number = Defines.MZ2_INFANTRY_MACHINEGUN_2 + (self.s.frame - FRAME_death211);
                    Math3D.AngleVectors(self.s.angles, forward, right, null);
                    Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[flash_number], forward, right, start);
                    Math3D.VectorSubtract(self.s.angles, aimangles[flash_number - Defines.MZ2_INFANTRY_MACHINEGUN_2], vec);
                    Math3D.AngleVectors(vec, forward, null, null);
                }

                Monster.Monster_fire_bullet(self, start, forward, 3, 4, Defines.DEFAULT_BULLET_HSPREAD, Defines.DEFAULT_BULLET_VSPREAD, flash_number);
                return(true);
            }
Beispiel #14
0
            public override bool Think(edict_t self)
            {
                float[] offset = new float[] { 0, 0, 0 }, start = new float[] { 0, 0, 0 }, end = new float[] { 0, 0, 0 }, f = new float[] { 0, 0, 0 }, r = new float[] { 0, 0, 0 };
                trace_t tr;

                float[] dir = new float[] { 0, 0, 0 }, angles = new float[] { 0, 0, 0 };
                float   distance;

                if (!self.enemy.inuse)
                {
                    return(true);
                }
                Math3D.AngleVectors(self.s.angles, f, r, null);
                Math3D.VectorCopy(medic_cable_offsets[self.s.frame - FRAME_attack42], offset);
                Math3D.G_ProjectSource(self.s.origin, offset, f, r, start);
                Math3D.VectorSubtract(start, self.enemy.s.origin, dir);
                distance = Math3D.VectorLength(dir);
                if (distance > 256)
                {
                    return(true);
                }
                Math3D.Vectoangles(dir, angles);
                if (angles[0] < -180)
                {
                    angles[0] += 360;
                }
                if (Math.Abs(angles[0]) > 45)
                {
                    return(true);
                }
                tr = GameBase.gi.Trace(start, null, null, self.enemy.s.origin, self, Defines.MASK_SHOT);
                if (tr.fraction != 1 && tr.ent != self.enemy)
                {
                    return(true);
                }
                if (self.s.frame == FRAME_attack43)
                {
                    GameBase.gi.Sound(self.enemy, Defines.CHAN_AUTO, sound_hook_hit, 1, Defines.ATTN_NORM, 0);
                    self.enemy.monsterinfo.aiflags |= Defines.AI_RESURRECTING;
                }
                else if (self.s.frame == FRAME_attack50)
                {
                    self.enemy.spawnflags          = 0;
                    self.enemy.monsterinfo.aiflags = 0;
                    self.enemy.target       = null;
                    self.enemy.targetname   = null;
                    self.enemy.combattarget = null;
                    self.enemy.deathtarget  = null;
                    self.enemy.owner        = self;
                    GameSpawn.ED_CallSpawn(self.enemy);
                    self.enemy.owner = null;
                    if (self.enemy.think != null)
                    {
                        self.enemy.nextthink = GameBase.level.time;
                        self.enemy.think.Think(self.enemy);
                    }

                    self.enemy.monsterinfo.aiflags |= Defines.AI_RESURRECTING;
                    if (self.oldenemy != null && self.oldenemy.client != null)
                    {
                        self.enemy.enemy = self.oldenemy;
                        GameUtil.FoundTarget(self.enemy);
                    }
                }
                else
                {
                    if (self.s.frame == FRAME_attack44)
                    {
                        GameBase.gi.Sound(self, Defines.CHAN_WEAPON, sound_hook_heal, 1, Defines.ATTN_NORM, 0);
                    }
                }

                Math3D.VectorMA(start, 8, f, start);
                Math3D.VectorCopy(self.enemy.s.origin, end);
                end[2] = self.enemy.absmin[2] + self.enemy.size[2] / 2;
                GameBase.gi.WriteByte(Defines.svc_temp_entity);
                GameBase.gi.WriteByte(Defines.TE_MEDIC_CABLE_ATTACK);
                GameBase.gi.WriteShort(self.index);
                GameBase.gi.WritePosition(start);
                GameBase.gi.WritePosition(end);
                GameBase.gi.Multicast(self.s.origin, Defines.MULTICAST_PVS);
                return(true);
            }
Beispiel #15
0
            public override void Ai(edict_t self, float dist)
            {
                float[] v = new float[] { 0, 0, 0 };
                edict_t tempgoal;
                edict_t save;
                bool    new1;
                edict_t marker;
                float   d1, d2;
                trace_t tr;

                float[] v_forward = new float[] { 0, 0, 0 }, v_right = new float[] { 0, 0, 0 };
                float   left, center, right;

                float[] left_target = new float[] { 0, 0, 0 }, right_target = new float[] { 0, 0, 0 };
                if ((self.monsterinfo.aiflags & Defines.AI_COMBAT_POINT) != 0)
                {
                    M.M_MoveToGoal(self, dist);
                    return;
                }

                if ((self.monsterinfo.aiflags & Defines.AI_SOUND_TARGET) != 0)
                {
                    Math3D.VectorSubtract(self.s.origin, self.enemy.s.origin, v);
                    if (Math3D.VectorLength(v) < 64)
                    {
                        self.monsterinfo.stand.Think(self);
                        self.spawnflags &= ~1;
                        self.enemy       = null;
                    }
                    else
                    {
                        M.M_MoveToGoal(self, dist);
                    }
                    if (!GameUtil.FindTarget(self))
                    {
                        return;
                    }
                }

                if (Ai_checkattack(self, dist))
                {
                    return;
                }
                if (self.monsterinfo.attack_state == Defines.AS_SLIDING)
                {
                    Ai_run_slide(self, dist);
                    return;
                }

                if (enemy_vis)
                {
                    M.M_MoveToGoal(self, dist);
                    self.monsterinfo.aiflags &= ~Defines.AI_LOST_SIGHT;
                    Math3D.VectorCopy(self.enemy.s.origin, self.monsterinfo.last_sighting);
                    self.monsterinfo.trail_time = GameBase.level.time;
                    return;
                }

                if (GameBase.coop.value != 0)
                {
                    if (GameUtil.FindTarget(self))
                    {
                        return;
                    }
                }

                if ((self.monsterinfo.search_time != 0) && (GameBase.level.time > (self.monsterinfo.search_time + 20)))
                {
                    M.M_MoveToGoal(self, dist);
                    self.monsterinfo.search_time = 0;
                    return;
                }

                save            = self.goalentity;
                tempgoal        = GameUtil.G_Spawn();
                self.goalentity = tempgoal;
                new1            = false;
                if (0 == (self.monsterinfo.aiflags & Defines.AI_LOST_SIGHT))
                {
                    self.monsterinfo.aiflags |= (Defines.AI_LOST_SIGHT | Defines.AI_PURSUIT_LAST_SEEN);
                    self.monsterinfo.aiflags &= ~(Defines.AI_PURSUE_NEXT | Defines.AI_PURSUE_TEMP);
                    new1 = true;
                }

                if ((self.monsterinfo.aiflags & Defines.AI_PURSUE_NEXT) != 0)
                {
                    self.monsterinfo.aiflags    &= ~Defines.AI_PURSUE_NEXT;
                    self.monsterinfo.search_time = GameBase.level.time + 5;
                    if ((self.monsterinfo.aiflags & Defines.AI_PURSUE_TEMP) != 0)
                    {
                        self.monsterinfo.aiflags &= ~Defines.AI_PURSUE_TEMP;
                        marker = null;
                        Math3D.VectorCopy(self.monsterinfo.saved_goal, self.monsterinfo.last_sighting);
                        new1 = true;
                    }
                    else if ((self.monsterinfo.aiflags & Defines.AI_PURSUIT_LAST_SEEN) != 0)
                    {
                        self.monsterinfo.aiflags &= ~Defines.AI_PURSUIT_LAST_SEEN;
                        marker = PlayerTrail.PickFirst(self);
                    }
                    else
                    {
                        marker = PlayerTrail.PickNext(self);
                    }

                    if (marker != null)
                    {
                        Math3D.VectorCopy(marker.s.origin, self.monsterinfo.last_sighting);
                        self.monsterinfo.trail_time = marker.timestamp;
                        self.s.angles[Defines.YAW]  = self.ideal_yaw = marker.s.angles[Defines.YAW];
                        new1 = true;
                    }
                }

                Math3D.VectorSubtract(self.s.origin, self.monsterinfo.last_sighting, v);
                d1 = Math3D.VectorLength(v);
                if (d1 <= dist)
                {
                    self.monsterinfo.aiflags |= Defines.AI_PURSUE_NEXT;
                    dist = d1;
                }

                Math3D.VectorCopy(self.monsterinfo.last_sighting, self.goalentity.s.origin);
                if (new1)
                {
                    tr = GameBase.gi.Trace(self.s.origin, self.mins, self.maxs, self.monsterinfo.last_sighting, self, Defines.MASK_PLAYERSOLID);
                    if (tr.fraction < 1)
                    {
                        Math3D.VectorSubtract(self.goalentity.s.origin, self.s.origin, v);
                        d1     = Math3D.VectorLength(v);
                        center = tr.fraction;
                        d2     = d1 * ((center + 1) / 2);
                        self.s.angles[Defines.YAW] = self.ideal_yaw = Math3D.Vectoyaw(v);
                        Math3D.AngleVectors(self.s.angles, v_forward, v_right, null);
                        Math3D.VectorSet(v, d2, -16, 0);
                        Math3D.G_ProjectSource(self.s.origin, v, v_forward, v_right, left_target);
                        tr   = GameBase.gi.Trace(self.s.origin, self.mins, self.maxs, left_target, self, Defines.MASK_PLAYERSOLID);
                        left = tr.fraction;
                        Math3D.VectorSet(v, d2, 16, 0);
                        Math3D.G_ProjectSource(self.s.origin, v, v_forward, v_right, right_target);
                        tr     = GameBase.gi.Trace(self.s.origin, self.mins, self.maxs, right_target, self, Defines.MASK_PLAYERSOLID);
                        right  = tr.fraction;
                        center = (d1 * center) / d2;
                        if (left >= center && left > right)
                        {
                            if (left < 1)
                            {
                                Math3D.VectorSet(v, d2 * left * 0.5F, -16F, 0F);
                                Math3D.G_ProjectSource(self.s.origin, v, v_forward, v_right, left_target);
                            }

                            Math3D.VectorCopy(self.monsterinfo.last_sighting, self.monsterinfo.saved_goal);
                            self.monsterinfo.aiflags |= Defines.AI_PURSUE_TEMP;
                            Math3D.VectorCopy(left_target, self.goalentity.s.origin);
                            Math3D.VectorCopy(left_target, self.monsterinfo.last_sighting);
                            Math3D.VectorSubtract(self.goalentity.s.origin, self.s.origin, v);
                            self.s.angles[Defines.YAW] = self.ideal_yaw = Math3D.Vectoyaw(v);
                        }
                        else if (right >= center && right > left)
                        {
                            if (right < 1)
                            {
                                Math3D.VectorSet(v, d2 * right * 0.5F, 16F, 0F);
                                Math3D.G_ProjectSource(self.s.origin, v, v_forward, v_right, right_target);
                            }

                            Math3D.VectorCopy(self.monsterinfo.last_sighting, self.monsterinfo.saved_goal);
                            self.monsterinfo.aiflags |= Defines.AI_PURSUE_TEMP;
                            Math3D.VectorCopy(right_target, self.goalentity.s.origin);
                            Math3D.VectorCopy(right_target, self.monsterinfo.last_sighting);
                            Math3D.VectorSubtract(self.goalentity.s.origin, self.s.origin, v);
                            self.s.angles[Defines.YAW] = self.ideal_yaw = Math3D.Vectoyaw(v);
                        }
                    }
                }

                M.M_MoveToGoal(self, dist);
                GameUtil.G_FreeEdict(tempgoal);
                if (self != null)
                {
                    self.goalentity = save;
                }
            }