]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Some more targeting cleanup (fixes monsters targeting invisible players after re...
authorMario <mario.mario@y7mail.com>
Fri, 8 Feb 2013 00:17:25 +0000 (11:17 +1100)
committerMario <mario.mario@y7mail.com>
Fri, 8 Feb 2013 00:17:25 +0000 (11:17 +1100)
qcsrc/server/monsters/lib/monsters.qc
qcsrc/server/mutators/gamemode_rts.qc
qcsrc/server/mutators/gamemode_rts.qh

index 5ca1ae56883838a2efe46a05ac19f20c3536108e..33a1e1efa588ef0445ad18ff547a0f645e2b1223 100644 (file)
@@ -231,7 +231,7 @@ void Monster_Fade ()
                self.nextthink = time + self.respawntime;
                setorigin(self, self.pos1);
                self.angles = self.pos2;
-               self.health = 0;
+               self.health = self.max_health; // TODO: check if resetting to max_health is wise here
                return;
        }
        self.think = SUB_Remove;
@@ -469,6 +469,9 @@ void monster_move(float runspeed, float walkspeed, float stopspeed, float manim_
        if(self.enemy.health <= 0 || (!autocvar_g_monsters_typefrag && self.enemy.BUTTON_CHAT))
                self.enemy = world;
                
+       if not(self.enemy.takedamage)
+               self.enemy = world;
+               
        if not(self.enemy)
                self.enemy = FindTarget(self);
                
@@ -619,7 +622,11 @@ void monsters_damage (entity inflictor, entity attacker, float damage, float dea
                self.target2 = "";
                SUB_UseTargets();
        
-               self.monster_die();     
+               self.monster_die();
+               
+               frag_attacker = attacker;
+               frag_target = self;
+               MUTATOR_CALLHOOK(MonsterDies);
        }
 }
 
@@ -639,14 +646,11 @@ void monster_hook_death()
                self.realowner.monstercount -= 1;
                
        totalspawned -= 1;
-       
-       MUTATOR_CALLHOOK(MonsterDies);
 }
 
 // used to hook into monster post spawn functions without a mutator
 void monster_hook_spawn()
 {
-       self.health *= monster_skill; // skill based monster health?
        self.max_health = self.health;
        
        if(teamplay && autocvar_g_monsters_teams)
@@ -683,11 +687,11 @@ float monster_initialize(string  net_name,
                return FALSE;
                
        // support for quake style removing monsters based on skill
-       if(autocvar_skill <= autocvar_g_monsters_skill_easy && (self.spawnflags & MONSTERSKILL_NOTEASY)) { return FALSE; }
-       else if(autocvar_skill == autocvar_g_monsters_skill_normal && (self.spawnflags & MONSTERSKILL_NOTMEDIUM)) { return FALSE; }
-       else if(autocvar_skill == autocvar_g_monsters_skill_hard && (self.spawnflags & MONSTERSKILL_NOTHARD)) { return FALSE; }
-       else if(autocvar_skill == autocvar_g_monsters_skill_insane && (self.spawnflags & MONSTERSKILL_NOTINSANE)) { return FALSE; }
-       else if(autocvar_skill >= autocvar_g_monsters_skill_nightmare && (self.spawnflags & MONSTERSKILL_NOTNIGHTMARE)) { return FALSE; }
+       if(monster_skill <= autocvar_g_monsters_skill_easy && (self.spawnflags & MONSTERSKILL_NOTEASY)) { return FALSE; }
+       if(monster_skill == autocvar_g_monsters_skill_normal && (self.spawnflags & MONSTERSKILL_NOTMEDIUM)) { return FALSE; }
+       if(monster_skill == autocvar_g_monsters_skill_hard && (self.spawnflags & MONSTERSKILL_NOTHARD)) { return FALSE; }
+       if(monster_skill == autocvar_g_monsters_skill_insane && (self.spawnflags & MONSTERSKILL_NOTINSANE)) { return FALSE; }
+       if(monster_skill >= autocvar_g_monsters_skill_nightmare && (self.spawnflags & MONSTERSKILL_NOTNIGHTMARE)) { return FALSE; }
 
        if(self.model == "")
        if(bodymodel == "")
index cd815b991da02bbf7ed4b46e0c4510dc0068df03..c9a570571d457338983ec39a48188f0ae9b2e862 100644 (file)
@@ -9,11 +9,47 @@ void spawnfunc_healing_tower()
        spawnfunc_turret_fusionreactor();
        self.classname = "healing_tower";
        self.target_range = 1000;
-       self.shot_dmg = 20;
+       self.shot_dmg = 30;
+}
+
+void rts_waypoint_think()
+{
+       float goalcount = 0;
+       entity e;
+       
+       self.nextthink = time + 0.1;
+       
+       for(e = world; (e = findentity(e, goalentity, self)); )
+       {
+               ++goalcount;
+       }
+       
+       if(goalcount < 1)
+       {
+               WaypointSprite_Kill(self.sprite);
+               remove(self);
+               return;
+       }
+}
+
+void Monster_LevelUp(entity e)
+{
+       if(self.level >= 5)
+               return; // max level is 5 for now
+       e.speed += 0.25;
+       e.max_health += 20;
+       e.health = e.max_health;
+       e.level += 1;
+       WaypointSprite_UpdateHealth(e.sprite, e.health);
 }
 
 MUTATOR_HOOKFUNCTION(rts_PlayerSpawn)
 {
+       if(self.rts_viewangle)
+               self.angles_x = self.rts_viewangle;
+       else
+               self.angles_x = 30;
+               
        self.effects |= EF_NODRAW;
        self.oldorigin = self.origin;
        self.monster_attack = FALSE;
@@ -21,7 +57,6 @@ MUTATOR_HOOKFUNCTION(rts_PlayerSpawn)
        self.takedamage = DAMAGE_NO;
        self.flags |= FL_NOTARGET;
        self.movetype = MOVETYPE_NOCLIP;
-       self.angles_x = 30;
        stuffcmd(self, "cl_cmd settemp cl_prydoncursor 1\n");
        return FALSE;
 }
@@ -57,28 +92,20 @@ MUTATOR_HOOKFUNCTION(rts_PlayerThink)
                        self.oldorigin_z -= 50;
                        break;
        }
-       self.hasweapon_complain_spam = time + 99999; // no spam
+       self.hasweapon_complain_spam = time + 9999999999; // no spam
                
-       entity head, w, wp = world;
+       entity head, wp = world;
        if(!self.cursor_trace_ent && self.BUTTON_ATCK && time >= self.last_click)
        {       
                FOR_EACH_MONSTER(head)
                {
-                       if(head.goalentity) head.goalentity.selected = TRUE; // do this to make sure we're not removing any owned waypoints below
-                       
                        if(head.owner != self) continue;
-                               
+                       
                        head.selected = FALSE;
                        
                        if(!self.enemy)
                                head.owner = world;
                }
-               
-               for(w = world; (w = find(w, classname, "monster_waypoint")); )
-               {
-                       if not(w.selected)
-                               remove(w);
-               }
        }
        if(self.cursor_trace_ent.flags & FL_MONSTER && self.BUTTON_ATCK && time >= self.last_click)
        {
@@ -101,20 +128,20 @@ MUTATOR_HOOKFUNCTION(rts_PlayerThink)
        }
        if(self.BUTTON_ATCK2)
        {
-               entity e = world;
-               if(self.cursor_trace_ent) e = self.cursor_trace_ent;
-               else e = findradius(self.cursor_trace_endpos, 50);
-               
-               if not(IsDifferentTeam(e, self))
-                       e = world; // same team
+               entity e = self.cursor_trace_ent;
                
-               if not(e.takedamage)
-                       e = world; // can't hurt this enemy
+               if(e)
+               if not(IsDifferentTeam(e, self) || e.takedamage)
+                       e = world;
                
-               if(e == world)
+               if not(e)
                {
                        wp = spawn();
                        wp.classname = "monster_waypoint"; // set so we can kill this later
+                       wp.owner = self; // hmm...
+                       wp.think = rts_waypoint_think;
+                       wp.nextthink = time;
+                       WaypointSprite_Spawn("Waypoint", 0, 0, wp, '0 0 10', world, 0, wp, sprite, FALSE, RADARICON_DANGER, ((teamplay) ? TeamColor(self.team) : '1 0 0'));
                        setorigin(wp, self.cursor_trace_endpos);
                }
                
@@ -125,11 +152,10 @@ MUTATOR_HOOKFUNCTION(rts_PlayerThink)
                        
                        if(e)
                        {
-                               remove(head.goalentity);
                                head.goalentity = world;
                                head.enemy = e;
                        }
-                       else if(wp)
+                       else
                        {
                                head.goalentity = wp;
                                head.enemy = world;
@@ -142,7 +168,20 @@ MUTATOR_HOOKFUNCTION(rts_PlayerThink)
 
 MUTATOR_HOOKFUNCTION(rts_MonsterSpawn)
 {
-       self.respawntime = 10; // default to 5 seconds for now
+       // new monster
+       if not(self.monster_respawned)
+       {
+               self.level = 0;
+               self.speed = 1;
+       }
+       
+       self.spawnflags = MONSTERFLAG_NORESPAWN;
+       
+       self.goalentity = world;
+       self.enemy = world;
+       self.moveto = self.origin;
+               
+       self.respawntime = 10; // default to 10 seconds for now
        self.effects |= EF_SELECTABLE;
        self.monster_moveflags = MONSTER_MOVE_NOMOVE;
        
@@ -166,33 +205,33 @@ MUTATOR_HOOKFUNCTION(rts_MonsterThink)
                self.heal_delay = time + 2;
        }
                
-       monster_speed_run = 150;
-       monster_speed_walk = 150;
+       monster_speed_run = 150 * self.speed;
+       monster_speed_walk = 150 * self.speed;
+       
+       if(monster_target.classname == "player")
+               monster_target = world;
        
        if(self.selected)
                self.colormod = color * 4;
        else
                self.colormod = color;
-       
-       if(self.goalentity)
+               
+       if(monster_target)
                self.enemy = world; // don't ignore our owner's commands
        
-       if(!self.sprite)
+       if not(self.sprite)
        {
-               WaypointSprite_Spawn(self.netname, 0, 0, self, '0 0 1' * self.sprite_height, world, self.team, self, sprite, FALSE, RADARICON_DANGER, ((teamplay) ? TeamColor(self.team) : '1 0 0'));   
+               WaypointSprite_Spawn(self.netname, 0, 0, self, '0 0 1' * self.sprite_height, world, self.team, self, sprite, FALSE, RADARICON_DANGER, ((teamplay) ? TeamColor(self.team) : '1 0 0'));
                WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health);
                WaypointSprite_UpdateHealth(self.sprite, self.health);
        }
        
-       if(!self.selected)
        if(self.owner)
+       if not(self.selected)
                self.owner = world;
        
-       if(!IsDifferentTeam(self, self.enemy))
+       if not(IsDifferentTeam(self, self.enemy))
                self.enemy = world; // no same team fighting
-               
-       if(!self.goalentity && !self.enemy && vlen(self.velocity) > 64) // wtf
-               self.moveto = self.origin;
        
        self.last_trace = time; // realtime moving?
                
@@ -201,17 +240,28 @@ MUTATOR_HOOKFUNCTION(rts_MonsterThink)
 
 MUTATOR_HOOKFUNCTION(rts_MonsterDies)
 {
-       float otherteam = ((self.team == COLOR_TEAM1) ? COLOR_TEAM2 : COLOR_TEAM1);
+       if(IsDifferentTeam(frag_attacker, frag_target) && frag_attacker.team)
+               TeamScore_AddToTeam(frag_attacker.team, ST_SCORE, 1);
        
-       TeamScore_AddToTeam(otherteam, ST_SCORE, 1);
+       // need to keep the monster selected to get the points... hmm (TODO: realowners?)
+       if(frag_attacker.owner.classname == "player")
+       {
+               PlayerScore_Add(frag_attacker.owner, SP_SCORE, 5);
+               PlayerScore_Add(frag_attacker.owner, SP_KILLS, 1);
+       }
+               
+       if(frag_attacker.flags & FL_MONSTER)
+       {
+               frag_attacker.monster_score += 5;
+               if(frag_attacker.monster_score == 25)
+                       Monster_LevelUp(frag_attacker);
+       }
 
        self.effects &~= EF_SELECTABLE;
        self.selected = FALSE;
-       if(self.goalentity)
-       {
-               remove(self.goalentity);
-               self.goalentity = world;
-       }
+       
+       self.goalentity = world;
+       self.enemy = world;
        
        return FALSE;
 }
@@ -271,7 +321,7 @@ MUTATOR_HOOKFUNCTION(rts_PlayerDies)
        FOR_EACH_MONSTER(head)
        {
                if(head.owner != self) continue;
-               if(!head.selected) continue;
+               if not(head.selected) continue;
                
                if(IsDifferentTeam(self, head))
                {
index 8284c1f6c5686049fe377202505d7904a50c0df5..c08a5c175f7cc09b173ef5f9f30452404603caed 100644 (file)
@@ -1,4 +1,7 @@
 .vector oldorigin;
 .float selected;
 .float last_click;
-.float heal_delay;
\ No newline at end of file
+.float heal_delay;
+.float monster_score;
+.float level;
+.float rts_viewangle;
\ No newline at end of file