]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Fix TD monster spawn protection. Improve TD monster pathfinding
authorMario <mario.mario@y7mail.com>
Thu, 24 Jan 2013 14:13:09 +0000 (01:13 +1100)
committerMario <mario.mario@y7mail.com>
Thu, 24 Jan 2013 14:13:09 +0000 (01:13 +1100)
20 files changed:
gamemodes.cfg
monsters.cfg
qcsrc/server/autocvars.qh
qcsrc/server/monsters/lib/monsters.qc
qcsrc/server/monsters/monster/demon.qc
qcsrc/server/monsters/monster/dog.qc
qcsrc/server/monsters/monster/enforcer.qc
qcsrc/server/monsters/monster/fish.qc
qcsrc/server/monsters/monster/hknight.qc
qcsrc/server/monsters/monster/knight.qc
qcsrc/server/monsters/monster/ogre.qc
qcsrc/server/monsters/monster/shalrath.qc
qcsrc/server/monsters/monster/shambler.qc
qcsrc/server/monsters/monster/soldier.qc
qcsrc/server/monsters/monster/spider.qc
qcsrc/server/monsters/monster/tarbaby.qc
qcsrc/server/monsters/monster/wizard.qc
qcsrc/server/monsters/monster/zombie.qc
qcsrc/server/mutators/gamemode_td.qc
qcsrc/server/mutators/gamemode_td.qh

index 94926ebaa2cb1b78fa96de11d4048a1f7f7da2e5..8987e5e5f2b114c3ab51c91bd44b6fe9253ef392 100644 (file)
@@ -495,7 +495,7 @@ set g_td_generator_dontend 0 "don't change maps when a generator is destroyed (o
 set g_td_pvp 0
 set g_td_monsters_skill_start 1
 set g_td_monsters_skill_increment 0.1
-set g_td_monster_spawn_protection_radius 300
+set g_td_monsters_spawnshield_time 2
 set g_td_max_waves 8
 set g_td_kill_points 5
 set g_td_turretkill_points 3
index 3d79f77e69891f27c3c54f56323a059350061ab6..cae7a40eb2a0554330b4224805bbd1b2cbbff73c 100644 (file)
@@ -190,16 +190,12 @@ set g_monster_zombie_drop_size large "Size of the item zombies drop. Possible va
 set g_monster_spider 1 "Enable Spiders"
 set g_monster_spider_attack_type 0 "Spider attack type (0 = ice, 1 = fire, ...)"
 set g_monster_spider_attack_leap_delay 1.5 "Delay after spider attack leap"
-set g_monster_spider_attack_leap_range 96 "Range of spider attack leap"
 set g_monster_spider_attack_stand_damage 35 "Damage when spider hits from a standing position"
 set g_monster_spider_attack_stand_delay 1.2 "Delay after a spider hits from a standing position"
-set g_monster_spider_attack_stand_range 48 "Range of a spider standing position attack"
 set g_monster_spider_health 200 "Spider health"
 set g_monster_spider_idle_timer_min 1 "Minimum time a spider can stay idle"
 set g_monster_spider_speed_walk 150 "Spider walk speed"
 set g_monster_spider_speed_run 400 "Spider run speed"
 set g_monster_spider_stopspeed 100 Speed at which spider stops"
-set g_monster_spider_target_recheck_delay 5 How much time should a spider run afer an enemy before checking if it's still in range"
-set g_monster_spider_target_range 1200 How far the spider can see an enemy"
 set g_monster_spider_drop health "Spider drops this item on death"
 set g_monster_spider_drop_size large "Size of the item spiders drop. Possible values are: small, medium, large"
\ No newline at end of file
index e00fd585ba38f3a96a149c5a20eea4a7e547217c..dd3284a6f857b6e4f55757e6eef014d50f1fd968 100644 (file)
@@ -1296,7 +1296,7 @@ float autocvar_g_td_turret_walker_cost;
 float autocvar_g_td_tower_buff_cost;
 float autocvar_g_td_monsters_skill_start;
 float autocvar_g_td_monsters_skill_increment;
-float autocvar_g_td_monster_spawn_protection_radius;
+float autocvar_g_td_monsters_spawnshield_time;
 float autocvar_g_za_monster_count;
 float autocvar_g_monsters;
 float autocvar_g_monsters_max;
index 0338f5ef6f97ba2286cd5f752c32dc7cb34598e0..38f41c2dbbb5f96eef9c11037e73625bbc48d617 100644 (file)
@@ -113,6 +113,7 @@ void MonsterTouch ()
                return;
                
        if(self.enemy != other)
+       if not(other.flags & FL_MONSTER)
        if(monster_isvalidtarget(other, self, FALSE))
                self.enemy = other;
 }
@@ -541,7 +542,7 @@ void Monster_Appear ()
 
 entity FindTarget (entity ent) 
 {
-       if(MUTATOR_CALLHOOK(MonsterFindTarget)) { return ent.goalentity; } // Handled by a mutator
+       if(MUTATOR_CALLHOOK(MonsterFindTarget)) { return ent.enemy; } // Handled by a mutator
        local entity e;
        for(e = world; (e = findflags(e, monster_attack, TRUE)); ) 
        {
index 1e54bec4e075df4f8759c60e09c6238c5a41cf78..6bff2017c129d752291009484371534eff493570 100644 (file)
@@ -22,7 +22,7 @@ const vector DEMON_MAX = '32 32 24';
 void demon_think ()
 {
        self.think = demon_think;
-       self.nextthink = time + 0.3;
+       self.nextthink = time + 0.1;
        
        monster_move(autocvar_g_monster_demon_speed_run, autocvar_g_monster_demon_speed_walk, 100, demon_anim_run, demon_anim_walk, demon_anim_stand);
 }
index aa65d6d4bc689c04277c8f5359bf8e29cfb55863..a79c443e2ea44e4ea1d60d7ff6067f7b4f4dd0bd 100644 (file)
@@ -37,7 +37,7 @@ void Dog_JumpTouch ()
 void dog_think ()
 {
        self.think = dog_think;
-       self.nextthink = time + 0.3;
+       self.nextthink = time + 0.1;
        
        monster_move(autocvar_g_monster_dog_speed_run, autocvar_g_monster_dog_speed_walk, 50, dog_anim_run, dog_anim_walk, dog_anim_idle);
 }
index 2e3fa1a55dda024dc2f32f05a6a8a4d68afa033d..b370e402ee49549423e3fa56b0b884bc6c4d8879 100644 (file)
@@ -24,7 +24,7 @@ float autocvar_g_monster_enforcer_attack_uzi_bullets;
 void enforcer_think ()
 {
        self.think = enforcer_think;
-       self.nextthink = time + 0.3;
+       self.nextthink = time + 0.1;
        
        if(self.delay != -1)
                self.nextthink = self.delay;
index 970fd47e386bd35d0c098128c057930910d299e1..f40272266a79a4f35f11d56022ae3b0d465a0f8b 100644 (file)
@@ -18,7 +18,7 @@ float autocvar_g_monster_fish_speed_run;
 void fish_think ()
 {
        self.think = fish_think;
-       self.nextthink = time + 0.3;
+       self.nextthink = time + 0.1;
        
        monster_move(autocvar_g_monster_fish_speed_run, autocvar_g_monster_fish_speed_walk, 10, fish_anim_swim, fish_anim_swim, fish_anim_swim);
 }
index f1d7e3cd2d436e8e67f52c13dd89c930671fb1df..a4b42acbd557c8b106ecbd43980614ec7dd0224d 100644 (file)
@@ -171,7 +171,7 @@ void CheckContinueCharge ()
 void hellknight_think ()
 {
        self.think = hellknight_think;
-       self.nextthink = time + 0.3;
+       self.nextthink = time + 0.1;
        
        monster_move(autocvar_g_monster_hellknight_speed_run, autocvar_g_monster_hellknight_speed_walk, 100, hellknight_anim_run, hellknight_anim_walk, hellknight_anim_stand);
 }
index 4aa625415c1101f4e6cc4991abd867c7e5e6cfc2..67ef1576b503edc127b2b186d0e0e98338795fc8 100644 (file)
@@ -25,7 +25,7 @@ float autocvar_g_monster_knight_speed_run;
 void knight_think ()
 {
        self.think = knight_think;
-       self.nextthink = time + 0.3;
+       self.nextthink = time + 0.1;
        
        monster_move(autocvar_g_monster_knight_speed_run, autocvar_g_monster_knight_speed_walk, 50, knight_anim_run, knight_anim_walk, knight_anim_stand);
 }
index 6b30c8e2549ef4c305f887f44bb6d2ace77322b4..2331dd9f4035a5b695096a915c567e1e2ab9b897 100644 (file)
@@ -40,7 +40,7 @@ void chainsaw (float side)
 void ogre_think ()
 {
        self.think = ogre_think;
-       self.nextthink = time + 0.3;
+       self.nextthink = time + 0.1;
        
        if(self.delay != -1)
                self.nextthink = self.delay;
index c19e1ce677101c61dde496bf477db35b61b4fbb7..732ff78ae4de4dc2cfd6ee402e30fffd72f9008f 100644 (file)
@@ -19,7 +19,7 @@ void() ShalMissile;
 void shalrath_think ()
 {
        self.think = shalrath_think;
-       self.nextthink = time + 0.3;
+       self.nextthink = time + 0.1;
        
        if(self.delay != -1)
                self.nextthink = self.delay;
index 0f82cc717e83958c469a5ab2922d053bb5b55cc1..5694628678570fb025a479f97d528ef7c228e70f 100644 (file)
@@ -25,7 +25,7 @@ float autocvar_g_monster_shambler_speed_run;
 void shambler_think ()
 {
        self.think = shambler_think;
-       self.nextthink = time + 0.3;
+       self.nextthink = time + 0.1;
        
        monster_move(autocvar_g_monster_shambler_speed_run, autocvar_g_monster_shambler_speed_walk, 300, shambler_anim_run, shambler_anim_walk, shambler_anim_stand);
 }
index b4e46e0f55c4551001c7082fdff65c764f2a7af9..54c7849e8fc3da6fc456a5d69c6862afe9741086 100644 (file)
@@ -30,7 +30,7 @@ float autocvar_g_monster_soldier_attack_uzi_bullets;
 void soldier_think ()
 {
        self.think = soldier_think;
-       self.nextthink = time + 0.3;
+       self.nextthink = time + 0.1;
        
        if(self.delay != -1)
                self.nextthink = self.delay;
index 2007e5e28df781c484a13465208ced84aeafa70f..744e05eb41e174bcf69b472e877d2144c48fc6bc 100644 (file)
@@ -2,16 +2,11 @@
 float autocvar_g_monster_spider;
 float autocvar_g_monster_spider_stopspeed;
 float autocvar_g_monster_spider_attack_leap_delay;
-float autocvar_g_monster_spider_attack_leap_range;
 float autocvar_g_monster_spider_attack_stand_damage;
 float autocvar_g_monster_spider_attack_stand_delay;
-float autocvar_g_monster_spider_attack_stand_range;
 float autocvar_g_monster_spider_health;
-float autocvar_g_monster_spider_idle_timer_min;
 float autocvar_g_monster_spider_speed_walk;
 float autocvar_g_monster_spider_speed_run;
-float autocvar_g_monster_spider_target_recheck_delay;
-float autocvar_g_monster_spider_target_range;
 float autocvar_g_monster_spider_attack_type;
 
 // spider animations
@@ -165,92 +160,18 @@ void spider_attack_leap()
        }
 }
 
-void spider_think()
+float spider_attack_ranged()
 {
-       float finished = FALSE, enemyDistance = 0, mySpeed = 0;
+       spider_attack_leap();
+       return TRUE;
+}
 
+void spider_think()
+{
        self.think = spider_think;
+       self.nextthink = time + 0.1;
        
-       if(self.enemy && !monster_isvalidtarget(self.enemy, self, FALSE))
-               self.enemy = world;
-       
-       if (self.enemy)
-       if (self.enemy.team == self.team || self.monster_owner == self.enemy)
-               self.enemy = world;
-       
-       if(teamplay && autocvar_g_monsters_teams && self.monster_owner.team != self.team)
-               self.monster_owner = world;     
-       
-       // remove enemy that ran away
-       if (self.enemy)
-       if (self.delay <= time) // check if we can do the rescan now
-       if (vlen(self.origin - self.enemy.origin) > autocvar_g_monster_spider_target_range * self.scale) 
-       {
-               //print("removing enemy, he is too far: ", ftos(vlen(self.origin - self.enemy.origin)), "\n");
-               //print("delay was ", ftos(self.delay), "\n");
-               self.enemy = world;
-       } 
-       else
-               self.delay = time + autocvar_g_monster_spider_target_recheck_delay;
-       
-       // find an enemy if no enemy available
-       if not(self.enemy) 
-       {
-               self.enemy = FindTarget(self);
-               if (self.enemy)
-                       self.delay = time + autocvar_g_monster_spider_target_recheck_delay;
-       }
-
-       if (self.enemy) 
-       {
-               // this spider has an enemy, attack if close enough, go to it if not!
-               traceline(self.origin, self.enemy.origin, FALSE, self);
-               enemyDistance = vlen(trace_endpos - self.origin);
-               mySpeed = vlen(self.velocity);
-               
-               //print("speed ", ftos(mySpeed), "\n");
-               
-               if (trace_ent == self.enemy)
-               if (self.enemy.deadflag == DEAD_NO)
-                       if (enemyDistance <= autocvar_g_monster_spider_attack_stand_range * self.scale && mySpeed <= 30) 
-                       {
-                               
-                               //RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity ignore, float forceintensity, float deathtype, entity directhitentity)
-                               spider_attack_standing();
-                               finished = TRUE;
-                       } 
-                       else if (enemyDistance <= autocvar_g_monster_spider_attack_leap_range * self.scale && !self.enemy.frozen) 
-                       {
-                               // do attackleap (set yaw, velocity, and check do damage on the first player entity it touches)
-                               spider_attack_leap();
-                               finished = TRUE;
-                       }
-               
-       }
-       
-       self.nextthink = time + 1;
-
-       if not(finished) 
-       {
-               monster_move(autocvar_g_monster_spider_speed_run, autocvar_g_monster_spider_speed_walk, autocvar_g_monster_spider_stopspeed, spider_anim_walk, spider_anim_walk, spider_anim_idle);
-               
-               if (self.enemy || self.monster_owner)
-               {
-                       self.nextthink = time + 0.1;
-                       return;
-               }   
-       }
-       
-       if not(self.enemy || self.monster_owner || self.goalentity) 
-       {
-               // stay idle
-               //print("spider is idling while waiting for some fresh meat...\n");
-               if (mySpeed <= 10)
-                       self.frame = spider_anim_idle;
-               else
-                       self.frame = spider_anim_walk;
-               self.nextthink = time + autocvar_g_monster_spider_idle_timer_min * random();    
-       }
+       monster_move(autocvar_g_monster_spider_speed_run, autocvar_g_monster_spider_speed_walk, autocvar_g_monster_spider_stopspeed, spider_anim_walk, spider_anim_walk, spider_anim_idle);
 }
 
 /**
@@ -265,6 +186,8 @@ void spider_spawn()
        self.nextthink                  = time + random() * 0.5 + 0.1;
        self.pain_finished      = self.nextthink;
        self.frame                              = spider_anim_idle;
+       self.attack_melee               = spider_attack_standing;
+       self.attack_ranged              = spider_attack_ranged;
        self.think                              = spider_think;
        self.sprite_height      = 40 * self.scale;
        
index 355648ef54b5326d310aba997b7189e2c8b021a3..25903b3ef73f7768373555c76a074343719314de 100644 (file)
@@ -18,7 +18,7 @@ float autocvar_g_monster_tarbaby_speed_run;
 void tarbaby_think ()
 {
        self.think = tarbaby_think;
-       self.nextthink = time + 0.3;
+       self.nextthink = time + 0.1;
        
        monster_move(autocvar_g_monster_tarbaby_speed_run, autocvar_g_monster_tarbaby_speed_walk, 20, tarbaby_anim_run, tarbaby_anim_walk, tarbaby_anim_walk);
 }
index 4460e02214e0aa3bd62074f613d92f50220191f7..62a3be9e0a889000a9ded01f07f837f772b944bc 100644 (file)
@@ -91,7 +91,7 @@ void Wiz_StartFast ()
 void wizard_think ()
 {
        self.think = wizard_think;
-       self.nextthink = time + 0.3;
+       self.nextthink = time + 0.1;
        
        monster_move(autocvar_g_monster_wizard_speed_run, autocvar_g_monster_wizard_speed_walk, 300, wizard_anim_fly, wizard_anim_hover, wizard_anim_hover);
 }
index ff73c8efa4a1313dd7763fcf9a57d73609dec901..113ea64519c9a492ef18d36be569067bfbc43cb2 100644 (file)
@@ -151,7 +151,7 @@ float zombie_attack_ranged()
 void zombie_think()
 {
        self.think = zombie_think;
-       self.nextthink = time + 0.3;
+       self.nextthink = time + 0.1;
 
        monster_move(autocvar_g_monster_zombie_speed_run, autocvar_g_monster_zombie_speed_walk, autocvar_g_monster_zombie_stopspeed, zombie_anim_runforward, zombie_anim_runforward, zombie_anim_idle);
 }
index 05016232282c00388cdc08db376ab28d78d50066..077aa85325203a52bc117fd8be48a69c98fe0428 100644 (file)
@@ -21,6 +21,7 @@ void spawnfunc_td_controller()
        totalmonsters = ((self.monstercount) ? self.monstercount : autocvar_g_td_monster_count);
        wave_count = ((self.startwave) ? self.startwave : autocvar_g_td_start_wave);
        max_turrets = ((self.maxturrets) ? self.maxturrets : autocvar_g_td_turret_max);
+       build_time = ((self.buildtime) ? self.buildtime : autocvar_g_td_buildphase_time);
                
        wave_end(TRUE);
 }
@@ -180,9 +181,6 @@ void spawnfunc_monster_swarm()
                default:
                        self.classname = "monster_swarm"; break;
        }
-               
-       if(!self.protection_radius)
-               self.protection_radius = autocvar_g_td_monster_spawn_protection_radius;
        
        if(self.target2 != "")
        {
@@ -557,7 +555,7 @@ void build_phase()
         GameLogEcho(sprintf(":buildphase:%d:%d", wave_count, totalmonsters));
        
        self.think = combat_phase_announce;
-       self.nextthink = time + autocvar_g_td_buildphase_time - 6;
+       self.nextthink = time + build_time - 6;
 }
 
 void wave_end(float starting)
@@ -688,6 +686,9 @@ MUTATOR_HOOKFUNCTION(td_PlayerDamage_Calculate)
        if(frag_attacker.realowner == frag_target)
                frag_damage = 0;
                
+       if(frag_target.flags & FL_MONSTER && time < frag_target.spawnshieldtime)
+               frag_damage = 0;
+               
        if(frag_target.vehicle_flags & VHF_ISVEHICLE && !DEATH_ISMONSTER(frag_deathtype))
                frag_damage = 0;
                
@@ -761,14 +762,18 @@ MUTATOR_HOOKFUNCTION(td_MonsterMove)
                return FALSE;
        }
        
+       if((vlen(self.goalentity.origin - self.origin) <= 100 && self.goalentity.classname == "td_waypoint") || (vlen(self.goalentity.origin - self.origin) <= 200 && self.flags & FL_FLY && self.goalentity.classname == "td_waypoint"))
+       {
+               self.target = self.goalentity.target;
+               self.goalentity = find(world, targetname, self.target);
+       }
+       
+       if(self.goalentity == world)
+               self.goalentity = generator;
+       
        monster_speed_run = 110 * monster_skill;
        monster_speed_walk = 75 * monster_skill;
        
-       if(vlen(self.realowner.origin - self.origin) < self.realowner.protection_radius && self.realowner.classname == "monster_swarm")
-        self.takedamage = DAMAGE_NO;
-    else
-        self.takedamage = DAMAGE_AIM;
-       
        return FALSE;
 }
 
@@ -789,6 +794,8 @@ MUTATOR_HOOKFUNCTION(td_MonsterSpawn)
                return TRUE;
        }
        
+       self.spawnshieldtime = time + autocvar_g_td_monsters_spawnshield_time;
+       
        self.lastcheck = time;
        
        self.drop_size = self.health * 0.05;
@@ -871,18 +878,7 @@ MUTATOR_HOOKFUNCTION(td_MonsterFindTarget)
        FOR_EACH_PLAYER(player) { ++n_players; }
        
        if(n_players < 1) // no players online, so do nothing
-       {
                return TRUE;
-       }
-       
-       if(vlen(self.goalentity.origin - self.origin) <= 100 && self.goalentity.classname == "waypoint")
-               self.goalentity.lastchecked = self;
-               
-       if((vlen(self.goalentity.origin - self.origin) <= 100 && self.goalentity.classname == "td_waypoint") || (vlen(self.goalentity.origin - self.origin) <= 200 && self.flags & FL_FLY && self.goalentity.classname == "td_waypoint"))
-       {
-               self.goalentity = find(world, targetname, self.goalentity.target);
-               self.target = self.goalentity.target;
-       }
        
        if(generator == world)
        {
@@ -905,27 +901,6 @@ MUTATOR_HOOKFUNCTION(td_MonsterFindTarget)
                if((vlen(trace_endpos - self.origin) < 100 && e.turrcaps_flags & TFL_TURRCAPS_ISTURRET) || (vlen(trace_endpos - self.origin) < 200 && e != generator) || (vlen(trace_endpos - self.origin) < 500 && e == generator))
                {
                        self.enemy = e;
-                       return TRUE;
-               }
-       }
-       if(self.target) // follow target if available
-       {
-               self.goalentity = find(world, targetname, self.target);
-               if(self.goalentity == world)
-                       self.goalentity = generator;
-               return TRUE;
-       }
-       else
-               self.goalentity = generator;
-               
-       for(e = world;(e = find(e, classname, "waypoint")); )
-       {
-               if(vlen(e.origin - self.origin) < 500)
-               if(e.lastchecked != self)
-               if(vlen(e.origin - self.origin) > 50)
-               {
-                       //print(strcat("Goal found at ", vtos(e.origin), "\n"));
-                       self.goalentity = e;
                }
        }
        
index 6926876200c4bc8c6c10329bb468b921cf549477..84cec1a253b0509688e57cc7f58419d51c2fae1a 100644 (file)
@@ -25,6 +25,7 @@ float SWARM_WEAK      = 1;
 float SWARM_STRONG     = 2;
 float SWARM_FLY                = 3;
 float SWARM_SWIM       = 4;
+float build_time;
 float td_dont_end;
 .float lastcheck;
 void(float starting) wave_end;
@@ -32,7 +33,6 @@ void(float starting) wave_end;
 float td_gencount;
 void() spawnfunc_td_controller;
 float oldrespawncvar;
-.float protection_radius;
 float current_phase;
 #define PHASE_BUILD    1
 #define PHASE_COMBAT   2
@@ -50,10 +50,10 @@ float current_phase;
 .float startwave;
 .float dontend;
 .float maxturrets;
+.float buildtime;
 
 // Generator
 float gendestroyed;
-.entity lastchecked;
 entity generator; // global generator entity (TODO: replace with a script for multi generator support?)
 float gendmg;
 #define GENERATOR_MIN '-52 -52 -14'