]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/monsters/sv_monsters.qc
Merge branch 'master' into TimePath/unified_weapons
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / monsters / sv_monsters.qc
index d4e1691f0ce1a1dd5ba73880bb9c709f7bedb7cf..8b05f781d2e395b44a3893474fdc6788501dd40e 100644 (file)
@@ -39,6 +39,7 @@ void monster_dropitem()
 
        vector org = self.origin + ((self.mins + self.maxs) * 0.5);
        entity e = spawn();
 
        vector org = self.origin + ((self.mins + self.maxs) * 0.5);
        entity e = spawn();
+       e.spawnfunc_checked = true;
 
        e.monster_loot = self.monster_loot;
 
 
        e.monster_loot = self.monster_loot;
 
@@ -49,7 +50,7 @@ void monster_dropitem()
        {
                setself(e);
                e.noalign = true;
        {
                setself(e);
                e.noalign = true;
-               e.monster_loot();
+               e.monster_loot(e);
                e.gravity = 1;
                e.movetype = MOVETYPE_TOSS;
                e.reset = SUB_Remove;
                e.gravity = 1;
                e.movetype = MOVETYPE_TOSS;
                e.reset = SUB_Remove;
@@ -118,7 +119,7 @@ bool Monster_ValidTarget(entity mon, entity player)
                makevectors (mon.angles);
                dot = normalize (player.origin - mon.origin) * v_forward;
 
                makevectors (mon.angles);
                dot = normalize (player.origin - mon.origin) * v_forward;
 
-               if(dot <= 0.3) { return false; }
+               if(dot <= autocvar_g_monsters_target_infront_range) { return false; }
        }
 
        return true; // this target is valid!
        }
 
        return true; // this target is valid!
@@ -181,11 +182,11 @@ void monster_setupcolors(entity mon)
 void monster_changeteam(entity ent, float newteam)
 {
        if(!teamplay) { return; }
 void monster_changeteam(entity ent, float newteam)
 {
        if(!teamplay) { return; }
-       
+
        ent.team = newteam;
        ent.monster_attack = true; // new team, activate attacking
        monster_setupcolors(ent);
        ent.team = newteam;
        ent.monster_attack = true; // new team, activate attacking
        monster_setupcolors(ent);
-       
+
        if(ent.sprite)
        {
                WaypointSprite_UpdateTeamRadar(ent.sprite, RADARICON_DANGER, ((newteam) ? Team_ColorRGB(newteam) : '1 0 0'));
        if(ent.sprite)
        {
                WaypointSprite_UpdateTeamRadar(ent.sprite, RADARICON_DANGER, ((newteam) ? Team_ColorRGB(newteam) : '1 0 0'));
@@ -267,7 +268,7 @@ void Monster_Sound_Precache(string f)
 
 void Monster_Sounds_Precache()
 {SELFPARAM();
 
 void Monster_Sounds_Precache()
 {SELFPARAM();
-       string m = (get_monsterinfo(self.monsterid)).model;
+       string m = (get_monsterinfo(self.monsterid)).m_model.model_str();
        float globhandle, n, i;
        string f;
 
        float globhandle, n, i;
        string f;
 
@@ -434,7 +435,7 @@ void Monster_Attack_Check(entity e, entity targ)
 
        if(targ_vlen <= e.attack_range)
        {
 
        if(targ_vlen <= e.attack_range)
        {
-               float attack_success = e.monster_attackfunc(MONSTER_ATTACK_MELEE);
+               float attack_success = e.monster_attackfunc(MONSTER_ATTACK_MELEE, targ);
                if(attack_success == 1)
                        Monster_Sound(monstersound_melee, 0, false, CH_VOICE);
                else if(attack_success > 0)
                if(attack_success == 1)
                        Monster_Sound(monstersound_melee, 0, false, CH_VOICE);
                else if(attack_success > 0)
@@ -443,7 +444,7 @@ void Monster_Attack_Check(entity e, entity targ)
 
        if(targ_vlen > e.attack_range)
        {
 
        if(targ_vlen > e.attack_range)
        {
-               float attack_success = e.monster_attackfunc(MONSTER_ATTACK_RANGED);
+               float attack_success = e.monster_attackfunc(MONSTER_ATTACK_RANGED, targ);
                if(attack_success == 1)
                        Monster_Sound(monstersound_melee, 0, false, CH_VOICE);
                else if(attack_success > 0)
                if(attack_success == 1)
                        Monster_Sound(monstersound_melee, 0, false, CH_VOICE);
                else if(attack_success > 0)
@@ -471,7 +472,8 @@ void Monster_UpdateModel()
        self.anim_die2   = animfixfps(self, '9 1 0.01', '0 0 0');*/
 
        // then get the real values
        self.anim_die2   = animfixfps(self, '9 1 0.01', '0 0 0');*/
 
        // then get the real values
-       MON_ACTION(self.monsterid, MR_ANIM);
+       Monster mon = get_monsterinfo(self.monsterid);
+       mon.mr_anim(mon);
 }
 
 void Monster_Touch()
 }
 
 void Monster_Touch()
@@ -538,7 +540,7 @@ void Monster_Dead_Fade()
                setorigin(self, self.pos1);
                self.angles = self.pos2;
                self.health = self.max_health;
                setorigin(self, self.pos1);
                self.angles = self.pos2;
                self.health = self.max_health;
-               setmodel(self, "null");
+               setmodel(self, MDL_Null);
        }
        else
        {
        }
        else
        {
@@ -831,7 +833,7 @@ void Monster_Move(float runspeed, float walkspeed, float stpspeed)
                                self.moveto = WarpZone_RefSys_TransformOrigin(self.enemy, self, (0.5 * (self.enemy.absmin + self.enemy.absmax)));
                                self.monster_moveto = '0 0 0';
                                self.monster_face = '0 0 0';
                                self.moveto = WarpZone_RefSys_TransformOrigin(self.enemy, self, (0.5 * (self.enemy.absmin + self.enemy.absmax)));
                                self.monster_moveto = '0 0 0';
                                self.monster_face = '0 0 0';
-                               
+
                                self.pass_distance = vlen((('1 0 0' * self.enemy.origin_x) + ('0 1 0' * self.enemy.origin_y)) - (('1 0 0' *  self.origin_x) + ('0 1 0' *  self.origin_y)));
                                Monster_Sound(monstersound_sight, 0, false, CH_VOICE);
                        }
                                self.pass_distance = vlen((('1 0 0' * self.enemy.origin_x) + ('0 1 0' * self.enemy.origin_y)) - (('1 0 0' *  self.origin_x) + ('0 1 0' *  self.origin_y)));
                                Monster_Sound(monstersound_sight, 0, false, CH_VOICE);
                        }
@@ -1035,9 +1037,10 @@ void Monster_Dead(entity attacker, float gibbed)
        if(!((self.flags & FL_FLY) || (self.flags & FL_SWIM)))
                self.velocity = '0 0 0';
 
        if(!((self.flags & FL_FLY) || (self.flags & FL_SWIM)))
                self.velocity = '0 0 0';
 
-       CSQCModel_UnlinkEntity();
+       CSQCModel_UnlinkEntity(self);
 
 
-       MON_ACTION(self.monsterid, MR_DEATH);
+       Monster mon = get_monsterinfo(self.monsterid);
+       mon.mr_death(mon);
 
        if(self.candrop && self.weapon)
                W_ThrowNewWeapon(self, self.weapon, 0, self.origin, randomvec() * 150 + '0 0 325');
 
        if(self.candrop && self.weapon)
                W_ThrowNewWeapon(self, self.weapon, 0, self.origin, randomvec() * 150 + '0 0 325');
@@ -1045,7 +1048,7 @@ void Monster_Dead(entity attacker, float gibbed)
 
 void Monster_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
 {SELFPARAM();
 
 void Monster_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
 {SELFPARAM();
-       if((self.spawnflags & MONSTERFLAG_INVINCIBLE) && deathtype != DEATH_KILL)
+       if((self.spawnflags & MONSTERFLAG_INVINCIBLE) && deathtype != DEATH_KILL && !ITEM_DAMAGE_NEEDKILL(deathtype))
                return;
 
        if(self.frozen && deathtype != DEATH_KILL && deathtype != DEATH_NADE_ICE_FREEZE)
                return;
 
        if(self.frozen && deathtype != DEATH_KILL && deathtype != DEATH_NADE_ICE_FREEZE)
@@ -1070,7 +1073,8 @@ void Monster_Damage(entity inflictor, entity attacker, float damage, int deathty
        damage_take = take;
        frag_attacker = attacker;
        frag_deathtype = deathtype;
        damage_take = take;
        frag_attacker = attacker;
        frag_deathtype = deathtype;
-       MON_ACTION(self.monsterid, MR_PAIN);
+       Monster mon = get_monsterinfo(self.monsterid);
+       mon.mr_pain(mon);
        take = damage_take;
 
        if(take)
        take = damage_take;
 
        if(take)
@@ -1085,7 +1089,7 @@ void Monster_Damage(entity inflictor, entity attacker, float damage, int deathty
        self.dmg_time = time;
 
        if(sound_allowed(MSG_BROADCAST, attacker) && deathtype != DEATH_DROWN)
        self.dmg_time = time;
 
        if(sound_allowed(MSG_BROADCAST, attacker) && deathtype != DEATH_DROWN)
-               spamsound (self, CH_PAIN, "misc/bodyimpact1.wav", VOL_BASE, ATTEN_NORM);  // FIXME: PLACEHOLDER
+               spamsound (self, CH_PAIN, SND(BODYIMPACT1), VOL_BASE, ATTEN_NORM);  // FIXME: PLACEHOLDER
 
        self.velocity += force * self.damageforcescale;
 
 
        self.velocity += force * self.damageforcescale;
 
@@ -1140,22 +1144,22 @@ void Monster_Move_2D(float mspeed, float allow_jumpoff)
 
        float reverse = FALSE;
        vector a, b;
 
        float reverse = FALSE;
        vector a, b;
-       
+
        makevectors(self.angles);
        a = self.origin + '0 0 16';
        b = self.origin + '0 0 16' + v_forward * 32;
        makevectors(self.angles);
        a = self.origin + '0 0 16';
        b = self.origin + '0 0 16' + v_forward * 32;
-       
+
        traceline(a, b, MOVE_NORMAL, self);
        traceline(a, b, MOVE_NORMAL, self);
-       
+
        if(trace_fraction != 1.0)
        {
                reverse = TRUE;
        if(trace_fraction != 1.0)
        {
                reverse = TRUE;
-               
+
                if(trace_ent)
                if(IS_PLAYER(trace_ent) && !(trace_ent.items & IT_STRENGTH))
                        reverse = FALSE;
        }
                if(trace_ent)
                if(IS_PLAYER(trace_ent) && !(trace_ent.items & IT_STRENGTH))
                        reverse = FALSE;
        }
-       
+
        // TODO: fix this... tracing is broken if the floor is thin
        /*
        if(!allow_jumpoff)
        // TODO: fix this... tracing is broken if the floor is thin
        /*
        if(!allow_jumpoff)
@@ -1165,13 +1169,13 @@ void Monster_Move_2D(float mspeed, float allow_jumpoff)
                if(trace_fraction == 1.0)
                        reverse = TRUE;
        } */
                if(trace_fraction == 1.0)
                        reverse = TRUE;
        } */
-       
+
        if(reverse)
        {
                self.angles_y = anglemods(self.angles_y - 180);
                makevectors(self.angles);
        }
        if(reverse)
        {
                self.angles_y = anglemods(self.angles_y - 180);
                makevectors(self.angles);
        }
-       
+
        movelib_move_simple_gravity(v_forward, mspeed, 1);
 
        if(time > self.pain_finished)
        movelib_move_simple_gravity(v_forward, mspeed, 1);
 
        if(time > self.pain_finished)
@@ -1231,7 +1235,8 @@ void Monster_Think()
                return;
        }
 
                return;
        }
 
-       if(MON_ACTION(self.monsterid, MR_THINK))
+       Monster mon = get_monsterinfo(self.monsterid);
+       if(mon.mr_think(mon))
                Monster_Move(self.speed2, self.speed, self.stopspeed);
 
        Monster_Anim();
                Monster_Move(self.speed2, self.speed, self.stopspeed);
 
        Monster_Anim();
@@ -1241,7 +1246,8 @@ void Monster_Think()
 
 float Monster_Spawn_Setup()
 {SELFPARAM();
 
 float Monster_Spawn_Setup()
 {SELFPARAM();
-       MON_ACTION(self.monsterid, MR_SETUP);
+       Monster mon = get_monsterinfo(self.monsterid);
+       mon.mr_setup(mon);
 
        // ensure some basic needs are met
        if(!self.health) { self.health = 100; }
 
        // ensure some basic needs are met
        if(!self.health) { self.health = 100; }
@@ -1307,7 +1313,6 @@ bool Monster_Spawn(int mon_id)
 
        if(!autocvar_g_monsters) { Monster_Remove(self); return false; }
 
 
        if(!autocvar_g_monsters) { Monster_Remove(self); return false; }
 
-       self.mdl = mon.model;
        if(Monster_Appear_Check(self, mon_id)) { return true; } // return true so the monster isn't removed
 
        if(!self.monster_skill)
        if(Monster_Appear_Check(self, mon_id)) { return true; } // return true so the monster isn't removed
 
        if(!self.monster_skill)
@@ -1325,7 +1330,7 @@ bool Monster_Spawn(int mon_id)
        if(!(self.spawnflags & MONSTERFLAG_RESPAWNED)) // don't count re-spawning monsters either
                monsters_total += 1;
 
        if(!(self.spawnflags & MONSTERFLAG_RESPAWNED)) // don't count re-spawning monsters either
                monsters_total += 1;
 
-       setmodel(self, self.mdl);
+       setmodel(self, mon.m_model);
        self.flags                              = FL_MONSTER;
        self.classname                  = "monster";
        self.takedamage                 = DAMAGE_AIM;
        self.flags                              = FL_MONSTER;
        self.classname                  = "monster";
        self.takedamage                 = DAMAGE_AIM;
@@ -1361,7 +1366,7 @@ bool Monster_Spawn(int mon_id)
        self.monster_moveto             = '0 0 0';
        self.monster_face               = '0 0 0';
        self.dphitcontentsmask  = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_BOTCLIP | DPCONTENTS_MONSTERCLIP;
        self.monster_moveto             = '0 0 0';
        self.monster_face               = '0 0 0';
        self.dphitcontentsmask  = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_BOTCLIP | DPCONTENTS_MONSTERCLIP;
-       
+
        if(!self.scale) { self.scale = 1; }
        if(autocvar_g_monsters_edit) { self.grab = 1; }
        if(autocvar_g_fullbrightplayers) { self.effects |= EF_FULLBRIGHT; }
        if(!self.scale) { self.scale = 1; }
        if(autocvar_g_monsters_edit) { self.grab = 1; }
        if(autocvar_g_fullbrightplayers) { self.effects |= EF_FULLBRIGHT; }