From eb439bf3fb5abd2b90afee55d19facbcbf2805ce Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 7 Feb 2013 09:00:15 +1100 Subject: [PATCH] Some more RTS cleanup --- qcsrc/server/monsters/lib/monsters.qc | 7 +- qcsrc/server/mutators/gamemode_rts.qc | 76 +++++++++++++------ qcsrc/server/mutators/gamemode_rts.qh | 4 + qcsrc/server/progs.src | 1 + .../tturrets/units/unit_fusionreactor.qc | 22 ++++++ 5 files changed, 82 insertions(+), 28 deletions(-) create mode 100644 qcsrc/server/mutators/gamemode_rts.qh diff --git a/qcsrc/server/monsters/lib/monsters.qc b/qcsrc/server/monsters/lib/monsters.qc index cca80384a..684461a46 100644 --- a/qcsrc/server/monsters/lib/monsters.qc +++ b/qcsrc/server/monsters/lib/monsters.qc @@ -394,9 +394,6 @@ void monster_move(float runspeed, float walkspeed, float stopspeed, float manim_ if(self.target) self.goalentity = find(world, targetname, self.target); - float l = vlen(self.moveto - self.origin); - float t1 = trace_path(self.origin+'0 0 10', self.moveto+'0 0 10'); - float t2 = trace_path(self.origin-'0 0 15', self.moveto-'0 0 15'); entity targ = self.goalentity; if(self.frozen) @@ -499,6 +496,10 @@ void monster_move(float runspeed, float walkspeed, float stopspeed, float manim_ v_forward = normalize(self.moveto - self.origin); + float l = vlen(self.moveto - self.origin); + float t1 = trace_path(self.origin+'0 0 10', self.moveto+'0 0 10'); + float t2 = trace_path(self.origin-'0 0 15', self.moveto-'0 0 15'); + if(t1*l-t2*l>50 && (t1*l > 100 || t1 > 0.8)) if(self.flags & FL_ONGROUND) movelib_jump_simple(100); diff --git a/qcsrc/server/mutators/gamemode_rts.qc b/qcsrc/server/mutators/gamemode_rts.qc index 15dc34597..847e8bbbf 100644 --- a/qcsrc/server/mutators/gamemode_rts.qc +++ b/qcsrc/server/mutators/gamemode_rts.qc @@ -1,19 +1,28 @@ // Real-Time Strategy // Gamemode by Mario -.vector oldorigin; -.float selected; -.float last_click; +// basically a fusion reactor with a new classname +void spawnfunc_healing_tower() +{ + self.spawnflags = TSL_NO_RESPAWN; // healing towers don't respawn? + self.netname = "Monster Healing Tower"; // not used by waypoints... + spawnfunc_turret_fusionreactor(); + self.classname = "healing_tower"; + self.target_range = 1000; + self.shot_dmg = 20; +} + MUTATOR_HOOKFUNCTION(rts_PlayerSpawn) { self.effects |= EF_NODRAW; self.oldorigin = self.origin; + self.monster_attack = FALSE; self.last_click = time; self.takedamage = DAMAGE_NO; self.flags |= FL_NOTARGET; self.movetype = MOVETYPE_NOCLIP; self.angles_x = 30; - stuffcmd(self, "settemp cl_prydoncursor 1\n"); + stuffcmd(self, "cl_cmd settemp cl_prydoncursor 1\n"); return FALSE; } @@ -51,7 +60,7 @@ MUTATOR_HOOKFUNCTION(rts_PlayerThink) self.hasweapon_complain_spam = time + 99999; // no spam entity head, wp = world; - if(self.cursor_trace_ent == world && self.BUTTON_ATCK && time >= self.last_click) + if(!self.cursor_trace_ent && self.BUTTON_ATCK && time >= self.last_click) { FOR_EACH_MONSTER(head) { @@ -59,7 +68,7 @@ MUTATOR_HOOKFUNCTION(rts_PlayerThink) head.selected = FALSE; - if(!self.enemy && !self.goalentity) + if(!self.enemy) head.owner = world; } } @@ -84,7 +93,14 @@ MUTATOR_HOOKFUNCTION(rts_PlayerThink) } if(self.BUTTON_ATCK2) { - if not(self.cursor_trace_ent) + entity e; + if(self.cursor_trace_ent) e = self.cursor_trace_ent; + else e = findradius(self.cursor_trace_endpos, 50); + + if(!IsDifferentTeam(e, self) || !e.takedamage) + e = world; + + if(e == world) { float selected_count = 0; FOR_EACH_MONSTER(head) { if(head.owner == self) selected_count += 1; } @@ -105,9 +121,9 @@ MUTATOR_HOOKFUNCTION(rts_PlayerThink) head.goalentity = world; } - if(self.cursor_trace_ent && self.cursor_trace_ent.team != self.team) - head.enemy = self.cursor_trace_ent; - else + if(e && IsDifferentTeam(head, e) && e.takedamage) + head.enemy = e; + else if(wp) { head.goalentity = wp; head.enemy = world; @@ -120,23 +136,29 @@ MUTATOR_HOOKFUNCTION(rts_PlayerThink) MUTATOR_HOOKFUNCTION(rts_MonsterSpawn) { - self.respawntime = time + 5; // default to 5 seconds for now + self.respawntime = 10; // default to 5 seconds for now self.effects |= EF_SELECTABLE; self.monster_moveflags = MONSTER_MOVE_NOMOVE; WaypointSprite_Kill(self.sprite); self.sprite = world; + self.heal_delay = -1; // this is reset when monster takes damage return FALSE; } MUTATOR_HOOKFUNCTION(rts_MonsterThink) { - vector color; - if(self.team) - color = TeamColor(self.team); - else - color = '1 1 1'; + vector color = ((self.team) ? TeamColor(self.team) : '1 1 1'); + + if(self.health >= self.max_health) + self.heal_delay = -1; + else if(time >= self.heal_delay) + { + self.health = min(self.health + 5, self.max_health); + WaypointSprite_UpdateHealth(self.sprite, self.health); + self.heal_delay = time + 2; + } monster_speed_run = 150; monster_speed_walk = 150; @@ -144,14 +166,7 @@ MUTATOR_HOOKFUNCTION(rts_MonsterThink) if(self.selected) self.colormod = color * 4; else - { self.colormod = color; - if(self.goalentity && vlen(self.origin - self.moveto) <= 64) - { - remove(self.goalentity); - self.goalentity = world; - } - } if(self.goalentity) self.enemy = world; // don't ignore our owner's commands @@ -165,10 +180,10 @@ MUTATOR_HOOKFUNCTION(rts_MonsterThink) if(!self.selected) if(self.owner) - if(!self.goalentity && !self.enemy) + if(!self.enemy) self.owner = world; - if(self.enemy.team == self.team) + if(!IsDifferentTeam(self, self.enemy)) self.enemy = world; // no same team fighting self.last_trace = time; // realtime moving? @@ -184,6 +199,11 @@ MUTATOR_HOOKFUNCTION(rts_MonsterDies) self.effects &~= EF_SELECTABLE; self.selected = FALSE; + if(self.goalentity) + { + remove(self.goalentity); + self.goalentity = world; + } return FALSE; } @@ -216,6 +236,12 @@ MUTATOR_HOOKFUNCTION(rts_PlayerDamage) if((frag_target.flags & FL_MONSTER) && frag_target.goalentity) frag_target.enemy = world; // don't attack the attacker, we're probably pulling back + if((frag_target.flags & FL_MONSTER) && !IsDifferentTeam(frag_target, frag_attacker)) + frag_damage = 0; // no team damage + + if((frag_target.flags & FL_MONSTER) && frag_damage > 0) + frag_target.heal_delay = time + 2; // reset delay whenever hurt + return FALSE; } diff --git a/qcsrc/server/mutators/gamemode_rts.qh b/qcsrc/server/mutators/gamemode_rts.qh new file mode 100644 index 000000000..8284c1f6c --- /dev/null +++ b/qcsrc/server/mutators/gamemode_rts.qh @@ -0,0 +1,4 @@ +.vector oldorigin; +.float selected; +.float last_click; +.float heal_delay; \ No newline at end of file diff --git a/qcsrc/server/progs.src b/qcsrc/server/progs.src index f7029fe23..b7e064c88 100644 --- a/qcsrc/server/progs.src +++ b/qcsrc/server/progs.src @@ -36,6 +36,7 @@ mutators/gamemode_keepaway.qh mutators/gamemode_nexball.qh mutators/mutator_dodging.qh mutators/gamemode_td.qh +mutators/gamemode_rts.qh //// tZork Turrets //// tturrets/include/turrets_early.qh diff --git a/qcsrc/server/tturrets/units/unit_fusionreactor.qc b/qcsrc/server/tturrets/units/unit_fusionreactor.qc index de8509b3e..6301079d9 100644 --- a/qcsrc/server/tturrets/units/unit_fusionreactor.qc +++ b/qcsrc/server/tturrets/units/unit_fusionreactor.qc @@ -12,6 +12,12 @@ void turret_fusionreactor_fire() self.enemy.health = min(self.enemy.health + self.shot_dmg,self.enemy.max_health); self.enemy.tur_health = min(self.enemy.tur_health + self.shot_dmg,self.enemy.max_health); } + if(g_rts) // monster healing + { + self.enemy.heal_delay = time + 0.5; + self.enemy.health = min(self.enemy.health + self.shot_dmg,self.enemy.max_health); + WaypointSprite_UpdateHealth(self.enemy.sprite, self.enemy.health); + } fl_org = 0.5 * (self.enemy.absmin + self.enemy.absmax); te_smallflash(fl_org); } @@ -59,6 +65,22 @@ float turret_fusionreactor_firecheck() if(self.enemy.health >= self.enemy.max_health) return 0; } + if(g_rts) + { + if(IsDifferentTeam(self, self.enemy)) + return 0; + + if not(self.enemy.flags & FL_MONSTER) + return 0; + + if(self.enemy.health >= self.enemy.max_health) + return 0; + + if(time < self.enemy.heal_delay) + return 0; + + return 1; // this is for monsters, so don't do the other checks + } if (self.enemy.ammo >= self.enemy.ammo_max) return 0; -- 2.39.2