]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Cleanup RTS mode a bit
authorMario <mario.mario@y7mail.com>
Wed, 6 Feb 2013 17:36:42 +0000 (04:36 +1100)
committerMario <mario.mario@y7mail.com>
Wed, 6 Feb 2013 17:36:42 +0000 (04:36 +1100)
qcsrc/server/monsters/lib/monsters.qc
qcsrc/server/mutators/base.qh
qcsrc/server/mutators/gamemode_rts.qc
qcsrc/server/teamplay.qc

index e6f53a68101ea949895d73880616d5c10555dea9..b0b11322732abad5dbbf0b60b4cf8563ffab0737 100644 (file)
@@ -210,15 +210,29 @@ void Monster_CheckMinibossFlag ()
        }
 }
 
+float Monster_CanRespawn(entity ent)
+{
+       other = ent;
+       if(MUTATOR_CALLHOOK(MonsterRespawn))
+               return TRUE; // enabled by a mutator
+               
+       if(ent.spawnflags & MONSTERFLAG_NORESPAWN)
+               return FALSE;
+               
+       if not(autocvar_g_monsters_respawn)
+               return FALSE;
+               
+       return TRUE;
+}
+
 void Monster_Fade ()
 {
-       if not(self.spawnflags & MONSTERFLAG_NORESPAWN)
-       if(autocvar_g_monsters_respawn)
+       if(Monster_CanRespawn(self))
        {
                self.monster_respawned = TRUE;
                setmodel(self, "");
                self.think = self.monster_spawnfunc;
-               self.nextthink = time + autocvar_g_monsters_respawn_delay;
+               self.nextthink = time + self.respawntime;
                setorigin(self, self.pos1);
                self.angles = self.pos2;
                self.health = 0;
@@ -338,6 +352,11 @@ vector monster_pickmovetarget(entity targ)
                self.monster_movestate = MONSTER_MOVE_ENEMY;
                return self.enemy.origin;
        }
+       if(targ)
+       {
+               self.monster_movestate = MONSTER_MOVE_WANDER;
+               return targ.origin;
+       }
        
        switch(self.monster_moveflags)
        {
@@ -350,8 +369,6 @@ vector monster_pickmovetarget(entity targ)
                case MONSTER_MOVE_WANDER:
                {
                        self.monster_movestate = MONSTER_MOVE_WANDER;
-                       if(targ)
-                               return targ.origin;
                                
                        self.angles_y = random() * 500;
                        makevectors(self.angles);
@@ -464,7 +481,7 @@ void monster_move(float runspeed, float walkspeed, float stopspeed, float manim_
                
        if(time >= self.last_trace)
        {
-               if(self.monster_movestate == MONSTER_MOVE_WANDER && (self.goalentity.classname != "td_waypoint" || self.goalentity != self.sprite))
+               if(self.monster_movestate == MONSTER_MOVE_WANDER && self.goalentity.classname != "td_waypoint")
                        self.last_trace = time + 2;
                else
                        self.last_trace = time + 0.5;
@@ -734,6 +751,9 @@ float monster_initialize(string  net_name,
        self.pos1                               = self.origin;
        self.pos2                               = self.angles;
        
+       if not(self.respawntime)
+               self.respawntime = autocvar_g_monsters_respawn_delay;
+       
        if not(self.monster_moveflags)
                self.monster_moveflags = MONSTER_MOVE_WANDER;
 
index 43e807b6fb413a84ecb61c52532570d9fdc500a8..abef8e8d69bf9b1c3acf4aca40c840a37cd5a451 100644 (file)
@@ -144,6 +144,11 @@ MUTATOR_HOOKABLE(MonsterDies);
        // INPUT:
                entity frag_attacker;
                
+MUTATOR_HOOKABLE(MonsterRespawn);
+       // called when a monster wants to respawn
+       // INPUT:
+               entity other;
+               
 MUTATOR_HOOKABLE(MonsterDropItem);
        // called when a monster is dropping loot
        // INPUT, OUTPUT:
index 7cbf32f6fedb024b543b8d4db28546e5bacf2e7e..dd7b686fc7f94a7bcc1ead2ca8dce54e49af7b00 100644 (file)
@@ -6,8 +6,10 @@
 .float last_click;
 MUTATOR_HOOKFUNCTION(rts_PlayerSpawn)
 {
+       self.effects |= EF_NODRAW;
        self.oldorigin = self.origin;
        self.last_click = time;
+       self.takedamage = DAMAGE_NO;
        self.flags |= FL_NOTARGET;
        self.movetype = MOVETYPE_FLY;
        stuffcmd(self, "settemp cl_prydoncursor 1\n");
@@ -29,33 +31,41 @@ MUTATOR_HOOKFUNCTION(rts_SetStartItems)
 
 MUTATOR_HOOKFUNCTION(rts_PlayerThink)
 {
+       if(self.classname != "player")
+               return FALSE; // dont do any checks for spectators
        entity head, wp = world;
-       if(self.cursor_trace_ent == world && self.BUTTON_ATCK)
+       if(self.cursor_trace_ent == world && self.BUTTON_ATCK && time >= self.last_click)
        {       
                FOR_EACH_MONSTER(head)
                {
-                       if(head.waypointsprite_attachedforcarrier)
-                               WaypointSprite_Kill(head.waypointsprite_attachedforcarrier);
+                       if(head.owner != self) continue;
+                       
+                       if(head.goalentity)
+                       {
+                               remove(head.goalentity);
+                               head.goalentity = world;
+                       }
                                
                        head.selected = FALSE;
                        
-                       if(head.owner == self)
+                       if(!self.enemy && !self.goalentity)
                                head.owner = world;
                }
        }
        if(self.cursor_trace_ent.flags & FL_MONSTER && self.BUTTON_ATCK && time >= self.last_click)
        {
-               if(self.cursor_trace_ent.selected)
+               if(self.cursor_trace_ent.owner != self && self.cursor_trace_ent.owner != world)
+                       return FALSE; // someone else owns it
+               else if(self.cursor_trace_ent.team != self.team)
+                       return FALSE; // not our team
+               else if(self.cursor_trace_ent.selected)
                {
-                       WaypointSprite_Kill(self.cursor_trace_ent.waypointsprite_attachedforcarrier);
                        self.cursor_trace_ent.selected = FALSE;
                        self.cursor_trace_ent.owner = world;
                        self.last_click = time + 0.5; // prevent spamming
                }
                else
                {
-                       WaypointSprite_Spawn("Selected", 0, 0, self.cursor_trace_ent, '0 0 64' + ('0 0 1' * self.cursor_trace_ent.maxs_z), world, 0, self.cursor_trace_ent, waypointsprite_attachedforcarrier, FALSE, RADARICON_FLAGCARRIER, BALL_SPRITECOLOR);
-                       
                        self.cursor_trace_ent.owner = self;
                        self.cursor_trace_ent.selected = TRUE;
                        self.last_click = time + 0.5; // prevent spamming
@@ -71,7 +81,6 @@ MUTATOR_HOOKFUNCTION(rts_PlayerThink)
                        {
                                wp = spawn();
                                setorigin(wp, self.cursor_trace_endpos);
-                               WaypointSprite_SpawnFixed("Moving Here", wp.origin + '0 0 40', wp, sprite, RADARICON_HERE, '1 0.5 0');
                        }
                }
                
@@ -81,19 +90,17 @@ MUTATOR_HOOKFUNCTION(rts_PlayerThink)
                        
                        if(head.goalentity)
                        {
-                               if(head.goalentity.sprite)
-                                       WaypointSprite_Kill(head.goalentity.sprite);
                                remove(head.goalentity);
                                head.goalentity = world;
                        }
                        
-                       if(head.sprite)
-                               WaypointSprite_Kill(head.sprite);
-                       
-                       if(self.cursor_trace_ent)
+                       if(self.cursor_trace_ent && self.cursor_trace_ent.team != self.team)
                                head.enemy = self.cursor_trace_ent;
                        else
+                       {
                                head.goalentity = wp;
+                               head.enemy = world;
+                       }
                }
        }
 
@@ -102,34 +109,105 @@ MUTATOR_HOOKFUNCTION(rts_PlayerThink)
 
 MUTATOR_HOOKFUNCTION(rts_MonsterSpawn)
 {
+       self.respawntime = time + 5; // default to 5 seconds for now
        self.effects |= EF_SELECTABLE;
+       self.monster_moveflags = MONSTER_MOVE_NOMOVE;
        
-       if(self.sprite)
-               WaypointSprite_Kill(self.sprite); // no waypoint names in rts...?
+       WaypointSprite_Kill(self.sprite);
+       self.sprite = world;
        
        return FALSE;
 }
 
 MUTATOR_HOOKFUNCTION(rts_MonsterThink)
 {
+       vector color;
+       if(self.team)
+               color = TeamColor(self.team);
+       else
+               color = '1 1 1';
+               
+       monster_speed_run = 100;
+       monster_speed_walk = 100;
+       
        if(self.selected)
-               self.colormod = '1 1 1' * 4;
+               self.colormod = color * 4;
        else
-               self.colormod = '1 1 1';
+       {
+               self.colormod = color;
+               if(self.goalentity)
+               {
+                       remove(self.goalentity);
+                       self.goalentity = world;
+               }
+       }
+       
+       if(self.goalentity)
+               self.enemy = world; // don't ignore our owner's commands
+       
+       if(!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_UpdateMaxHealth(self.sprite, self.max_health);
+               WaypointSprite_UpdateHealth(self.sprite, self.health);
+       }
+       
+       if(!self.selected)
+       if(self.owner)
+       if(!self.goalentity && !self.enemy)
+               self.owner = world;
+       
+       if(self.enemy.team == self.team)
+               self.enemy = world; // no same team fighting
+       
+       self.last_trace = time; // realtime moving?
                
        return FALSE;
 }
 
 MUTATOR_HOOKFUNCTION(rts_MonsterDies)
 {
-       if(self.waypointsprite_attachedforcarrier)
-               WaypointSprite_Kill(self.waypointsprite_attachedforcarrier);
-               
+       float otherteam = ((self.team == COLOR_TEAM1) ? COLOR_TEAM2 : COLOR_TEAM1);
+       
+       TeamScore_AddToTeam(otherteam, ST_SCORE, 1);
+
+       self.effects &~= EF_SELECTABLE;
        self.selected = FALSE;
        
        return FALSE;
 }
 
+MUTATOR_HOOKFUNCTION(rts_MonsterRespawn)
+{
+       if(other.team)
+               return TRUE;
+               
+       return FALSE; // if no team is set, don't respawn
+}
+
+MUTATOR_HOOKFUNCTION(rts_MonsterTarget)
+{
+       // don't search for enemies, they are given to us
+       return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(rts_MonsterBossFlag)
+{
+       // no minibosses in RTS
+       return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(rts_PlayerDamage)
+{
+       if(frag_target.classname == "player")
+               frag_damage = 0; // don't damage the invincible players...
+               
+       if((frag_target.flags & FL_MONSTER) && frag_target.goalentity)
+               frag_target.enemy = world; // don't attack the attacker, we're probably pulling back
+               
+       return FALSE;
+}
+
 MUTATOR_HOOKFUNCTION(rts_PlayerPhysics)
 {
        self.origin_z = self.oldorigin_z;
@@ -138,6 +216,22 @@ MUTATOR_HOOKFUNCTION(rts_PlayerPhysics)
        return FALSE;
 }
 
+void rts_ScoreRules()
+{
+       ScoreRules_basics(2, SFL_SORT_PRIO_PRIMARY, 0, TRUE);
+       ScoreRules_basics_end();
+}
+
+void rts_DelayedInit()
+{
+       rts_ScoreRules();
+}
+
+void rts_Initialize()
+{
+       InitializeEntity(world, rts_DelayedInit, INITPRIO_GAMETYPE);
+}
+
 MUTATOR_DEFINITION(gamemode_rts)
 {
        MUTATOR_HOOK(PlayerPhysics, rts_PlayerPhysics, CBC_ORDER_ANY);
@@ -147,13 +241,19 @@ MUTATOR_DEFINITION(gamemode_rts)
        MUTATOR_HOOK(MonsterSpawn, rts_MonsterSpawn, CBC_ORDER_ANY);
        MUTATOR_HOOK(PlayerPreThink, rts_PlayerThink, CBC_ORDER_ANY);
        MUTATOR_HOOK(MonsterMove, rts_MonsterThink, CBC_ORDER_ANY);
+       MUTATOR_HOOK(MonsterFindTarget, rts_MonsterTarget, CBC_ORDER_ANY);
        MUTATOR_HOOK(MonsterDies, rts_MonsterDies, CBC_ORDER_ANY);
+       MUTATOR_HOOK(MonsterRespawn, rts_MonsterRespawn, CBC_ORDER_ANY);
+       MUTATOR_HOOK(MonsterCheckBossFlag, rts_MonsterBossFlag, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerDamage_Calculate, rts_PlayerDamage, CBC_ORDER_ANY);
        
        MUTATOR_ONADD
        {
                if(time > 1) // game loads at time 1
                        error("This is a game type and it cannot be added at runtime.");        
                cvar_settemp("g_monsters", "1");
+               
+               rts_Initialize();
        }
 
        MUTATOR_ONREMOVE
index 3581f6bd18c3b3aaaaf2a3623671eb53c70ca3d0..564171c0c1813f38b71723e73fe46feb0bf301ea 100644 (file)
@@ -155,9 +155,11 @@ void InitGameplayMode()
        
        if(g_rts)
        {
+               ActivateTeamplay();
                fraglimit_override = 0;
                leadlimit_override = 0;
                MUTATOR_ADD(gamemode_rts);
+               have_team_spawns = -1; // request team spawns
        }
 
        if(g_runematch)