]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Monsters!
authorMario <mario.mario@y7mail.com>
Tue, 22 Jan 2013 10:02:56 +0000 (21:02 +1100)
committerMario <mario.mario@y7mail.com>
Tue, 22 Jan 2013 10:02:56 +0000 (21:02 +1100)
82 files changed:
balanceXonotic.cfg
commands.cfg
defaultXonotic.cfg
gamemodes.cfg
models/monsters/demon.mdl [new file with mode: 0644]
models/monsters/demon.mdl.framegroups [new file with mode: 0644]
models/monsters/demon.txt [new file with mode: 0644]
models/monsters/dog.dpm [new file with mode: 0644]
models/monsters/dog.dpm.framegroups [new file with mode: 0644]
models/monsters/dog.txt [new file with mode: 0644]
models/monsters/enforcer.mdl [new file with mode: 0644]
models/monsters/enforcer.mdl.framegroups [new file with mode: 0644]
models/monsters/enforcer.txt [new file with mode: 0644]
models/monsters/fish.mdl [new file with mode: 0644]
models/monsters/fish.mdl.framegroups [new file with mode: 0644]
models/monsters/gpl.txt [new file with mode: 0644]
models/monsters/hknight.mdl [new file with mode: 0644]
models/monsters/hknight.mdl.framegroups [new file with mode: 0644]
models/monsters/hknight.txt [new file with mode: 0644]
models/monsters/knight.mdl [new file with mode: 0644]
models/monsters/knight.mdl.framegroups [new file with mode: 0644]
models/monsters/knight.txt [new file with mode: 0644]
models/monsters/monsters.txt [new file with mode: 0644]
models/monsters/ogre.mdl [new file with mode: 0644]
models/monsters/ogre.mdl.framegroups [new file with mode: 0644]
models/monsters/shalrath.mdl [new file with mode: 0644]
models/monsters/shalrath.mdl.framegroups [new file with mode: 0644]
models/monsters/shambler.mdl [new file with mode: 0644]
models/monsters/shambler.mdl.framegroups [new file with mode: 0644]
models/monsters/soldier.mdl [new file with mode: 0644]
models/monsters/soldier.mdl.framegroups [new file with mode: 0644]
models/monsters/spider.dpm [new file with mode: 0644]
models/monsters/spider.dpm.framegroups [new file with mode: 0644]
models/monsters/spider.txt [new file with mode: 0644]
models/monsters/tarbaby.mdl [new file with mode: 0644]
models/monsters/tarbaby.mdl.framegroups [new file with mode: 0644]
models/monsters/wizard.mdl [new file with mode: 0644]
models/monsters/wizard.mdl.framegroups [new file with mode: 0644]
models/monsters/wizard.txt [new file with mode: 0644]
models/monsters/zombie.dpm_0.skin [new file with mode: 0644]
models/monsters/zombie.dpm_1.skin [new file with mode: 0644]
models/monsters/zombie.dpm_2.skin [new file with mode: 0644]
monsters.cfg [new file with mode: 0644]
qcsrc/client/hud.qc
qcsrc/client/scoreboard.qc
qcsrc/common/constants.qh
qcsrc/common/mapinfo.qc
qcsrc/common/mapinfo.qh
qcsrc/server/accuracy.qc
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc
qcsrc/server/cl_physics.qc
qcsrc/server/cl_player.qc
qcsrc/server/cl_weapons.qc
qcsrc/server/cl_weaponsystem.qc
qcsrc/server/command/cmd.qc
qcsrc/server/command/cmd.qh
qcsrc/server/command/sv_cmd.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_hook.qc
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/movelib.qc
qcsrc/server/mutators/base.qh
qcsrc/server/mutators/mutators.qh
qcsrc/server/progs.src
qcsrc/server/sv_main.qc
qcsrc/server/teamplay.qc
qcsrc/server/tturrets/system/system_damage.qc
qcsrc/server/tturrets/system/system_main.qc
qcsrc/server/tturrets/system/system_scoreprocs.qc
qcsrc/server/tturrets/units/unit_fusionreactor.qc
qcsrc/server/tturrets/units/unit_walker.qc
qcsrc/server/w_all.qc
qcsrc/server/w_electro.qc
textures/bloodyskull_pants.jpg [new file with mode: 0644]
textures/cerberus/cerberus_text.png [new file with mode: 0644]
textures/cerberus/cerberus_text_pants.png [new file with mode: 0644]
textures/meat_pants.tga [new file with mode: 0644]
textures/spider/spidertex.tga [new file with mode: 0644]
za.cfg [new file with mode: 0644]

index 871b9a390f2a39fc8daa1b59d6f0bbe34f3b50fa..6e65eced5c264653691d2bb1458dab99c6e57b9e 100644 (file)
@@ -15,6 +15,7 @@ set g_start_weapon_porto -1 "0 = never provide the weapon, 1 = always provide th
 set g_start_weapon_hook -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
 set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
 set g_start_weapon_fireball -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+set g_start_weapon_incubator -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
 set g_balance_health_start 100
 set g_balance_armor_start 0
 set g_start_ammo_shells 15
index 44fa671bd7f88e4ace9f1c4be2cf0e3929ad1542..091cf49ee51c4db04c787a284155e90c154ec596 100644 (file)
@@ -152,6 +152,7 @@ alias reportcvar           "qc_cmd_cmd    reportcvar           ${* ?}" // Old sy
 alias selectteam           "qc_cmd_cmd    selectteam           ${* ?}" // Attempt to choose a team to join into
 alias selfstuff            "qc_cmd_cmd    selfstuff            ${* ?}" // Stuffcmd a command to your own client
 alias sentcvar             "qc_cmd_cmd    sentcvar             ${* ?}" // New system for sending a client cvar to the server
+alias spawnmob                    "qc_cmd_cmd    mobspawn                         ${* ?}" // Spawn a monster infront of the player
 alias spectate             "qc_cmd_cmd    spectate             ${* ?}" // Become an observer
 alias suggestmap           "qc_cmd_cmd    suggestmap           ${* ?}" // Suggest a map to the mapvote at match end
 //alias tell               "qc_cmd_cmd    tell                 ${* ?}" // Send a message directly to a player
@@ -170,6 +171,9 @@ alias spec "spectate"
 
 // mutator aliases
 alias sandbox "cmd g_sandbox ${* ?}"
+alias spawnturret "cmd turretspawn ${* ?}"
+alias debugmonsters "cmd debugmonsters ${* ?}"
+alias upgradeturret "cmd buffturret ${* ?}"
 
 
 // ============================================================
@@ -181,6 +185,7 @@ alias allspec              "qc_cmd_sv     allspec              ${* ?}" // Force
 alias anticheat            "qc_cmd_sv     anticheat            ${* ?}" // Create an anticheat report for a client
 alias bbox                 "qc_cmd_sv     bbox                 ${* ?}" // Print detailed information about world size
 alias bot_cmd              "qc_cmd_sv     bot_cmd              ${* ?}" // Control and send commands to bots
+alias butcher                     "qc_cmd_sv     butcher                          ${* ?}" // Remove all monsters on the map
 alias cointoss             "qc_cmd_sv     cointoss             ${* ?}" // Flip a virtual coin and give random result
 alias database             "qc_cmd_sv     database             ${* ?}" // Extra controls of the serverprogs database
 alias defer_clear          "qc_cmd_sv     defer_clear          ${* ?}" // Clear all queued defer commands for a specific client
index 1ad85c8bd01da28797e5aaa8cf42a8a97fd3b321..fc397ca7a740641d2a132da8b93c948a97d40988 100644 (file)
@@ -1388,6 +1388,7 @@ set g_weaponreplace_minstanex ""
 set g_weaponreplace_hook ""
 set g_weaponreplace_tuba ""
 set g_weaponreplace_fireball ""
+set g_weaponreplace_incubator ""
 set sv_q3acompat_machineshotgunswap 0 "shorthand for swapping uzi and shotgun (for Q3A map compatibility in mapinfo files)"
 
 set g_movement_highspeed 1 "movement speed modification factor (only changes movement when above maxspeed)"
@@ -1546,6 +1547,8 @@ exec turrets.cfg
 exec vehicles.cfg
 exec crosshairs.cfg
 exec gamemodes.cfg
+exec monsters.cfg
+exec za.cfg
 
 // load console command aliases and settings
 exec commands.cfg
index 6cff7e5a42666ab32954c8ec8d5abb757b1a09f6..94926ebaa2cb1b78fa96de11d4048a1f7f7da2e5 100644 (file)
@@ -38,6 +38,7 @@ alias cl_hook_gamestart_nb
 alias cl_hook_gamestart_cts
 alias cl_hook_gamestart_ka
 alias cl_hook_gamestart_ft
+alias cl_hook_gamestart_td
 alias cl_hook_gameend
 alias cl_hook_activeweapon
 
@@ -60,6 +61,7 @@ alias sv_hook_gamestart_nb
 alias sv_hook_gamestart_cts
 alias sv_hook_gamestart_ka
 alias sv_hook_gamestart_ft
+alias sv_hook_gamestart_td
 alias sv_hook_gamerestart
 alias sv_hook_gameend
 
@@ -141,6 +143,9 @@ set g_cts_weapon_stay 2
 set g_ft_respawn_waves 0
 set g_ft_respawn_delay 0
 set g_ft_weapon_stay 0
+set g_td_respawn_waves 0
+set g_td_respawn_delay 0
+set g_td_weapon_stay 0
 
 
 // =======
@@ -472,3 +477,30 @@ set g_balance_rune_speed_highspeed                 1.5
 set g_balance_curse_slow_highspeed                     0.6
 set g_balance_rune_speed_combo_highspeed                       0.9
 
+// ===============
+//  tower defense
+// ===============
+set g_td 0 "Tower Defense: protect the generator/s from waves of monsters"
+set g_td_force_settings 0 "if enabled, don't use map settings (monster count, start wave etc.)"
+set g_td_start_wave 1
+set g_td_generator_health 700
+set g_td_generator_damaged_points 20 "player loses this many points if the generator was damaged during the wave"
+set g_td_current_monsters 10 "maximum monsters that can be spawned simultaneously"
+set g_td_miniboss_min_monsters 5 "monster count to start spawning minibosses at"
+set g_td_monster_count 10
+set g_td_monster_count_increment 5
+set g_td_hardcore 0 "if enabled, players can't respawn during combat phase"
+set g_td_buildphase_time 20
+set g_td_generator_dontend 0 "don't change maps when a generator is destroyed (only if there is more than 1 generator)"
+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_max_waves 8
+set g_td_kill_points 5
+set g_td_turretkill_points 3
+set g_td_turret_max 4
+set g_td_turret_plasma_cost 50
+set g_td_turret_mlrs_cost 80
+set g_td_turret_walker_cost 100
+set g_td_tower_buff_cost 70
diff --git a/models/monsters/demon.mdl b/models/monsters/demon.mdl
new file mode 100644 (file)
index 0000000..d2a566b
Binary files /dev/null and b/models/monsters/demon.mdl differ
diff --git a/models/monsters/demon.mdl.framegroups b/models/monsters/demon.mdl.framegroups
new file mode 100644 (file)
index 0000000..b87a087
--- /dev/null
@@ -0,0 +1 @@
+1 12 10 1 // demon stand\r14 7 10 1 // demon walk\r22 5 10 1 // demon run\r28 11 10 0 // demon leap\r40 5 10 0 // demon pain\r46 8 10 0 // demon death\r55 14 10 1 // demon melee
\ No newline at end of file
diff --git a/models/monsters/demon.txt b/models/monsters/demon.txt
new file mode 100644 (file)
index 0000000..fa60336
--- /dev/null
@@ -0,0 +1,25 @@
+Fiendish Deamon Doll model
+
+Copyright (C) 2003 Ulrich Gablraith
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+History:
+
+7-5-04
+
+The model was given to Mapes so he could port it into OpenQuartz by permission.
+
+Greg Mapes
\ No newline at end of file
diff --git a/models/monsters/dog.dpm b/models/monsters/dog.dpm
new file mode 100644 (file)
index 0000000..e220158
Binary files /dev/null and b/models/monsters/dog.dpm differ
diff --git a/models/monsters/dog.dpm.framegroups b/models/monsters/dog.dpm.framegroups
new file mode 100644 (file)
index 0000000..9ace1c4
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+Generated framegroups file for dog
+Used by DarkPlaces to simulate frame groups in DPM models.
+*/
+
+1 25 60 1 // dog idle
+26 37 60 1 // dog walk
+63 37 120 1 // dog run
+100 50 60 1 // dog attack
+150 42 60 0 // dog die
+192 25 60 1 // dog pain
diff --git a/models/monsters/dog.txt b/models/monsters/dog.txt
new file mode 100644 (file)
index 0000000..4cd5dde
--- /dev/null
@@ -0,0 +1 @@
+This cerberus model is GPL 2.0 compatible (http://opengameart.org/content/animated-cerberus).
\ No newline at end of file
diff --git a/models/monsters/enforcer.mdl b/models/monsters/enforcer.mdl
new file mode 100644 (file)
index 0000000..b52fe4f
Binary files /dev/null and b/models/monsters/enforcer.mdl differ
diff --git a/models/monsters/enforcer.mdl.framegroups b/models/monsters/enforcer.mdl.framegroups
new file mode 100644 (file)
index 0000000..b767b2b
--- /dev/null
@@ -0,0 +1 @@
+1 6 10 1 // enforcer stand\r8 15 10 1 // enforcer walk\r24 7 10 1 // enforcer run\r32 9 10 1 // enforcer attack\r42 13 10 0 // enforcer death1\r56 10 10 0 // enforcer death2\r67 3 10 0 // enforcer pain1\r71 4 10 0 // enforcer pain2\r76 7 10 0 // enforcer pain3\r84 18 10 0 // enforcer pain4
\ No newline at end of file
diff --git a/models/monsters/enforcer.txt b/models/monsters/enforcer.txt
new file mode 100644 (file)
index 0000000..6a85459
--- /dev/null
@@ -0,0 +1,28 @@
+Enforcer
+
+Copyright (C) 2004  Greg Mapes
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+7-7-04
+First Release:
+
+Greg Mapes
+
+7-11-04
+
+The gun was a bit long and stuck through a lot of walls and other surfaces when it died, so it got revised.
+
+Greg Mapes
diff --git a/models/monsters/fish.mdl b/models/monsters/fish.mdl
new file mode 100644 (file)
index 0000000..e1db999
Binary files /dev/null and b/models/monsters/fish.mdl differ
diff --git a/models/monsters/fish.mdl.framegroups b/models/monsters/fish.mdl.framegroups
new file mode 100644 (file)
index 0000000..bf18b81
--- /dev/null
@@ -0,0 +1 @@
+1 17 10 1 // fish attack\r19 19 10 0 // fish death\r41 16 10 1 // fish swim\r59 8 10 0 // fish pain
\ No newline at end of file
diff --git a/models/monsters/gpl.txt b/models/monsters/gpl.txt
new file mode 100644 (file)
index 0000000..6bf61e7
--- /dev/null
@@ -0,0 +1 @@
+All the models in this folder (except zombie.dpm) were copied from the GPL project OpenQuartz 2 (http://www.quakewiki.net/openquartz-2).
\ No newline at end of file
diff --git a/models/monsters/hknight.mdl b/models/monsters/hknight.mdl
new file mode 100644 (file)
index 0000000..a0cd4d7
Binary files /dev/null and b/models/monsters/hknight.mdl differ
diff --git a/models/monsters/hknight.mdl.framegroups b/models/monsters/hknight.mdl.framegroups
new file mode 100644 (file)
index 0000000..cc16b30
--- /dev/null
@@ -0,0 +1 @@
+1 8 10 1 // hellknight stand\r10 19 10 1 // hellknight walk\r30 7 10 1 // hellknight run\r38 4 10 0 // hellknight pain\r43 11 10 0 // hellknight death1\r55 8 10 0 // hellknight death2\r64 15 10 0 // hellknight charge1\r80 13 10 0 // hellknight magic1\r94 12 10 0 // hellknight magic2\r107 5 10 0 // hellknight charge2\r113 9 10 1 // hellknight slice\r123 9 10 1 // hellknight smash\r133 21 10 1 // hellknight weapon attack\r155 10 10 0 //hellknight magic3
\ No newline at end of file
diff --git a/models/monsters/hknight.txt b/models/monsters/hknight.txt
new file mode 100644 (file)
index 0000000..1dffdb7
--- /dev/null
@@ -0,0 +1,25 @@
+Hooded model
+
+Copyright (C) 2003 Ulrich Gablraith
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+History:
+
+7-5-04
+
+The model was given to Mapes so he could port it into OpenQuartz by permission.
+
+Greg Mapes
\ No newline at end of file
diff --git a/models/monsters/knight.mdl b/models/monsters/knight.mdl
new file mode 100644 (file)
index 0000000..36ebd61
Binary files /dev/null and b/models/monsters/knight.mdl differ
diff --git a/models/monsters/knight.mdl.framegroups b/models/monsters/knight.mdl.framegroups
new file mode 100644 (file)
index 0000000..c4acc5e
--- /dev/null
@@ -0,0 +1 @@
+1 8 10 1 // knight stand\r10 7 10 1 // knight run\r18 10 10 1 // knight run attack\r29 2 10 0 // knight pain1\r32 10 10 0 // knight pain2\r43 9 10 1 // knight attack\r53 13 10 1 // knight walk\r67 4 10 0 // knight kneel\r72 4 10 1 // knight standing\r77 9 10 0 // knight death1\r88 10 10 0 // knight death2
\ No newline at end of file
diff --git a/models/monsters/knight.txt b/models/monsters/knight.txt
new file mode 100644 (file)
index 0000000..59cec6c
--- /dev/null
@@ -0,0 +1,25 @@
+Knight model
+
+Copyright (C) 2004 Ulrich Gablraith
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+History:
+
+7-5-04
+
+The model was given to Mapes so he could port it into OpenQuartz by permission.
+
+Greg Mapes
\ No newline at end of file
diff --git a/models/monsters/monsters.txt b/models/monsters/monsters.txt
new file mode 100644 (file)
index 0000000..9e55cb8
--- /dev/null
@@ -0,0 +1,31 @@
+Monsters -Phantom Knight, Magical Knight, Master Knight, Knight, Jack-o-Lantern,
+        -Doll Fiend.
+
+Copyright (C) 2004  Ulrich Galbraith
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Ulrich Galbraith
+ugalbrai@krl.org
+
+
+7-22-04
+
+First release
+
+I had to give some of them proper animation and proper connecting models so they would work.
+
+-Mapes
\ No newline at end of file
diff --git a/models/monsters/ogre.mdl b/models/monsters/ogre.mdl
new file mode 100644 (file)
index 0000000..a0cd4d7
Binary files /dev/null and b/models/monsters/ogre.mdl differ
diff --git a/models/monsters/ogre.mdl.framegroups b/models/monsters/ogre.mdl.framegroups
new file mode 100644 (file)
index 0000000..0d69386
--- /dev/null
@@ -0,0 +1 @@
+1 8 10 1 // ogre stand\r10 15 10 1 // ogre walk\r26 7 10 1 // ogre run\r34 13 10 1 // ogre swing\r48 13 10 1 // ogre smash\r62 5 10 1 // ogre shoot\r68 4 10 0 // ogre pain1\r73 2 10 0 // ogre pain2\r76 5 10 0 // ogre pain3\r82 15 10 0 // ogre pain4\r98 14 10 0 // ogre pain5\r113 13 10 0 // ogre death1\r127 9 10 0 // ogre death2\r137 10 10 0 // ogre pull
\ No newline at end of file
diff --git a/models/monsters/shalrath.mdl b/models/monsters/shalrath.mdl
new file mode 100644 (file)
index 0000000..bfa4ec2
Binary files /dev/null and b/models/monsters/shalrath.mdl differ
diff --git a/models/monsters/shalrath.mdl.framegroups b/models/monsters/shalrath.mdl.framegroups
new file mode 100644 (file)
index 0000000..35108f5
--- /dev/null
@@ -0,0 +1 @@
+1 10 10 1 // shalrath attack\r12 4 10 0 // shalrath pain\r18 5 10 0 // shalrath death\r26 12 10 1 // shalrath walk
\ No newline at end of file
diff --git a/models/monsters/shambler.mdl b/models/monsters/shambler.mdl
new file mode 100644 (file)
index 0000000..2e23dfa
Binary files /dev/null and b/models/monsters/shambler.mdl differ
diff --git a/models/monsters/shambler.mdl.framegroups b/models/monsters/shambler.mdl.framegroups
new file mode 100644 (file)
index 0000000..b003d56
--- /dev/null
@@ -0,0 +1 @@
+1 16 10 1 // shambler stand\r18 11 10 1 // shambler walk\r31 5 10 1 // shambler run\r37 11 10 1 // shambler smash\r49 8 10 1 // shambler swing right\r58 8 10 1 // shambler swing left\r67 11 10 1 // shambler magic\r79 5 10 0 // shambler pain\r85 10 10 0 // shambler death
\ No newline at end of file
diff --git a/models/monsters/soldier.mdl b/models/monsters/soldier.mdl
new file mode 100644 (file)
index 0000000..a0cd4d7
Binary files /dev/null and b/models/monsters/soldier.mdl differ
diff --git a/models/monsters/soldier.mdl.framegroups b/models/monsters/soldier.mdl.framegroups
new file mode 100644 (file)
index 0000000..0d69386
--- /dev/null
@@ -0,0 +1 @@
+1 8 10 1 // ogre stand\r10 15 10 1 // ogre walk\r26 7 10 1 // ogre run\r34 13 10 1 // ogre swing\r48 13 10 1 // ogre smash\r62 5 10 1 // ogre shoot\r68 4 10 0 // ogre pain1\r73 2 10 0 // ogre pain2\r76 5 10 0 // ogre pain3\r82 15 10 0 // ogre pain4\r98 14 10 0 // ogre pain5\r113 13 10 0 // ogre death1\r127 9 10 0 // ogre death2\r137 10 10 0 // ogre pull
\ No newline at end of file
diff --git a/models/monsters/spider.dpm b/models/monsters/spider.dpm
new file mode 100644 (file)
index 0000000..d0bc9ce
Binary files /dev/null and b/models/monsters/spider.dpm differ
diff --git a/models/monsters/spider.dpm.framegroups b/models/monsters/spider.dpm.framegroups
new file mode 100644 (file)
index 0000000..039a7c3
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+Generated framegroups file for spider
+Used by DarkPlaces to simulate frame groups in DPM models.
+*/
+
+1 60 60 1 // spider idle
+61 41 120 1 // spider walk
+102 24 60 1 // spider attack
+125 10 60 1 // spider attack2
\ No newline at end of file
diff --git a/models/monsters/spider.txt b/models/monsters/spider.txt
new file mode 100644 (file)
index 0000000..7d7cdaf
--- /dev/null
@@ -0,0 +1 @@
+This spider model is GPL 2.0 compatible (http://opengameart.org/content/low-poly-spider-glest).
\ No newline at end of file
diff --git a/models/monsters/tarbaby.mdl b/models/monsters/tarbaby.mdl
new file mode 100644 (file)
index 0000000..db8c318
Binary files /dev/null and b/models/monsters/tarbaby.mdl differ
diff --git a/models/monsters/tarbaby.mdl.framegroups b/models/monsters/tarbaby.mdl.framegroups
new file mode 100644 (file)
index 0000000..7271df4
--- /dev/null
@@ -0,0 +1 @@
+1 24 10 1 // tarbaby walk\r26 24 10 1 // tarbaby run\r51 5 10 0 // tarbaby jump\r57 3 10 1 // tarbaby fly\r61 1 10 0 // tarbaby explode
\ No newline at end of file
diff --git a/models/monsters/wizard.mdl b/models/monsters/wizard.mdl
new file mode 100644 (file)
index 0000000..b130ba0
Binary files /dev/null and b/models/monsters/wizard.mdl differ
diff --git a/models/monsters/wizard.mdl.framegroups b/models/monsters/wizard.mdl.framegroups
new file mode 100644 (file)
index 0000000..c51109a
--- /dev/null
@@ -0,0 +1 @@
+1 14 10 1 // wizard hover\r16 13 10 1 // wizard fly\r30 12 10 1 // wizard magic attack\r43 3 10 0 // wizard pain\r47 7 10 0 // wizard death
\ No newline at end of file
diff --git a/models/monsters/wizard.txt b/models/monsters/wizard.txt
new file mode 100644 (file)
index 0000000..3b00dde
--- /dev/null
@@ -0,0 +1,31 @@
+pterascragg model
+
+Copyright (C) 2000  Dylan "lithiumbat" Sartain
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+History:
+
+7-11-00
+
+First release
+build time: about 2 hrs spread over three days
+model was made as a replacement for the scragg or wizard.
+
+7-13-00
+
+Seth Galbraith (sgalbrai@krl.org):
+Lowered death frame to lie on the ground
+Created head gib model
diff --git a/models/monsters/zombie.dpm_0.skin b/models/monsters/zombie.dpm_0.skin
new file mode 100644 (file)
index 0000000..19ad7a7
--- /dev/null
@@ -0,0 +1,2 @@
+bloodyskull,bloodyskull
+meat,meat
\ No newline at end of file
diff --git a/models/monsters/zombie.dpm_1.skin b/models/monsters/zombie.dpm_1.skin
new file mode 100644 (file)
index 0000000..1561520
--- /dev/null
@@ -0,0 +1,2 @@
+bloodyskull,bloodyskull_alien
+meat,meat_alien
\ No newline at end of file
diff --git a/models/monsters/zombie.dpm_2.skin b/models/monsters/zombie.dpm_2.skin
new file mode 100644 (file)
index 0000000..e00379e
--- /dev/null
@@ -0,0 +1,2 @@
+bloodyskull,bloodyskull_robot
+meat,meat_robot
\ No newline at end of file
diff --git a/monsters.cfg b/monsters.cfg
new file mode 100644 (file)
index 0000000..5a9007b
--- /dev/null
@@ -0,0 +1,210 @@
+// Misc
+set g_monsters 1 "Enable monsters (master switch)"
+set g_monsters_skill 1 "Monster skill (affecting some of their attributes). 1 - easy, 2 - medium, 3 - hard, 4 - insane, 5 - nightmare"
+set g_monsters_miniboss_chance 5
+set g_monsters_miniboss_healthboost 100
+set g_monsters_forcedrop "" "Force all monsters to drop this item on death. Possible values are: health, armor, ammo"
+set g_monsters_drop_size medium "Size of the item monsters drop. Possible health/amor values are: small, medium, large. Possible ammo values are: shells, bullets, cells, rockets"
+set g_monsters_owners 1 "Monsters will not attack their owners if set to 1"
+set g_monsters_teams 1
+set g_monster_spawnshieldtime 2 "Monsters will not take damage for this amount of seconds"
+set g_monsters_typefrag 1
+set g_monsters_healthbars 1 "Show health bars above monsters"
+set g_monsters_giants_only 0
+set g_monsters_nogiants 1
+set g_monsters_respawn 1 "Enable monster respawning"
+set g_monsters_respawn_delay 20 "Monsters respawn in this amount of seconds"
+set g_monsters_score_kill 1 "Get this many points for killing a naturally spawned monster"
+set g_monsters_max 20 "Global maximum player-spawned monsters"
+set g_monsters_max_perplayer 3 "Maximum monsters per-player"
+set g_monsters_skill_easy 2 "Monster easy skill level (used for skill based functions)"
+set g_monsters_skill_normal 4 "Monster normal skill level (used for skill based functions)"
+set g_monsters_skill_hard 5 "Monster hard skill level (used for skill based functions)"
+set g_monsters_skill_insane 7 "Monster insane skill level (used for skill based functions)"
+set g_monsters_skill_nightmare 10 "Monster nightmare skill level (used for skill based functions)"
+
+// Enforcer
+set g_monster_enforcer 1 "Enable Enforcers"
+set g_monster_enforcer_health 80 "Enforcer health"
+set g_monster_enforcer_drop armor "Enforcer drops this item on death"
+set g_monster_enforcer_drop_size large "Size of the item Enforcers drop. Possible values are: small, medium, large"
+set g_monster_enforcer_speed_walk 75 "Enforcer walk speed"
+set g_monster_enforcer_speed_run 100 "Enforcer run speed"
+set g_monster_enforcer_attack_uzi_bullets 3 "Number of machine gun bullets Enforcer fires"
+
+// Ogre
+set g_monster_ogre 1 "Enable Ogres"
+set g_monster_ogre_health 200 "Ogre health"
+set g_monster_ogre_chainsaw_damage 15 "Ogre chainsaw damage (hits multiple times)"
+set g_monster_ogre_drop ammo "Ogre drops this item on death"
+set g_monster_ogre_drop_size bullets "Size of the item Ogres drop. Possible values are: small, medium, large"
+set g_monster_ogre_speed_walk 100 "Ogre walk speed"
+set g_monster_ogre_speed_run 150 "Ogre run speed"
+set g_monster_ogre_attack_uzi_bullets 3 "Number of machine gun bullets Ogre fires"
+
+// Fiend
+set g_monster_demon 1 "Enable Fiends"
+set g_monster_demon_health 300 "Fiend health"
+set g_monster_demon_attack_jump_damage 40 "Fiend jump attack damage"
+set g_monster_demon_damage 20 "Fiend melee attack damage"
+set g_monster_demon_drop health "Fiend drops this item on death"
+set g_monster_demon_drop_size medium "Size of the item Fiends drop. Possible values are: small, medium, large"
+set g_monster_demon_speed_walk 150 "Fiend walk speed"
+set g_monster_demon_speed_run 300 "Fiend run speed"
+
+// Shambler
+set g_monster_shambler 1 "Enable Shamblers"
+set g_monster_shambler_health 600 "Shambler health"
+set g_monster_shambler_damage 50 "Shambler melee attack damage"
+set g_monster_shambler_attack_lightning_damage 20 "Shambler lightning attack damage per frame"
+set g_monster_shambler_attack_claw_damage 30 "Shambler claw attack damage"
+set g_monster_shambler_drop health "Shambler drops this item on death"
+set g_monster_shambler_drop_size large "Size of the item Shamblers drop. Possible values are: small, medium, large"
+set g_monster_shambler_speed_walk 100 "Shambler walk speed"
+set g_monster_shambler_speed_run 150 "Shambler run speed"
+
+// Knight
+set g_monster_knight 1 "Enable Knights"
+set g_monster_knight_health 75 "Knight Health"
+set g_monster_knight_drop armor "Knight drops this item on death"
+set g_monster_knight_drop_size medium "Size of the item Knights drop. Possible values are: small, medium, large"
+set g_monster_knight_melee_damage 20 "Knight melee attack damage"
+set g_monster_knight_melee_side_damage 10 "Knight melee attack side damage"
+set g_monster_knight_speed_walk 40 "Knight walk speed"
+set g_monster_knight_speed_run 70 "Knight 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 30 "Grunt walk speed"
+set g_monster_soldier_speed_run 50 "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"
+
+// Scrag
+set g_monster_wizard 1 "Enable Scrags"
+set g_monster_wizard_health 80 "Scrag health"
+set g_monster_wizard_drop ammo "Scrag drops this item on death"
+set g_monster_wizard_drop_size cells "Size of the item Scrags drop. Possible values are: small, medium, large"
+set g_monster_wizard_speed_walk 40 "Scrag walk speed"
+set g_monster_wizard_speed_run 70 "Scrag run speed"
+set g_monster_wizard_spike_damage 15 "Scrag spike damage"
+set g_monster_wizard_spike_damage 7 "Scrag spike edge damage"
+set g_monster_wizard_spike_radius 20 "Scrag spike damage radius"
+set g_monster_wizard_spike_speed 400 "Scrag spike speed"
+
+// Rottweiler
+set g_monster_dog 1 "Enable Rottweilers"
+set g_monster_dog_health 25 "Rottweiler health"
+set g_monster_dog_bite_damage 15 "Rottweiler bite attack damage"
+set g_monster_dog_attack_jump_damage 30 "Rottweiler jump attack damage"
+set g_monster_dog_drop health "Rottweiler drops this item on death"
+set g_monster_dog_drop_size small "Size of the item Rottweilers drop. Possible values are: small, medium, large"
+set g_monster_dog_speed_walk 60 "Rottweiler walk speed"
+set g_monster_dog_speed_run 120 "Rottweiler run speed"
+
+// Spawn
+set g_monster_tarbaby 1 "Enable Spawns"
+set g_monster_tarbaby_health 80 "Spawn health"
+set g_monster_tarbaby_drop ammo "Spawn drops this item when it explodes"
+set g_monster_tarbaby_drop_size rockets "Size of the item Spawns drop. Possible values are: small, medium, large"
+set g_monster_tarbaby_speed_walk 20 "Spawn walk speed"
+set g_monster_tarbaby_speed_run 30 "Spawn run speed"
+
+// Hell-Knight
+set g_monster_hellknight 1 "Enable Hell-Knights"
+set g_monster_hellknight_health 250 "Hell-Knight health"
+set g_monster_hellknight_drop armor "Hell-Knight drops this item on death"
+set g_monster_hellknight_drop_size medium "Size of the item Hell-Knights drop. Possible values are: small, medium, large"
+set g_monster_hellknight_inferno_damage 40 "Hell-Knight inferno damage"
+set g_monster_hellknight_inferno_chance 0.4 "Hell-Knight inferno attack chance"
+set g_monster_hellknight_inferno_damagetime 3 "How long the inferno should burn the player"
+set g_monster_hellknight_fireball_damage 30 "Hell-Knight fireball projectile damage"
+set g_monster_hellknight_fireball_edgedamage 10 "Hell-Knight fireball indirect hit damage"
+set g_monster_hellknight_fireball_force 50 "Hell-Knight fireball projectile push force"
+set g_monster_hellknight_fireball_radius 70 "Hell-Knight fireball projectile damage radius"
+set g_monster_hellknight_fireball_speed 600 "Hell-Knight fireball projectile speed"
+set g_monster_hellknight_fireball_spread 0 "Hell-Knight fireball projectile spread"
+set g_monster_hellknight_fireball_chance 0.3 "Chance for Hell-Knight to throw a fireball"
+set g_monster_hellknight_jump_chance 0.2 "Chance for Hell-Knight to jump at the player (always 1 if enemy is further than _dist)"
+set g_monster_hellknight_jump_damage 25 "Hell-Knight jump attack damage"
+set g_monster_hellknight_jump_dist 500 "Hell-Knight will prioritise jumping if the enemy is this far away"
+set g_monster_hellknight_melee_damage 20 "Hell-Knight melee attack damage"
+set g_monster_hellknight_spike_damage 5 "Hell-Knight spike projectile damage"
+set g_monster_hellknight_spike_edgedamage 5 "Hell-Knight spike projectile indirect hit damage"
+set g_monster_hellknight_spike_radius 20 "Hell-Knight spike projectile damage radius"
+set g_monster_hellknight_spike_force 5 "Hell-Knight spike projectile force"
+set g_monster_hellknight_spike_chance 0.5 "Hell-Knight spike attack chance"
+set g_monster_hellknight_speed_walk 75 "Hell-Knight walk speed"
+set g_monster_hellknight_speed_run 150 "Hell-Knight run speed"
+
+// Rotfish
+set g_monster_fish 1 "Enable Rotfish"
+set g_monster_fish_health 25 "Rotfish health"
+set g_monster_fish_damage 10 "Rotfish bite attack damage"
+set g_monster_fish_drop health "Rotfish drops this item on death"
+set g_monster_fish_drop_size small "Size of the item Rotfish drop. Possible values are: small, medium, large"
+set g_monster_fish_speed_walk 40 "Rotfish walk speed"
+set g_monster_fish_speed_run 70 "Rotfish run speed"
+
+// Vore
+set g_monster_shalrath 1 "Enable Vores"
+set g_monster_shalrath_health 400 "Vore health"
+set g_monster_shalrath_damage 30 "Vore magic attack damage"
+set g_monster_shalrath_drop health "Vore drops this item on death"
+set g_monster_shalrath_drop_size medium "Size of the item Vores drop. Possible values are: small, medium, large"
+set g_monster_shalrath_speed 50 "Vore move speed"
+
+// Spawner
+set g_monster_spawner 1 "Enable Monster Spawner"
+set g_monster_spawner_health 100 "Spawner health"
+set g_monster_spawner_target_recheck_delay 1 "Spawner enemy check delay"
+set g_monster_spawner_target_range 600 "Spawner maximum enemy distance"
+set g_monster_spawner_spawn_range 600 "Spawn monsters while enemy is within this range"
+set g_monster_spawner_maxmobs 4 "Maximum number of spawned monsters"
+set g_monster_spawner_forcespawn 0 "Force spawner to spawn this type of monster"
+
+// Zombie
+set g_monster_zombie 1 "Enable Zombies"
+set g_monster_zombie_attack_leap_damage 45 "Damage when zombie performs an attack leap"
+set g_monster_zombie_attack_leap_delay 1.5 "Delay after zombie attack leap"
+set g_monster_zombie_attack_leap_force 55 "Force of zombie attack leap"
+set g_monster_zombie_attack_leap_range 96 "Range of zombie attack leap"
+set g_monster_zombie_attack_leap_speed 500 "The speed of a zombie attack leap"
+set g_monster_zombie_attack_stand_damage 35 "Damage when zombie hits from a standing position"
+set g_monster_zombie_attack_stand_delay 1.2 "Delay after a zombie hits from a standing position"
+set g_monster_zombie_attack_stand_range 48 "Range of a zombie standing position attack"
+set g_monster_zombie_health 200 "Zombie health"
+set g_monster_zombie_idle_timer 1 "Minimum time a zombie can stay idle"
+set g_monster_zombie_speed_walk 150 "Zombie walk speed"
+set g_monster_zombie_speed_run 400 "Zombie run speed"
+set g_monster_zombie_stopspeed 100 "Speed at which zombie stops"
+set g_monster_zombie_target_recheck_delay 5 How much time should a zombie run afer an enemy before checking if it's still in range"
+set g_monster_zombie_target_range 1200 How far the zombie can see an enemy"
+set g_monster_zombie_drop health "Zombie drops this item on death"
+set g_monster_zombie_drop_size large "Size of the item zombies drop. Possible values are: small, medium, large"
+
+// Spider
+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 cc870794b10653a3dea145058a83693ab5282e3b..987da3bfca5659d5bff3fad6963b6b0df0e1426f 100644 (file)
@@ -1978,7 +1978,74 @@ void HUD_KillNotify(string s1, string s2, string s3, float type, float msg) // s
                                        }
                                }
                        }
-               } else if (type == DEATH_CUSTOM) {
+               } else if(DEATH_ISMONSTER(type)) {
+                       HUD_KillNotify_Push(s1, "", 0, DEATH_GENERIC);
+                       if(alsoprint)
+                       {
+                               if(gentle)
+                                       print (sprintf(_("^1%s^1 hit a monster, and the monster hit back\n"), s1));
+                               else
+                               {
+                                       switch(type)
+                                       {
+                                               case DEATH_MONSTER_DEMON_MELEE:
+                                                       print (sprintf(_("^1%s^1 was eviscerated by a Fiend \n"), s1));
+                                                       break;
+                                               case DEATH_MONSTER_DEMON_JUMP:
+                                                       print (sprintf(_("^1%s^1 didn't see the Fiend pouncing at them \n"), s1));
+                                                       break;
+                                               case DEATH_MONSTER_SHAMBLER_MELEE:
+                                                       print (sprintf(_("^1%s^1 was smashed by a Shambler \n"), s1));
+                                                       break;
+                                               case DEATH_MONSTER_SHAMBLER_CLAW:
+                                                       print (sprintf(_("^1%s^1's insides were ripped out by a Shambler \n"), s1));
+                                                       break;
+                                               case DEATH_MONSTER_SHAMBLER_LIGHTNING:
+                                                       print (sprintf(_("^1%s^1 was zapped to death by a Shambler \n"), s1));
+                                                       break;
+                                               case DEATH_MONSTER_SOLDIER_NAIL:
+                                                       print (sprintf(_("^1%s^1 was riddled full of holes by a Soldier \n"), s1));
+                                                       break;
+                                               case DEATH_MONSTER_ENFORCER_NAIL:
+                                                       print (sprintf(_("^1%s^1 was riddled full of holes by an Enforcer \n"), s1));
+                                                       break;
+                                               case DEATH_MONSTER_DOG_BITE:
+                                                       print (sprintf(_("^1%s^1 was mauled by a Rottweiler \n"), s1));
+                                                       break;
+                                               case DEATH_MONSTER_DOG_JUMP:
+                                                       print (sprintf(_("^1%s^1 didn't see the pouncing Rottweiler \n"), s1));
+                                                       break;
+                                               case DEATH_MONSTER_TARBABY_BLOWUP:
+                                                       print (sprintf(_("^1%s^1 was slimed by a Spawn \n"), s1));
+                                                       break;
+                                               case DEATH_MONSTER_FISH_BITE:
+                                                       print (sprintf(_("^1%s^1 was fed to the Rotfish \n"), s1));
+                                                       break;
+                                               case DEATH_MONSTER_HELLFISH_BITE:                       
+                                                       print (sprintf(_("^1%s^1 was eaten alive by a Hellfish \n"), s1));
+                                                       break;
+                        case DEATH_MONSTER_SHALRATH_MELEE:
+                                                       print (sprintf(_("^1%s^1 was exploded by a Vore \n"), s1));
+                                                       break;
+                                               case DEATH_MONSTER_OGRE_CHAINSAW:
+                                                       print (sprintf(_("^1%s^1 was destroyed by an Ogre \n"), s1));
+                                                       break;
+                                               case DEATH_MONSTER_OGRE_NAIL:
+                                                       print (sprintf(_("^1%s^1 was riddled full of holes by an Ogre \n"), s1));
+                                                       break;
+                                               case DEATH_MONSTER_ZOMBIE:
+                                                       print (sprintf(_("^1%s^1's brains were eaten by a Zombie \n"), s1));
+                                                       break;
+                                               case DEATH_MONSTER_HELLKNIGHT_FIREBALL:
+                                                       print (sprintf(_("^1%s^1 was exploded by a Hell-Knight's fireball \n"), s1));
+                                               case DEATH_MONSTER_MELEE:                       
+                                                       print (sprintf(_("^1%s^1 was killed by a monster \n"), s1));
+                                                       break;
+                                       }
+                               }
+                       }
+               }        
+        else if (type == DEATH_CUSTOM) {
                        HUD_KillNotify_Push(s1, "", 0, DEATH_CUSTOM);
                        if(alsoprint)
                                print("^1", sprintf(s2, strcat(s1, "^1")), "\n");
index af982ad46547bd4d2435e56f40e7e929b6d38723..134987fe83da3c71fae5df275e3a473a93777da8 100644 (file)
@@ -1083,15 +1083,30 @@ vector HUD_DrawKeyValue(vector pos, string key, string value) {
 
 vector HUD_DrawMapStats(vector pos, vector rgb, vector bg_size) {
        float stat_secrets_found, stat_secrets_total;
-       float rows;
+       float stat_current_wave, stat_totalwaves;
+       float stat_monsters_killed, stat_monsters_total;
+       float rows = 0;
        string val;
+       
+       // get tower defense stats
+       stat_current_wave = getstatf(STAT_CURRENT_WAVE);
+       stat_totalwaves = getstatf(STAT_TOTALWAVES);
+       
+       // get monster stats
+       stat_monsters_killed = getstatf(STAT_MONSTERS_KILLED);
+       stat_monsters_total = getstatf(STAT_MONSTERS_TOTAL);
 
        // get secrets stats
        stat_secrets_found = getstatf(STAT_SECRETS_FOUND);
        stat_secrets_total = getstatf(STAT_SECRETS_TOTAL);
 
        // get number of rows
-       rows = (stat_secrets_total ? 1 : 0);
+       if(stat_secrets_total)
+               rows += 1;
+       if(stat_totalwaves)
+               rows += 1;
+       if(stat_monsters_total)
+               rows += 1;
 
        // if no rows, return
        if not(rows)
@@ -1111,10 +1126,27 @@ vector HUD_DrawMapStats(vector pos, vector rgb, vector bg_size) {
        else
                drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
        drawborderlines(autocvar_scoreboard_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg * 0.75, DRAWFLAG_NORMAL);
+       
+       // draw waves
+       if(stat_totalwaves)
+       {
+               val = sprintf("%d/%d", stat_current_wave, stat_totalwaves);
+               pos = HUD_DrawKeyValue(pos, _("Current wave:"), val);
+       }
+       
+       // draw monsters
+       if(stat_monsters_total)
+       {
+               val = sprintf("%d/%d", stat_monsters_killed, stat_monsters_total);
+               pos = HUD_DrawKeyValue(pos, _("Monsters killed:"), val);
+       }
 
        // draw secrets
-       val = sprintf("%d/%d", stat_secrets_found, stat_secrets_total);
-       pos = HUD_DrawKeyValue(pos, _("Secrets found:"), val);
+       if(stat_secrets_total)
+       {
+               val = sprintf("%d/%d", stat_secrets_found, stat_secrets_total);
+               pos = HUD_DrawKeyValue(pos, _("Secrets found:"), val);
+       }
        
        // update position
        pos_y += 1.25 * hud_fontsize_y;
index 75f5a0bde762037387dbeb344989a47b1409bc01..133da188ed1decee3087caff4e49d351451a7f87 100644 (file)
@@ -181,6 +181,12 @@ const float STAT_SECRETS_FOUND = 71;
 
 const float STAT_RESPAWN_TIME = 72;
 
+const float STAT_CURRENT_WAVE = 73;
+const float STAT_TOTALWAVES = 74;
+
+const float STAT_MONSTERS_TOTAL = 75;
+const float STAT_MONSTERS_KILLED = 76;
+
 // mod stats (1xx)
 const float STAT_REDALIVE = 100;
 const float STAT_BLUEALIVE = 101;
@@ -427,6 +433,28 @@ float DEATH_TURRET_PHASER           = 10511;
 float DEATH_TURRET_TESLA            = 10512;
 float DEATH_TURRET_LAST            = 10512;
 
+// Monster death types
+float DEATH_MONSTER                        = 10513;
+float DEATH_MONSTER_DEMON_MELEE            = 10514;
+float DEATH_MONSTER_DEMON_JUMP             = 10515;
+float DEATH_MONSTER_SHAMBLER_MELEE         = 10516;
+float DEATH_MONSTER_SHAMBLER_CLAW          = 10517;
+float DEATH_MONSTER_SHAMBLER_LIGHTNING     = 10518;
+float DEATH_MONSTER_SOLDIER_NAIL           = 10519;
+float DEATH_MONSTER_ENFORCER_NAIL          = 10520;
+float DEATH_MONSTER_DOG_BITE               = 10521;
+float DEATH_MONSTER_DOG_JUMP               = 10522;
+float DEATH_MONSTER_TARBABY_BLOWUP         = 10523;
+float DEATH_MONSTER_FISH_BITE              = 10524;
+float DEATH_MONSTER_HELLFISH_BITE          = 10525;
+float DEATH_MONSTER_SHALRATH_MELEE         = 10526;
+float DEATH_MONSTER_OGRE_CHAINSAW          = 10527;
+float DEATH_MONSTER_OGRE_NAIL              = 10528;
+float DEATH_MONSTER_MELEE                  = 10529;
+float DEATH_MONSTER_ZOMBIE                                = 10530;
+float DEATH_MONSTER_HELLKNIGHT_FIREBALL           = 10531;
+float DEATH_MONSTER_LAST                   = 10532;
+
 float DEATH_WEAPONMASK = 0xFF;
 float DEATH_HITTYPEMASK = 0x1F00; // which is WAY below 10000 used for normal deaths
 float HITTYPE_SECONDARY = 0x100;
@@ -442,6 +470,7 @@ float HITTYPE_RESERVED = 0x1000; // unused yet
 #define DEATH_ISWEAPON(t,w)           (!DEATH_ISSPECIAL(t) && DEATH_WEAPONOFWEAPONDEATH(t) == (w))
 #define DEATH_WEAPONOF(t)             (DEATH_ISSPECIAL(t) ? 0 : DEATH_WEAPONOFWEAPONDEATH(t))
 #define WEP_VALID(w)                  ((w) >= WEP_FIRST && (w) <= WEP_LAST)
+#define DEATH_ISMONSTER(t)            ((t) >= DEATH_MONSTER && (t) <= DEATH_MONSTER_LAST)
 
 #define FRAGS_PLAYER 0
 #define FRAGS_SPECTATOR -666
index f7ced420579acb32837ea61f04511d39ddac86f5..606df668fafd96320a5aa6550137a6502b426ec0 100644 (file)
@@ -315,6 +315,8 @@ float _MapInfo_Generate(string pFilename) // 0: failure, 1: ok ent, 2: ok bsp
                                        MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_CTF;
                                else if(v == "runematch_spawn_point")
                                        MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_RUNEMATCH;
+                               else if(v == "td_generator")
+                                       MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_TD;
                                else if(v == "target_assault_roundend")
                                        MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_ASSAULT;
                                else if(v == "onslaught_generator")
index bd67f67a825104abcd3108d8096d501fa8a27762..253c7750bc8ab3498d951b0eb95255ce568930d3 100644 (file)
@@ -39,6 +39,9 @@ REGISTER_GAMETYPE(_("Deathmatch"),dm,g_dm,DEATHMATCH,"timelimit=20 pointlimit=30
 REGISTER_GAMETYPE(_("Last Man Standing"),lms,g_lms,LMS,"timelimit=20 lives=9 leadlimit=0")
 #define g_lms IS_GAMETYPE(LMS)
 
+REGISTER_GAMETYPE(_("Tower Defense"),td,g_td,TD,"timelimit=20 pointlimit=10 leadlimit=0")
+#define g_td IS_GAMETYPE(TD)
+
 REGISTER_GAMETYPE(_("Arena"),arena,g_arena,ARENA,"timelimit=20 pointlimit=10 leadlimit=0")
 #define g_arena IS_GAMETYPE(ARENA)
 
index 9271e03d0ad20ef4b7e8e9a6536d68b723b40348..f7a01d572293ca6c48cf7f500e253567fbfb5e87 100644 (file)
@@ -111,6 +111,7 @@ float accuracy_isgooddamage(entity attacker, entity targ)
 {
        if(!inWarmupStage)
        if(targ.flags & FL_CLIENT)
+       if(!(attacker.flags & FL_MONSTER)) // no accuracy for monsters
        if(targ.deadflag == DEAD_NO)
        if(IsDifferentTeam(attacker, targ))
                return TRUE;
index 433261d45a94b464e25e1e5d4b2b3d6a53aefecd..564c76b151c63705405e7d75b789a10e0352672c 100644 (file)
@@ -1275,3 +1275,47 @@ float autocvar_g_sandbox_object_material_velocity_min;
 float autocvar_g_sandbox_object_material_velocity_factor;
 float autocvar_g_max_info_autoscreenshot;
 float autocvar_physics_ode;
+float autocvar_g_td_start_wave;
+float autocvar_g_td_hardcore;
+float autocvar_g_td_generator_health;
+float autocvar_g_td_current_monsters;
+float autocvar_g_td_generator_damaged_points;
+float autocvar_g_td_monster_count;
+float autocvar_g_td_monster_count_increment;
+float autocvar_g_td_buildphase_time;
+float autocvar_g_td_pvp;
+float autocvar_g_td_max_waves;
+float autocvar_g_td_kill_points;
+float autocvar_g_td_turretkill_points;
+float autocvar_g_td_generator_dontend;
+float autocvar_g_td_force_settings;
+float autocvar_g_td_turret_max;
+float autocvar_g_td_turret_plasma_cost;
+float autocvar_g_td_turret_mlrs_cost;
+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_za_monster_count;
+float autocvar_g_monsters;
+float autocvar_g_monsters_max;
+float autocvar_g_monsters_max_perplayer;
+float autocvar_g_monsters_giants_only;
+float autocvar_g_monsters_typefrag;
+float autocvar_g_monsters_owners;
+float autocvar_g_monsters_miniboss_chance;
+float autocvar_g_monsters_miniboss_healthboost;
+string autocvar_g_monsters_forcedrop;
+string autocvar_g_monsters_drop_type;
+string autocvar_g_monsters_drop_size;
+float autocvar_g_monsters_teams;
+float autocvar_g_monsters_healthbars;
+float autocvar_g_monsters_respawn_delay;
+float autocvar_g_monsters_respawn;
+float autocvar_g_monsters_nogiants;
+float autocvar_g_monsters_skill_easy;
+float autocvar_g_monsters_skill_normal;
+float autocvar_g_monsters_skill_hard;
+float autocvar_g_monsters_skill_insane;
+float autocvar_g_monsters_skill_nightmare;
index 165460eeb2ae3ad678729611f873f927c7f65cb9..e5dc5e5d48503e38daee9edfdae391071472ce67 100644 (file)
@@ -843,6 +843,7 @@ void PutClientInServer (void)
                self.event_damage = PlayerDamage;
 
                self.bot_attack = TRUE;
+               self.monster_attack = TRUE;
 
                self.statdraintime = time + 5;
                self.BUTTON_ATCK = self.BUTTON_JUMP = self.BUTTON_ATCK2 = 0;
@@ -897,6 +898,8 @@ void PutClientInServer (void)
                                self.target = s;
                        activator = world;
                self = oldself;
+               
+               Unfreeze(self);
 
                spawn_spot = spot;
                MUTATOR_CALLHOOK(PlayerSpawn);
@@ -2369,6 +2372,9 @@ float nJoinAllowed(entity ignore) {
                if(autocvar_g_forced_team_otherwise == "spectator")
                        return 0;
        }
+       
+       if(MUTATOR_CALLHOOK(PlayerCanJoin))
+               return 0;
 
        if(self.team_forced < 0)
                return 0; // forced spectators can never join
@@ -2622,6 +2628,15 @@ void PlayerPreThink (void)
                return;
 #endif
 
+       if(self.frozen)
+       {
+               self.revive_progress = bound(0, self.revive_progress + frametime * self.revive_speed, 1);
+               self.health = max(1, self.revive_progress * autocvar_g_balance_health_start);
+
+               if(self.revive_progress >= 1)
+                       Unfreeze(self);
+       }
+
        MUTATOR_CALLHOOK(PlayerPreThink);
 
        if(!self.cvar_cl_newusekeysupported) // FIXME remove this - it was a stupid idea to begin with, we can JUST use the button
@@ -2786,7 +2801,7 @@ void PlayerPreThink (void)
                self.prevorigin = self.origin;
 
                if (!self.vehicle)
-               if (((self.BUTTON_CROUCH && !self.hook.state) || self.health <= g_bloodloss) && self.animstate_startframe != self.anim_melee_x && !self.freezetag_frozen) // prevent crouching if using melee attack
+               if (((self.BUTTON_CROUCH && !self.hook.state) || self.health <= g_bloodloss) && self.animstate_startframe != self.anim_melee_x && !self.freezetag_frozen && !self.frozen) // prevent crouching if using melee attack
                {
                        if (!self.crouch)
                        {
@@ -2853,6 +2868,9 @@ void PlayerPreThink (void)
                // secret status
                secrets_setstatus();
                
+               // monsters status
+               monsters_setstatus();
+               
                self.dmg_team = max(0, self.dmg_team - autocvar_g_teamdamage_resetspeed * frametime);
 
                //self.angles_y=self.v_angle_y + 90;   // temp
index 3e2268d89748d1eb193892407968c8ee721f66a5..8efecbadba669ca3e76c4838b66982c6c6547a3f 100644 (file)
@@ -23,7 +23,7 @@ When you press the jump key
 */
 void PlayerJump (void)
 {
-       if(self.freezetag_frozen)
+       if(self.freezetag_frozen || self.frozen)
                return; // no jumping in freezetag when frozen
 
        float mjumpheight;
@@ -872,6 +872,12 @@ void SV_PlayerPhysics()
        self.disableclientprediction = 0;
        if(time < self.ladder_time)
                self.disableclientprediction = 1;
+               
+       if(self.frozen)
+       {
+               self.movement = '0 0 0';
+               self.disableclientprediction = 1;
+       }
 
        MUTATOR_CALLHOOK(PlayerPhysics);
 
@@ -1074,7 +1080,7 @@ void SV_PlayerPhysics()
                        PM_Accelerate(wishdir, wishspeed, wishspeed, autocvar_sv_accelerate*maxspd_mod, 1, 0, 0, 0);
                }
        }
-       else if ((self.items & IT_JETPACK) && self.BUTTON_HOOK && (!autocvar_g_jetpack_fuel || self.ammo_fuel >= 0.01 || self.items & IT_UNLIMITED_WEAPON_AMMO) && !self.freezetag_frozen)
+       else if ((self.items & IT_JETPACK) && self.BUTTON_HOOK && (!autocvar_g_jetpack_fuel || self.ammo_fuel >= 0.01 || self.items & IT_UNLIMITED_WEAPON_AMMO) && !self.freezetag_frozen && !self.frozen)
        {
                //makevectors(self.v_angle_y * '0 1 0');
                makevectors(self.v_angle);
index 6945fe7221463fd6dd638ec5688d1ee7f5532b30..2d028c17cd5455de63257dcba03bff7996ec5027 100644 (file)
@@ -273,7 +273,7 @@ void player_anim (void)
 
        if (!self.animstate_override)
        {
-               if (self.freezetag_frozen)
+               if (self.freezetag_frozen || self.frozen)
                        setanim(self, self.anim_idle, TRUE, FALSE, FALSE);
                else if (!(self.flags & FL_ONGROUND) || self.BUTTON_JUMP)
                {
index 236c0923fdc330834469234bc9eb2285a1f6bb26..835c39a94ad4cffe40b7283fb89398496d1c26d0 100644 (file)
@@ -343,6 +343,8 @@ void W_ThrowWeapon(vector velo, vector delta, float doreduce)
        w = self.weapon;
        if (w == 0)
                return; // just in case
+       if(self.frozen)
+               return;
        if(MUTATOR_CALLHOOK(ForbidThrowCurrentWeapon))
                return;
        if(!autocvar_g_weapon_throwable)
@@ -377,7 +379,7 @@ void W_WeaponFrame()
        if(((arena_roundbased || g_ca || g_freezetag) && time < warmup) || ((time < game_starttime) && !autocvar_sv_ready_restart_after_countdown))
                return;
 
-       if(self.freezetag_frozen == 1)
+       if(self.freezetag_frozen == 1 || self.frozen == 1)
                return;
 
        if (!self.weaponentity || self.health < 1)
index 8f510edff00bf700610370218907ffba6922f7ab..0d8d46a6c805d9f162fab4584077cf42c6ac6473 100644 (file)
@@ -103,7 +103,7 @@ void W_HitPlotAnalysis(entity player, vector screenforward, vector screenright,
        vector org;
        float lag;
 
-       if(player.hitplotfh >= 0)
+       if(player.hitplotfh >= 0 && !(player.flags & FL_MONSTER))
        {
                lag = ANTILAG_LATENCY(player);
                if(lag < 0.001)
@@ -1092,6 +1092,8 @@ vector W_CalculateProjectileVelocity(vector pvelocity, vector mvelocity, float f
 
 void W_AttachToShotorg(entity flash, vector offset)
 {
+       if(self.flags & FL_MONSTER)
+               return; // no flash for monsters
        entity xflash;
        flash.owner = self;
        flash.angles_z = random() * 360;
@@ -1355,6 +1357,9 @@ void W_SetupProjectileVelocity(entity missile, float pSpeed, float spread)
 
 void W_DecreaseAmmo(.float ammo_type, float ammo_use, float ammo_reload)
 {
+       if(self.flags & FL_MONSTER) // no ammo for monsters... yet
+               return;
+               
        if((self.items & IT_UNLIMITED_WEAPON_AMMO) && !ammo_reload)
                return;
 
index 530646afd2ec8fbb105dc8a080b41dadaaa25d0f..007514983e00b8f401cc0ece8088d738a8595c85 100644 (file)
@@ -182,6 +182,66 @@ void ClientCommand_join(float request)
        }
 }
 
+void ClientCommand_mobspawn(float request, float argc)
+{
+       switch(request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       entity e;
+                       string tospawn, mname, s;
+                       float spawncount = 0, moveflag, max_global, max_perplayer, i;
+                       
+                       max_global = autocvar_g_monsters_max;
+                       max_perplayer = autocvar_g_monsters_max_perplayer;
+                       moveflag = (argv(3) ? stof(argv(3)) : 1); // follow owner if not defined
+                       spawncount = ((argv(2)) ? stof(argv(2)) : 1);
+                       tospawn = argv(1);
+                       mname = argv(4);
+                       s = ((spawncount == 1) ? "" : "s");
+                       
+                       if(tospawn == "list")
+                       {
+                               sprint(self, "Available monsters:\n");
+                               sprint(self, strcat(monsterlist(), "\n"));
+                               return;
+                       }
+                       
+                       if(self.classname != STR_PLAYER) { sprint(self, "You can't spawn monsters while spectating.\n"); return; }
+                       else if(self.deadflag) { sprint(self, "You can't spawn monsters while dead.\n"); return; }
+                       else if(self.monstercount > max_perplayer) { sprint(self, "You have spawned too many monsters, kill some before trying to spawn any more.\n"); return; }
+                       else if(totalspawned > max_global) { sprint(self, "The global maximum monster count has been reached, kill some before trying to spawn any more.\n"); return; }
+                       else if(spawncount == 0) { sprint(self, "No monsters to spawn.\n"); return; }
+                       
+                       makevectors(self.v_angle);
+            WarpZone_TraceLine(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * 100, MOVE_NORMAL, self);
+                       
+                       for(i = 0; i < spawncount; i++)
+                       {
+                               self.monstercount++;
+                               if(self.monstercount > max_perplayer) break; // FIXME: check for these properly
+                               e = spawnmonster(tospawn, self, self, trace_endpos, FALSE, moveflag);
+                               if(e == world) { self.monstercount -= 1; break; } // take back the 1 that was lost
+                               if(mname != "") e.netname = mname;
+                               totalspawned++;
+                       }
+                       
+                       sprint(self, sprintf("Spawned %d %s%s\n", spawncount, tospawn, s));
+                       
+                       return;
+               }
+       
+               default:
+                       sprint(self, "Incorrect parameters for ^2mobspawn^7\n");
+               case CMD_REQUEST_USAGE:
+               {
+                       sprint(self, "\nUsage:^3 cmd mobspawn monster\n");
+                       sprint(self, "  See 'cmd mobspawn list' for available arguments.\n");
+                       return;
+               }
+       }
+}
+
 void ClientCommand_ready(float request) // todo: anti-spam for toggling readyness
 {
        switch(request)
@@ -560,6 +620,7 @@ void ClientCommand_(float request)
        CLIENT_COMMAND("clientversion", ClientCommand_clientversion(request, arguments), "Release version of the game") \
        CLIENT_COMMAND("mv_getpicture", ClientCommand_mv_getpicture(request, arguments), "Retrieve mapshot picture from the server") \
        CLIENT_COMMAND("join", ClientCommand_join(request), "Become a player in the game") \
+       CLIENT_COMMAND("mobspawn", ClientCommand_mobspawn(request, arguments), "Spawn monsters infront of yourself") \
        CLIENT_COMMAND("ready", ClientCommand_ready(request), "Qualify as ready to end warmup stage (or restart server if allowed)") \
        CLIENT_COMMAND("say", ClientCommand_say(request, arguments, command), "Print a message to chat to all players") \
        CLIENT_COMMAND("say_team", ClientCommand_say_team(request, arguments, command), "Print a message to chat to all team mates") \
index e64cbc267ac505e61d579318cd644a2e7b2d4595..120bf3e02ebfd3a4ab0154490d5d2114d8b60ae4 100644 (file)
@@ -8,7 +8,10 @@
 .float lms_spectate_warning;
 .float checkfail;
 
+// number of monsters spawned with mobspawn command
+float totalspawned;
+
 string MapVote_Suggest(string m);
 
 // used by common/command/generic.qc:GenericCommand_dumpcommands to list all commands into a .txt file
-void ClientCommand_macro_write_aliases(float fh);
\ No newline at end of file
+void ClientCommand_macro_write_aliases(float fh);
index 0710ddfa8474874cca23787d9ed6221e44660ebd..382c7de6127531afbd21de28b6174a623682daab 100644 (file)
@@ -139,6 +139,43 @@ void GameCommand_adminmsg(float request, float argc)
        }
 }
 
+void GameCommand_butcher(float request)
+{
+       switch(request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+            float removed_count = 0;
+            totalspawned = 0;
+                       entity montokill = world;
+            FOR_EACH_MONSTER(montokill)
+            {
+                if(montokill.sprite)
+                    WaypointSprite_Kill(montokill.sprite);
+                                       
+                               if(montokill.realowner.flags & FL_CLIENT)
+                                       montokill.realowner.monstercount -= 1;
+                    
+                remove(montokill);
+                removed_count += 1;
+            }
+                       if(removed_count <= 0)
+                               print("No monsters to kill\n");
+                       else
+                               print(strcat("Killed ", ftos(removed_count), " monster", ((removed_count == 1) ? "\n" : "s\n")));
+                       return; // never fall through to usage
+               }
+                       
+               default:
+               case CMD_REQUEST_USAGE:
+               {
+                       print("\nUsage:^3 sv_cmd butcher\n");
+                       print("  No arguments required.\n");
+                       return;
+               }
+       }
+}
+
 void GameCommand_allready(float request)
 {
        switch(request)
@@ -1727,6 +1764,7 @@ void GameCommand_(float request)
 // Common commands have double indentation to separate them a bit.
 #define SERVER_COMMANDS(request,arguments,command) \
        SERVER_COMMAND("adminmsg", GameCommand_adminmsg(request, arguments), "Send an admin message to a client directly") \
+       SERVER_COMMAND("butcher", GameCommand_butcher(request), "Instantly removes all monsters on the map") \
        SERVER_COMMAND("allready", GameCommand_allready(request), "Restart the server and reset the players") \
        SERVER_COMMAND("allspec", GameCommand_allspec(request, arguments), "Force all players to spectate") \
        SERVER_COMMAND("anticheat", GameCommand_anticheat(request, arguments), "Create an anticheat report for a client") \
index f777254138e0c0dc4facdb4259567ac397d11cba..c2cc06dadc61d98b3aed4a4c475e695b204c2f9a 100644 (file)
@@ -584,6 +584,7 @@ float client_cefc_accumulatortime;
 #endif
 
 ..float current_ammo;
+.float currentegg;
 
 .float weapon_load[WEP_MAXCOUNT];
 .float ammo_none; // used by the reloading system, must always be 0
@@ -644,6 +645,10 @@ float serverflags;
 .float freezetag_frozen;
 .float freezetag_revive_progress;
 
+.float frozen; // for freeze attacks
+.float revive_progress;
+.float revive_speed; // NOTE: multiplier (anything above 1 is instaheal)
+
 .entity muzzle_flash;
 .float misc_bulletcounter;     // replaces uzi & hlac bullet counter.
 
@@ -674,3 +679,19 @@ string modname;
 #define MISSILE_IS_CONFUSABLE(m) ((m.missile_flags & MIF_GUIDED_CONFUSABLE) ? TRUE : FALSE)
 #define MISSILE_IS_GUIDED(m) ((m.missile_flags & MIF_GUIDED_ALL) ? TRUE : FALSE)
 #define MISSILE_IS_TRACKING(m) ((m.missile_flags & MIF_GUIDED_TRACKING) ? TRUE : FALSE)
+
+.string spawnmob;
+.float monster_attack;
+
+float monster_skill;
+float spawncode_first_load; // used to tell the player the monster database is loading (TODO: fix this?)
+
+.entity monster_owner; // new monster owner entity, fixes non-solid monsters
+.float monstercount; // per player monster count
+
+.float stat_monsters_killed; // stats
+.float stat_monsters_total;
+float monsters_total;
+float monsters_killed;
+void monsters_setstatus(); // monsters.qc
+string monsterlist();
index a3eeefb73033ce71cfa2532ce575378af314904e..c55c40a66cdf7d7d8142c09baba5894e6dcbf650 100644 (file)
@@ -529,6 +529,67 @@ void Obituary (entity attacker, entity inflictor, entity targ, float deathtype)
        }
 }
 
+void Ice_Think()
+{
+       if(self.owner.health < 1)
+       {
+               remove(self);
+               return;
+       }
+       setorigin(self, self.owner.origin - '0 0 16');
+       self.nextthink = time;
+}
+
+void Freeze (entity targ, float freeze_time)
+{
+       float monster = (targ.flags & FL_MONSTER);
+       float player = (targ.flags & FL_CLIENT);
+       
+       if(!player && !monster) // only specified entities can be freezed
+               return;
+               
+       if(targ.frozen || targ.freezetag_frozen)
+               return;
+               
+       targ.frozen = 1;
+       targ.revive_progress = 0;
+       targ.health = 1;
+       targ.revive_speed = freeze_time;
+
+       entity ice;
+       ice = spawn();
+       ice.owner = targ;
+       ice.classname = "ice";
+       ice.scale = targ.scale;
+       ice.think = Ice_Think;
+       ice.nextthink = time;
+       ice.frame = floor(random() * 21); // ice model has 20 different looking frames
+       setmodel(ice, "models/ice/ice.md3");
+
+       entity oldself;
+       oldself = self;
+       self = ice;
+       Ice_Think();
+       self = oldself;
+
+       RemoveGrapplingHook(targ);
+}
+
+void Unfreeze (entity targ)
+{
+       targ.frozen = 0;
+       targ.revive_progress = 0;
+       targ.health = ((targ.classname == STR_PLAYER) ? autocvar_g_balance_health_start : targ.max_health);
+
+       // remove the ice block
+       entity ice;
+       for(ice = world; (ice = find(ice, classname, "ice")); ) if(ice.owner == targ)
+       {
+               remove(ice);
+               break;
+       }
+}
+
 // these are updated by each Damage call for use in button triggering and such
 entity damage_targ;
 entity damage_inflictor;
@@ -715,6 +776,12 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
                        mirrorforce *= g_weaponforcefactor;
                }
                
+               if(targ.frozen && attacker.classname != "monster_spider")
+               {
+                       damage = 0;
+                       force *= 0.2;
+               }
+               
                // should this be changed at all? If so, in what way?
                frag_attacker = attacker;
                frag_target = targ;
@@ -823,7 +890,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
                        else
                                victim = targ;
 
-                       if(victim.classname == "player" || victim.turrcaps_flags & TFL_TURRCAPS_ISTURRET)
+                       if(victim.classname == "player" || victim.turrcaps_flags & TFL_TURRCAPS_ISTURRET || victim.flags & FL_MONSTER)
                        {
                                if(IsDifferentTeam(victim, attacker))
                                {
@@ -1347,7 +1414,7 @@ void Fire_ApplyDamage(entity e)
                e.fire_endtime = 0;
 
        // ice stops fire
-       if(e.freezetag_frozen)
+       if(e.freezetag_frozen || e.frozen)
                e.fire_endtime = 0;
 
        t = min(frametime, e.fire_endtime - time);
index f7af47d924036f121a6b8340a8dc2df5a0edaee4..ad1da10f7f4be77db9181e8f87cb89cbc963f640 100644 (file)
@@ -302,7 +302,7 @@ void FireGrapplingHook (void)
        if((arena_roundbased && time < warmup) || (time < game_starttime))
                return;
 
-  if(self.freezetag_frozen)
+  if(self.freezetag_frozen || self.frozen)
                return;
        
        if(self.vehicle)
index 8d8c0328ec6abed9d4e4e7c7d516fb4249faf260..bacdce4170d68244ef8871e6bd88dc8a7313e1f1 100644 (file)
@@ -264,6 +264,7 @@ void cvar_changes_init()
                BADCVAR("g_freezetag");
                BADCVAR("g_keepaway");
                BADCVAR("g_keyhunt");
+               BADCVAR("g_td");
                BADCVAR("g_keyhunt_teams");
                BADCVAR("g_keyhunt_teams");
                BADCVAR("g_lms");
@@ -820,6 +821,16 @@ void spawnfunc_worldspawn (void)
                addstat(STAT_FROZEN, AS_INT, freezetag_frozen);
                addstat(STAT_REVIVE_PROGRESS, AS_FLOAT, freezetag_revive_progress);
        }
+       
+       if(g_td)
+       {
+               addstat(STAT_CURRENT_WAVE, AS_FLOAT, stat_current_wave);
+               addstat(STAT_TOTALWAVES, AS_FLOAT, stat_totalwaves);
+       }
+       
+       // freeze attacks
+       addstat(STAT_FROZEN, AS_INT, frozen);
+       addstat(STAT_REVIVE_PROGRESS, AS_FLOAT, revive_progress);
 
        // g_movementspeed hack
        addstat(STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW, AS_FLOAT, stat_sv_airspeedlimit_nonqw);
@@ -830,6 +841,10 @@ void spawnfunc_worldspawn (void)
        // secrets
        addstat(STAT_SECRETS_TOTAL, AS_FLOAT, stat_secrets_total);
        addstat(STAT_SECRETS_FOUND, AS_FLOAT, stat_secrets_found);
+       
+       // monsters
+       addstat(STAT_MONSTERS_TOTAL, AS_FLOAT, stat_monsters_total);
+       addstat(STAT_MONSTERS_KILLED, AS_FLOAT, stat_monsters_killed);
 
        // misc
        addstat(STAT_RESPAWN_TIME, AS_FLOAT, stat_respawn_time);
@@ -942,6 +957,8 @@ void spawnfunc_worldspawn (void)
        // weird mutators that deserve to count as mod
        if(autocvar_g_minstagib)
                modname = "MinstaGib";
+       if(autocvar_g_monsters)
+               modname = "Monsters";
        // extra mutators that deserve to count as mod
        MUTATOR_CALLHOOK(SetModname);
        // weird game types that deserve to count as mod
@@ -2119,6 +2136,36 @@ float WinningCondition_RanOutOfSpawns()
                return WINNING_NO;
 }
 
+// TD winning condition:
+// game terminates if there are no generators (or 1 dies if td_dontend is TRUE)
+float gensurvived;
+float WinningCondition_TowerDefense()
+{
+       WinningConditionHelper(); // set worldstatus
+
+       if(inWarmupStage)
+               return WINNING_NO;
+
+       // first check if the game has ended
+       if(gendestroyed == TRUE) // FALSE means either generator hasen't spawned yet, or mapper didn't add one
+       if(td_gencount < 1 || !td_dont_end)
+       {
+               ClearWinners();
+               dprint("Everyone lost, ending game.\n");
+               return WINNING_YES;
+       }
+       
+       if(gensurvived)
+       {
+               ClearWinners();
+               SetWinners(winning, 4);
+               return WINNING_YES;
+       }
+
+       // Two or more teams remain
+       return WINNING_NO;
+}
+
 /*
 ============
 CheckRules_World
@@ -2274,6 +2321,10 @@ void CheckRules_World()
        {
                checkrules_status = WinningCondition_Onslaught(); // TODO remove this?
        }
+       else if(g_td)
+       {
+               checkrules_status = WinningCondition_TowerDefense(); // TODO make these mutator hooks?
+       }
        else
        {
                checkrules_status = WinningCondition_Scores(fraglimit, leadlimit);
index efb73540672df091703c6649b2aa90e7862ffb2b..4a226c7868b8afc55f19dbd2e37892cd1b4031dd 100644 (file)
@@ -90,6 +90,7 @@ string STR_OBSERVER = "observer";
 #define FOR_EACH_REALCLIENT(v) FOR_EACH_CLIENT(v) if(clienttype(v) == CLIENTTYPE_REAL)
 #define FOR_EACH_PLAYER(v) for(v = world; (v = find(v, classname, STR_PLAYER)) != world; )
 #define FOR_EACH_REALPLAYER(v) FOR_EACH_PLAYER(v) if(clienttype(v) == CLIENTTYPE_REAL)
+#define FOR_EACH_MONSTER(v) for(v = world; (v = findflags(v, flags, FL_MONSTER)) != world; )
 #else
 #define FOR_EACH_CLIENTSLOT(v) for(v = world; (v = nextent(v)) && (num_for_edict(v) <= maxclients); )
 #define FOR_EACH_CLIENT(v) FOR_EACH_CLIENTSLOT(v) if(v.flags & FL_CLIENT)
@@ -97,6 +98,7 @@ string STR_OBSERVER = "observer";
 #define FOR_EACH_PLAYER(v) FOR_EACH_CLIENT(v) if(v.classname == STR_PLAYER)
 #define FOR_EACH_SPEC(v) FOR_EACH_CLIENT(v) if(v.classname != STR_PLAYER)
 #define FOR_EACH_REALPLAYER(v) FOR_EACH_REALCLIENT(v) if(v.classname == STR_PLAYER)
+#define FOR_EACH_MONSTER(v) for(v = world; (v = findflags(v, flags, FL_MONSTER)) != world; )
 #endif
 
 #define CENTER_OR_VIEWOFS(ent) (ent.origin + ((ent.classname == STR_PLAYER) ? ent.view_ofs : ((ent.mins + ent.maxs) * 0.5)))
@@ -1115,6 +1117,8 @@ string GetGametype(); // g_world.qc
 void readlevelcvars(void)
 {
        g_minstagib = cvar("g_minstagib");
+    
+        monster_skill = cvar("g_monsters_skill");
 
        // load ALL the mutators
        if(cvar("g_dodging"))
@@ -1140,6 +1144,9 @@ void readlevelcvars(void)
        // is this a mutator? is this a mode?
        if(cvar("g_sandbox"))
                MUTATOR_ADD(sandbox);
+        
+    if(cvar("g_za"))
+               MUTATOR_ADD(mutator_zombie_apocalypse);
 
        if(cvar("sv_allow_fullbright"))
                serverflags |= SERVERFLAG_ALLOW_FULLBRIGHT;
index 9b9f7fde01abe5dc22dcd51310665c265aa15e6d..633b0760917fa7438a592c1769140638ccf82e14 100644 (file)
@@ -102,6 +102,19 @@ void movelib_move(vector force,float max_velocity,float drag,float theMass,float
             self.velocity = normalize(self.velocity) * (mspeed - 50);//* max_velocity;
 }
 
+void movelib_move_simple_gravity(vector newdir,float velo,float blendrate)
+{
+    float z_speed = self.velocity_z;
+    self.movelib_lastupdate = time;
+    self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo;
+    self.velocity_z = z_speed;
+}
+
+void movelib_jump_simple(float power){
+    self.velocity_z=power;
+    self.movelib_lastupdate = time;
+}
+
 /*
 .float mass;
 .float side_friction;
index 1b6cea8fc4501ee47eaa8b26089926d927544878..da9d0f36c7c5e091320b94947f47f849972d8fff 100644 (file)
@@ -50,6 +50,10 @@ MUTATOR_HOOKABLE(PlayerSpawn);
 
 MUTATOR_HOOKABLE(ClientDisconnect);
        // called when a player disconnects
+       
+MUTATOR_HOOKABLE(PlayerCanJoin);
+       // called when a player tries to join
+       // if this returns TRUE, the player cannot join
 
 MUTATOR_HOOKABLE(PlayerDies);
        // called when a player dies to e.g. remove stuff he was carrying.
@@ -103,6 +107,12 @@ MUTATOR_HOOKABLE(TurretSpawn);
        // return error to request removal
        // INPUT: self - turret
        
+MUTATOR_HOOKABLE(TurretValidateTarget);
+       // return target score
+       // INPUT:
+               entity turret_target;
+               entity turret;
+       
 MUTATOR_HOOKABLE(OnEntityPreSpawn);
        // return error to prevent entity spawn, or modify the entity
 
@@ -127,6 +137,33 @@ MUTATOR_HOOKABLE(EditProjectile);
        // INPUT:
                entity self;
                entity other;
+        
+MUTATOR_HOOKABLE(MonsterSpawn);
+       // called when a monster spawns
+    
+MUTATOR_HOOKABLE(MonsterDies);
+       // called when a monster dies
+       // INPUT:
+               entity frag_attacker;
+               
+MUTATOR_HOOKABLE(MonsterDropItem);
+       // called when a monster is dropping loot
+       // INPUT, OUTPUT:
+               string monster_dropitem;
+               string monster_dropsize;
+       
+MUTATOR_HOOKABLE(MonsterMove);
+       // called when a monster moves
+       // INPUT:
+               float monster_speed_run;
+               float monster_speed_walk;
+               entity monster_target;
+    
+MUTATOR_HOOKABLE(MonsterFindTarget);
+       // called when a monster looks for another target
+    
+MUTATOR_HOOKABLE(MonsterCheckBossFlag);
+    // called to change a random monster to a miniboss
 
 MUTATOR_HOOKABLE(PlayerDamage_SplitHealthArmor);
        // called when a player gets damaged to e.g. remove stuff he was carrying.
index 2ac6094d339d578d174da5ec3ed06eed91fcad20..b1cd9469e079cd69fea24400c334657fc40b065a 100644 (file)
@@ -4,6 +4,7 @@ MUTATOR_DECLARATION(gamemode_keepaway);
 MUTATOR_DECLARATION(gamemode_ctf);
 MUTATOR_DECLARATION(gamemode_nexball);
 MUTATOR_DECLARATION(gamemode_onslaught);
+MUTATOR_DECLARATION(gamemode_td);
 
 MUTATOR_DECLARATION(mutator_dodging);
 MUTATOR_DECLARATION(mutator_invincibleprojectiles);
@@ -13,5 +14,6 @@ MUTATOR_DECLARATION(mutator_rocketflying);
 MUTATOR_DECLARATION(mutator_spawn_near_teammate);
 MUTATOR_DECLARATION(mutator_vampire);
 MUTATOR_DECLARATION(mutator_superspec);
+MUTATOR_DECLARATION(mutator_zombie_apocalypse);
 
 MUTATOR_DECLARATION(sandbox);
index 028519372f025ae24aa923d472ba0a6593de86b7..7b30b2ebae1570d51054359d0c37d062fc7f8027 100644 (file)
@@ -34,6 +34,7 @@ mutators/gamemode_keyhunt.qh // TODO fix this
 mutators/gamemode_keepaway.qh
 mutators/gamemode_nexball.qh 
 mutators/mutator_dodging.qh
+mutators/gamemode_td.qh
 
 //// tZork Turrets ////
 tturrets/include/turrets_early.qh
@@ -206,6 +207,8 @@ playerstats.qc
 
 ../common/explosion_equation.qc
 
+monsters/monsters.qh
+
 mutators/base.qc
 mutators/gamemode_ctf.qc
 mutators/gamemode_freezetag.qc
@@ -213,6 +216,7 @@ mutators/gamemode_keyhunt.qc
 mutators/gamemode_keepaway.qc
 mutators/gamemode_nexball.qc
 mutators/gamemode_onslaught.qc
+mutators/gamemode_td.qc
 mutators/mutator_invincibleproj.qc
 mutators/mutator_new_toys.qc
 mutators/mutator_nix.qc
@@ -222,6 +226,7 @@ mutators/mutator_vampire.qc
 mutators/mutator_spawn_near_teammate.qc
 mutators/sandbox.qc
 mutators/mutator_superspec.qc
+mutators/mutator_zombie_apocalypse.qc
 
 ../warpzonelib/anglestransform.qc
 ../warpzonelib/mathlib.qc
index c91c1ac1895ecae9d49667175258f3b91b9f9486..579afd544718e0cbec1ba923afc90dda3cb29d36 100644 (file)
@@ -10,6 +10,7 @@ void CreatureFrame (void)
                
                float vehic = (self.vehicle_flags & VHF_ISVEHICLE);
                float projectile = (self.flags & FL_PROJECTILE);
+               float monster = (self.flags & FL_MONSTER);
                
                if (self.watertype <= CONTENT_WATER && self.waterlevel > 0) // workaround a retarded bug made by id software :P (yes, it's that old of a bug)
                {
@@ -19,7 +20,7 @@ void CreatureFrame (void)
                                self.dmgtime = 0;
                        }
 
-                       if(!vehic && !projectile) // vehicles and projectiles don't drown
+                       if(!vehic && !projectile && !monster) // vehicles, monsters and projectiles don't drown
                        {
                                if (self.waterlevel != WATERLEVEL_SUBMERGED)
                                {
index b8f2f3ac8746ea4e02daae0936833d2086954699..4df34ee603df5ebaf109ffa8569c9a55b3ca57e3 100644 (file)
@@ -146,6 +146,13 @@ void InitGameplayMode()
                MUTATOR_ADD(gamemode_ctf);
                have_team_spawns = -1; // request team spawns
        }
+    
+       if(g_td)
+       {
+               fraglimit_override = 0; // no limits in TD - it's a survival mode
+               leadlimit_override = 0;
+               MUTATOR_ADD(gamemode_td);
+       }
 
        if(g_runematch)
        {
index 971d65cca3916eea9f99a17d28b5d41ee096211f..4ac34eb63fb9459e182f01df31b10ba329f32657 100644 (file)
@@ -64,6 +64,7 @@ void turret_stdproc_respawn()
     self.tur_head.avelocity     = self.avelocity;
     self.tur_head.angles        = self.idle_aim;
     self.health                 = self.tur_health;
+       self.max_health                         = self.tur_health;
 
     self.enemy                  = world;
     self.volly_counter          = self.shot_volly;
@@ -125,6 +126,9 @@ void turret_stdproc_damage (entity inflictor, entity attacker, float damage, flo
         self.takedamage             = DAMAGE_NO;
         self.nextthink = time;
         self.think = turret_stdproc_die;
+               
+       if(self.realowner)
+               self.realowner.turret_cnt -= 1;
     }
     
     self.SendFlags  |= TNSF_STATUS;
index dd58b3cee2860e0c031dc131a47eab165c846967..8907bc41b8d4e62685f0677fce7a7f70622e49ea 100644 (file)
@@ -571,6 +571,13 @@ float turret_stdproc_firecheck()
 float turret_validate_target(entity e_turret, entity e_target, float validate_flags)
 {
     vector v_tmp;
+       
+       turret_target = e_target;
+       turret = e_turret;
+       if(MUTATOR_CALLHOOK(TurretValidateTarget))
+               return 1;
+       e_target = turret_target;
+       e_turret = turret;
         
     //if(!validate_flags & TFL_TARGETSELECT_NOBUILTIN)
     //    return -0.5;
@@ -1107,6 +1114,9 @@ float turret_stdproc_init (string cvar_base_name, string base, string head, floa
     if not (self.health)
         self.health = 1000;
     self.tur_health = max(1, self.health);
+       self.max_health = self.tur_health;
+       self.bot_attack = TRUE;
+    self.monster_attack = TRUE;
 
     if not (self.turrcaps_flags)
         self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
@@ -1339,7 +1349,6 @@ float turret_stdproc_init (string cvar_base_name, string base, string head, floa
         self.turret_score_target    = turret_stdproc_targetscore_generic;
 
     self.use = turret_stdproc_use;
-    self.bot_attack = TRUE;
 
     ++turret_count;
     self.nextthink = time + 1;
index c542dab401ba2ee88da3f88df7d7c57f48329478..16ecbce5e72167a4dd42e0c311e67d792d48fb06 100644 (file)
@@ -44,7 +44,10 @@ float turret_stdproc_targetscore_generic(entity _turret, entity _target)
     if ((_turret.target_select_missilebias > 0) && (_target.flags & FL_PROJECTILE))
         m_score = 1;
 
-    if ((_turret.target_select_playerbias > 0) && (_target.flags & FL_CLIENT))
+    if ((_turret.target_select_playerbias > 0) && (_target.flags & FL_CLIENT) && !g_td)
+        p_score = 1;
+        
+    if(g_td && _target.flags & FL_MONSTER)
         p_score = 1;
 
     d_score = max(d_score, 0);
index 8118b8f234dfa1cb23d2c52d737489679dd47ab1..de8509b3e21d6bc48a568bcf11cf0f0c9d068fe0 100644 (file)
@@ -7,6 +7,11 @@ void turret_fusionreactor_fire()
     vector fl_org;
 
     self.enemy.ammo = min(self.enemy.ammo + self.shot_dmg,self.enemy.ammo_max);
+    if(g_td) // auto repair?
+       {
+        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);
+       }
     fl_org = 0.5 * (self.enemy.absmin + self.enemy.absmax);
     te_smallflash(fl_org);
 }
@@ -38,15 +43,27 @@ float turret_fusionreactor_firecheck()
                return 0;
 
        if (self.ammo < self.shot_dmg)
-               return 0;
+               return 0;       
+       
+       if (vlen(self.enemy.origin - self.origin) > self.target_range)
+               return 0;       
 
+    if(g_td)
+    {
+        if(self.realowner != self.enemy.realowner)
+            return 0;
+            
+               if(self.enemy.turrcaps_flags & TFL_TURRCAPS_AMMOSOURCE)
+                       return 0;
+                       
+        if(self.enemy.health >= self.enemy.max_health)
+            return 0;
+    }
+       
        if (self.enemy.ammo >= self.enemy.ammo_max)
                return 0;
        
-       if (vlen(self.enemy.origin - self.origin) > self.target_range)
-               return 0;                               
-       
-       if(self.team != self.enemy.team)
+       if(teamplay && self.team != self.enemy.team)
                return 0;
        
        if not (self.enemy.ammo_flags & TFL_AMMO_ENERGY)
index 041c16929ebdd16b18a232649b36468e5325cd34..ebdd0a1331d5162e0b151a0a05fda1fec38895a5 100644 (file)
@@ -107,7 +107,7 @@ void walker_rocket_think()
     m_speed = vlen(self.velocity);
 
     // Enemy dead? just keep on the current heading then.
-    if (self.enemy == world || self.enemy.deadflag != DEAD_NO)
+    if (self.enemy == world || self.enemy.deadflag != DEAD_NO || (g_td && !(self.enemy.flags & FL_MONSTER || self.enemy.classname == "td_generator")) || self.enemy.classname == "td_generator")
         self.enemy = world;
 
     if (self.enemy)
index ac4ef47ed3bc74c009b3b9d79e1433975102c3c7..f8240dcc6888119284fa41d5ad584267689c6c43 100644 (file)
@@ -19,3 +19,4 @@
 #include "w_rifle.qc"
 #include "w_fireball.qc"
 #include "w_seeker.qc"
+#include "w_incubator.qc"
index ad1fbf0fddcf2a02eb261cd7ec830b4f466c0662..f59e3b3ebe1260a9861e6b4cba7e276e99200e1d 100644 (file)
@@ -253,7 +253,7 @@ void lgbeam_think()
                return;
        }
 
-       if (owner_player.weaponentity.state != WS_INUSE || !lgbeam_checkammo() || owner_player.deadflag != DEAD_NO || !owner_player.BUTTON_ATCK || owner_player.freezetag_frozen)
+       if (owner_player.weaponentity.state != WS_INUSE || !lgbeam_checkammo() || owner_player.deadflag != DEAD_NO || !owner_player.BUTTON_ATCK || owner_player.freezetag_frozen || owner_player.frozen)
        {
                if(self == owner_player.lgbeam)
                        owner_player.lgbeam = world;
diff --git a/textures/bloodyskull_pants.jpg b/textures/bloodyskull_pants.jpg
new file mode 100644 (file)
index 0000000..e0083ac
Binary files /dev/null and b/textures/bloodyskull_pants.jpg differ
diff --git a/textures/cerberus/cerberus_text.png b/textures/cerberus/cerberus_text.png
new file mode 100644 (file)
index 0000000..3ac7c05
Binary files /dev/null and b/textures/cerberus/cerberus_text.png differ
diff --git a/textures/cerberus/cerberus_text_pants.png b/textures/cerberus/cerberus_text_pants.png
new file mode 100644 (file)
index 0000000..d109711
Binary files /dev/null and b/textures/cerberus/cerberus_text_pants.png differ
diff --git a/textures/meat_pants.tga b/textures/meat_pants.tga
new file mode 100644 (file)
index 0000000..1568b09
Binary files /dev/null and b/textures/meat_pants.tga differ
diff --git a/textures/spider/spidertex.tga b/textures/spider/spidertex.tga
new file mode 100644 (file)
index 0000000..e9f8df1
Binary files /dev/null and b/textures/spider/spidertex.tga differ
diff --git a/za.cfg b/za.cfg
new file mode 100644 (file)
index 0000000..1e6682e
--- /dev/null
+++ b/za.cfg
@@ -0,0 +1,2 @@
+set g_za 0 "Enable zombie apocalypse mutator"
+set g_za_monster_count 20
\ No newline at end of file