]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Rename grunt to marine
authorMario <mario.mario@y7mail.com>
Mon, 29 Apr 2013 17:33:00 +0000 (03:33 +1000)
committerMario <mario.mario@y7mail.com>
Mon, 29 Apr 2013 17:33:00 +0000 (03:33 +1000)
models/monsters/marine.zym [new file with mode: 0644]
models/monsters/soldier.zym [deleted file]
monsters.cfg
qcsrc/client/monsters.qc
qcsrc/menu/xonotic/dialog_monstertools.c
qcsrc/server/monsters/monster/marine.qc [new file with mode: 0644]
qcsrc/server/monsters/monster/soldier.qc [deleted file]
qcsrc/server/monsters/monsters.qh
qcsrc/server/mutators/gamemode_towerdefense.qc
qcsrc/server/mutators/gamemode_towerdefense.qh

diff --git a/models/monsters/marine.zym b/models/monsters/marine.zym
new file mode 100644 (file)
index 0000000..1615af4
Binary files /dev/null and b/models/monsters/marine.zym differ
diff --git a/models/monsters/soldier.zym b/models/monsters/soldier.zym
deleted file mode 100644 (file)
index 1615af4..0000000
Binary files a/models/monsters/soldier.zym and /dev/null differ
index d14a8bb149037a634df6ecd6688e5c39d6253dd3..9675810407a583154d92acbfc2f68def32f7f9dd 100644 (file)
@@ -75,38 +75,38 @@ set g_monster_bruiser_melee_side_damage 10 "Bruiser melee attack side damage"
 set g_monster_bruiser_speed_walk 40 "Bruiser walk speed"
 set g_monster_bruiser_speed_run 70 "Bruiser run speed"
 
-// Grunt
-set g_monster_soldier 1 "Enable Grunts"
-set g_monster_soldier_health 100 "Grunt Health"
-set g_monster_soldier_drop ammo "Grunt drops this item on death"
-set g_monster_soldier_drop_size shells "Size of the item Grunts drop. Possible values are: small, medium, large"
-set g_monster_soldier_melee_damage 20 "Grunt melee attack damage"
-set g_monster_soldier_speed_walk 75 "Grunt walk speed"
-set g_monster_soldier_speed_run 100 "Grunt run speed"
-set g_monster_soldier_ammo 5 "Grunt weapon ammo"
-set g_monster_soldier_weapon_laser_chance 6 "Chance of Grunt weapon being laser"
-set g_monster_soldier_weapon_shotgun_chance 8 "Chance of Grunt weapon being shotgun"
-set g_monster_soldier_weapon_machinegun_chance 4 "Chance of Grunt weapon being machine gun"
-set g_monster_soldier_weapon_rocketlauncher_chance 2 "Chance of Grunt weapon being rocket launcher"
-set g_monster_soldier_attack_uzi_bullets 3 "Number of machine gun bullets Grunt fires"
-set g_monster_soldier_attack_uzi_damage 10 "Grunt machine gun damage per bullet"
-set g_monster_soldier_attack_uzi_force 5 "Grunt machine gun knockback"
-set g_monster_soldier_attack_shotgun_damage 4 "Grunt shotgun per bullet damage"
-set g_monster_soldier_attack_shotgun_spread 0.2 "Grunt shotgun bullet spread"
-set g_monster_soldier_attack_shotgun_bullets 12 "Grunt shotgun bullets per shot"
-set g_monster_soldier_attack_shotgun_force 5 "Grunt shotgun knockback"
-set g_monster_soldier_attack_rocket_damage 50 "Grunt rocket direct hit damage"
-set g_monster_soldier_attack_rocket_edgedamage 25 "Grunt rocket indirect hit damage"
-set g_monster_soldier_attack_rocket_radius 110 "Grunt rocket explosion radius"
-set g_monster_soldier_attack_rocket_force 25 "Grunt rocket knockback"
-set g_monster_soldier_attack_rocket_lifetime 5 "Grunt rocket lifetime"
-set g_monster_soldier_attack_rocket_speed 2000 "Grunt rocket fly speed"
-set g_monster_soldier_attack_laser_damage 15 "Grunt laser damage"
-set g_monster_soldier_attack_laser_edgedamage 7 "Grunt laser indirect hit damage"
-set g_monster_soldier_attack_laser_radius 50 "Grunt laser damage radius"
-set g_monster_soldier_attack_laser_force 300 "Grunt laser knockback"
-set g_monster_soldier_attack_laser_speed 2000 "Grunt laser projectile speed"
-set g_monster_soldier_attack_laser_spread 0 "Grunt laser projectile spread"
+// Marine
+set g_monster_marine 1 "Enable Marines"
+set g_monster_marine_health 100 "Marine Health"
+set g_monster_marine_drop ammo "Marine drops this item on death"
+set g_monster_marine_drop_size shells "Size of the item Marines drop. Possible values are: small, medium, large"
+set g_monster_marine_melee_damage 20 "Marine melee attack damage"
+set g_monster_marine_speed_walk 75 "Marine walk speed"
+set g_monster_marine_speed_run 100 "Marine run speed"
+set g_monster_marine_ammo 5 "Marine weapon ammo"
+set g_monster_marine_weapon_laser_chance 6 "Chance of Marine weapon being laser"
+set g_monster_marine_weapon_shotgun_chance 8 "Chance of Marine weapon being shotgun"
+set g_monster_marine_weapon_machinegun_chance 4 "Chance of Marine weapon being machine gun"
+set g_monster_marine_weapon_rocketlauncher_chance 2 "Chance of Marine weapon being rocket launcher"
+set g_monster_marine_attack_uzi_bullets 3 "Number of machine gun bullets Marine fires"
+set g_monster_marine_attack_uzi_damage 10 "Marine machine gun damage per bullet"
+set g_monster_marine_attack_uzi_force 5 "Marine machine gun knockback"
+set g_monster_marine_attack_shotgun_damage 4 "Marine shotgun per bullet damage"
+set g_monster_marine_attack_shotgun_spread 0.2 "Marine shotgun bullet spread"
+set g_monster_marine_attack_shotgun_bullets 12 "Marine shotgun bullets per shot"
+set g_monster_marine_attack_shotgun_force 5 "Marine shotgun knockback"
+set g_monster_marine_attack_rocket_damage 50 "Marine rocket direct hit damage"
+set g_monster_marine_attack_rocket_edgedamage 25 "Marine rocket indirect hit damage"
+set g_monster_marine_attack_rocket_radius 110 "Marine rocket explosion radius"
+set g_monster_marine_attack_rocket_force 25 "Marine rocket knockback"
+set g_monster_marine_attack_rocket_lifetime 5 "Marine rocket lifetime"
+set g_monster_marine_attack_rocket_speed 2000 "Marine rocket fly speed"
+set g_monster_marine_attack_laser_damage 15 "Marine laser damage"
+set g_monster_marine_attack_laser_edgedamage 7 "Marine laser indirect hit damage"
+set g_monster_marine_attack_laser_radius 50 "Marine laser damage radius"
+set g_monster_marine_attack_laser_force 300 "Marine laser knockback"
+set g_monster_marine_attack_laser_speed 2000 "Marine laser projectile speed"
+set g_monster_marine_attack_laser_spread 0 "Marine laser projectile spread"
 
 // Wyvern
 set g_monster_wyvern 1 "Enable Wyverns"
index e88116a4e18a9cfdb7dcfa3e78d762adc35c2de4..725c2f057ad53f96bea85f32955f7086361e73fd 100644 (file)
@@ -41,7 +41,7 @@ void monster_precache(float _mid)
                }
                case MONSTER_MARINE:
                {
-                       precache_model(SOLDIER_MODEL);
+                       precache_model(MARINE_MODEL);
                        precache_sound("weapons/shotgun_fire.wav");
                        precache_sound("weapons/uzi_fire.wav");
                        precache_sound("weapons/laser_fire.wav");
@@ -146,10 +146,10 @@ void monster_mid2info(float _mid)
                }
                case MONSTER_MARINE:
                {
-                       mid2info_model = SOLDIER_MODEL;
+                       mid2info_model = MARINE_MODEL;
                        mid2info_name = "Marine";
-                       mid2info_min = SOLDIER_MIN;
-                       mid2info_max = SOLDIER_MAX;
+                       mid2info_min = MARINE_MIN;
+                       mid2info_max = MARINE_MAX;
                        break;
                }
                case MONSTER_WYVERN:
index 4fa0227ff868b4741fa6dd94a9bafcdb80c2253c..7d5228a1bba4fa879fffcc92fe0cbbfe54d130f6 100644 (file)
@@ -25,7 +25,7 @@ void XonoticMonsterToolsDialog_fill(entity me)
                me.TD(me, 1, 0.4, e = makeXonoticRadioButton(2, "menu_monsters_edit_spawn", "bruiser", _("Bruiser")));
                me.TD(me, 1, 0.4, e = makeXonoticRadioButton(2, "menu_monsters_edit_spawn", "knight", _("Knight")));
                me.TD(me, 1, 0.4, e = makeXonoticRadioButton(2, "menu_monsters_edit_spawn", "shambler", _("Shambler")));
-               me.TD(me, 1, 0.4, e = makeXonoticRadioButton(2, "menu_monsters_edit_spawn", "soldier", _("Marine")));
+               me.TD(me, 1, 0.4, e = makeXonoticRadioButton(2, "menu_monsters_edit_spawn", "marine", _("Marine")));
        me.TR(me);
                me.TD(me, 1, 0.4, e = makeXonoticRadioButton(2, "menu_monsters_edit_spawn", "cerberus", _("Cerberus")));
                me.TD(me, 1, 0.4, e = makeXonoticRadioButton(2, "menu_monsters_edit_spawn", "slime", _("Slime")));
diff --git a/qcsrc/server/monsters/monster/marine.qc b/qcsrc/server/monsters/monster/marine.qc
new file mode 100644 (file)
index 0000000..6560ae8
--- /dev/null
@@ -0,0 +1,387 @@
+// size
+const vector MARINE_MIN = '-16 -16 -30';
+const vector MARINE_MAX = '16 16 32';
+
+// model
+string MARINE_MODEL = "models/monsters/marine.zym";
+
+#ifdef SVQC
+// cvars
+float autocvar_g_monster_marine;
+float autocvar_g_monster_marine_health;
+float autocvar_g_monster_marine_melee_damage;
+float autocvar_g_monster_marine_speed_walk;
+float autocvar_g_monster_marine_speed_run;
+float autocvar_g_monster_marine_ammo;
+float autocvar_g_monster_marine_weapon_laser_chance;
+float autocvar_g_monster_marine_weapon_shotgun_chance;
+float autocvar_g_monster_marine_weapon_machinegun_chance;
+float autocvar_g_monster_marine_weapon_rocketlauncher_chance;
+float autocvar_g_monster_marine_attack_uzi_bullets;
+float autocvar_g_monster_marine_attack_uzi_damage;
+float autocvar_g_monster_marine_attack_uzi_force;
+float autocvar_g_monster_marine_attack_shotgun_damage;
+float autocvar_g_monster_marine_attack_shotgun_force;
+float autocvar_g_monster_marine_attack_shotgun_spread;
+float autocvar_g_monster_marine_attack_shotgun_bullets;
+float autocvar_g_monster_marine_attack_rocket_damage;
+float autocvar_g_monster_marine_attack_rocket_edgedamage;
+float autocvar_g_monster_marine_attack_rocket_radius;
+float autocvar_g_monster_marine_attack_rocket_force;
+float autocvar_g_monster_marine_attack_rocket_lifetime;
+float autocvar_g_monster_marine_attack_rocket_speed;
+float autocvar_g_monster_marine_attack_laser_damage;
+float autocvar_g_monster_marine_attack_laser_edgedamage;
+float autocvar_g_monster_marine_attack_laser_radius;
+float autocvar_g_monster_marine_attack_laser_force;
+
+// animations
+const float marine_anim_die1                   = 0;
+const float marine_anim_die2                   = 1;
+const float marine_anim_draw                   = 2;
+const float marine_anim_duck                   = 3;
+const float marine_anim_duckwalk               = 4;
+const float marine_anim_duckjump               = 5;
+const float marine_anim_duckidle               = 6;
+const float marine_anim_idle                   = 7;
+const float marine_anim_jump                   = 8;
+const float marine_anim_pain1                  = 9;
+const float marine_anim_pain2                  = 10;
+const float marine_anim_shoot                  = 11;
+const float marine_anim_taunt                  = 12;
+const float marine_anim_run                    = 13;
+const float marine_anim_runbackwards   = 14;
+const float marine_anim_strafeleft     = 15;
+const float marine_anim_straferight    = 16;
+const float marine_anim_dead1                  = 17;
+const float marine_anim_dead2                  = 18;
+const float marine_anim_forwardright   = 19;
+const float marine_anim_forwardleft    = 20;
+const float marine_anim_backright              = 21;
+const float marine_anim_backleft               = 22;
+
+.float marine_cycles;
+
+void marine_think()
+{
+       self.think = marine_think;
+       self.nextthink = time + self.ticrate;
+       
+       if(time < self.attack_finished_single)
+               monster_move(0, 0, 0, marine_anim_shoot, marine_anim_shoot, marine_anim_shoot);
+       else
+               monster_move(autocvar_g_monster_marine_speed_run, autocvar_g_monster_marine_speed_walk, 50, marine_anim_run, marine_anim_run, marine_anim_idle);
+}
+
+void marine_reload()
+{
+       self.monster_delayedattack = func_null; // out of ammo, don't keep attacking
+       self.delay = -1;
+       monsters_setframe(marine_anim_draw);
+       self.attack_finished_single = time + 2;
+       self.currentammo = autocvar_g_monster_marine_ammo;
+       sound (self, CH_SHOTS, "weapons/reload.wav", VOL_BASE, ATTN_LARGE);
+}
+
+void marine_uzi()
+{
+       self.currentammo -= 1;
+       if(self.currentammo <= 0)
+       {
+               marine_reload();
+               return;
+       }
+               
+       self.marine_cycles += 1;
+       
+       if(self.marine_cycles > autocvar_g_monster_marine_attack_uzi_bullets)
+       {
+               self.monster_delayedattack = func_null;
+               self.delay = -1;
+               return;
+       }
+       
+       monster_makevectors(self.enemy);
+       
+       W_SetupShot(self, autocvar_g_antilag_bullets && 18000 >= autocvar_g_antilag_bullets, 0, "weapons/uzi_fire.wav", CH_WEAPON_A, autocvar_g_monster_marine_attack_uzi_damage);
+       fireBallisticBullet(w_shotorg, w_shotdir, 0.02, 18000, 5, autocvar_g_monster_marine_attack_uzi_damage, autocvar_g_monster_marine_attack_uzi_force, DEATH_MONSTER_MARINE, 0, 1, 115);
+       endFireBallisticBullet();
+       
+       self.delay = time + 0.1;
+       self.monster_delayedattack = marine_uzi;
+}
+
+void marine_rocket_explode()
+{
+       self.event_damage = func_null;
+       self.takedamage = DAMAGE_NO;
+       
+       pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
+       sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
+
+       RadiusDamage(self, self.realowner, autocvar_g_monster_marine_attack_rocket_damage, autocvar_g_monster_marine_attack_rocket_edgedamage, autocvar_g_monster_marine_attack_rocket_radius, world, autocvar_g_monster_marine_attack_rocket_force, self.projectiledeathtype, other);
+
+       remove(self);
+}
+
+void marine_rocket_touch()
+{
+       PROJECTILE_TOUCH;
+       
+       marine_rocket_explode();
+}
+
+void marine_rocket_think()
+{
+       self.nextthink = time;
+       if(time >= self.cnt)
+       {
+               marine_rocket_explode();
+               return;
+       }
+}
+
+void marine_rocket_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+{
+       if(self.health <= 0)
+               return;
+       
+       if(!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, -1)) // no exceptions
+               return; // g_projectiles_damage says to halt
+               
+       self.health -= damage;
+       self.angles = vectoangles(self.velocity);
+       
+       if(self.health <= 0)
+               W_PrepareExplosionByDamage(attacker, marine_rocket_explode);
+}
+
+void marine_rocket()
+{
+       entity missile;
+       
+       W_SetupShot_ProjectileSize(self, '-3 -3 -3', '3 3 3', FALSE, 5, "weapons/rocket_fire.wav", CH_WEAPON_A, autocvar_g_monster_marine_attack_rocket_damage);
+
+       missile = spawn();
+       missile.owner = missile.realowner = self;
+       missile.classname = "rocket";
+       missile.bot_dodge = TRUE;
+       missile.bot_dodgerating = autocvar_g_monster_marine_attack_rocket_damage * 2; // * 2 because it can be detonated inflight which makes it even more dangerous
+
+       missile.takedamage = DAMAGE_YES;
+       missile.health = 50;
+       missile.event_damage = marine_rocket_damage;
+       missile.damagedbycontents = TRUE;
+
+       missile.movetype = MOVETYPE_FLY;
+       PROJECTILE_MAKETRIGGER(missile);
+       missile.projectiledeathtype = DEATH_MONSTER_MARINE;
+       setsize(missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
+
+       setorigin(missile, w_shotorg - v_forward * 3); // move it back so it hits the wall at the right point
+       W_SetupProjectileVelocity(missile, autocvar_g_monster_marine_attack_rocket_speed, 0);
+       missile.angles = vectoangles(missile.velocity);
+
+       missile.touch = marine_rocket_touch;
+       missile.think = marine_rocket_think;
+       missile.nextthink = time;
+       missile.cnt = time + autocvar_g_monster_marine_attack_rocket_lifetime;
+       missile.flags = FL_PROJECTILE;
+       missile.missile_flags = MIF_SPLASH; 
+
+       CSQCProjectile(missile, TRUE, PROJECTILE_ROCKET, FALSE);
+}
+
+void marine_shotgun()
+{
+       float sc;
+       W_SetupShot(self, autocvar_g_antilag_bullets && 18000 >= autocvar_g_antilag_bullets, 5, "weapons/shotgun_fire.wav", CH_WEAPON_A, autocvar_g_monster_marine_attack_shotgun_damage * autocvar_g_monster_marine_attack_shotgun_bullets);
+       for(sc = 0;sc < autocvar_g_monster_marine_attack_shotgun_bullets;sc = sc + 1)
+               fireBallisticBullet(w_shotorg, w_shotdir, autocvar_g_monster_marine_attack_shotgun_spread, 18000, 5, autocvar_g_monster_marine_attack_shotgun_damage, autocvar_g_monster_marine_attack_shotgun_force, DEATH_MONSTER_MARINE, 0, 1, 115);
+       endFireBallisticBullet();
+}
+
+void marine_laser_touch()
+{
+       PROJECTILE_TOUCH;
+
+       self.event_damage = func_null;
+       RadiusDamage(self, self.realowner, autocvar_g_monster_marine_attack_laser_damage, autocvar_g_monster_marine_attack_laser_edgedamage, autocvar_g_monster_marine_attack_laser_radius, world, autocvar_g_monster_marine_attack_laser_force, self.projectiledeathtype, other);
+
+       remove(self);
+}
+
+void marine_laser()
+{
+       entity missile;
+       
+       W_SetupShot_Dir(self, v_forward, FALSE, 3, "weapons/lasergun_fire.wav", CH_WEAPON_B, autocvar_g_monster_marine_attack_laser_damage);
+       
+       missile = spawn();
+       missile.owner = missile.realowner = self;
+       missile.classname = "laserbolt";
+       PROJECTILE_MAKETRIGGER(missile);
+       missile.projectiledeathtype = DEATH_MONSTER_MARINE;
+
+       setorigin(missile, w_shotorg);
+       setsize(missile, '0 0 0', '0 0 0');
+
+       W_SETUPPROJECTILEVELOCITY(missile, g_monster_marine_attack_laser);
+       missile.angles = vectoangles(missile.velocity);
+       missile.touch = marine_laser_touch;
+
+       missile.flags = FL_PROJECTILE;
+       missile.missile_flags = MIF_SPLASH;
+       missile.movetype = MOVETYPE_FLY;
+       
+       missile.think = SUB_Remove;
+       missile.nextthink = time + 5;
+       
+       CSQCProjectile(missile, TRUE, PROJECTILE_LASER, TRUE);
+}
+
+float marine_attack(float attack_type)
+{
+       switch(attack_type)
+       {
+               case MONSTER_ATTACK_MELEE:
+               {
+                       monsters_setframe(marine_anim_shoot);
+                       self.attack_finished_single = time + 0.8;
+                       monster_melee(self.enemy, autocvar_g_monster_marine_melee_damage, 0.3, DEATH_MONSTER_MARINE_SLAP, TRUE);
+                       
+                       return TRUE;
+               }
+               case MONSTER_ATTACK_RANGED:
+               {
+                       if(self.currentammo <= 0)
+                       {
+                               marine_reload();
+                               
+                               return FALSE;
+                       }
+                       
+                       monsters_setframe(marine_anim_shoot);
+                       monster_makevectors(self.enemy);
+                       self.marine_cycles = 0;
+       
+                       switch(self.weapon)
+                       {
+                               case WEP_ROCKET_LAUNCHER:
+                               {
+                                       self.currentammo -= 1;
+                                       self.attack_finished_single = time + 0.8;
+                                       marine_rocket();
+                                       
+                                       return TRUE;
+                               }
+                               case WEP_SHOTGUN:
+                               {
+                                       self.currentammo -= 1;
+                                       self.attack_finished_single = time + 0.8;
+                                       marine_shotgun();
+                                       
+                                       return TRUE;
+                               }
+                               case WEP_UZI:
+                               {
+                                       self.attack_finished_single = time + 0.8;
+                                       self.delay = time + 0.1;
+                                       self.monster_delayedattack = marine_uzi;
+                                       
+                                       return TRUE;
+                               }
+                               case WEP_LASER:
+                               {
+                                       self.attack_finished_single = time + 0.8;
+                                       marine_laser();
+                                       
+                                       return TRUE;
+                               }
+                       }
+                       
+                       return FALSE;
+               }
+       }
+       
+       return FALSE;
+}
+
+void marine_die()
+{
+       Monster_CheckDropCvars ("marine");
+       
+       self.think = monster_dead_think;
+       self.nextthink = time + self.ticrate;
+       self.ltime = time + 5;
+       monsters_setframe((random() > 0.5) ? marine_anim_die1 : marine_anim_die2);
+               
+       monster_hook_death(); // for post-death mods
+}
+
+void marine_spawn()
+{
+       if not(self.health)
+               self.health = autocvar_g_monster_marine_health;
+
+       self.damageforcescale   = 0.003;
+       self.classname                  = "monster_marine";
+       self.monster_attackfunc = marine_attack;
+       self.nextthink                  = time + random() * 0.5 + 0.1;
+       self.think                              = marine_think;
+       self.currentammo                = 3;
+       self.items                              = (IT_SHELLS | IT_ROCKETS | IT_NAILS);
+       
+       monsters_setframe(marine_anim_draw);
+       
+       monster_setupsounds("marine");
+       
+       setmodel(self, MARINE_MODEL);
+       
+       RandomSelection_Init();
+       RandomSelection_Add(world, WEP_LASER, string_null, autocvar_g_monster_marine_weapon_laser_chance, 1);
+       RandomSelection_Add(world, WEP_SHOTGUN, string_null, autocvar_g_monster_marine_weapon_shotgun_chance, 1);
+       RandomSelection_Add(world, WEP_UZI, string_null, autocvar_g_monster_marine_weapon_machinegun_chance, 1);
+       RandomSelection_Add(world, WEP_ROCKET_LAUNCHER, string_null, autocvar_g_monster_marine_weapon_rocketlauncher_chance, 1);
+       
+       self.weaponentity = spawn();
+       self.weaponentity.movetype = MOVETYPE_NOCLIP;
+       self.weaponentity.team = self.team;
+       self.weaponentity.solid = SOLID_NOT;
+       self.weaponentity.owner = self.weaponentity.realowner = self;
+       setmodel(self.weaponentity, "models/weapons/v_seeker.md3");
+       setattachment(self.weaponentity, self, "bip01 r hand");
+       
+       self.armorvalue = bound(0.5, random(), 1);
+       self.weapon = RandomSelection_chosen_float;
+
+       monster_hook_spawn(); // for post-spawn mods
+}
+
+void spawnfunc_monster_marine()
+{      
+       if not(autocvar_g_monster_marine) { remove(self); return; }
+       
+       self.monster_spawnfunc = spawnfunc_monster_marine;
+       
+       if(Monster_CheckAppearFlags(self))
+               return;
+               
+       precache_model("models/weapons/v_seeker.md3");
+       precache_model(MARINE_MODEL);
+       
+       if not (monster_initialize(
+                        "Marine", MONSTER_MARINE,
+                        MARINE_MIN, MARINE_MAX,
+                        FALSE,
+                        marine_die, marine_spawn))
+       {
+               remove(self);
+               return;
+       }
+}
+
+// compatibility with old spawns
+void spawnfunc_monster_army() { spawnfunc_monster_marine(); }
+
+#endif // SVQC
diff --git a/qcsrc/server/monsters/monster/soldier.qc b/qcsrc/server/monsters/monster/soldier.qc
deleted file mode 100644 (file)
index dfe7de8..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-// size
-const vector SOLDIER_MIN = '-16 -16 -30';
-const vector SOLDIER_MAX = '16 16 32';
-
-// model
-string SOLDIER_MODEL = "models/monsters/soldier.zym";
-
-#ifdef SVQC
-// cvars
-float autocvar_g_monster_soldier;
-float autocvar_g_monster_soldier_health;
-float autocvar_g_monster_soldier_melee_damage;
-float autocvar_g_monster_soldier_speed_walk;
-float autocvar_g_monster_soldier_speed_run;
-float autocvar_g_monster_soldier_ammo;
-float autocvar_g_monster_soldier_weapon_laser_chance;
-float autocvar_g_monster_soldier_weapon_shotgun_chance;
-float autocvar_g_monster_soldier_weapon_machinegun_chance;
-float autocvar_g_monster_soldier_weapon_rocketlauncher_chance;
-float autocvar_g_monster_soldier_attack_uzi_bullets;
-float autocvar_g_monster_soldier_attack_uzi_damage;
-float autocvar_g_monster_soldier_attack_uzi_force;
-float autocvar_g_monster_soldier_attack_shotgun_damage;
-float autocvar_g_monster_soldier_attack_shotgun_force;
-float autocvar_g_monster_soldier_attack_shotgun_spread;
-float autocvar_g_monster_soldier_attack_shotgun_bullets;
-float autocvar_g_monster_soldier_attack_rocket_damage;
-float autocvar_g_monster_soldier_attack_rocket_edgedamage;
-float autocvar_g_monster_soldier_attack_rocket_radius;
-float autocvar_g_monster_soldier_attack_rocket_force;
-float autocvar_g_monster_soldier_attack_rocket_lifetime;
-float autocvar_g_monster_soldier_attack_rocket_speed;
-float autocvar_g_monster_soldier_attack_laser_damage;
-float autocvar_g_monster_soldier_attack_laser_edgedamage;
-float autocvar_g_monster_soldier_attack_laser_radius;
-float autocvar_g_monster_soldier_attack_laser_force;
-
-// animations
-const float soldier_anim_die1                  = 0;
-const float soldier_anim_die2                  = 1;
-const float soldier_anim_draw                  = 2;
-const float soldier_anim_duck                  = 3;
-const float soldier_anim_duckwalk              = 4;
-const float soldier_anim_duckjump              = 5;
-const float soldier_anim_duckidle              = 6;
-const float soldier_anim_idle                  = 7;
-const float soldier_anim_jump                  = 8;
-const float soldier_anim_pain1                         = 9;
-const float soldier_anim_pain2                         = 10;
-const float soldier_anim_shoot                         = 11;
-const float soldier_anim_taunt                         = 12;
-const float soldier_anim_run                   = 13;
-const float soldier_anim_runbackwards  = 14;
-const float soldier_anim_strafeleft    = 15;
-const float soldier_anim_straferight   = 16;
-const float soldier_anim_dead1                         = 17;
-const float soldier_anim_dead2                         = 18;
-const float soldier_anim_forwardright  = 19;
-const float soldier_anim_forwardleft   = 20;
-const float soldier_anim_backright             = 21;
-const float soldier_anim_backleft              = 22;
-
-void soldier_think ()
-{
-       self.think = soldier_think;
-       self.nextthink = time + self.ticrate;
-       
-       if(time < self.attack_finished_single)
-               monster_move(0, 0, 0, soldier_anim_shoot, soldier_anim_shoot, soldier_anim_shoot);
-       else
-               monster_move(autocvar_g_monster_soldier_speed_run, autocvar_g_monster_soldier_speed_walk, 50, soldier_anim_run, soldier_anim_run, soldier_anim_idle);
-}
-
-void soldier_reload ()
-{
-       self.monster_delayedattack = func_null; // out of ammo, don't keep attacking
-       self.delay = -1;
-       monsters_setframe(soldier_anim_draw);
-       self.attack_finished_single = time + 2;
-       self.currentammo = autocvar_g_monster_soldier_ammo;
-       sound (self, CH_SHOTS, "weapons/reload.wav", VOL_BASE, ATTN_LARGE);
-}
-
-.float grunt_cycles;
-void soldier_uzi_fire ()
-{
-       self.currentammo -= 1;
-       if(self.currentammo <= 0)
-       {
-               soldier_reload();
-               return;
-       }
-               
-       self.grunt_cycles += 1;
-       
-       if(self.grunt_cycles > autocvar_g_monster_soldier_attack_uzi_bullets)
-       {
-               self.monster_delayedattack = func_null;
-               self.delay = -1;
-               return;
-       }
-       
-       W_SetupShot (self, autocvar_g_antilag_bullets && 18000 >= autocvar_g_antilag_bullets, 0, "weapons/uzi_fire.wav", CH_WEAPON_A, autocvar_g_monster_soldier_attack_uzi_damage);
-       fireBallisticBullet(w_shotorg, w_shotdir, 0.02, 18000, 5, autocvar_g_monster_soldier_attack_uzi_damage, autocvar_g_monster_soldier_attack_uzi_force, DEATH_MONSTER_MARINE, 0, 1, 115);
-       endFireBallisticBullet();
-       
-       self.delay = time + 0.1;
-       self.monster_delayedattack = soldier_uzi_fire;
-}
-
-void soldier_rocket_explode()
-{
-       self.event_damage = func_null;
-       self.takedamage = DAMAGE_NO;
-       
-       pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
-       sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
-
-       RadiusDamage (self, self.realowner, autocvar_g_monster_soldier_attack_rocket_damage, autocvar_g_monster_soldier_attack_rocket_edgedamage, autocvar_g_monster_soldier_attack_rocket_radius, world, autocvar_g_monster_soldier_attack_rocket_force, self.projectiledeathtype, other);
-
-       remove (self);
-}
-
-void soldier_rocket_touch()
-{
-       PROJECTILE_TOUCH;
-       
-       soldier_rocket_explode();
-}
-
-void soldier_rocket_think()
-{
-       self.nextthink = time;
-       if (time > self.cnt)
-       {
-               soldier_rocket_explode();
-               return;
-       }
-}
-
-void soldier_rocket_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
-{
-       if (self.health <= 0)
-               return;
-       
-       if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, -1)) // no exceptions
-               return; // g_projectiles_damage says to halt
-               
-       self.health -= damage;
-       self.angles = vectoangles(self.velocity);
-       
-       if (self.health <= 0)
-               W_PrepareExplosionByDamage(attacker, soldier_rocket_explode);
-}
-
-void soldier_rocket_fire()
-{
-       entity missile;
-       
-       W_SetupShot_ProjectileSize (self, '-3 -3 -3', '3 3 3', FALSE, 5, "weapons/rocket_fire.wav", CH_WEAPON_A, autocvar_g_monster_soldier_attack_rocket_damage);
-
-       missile = spawn();
-       missile.owner = missile.realowner = self;
-       missile.classname = "rocket";
-       missile.bot_dodge = TRUE;
-       missile.bot_dodgerating = autocvar_g_monster_soldier_attack_rocket_damage * 2; // * 2 because it can be detonated inflight which makes it even more dangerous
-
-       missile.takedamage = DAMAGE_YES;
-       missile.health = 50;
-       missile.event_damage = soldier_rocket_damage;
-       missile.damagedbycontents = TRUE;
-
-       missile.movetype = MOVETYPE_FLY;
-       PROJECTILE_MAKETRIGGER(missile);
-       missile.projectiledeathtype = DEATH_MONSTER_MARINE;
-       setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
-
-       setorigin (missile, w_shotorg - v_forward * 3); // move it back so it hits the wall at the right point
-       W_SetupProjectileVelocity(missile, autocvar_g_monster_soldier_attack_rocket_speed, 0);
-       missile.angles = vectoangles (missile.velocity);
-
-       missile.touch = soldier_rocket_touch;
-       missile.think = soldier_rocket_think;
-       missile.nextthink = time;
-       missile.cnt = time + autocvar_g_monster_soldier_attack_rocket_lifetime;
-       missile.flags = FL_PROJECTILE;
-       missile.missile_flags = MIF_SPLASH; 
-
-       CSQCProjectile(missile, TRUE, PROJECTILE_ROCKET, FALSE);
-}
-
-void soldier_shotgun_fire()
-{
-       float sc;
-       W_SetupShot (self, autocvar_g_antilag_bullets && 18000 >= autocvar_g_antilag_bullets, 5, "weapons/shotgun_fire.wav", CH_WEAPON_A, autocvar_g_monster_soldier_attack_shotgun_damage * autocvar_g_monster_soldier_attack_shotgun_bullets);
-       for (sc = 0;sc < autocvar_g_monster_soldier_attack_shotgun_bullets;sc = sc + 1)
-               fireBallisticBullet(w_shotorg, w_shotdir, autocvar_g_monster_soldier_attack_shotgun_spread, 18000, 5, autocvar_g_monster_soldier_attack_shotgun_damage, autocvar_g_monster_soldier_attack_shotgun_force, DEATH_MONSTER_MARINE, 0, 1, 115);
-       endFireBallisticBullet();
-}
-
-void soldier_laser_touch()
-{
-       PROJECTILE_TOUCH;
-
-       self.event_damage = func_null;
-       RadiusDamage (self, self.realowner, autocvar_g_monster_soldier_attack_laser_damage, autocvar_g_monster_soldier_attack_laser_edgedamage, autocvar_g_monster_soldier_attack_laser_radius, world, autocvar_g_monster_soldier_attack_laser_force, self.projectiledeathtype, other);
-
-       remove (self);
-}
-
-void soldier_laser_fire()
-{
-       entity missile;
-       
-       W_SetupShot_Dir(self, v_forward, FALSE, 3, "weapons/lasergun_fire.wav", CH_WEAPON_B, autocvar_g_monster_soldier_attack_laser_damage);
-       
-       missile = spawn ();
-       missile.owner = missile.realowner = self;
-       missile.classname = "laserbolt";
-       PROJECTILE_MAKETRIGGER(missile);
-       missile.projectiledeathtype = DEATH_MONSTER_MARINE;
-
-       setorigin (missile, w_shotorg);
-       setsize(missile, '0 0 0', '0 0 0');
-
-       W_SETUPPROJECTILEVELOCITY(missile, g_monster_soldier_attack_laser);
-       missile.angles = vectoangles(missile.velocity);
-       missile.touch = soldier_laser_touch;
-
-       missile.flags = FL_PROJECTILE;
-       missile.missile_flags = MIF_SPLASH;
-       missile.movetype = MOVETYPE_FLY;
-       
-       missile.think = SUB_Remove;
-       missile.nextthink = time + 5;
-       
-       CSQCProjectile(missile, TRUE, PROJECTILE_LASER, TRUE);
-}
-
-float marine_attack(float attack_type)
-{
-       switch(attack_type)
-       {
-               case MONSTER_ATTACK_MELEE:
-               {
-                       monsters_setframe(soldier_anim_shoot);
-                       self.attack_finished_single = time + 0.8;
-                       monster_melee(self.enemy, autocvar_g_monster_soldier_melee_damage, 0.3, DEATH_MONSTER_MARINE_SLAP, TRUE);
-                       
-                       return TRUE;
-               }
-               case MONSTER_ATTACK_RANGED:
-               {
-                       if(self.currentammo <= 0)
-                       {
-                               soldier_reload();
-                               
-                               return FALSE;
-                       }
-                       
-                       monsters_setframe(soldier_anim_shoot);
-                       monster_makevectors(self.enemy);
-                       self.grunt_cycles = 0;
-       
-                       switch(self.weapon)
-                       {
-                               case WEP_ROCKET_LAUNCHER:
-                               {
-                                       self.currentammo -= 1;
-                                       self.attack_finished_single = time + 0.8;
-                                       soldier_rocket_fire();
-                                       
-                                       return TRUE;
-                               }
-                               case WEP_SHOTGUN:
-                               {
-                                       self.currentammo -= 1;
-                                       self.attack_finished_single = time + 0.8;
-                                       soldier_shotgun_fire();
-                                       
-                                       return TRUE;
-                               }
-                               case WEP_UZI:
-                               {
-                                       self.attack_finished_single = time + 0.8;
-                                       self.delay = time + 0.1;
-                                       self.monster_delayedattack = soldier_uzi_fire;
-                                       
-                                       return TRUE;
-                               }
-                               case WEP_LASER:
-                               {
-                                       self.attack_finished_single = time + 0.8;
-                                       soldier_laser_fire();
-                                       
-                                       return TRUE;
-                               }
-                       }
-                       
-                       return FALSE;
-               }
-       }
-       
-       return FALSE;
-}
-
-void soldier_die()
-{
-       Monster_CheckDropCvars ("soldier");
-       
-       self.think = monster_dead_think;
-       self.nextthink = time + self.ticrate;
-       self.ltime = time + 5;
-       monsters_setframe((random() > 0.5) ? soldier_anim_die1 : soldier_anim_die2);
-               
-       monster_hook_death(); // for post-death mods
-}
-
-void soldier_spawn ()
-{
-       if not(self.health)
-               self.health = autocvar_g_monster_soldier_health;
-
-       self.damageforcescale   = 0.003;
-       self.classname                  = "monster_soldier";
-       self.monster_attackfunc = marine_attack;
-       self.nextthink                  = time + random() * 0.5 + 0.1;
-       self.think                              = soldier_think;
-       self.currentammo                = 3;
-       self.items                              = (IT_SHELLS | IT_ROCKETS | IT_NAILS);
-       
-       monsters_setframe(soldier_anim_draw);
-       
-       monster_setupsounds("soldier");
-       
-       setmodel(self, SOLDIER_MODEL);
-       
-       RandomSelection_Init();
-       RandomSelection_Add(world, WEP_LASER, string_null, autocvar_g_monster_soldier_weapon_laser_chance, 1);
-       RandomSelection_Add(world, WEP_SHOTGUN, string_null, autocvar_g_monster_soldier_weapon_shotgun_chance, 1);
-       RandomSelection_Add(world, WEP_UZI, string_null, autocvar_g_monster_soldier_weapon_machinegun_chance, 1);
-       RandomSelection_Add(world, WEP_ROCKET_LAUNCHER, string_null, autocvar_g_monster_soldier_weapon_rocketlauncher_chance, 1);
-       
-       self.weaponentity = spawn();
-       self.weaponentity.movetype = MOVETYPE_NOCLIP;
-       self.weaponentity.team = self.team;
-       self.weaponentity.solid = SOLID_NOT;
-       self.weaponentity.owner = self.weaponentity.realowner = self;
-       setmodel(self.weaponentity, "models/weapons/v_seeker.md3");
-       setattachment(self.weaponentity, self, "bip01 r hand");
-       
-       self.armorvalue = bound(0.5, random(), 1);
-       self.weapon = RandomSelection_chosen_float;
-
-       monster_hook_spawn(); // for post-spawn mods
-}
-
-void spawnfunc_monster_marine()
-{      
-       if not(autocvar_g_monster_soldier) { remove(self); return; }
-       
-       self.monster_spawnfunc = spawnfunc_monster_marine;
-       
-       if(Monster_CheckAppearFlags(self))
-               return;
-               
-       precache_model("models/weapons/v_seeker.md3");
-       precache_model(SOLDIER_MODEL);
-       
-       if not (monster_initialize(
-                        "Marine", MONSTER_MARINE,
-                        SOLDIER_MIN, SOLDIER_MAX,
-                        FALSE,
-                        soldier_die, soldier_spawn))
-       {
-               remove(self);
-               return;
-       }
-}
-
-// compatibility with old spawns
-void spawnfunc_monster_army() { spawnfunc_monster_marine(); }
-
-#endif // SVQC
index d633c2c9d55344a66232a787aa70f222de5e9bb4..aa46643b58929ea9e1936e563c317acc52b617a3 100644 (file)
@@ -10,7 +10,7 @@
 #include "monster/animus.qc"
 #include "monster/shambler.qc"
 #include "monster/bruiser.qc"
-#include "monster/soldier.qc"
+#include "monster/marine.qc"
 #include "monster/wyvern.qc"
 #include "monster/cerberus.qc"
 #include "monster/slime.qc"
index 79f1c7a3f9bc56e35db644b2c23542efc8b29c5c..d0204ae6e5ca7f7c9632d274a4471ebb8949db57 100644 (file)
@@ -449,7 +449,7 @@ float RandomMonster()
        
        if(n_animuses) RandomSelection_Add(world, MONSTER_ANIMUS, "", 1, 1);
        if(n_mages) RandomSelection_Add(world, MONSTER_MAGE, "", 1, 1);
-       if(n_soldiers) RandomSelection_Add(world, MONSTER_MARINE, "", 1, 1);
+       if(n_marines) RandomSelection_Add(world, MONSTER_MARINE, "", 1, 1);
        if(n_knights) RandomSelection_Add(world, MONSTER_KNIGHT, "", 1, 1);
        if(n_zombies) RandomSelection_Add(world, MONSTER_ZOMBIE, "", 1, 1);
        if(n_spiders) RandomSelection_Add(world, MONSTER_SPIDER, "", 1, 1);
@@ -507,7 +507,7 @@ void queue_monsters(float maxmonsters)
        n_cerberuses    = DistributeEvenly_Get(1);
        n_bruisers      = DistributeEvenly_Get(1);
        n_mages                 = DistributeEvenly_Get(1);
-       n_soldiers      = DistributeEvenly_Get(1);
+       n_marines       = DistributeEvenly_Get(1);
        n_knights       = DistributeEvenly_Get(1);
        n_zombies       = DistributeEvenly_Get(1);
        n_spiders       = DistributeEvenly_Get(1);
@@ -843,7 +843,7 @@ MUTATOR_HOOKFUNCTION(td_MonsterSpawn)
                case MONSTER_ANIMUS: n_animuses -= 1; break;
                case MONSTER_SHAMBLER: n_shamblers -= 1; break;
                case MONSTER_BRUISER: n_bruisers -= 1; break;
-               case MONSTER_MARINE: n_soldiers -= 1; break;
+               case MONSTER_MARINE: n_marines -= 1; break;
                case MONSTER_WYVERN: n_wyverns -= 1; break;
                case MONSTER_CERBERUS: n_cerberuses -= 1; break;
                case MONSTER_SLIME: n_slimes -= 1; break;
index 67049fc4caf96c2db6ec46978056b0bf7e45fad4..2086ee60eece723359ade3e28afbef4b1c39b133 100644 (file)
@@ -1,6 +1,6 @@
 // Counters
 float monster_count, totalmonsters;
-float n_bruisers, n_cerberuses, n_ogres, n_shamblers, n_wyverns, n_mages, n_soldiers, n_knights, n_animuses, n_zombies, n_slimes, n_fish, n_spiders;
+float n_bruisers, n_cerberuses, n_ogres, n_shamblers, n_wyverns, n_mages, n_marines, n_knights, n_animuses, n_zombies, n_slimes, n_fish, n_spiders;
 float current_monsters;
 float waterspawns_count, flyspawns_count;
 float wave_count, max_waves;