djcev.com

//

Git Repos / fte_dogmode / commit f9955e9

Commit: f9955e96a17aa1fc020faf245f03f58b21c9f75b
Parent: 87b5ca93239afdd4dc23bb0643c8673c71db46d4
Author: Cameron Vanderzanden, 2023-10-13 11:17
Committer: Cameron Vanderzanden, 2023-10-13 11:17

Commit Message

Rename "qc-server" dir to "qc"

Change List

?File Add Del
D qc-server/ai.qc -858
D qc-server/buttons.qc -205
D qc-server/client.qc -1447
D qc-server/combat.qc -366
D qc-server/cshift.qc -75
D qc-server/csqc/csqc_defs.qc -398
D qc-server/csqc/csqc_defsclient.qc -759
D qc-server/csqc/csqc_fteopts.qc -2
D qc-server/csqc/csqc_hudvanilla.qc -958
D qc-server/csqc/csqc_progs.src -7
D qc-server/custom_mdls.qc -70
D qc-server/custom_snd.qc -100
D qc-server/cutscene.qc -939
D qc-server/defs_builtins.qc -223
D qc-server/defs_entvars.qc -115
D qc-server/defs_globalvars.qc -86
D qc-server/defs_misc.qc -676
D qc-server/doe_elbutton.qc -157
D qc-server/doe_ltrail.qc -194
D qc-server/doe_plats.qc -630
D qc-server/doors.qc -945
D qc-server/dtmisc.qc -1176
D qc-server/dtquake.qc -103
D qc-server/fight.qc -509
D qc-server/fog.qc -544
D qc-server/fteopts.qc -2
D qc-server/fteqcc.ini -240
D qc-server/func_bob.qc -198
D qc-server/func_brush.qc -80
D qc-server/func_fall2.qc -280
D qc-server/hip_count.qc -219
D qc-server/hip_part.qc -316
D qc-server/hip_rotate.qc -1222
D qc-server/hip_trig.qc -238
D qc-server/intermission.qc -398
D qc-server/items.qc -2441
D qc-server/keydata.qc -222
D qc-server/keylock.qc -226
D qc-server/lights.qc -503
D qc-server/math.qc -209
D qc-server/misc.qc -1871
D qc-server/misc_model.qc -170
D qc-server/mobot.qc -500
D qc-server/monsters.qc -518
D qc-server/monsters/boss.qc -415
D qc-server/monsters/boss2.qc -491
D qc-server/monsters/demon.qc -502
D qc-server/monsters/dog.qc -503
D qc-server/monsters/enforcer.qc -1044
D qc-server/monsters/fish.qc -306
D qc-server/monsters/hknight.qc -755
D qc-server/monsters/knight.qc -418
D qc-server/monsters/ogre.qc -1571
D qc-server/monsters/oldone.qc -296
D qc-server/monsters/oldone2.qc -367
D qc-server/monsters/shalrath.qc -433
D qc-server/monsters/shambler.qc -727
D qc-server/monsters/soldier.qc -709
D qc-server/monsters/wizard.qc -580
D qc-server/monsters/zombie.qc -865
D qc-server/newflags.qc -205
D qc-server/plats.qc -786
D qc-server/player.qc -762
D qc-server/progs.src -76
D qc-server/rubicon2.qc -1010
D qc-server/subs.qc -741
D qc-server/triggers.qc -1781
D qc-server/utility.qc -218
D qc-server/weapons.qc -1807
D qc-server/world.qc -621
A qc/ai.qc +858
A qc/buttons.qc +205
A qc/client.qc +1447
A qc/combat.qc +366
A qc/cshift.qc +75
A qc/csqc/csqc_defs.qc +398
A qc/csqc/csqc_defsclient.qc +759
A qc/csqc/csqc_fteopts.qc +2
A qc/csqc/csqc_hudvanilla.qc +958
A qc/csqc/csqc_progs.src +7
A qc/custom_mdls.qc +70
A qc/custom_snd.qc +100
A qc/cutscene.qc +939
A qc/defs_builtins.qc +223
A qc/defs_entvars.qc +115
A qc/defs_globalvars.qc +86
A qc/defs_misc.qc +676
A qc/doe_elbutton.qc +157
A qc/doe_ltrail.qc +194
A qc/doe_plats.qc +630
A qc/doors.qc +945
A qc/dtmisc.qc +1176
A qc/dtquake.qc +103
A qc/fight.qc +509
A qc/fog.qc +544
A qc/fteopts.qc +2
A qc/fteqcc.ini +240
A qc/func_bob.qc +198
A qc/func_brush.qc +80
A qc/func_fall2.qc +280
A qc/hip_count.qc +219
A qc/hip_part.qc +316
A qc/hip_rotate.qc +1222
A qc/hip_trig.qc +238
A qc/intermission.qc +398
A qc/items.qc +2441
A qc/keydata.qc +222
A qc/keylock.qc +226
A qc/lights.qc +503
A qc/math.qc +209
A qc/misc.qc +1871
A qc/misc_model.qc +170
A qc/mobot.qc +500
A qc/monsters.qc +518
A qc/monsters/boss.qc +415
A qc/monsters/boss2.qc +491
A qc/monsters/demon.qc +502
A qc/monsters/dog.qc +503
A qc/monsters/enforcer.qc +1044
A qc/monsters/fish.qc +306
A qc/monsters/hknight.qc +755
A qc/monsters/knight.qc +418
A qc/monsters/ogre.qc +1571
A qc/monsters/oldone.qc +296
A qc/monsters/oldone2.qc +367
A qc/monsters/shalrath.qc +433
A qc/monsters/shambler.qc +727
A qc/monsters/soldier.qc +709
A qc/monsters/wizard.qc +580
A qc/monsters/zombie.qc +865
A qc/newflags.qc +205
A qc/plats.qc +786
A qc/player.qc +762
A qc/progs.src +76
A qc/rubicon2.qc +1010
A qc/subs.qc +741
A qc/triggers.qc +1781
A qc/utility.qc +218
A qc/weapons.qc +1807
A qc/world.qc +621

Diff qc-server/ai.qc

diff --git a/qc-server/ai.qc b/qc-server/ai.qc
deleted file mode 100644
index 0d8f18a..0000000
--- a/qc-server/ai.qc
+++ /dev/null
@@ -1,858 +0,0 @@
-void() movetarget_f;
-void() t_movetarget;
-void() knight_walk1;
-void() knight_bow6;
-void() knight_bow1;
-void(entity etemp, entity stemp, entity stemp, float dmg) T_Damage;
-float NO_SIGHT_SOUND = 32;
-float PASSIVE_UNTIL_ATTACKED = 64;
-float PASSIVE_ALWAYS = 128;
-/*
-
-.enemy
-Will be world if not currently angry at anyone.
-
-.movetarget
-The next path spot to walk toward. If .enemy, ignore .movetarget.
-When an enemy is killed, the monster will try to return to it's path.
-
-.huntt_ime
-Set to time + something when the player is in sight, but movement straight for
-him is blocked. This causes the monster to use wall following code for
-movement direction instead of sighting on the player.
-
-.ideal_yaw
-A yaw angle of the intended direction, which will be turned towards at up
-to 45 deg / state. If the enemy is in view and hunt_time is not active,
-this will be the exact line towards the enemy.
-
-.pausetime
-A monster will leave it's stand state and head towards it's .movetarget when
-time > .pausetime.
-
-walkmove(angle, speed) primitive is all or nothing
-*/
-
-
-//
-// globals
-//
-
-//
-// when a monster becomes angry at a player, that monster will be used
-// as the sight target the next frame so that monsters near that one
-// will wake up even if they wouldn't have noticed the player
-//
-entity sight_entity;
-float sight_entity_time;
-
-float(float v) anglemod =
-{
- while (v >= 360)
- v = v - 360;
- while (v < 0)
- v = v + 360;
- return v;
-};
-
-/*
-==============================================================================
-
-MOVETARGET CODE
-
-The angle of the movetarget effects standing and bowing direction, but has no effect on movement, which always heads to the next target.
-
-targetname
-must be present. The name of this movetarget.
-
-target
-the next spot to move to. If not present, stop here for good.
-
-pausetime
-The number of seconds to spend standing or bowing for path_stand or path_bow
-
-==============================================================================
-*/
-
-
-void() movetarget_f =
-{
- if (!self.targetname)
- objerror ("monster_movetarget: no targetname");
-
- self.solid = SOLID_TRIGGER;
- self.touch = t_movetarget;
- setsize (self, '-8 -8 -8', '8 8 8');
-
-};
-
-/*QUAKED path_corner (0.5 0.3 0) (-8 -8 -8) (8 8 8)
-Monsters will continue walking towards the next target corner.
-*/
-void() path_corner =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.noise) precache_sound(self.noise);
- if (self.noise2) precache_sound(self.noise2);
-
- movetarget_f ();
-};
-
-
-/*
-=============
-t_movetarget
-
-Something has bumped into a movetarget. If it is a monster
-moving towards it, change the next destination and continue.
-==============
-*/
-void() t_movetarget =
-{
-local entity temp;
-
- if (other.movetarget != self)
- return;
-
- if (other.enemy)
- return; // fighting, not following a path
-
- temp = self;
- self = other;
- other = temp;
-
- if (self.classname == "monster_ogre")
- sound_misc (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);// play chainsaw drag sound -- sound_custom -- dumptruck_ds
-
-//dprint ("t_movetarget\n");
- self.goalentity = self.movetarget = find (world, targetname, other.target);
- self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
- if (!self.movetarget)
- {
- self.pausetime = time + 999999;
- self.th_stand ();
- return;
- }
-};
-
-
-
-//============================================================================
-
-/*
-=============
-range
-
-returns the range catagorization of an entity reletive to self
-0 melee range, will become hostile even if back is turned
-1 visibility and infront, or visibility and show hostile
-2 infront and show hostile
-3 only triggered by damage
-=============
-*/
-float(entity targ) range =
-{
-local vector spot1, spot2;
-local float r;
- spot1 = self.origin + self.view_ofs;
- spot2 = targ.origin + targ.view_ofs;
-
- r = vlen (spot1 - spot2);
- if (r < 120)
- return RANGE_MELEE;
- if (r < 500)
- return RANGE_NEAR;
- if (r < 1000)
- return RANGE_MID;
- return RANGE_FAR;
-};
-
-/*
-=============
-visible
-
-returns 1 if the entity is visible to self, even if not infront ()
-=============
-*/
-float (entity targ) visible =
-{
- local vector spot1, spot2;
-
- spot1 = self.origin + self.view_ofs;
- spot2 = targ.origin + targ.view_ofs;
- traceline (spot1, spot2, TRUE, self); // see through other monsters
-
- if (trace_inopen && trace_inwater)
- return FALSE; // sight line crossed contents
-
- if (trace_fraction == 1)
- return TRUE;
- return FALSE;
-};
-
-
-/*
-=============
-infront
-
-returns 1 if the entity is in front (in sight) of self
-=============
-*/
-float(entity targ) infront =
-{
- local vector vec;
- local float dot;
-
- makevectors (self.angles);
- vec = normalize (targ.origin - self.origin);
- dot = vec * v_forward;
-
- if ( dot > 0.3)
- {
- return TRUE;
- }
- return FALSE;
-};
-
-
-//============================================================================
-
-/*
-===========
-ChangeYaw
-
-Turns towards self.ideal_yaw at self.yaw_speed
-Sets the global variable current_yaw
-Called every 0.1 sec by monsters
-============
-*/
-/*
-
-void() ChangeYaw =
-{
- local float ideal, move;
-
-//current_yaw = self.ideal_yaw;
-// mod down the current angle
- current_yaw = anglemod( self.angles_y );
- ideal = self.ideal_yaw;
-
- if (current_yaw == ideal)
- return;
-
- move = ideal - current_yaw;
- if (ideal > current_yaw)
- {
- if (move > 180)
- move = move - 360;
- }
- else
- {
- if (move < -180)
- move = move + 360;
- }
-
- if (move > 0)
- {
- if (move > self.yaw_speed)
- move = self.yaw_speed;
- }
- else
- {
- if (move < 0-self.yaw_speed )
- move = 0-self.yaw_speed;
- }
-
- current_yaw = anglemod (current_yaw + move);
-
- self.angles_y = current_yaw;
-};
-
-*/
-
-
-//============================================================================
-
-void() HuntTarget =
-{
- self.goalentity = self.enemy;
- self.think = self.th_run;
- self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
- self.nextthink = time + 0.1;
- SUB_AttackFinished (1); // wait a while before first attack
-};
-
-void() SightSound =
-{
- if !(self.spawnflags & PASSIVE_ALWAYS)
-
- local float rsnd;
-
- if (self.classname == "monster_ogre")
- sound_sight (self, CHAN_VOICE, "ogre/ogwake.wav", 1, ATTN_NORM);
- else if (self.classname == "monster_ogre_marksman")
- sound_sight (self, CHAN_VOICE, "ogre/ogwake.wav", 1, ATTN_NORM);
- else if (self.classname == "monster_knight")
- sound_sight (self, CHAN_VOICE, "knight/ksight.wav", 1, ATTN_NORM);
- else if (self.classname == "monster_shambler")
- sound_sight (self, CHAN_VOICE, "shambler/ssight.wav", 1, ATTN_NORM);
- else if (self.classname == "monster_demon1")
- sound_sight (self, CHAN_VOICE, "demon/sight2.wav", 1, ATTN_NORM);
- else if (self.classname == "monster_wizard")
- sound_sight (self, CHAN_VOICE, "wizard/wsight.wav", 1, ATTN_NORM);
- else if (self.classname == "monster_zombie")
- sound_sight (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_NORM);
- else if (self.classname == "monster_dog")
- sound_sight (self, CHAN_VOICE, "dog/dsight.wav", 1, ATTN_NORM); //dumptruck_ds
- else if (self.classname == "monster_hell_knight")
- sound_sight (self, CHAN_VOICE, "hknight/sight1.wav", 1, ATTN_NORM);
- else if (self.classname == "monster_enforcer")
- {
- rsnd = rint(random() * 3);
- if (rsnd == 1)
- sound_sight (self, CHAN_VOICE, "enforcer/sight1.wav", 1, ATTN_NORM); //dumptruck_ds
- else if (rsnd == 2)
- sound_misc (self, CHAN_VOICE, "enforcer/sight2.wav", 1, ATTN_NORM);
- else if (rsnd == 0)
- sound_misc1 (self, CHAN_VOICE, "enforcer/sight3.wav", 1, ATTN_NORM);
- else
- sound_misc2 (self, CHAN_VOICE, "enforcer/sight4.wav", 1, ATTN_NORM);
- }
- else if (self.classname == "monster_army")
- sound_sight (self, CHAN_VOICE, "soldier/sight1.wav", 1, ATTN_NORM);
- else if (self.classname == "monster_shalrath")
- sound_sight (self, CHAN_VOICE, "shalrath/sight.wav", 1, ATTN_NORM);
- else if (self.classname == "monster_oldone2") //dumptruck_ds added Shub sighting SFX
- sound_sight (self, CHAN_VOICE, "boss2/sight.wav", 1, ATTN_NONE);
-};
-
-void() FoundTarget =
-{
- if (self.enemy.classname == "player")
- { // let other monsters see this monster for a while
- sight_entity = self;
- sight_entity_time = time;
- }
-
- self.show_hostile = time + 1; // wake up other monsters
-
- if !(self.spawnflags & NO_SIGHT_SOUND || self.spawnflags & PASSIVE_ALWAYS || self.spawnflags & PASSIVE_UNTIL_ATTACKED)
- {
- SightSound ();
- }
- HuntTarget ();
-
- if (self.sight_trigger == 1) //thanks RennyC -- dumptruck_ds
- {
- activator = self.enemy;
- SUB_UseAndForgetTargets ();
- }
-};
-
-/*
-===========
-FindTarget
-
-Self is currently not attacking anything, so try to find a target
-
-Returns TRUE if an enemy was sighted
-
-When a player fires a missile, the point of impact becomes a fakeplayer so
-that monsters that see the impact will respond as if they had seen the
-player.
-
-To avoid spending too much time, only a single client (or fakeclient) is
-checked each frame. This means multi player games will have slightly
-slower noticing monsters.
-============
-*/
-float() FindTarget =
-{
- local entity client;
- local float r;
-
-// if the first spawnflag bit is set, the monster will only wake up on
-// really seeing the player, not another monster getting angry
-
-// spawnflags & 3 is a big hack, because zombie crucified used the first
-// spawn flag prior to the ambush flag, and I forgot about it, so the second
-// spawn flag works as well
- if (sight_entity_time >= time - 0.1 && !(self.spawnflags & 3) )
- {
- client = sight_entity;
- if (client.enemy == self.enemy)
- return TRUE;
- }
- else
- {
- client = checkclient ();
- if (!client)
- return FALSE; // current check entity isn't in PVS
- }
-
- if ((self.spawnflags & PASSIVE_UNTIL_ATTACKED) || (self.spawnflags & PASSIVE_ALWAYS))
- return FALSE;
-
- if (client.flags & FL_NOTARGET || client.movetype == MOVETYPE_NOCLIP) // from Copper -- dumptruck_ds
- return FALSE;
-
- if (client.health <= 0)
- return FALSE;
-
- if (client.classname != "player")
- if (client.enemy.health <= 0)
- return FALSE;
-
- if (client == self.enemy)
- return FALSE;
-
- if (client.flags & FL_NOTARGET)
- return FALSE;
- if (client.items & IT_INVISIBILITY)
- return FALSE;
-
- r = range (client);
- if (r == RANGE_FAR)
- return FALSE;
-
- if (!visible (client))
- return FALSE;
-
- if (r == RANGE_NEAR)
- {
- if (client.show_hostile < time && !infront (client))
- return FALSE;
- }
- else if (r == RANGE_MID)
- {
- if ( /* client.show_hostile < time || */ !infront (client))
- return FALSE;
- }
-
-//
-// got one
-//
- self.enemy = client;
- if (self.enemy.classname != "player")
- {
- self.enemy = self.enemy.enemy;
- if (self.enemy.classname != "player")
- {
- self.enemy = world;
- return FALSE;
- }
- }
-
- FoundTarget ();
-
- return TRUE;
-};
-
-
-//=============================================================================
-
-void(float dist) ai_forward =
-{
- // dprint("ai_forward\n");
- walkmove (self.angles_y, dist);
-};
-
-void(float dist) ai_back =
-{
- // dprint("ai_back\n");
- walkmove ( (self.angles_y+180), dist);
-};
-
-
-/*
-=============
-ai_pain
-
-stagger back a bit
-=============
-*/
-void(float dist) ai_pain =
-{
-
- ai_back (dist);
-/*
- local float away;
-
- away = anglemod (vectoyaw (self.origin - self.enemy.origin)
- + 180*(random()- 0.5) );
-
- walkmove (away, dist);
-*/
-};
-
-/*
-=============
-ai_painforward
-
-stagger back a bit
-=============
-*/
-void(float dist) ai_painforward =
-{
- // dprint("ai_painforward\n");
- walkmove (self.ideal_yaw, dist);
-};
-
-/*
-=============
-ai_walk
-
-The monster is walking it's beat
-=============
-*/
-void(float dist) ai_walk =
-{
-
- movedist = dist;
-
- if (self.classname == "monster_dragon")
- {
- movetogoal (dist);
- return;
- }
- // check for noticing a player
- if (FindTarget ())
- return;
-
- movetogoal (dist);
-};
-
-
-/*
-=============
-ai_stand
-
-The monster is staying in one place for a while, with slight angle turns
-=============
-*/
-void() ai_stand =
-{
- if (FindTarget ())
- return;
-
- if (time > self.pausetime)
- {
- self.th_walk ();
- return;
- }
-
-// change angle slightly
-
-};
-
-/*
-=============
-ai_turn
-
-don't move, but turn towards ideal_yaw
-=============
-*/
-void() ai_turn =
-{
- if (FindTarget ())
- return;
-
- ChangeYaw ();
-};
-
-//=============================================================================
-
-/*
-=============
-ChooseTurn
-=============
-*/
-void(vector dest3) ChooseTurn =
-{
- local vector dir, newdir;
-
- dir = self.origin - dest3;
-
- newdir_x = trace_plane_normal_y;
- newdir_y = 0 - trace_plane_normal_x;
- newdir_z = 0;
-
- if (dir * newdir > 0)
- {
- dir_x = 0 - trace_plane_normal_y;
- dir_y = trace_plane_normal_x;
- }
- else
- {
- dir_x = trace_plane_normal_y;
- dir_y = 0 - trace_plane_normal_x;
- }
-
- dir_z = 0;
- self.ideal_yaw = vectoyaw(dir);
-};
-
-/*
-============
-FacingIdeal
-
-============
-*/
-float() FacingIdeal =
-{
- local float delta;
-
- delta = anglemod(self.angles_y - self.ideal_yaw);
- if (delta > 45 && delta < 315)
- return FALSE;
- return TRUE;
-};
-
-
-//=============================================================================
-
-float() WizardCheckAttack;
-float() DogCheckAttack;
-
-float() CheckAnyAttack =
-{
- if (cutscene) // Drake devkit -- dumptruck_ds
- if (self.enemy.classname == "camera")
- return FALSE; // Don't attack the camera (player)!
-
- if (!enemy_vis)
- return FALSE;
- if (self.classname == "monster_army")
- return SoldierCheckAttack ();
- if ((self.classname == "monster_ogre") || (self.classname == "monster_ogre_marksman"))
- return OgreCheckAttack ();
- if (self.classname == "monster_shambler")
- return ShamCheckAttack ();
- if (self.classname == "monster_demon1")
- return DemonCheckAttack ();
- if (self.classname == "monster_dog")
- return DogCheckAttack ();
- if (self.classname == "monster_wizard")
- return WizardCheckAttack ();
- return CheckAttack ();
-};
-
-
-/*
-=============
-ai_run_melee
-
-Turn and close until within an angle to launch a melee attack
-=============
-*/
-void() ai_run_melee =
-{
- self.ideal_yaw = enemy_yaw;
- ChangeYaw ();
-
- if (FacingIdeal())
- {
- self.th_melee ();
- self.attack_state = AS_STRAIGHT;
- }
-};
-
-
-/*
-=============
-ai_run_missile
-
-Turn in place until within an angle to launch a missile attack
-=============
-*/
-void() ai_run_missile =
-{
- self.ideal_yaw = enemy_yaw;
- // dprint("ai_run_missile GO\n");
- ChangeYaw ();
- if (FacingIdeal())
- {
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_turret();
- // dprint("th_turret...\n");
- }
- else
- {
- self.th_missile ();
- // dprint("th_missile\n");
- }
- self.attack_state = AS_STRAIGHT;
- }
-};
-
-
-/*
-=============
-ai_run_slide
-
-Strafe sideways, but stay at aproximately the same range
-=============
-*/
-void() ai_run_slide =
-{
- local float ofs;
-
- self.ideal_yaw = enemy_yaw;
- ChangeYaw ();
- if (self.lefty)
- ofs = 90;
- else
- ofs = -90;
-
- if (walkmove (self.ideal_yaw + ofs, movedist))
- return;
-
- self.lefty = 1 - self.lefty;
-
- walkmove (self.ideal_yaw - ofs, movedist);
-};
-
-
-/*
-=============
-ai_run
-
-The monster has an enemy it is trying to kill
-=============
-*/
-void(float dist) ai_run =
-{
- // dprint("ai_run\n");
- movedist = dist;
-// see if the enemy is dead
- if ((self.enemy.health <= 0) || (self.spawnflags & PASSIVE_ALWAYS))
- {
- self.enemy = world;
- // FIXME: look all around for other targets
- if (self.oldenemy.health > 0)
- {
- self.enemy = self.oldenemy;
- HuntTarget ();
- }
- else
- {
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_stand ();
- }
- else if (self.movetarget)
- self.th_walk ();
- else
- self.th_stand ();
- return;
- }
- }
-
- self.show_hostile = time + 1; // wake up other monsters
-
-// check knowledge of enemy
- enemy_vis = visible(self.enemy);
- if (enemy_vis)
- self.search_time = time + 5;
-
-// look for other coop players
- if (coop && self.search_time < time)
- {
- if (FindTarget ())
- return;
- }
-
- enemy_infront = infront(self.enemy);
- enemy_range = range(self.enemy);
- enemy_yaw = vectoyaw(self.enemy.origin - self.origin);
-
- if (self.spawnflags & I_AM_TURRET)
- {
- ai_face ();
- }
-
- // if ((self.attack_state == AS_MISSILE) || !(self.spawnflags & I_AM_TURRET))
- if (self.attack_state == AS_MISSILE)
- {
- // dprint ("ai_run_missile... from ai_run\n");
- ai_run_missile ();
- return;
- }
- // if ((self.attack_state == AS_MELEE) || !(self.spawnflags & I_AM_TURRET))
- if (self.attack_state == AS_MELEE)
- {
-//dprint ("ai_run_melee\n");
- ai_run_melee ();
- return;
- }
-
- if (CheckAnyAttack ())
- return; // beginning an attack
-
- // if ((self.attack_state == AS_SLIDING) || !(self.spawnflags & I_AM_TURRET))
- if (self.attack_state == AS_SLIDING)
- {
- ai_run_slide ();
- return;
- }
- // part of monster face from TheSolipsist
- // urged to change positions
- if (time < self.t_length) // if orientation is forced
- {
- ChangeYaw();
-
- if (walkmove(self.ideal_yaw, dist))
- return;
-
- self.ideal_yaw += 30; // dodge left
- ChangeYaw();
-
- if (walkmove(self.ideal_yaw, dist))
- return;
-
- self.ideal_yaw -= 60; // dodge right
- ChangeYaw();
- ChangeYaw();
-
- if (walkmove(self.ideal_yaw, dist))
- return;
-
- self.ideal_yaw += 30; // give up
- ChangeYaw();
- self.touch_time = self.touch_time - 0.1; // lose patience
-
- return;
- }
-
-if !(self.spawnflags & I_AM_TURRET) // keeps monster from moving to player - dumptruck_ds
-// head straight in
- movetogoal (dist); // done in C code...
-};
-/*
-=============
-visibleToOther
-
-returns 1 if the entity is visible to other, even if not infront ()
-=============
-*/
-float (entity targ) visibleToOther =
-{
- local vector spot1, spot2;
-
- spot1 = other.origin + other.view_ofs;
- spot2 = targ.origin + targ.view_ofs;
- traceline(spot1, spot2, TRUE, other); // see through other monsters
-
- if (trace_inopen && trace_inwater)
- return FALSE; // sight line crossed contents
-
- if (trace_fraction == 1)
- return TRUE;
-
- return FALSE;
-};
-
-//----------------------------------------------------------------------------

Return to the top of this page or return to the overview of this repo.

Diff qc-server/buttons.qc

diff --git a/qc-server/buttons.qc b/qc-server/buttons.qc
deleted file mode 100644
index bc34e53..0000000
--- a/qc-server/buttons.qc
+++ /dev/null
@@ -1,205 +0,0 @@
-// button and multiple button
-
-void() button_wait;
-void() button_return;
-
-void() button_wait =
-{
- self.state = STATE_TOP;
- self.nextthink = self.ltime + self.wait;
- self.think = button_return;
- activator = self.enemy;
- self.frame = 1; // use alternate textures
-
- if (self.estate != STATE_ACTIVE)
- return;
-
- SUB_UseTargets();
-
-};
-
-void() button_done =
-{
- self.state = STATE_BOTTOM;
-};
-
-void() button_return =
-{
- if (self.estate != STATE_ACTIVE) return;
-
- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos1, self.speed, button_done);
- self.frame = 0; // use normal textures
- if (self.health)
- self.takedamage = DAMAGE_YES; // can be shot again
-};
-
-
-void() button_blocked =
-{ // do nothing, just don't ome all the way back out
-};
-
-
-void() button_fire =
-{
- if (self.estate != STATE_ACTIVE) return;
-
- if (self.state == STATE_UP || self.state == STATE_TOP)
- return;
-
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
-
- self.state = STATE_UP;
- SUB_CalcMove (self.pos2, self.speed, button_wait);
-};
-
-
-void() button_use =
-{
- self.enemy = activator;
- button_fire ();
-};
-
-void() button_touch =
-{
- if (other.classname != "player")
- return;
- self.enemy = other;
- button_fire ();
-};
-
-void() button_killed =
-{
- if (self.estate != STATE_ACTIVE) return;
-
- self.enemy = damage_attacker;
- self.health = self.max_health;
- self.takedamage = DAMAGE_NO; // wil be reset upon return
- button_fire ();
-};
-
-
-
-// adapted from Copper, thanks Lunaran
-void(entity b) button_lock =
-{
- entity oself;
-
- if (b.estate == STATE_INACTIVE)
- return;
-
- oself = self;
- self = b;
-
- if (self.state == STATE_UP || self.state == STATE_TOP)
- self.prevstate = STATE_TOP;
- else
- self.prevstate = STATE_BOTTOM;
-
- if (self.max_health)
- self.takedamage = DAMAGE_NO;
- self.state = STATE_UP;
- SUB_CalcMove (self.pos2, self.speed, button_wait);
- self.estate = STATE_INACTIVE;
-
- self = oself;
-}
-
-void(entity b, float dontresetstate) button_unlock =
-{
- entity oself;
-
- if (b.estate == STATE_ACTIVE)
- return;
-
- oself = self;
- self = b;
-
- if (!dontresetstate || self.wait != -1 || self.prevstate == STATE_BOTTOM) {
- if (self.max_health)
- {
- self.takedamage = DAMAGE_YES;
- self.health = self.max_health;
- }
- self.frame = 0; // use normal textures
- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos1, self.speed, button_done);
- }
-
- self.estate = STATE_ACTIVE;
-
- self = oself;
-}
-
-
-/*QUAKED func_button (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again.
-
-"angle" determines the opening direction
-"target" all entities with a matching targetname will be used
-"speed" override the default 40 speed
-"wait" override the default 1 second wait (-1 = never return)
-"lip" override the default 4 pixel lip remaining at end of move
-"health" if set, the button must be killed instead of touched
-"sounds"
-0) steam metal
-1) wooden clunk
-2) metallic click
-3) in-out
-*/
-void() func_button =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.sounds == 0)
- {
- precache_sound ("buttons/airbut1.wav");
- self.noise = "buttons/airbut1.wav";
- }
- if (self.sounds == 1)
- {
- precache_sound ("buttons/switch21.wav");
- self.noise = "buttons/switch21.wav";
- }
- if (self.sounds == 2)
- {
- precache_sound ("buttons/switch02.wav");
- self.noise = "buttons/switch02.wav";
- }
- if (self.sounds == 3)
- {
- precache_sound ("buttons/switch04.wav");
- self.noise = "buttons/switch04.wav";
- }
-
- SetMovedir ();
-
- self.movetype = MOVETYPE_PUSH;
- self.solid = SOLID_BSP;
- setmodel (self, self.model);
-
- self.blocked = button_blocked;
- self.use = button_use;
-
- if (self.health)
- {
- self.max_health = self.health;
- self.th_die = button_killed;
- self.takedamage = DAMAGE_YES;
- }
- else
- self.touch = button_touch;
-
- if (!self.speed)
- self.speed = 40;
- if (!self.wait)
- self.wait = 1;
- if (!self.lip)
- self.lip = 4;
-
- self.state = STATE_BOTTOM;
-
- self.pos1 = self.origin;
- self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/client.qc

diff --git a/qc-server/client.qc b/qc-server/client.qc
deleted file mode 100644
index cb97b95..0000000
--- a/qc-server/client.qc
+++ /dev/null
@@ -1,1447 +0,0 @@
-
-// prototypes
-void () W_WeaponFrame;
-void() W_SetCurrentAmmo;
-void(entity attacker, float damage) player_pain;
-void() player_stand1;
-//void (vector org) spawn_tfog; //moved to items.qc -- dumptruck_ds
-void (vector org, entity death_owner) spawn_tdeath;
-
-
-float modelindex_eyes, modelindex_player;
-void() SUB_CheckWaiting; // in triggers.qc
-
-
-
-
-
-void() SetChangeParms =
-{
- if (self.health <= 0)
- {
- SetNewParms ();
- return;
- }
-
-// remove items
- self.items = self.items - (self.items &
- (IT_KEY1 | IT_KEY2 | IT_INVISIBILITY | IT_INVULNERABILITY | IT_SUIT | IT_QUAD) );
-
-// cap super health
- if (self.health > 100)
- self.health = 100;
- if (self.health < 50)
- self.health = 50;
- parm1 = self.items;
- parm2 = self.health;
- parm3 = self.armorvalue;
- if (self.ammo_shells < 25)
- parm4 = 25;
- else
- parm4 = self.ammo_shells;
- parm5 = self.ammo_nails;
- parm6 = self.ammo_rockets;
- parm7 = self.ammo_cells;
- parm8 = self.weapon;
- parm9 = self.armortype * 100;
-};
-
-void() SetNewParms =
-{
- parm2 = 100; // self.health
- parm3 = 0; // self.armorvalue
- parm5 = 0; // self.ammo_nails
- parm6 = 0; // self.ammo_rockets
- parm7 = 0; // self.ammo_cells
- parm9 = 0; // self.armortype * 100
-
-// "reset_items 2" makes the player start with only the axe -- iw
- if (world.reset_items == 2)
- {
- parm1 = IT_AXE; // self.items
- parm4 = 0; // self.ammo_shells
- parm8 = IT_AXE; // self.weapon
- }
- else
- {
- parm1 = IT_AXE | IT_SHOTGUN; // self.items
- parm4 = 25; // self.ammo_shells
- parm8 = IT_SHOTGUN; // self.weapon
- }
-};
-
-void() DecodeLevelParms =
-{
-// Reset the player's inventory if they returned to the start map with
-// a rune, or if the mapper set the "reset_items" field of worldspawn to
-// a non-zero value. (The old "reset_items" check, which this replaces,
-// had a comment from dumptruck_ds thanking Spike.) -- iw
-//
- if ((serverflags != 0 && world.model == "maps/start.bsp") ||
- world.reset_items != 0)
- {
- SetNewParms ();
- }
-
- self.items = parm1;
- self.health = parm2;
- self.armorvalue = parm3;
- self.ammo_shells = parm4;
- self.ammo_nails = parm5;
- self.ammo_rockets = parm6;
- self.ammo_cells = parm7;
- self.weapon = parm8;
- self.armortype = parm9 * 0.01;
-};
-
-void(entity client, string savename) autosave =
-{
- //autosavename = savename;
- stuffcmd(client, "echo Autosaving...; wait; save ");
- stuffcmd(client, savename);
- stuffcmd(client, "\n");
-}
-
-/*
-=============================================================================
-
- PLAYER GAME EDGE FUNCTIONS
-
-=============================================================================
-*/
-
-void() set_suicide_frame;
-
-// called by ClientKill and DeadThink
-void() respawn =
-{
- if (coop)
- {
- // make a copy of the dead body for appearances sake
- CopyToBodyQue (self);
- // get the spawn parms as they were at level start
- setspawnparms (self);
- // respawn
- PutClientInServer ();
- }
- else if (deathmatch)
- {
- // make a copy of the dead body for appearances sake
- CopyToBodyQue (self);
- // set default spawn parms
- SetNewParms ();
- // respawn
- PutClientInServer ();
- }
- else
- { // restart the entire server
- localcmd ("restart\n");
- }
-};
-
-
-/*
-============
-ClientKill
-
-Player entered the suicide command
-============
-*/
-void() ClientKill =
-
-{
- // 1998-07-27 Suicide during intermission fix by Zhenga start
- if ((intermission_running)&&((coop)||(deathmatch))) // not allowed during intermission
- return;
-// 1998-07-27 Suicide during intermission fix by Zhenga end
- bprint (self.netname);
- bprint (" suicides\n");
- set_suicide_frame ();
- self.modelindex = modelindex_player;
- self.frags = self.frags - 2; // extra penalty
- respawn ();
-};
-
-float(vector v) CheckSpawnPoint =
-{
- return FALSE;
-};
-
-/*
-============
-SelectSpawnPoint
-
-Returns the entity to spawn at
-============
-*/
-entity() SelectSpawnPoint =
-{
- local entity spot;
- local entity thing;
- local float pcount;
-
-// testinfo_player_start is only found in regioned levels
- spot = find (world, classname, "testplayerstart");
- if (spot)
- return spot;
-
-// choose a info_player_deathmatch point
- if (coop)
- {
- lastspawn = find(lastspawn, classname, "info_player_coop");
- if (lastspawn == world)
- lastspawn = find (lastspawn, classname, "info_player_start");
- if (lastspawn != world)
- return lastspawn;
- }
- else if (deathmatch)
- {
- spot = lastspawn;
- while (1)
- {
- spot = find(spot, classname, "info_player_deathmatch");
- if (spot != world)
- {
- if (spot == lastspawn)
- return lastspawn;
- pcount = 0;
- thing = findradius(spot.origin, 32);
- while(thing)
- {
- if (thing.classname == "player")
- pcount = pcount + 1;
- thing = thing.chain;
- }
- if (pcount == 0)
- {
- lastspawn = spot;
- return spot;
- }
- }
- }
- }
-
- if (serverflags)
- { // return with a rune to start
- spot = find (world, classname, "info_player_start2");
- if (spot)
- return spot;
- }
-
- spot = find (world, classname, "info_player_start");
- if (!spot)
- error ("PutClientInServer: no info_player_start on level");
-
- return spot;
-};
-
-/*
-===========
-PutClientInServer
-
-called each time a player is spawned
-============
-*/
-void() DecodeLevelParms;
-void() PlayerDie;
-void() monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
-
-void() PutClientInServer =
-{
- local entity spot;
-
- spot = SelectSpawnPoint ();
-
- self.classname = "player";
- self.health = 100;
- self.takedamage = DAMAGE_AIM;
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_WALK;
- self.show_hostile = 0;
- self.max_health = 100;
- self.flags = FL_CLIENT;
- self.air_finished = time + 12;
- self.dmg = 2; // initial water damage
- self.super_damage_finished = 0;
- self.radsuit_finished = 0;
- self.invisible_finished = 0;
- self.invincible_finished = 0;
- self.effects = 0;
- self.invincible_time = 0;
- self.deathtype = "";
- self.gravity = 0;
- self.wantedgravity = 0;
- self.onladder = 0;
- self.customkeys = 0; // support for item_key_custom -- iw
-
- // Setup cutscene stuff. Legacy code from Zerstorer. --dumptruck_ds
- self.script_count = 2;
- self.script_delay = 1;
- self.script_time = 0;
-
-
- DecodeLevelParms ();
-
- W_SetCurrentAmmo ();
-
- self.attack_finished = time;
- self.th_pain = player_pain;
- self.th_die = PlayerDie;
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
- self.deadflag = DEAD_NO;
-// paustime is set by teleporters to keep the player from moving a while
- self.pausetime = 0;
-
-// spot = SelectSpawnPoint ();
-
- self.origin = spot.origin + '0 0 1';
- self.angles = spot.angles;
- self.fixangle = TRUE; // turn this way immediately
-
- // fog control.
- // Looks if there's any fog values set at the current spawn point. If not, looks for those in worldspawn instead
- if (spot.fog_density)
- fog_save(self, spot.fog_density, spot.fog_color);
- else if (world.fog_density)
- fog_save(self, world.fog_density, world.fog_color);
-
- if (spot.skyfog_density)
- skyfog_save(self, spot.skyfog_density);
- else if (world.skyfog_density)
- skyfog_save(self, world.skyfog_density);
-
- cleanUpClientStuff = 2; // decreased on subsequent frames, used to startup some fog-related stuff
-
-// oh, this is a hack!
- setmodel (self, "progs/eyes.mdl");
- modelindex_eyes = self.modelindex;
-
- setmodel (self, "progs/s_null.spr"); // Drake -- dumptruck_ds
- // setmodel (self, "progs/null_256.spr"); // Drake -- dumptruck_ds
- mindex_inviso = self.modelindex;
-
- setmodel (self, "progs/player.mdl");
- modelindex_player = self.modelindex;
-
- setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
-
- self.view_ofs = '0 0 22';
-// Mod - Xian (May.20.97)
-// Bug where player would have velocity from their last kill
- self.velocity = '0 0 0'; // 1998-07-21 Player moves after respawn fix by Xian
-
- player_stand1 ();
-
- if (deathmatch || coop)
- {
- makevectors(self.angles);
- spawn_tfog (self.origin + v_forward*20);
- }
-
- spawn_tdeath (self.origin, self);
-};
-
-
-/*
-=============================================================================
-
- QUAKED FUNCTIONS
-
-=============================================================================
-*/
-
-
-/*QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/player.mdl");
-}
-The normal starting point for a level.
-*/
-void() info_player_start =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-};
-
-
-/*QUAKED info_player_start2 (1 0 0) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/player.mdl");
-}
-Only used on start map for the return point from an episode.
-*/
-void() info_player_start2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-};
-
-
-/*
-saved out by quaked in region mode
-*/
-void() testplayerstart =
-{
-};
-
-/*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/player.mdl");
-}
-potential spawning position for deathmatch games
-*/
-void() info_player_deathmatch =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-};
-
-/*QUAKED info_player_coop (1 0 1) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/player.mdl");
-}
-potential spawning position for coop games
-*/
-void() info_player_coop =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-};
-
-/*QUAKED info_monster_spawnpoint (1 0 1) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/teleport.mdl");
-}
- spawning position for func_monster_spawner
-*/
-void() info_monster_spawnpoint =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-};
-
-/*
-===============================================================================
-
-RULES
-
-===============================================================================
-*/
-
-/*
-go to the next level for deathmatch
-only called if a time or frag limit has expired
-*/
-void() NextLevel =
-{
- local entity o;
-
- if (mapname == "start")
- {
- if (!cvar("registered"))
- {
- mapname = "e1m1";
- }
- else if (!(serverflags & 1))
- {
- mapname = "e1m1";
- serverflags = serverflags | 1;
- }
- else if (!(serverflags & 2))
- {
- mapname = "e2m1";
- serverflags = serverflags | 2;
- }
- else if (!(serverflags & 4))
- {
- mapname = "e3m1";
- serverflags = serverflags | 4;
- }
- else if (!(serverflags & 8))
- {
- mapname = "e4m1";
- serverflags = serverflags - 7;
- }
-
- o = spawn();
- o.map = mapname;
- }
- else
- {
- // find a trigger changelevel
- o = find(world, classname, "trigger_changelevel");
-
- // go back to start if no trigger_changelevel
- if (!o)
- {
- mapname = "start";
- o = spawn();
- o.map = mapname;
- }
- }
-
- nextmap = o.map;
- gameover = TRUE;
-
- if (o.nextthink < time)
- {
- o.think = execute_changelevel;
- o.nextthink = time + 0.1;
- }
-};
-
-/*
-============
-CheckRules
-
-Exit deathmatch games upon conditions
-============
-*/
-void() CheckRules =
-{
- local float timelimit;
- local float fraglimit;
-
- if (gameover) // someone else quit the game already
- return;
-
- timelimit = cvar("timelimit") * 60;
- fraglimit = cvar("fraglimit");
-
-if (deathmatch && timelimit && time >= timelimit) // 1998-07-27 Timelimit/Fraglimit fix by Maddes
- {
- NextLevel ();
- return;
- }
-
-if (deathmatch && fraglimit && self.frags >= fraglimit) // 1998-07-27 Timelimit/Fraglimit fix by Maddes
- {
- NextLevel ();
- return;
- }
-};
-
-//============================================================================
-
-void() PlayerDeathThink =
-{
- local float forward;
-
- if ((self.flags & FL_ONGROUND))
- {
- forward = vlen (self.velocity);
- forward = forward - 20;
- if (forward <= 0)
- self.velocity = '0 0 0';
- else
- self.velocity = forward * normalize(self.velocity);
- }
-
-// wait for all buttons released
- if (self.deadflag == DEAD_DEAD)
- {
- if (self.button2 || self.button1 || self.button0)
- return;
- self.deadflag = DEAD_RESPAWNABLE;
- return;
- }
-
-// wait for any button down
- if (!self.button2 && !self.button1 && !self.button0)
- return;
-
- self.button0 = 0;
- self.button1 = 0;
- self.button2 = 0;
- respawn();
-};
-
-/*
-===========
-PlayerClimb
-============
-*/
-void() PlayerClimb = //johnfitz
-{
- self.velocity = '0 0 160';
-}
-
-
-void() PlayerJump =
-{
-
- if (self.flags & FL_WATERJUMP)
- return;
-
- if (self.waterlevel >= 2)
- {
- if (self.watertype == CONTENT_WATER)
- self.velocity_z = 100;
- else if (self.watertype == CONTENT_SLIME)
- self.velocity_z = 80;
- else
- self.velocity_z = 50;
-
-// play swiming sound
- if (self.swim_flag < time)
- {
- self.swim_flag = time + 1;
- if (random() < 0.5)
- sound (self, CHAN_BODY, "misc/water1.wav", 1, ATTN_NORM);
- else
- sound (self, CHAN_BODY, "misc/water2.wav", 1, ATTN_NORM);
- }
-
- return;
- }
-
- // refactoring from Copper -- dumptruck_ds
- if (self.movetype != MOVETYPE_NOCLIP)
- {
- if (!(self.flags & FL_ONGROUND)) return;
- if ( !(self.flags & FL_JUMPRELEASED) ) return; // don't pogo stick
- // player jumping sound
- sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM); // h00rt
- }
-
- // if (!(self.flags & FL_ONGROUND))
- // return;
- //
- // if ( !(self.flags & FL_JUMPRELEASED) )
- // return; // don't pogo stick
- // refactoring from Copper -- dumptruck_ds
- // self.flags = not(self.flags, FL_JUMPRELEASED | FL_ONGROUND); // don't stairwalk
-
- self.flags = self.flags - (self.flags & FL_JUMPRELEASED);
-
- self.flags = self.flags - FL_ONGROUND; // don't stairwalk
-
- self.button2 = 0;
- // sound (self, CHAN_AUTO, "player/plyrjmp8.wav", 1, ATTN_NORM);
- self.velocity_z = self.velocity_z + 270;
-};
-
-
-/*
-===========
-WaterMove
-
-============
-*/
-.float dmgtime;
-
-void() WaterMove =
-{
-//dprint (ftos(self.waterlevel));
- // if (self.movetype == MOVETYPE_NOCLIP)
- // return;
- //from Copper -- dumptruck_ds
- if (self.movetype == MOVETYPE_NOCLIP)
- {
- self.air_finished = time + 120;
- return;
- }
-
- if (self.health < 0)
- return;
-
- if (self.waterlevel != 3)
- {
- if (self.air_finished < time)
- sound (self, CHAN_VOICE, "player/gasp2.wav", 1, ATTN_NORM);
- else if (self.air_finished < time + 9)
- sound (self, CHAN_VOICE, "player/gasp1.wav", 1, ATTN_NORM);
- self.air_finished = time + 12;
- self.dmg = 2;
- }
- else if (self.air_finished < time)
- { // drown!
- if (self.pain_finished < time)
- {
- self.dmg = self.dmg + 2;
- if (self.dmg > 15)
- self.dmg = 10;
- self.deathtype = "drowning";
- T_Damage (self, world, world, self.dmg);
- self.deathtype = "";
- self.pain_finished = time + 1;
- }
- }
-
- if (!self.waterlevel)
- {
- if (self.flags & FL_INWATER)
- {
- // play leave water sound
- sound (self, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM);
- self.flags = self.flags - FL_INWATER;
- }
- return;
- }
-
- if (self.watertype == CONTENT_LAVA)
- { // do damage
- if (self.dmgtime < time)
- {
- if (self.radsuit_finished > time)
- self.dmgtime = time + 1;
- else
- self.dmgtime = time + 0.2;
-
- self.deathtype = "lava";
- T_Damage (self, world, world, 10*self.waterlevel);
- self.deathtype = "";
- }
- }
- else if (self.watertype == CONTENT_SLIME)
- { // do damage
- if (self.dmgtime < time && self.radsuit_finished < time)
- {
- self.dmgtime = time + 1;
- self.deathtype = "slime";
- T_Damage (self, world, world, 4*self.waterlevel);
- self.deathtype = "";
- }
- }
-
- if ( !(self.flags & FL_INWATER) )
- {
-
-// player enter water sound
-
- if (self.watertype == CONTENT_LAVA)
- sound (self, CHAN_BODY, "player/inlava.wav", 1, ATTN_NORM);
- if (self.watertype == CONTENT_WATER)
- sound (self, CHAN_BODY, "player/inh2o.wav", 1, ATTN_NORM);
- if (self.watertype == CONTENT_SLIME)
- sound (self, CHAN_BODY, "player/slimbrn2.wav", 1, ATTN_NORM);
-
- self.flags = self.flags + FL_INWATER;
- self.dmgtime = 0;
- }
-
- if (! (self.flags & FL_WATERJUMP) )
- self.velocity = self.velocity - 0.8*self.waterlevel*frametime*self.velocity;
-};
-
-void() CheckWaterJump =
-{
- if (self.movetype == MOVETYPE_NOCLIP) // from Copper -- dumptruck_ds
- return;
-
- local vector start, end;
-
-// check for a jump-out-of-water
- makevectors (self.angles);
- start = self.origin;
- start_z = start_z + 8;
- v_forward_z = 0;
- normalize(v_forward);
- end = start + v_forward*24;
- traceline (start, end, TRUE, self);
- if (trace_fraction < 1)
- { // solid at waist
- start_z = start_z + self.maxs_z - 8;
- end = start + v_forward*24;
- self.movedir = trace_plane_normal * -50;
- traceline (start, end, TRUE, self);
- if (trace_fraction == 1)
- { // open at eye level
- self.flags = self.flags | FL_WATERJUMP;
- self.velocity_z = 225;
- self.flags = self.flags - (self.flags & FL_JUMPRELEASED);
- self.teleport_time = time + 2; // safety net
- return;
- }
- }
-};
-
-
-/*
-================
-PlayerPreThink
-
-Called every frame before physics are run
-================
-*/
-void() PlayerPreThink =
-{
- local float do_ladder_physics;
-
- if (intermission_running)
- {
- IntermissionThink (); // otherwise a button could be missed between
- return; // the think tics
- }
-
- if (self.view_ofs == '0 0 0')
- {
- Cutscene_Think (); // Check for cutscene stuff.
- return; // intermission or finale
- }
-
- // note that this code block is here, before the tests which check
- // whether the player is dead, so that the player's gravity will be
- // correctly updated even if they e.g. fell off a ladder because
- // they died -- iw
- if (self.onladder)
- {
- do_ladder_physics = TRUE;
- self.gravity = 0.0000001; // not zero, because zero means "default"
- self.onladder = 0;
- }
- else
- {
- do_ladder_physics = FALSE;
- self.gravity = self.wantedgravity;
- }
-
- // If just spawned in, try to recover previous fog values from own client entity, if any
- if (cleanUpClientStuff)
- fog_setFromEnt(self, self);
-
- makevectors (self.v_angle); // is this still used
-
- CheckRules ();
- WaterMove ();
-
- if (self.waterlevel == 2)
- CheckWaterJump ();
-
- if (self.deadflag >= DEAD_DEAD)
- {
- PlayerDeathThink ();
- return;
- }
-
- if (self.deadflag == DEAD_DYING)
- return; // dying, so do nothing
-
-//johnfitz ladder conditions //added from Rubicon2 client.qc -- dumptruck_ds
-if (do_ladder_physics)
-{
- if (self.button2)
- {
- PlayerClimb ();
-
- /* no ladder footsteps for now
- if (time > self.ladder_step_finished) {
- r = random();
- if (r > 0.66)
- sound (self, CHAN_BODY, "ladder/metal1.wav", 0.5, ATTN_NORM);
- else if (r > 0.33)
- sound (self, CHAN_BODY, "ladder/metal2.wav", 0.5, ATTN_NORM);
- else
- sound (self, CHAN_BODY, "ladder/metal3.wav", 0.5, ATTN_NORM);
- self.ladder_step_finished = time + 0.3;
- }
- */
- }
- else
- {
- self.flags = self.flags | FL_JUMPRELEASED;
- self.velocity = 0.9 * self.velocity;
- self.velocity_z = 0;
- }
-}
-else
-{
- if (self.button2)
- PlayerJump ();
- else
- self.flags = self.flags | FL_JUMPRELEASED;
-} //johnfitz
-
-// teleporters can force a non-moving pause time
- if (time < self.pausetime)
- self.velocity = '0 0 0';
-
- if(time > self.attack_finished && self.currentammo == 0 && self.weapon != IT_AXE)
- {
- self.weapon = W_BestWeapon ();
- W_SetCurrentAmmo ();
- }
- // from copper -- dumptruck_ds
- if (self.movetype == MOVETYPE_NOCLIP)
- {
- self.flags = self.flags | FL_FLY;
- }
-};
-
-/*
-================
-CheckPowerups
-
-Check for turning off powerups
-================
-*/
-void() CheckPowerups =
-{
- if (self.health <= 0)
- return;
-
-// invisibility
- if (self.invisible_finished)
- {
-// sound and screen flash when items starts to run out
- if (self.invisible_sound < time)
- {
- sound (self, CHAN_AUTO, "items/inv3.wav", 0.5, ATTN_IDLE);
- self.invisible_sound = time + ((random() * 3) + 1);
- }
-
-
- if (self.invisible_finished < time + 3)
- {
- if (self.invisible_time == 1)
- {
- sprint (self, "Ring of Shadows magic is fading\n");
- stuffcmd (self, "bf\n");
- sound (self, CHAN_AUTO, "items/inv2.wav", 1, ATTN_NORM);
- self.invisible_time = time + 1;
- }
-
- if (self.invisible_time < time)
- {
- self.invisible_time = time + 1;
- stuffcmd (self, "bf\n");
- }
- }
-
- if (self.invisible_finished < time)
- { // just stopped
- self.items = self.items - IT_INVISIBILITY;
- self.invisible_finished = 0;
- self.invisible_time = 0;
- }
-
- // use the eyes
- self.frame = 0;
- self.modelindex = modelindex_eyes;
- }
- else
- self.modelindex = modelindex_player; // don't use eyes
-
-// invincibility
- if (self.invincible_finished)
- {
-// sound and screen flash when items starts to run out
- if (self.invincible_finished < time + 3)
- {
- if (self.invincible_time == 1)
- {
- sprint (self, "Protection is almost burned out\n");
- stuffcmd (self, "bf\n");
- sound (self, CHAN_AUTO, "items/protect2.wav", 1, ATTN_NORM);
- self.invincible_time = time + 1;
- }
-
- if (self.invincible_time < time)
- {
- self.invincible_time = time + 1;
- stuffcmd (self, "bf\n");
- }
- }
-
- if (self.invincible_finished < time)
- { // just stopped
- self.items = self.items - IT_INVULNERABILITY;
- self.invincible_time = 0;
- self.invincible_finished = 0;
- }
- if (self.invincible_finished > time)
- self.effects = self.effects | EF_DIMLIGHT;
- else
- self.effects = self.effects - (self.effects & EF_DIMLIGHT);
- }
-
-// super damage
- if (self.super_damage_finished)
- {
-
-// sound and screen flash when items starts to run out
-
- if (self.super_damage_finished < time + 3)
- {
- if (self.super_time == 1)
- {
- sprint (self, "Quad Damage is wearing off\n");
- stuffcmd (self, "bf\n");
- sound (self, CHAN_AUTO, "items/damage2.wav", 1, ATTN_NORM);
- self.super_time = time + 1;
- }
-
- if (self.super_time < time)
- {
- self.super_time = time + 1;
- stuffcmd (self, "bf\n");
- }
- }
-
- if (self.super_damage_finished < time)
- { // just stopped
- self.items = self.items - IT_QUAD;
- self.super_damage_finished = 0;
- self.super_time = 0;
- }
- if (self.super_damage_finished > time)
- self.effects = self.effects | EF_DIMLIGHT;
- else
- self.effects = self.effects - (self.effects & EF_DIMLIGHT);
- }
-
-// suit
- if (self.radsuit_finished)
- {
- self.air_finished = time + 12; // don't drown
-
-// sound and screen flash when items starts to run out
- if (self.radsuit_finished < time + 3)
- {
- if (self.rad_time == 1)
- {
- sprint (self, "Air supply in Biosuit expiring\n");
- stuffcmd (self, "bf\n");
- sound (self, CHAN_AUTO, "items/suit2.wav", 1, ATTN_NORM);
- self.rad_time = time + 1;
- }
-
- if (self.rad_time < time)
- {
- self.rad_time = time + 1;
- stuffcmd (self, "bf\n");
- }
- }
-
- if (self.radsuit_finished < time)
- { // just stopped
- self.items = self.items - IT_SUIT;
- self.rad_time = 0;
- self.radsuit_finished = 0;
- }
- }
-};
-
-/*
-================
-PlayerPostThink
-
-Called every frame after physics are run
-================
-*/
-void() PlayerPostThink =
-{
-
- if (self.view_ofs == '0 0 0')
- return; // intermission or finale
- if (self.deadflag)
- return;
-
-// do weapon stuff
-
- W_WeaponFrame ();
-
-// check to see if player landed and play landing sound
- if ((self.jump_flag < -300) && (self.flags & FL_ONGROUND) && (self.health > 0))
- {
- if (self.watertype == CONTENT_WATER)
- sound (self, CHAN_BODY, "player/h2ojump.wav", 1, ATTN_NORM);
- else if (self.jump_flag < -650)
- {
- self.deathtype = "falling";
- T_Damage (self, world, world, 5);
- self.deathtype = "";
- sound (self, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM);
- }
- else
- sound (self, CHAN_VOICE, "player/land.wav", 1, ATTN_NORM);
-
- self.jump_flag = 0;
- }
-
- if (!(self.flags & FL_ONGROUND))
- self.jump_flag = self.velocity_z;
-
- if (self.health > self.max_health) //dumptruck_ds -- this replaces item_megahealth_rot in items.qc
-
- {
- if (self.megahealth_rottime < time)
- {
- self.megahealth_rottime = time + 1;
- self.health = self.health - 1;
- }
-
- else if (self.health <= 100) //thanks ydrol!!!
- self.items = self.items - (self.items & IT_SUPERHEALTH);
-}
-
-CheckPowerups ();
-// from Copper -- dumptruck_ds
-if (self.movetype != MOVETYPE_NOCLIP)
-{
- self.flags = not(self.flags, FL_FLY);
-}
-
-};
-
-
-/*
-===========
-ClientConnect
-
-called when a player connects to a server
-============
-*/
-void() ClientConnect =
-{
- bprint (self.netname);
- bprint (" entered the game\n");
-
-// a client connecting during an intermission can cause problems
- if (intermission_running)
- ExitIntermission ();
-};
-
-
-/*
-===========
-ClientDisconnect
-
-called when a player disconnects from a server
-============
-*/
-void() ClientDisconnect =
-{
- if (gameover)
- return;
- // if the level end trigger has been activated, just return
- // since they aren't *really* leaving
-
- // let everyone else know
- bprint (self.netname);
- bprint (" left the game with ");
- bprint (ftos(self.frags));
- bprint (" frags\n");
- sound (self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE);
- set_suicide_frame ();
-};
-
-/*
-===========
-ClientObituary
-
-called when a player dies
-============
-*/
-void(entity targ, entity inflictor, entity attacker) ClientObituary =
-{
- local float rnum;
- local string deathstring, deathstring2;
- rnum = random();
-
- if (targ.classname == "player")
- {
- if (attacker.classname == "teledeath")
- {
- bprint (targ.netname);
- bprint (" was telefragged by ");
- bprint (attacker.owner.netname);
- bprint ("\n");
-
- attacker.owner.frags = attacker.owner.frags + 1;
- return;
- }
-
- if (attacker.classname == "teledeath2")
- {
- bprint ("Satan's power deflects ");
- bprint (targ.netname);
- bprint ("'s telefrag\n");
-
- targ.frags = targ.frags - 1;
- return;
- }
-// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes start
- // double 666 telefrag
- // (can happen often in deathmatch 4 and levels with more than one pentagram)
- if (attacker.classname == "teledeath3")
- {
- bprint (targ.netname);
- bprint (" was telefragged by ");
- bprint (attacker.owner.netname);
- bprint ("'s Satan's power\n");
-// 1998-07-26 only telefrag player on spot by Maddes start
-// targ.frags = targ.frags - 1;
- attacker.owner.frags = attacker.owner.frags + 1;
-// 1998-07-26 only telefrag player on spot by Maddes end
- return;
- }
-// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes end
- if (attacker.classname == "player")
- {
- if (targ == attacker)
- {
- // killed self
- attacker.frags = attacker.frags - 1;
- bprint (targ.netname);
-
- if (targ.weapon == 64 && targ.waterlevel > 1)
- {
- bprint (" discharges into the water.\n");
- return;
- }
- if (targ.weapon == IT_GRENADE_LAUNCHER)
- bprint (" tries to put the pin back in\n");
- else
- bprint (" becomes bored with life\n");
- return;
- }
- else if ( (teamplay == 2) && (targ.team > 0)&&(targ.team == attacker.team) )
- {
- if (rnum < 0.25)
- deathstring = " mows down a teammate\n";
- else if (rnum < 0.50)
- deathstring = " checks his glasses\n";
- else if (rnum < 0.75)
- deathstring = " gets a frag for the other team\n";
- else
- deathstring = " loses another friend\n";
- bprint (attacker.netname);
- bprint (deathstring);
- attacker.frags = attacker.frags - 1;
- return;
- }
- else
- {
- attacker.frags = attacker.frags + 1;
-
- rnum = attacker.weapon;
- if (rnum == IT_AXE)
- {
- deathstring = " was ax-murdered by ";
- deathstring2 = "\n";
- }
- if (rnum == IT_SHOTGUN)
- {
- deathstring = " chewed on ";
- deathstring2 = "'s boomstick\n";
- }
- if (rnum == IT_SUPER_SHOTGUN)
- {
- deathstring = " ate 2 loads of ";
- deathstring2 = "'s buckshot\n";
- }
- if (rnum == IT_NAILGUN)
- {
- deathstring = " was nailed by ";
- deathstring2 = "\n";
- }
- if (rnum == IT_SUPER_NAILGUN)
- {
- deathstring = " was punctured by ";
- deathstring2 = "\n";
- }
- if (rnum == IT_GRENADE_LAUNCHER)
- {
- deathstring = " eats ";
- deathstring2 = "'s pineapple\n";
- if (targ.health < -40)
- {
- deathstring = " was gibbed by ";
- deathstring2 = "'s grenade\n";
- }
- }
- if (rnum == IT_ROCKET_LAUNCHER)
- {
- deathstring = " rides ";
- deathstring2 = "'s rocket\n";
- if (targ.health < -40)
- {
- deathstring = " was gibbed by ";
- deathstring2 = "'s rocket\n" ;
- }
- }
- if (rnum == IT_LIGHTNING)
- {
- deathstring = " accepts ";
- if (attacker.waterlevel > 1)
- deathstring2 = "'s discharge\n";
- else
- deathstring2 = "'s shaft\n";
- }
- bprint (targ.netname);
- bprint (deathstring);
- bprint (attacker.netname);
- bprint (deathstring2);
- }
- return;
- }
- else
- {
- targ.frags = targ.frags - 1;
- bprint (targ.netname);
-
- // custom obituary messages
- if (inflictor.deathtype != "")
- {
- bprint (" ");
- bprint (inflictor.deathtype);
- bprint ("\n");
- return;
- }
- if (attacker.deathtype != "")
- {
- bprint (" ");
- bprint (attacker.deathtype);
- bprint ("\n");
- return;
- }
-
- // killed by a montser?
- // if (attacker.flags & FL_MONSTER)
- if ((attacker.flags & FL_MONSTER) && (attacker.obit_name == ""))
- {
- if (attacker.classname == "monster_army")
- bprint (" was shot by a Grunt\n");
- if (attacker.classname == "monster_demon1")
- bprint (" was eviscerated by a Fiend\n");
- if (attacker.classname == "monster_dog")
- bprint (" was mauled by a Rottweiler\n");
- if (attacker.classname == "monster_dragon")
- bprint (" was fried by a Dragon\n");
- if (attacker.classname == "monster_enforcer")
- bprint (" was blasted by an Enforcer\n");
- if (attacker.classname == "monster_fish")
- bprint (" was fed to the Rotfish\n");
- if (attacker.classname == "monster_hell_knight")
- bprint (" was slain by a Death Knight\n");
- if (attacker.classname == "monster_knight")
- bprint (" was slashed by a Knight\n");
- if (attacker.classname == "monster_ogre")
- bprint (" was destroyed by an Ogre\n");
- if (attacker.classname == "monster_ogre_marksman")
- bprint (" was felled by a Marksman\n"); // dumptruck_ds
- if (attacker.classname == "monster_oldone")
- bprint (" became one with Shub-Niggurath\n");
- if (attacker.classname == "monster_oldone2")// dumptruck_ds
- bprint (" became one with Shub-Niggurath\n");
- if (attacker.classname == "monster_boss2")// dumptruck_ds
- bprint (" was exploded by Chthon\n");
- if (attacker.classname == "monster_boss")// dumptruck_ds
- bprint (" was exploded by Chthon\n");
- if (attacker.classname == "monster_shalrath")
- bprint (" was exploded by a Vore\n");
- if (attacker.classname == "monster_shambler")
- bprint (" was smashed by a Shambler\n");
- if (attacker.classname == "monster_vomit")
- bprint (" was vomited on by a Vomitus\n");
- if (attacker.classname == "monster_wizard")
- bprint (" was scragged by a Scrag\n");
- if (attacker.classname == "monster_zombie")
- bprint (" joins the Zombies\n");
-
- return;
- }
- // obits for custom monsters -- progs_dump -- dumptruck_ds
- if (attacker.obit_name != "")
- {
- bprint (" was ");
- if !(attacker.obit_method)
- bprint ("killed");
- else
- bprint (attacker.obit_method); // e.g. ripped apart
- bprint (" by ");
- bprint (attacker.obit_name); // a bad monster
- bprint ("\n");
- return;
- }
-
- // tricks and traps
- if (attacker.classname == "explo_box" ||
- attacker.classname == "play_explosion")
- {
- bprint (" blew up\n");
- return;
- }
- if (attacker.classname == "func_laser")
- {
- bprint (" discovered that lasers are hot\n");
- return;
- }
- if ((attacker.solid == SOLID_BSP &&
- attacker != world &&
- attacker.classname != "togglewall") ||
- (inflictor.classname == "func_movewall" &&
- !(inflictor.spawnflags & MOVEWALL_TOUCH)))
- {
- bprint (" was squished\n");
- return;
- }
- if (attacker.classname == "trap_shooter" ||
- attacker.classname == "trap_spikeshooter" ||
- attacker.classname == "trap_switched_shooter")
- {
- // bprint (" was spiked\n");
- bprint (" was unlucky\n"); //changed for custom shooters --dumptruck_ds
- return;
- }
- if (attacker.classname == "ltrail_start" ||
- attacker.classname == "ltrail_relay")
- {
- bprint (" had an electrifying experience\n");
- return;
- }
- if (attacker.classname == "fireball")
- {
- bprint (" ate a lavaball\n");
- return;
- }
- if (attacker.classname == "trigger_changelevel")
- {
- bprint (" tried to leave\n");
- return;
- }
-
- // in-liquid deaths
- if (targ.deathtype == "drowning")
- {
- if (random() < 0.5)
- bprint (" sleeps with the fishes\n");
- else
- bprint (" sucks it down\n");
- return;
- }
- if (targ.deathtype == "slime")
- {
- if (random() < 0.5)
- bprint (" gulped a load of slime\n");
- else
- bprint (" can't exist on slime alone\n");
- return;
- }
- if (targ.deathtype == "lava")
- {
- if (targ.health < -15)
- {
- bprint (" burst into flames\n");
- return;
- }
- if (random() < 0.5)
- bprint (" turned into hot slag\n");
- else
- bprint (" visits the Volcano God\n");
- return;
- }
-
- // fell to their death?
- if (targ.deathtype == "falling")
- {
- bprint (" fell to his death\n");
- return;
- }
-
- // hell if I know; he's just dead!!!
- bprint (" died\n");
- }
- }
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/combat.qc

diff --git a/qc-server/combat.qc b/qc-server/combat.qc
deleted file mode 100644
index 83ca79a..0000000
--- a/qc-server/combat.qc
+++ /dev/null
@@ -1,366 +0,0 @@
-
-void() T_MissileTouch;
-void() info_player_start;
-void(entity targ, entity inflictor, entity attacker) ClientObituary;
-
-void() monster_death_use;
-
-//============================================================================
-
-/*
-============
-CanDamage
-
-Returns true if the inflictor can directly damage the target. Used for
-explosions and melee attacks.
-============
-*/
-float(entity targ, entity inflictor) CanDamage =
-{
-// bmodels need special checking because their origin is 0,0,0
- if (targ.movetype == MOVETYPE_PUSH)
- {
- traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self);
- if (trace_fraction == 1)
- return TRUE;
- if (trace_ent == targ)
- return TRUE;
- return FALSE;
- }
-
- traceline(inflictor.origin, targ.origin, TRUE, self);
- if (trace_fraction == 1)
- return TRUE;
- traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self);
- if (trace_fraction == 1)
- return TRUE;
- traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self);
- if (trace_fraction == 1)
- return TRUE;
- traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self);
- if (trace_fraction == 1)
- return TRUE;
- traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self);
- if (trace_fraction == 1)
- return TRUE;
-
- return FALSE;
-};
-
-
-/*
-============
-Killed
-============
-*/
-void(entity targ, entity inflictor, entity attacker) Killed =
-{
- local entity oself;
-
- oself = self;
- self = targ;
-
- if (self.health < -99)
- self.health = -99; // don't let sbar look bad if a player
-
- if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE)
- { // doors, triggers, etc
- self.th_die ();
- self = oself;
- return;
- }
-
- self.enemy = attacker;
-
-// bump the monster counter
- if (self.flags & FL_MONSTER)
- {
- killed_monsters = killed_monsters + 1;
- WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
- }
-
- ClientObituary (self, inflictor, attacker);
-
- self.takedamage = DAMAGE_NO;
- self.touch = SUB_Null;
-
- monster_death_use();
- self.th_die ();
-
- self = oself;
-};
-
-
-/*
-============
-T_Damage
-
-The damage is coming from inflictor, but get mad at attacker
-This should be the only function that ever reduces health.
-============
-*/
-void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
-{
- local vector dir;
- local entity oldself;
- local float save;
- local float take;
- local float ignore_armor; //johnfitz
- local string death_type; //johnfitz
-
- // don't try to damage the world. Not healthy - bmFbr
- if (!targ)
- return;
-
- //johnfitz -- make sure targ.deathtype doesn't keep stale info after this function is done
- death_type = targ.deathtype;
- targ.deathtype = "";
- //johnfitz
-
- if (!targ.takedamage)
- return;
-
- //johnfitz -- some func_breakables ignore monster damage //added from Rubicon2 combat.qc dumptruck_ds
- if (targ.classname == "func_breakable")
- {
- if (targ.spawnflags & BREAKABLE_NO_MONSTERS && attacker.flags & FL_MONSTER)
- return;
- }
- //johnfitz
-
-// used by buttons and triggers to set activator for target firing
- damage_attacker = attacker;
-
-// check for quad damage powerup on the attacker
- if (attacker.super_damage_finished > time)
- damage = damage * 4;
-
- // damage mod for monsters -- dumptruck_ds
- if (attacker.damage_mod)
- damage = damage * attacker.damage_mod;
-
- //don't deplete armor if drowning/burning, or protected by biosuit/pentagram/godmode (note: in ID1 pentagram/godmode doesn't actually protect your armor)
- if (death_type == "burning" || death_type == "drowning" || targ.invincible_finished >= time || targ.flags & FL_GODMODE)
- ignore_armor = TRUE;
- else
- ignore_armor = FALSE;
-//johnfitz
-// save damage based on the target's armor level
- if (ignore_armor) //johnfitz -- some damage doesn't deplete armor
- {
- save = 0;
- }
- else
- {
- save = ceil(targ.armortype*damage);
- if (save >= targ.armorvalue)
- {
- save = targ.armorvalue;
- targ.armortype = 0; // lost all armor
- targ.items = targ.items - (targ.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3));
- }
-}
-// // 1998-08-12 Drowning doesn't hurt armor by Maddes/Athos start
-// }
-// else
-// save = 0;
-// // 1998-08-12 Drowning doesn't hurt armor by Maddes/Athos end
- targ.armorvalue = targ.armorvalue - save;
- take = ceil(damage-save);
-
-// add to the damage total for clients, which will be sent as a single
-// message at the end of the frame
-// FIXME: remove after combining shotgun blasts?
- if (targ.flags & FL_CLIENT)
- {
- targ.dmg_take = targ.dmg_take + take;
- targ.dmg_save = targ.dmg_save + save;
- targ.dmg_inflictor = inflictor;
- }
-
-// figure momentum add
- if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
- {
- dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
- dir = normalize(dir);
- targ.velocity = targ.velocity + dir*damage*8;
- }
-
-// check for godmode or invincibility
- if (targ.flags & FL_GODMODE)
- return;
- if (targ.invincible_finished >= time)
- {
- if (self.invincible_sound < time)
- {
- sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
- self.invincible_sound = time + 2;
- }
- return;
- }
-
-// team play damage avoidance
-// 1998-07-29 Teamplay 1 fix by Maddes start
- if ( (teamplay == 1) && (targ.team > 0) && (targ.team == attacker.team)
- && (targ != attacker)
- && (attacker.classname == "player")
- && (inflictor.classname != "door") ) // because squishing a teammate is still possible
-// 1998-07-29 Teamplay 1 fix by Maddes end
- return;
-
-// do the damage
- targ.health = targ.health - take;
-
-// fire pain_target if appropriate
- if ((targ.flags & FL_MONSTER) &&
- targ.pain_target != "" &&
- targ.health <= targ.pain_threshold)
- {
- oldself = self;
- self = targ;
- monster_pain_use ();
- self = oldself;
- }
-
- if (targ.health <= 0)
- {
- Killed (targ, inflictor, attacker);
- return;
- }
-
-// react to the damage
- oldself = self;
- self = targ;
-
- if ( (self.flags & FL_MONSTER) && attacker != world)
- {
- // get mad unless of the same class (except for soldiers)
- if (self != attacker && attacker != self.enemy)
- {
- local float mode;
- mode = 0;
- // take highest mode so infighting happens consistently
- if (self.infight_mode == -1 || self.infight_mode > mode)
- {
- mode = self.infight_mode;
- }
- if (mode != -1 && attacker.infight_mode > mode)
- {
- mode = attacker.infight_mode;
- }
- //soldiers of the same style will infight -- dumptruck_ds - thanks for c0burn and Shamblernaut for your help!
- if (mode == -1)
- {
- if (attacker.classname == "player")
- {
- if (self.enemy.classname == "player")
- self.oldenemy = self.enemy;
- self.enemy = attacker;
- FoundTarget ();
- }
- }
- else if (
- (self.classname != attacker.classname) ||
- ((self.classname == "monster_army") && (self.style == attacker.style)) ||
- (mode > 0 && self.mdl_body != attacker.mdl_body) || // infight if different models
- (mode > 1 && self.skin != attacker.skin) || // infight if different skin
- (mode > 2) // always infight
- )
- {
- if (self.enemy.classname == "player")
- self.oldenemy = self.enemy;
- self.enemy = attacker;
- FoundTarget ();
- }
- }
- }
-
- if (self.th_pain)
- {
- self.th_pain (attacker, take);
- // nightmare mode monsters don't go into pain frames often
- if (skill == 3)
- self.pain_finished = time + 5;
- }
-
- self = oldself;
-};
-
-/*
-============
-T_RadiusDamage
-============
-*/
-void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =
-{
- local float points;
- local entity head;
- local vector org;
-
- head = findradius(inflictor.origin, damage+40);
-
- while (head)
- {
- if (head != ignore)
- {
- if (head.takedamage)
- {
- org = head.origin + (head.mins + head.maxs)*0.5;
- points = 0.5*vlen (inflictor.origin - org);
- if (points < 0)
- points = 0;
- points = damage - points;
- if (head == attacker)
- points = points * 0.5;
- if (points > 0)
- {
- if (CanDamage (head, inflictor))
- { // shambler takes half damage from all explosions
- if (head.classname == "monster_shambler")
- T_Damage (head, inflictor, attacker, points*0.5);
- else
- T_Damage (head, inflictor, attacker, points);
- }
- }
- }
- }
- head = head.chain;
- }
-};
-
-/*
-============
-T_BeamDamage
-============
-*/
-void(entity attacker, float damage) T_BeamDamage =
-{
- local float points;
- local entity head;
-
- head = findradius(attacker.origin, damage+40);
-
- while (head)
- {
- if (head.takedamage)
- {
- points = 0.5*vlen (attacker.origin - head.origin);
- if (points < 0)
- points = 0;
- points = damage - points;
- if (head == attacker)
- points = points * 0.5;
- if (points > 0)
- {
- if (CanDamage (head, attacker))
- {
- if (head.classname == "monster_shambler")
- T_Damage (head, attacker, attacker, points*0.5);
- else
- T_Damage (head, attacker, attacker, points);
- }
- }
- }
- head = head.chain;
- }
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/cshift.qc

diff --git a/qc-server/cshift.qc b/qc-server/cshift.qc
deleted file mode 100644
index f7410a7..0000000
--- a/qc-server/cshift.qc
+++ /dev/null
@@ -1,75 +0,0 @@
-
-inline void(entity client, float density, vector color) csf_save = {
- client.csf_color = color;
- client.csf_density = density;
-}
-
-inline void(entity client) csf_apply = {
- stuffcmd(client, "\nv_cshift ");
- stuffcmd(client, ftos(client.csf_color_x));
- stuffcmd(client, " ");
- stuffcmd(client, ftos(client.csf_color_y));
- stuffcmd(client, " ");
- stuffcmd(client, ftos(client.csf_color_z));
- stuffcmd(client, " ");
- stuffcmd(client, ftos(client.csf_density));
- stuffcmd(client, "\n");
-}
-
-void(entity client, float density, vector color) csf_set = {
- csf_save(client, density, color);
- csf_apply(client);
-}
-
-void() csfcontroller_think = {
-
- entity e = self.owner;
-
- if (self.pain_finished > time && e.csf_density != self.csf_density) {
-
- float density;
- vector color;
-
- float fraction = 1 - (self.pain_finished - time) / self.speed; //wat
-
- density = lerpHermite(e.csf_density, self.csf_density, fraction);
- color = lerpVectorHermite(e.csf_color, self.csf_color, fraction);
-
- csf_set(e, density, color);
-
- self.nextthink = time + 0.04;
- }
- else {
- csf_set(e, self.csf_density, self.csf_color);
- }
-
-}
-
-
-void(entity client) csfcontroller_start = {
- if (client.csfcontroller.classname == "csfcontroller" && client.csfcontroller.owner == client)
- return;
-
- entity e = spawn();
- client.csfcontroller = e;
- e.owner = client;
- e.classname = "csfcontroller";
- e.think = csfcontroller_think;
-}
-
-
-void(entity client, float density, vector color, float spd) csf_fade = {
- csfcontroller_start(client);
-
- entity ct = client.csfcontroller;
-
- ct.speed = spd;
- ct.pain_finished = time + spd;
- ct.csf_color = color;
- ct.csf_density = density;
- ct.nextthink = time + 0.04;
-}
-
-
-
-

Return to the top of this page or return to the overview of this repo.

Diff qc-server/csqc/csqc_defs.qc

diff --git a/qc-server/csqc/csqc_defs.qc b/qc-server/csqc/csqc_defs.qc
deleted file mode 100644
index 7172e91..0000000
--- a/qc-server/csqc/csqc_defs.qc
+++ /dev/null
@@ -1,398 +0,0 @@
-//======================================================================
-// Author : Simon "Sock" OCallaghan
-// Website: www.simonoc.com
-//
-// This is a special defs file with all the relevant CSQC references
-// Should be included into progs and csprogs to reduce duplicates
-//
-//----------------------------------------------------------------------
-// The CSQC files are setup to be self contained and easy to port
-// to other MODS, but some stuff needs to exist in other QC files
-// In world.qc the extra variables for AD are located there
-//
-//----------------------------------------------------------------------
-// Special Variables used by CSQC (Client Side Quake C)
-// The engine will keep these insync between server and client
-// Defined with the addstat/clientstat command DP/FTE
-//----------------------------------------------------------------------
-
-const float CLIENT_HEALTH = 0; // Player's health
-const float CLIENT_WEAPONMODELI = 2; // Modelidx of current viewmodel
-const float CLIENT_AMMO = 3; // player.currentammo
-const float CLIENT_ARMOR = 4;
-const float CLIENT_WEAPONFRAME = 5;
-const float CLIENT_SHELLS = 6;
-const float CLIENT_NAILS = 7;
-const float CLIENT_ROCKETS = 8;
-const float CLIENT_CELLS = 9;
-const float CLIENT_ACTIVEWEAPON = 10; // player.weapon
-const float CLIENT_TOTALSECRETS = 11;
-const float CLIENT_TOTALMONSTERS = 12;
-const float CLIENT_FOUNDSECRETS = 13;
-const float CLIENT_KILLEDMONSTERS = 14;
-// getstatbits(CLIENT_ITEMS,0,23) to read self.items
-// getstatbits(CLIENT_ITEMS,23,11) to read self.items2
-// or getstatbits(CLIENT_ITEMS,28,4) to read the visible part of serverflags
-const float CLIENT_ITEMS = 15; // self.items | (self.items2<<23)
-const float CLIENT_VIEWHEIGHT = 16; // player.view_ofs_z
-const float CLIENT_VIEW2 = 20; // Entity Qty in server's .view2 field
-const float CLIENT_VIEWZOOM = 21; // Scales fov and sensitiity
-const float CLIENT_IDEALPITCH = 25;
-const float CLIENT_PUNCHANGLE_X = 26;
-const float CLIENT_PUNCHANGLE_Y = 27;
-const float CLIENT_PUNCHANGLE_Z = 28;
-// 32-127 is custom variables (defined here and linked in world.qc)
-const float CLIENT_MODITEMS = 40; // self.moditems (AD extra stuff)
-const float CLIENT_CKEYNAME1 = 50; // self.ckeyname1
-const float CLIENT_CKEYNAME2 = 51; // self.ckeyname2
-const float CLIENT_CKEYNAME3 = 52; // self.ckeyname3
-const float CLIENT_CKEYNAME4 = 53; // self.ckeyname4
-const float CLIENT_CKEYSKIN1 = 55; // self.ckeyskin1
-const float CLIENT_CKEYSKIN2 = 56; // self.ckeyskin2
-const float CLIENT_CKEYSKIN3 = 57; // self.ckeyskin3
-const float CLIENT_CKEYSKIN4 = 58; // self.ckeyskin4
-// CEV
-const float CLIENT_VELOCITY_X = 64;
-const float CLIENT_VELOCITY_Y = 65;
-
-//----------------------------------------------------------------------
-// Duplicate of IT_ references in defs.qc
-//----------------------------------------------------------------------
-const float CSQC_SHOTGUN = 1<<0; // 1
-const float CSQC_SUPER_SHOTGUN = 1<<1; // 2
-const float CSQC_NAILGUN = 1<<2; // 4
-const float CSQC_SUPER_NAILGUN = 1<<3; // 8
-const float CSQC_GRENADE_LAUNCHER = 1<<4; // 16
-const float CSQC_ROCKET_LAUNCHER = 1<<5; // 32
-const float CSQC_LIGHTNING = 1<<6; // 64
-// const float CSQC_EXTRA_WEAPON = 1<<7; // 128
-
-const float CSQC_SHELLS = 1<<8; // 256
-const float CSQC_NAILS = 1<<9; // 512
-const float CSQC_ROCKETS = 1<<10; // 1024
-const float CSQC_CELLS = 1<<11; // 2048
-const float CSQC_AXE = 1<<12; // 4096
-
-const float CSQC_ARMOR1 = 1<<13; // 8192
-const float CSQC_ARMOR2 = 1<<14; // 16384
-const float CSQC_ARMOR3 = 1<<15; // 32768
-// const float CSQC_SUPERHEALTH = 1<<16; // 65536
-
-const float CSQC_KEY1 = 1<<17; // 131072
-const float CSQC_KEY2 = 1<<18; // 262144
-
-const float CSQC_INVISIBILITY = 1<<19; // 524288
-const float CSQC_INVULNERABILITY = 1<<20; // 1048576
-const float CSQC_SUIT = 1<<21; // 2097152
-const float CSQC_QUAD = 1<<22; // 4194304
-
-// Runes in Serverflags
-const float CSQC_RUNE1 = 1<<5; // 32
-const float CSQC_RUNE2 = 1<<6; // 64
-const float CSQC_RUNE3 = 1<<7; // 128
-const float CSQC_RUNE4 = 1<<8; // 256
-
-// Variable types
-const float EV_VOID = 0;
-const float EV_STRING = 1;
-const float EV_FLOAT = 2;
-const float EV_VECTOR = 3;
-const float EV_ENTITY = 4;
-const float EV_FIELD = 5;
-const float EV_FUNCTION = 6;
-const float EV_POINTER = 7;
-const float EV_INTEGER = 8;
-
-// ======================================================================
-// This is a merge of three (DP/FTE/QSS) engine def files
-// dpextensions+csprogsdefs from SVN ICCULUS site (DP trunk)
-// fteexentions from triptohell website
-// qsextensions from QSS devkit on triptohell website
-//
-// CSQC range #300-#399
-// ======================================================================
-
-// ----------------------------------------------------------------------
-// DP/FTE extensions ONLY
-// ----------------------------------------------------------------------
-// Forgets all rentities, polygons, and temporary dlights.
-// Resets all view properties to their default values.
-void() clearscene = #300;
-void(float mask) addentities = #301;
-// Copies the entity fields into a new rentity for
-// later rendering via addscene
-void(entity ent) addentity = #302;
-// Allows you to override default view properties like
-// viewport, fov, and whether the engine hud will be drawn.
-// Different VF_ values have slightly different arguments,
-// some are vectors, some floats.
-float(float property, ...) setproperty = #303;
-// Draws all entities, polygons, and particles on the rentity list
-// (which were added via addentities or addentity), using the various
-// view properties set via setproperty. There is no ordering dependancy.
-// The scene must generally be cleared again before more entities
-// are added, as entities will persist even over to the next frame.
-// You may call this builtin multiple times per frame, but should
-// only be called from CSQC_UpdateView.
-void() renderscene = #304;
-// Adds a temporary dlight, ready to be drawn via addscene.
-// Cubemap orientation will be read from v_forward/v_right/v_up.
-void(vector org, float radius, vector lightcolours) adddynamiclight = #305;
-void(vector org, float radius, vector lightcolours, float style, string cubemapname, float pflags) adddynamiclight2 = #305;
-// Specifies the shader to use for the following polygons, along
-// with optional flags.
-// If is2d, the polygon will be drawn as soon as the EndPolygon
-// call is made, rather than waiting for renderscene. This allows
-// complex 2d effects.
-// FTE = void(string texturename, optional float flags, optional float is2d) R_BeginPolygon = #306;
-void(string texturename, float flag, ...) R_BeginPolygon = #306;
-// Specifies a polygon vertex with its various properties
-void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex = #307;
-// Ends the current polygon. At least 3 verticies must have been
-// specified. You do not need to call beginpolygon if you wish to
-// draw another polygon with the same shader
-void() R_EndPolygon = #308;
-// Retrieve a currently-set (typically view) property, allowing you
-// to read the current viewport or other things. Due to cheat protection,
-// certain values may be unretrievable
-// define = FTE version of DP version
-#define getviewprop getproperty
-float(float property) getproperty = #309;
-vector(float property) getpropertyvec = #309;
-// Transform a 2d screen-space point (with depth) into a 3d world-space
-// point, according the various origin+angle+fov etc settings set via
-// setproperty
-vector (vector v) cs_unproject = #310;
-// Transform a 3d world-space point into a 2d screen-space point,
-// according the various origin+angle+fov etc settings set via
-// setproperty
-vector (vector v) cs_project = #311;
-// Draws a 2d line between the two 2d points
-void(float width, vector pos1, vector pos2, vector rgb, float alpha, float flag) drawline = #315;
-// Tells the engine that the image is no longer needed.
-// The image will appear to be new the next time its needed
-void(string name) freepic = #319;
-// Draws the specified string without using any markup at all,
-// even in engines that support it.
-// If UTF-8 is globally enabled in the engine, then that encoding
-// is used (without additional markup), otherwise it is raw quake chars.
-// Software engines may assume a size of '8 8 0', rgb='1 1 1',
-// alpha=1, flag&3=0, but it is not an error to draw out of the screen.
-float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring = #321;
-// Retrieves the value of the given EV_STRING stat, as a tempstring.
-// Older engines may use 4 consecutive integer stats, with a limit
-// of 15 chars (yes, really. 15.), but FTE Quake uses a separate
-// namespace for string stats and has a much higher length limit.
-string(float stnum) getstats = #332;
-// Retrieves the name of the model based upon a precache index.
-// This can be used to reduce csqc network traffic by enabling
-// model matching
-string(float mdlindex) modelnameforindex = #334;
-// Looks up a named font slot. Matches the actual font name as a last resort.
-// find font by fontname and return it's index
-float findfont(string s) = #356;
-float loadfont(string fontname, string fontmaps, string sizes, float slot, float fix_scale, float fix_voffset) = #357;
-
-// ----------------------------------------------------------------------
-// QSS (CSQC Lit) + DP/FTE extensions
-// ----------------------------------------------------------------------
-// Checks to see if the image is currently loaded.
-// Engines might lie, or cache between maps.
-float(string name) iscachedpic = #316;
-// Forces the engine to load the named image. If trywad is specified,
-// the specified name must any lack path and extension.
-string(string name, optional float trywad) precache_pic = #317;
-// Returns the dimensions of the named image. Images specified
-// with .lmp should give the original .lmp's dimensions even if
-// texture replacements use a different resolution.
-// define = FTE version of DP version
-#define drawgetimagesize draw_getimagesize
-vector(string picname) draw_getimagesize = #318;
-// Draw the given quake character at the given position.
-// If flag&4, the function will consider the char to be a unicode
-// char instead (or display as a ? if outside the 32-127 range).
-// size should normally be something like '8 8 0'.
-// rgb should normally be '1 1 1' and alpha normally 1.
-// Software engines may assume the named defaults.
-// Note that ALL text may be rescaled on the X axis due to
-// variable width fonts. The X axis may even be ignored completely.
-float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter = #320;
-// Draws an shader within the given 2d screen box. Software engines
-// may omit support for rgb+alpha, but must support rescaling,
-// and must clip to the screen without crashing
-// flag = draw method; 0=normal, 1=additive, 2=modulate, 3=modulate2
-float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic = #322;
-// Draws a solid block over the given 2d box, with given colour,
-// alpha, and blend mode (specified via flags).
-// flags&3=0 simple blend flags&3=1 additive blend
-float(vector position, vector size, vector rgb, float alpha, float flag) drawfill = #323;
-// Specifies a 2d clipping region (aka: scissor test).
-// 2d draw calls will all be clipped to this 2d box,
-// the area outside will not be modified by any
-// 2d draw call (even 2d polygons).
-void(float x, float y, float width, float height) drawsetcliparea = #324;
-// Reverts the scissor/clip area to the whole screen
-void(void) drawresetcliparea = #325;
-// Draws a string, interpreting markup and recolouring as appropriate
-// QSS/FTE = drawstring, DP = drawcolorcodedstring/drawcolorcodedstring2
-// float(vector position, string text, vector size, vector rgb, float alpha, float drawflag) drawstring = #326;
-float(vector position, string text, vector scale, float alpha, float flag) drawcolorcodedstring = #326;
-vector(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawcolorcodedstring2 = #326;
-// Calculates the width of the screen in virtual pixels.
-// If usecolours is 1, markup that does not affect the string
-// width will be ignored. Will always be decoded as UTF-8 if
-// UTF-8 is globally enabled.
-// If the char size is not specified, '8 8 0' will be assumed
-// float(string text, float usecolours, optional vector fontsize) stringwidth = #327;
-// QSS/FTE = float(string text, float usecolours, optional vector fontsize) stringwidth = #327;
-float(string text, float allowColorCodes, vector size) stringwidth = #327;
-// Draws a rescaled subsection of an image to the screen
-// QSS/FTE = void(vector pos, vector sz, string pic, vector srcpos, vector srcsz, vector rgb, float alpha, optional float drawflag) drawsubpic = #328;
-float(vector position, vector size, string pic, vector srcPosition, vector srcSize, vector rgb, float alpha, float flag) drawsubpic = #328;
-// Nasty convoluted DP extension. Typically returns deltas instead
-// of positions. Use CSQC_InputEvent for such things in csqc mods
-vector() getmousepos = #344;
-// Looks up an input frame from the log, setting the input_*
-// globals accordingly.
-// The sequence number range used for prediction should normally
-// be servercommandframe < sequence <= clientcommandframe.
-// The sequence equal to clientcommandframe will change between
-// input frames
-float(float framenum) getinputstate = #345;
-// Perform the engine's standard player movement prediction upon
-// the given entity using the input_* globals to describe movement
-// this may or may not take a player ent
-void(...) runstandardplayerphysics = #347;
-// Sets the position of the view, as far as the audio subsystem is
-// concerned. This should be called once per CSQC_UpdateView as it
-// will otherwise revert to default. For reverbtype,
-// see setup_reverb or treat as 'underwater'
-// FTE = void(vector origin, vector forward, vector right, vector up, optional float reverbtype) SetListener = #351;
-void(vector origin, vector forward, vector right, vector up) SetListener = #351;
-
-// ----------------------------------------------------------------------
-// This is a bit of mess with DP (below) and FTE/QSS (further below)
-// Going in different directions with the CSQC standard
-// This is all about #330 returning an INT instead of a FLOAT
-// As getstatf has optional parameters it will still work fine with DP
-// Going with the FTE/QSS direction as it still works for DP
-// ----------------------------------------------------------------------
-//float(float stnum) getstatf = #330;
-// Can optionally take first bit and count
-//float(float stnum, ...) getstati = #331;
-
-// Retrieves the numerical value of the given EV_INTEGER or EV_ENTITY stat.
-// Use getstati_punf if you wish to type-pun a float stat as an int to
-// avoid truncation issues in DP
-#define getstati_punf(stnum) (float)(__variant)getstati(stnum)
-int(float stnum) getstati = #330;
-#define getstatbits getstatf
-float(float stnum, optional float firstbit, optional float bitcount) getstatf = #331;
-
-// ----------------------------------------------------------------------
-// QSS (CSQC Lit) + DP/FTE extensions
-// ----------------------------------------------------------------------
-// Sets a model by precache index instead of by name.
-// Otherwise identical to setmodel.
-void(entity e, float mdlindex) setmodelindex = #333;
-// Part of DP_ENT_TRAILEFFECTNUM, FTE_SV_POINTPARTICLES
-// Precaches the named particle effect. If your effect name is of
-// the form 'foo.bar' then particles/foo.cfg will be loaded by the
-// client if foo.bar was not already defined.
-// Different engines will have different particle systems, this
-// specifies the QC API only
-float(string effectname) particleeffectnum = #335;
-// Part of FTE_SV_POINTPARTICLES
-// Draws the given effect between the two named points. If ent is
-// not world, distances will be cached in the entity in order to
-// avoid framerate dependancies. The entity is not otherwise used
-void(float effectnum, entity ent, vector start, vector end) trailparticles = #336;
-// Part of FTE_SV_POINTPARTICLES
-// Spawn a load of particles from the given effect at the given
-// point traveling or aiming along the direction specified.
-// The number of particles are scaled by the count argument.
-// For regular particles, the dir vector is multiplied by the
-// 'veladd' property (while orgadd will push the particles along it).
-// Decals will use it as a hint to align to the correct surface.
-// In both cases, it should normally be a unit vector, but other
-// lengths will still work. If it has length 0 then FTE will
-// assume downwards
-void(float effectnum, vector origin, optional vector dir, optional float count) pointparticles = #337;
-
-// conflicts with void(entity client, string s1) centerprint = #73;
-void(string s, ...) csqc_centerprint = #338;
-// Print into the center of the screen just as ssqc's centerprint
-// would appear
-void(string s, ...) cprint = #338;
-// This is identical to dprint except that it always prints
-// regardless of the developer cvar. Same number as in EXT_CSQC
-// Unconditionally print on the local system's console, even in
-// ssqc (doesn't care about the value of the developer cvar)
-void(string s, ...) print = #339;
-// Returns a hunam-readable name for the given keycode, as a tempstring
-string(float keynum) keynumtostring = #340;
-// Looks up the key name in the same way that the bind command would,
-// returning the keycode for that key
-float(string keyname) stringtokeynum = #341;
-// Returns the current binding for the given key (returning only the
-// command executed when no modifiers are pressed)
-string(float key, float bindmap) getkeybind_bindmap = #342;
-string(float keynum) getkeybind = #342;
-// Pass TRUE if you want the engine to release the mouse cursor
-// (absolute input events + touchscreen mode). Pass FALSE if you
-// want the engine to grab the cursor (relative input
-// events + standard looking). If the image name is specified,
-// the engine will use that image for a cursor (use an empty
-// string to clear it again), in a way that will not conflict
-// with the console. Images specified this way will be hardware
-// accelerated, if supported by the platform/port
-// QSS/FTE = void(float usecursor, optional string cursorimage, optional vector hotspot, optional float scale) setcursormode = #343;
-void(float usecursor) setcursormode = #343;
-// Reports the cursor mode this module previously attempted to use.
-// If 'effective' is true, reports the cursor mode currently active
-// (if was overriden by a different module which has precidence,
-// for instance, or if there is only a touchscreen and no mouse)
-float(float effective) getcursormode = #0;
-// Temporarily scales the player's mouse sensitivity based upon
-// something like zoom, avoiding potential cvar saving and thus
-// corruption
-void(float sens) setsensitivityscale = #346;
-// Look up a player's userinfo, to discover things like their name,
-// topcolor, bottomcolor, skin, team, *ver.
-// Also includes scoreboard info like frags, ping, pl, userid,
-// entertime, as well as voipspeaking and voiploudness
-string(float playernum, string keyname) getplayerkeyvalue = #348;
-// Cheaper version of getplayerkeyvalue that avoids the need for
-// so many tempstrings
-float(float playernum, string keyname, optional float assumevalue) getplayerkeyfloat = #0;
-// Returns if the client is currently playing a demo or not
-float() isdemo = #349;
-// Returns if the client is acting as the server (aka: listen server)
-float() isserver = #350;
-// Register the given console command, for easy console use.
-// Console commands that are later used will invoke CSQC_ConsoleCommand
-void(string cmdname) registercommand = #352;
-// Quickly check to see if the entity is currently free. This
-// function is only valid during the two-second non-reuse window,
-// after that it may give bad results. Try one second to make it
-// more robust.
-float(entity ent) wasfreed = #353;
-// Look up a key in the server's public serverinfo string
-string(string key) serverkey = #354;
-// Version of serverkey that returns the value as a float
-// (which avoids tempstrings)
-float(string key, optional float assumevalue) serverkeyfloat = #0;
-// Use proper case; refer to the id1 Write* functions!
-float() ReadByte = #360;
-float() ReadChar = #361;
-float() ReadShort = #362;
-float() ReadLong = #363;
-float() ReadCoord = #364;
-float() ReadAngle = #365;
-string() ReadString = #366;
-float() ReadFloat = #367;
-float() readentitynum = #368;
-// Replaces the title of the game window, as seen when
-// task switching or just running in windowed mode
-void(string newcaption) setwindowcaption = #0;
-

Return to the top of this page or return to the overview of this repo.

Diff qc-server/csqc/csqc_defsclient.qc

diff --git a/qc-server/csqc/csqc_defsclient.qc b/qc-server/csqc/csqc_defsclient.qc
deleted file mode 100644
index 23e7f4b..0000000
--- a/qc-server/csqc/csqc_defsclient.qc
+++ /dev/null
@@ -1,759 +0,0 @@
-//======================================================================
-// Author : Simon "Sock" OCallaghan
-// Website: www.simonoc.com
-//
-// Based on the qsextensions.qc file in the QSS devkit
-// This is a special defs file for csprogs.dat ONLY
-// Requires csqc_defs.qc file for 300-399 range commands
-//
-//======================================================================
-// Some extra defs (csqc/csqc_simple)
-#ifndef CSQC
-#define CSQC
-#endif
-#ifndef CSQC_SIMPLE
-#define CSQC_SIMPLE
-#endif
-// Suppress reference errors
-#pragma noref 1
-
-//----------------------------------------------------------------------
-// Mostly stuff from GLOBALVARS_T C STRUCTURE
-//----------------------------------------------------------------------
-entity self,other,world;
-float time,frametime,force_retouch;
-string mapname;
-float deathmatch,coop,teamplay,serverflags,total_secrets,total_monsters,found_secrets,killed_monsters,parm1, parm2, parm3, parm4, parm5, parm6, parm7, parm8, parm9, parm10, parm11, parm12, parm13, parm14, parm15, parm16;
-vector v_forward, v_up, v_right;
-float trace_allsolid,trace_startsolid,trace_fraction;
-vector trace_endpos,trace_plane_normal;
-float trace_plane_dist;
-entity trace_ent;
-float trace_inopen,trace_inwater;
-entity msg_entity;
-void() main,StartFrame,PlayerPreThink,PlayerPostThink,ClientKill,ClientConnect,PutClientInServer,ClientDisconnect,SetNewParms,SetChangeParms;
-void end_sys_globals;
-.float modelindex;
-.vector absmin, absmax;
-.float ltime,movetype,solid;
-.vector origin,oldorigin,velocity,angles,avelocity,punchangle;
-.string classname,model;
-.float frame,skin,effects;
-.vector mins, maxs,size;
-.void() touch,use,think,blocked;
-.float nextthink;
-.entity groundentity;
-.float health,frags,weapon;
-.string weaponmodel;
-.float weaponframe,currentammo,ammo_shells,ammo_nails,ammo_rockets,ammo_cells,items,takedamage;
-.entity chain;
-.float deadflag;
-.vector view_ofs;
-.float button0,button1,button2,impulse,fixangle;
-.vector v_angle;
-.float idealpitch;
-.string netname;
-.entity enemy;
-.float flags,colormap,team,max_health,teleport_time,armortype,armorvalue,waterlevel,watertype,ideal_yaw,yaw_speed;
-.entity aiment,goalentity;
-.float spawnflags;
-.string target,targetname;
-.float dmg_take,dmg_save;
-.entity dmg_inflictor,owner;
-.vector movedir;
-.string message;
-.float sounds;
-.string noise, noise1, noise2, noise3;
-void end_sys_fields;
-
-// Custom types redefined as accessors
-#ifdef _ACCESSORS
-accessor strbuf:float;
-accessor searchhandle:float;
-accessor hashtable:float;
-accessor infostring:string;
-accessor filestream:float;
-#else
-#define strbuf float
-#define searchhandle float
-#define hashtable float
-#define infostring string
-#define filestream float
-#endif
-
-void(string cmd) SV_ParseClientCommand;
-void() EndFrame;
-
-// Core CSQC functions called by engine
-void(float apilevel, string enginename, float engineversion) CSQC_Init;
-void(vector virtsize, float showscores) CSQC_DrawHud;
-void(vector virtsize, float showscores) CSQC_DrawScores;
-float(float evtype, float scanx, float chary, float devid) CSQC_InputEvent;
-float(float save, float take, vector dir) CSQC_Parse_Damage;
-float(string cmdstr) CSQC_ConsoleCommand;
-void() CSQC_Parse_Event;
-
-float player_localnum; // Player slot that is assigned to us
-
-const float FALSE = 0;
-const float TRUE = 1;
-const float IE_KEYDOWN = 0;
-const float IE_KEYUP = 1;
-const float IE_MOUSEDELTA = 2;
-const float IE_MOUSEABS = 3;
-const float IE_JOYAXIS = 6;
-
-//----------------------------------------------------------------------
-// Extra fields
-//----------------------------------------------------------------------
-.float gravity;
-//.float items2; /*if defined, overrides serverflags for displaying runes on the hud*/
-.float traileffectnum; /*can also be set with 'traileffect' from a map editor*/
-.float emiteffectnum; /*can also be set with 'traileffect' from a map editor*/
-.vector movement; /*describes which forward/right/up keys the player is holidng*/
-.entity viewmodelforclient; /*attaches this entity to the specified player's view. invisible to other players*/
-.float scale; /*rescales the etntiy*/
-.float alpha; /*entity opacity*/
-.vector colormod; /*tints the entity's colours*/
-.entity tag_entity;
-.float tag_index;
-.float button3;
-.float button4;
-.float button5;
-.float button6;
-.float button7;
-.float button8;
-.float viewzoom; /*rescales the user's fov*/
-.float modelflags; /*provides additional modelflags to use (effects&EF_NOMODELFLAGS to replace the original model's)*/
-
-//----------------------------------------------------------------------
-// Supported Extension Constants
-//----------------------------------------------------------------------
-const float MOVETYPE_FOLLOW = 12;
-const float SOLID_CORPSE = 5;
-const float CLIENTTYPE_DISCONNECT = 0;
-const float CLIENTTYPE_REAL = 1;
-const float CLIENTTYPE_BOT = 2;
-const float CLIENTTYPE_NOTCLIENT = 3;
-const float EF_NOSHADOW = 0x1000;
-const float EF_NOMODELFLAGS = 0x800000; /*the standard modelflags from the model are ignored*/
-const float MF_ROCKET = 0x1;
-const float MF_GRENADE = 0x2;
-const float MF_GIB = 0x4;
-const float MF_ROTATE = 0x8;
-const float MF_TRACER = 0x10;
-const float MF_ZOMGIB = 0x20;
-const float MF_TRACER2 = 0x40;
-const float MF_TRACER3 = 0x80;
-const float MSG_MULTICAST = 4;
-const float MULTICAST_ALL = 0;
-const float MULTICAST_PVS = 2;
-const float MULTICAST_ONE = 6;
-const float MULTICAST_ALL_R = 3;
-const float MULTICAST_PVS_R = 5;
-const float MULTICAST_ONE_R = 7;
-const float MULTICAST_INIT = 8;
-const float FILE_READ = 0;
-const float FILE_APPEND = 1;
-const float FILE_WRITE = 2;
-
-//----------------------------------------------------------------------
-// Vanilla Builtin list (reduced, so as to avoid conflicts)
-//----------------------------------------------------------------------
-void(vector) makevectors = #1;
-void(entity,vector) setorigin = #2;
-void(entity,string) setmodel = #3;
-void(entity,vector,vector) setsize = #4;
-float() random = #7;
-vector(vector) normalize = #9;
-void(string e) error = #10;
-void(string n) objerror = #11;
-float(vector) vlen = #12;
-entity() spawn = #14;
-void(entity e) remove = #15;
-void(string,...) dprint = #25;
-string(float) ftos = #26;
-string(vector) vtos = #27;
-float(float n) rint = #36;
-float(float n) floor = #37;
-float(float n) ceil = #38;
-float(float n) fabs = #43;
-float(string) cvar = #45;
-void(string,...) localcmd = #46;
-entity(entity) nextent = #47;
-void(string var, string val) cvar_set = #72;
-
-//----------------------------------------------------------------------
-// Builtin list
-//----------------------------------------------------------------------
-vector(vector fwd, optional vector up) vectoangles2 = #51; /*
- Returns the angles (+x=UP) required to orient an entity to look in the given direction. The 'up' argument is required if you wish to set a roll angle, otherwise it will be limited to just monster-style turning. */
-
-float(float angle) sin = #60;
-float(float angle) cos = #61;
-float(float value) sqrt = #62;
-void(entity ent, entity ignore) tracetoss = #64;
-string(entity ent) etos = #65;
-string(entity e, string key) infokey = #80; /*
- If e is world, returns the field 'key' from either the serverinfo or the localinfo. If e is a player, returns the value of 'key' from the player's userinfo string. There are a few special exceptions, like 'ip' which is not technically part of the userinfo. */
-
-float(entity e, string key) infokeyf = #0; /*
- Identical to regular infokey, but returns it as a float instead of creating new tempstrings. */
-
-float(string) stof = #81;
-#define unicast(pl,reli) do{msg_entity = pl; multicast('0 0 0', reli?MULITCAST_ONE_R:MULTICAST_ONE);}while(0)
-void(vector where, float set) multicast = #82; /*
- Once the MSG_MULTICAST network message buffer has been filled with data, this builtin is used to dispatch it to the given target, filtering by pvs for reduced network bandwidth. */
-
-void(vector start, vector mins, vector maxs, vector end, float nomonsters, entity ent) tracebox = #90; /*
- Exactly like traceline, but a box instead of a uselessly thin point. Acceptable sizes are limited by bsp format, q1bsp has strict acceptable size values. */
-
-vector() randomvec = #91; /*
- Returns a vector with random values. Each axis is independantly a value between -1 and 1 inclusive. */
-
-vector(vector org) getlight = #92;
-float(string cvarname, string defaultvalue) registercvar = #93; /*
- Creates a new cvar on the fly. If it does not already exist, it will be given the specified value. If it does exist, this is a no-op.
- This builtin has the limitation that it does not apply to configs or commandlines. Such configs will need to use the set or seta command causing this builtin to be a noop.
- In engines that support it, you will generally find the autocvar feature easier and more efficient to use. */
-
-float(float a, float b, ...) min = #94; /*
- Returns the lowest value of its arguments. */
-
-float(float a, float b, ...) max = #95; /*
- Returns the highest value of its arguments. */
-
-float(float minimum, float val, float maximum) bound = #96; /*
- Returns val, unless minimum is higher, or maximum is less. */
-
-float(float value, float exp) pow = #97;
-#define findentity findfloat
-entity(entity start, .__variant fld, __variant match) findfloat = #98; /*
- Equivelent to the find builtin, but instead of comparing strings contents, this builtin compares the raw values. This builtin requires multiple calls in order to scan all entities - set start to the previous call's return value.
- world is returned when there are no more entities. */
-
-float(string extname) checkextension = #99; /*
- Checks for an extension by its name (eg: checkextension("FRIK_FILE") says that its okay to go ahead and use strcat).
- Use cvar("pr_checkextension") to see if this builtin exists. */
-
-float(__variant funcref) checkbuiltin = #0; /*
- Checks to see if the specified builtin is supported/mapped. This is intended as a way to check for #0 functions, allowing for simple single-builtin functions. */
-
-//----------------------------------------------------------------------
-// 100-199 Range
-//----------------------------------------------------------------------
-float(string builtinname) builtin_find = #100; /*
- Looks to see if the named builtin is valid, and returns the builtin number it exists at. */
-
-float(float value) anglemod = #102;
-filestream(string filename, float mode, optional float mmapminsize) fopen = #110; /*
- Opens a file, typically prefixed with "data/", for either read or write access. */
-
-void(filestream fhandle) fclose = #111;
-string(filestream fhandle) fgets = #112; /*
- Reads a single line out of the file. The new line character is not returned as part of the string. Returns the null string on EOF (use if not(string) to easily test for this, which distinguishes it from the empty string which is returned if the line being read is blank */
-
-void(filestream fhandle, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7) fputs = #113; /*
- Writes the given string(s) into the file. For compatibility with fgets, you should ensure that the string is terminated with a \n - this will not otherwise be done for you. It is up to the engine whether dos or unix line endings are actually written. */
-
-#define ftell fseek //c-compat
-int(filestream fhandle, optional int newoffset) fseek = #0; /*
- Changes the current position of the file, if specified. Returns prior position, in bytes. */
-
-float(string s) strlen = #114;
-string(string s1, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7, optional string s8) strcat = #115;
-string(string s, float start, float length) substring = #116;
-vector(string s) stov = #117;
-string(string s, ...) strzone = #118; /*
- Create a semi-permanent copy of a string that only becomes invalid once strunzone is called on the string (instead of when the engine assumes your string has left scope). */
-
-void(string s) strunzone = #119; /*
- Destroys a string that was allocated by strunzone. Further references to the string MAY crash the game. */
-
-//----------------------------------------------------------------------
-// 200-299 FTE Range
-//----------------------------------------------------------------------
-float(float number, float quantity) bitshift = #218;
-void(vector org) te_lightningblood = #219;
-float(string s1, string sub, optional float startidx) strstrofs = #221; /*
- Returns the 0-based offset of sub within the s1 string, or -1 if sub is not in s1.
- If startidx is set, this builtin will ignore matches before that 0-based offset. */
-
-float(string str, float index) str2chr = #222; /*
- Retrieves the character value at offset 'index'. */
-
-string(float chr, ...) chr2str = #223; /*
- The input floats are considered character values, and are concatenated. */
-
-string(float ccase, float redalpha, float redchars, string str, ...) strconv = #224; /*
- Converts quake chars in the input string amongst different representations.
- ccase specifies the new case for letters.
- 0: not changed.
- 1: forced to lower case.
- 2: forced to upper case.
- redalpha and redchars switch between colour ranges.
- 0: no change.
- 1: Forced white.
- 2: Forced red.
- 3: Forced gold(low) (numbers only).
- 4: Forced gold (high) (numbers only).
- 5+6: Forced to white and red alternately.
- You should not use this builtin in combination with UTF-8. */
-
-string(float pad, string str1, ...) strpad = #225; /*
- Pads the string with spaces, to ensure its a specific length (so long as a fixed-width font is used, anyway). If pad is negative, the spaces are added on the left. If positive the padding is on the right. */
-
-string(infostring old, string key, string value) infoadd = #226; /*
- Returns a new tempstring infostring with the named value changed (or added if it was previously unspecified). Key and value may not contain the \ character. */
-
-string(infostring info, string key) infoget = #227; /*
- Reads a named value from an infostring. The returned value is a tempstring */
-
-#define strcmp strncmp
-float(string s1, string s2, optional float len, optional float s1ofs, optional float s2ofs) strncmp = #228; /*
- Compares up to 'len' chars in the two strings. s1ofs allows you to treat s2 as a substring to compare against, or should be 0.
- Returns 0 if the two strings are equal, a negative value if s1 appears numerically lower, and positive if s1 appears numerically higher. */
-
-float(string s1, string s2) strcasecmp = #229; /*
- Compares the two strings without case sensitivity.
- Returns 0 if they are equal. The sign of the return value may be significant, but should not be depended upon. */
-
-float(string s1, string s2, float len, optional float s1ofs, optional float s2ofs) strncasecmp = #230; /*
- Compares up to 'len' chars in the two strings without case sensitivity. s1ofs allows you to treat s2 as a substring to compare against, or should be 0.
- Returns 0 if they are equal. The sign of the return value may be significant, but should not be depended upon. */
-
-string(string s) strtrim = #0; /*
- Trims the whitespace from the start+end of the string. */
-
-void(float num, float type, .__variant fld) clientstat = #232; /*
- Specifies what data to use in order to send various stats, in a client-specific way.
- 'num' should be a value between 32 and 127, other values are reserved.
- 'type' must be set to one of the EV_* constants, one of EV_FLOAT, EV_STRING, EV_INTEGER, EV_ENTITY.
- fld must be a reference to the field used, each player will be sent only their own copy of these fields. */
-
-void(float num, float type, string name) globalstat = #233; /*
- Specifies what data to use in order to send various stats, in a non-client-specific way. num and type are as in clientstat, name however, is the name of the global to read in the form of a string (pass "foo"). */
-
-void(float num, float type, __variant *address) pointerstat = #0; /*
- Specifies what data to use in order to send various stats, in a non-client-specific way. num and type are as in clientstat, address however, is the address of the variable you would like to use (pass &foo). */
-
-float(entity player) isbackbuffered = #234; /*
- Returns if the given player's network buffer will take multiple network frames in order to clear. If this builtin returns non-zero, you should delay or reduce the amount of reliable (and also unreliable) data that you are sending to that client. */
-
-void(vector org, float count) te_bloodqw = #239;
-float(float a, float n) mod = #245;
-int(string) stoi = #259; /*
- Converts the given string into a true integer. Base 8, 10, or 16 is determined based upon the format of the string. */
-
-string(int) itos = #260; /*
- Converts the passed true integer into a base10 string. */
-
-int(string) stoh = #261; /*
- Reads a base-16 string (with or without 0x prefix) as an integer. Bugs out if given a base 8 or base 10 string. :P */
-
-string(int) htos = #262; /*
- Formats an integer as a base16 string, with leading 0s and no prefix. Always returns 8 characters. */
-
-int(float) ftoi = #0; /*
- Converts the given float into a true integer without depending on extended qcvm instructions. */
-
-float(int) itof = #0; /*
- Converts the given true integer into a float without depending on extended qcvm instructions. */
-
-#ifndef dotproduct
-#define dotproduct(v1,v2) ((vector)(v1)*(vector)(v2))
-#endif
-vector(vector v1, vector v2) crossproduct = #0; /*
- Small helper function to calculate the crossproduct of two vectors. */
-
-float(float modidx, string framename) frameforname = #276; /*
- Looks up a framegroup from a model by name, avoiding the need for hardcoding. Returns -1 on error. */
-
-float(float modidx, float framenum) frameduration = #277; /*
- Retrieves the duration (in seconds) of the specified framegroup. */
-
-void(float buf, float fl) WriteFloat = #280;
-string(float modidx, float framenum) frametoname = #284;
-float(string name) checkcommand = #294; /*
- Checks to see if the supplied name is a valid command, cvar, or alias. Returns 0 if it does not exist. */
-
-// ----------------------------------------------------------------------
-// 300-399 Range - Moved to CSQC DEFS file
-// ----------------------------------------------------------------------
-
-//----------------------------------------------------------------------
-// 400-499 DP Range
-//----------------------------------------------------------------------
-entity(entity from, optional entity to) copyentity = #400; /*
- Copies all fields from one entity to another. */
-
-void(entity ent, float colours) setcolors = #401; /*
- Changes a player's colours. The bits 0-3 are the lower/trouser colour, bits 4-7 are the upper/shirt colours. */
-
-entity(.string field, string match) findchain = #402;
-entity(.float fld, float match) findchainfloat = #403;
-void(vector org, vector dir, float count) te_blood = #405;
-void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain = #409;
-void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow = #410;
-void(vector org, optional float count) te_gunshot = #418;
-void(vector org) te_spike = #419;
-void(vector org) te_superspike = #420;
-void(vector org) te_explosion = #421;
-void(vector org) te_tarexplosion = #422;
-void(vector org) te_wizspike = #423;
-void(vector org) te_knightspike = #424;
-void(vector org) te_lavasplash = #425;
-void(vector org) te_teleport = #426;
-void(vector org, float color, float colorlength) te_explosion2 = #427;
-void(entity own, vector start, vector end) te_lightning1 = #428;
-void(entity own, vector start, vector end) te_lightning2 = #429;
-void(entity own, vector start, vector end) te_lightning3 = #430;
-void(entity own, vector start, vector end) te_beam = #431;
-void(vector dir) vectorvectors = #432;
-float(entity e, float s) getsurfacenumpoints = #434;
-vector(entity e, float s, float n) getsurfacepoint = #435;
-vector(entity e, float s) getsurfacenormal = #436;
-string(entity e, float s) getsurfacetexture = #437;
-float(entity e, vector p) getsurfacenearpoint = #438;
-vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
-void(entity e, string s) clientcommand = #440;
-float(string s) tokenize = #441;
-string(float n) argv = #442;
-float() argc = #0;
-void(entity e, entity tagentity, string tagname) setattachment = #443; /* */
-
-searchhandle(string pattern, optional float caseinsensitive, optional float quiet) search_begin = #444; /*
- initiate a filesystem scan based upon filenames. Be sure to call search_end on the returned handle. */
-
-void(searchhandle handle) search_end = #445; /* */
-
-float(searchhandle handle) search_getsize = #446; /*
- Retrieves the number of files that were found. */
-
-string(searchhandle handle, float num) search_getfilename = #447; /*
- Retrieves name of one of the files that was found by the initial search. */
-
-float(searchhandle handle, float num) search_getfilesize = #0; /*
- Retrieves the size of one of the files that was found by the initial search. */
-
-string(searchhandle handle, float num) search_getfilemtime = #0; /*
- Retrieves modification time of one of the files in %Y-%m-%d %H:%M:%S format. */
-
-string(string cvarname) cvar_string = #448;
-entity(entity start, .float fld, float match) findflags = #449;
-entity(.float fld, float match) findchainflags = #450;
-void(entity player) dropclient = #453;
-entity() spawnclient = #454; /*
- Spawns a dummy player entity.
- Note that such dummy players will be carried from one map to the next.
- Warning: DP_SV_CLIENTCOLORS DP_SV_CLIENTNAME are not implemented in quakespasm, so use KRIMZON_SV_PARSECLIENTCOMMAND's clientcommand builtin to change the bot's name/colours/skin/team/etc, in the same way that clients would ask. */
-
-float(entity client) clienttype = #455;
-void(float target, string str) WriteUnterminatedString = #456;
-entity(float entnum) edict_num = #459;
-strbuf() buf_create = #460;
-void(strbuf bufhandle) buf_del = #461;
-float(strbuf bufhandle) buf_getsize = #462;
-void(strbuf bufhandle_from, strbuf bufhandle_to) buf_copy = #463;
-void(strbuf bufhandle, float sortprefixlen, float backward) buf_sort = #464;
-string(strbuf bufhandle, string glue) buf_implode = #465;
-string(strbuf bufhandle, float string_index) bufstr_get = #466;
-void(strbuf bufhandle, float string_index, string str) bufstr_set = #467;
-float(strbuf bufhandle, string str, float order) bufstr_add = #468;
-void(strbuf bufhandle, float string_index) bufstr_free = #469;
-float(float s) asin = #471;
-float(float c) acos = #472;
-float(float t) atan = #473;
-float(float c, float s) atan2 = #474;
-float(float a) tan = #475;
-float(string s) strlennocol = #476; /*
- Returns the number of characters in the string after any colour codes or other markup has been parsed. */
-
-string(string s) strdecolorize = #477; /*
- Flattens any markup/colours, removing them from the string. */
-
-string(float uselocaltime, string format, ...) strftime = #478;
-float(string s, string separator1, ...) tokenizebyseparator = #479;
-string(string s) strtolower = #480;
-string(string s) strtoupper = #481;
-string(string s) cvar_defstring = #482;
-void(vector origin, string sample, float volume, float attenuation) pointsound = #483;
-string(string search, string replace, string subject) strreplace = #484;
-string(string search, string replace, string subject) strireplace = #485;
-vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
-float(float caseinsensitive, string s, ...) crc16 = #494;
-float(string name) cvar_type = #495;
-float() numentityfields = #496; /*
- Gives the number of named entity fields. Note that this is not the size of an entity, but rather just the number of unique names (ie: vectors use 4 names rather than 3). */
-
-float(string fieldname) findentityfield = #0; /*
- Find a field index by name. */
-
-typedef .__variant field_t;
-field_t(float fieldnum) entityfieldref = #0; /*
- Returns a field value that can be directly used to read entity fields. Be sure to validate the type with entityfieldtype before using. */
-
-string(float fieldnum) entityfieldname = #497; /*
- Retrieves the name of the given entity field. */
-
-float(float fieldnum) entityfieldtype = #498; /*
- Provides information about the type of the field specified by the field num. Returns one of the EV_ values. */
-
-string(float fieldnum, entity ent) getentityfieldstring = #499;
-
-//----------------------------------------------------------------------
-// 500-599 Range
-//----------------------------------------------------------------------
-float(float fieldnum, entity ent, string s) putentityfieldstring = #500;
-string(string filename, optional float makereferenced) whichpack = #503; /*
- Returns the pak file name that contains the file specified. progs/player.mdl will generally return something like 'pak0.pak'. If makereferenced is true, clients will automatically be told that the returned package should be pre-downloaded and used, even if allow_download_refpackages is not set. */
-
-string(string in) uri_escape = #510;
-string(string in) uri_unescape = #511;
-float(entity ent) num_for_edict = #512;
-float(string str) tokenize_console = #514; /*
- Tokenize a string exactly as the console's tokenizer would do so. The regular tokenize builtin became bastardized for convienient string parsing, which resulted in a large disparity that can be exploited to bypass checks implemented in a naive SV_ParseClientCommand function, therefore you can use this builtin to make sure it exactly matches. */
-
-float(float idx) argv_start_index = #515; /*
- Returns the character index that the tokenized arg started at. */
-
-float(float idx) argv_end_index = #516; /*
- Returns the character index that the tokenized arg stopped at. */
-
-string(string cvarname) cvar_description = #518; /*
- Retrieves the description of a cvar, which might be useful for tooltips or help files. This may still not be useful. */
-
-float(optional float timetype) gettime = #519;
-string(string command, optional float bindmap) findkeysforcommand = #521; /*
- Returns a list of keycodes that perform the given console command in a format that can only be parsed via tokenize (NOT tokenize_console). This always returns at least two values - if only one key is actually bound, -1 will be returned. The bindmap argument is listed for compatibility with dp-specific defs, but is ignored in FTE. */
-
-string(string command, optional float bindmap) findkeysforcommandex = #0; /*
- Returns a list of key bindings in keyname format instead of keynums. Use tokenize to parse. This list may contain modifiers. May return large numbers of keys. */
-
-float(float v, optional float base) log = #532; /*
- Determines the logarithm of the input value according to the specified base. This can be used to calculate how much something was shifted by. */
-
-float(string filename, strbuf bufhandle) buf_loadfile = #535; /*
- Appends the named file into a string buffer (which must have been created in advance). The return value merely says whether the file was readable. */
-
-float(filestream filehandle, strbuf bufhandle, optional float startpos, optional float numstrings) buf_writefile = #536; /*
- Writes the contents of a string buffer onto the end of the supplied filehandle (you must have already used fopen). Additional optional arguments permit you to constrain the writes to a subsection of the stringbuffer. */
-
-//----------------------------------------------------------------------
-// 600-699 Range
-//----------------------------------------------------------------------
-void(.../*, string funcname*/) callfunction = #605; /*
- Invokes the named function. The function name is always passed as the last parameter and must always be present. The others are passed to the named function as-is */
-
-float(string s) isfunction = #607; /*
- Returns true if the named function exists and can be called with the callfunction builtin. */
-
-float(entity e, string s, optional float offset) parseentitydata = #613; /*
- Reads a single entity's fields into an already-spawned entity. s should contain field pairs like in a saved game: {"foo1" "bar" "foo2" "5"}. Returns <=0 on failure, otherwise returns the offset in the string that was read to. */
-
-string(string fmt, ...) sprintf = #627;
-float(entity e, float s) getsurfacenumtriangles = #628;
-vector(entity e, float s, float n) getsurfacetriangle = #629;
-
-//----------------------------------------------------------------------
-//Builtin Stubs List - present for simpler compatibility
-// Not properly supported in QuakeSpasm at this time
-//----------------------------------------------------------------------
-/*
-void(vector org, string modelname, float startframe, float endframe, float framerate) effect = #404;
-void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower = #406;
-void(vector org, vector color) te_explosionrgb = #407;
-void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube = #408;
-void(vector org, vector vel, float howmany) te_spark = #411;
-void(vector org) te_gunshotquad = #412;
-void(vector org) te_spikequad = #413;
-void(vector org) te_superspikequad = #414;
-void(vector org) te_explosionquad = #415;
-void(vector org) te_smallflash = #416;
-void(vector org, float radius, float lifetime, vector color) te_customflash = #417;
-void(vector org) te_plasmaburn = #433;
-*/
-
-//----------------------------------------------------------------------
-// Keyboard input values
-//----------------------------------------------------------------------
-const float K_TAB = 9;
-const float K_ENTER = 13;
-const float K_ESCAPE = 27;
-const float K_SPACE = 32;
-const float K_BACKSPACE = 127;
-const float K_UPARROW = 128;
-const float K_DOWNARROW = 129;
-const float K_LEFTARROW = 130;
-const float K_RIGHTARROW = 131;
-const float K_ALT = 132;
-const float K_CTRL = 133;
-const float K_SHIFT = 134;
-const float K_F1 = 135;
-const float K_F2 = 136;
-const float K_F3 = 137;
-const float K_F4 = 138;
-const float K_F5 = 139;
-const float K_F6 = 140;
-const float K_F7 = 141;
-const float K_F8 = 142;
-const float K_F9 = 143;
-const float K_F10 = 144;
-const float K_F11 = 145;
-const float K_F12 = 146;
-const float K_INS = 147;
-const float K_DEL = 148;
-const float K_PGDN = 149;
-const float K_PGUP = 150;
-const float K_HOME = 151;
-const float K_END = 152;
-const float K_KP_SLASH = 168;
-const float K_KP_STAR = 169;
-const float K_KP_MINUS = 170;
-const float K_KP_HOME = 164;
-const float K_KP_UPARROW = 165;
-const float K_KP_PGUP = 166;
-const float K_KP_PLUS = 171;
-const float K_KP_LEFTARROW = 161;
-const float K_KP_5 = 162;
-const float K_KP_RIGHTARROW = 163;
-const float K_KP_END = 158;
-const float K_KP_DOWNARROW = 159;
-const float K_KP_PGDN = 160;
-const float K_KP_ENTER = 172;
-const float K_KP_INS = 157;
-const float K_KP_DEL = 167;
-const float K_COMMAND = -170;
-const float K_MOUSE1 = 512;
-const float K_MOUSE2 = 513;
-const float K_MOUSE3 = 514;
-const float K_JOY1 = 768;
-const float K_JOY2 = 769;
-const float K_JOY3 = 770;
-const float K_JOY4 = 771;
-const float K_AUX1 = 784;
-const float K_AUX2 = 785;
-const float K_AUX3 = 786;
-const float K_AUX4 = 787;
-const float K_AUX5 = 788;
-const float K_AUX6 = 789;
-const float K_AUX7 = 790;
-const float K_AUX8 = 791;
-const float K_AUX9 = 792;
-const float K_AUX10 = 793;
-const float K_AUX11 = 794;
-const float K_AUX12 = 795;
-const float K_AUX13 = 796;
-const float K_AUX14 = 797;
-const float K_AUX15 = 798;
-const float K_AUX16 = 799;
-const float K_AUX17 = 800;
-const float K_AUX18 = 801;
-const float K_AUX19 = 802;
-const float K_AUX20 = 803;
-const float K_AUX21 = 804;
-const float K_AUX22 = 805;
-const float K_AUX23 = 806;
-const float K_AUX24 = 807;
-const float K_AUX25 = 808;
-const float K_AUX26 = 809;
-const float K_AUX27 = 810;
-const float K_AUX28 = 811;
-const float K_AUX29 = 812;
-const float K_AUX30 = 813;
-const float K_AUX31 = 814;
-const float K_AUX32 = 815;
-const float K_MWHEELUP = 515;
-const float K_MWHEELDOWN = 516;
-const float K_MOUSE4 = 517;
-const float K_MOUSE5 = 518;
-const float K_LTHUMB = 822;
-const float K_RTHUMB = 823;
-const float K_LSHOULDER = 824;
-const float K_RSHOULDER = 825;
-const float K_ABUTTON = 826;
-const float K_BBUTTON = 827;
-const float K_XBUTTON = 828;
-const float K_YBUTTON = 829;
-const float K_LTRIGGER = 830;
-const float K_RTRIGGER = 831;
-const float K_PAUSE = 153;
-
-//----------------------------------------------------------------------
-// Reset suppression of ref errors
-#pragma noref 0
-
-//----------------------------------------------------------------------
-// List of advertised extensions (not used, reference only)
-//----------------------------------------------------------------------
-//DP_CON_SET
-//DP_CON_SETA
-//DP_EF_NOSHADOW
-//DP_ENT_ALPHA
-//DP_ENT_COLORMOD
-//DP_ENT_SCALE
-//DP_ENT_TRAILEFFECTNUM
-//DP_INPUTBUTTONS
-//DP_QC_AUTOCVARS
-//DP_QC_ASINACOSATANATAN2TAN
-//DP_QC_COPYENTITY
-//DP_QC_CRC16
-//DP_QC_CVAR_DEFSTRING
-//DP_QC_CVAR_STRING
-//DP_QC_CVAR_TYPE
-//DP_QC_EDICT_NUM
-//DP_QC_ENTITYDATA
-//DP_QC_ETOS
-//DP_QC_FINDCHAIN
-//DP_QC_FINDCHAINFLAGS
-//DP_QC_FINDCHAINFLOAT
-//DP_QC_FINDFLAGS
-//DP_QC_FINDFLOAT
-//DP_QC_GETLIGHT
-//DP_QC_GETSURFACE
-//DP_QC_GETSURFACETRIANGLE
-//DP_QC_GETSURFACEPOINTATTRIBUTE
-//DP_QC_MINMAXBOUND
-//DP_QC_MULTIPLETEMPSTRINGS
-//DP_QC_RANDOMVEC
-//DP_QC_SINCOSSQRTPOW
-//DP_QC_SPRINTF
-//DP_QC_STRFTIME
-//DP_QC_STRING_CASE_FUNCTIONS
-//DP_QC_STRINGBUFFERS
-//DP_QC_STRINGCOLORFUNCTIONS
-//DP_QC_STRREPLACE
-//DP_QC_TOKENIZEBYSEPARATOR
-//DP_QC_TRACEBOX
-//DP_QC_TRACETOSS
-//DP_QC_TRACE_MOVETYPES
-//DP_QC_URI_ESCAPE
-//DP_QC_VECTOANGLES_WITH_ROLL
-//DP_QC_VECTORVECTORS
-//DP_QC_WHICHPACK
-//DP_VIEWZOOM
-//DP_REGISTERCVAR
-//DP_SV_BOTCLIENT
-//DP_SV_DROPCLIENT
-//DP_SV_POINTSOUND
-//DP_SV_PRINT
-//DP_SV_SETCOLOR
-//DP_SV_SPAWNFUNC_PREFIX
-//DP_SV_WRITEUNTERMINATEDSTRING
-//DP_TE_PARTICLERAIN
-//DP_TE_PARTICLESNOW
-//DP_TE_STANDARDEFFECTBUILTINS
-//EXT_BITSHIFT
-//FRIK_FILE
-//FTE_PART_SCRIPT
-//FTE_PART_NAMESPACES
-//FTE_PART_NAMESPACE_EFFECTINFO
-//FTE_QC_CHECKCOMMAND
-//FTE_QC_CROSSPRODUCT
-//FTE_QC_INFOKEY
-//FTE_QC_INTCONV
-//FTE_QC_MULTICAST
-//FTE_STRINGS
-//FTE_SV_POINTPARTICLES
-//KRIMZON_SV_PARSECLIENTCOMMAND
-//ZQ_QC_STRINGS

Return to the top of this page or return to the overview of this repo.

Diff qc-server/csqc/csqc_fteopts.qc

diff --git a/qc-server/csqc/csqc_fteopts.qc b/qc-server/csqc/csqc_fteopts.qc
deleted file mode 100644
index 8f7324f..0000000
--- a/qc-server/csqc/csqc_fteopts.qc
+++ /dev/null
@@ -1,2 +0,0 @@
-#define FTE
-#pragma TARGET FTE

Return to the top of this page or return to the overview of this repo.

Diff qc-server/csqc/csqc_hudvanilla.qc

diff --git a/qc-server/csqc/csqc_hudvanilla.qc b/qc-server/csqc/csqc_hudvanilla.qc
deleted file mode 100644
index c3b2ac9..0000000
--- a/qc-server/csqc/csqc_hudvanilla.qc
+++ /dev/null
@@ -1,958 +0,0 @@
-/*======================================================================
- All CSQC functions (Vanilla ONLY version)
-
- * This file is heavily influenced by QSS devkit (credit=spike)
- * re-written some functions to make better sense to me
- * Contains all HUD elements for full quake interface (SP/Coop/Dm)
- * Sripped out the experimental stuff included in devkit
- * Converted most of the hardcoded values into constants
- * Added loads of extra comments to show what is going on
-
-======================================================================*/
-float nocsqc; // CSQC State (0=on, 1=off)
-float detectDP; // Detect DP engine (using wrapper)
-float sitems; // CSQC copy of .items
-float sitems2; // CSQC copy of .items2 (or serverflags)
-float sweapon; // CSQC copy of .weapon
-float shealth; // CSQC copy of .health
-
-float sb_showscores; // Show lower tab scores
-float painfinishtime; // Track player damage for hud face
-
-float intermission; // in intermission
-float intermission_time; // when the intermission started
-
-float player_localentnum; // Entity number that csqc is attached to
-float numclientseats; // coop or splitscreen?
-float maxclients; // maximum players possible on this server
-float cltime; // increases regardless of pause or game speed
-
-.float ext_csqc; // Client Server Quake C HUD alive!
-string CSQC_PING = "csqcping"; // Test command to check if CSCQ alive
-
-// Default sizes for HUD elements
-vector HUDSIZE_320 = '320 24 0';// Background images
-vector HUDSIZE_24 = '24 24 0'; // Status Bar
-vector HUDSIZE_16 = '16 16 0'; // Inventory/Powerups
-vector HUDSIZE_816 = '8 16 0'; // Runes
-vector HUDSIZE_8 = '8 8 0'; // Ammo numbers
-vector HUDSIZE_C8 = '8 0 0'; // Character sizes
-
-// 8 pixel font table (index positions)
-float HUDFONT_WHITE = 0; // Default index = 48-57
-float HUDFONT_YELLOW = 1; // index = index - 30
-float HUDFONT_RED = 2; // index = index + 128
-
-// Default sizes for weapons
-vector HUDWPN_48 = '48 16 0'; // Vanilla LG
-vector HUDWPN_32 = '32 16 0'; // AD/Hipnotic LG
-vector HUDWPN_24 = '24 16 0'; // Default
-
-vector HUDRGB_DEF = '1 1 1';
-float baralpha; // Read scr_sbaralpha variable
-float hudalpha; // All gfx on hud bars
-
-//----------------------------------------------------------------------
-// These constants are only used in CSQC_UpdateView
-float MASK_ENGINE = 1;
-float MASK_VIEWMODEL = 2;
-float VF_MIN = 1;
-float VF_SIZE = 4;
-float VF_DRAWENGINESBAR = 20;
-float VF_DRAWCROSSHAIR = 21;
-
-//----------------------------------------------------------------------
-// Statue, Inventory and Score bars (All 320 x 24)
-string backgrd[3] = { "gfx/sbar", "gfx/ibar", "gfx/scorebar" };
-// Ranking (168 x 24), Complete (184 x 24), Inter (160 x 144)
-// Require .lmp extensions if not loaded diectly from GFX file
-string backlmp[3] = { "gfx/ranking.lmp", "gfx/complete.lmp", "gfx/inter.lmp" };
-
-//----------------------------------------------------------------------
-// Regular (24x24) brown numbers
-string number[10] = {
- "gfx/num_0", "gfx/num_1", "gfx/num_2", "gfx/num_3", "gfx/num_4",
- "gfx/num_5", "gfx/num_6", "gfx/num_7", "gfx/num_8", "gfx/num_9"
-};
-// Red (24x24) numbers for no armour, low HP (<25) and no ammo
-string anumber[10] = {
- "gfx/anum_0", "gfx/anum_1", "gfx/anum_2", "gfx/anum_3", "gfx/anum_4",
- "gfx/anum_5", "gfx/anum_6", "gfx/anum_7", "gfx/anum_8", "gfx/anum_9"
-};
-
-// Regular (24x24) characters for intermission
-string extrachar[3] = {
- "gfx/num_colon", "gfx/num_minus", "gfx/num_slash"
-};
-
-// 24x24 pixel icons for Status Bar
-string sbitems[8] = {
- "gfx/sb_shells", "gfx/sb_nails", "gfx/sb_rocket", "gfx/sb_cells",
- "gfx/sb_armor1", "gfx/sb_armor2", "gfx/sb_armor3", "gfx/disc"
-};
-
-// 16x16 pixel icons for Information Bar
-string ibitems[6] = {
- "gfx/sb_key1", "gfx/sb_key2", "gfx/sb_invis", "gfx/sb_invuln",
- "gfx/sb_suit", "gfx/sb_quad"
-};
-
-// 8x16 pixel runes for Information Bar
-string ibrunes[4] = {
- "gfx/sb_sigil1", "gfx/sb_sigil2", "gfx/sb_sigil3", "gfx/sb_sigil4"
-};
-
-//----------------------------------------------------------------------
-// All weapon HUD graphics are prefixed with certain characters which
-// means all weapon filenames can be generated with string commands
-// CSQC is really an advanced (QSS/FTE/DP) engine only thing and its
-// very likely that FTE_STRINGS is supported for string manipulation
-//----------------------------------------------------------------------
-// Special constants for weapons
-float WPN_ICONS = 7; // Total weapons to precache pics + flash timers
-float WPN_WIDTHLG = 6; // Odd weapon gfx width (48) default (24)
-// Record when weapons have been added (flash mechanic)
-float flashtime[WPN_ICONS];
-
-// Shotgun, SuperShotgun, Nailgun, SuperNailGun, GrenadeLauncher
-// RocketLauncher, LightningGun
-string wpnnames[WPN_ICONS] = {
- "shotgun", "sshotgun", "nailgun", "snailgun", "rlaunch",
- "srlaunch", "lightng"
-};
-// OFF / ON gfx (reflects active weapon)
-string wpnselect[2] = { "gfx/inv_", "gfx/inv2_" };
-// Special flash set for when the player gets weapon
-string wpnflash[5] = { "gfx/inva1_","gfx/inva2_","gfx/inva3_","gfx/inva4_","gfx/inva5_" };
-
-//----------------------------------------------------------------------
-// Frame 00-04 : Regular HP 100/80/60/40/20
-// Frame 05-09 : InPain HP 100/80/60/40/20
-// Frame 10 : Invisibility Ring + Pentagram!
-// Frame 11 : Quad Damage
-// Frame 12 : Invisibility Ring
-// Frame 13 : Pentagram (invulnerability)
-//----------------------------------------------------------------------
-string facetab[14] = {
- "gfx/face5", "gfx/face4", "gfx/face3", "gfx/face2", "gfx/face1",
- "gfx/face_p5", "gfx/face_p4", "gfx/face_p3", "gfx/face_p2",
- "gfx/face_p1",
- "gfx/face_inv2", "gfx/face_quad", "gfx/face_invis", "gfx/face_invul2"
-};
-
-//----------------------------------------------------------------------
-// Stubs for extra CSQC functions (not all supported)
-//----------------------------------------------------------------------
-// Can query or check anything types on the console here
-float(string str) CSQC_ConsoleCommand = {
- tokenize_console(str);
- return FALSE;
-};
-// Can query/check keyboard/mouse/joystick input with this function
-// For key events, scanx is one of the KEY_* values
-// chary is the character code (chr2str to shove it into a string)
-// For mouse events then x+y are the mouse delta/position values
-float(float evtype, float scanx, float chary, float devid) CSQC_InputEvent = {
- return FALSE;
-};
-// This is linked to client dmg_take / dmg_save / dmg_inflictor fields
-// returning TRUE will block the red flash damage stuff
-float(float save, float take, vector dir) CSQC_Parse_Damage = {
- painfinishtime = time + 0.2;
- return FALSE;
-};
-// Can query/check server MSG events
-// CSQC_Parse_Event is called when the client sees a
-// #define svcfte_cgamepacket (83) message from the server
-// Not supported for DP, is called from only QSS/FTE
-void() CSQC_Parse_Event = { };
-
-// Can intercept printed messages from the server (top of screen)
-// printlvl (text filtering) 0=low, 1=medium, 2=high, 3=chat
-// con_notifytime = amount of time the text remains on screen
-// ONLY define this function, if doing something with the text!!
-void(string printmsg, float printlvl) CSQC_Parse_Print = {
- print(printmsg);
-};
-
-// Running on the Server side of CSQC listening for commands back
-// This is never called on the client side of the progs
-void(string str) SV_ParseClientCommand = {
- local string ostr, cmd;
- // Save command string for later
- ostr = str;
- // Search for tokens in string
- tokenize_console(str);
- // Find the first argument of the command
- cmd = argv(0);
- // Is this my (AD CSQC) command?
- if (cmd == CSQC_PING) self.ext_csqc = TRUE;
- // Pass through original command
- else clientcommand(self, ostr);
-};
-
-//======================================================================
-// Display 24pixel numbers to HUD (cope with red version)
-//----------------------------------------------------------------------
-void(vector pos, float value, float threshhold) Hud_DrawNoFont24 =
-{
- local string val_str, disp_str;
- local float disp_col, disp_len, disp_no;
-
- // Make sure value is within range
- if (value < 0) value = 0;
- else if (value > 999) value = 999;
- // Work out which number colour to use
- if (value <= threshhold) disp_col = TRUE;
-
- // Round number down (floor) and work out length
- val_str = ftos(floor(value));
- disp_len = strlen(val_str);
- // Move to the lowest digit position first
- pos_x = pos_x + (3 * HUDSIZE_24_x);
-
- while (disp_len > 0) {
- // Countdown early (range is 0-2, strlen returns 1-3)
- disp_len = disp_len - 1;
- // Move backward to display a digit
- pos_x = pos_x - HUDSIZE_24_x;
- // Convert str character to font index numbers
- disp_no = (str2chr(val_str, disp_len) - '0');
- // Double check for any wierd range issues
- if (disp_no < 0 || disp_no > 9) disp_no = 0;
- // Work out which number colour to use
- if (disp_col) disp_str = anumber[disp_no];
- else disp_str = number[disp_no];
- // Draw number in correct (right-justified) position
- drawpic(pos, disp_str, HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
- }
-};
-
-//----------------------------------------------------------------------
-// Display 24pixel characters to HUD (limited chars available)
-//----------------------------------------------------------------------
-void(vector pos, string num) Hud_DrawCharFont24 =
-{
- float i, c;
- // Endless loop until end of string
- // Keep moving draw pos forward (pos_x)
- for(i = 0; ; i++, pos_x += HUDSIZE_24_x) {
- // Read next character from string
- c = str2chr(num, i);
- // End of string found?
- if (!c) break;
- // Check for special characters
- else if (c == ':' || c == '.')
- drawpic(pos, extrachar[0], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
- else if (c == '-')
- drawpic(pos, extrachar[1], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
- else if (c == '/')
- drawpic(pos, extrachar[2], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
- // Draw rest of the numbers
- else if (c >= '0' && c <= '9') {
- // Sanity check, make sure within range of array
- c = c - 48; if (c<0 || c>9) c=0;
- drawpic(pos, number[c], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
- }
- }
-};
-
-//----------------------------------------------------------------------
-// Draws small 8 pixel numbers to HUD (white/yellow/red text options)
-//----------------------------------------------------------------------
-void(vector pos, float value, float digit, float zerofill, float fontcol) Hud_DrawNoFont8 =
-{
- local string val_str;
- local float disp_len, disp_no;
-
- // Make sure value is within range
- if (value < 0) value = 0;
- // Check max range against max digits
- else if (value > 999 && digit >= 3) value = 999;
- else if (value > 99 && digit == 2) value = 99;
- else if (value > 9 && digit <= 1) value = 9;
-
- // Round number down (floor) and work out length
- val_str = ftos(floor(value));
- disp_len = strlen(val_str);
-
- // Zero fill number?
- if (zerofill) {
- while (disp_len < digit) {
- // Keep adding more zero's
- val_str = strcat("0", val_str);
- // Exit condition?
- disp_len = strlen(val_str);
- }
- }
-
- // Move to the lowest digit position first
- pos_x = pos_x + (digit * HUDSIZE_8_x);
-
- while (disp_len > 0) {
- // Countdown first (digit positions = 0-2)
- disp_len = disp_len - 1;
- // Move backward to display a digit
- pos_x = pos_x - HUDSIZE_8_x;
- // Convert character to number (font table index 48-57)
- disp_no = str2chr(val_str, disp_len);
- if (fontcol == HUDFONT_YELLOW) disp_no = disp_no - 30;
- else if (fontcol == HUDFONT_RED) disp_no = disp_no + 128;
- // Draw character from ascii font table (right-justified)
- drawcharacter(pos, disp_no, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- }
-};
-
-//----------------------------------------------------------------------
-// Change HUD face to reflect Health, Pain or Powerups
-//----------------------------------------------------------------------
-void(vector pos) Hud_DrawFace =
-{
- string face;
- local float hpframe;
-
- // Start with InvRing as it has two states
- if (sitems & CSQC_INVISIBILITY) {
- // InvRing + Pentagram!?! WTF!?! SandyP E4 design!
- if (sitems & CSQC_INVULNERABILITY) face = facetab[10];
- // Just InvRing only
- else face = facetab[12];
- }
- // Quad only
- else if (sitems & CSQC_QUAD) face = facetab[11];
- // Pentagram only
- else if (sitems & CSQC_INVULNERABILITY) face = facetab[13];
- // Regular face
- else {
- // Work out face based on HP (100/80/60/40/20)
- hpframe = floor(shealth / 20);
- // Check for negative and upper (MegaHP) limits
- if (hpframe < 0) hpframe = 0;
- else if (hpframe > 4) hpframe = 4;
- // Check for any pain/flinch updates
- if (painfinishtime > time) hpframe = hpframe + 5;
- // Final HP face
- face = facetab[hpframe];
- }
-
- // Draw face - always 24x24 size, full rgb/alpha
- drawpic(pos, face, HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
-};
-
-//----------------------------------------------------------------------
-// Update a weapon icon with selection or flash features
-//----------------------------------------------------------------------
-static void(float num, vector pos) Hud_DrawWeapon =
-{
- local string prefix, file_str;
- local vector gfx_size;
- local float flash;
-
- // The weapon flash is done every 0.1s and repeated twice!
- // When the player gets a new weapon the time is reset
- // This function will count the time difference for flashing
- // Convert the flash time to a 0-10+ range
- flash = (time - flashtime[num])*10;
-
- // Has the flash happened twice? (finished)
- if (flash >= 10) {
- // Work out if this weapon is currently selected
- if (sweapon == (1<<num)) prefix = wpnselect[1];
- // Default is no highlight
- else prefix = wpnselect[0];
- }
- // Flashing!
- else {
- // Is the flash into second phase?
- if (flash < 0) flash = 0;
- else if (flash >= 5) flash = flash - 5;
- // flash is only 0-4 frames
- prefix = wpnflash[flash];
- }
- // Merge prefix type (defined above) to weapon filename
- // Without string (str) functions this would involve a giant table
- // This sorta assumes that CSQC is running on an advanced engine
- // QSS/FTE/DP all support FTE_STRINGS extra str functions
- file_str = strcat(prefix, wpnnames[num]);
-
- // Most weapons are 24 pixels wide (half of ammo above)
- // As always there is an exception (lightning gun)
- if (num == WPN_WIDTHLG) gfx_size = HUDWPN_48;
- else gfx_size = HUDWPN_24;
- // Show weapon GFX (active/deactive/flashing)
- drawpic(pos, file_str, gfx_size, HUDRGB_DEF, hudalpha, 0);
-};
-
-//======================================================================
-// STATUS BAR ( Armour / Health quantities and current Ammo selected)
-//----------------------------------------------------------------------
-void (vector pos, vector virtsize) Hud_DrawSBar =
-{
- // Draw primary HUD bar (Armour/Face/Health/Ammo)
- drawpic(pos, backgrd[0], HUDSIZE_320, HUDRGB_DEF, baralpha, 0);
-
- // Deal with Pentagram first, its a simple test/update
- if (sitems & CSQC_INVULNERABILITY) {
- // Make sure 666 is in 24 pixel giant red numbers!
- Hud_DrawNoFont24(pos+[24,0], 666, 666);
- // Draw a pentagram symbol in the armour HUD slot
- drawpic(pos, sbitems[7], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
- }
- else {
- // Show armour type/quantity active
- Hud_DrawNoFont24(pos+'24 0 0', getstatf(CLIENT_ARMOR), 25);
- // Only 3 armour types (green/yellow/red)
- if (sitems & CSQC_ARMOR1)
- drawpic(pos, sbitems[4], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
- else if (sitems & CSQC_ARMOR2)
- drawpic(pos, sbitems[5], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
- else if (sitems & CSQC_ARMOR3)
- drawpic(pos, sbitems[6], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
- }
-
- // Draw face + HP value
- Hud_DrawFace(pos+[112,0]);
- Hud_DrawNoFont24(pos+[136,0], shealth, 25);
-
- // Only update ammo type/quantity if not using axe!
- if (sweapon != CSQC_AXE) {
- Hud_DrawNoFont24(pos+[248,0], getstatf(CLIENT_AMMO), 10);
- if (sitems & CSQC_SHELLS)
- drawpic(pos+[224,0], sbitems[0], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
- else if (sitems & CSQC_NAILS)
- drawpic(pos+[224,0], sbitems[1], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
- else if (sitems & CSQC_ROCKETS)
- drawpic(pos+[224,0], sbitems[2], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
- else if (sitems & CSQC_CELLS)
- drawpic(pos+[224,0], sbitems[3], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
- }
-};
-
-//======================================================================
-// INVENTORY BAR ( Ammo quantities, keys/runes and powerups )
-//----------------------------------------------------------------------
-void (vector pos, vector br) Hud_DrawIBar =
-{
- local vector topcol, botcol;
- local string player_frags;
-
- // Draw background bar using scr_sbaralpha default
- drawpic(pos, backgrd[1], HUDSIZE_320, HUDRGB_DEF, baralpha, 0);
-
- // Always draw ammo scores
- Hud_DrawNoFont8(pos + [10,0], getstatf(CLIENT_SHELLS), 3, FALSE, HUDFONT_YELLOW);
- Hud_DrawNoFont8(pos + [58,0], getstatf(CLIENT_NAILS), 3, FALSE, HUDFONT_YELLOW);
- Hud_DrawNoFont8(pos + [106,0], getstatf(CLIENT_ROCKETS), 3, FALSE, HUDFONT_YELLOW);
- Hud_DrawNoFont8(pos + [154,0], getstatf(CLIENT_CELLS), 3, FALSE, HUDFONT_YELLOW);
-
- // Draw weapons and highlight current one
- if (sitems & CSQC_SHOTGUN) Hud_DrawWeapon(0, pos+[24*0,8]);
- if (sitems & CSQC_SUPER_SHOTGUN) Hud_DrawWeapon(1, pos+[24*1,8]);
- if (sitems & CSQC_NAILGUN) Hud_DrawWeapon(2, pos+[24*2,8]);
- if (sitems & CSQC_SUPER_NAILGUN) Hud_DrawWeapon(3, pos+[24*3,8]);
- if (sitems & CSQC_GRENADE_LAUNCHER) Hud_DrawWeapon(4, pos+[24*4,8]);
- if (sitems & CSQC_ROCKET_LAUNCHER) Hud_DrawWeapon(5, pos+[24*5,8]);
- if (sitems & CSQC_LIGHTNING) Hud_DrawWeapon(6, pos+[24*6,8]);
-
- // Draw inventory items
- if (sitems & CSQC_KEY1)
- drawpic(pos+[192,8], ibitems[0], HUDSIZE_16, HUDRGB_DEF, hudalpha, 0);
- if (sitems & CSQC_KEY2)
- drawpic(pos+[208,8], ibitems[1], HUDSIZE_16, HUDRGB_DEF, hudalpha, 0);
- if (sitems & CSQC_INVISIBILITY)
- drawpic(pos+[224,8], ibitems[2], HUDSIZE_16, HUDRGB_DEF, hudalpha, 0);
- if (sitems & CSQC_INVULNERABILITY)
- drawpic(pos+[240,8], ibitems[3], HUDSIZE_16, HUDRGB_DEF, hudalpha, 0);
- if (sitems & CSQC_SUIT)
- drawpic(pos+[256,8], ibitems[4], HUDSIZE_16, HUDRGB_DEF, hudalpha, 0);
- if (sitems & CSQC_QUAD)
- drawpic(pos+[272,8], ibitems[5], HUDSIZE_16, HUDRGB_DEF, hudalpha, 0);
-
- // Draw Runes (special size + location)
- if (sitems2 & CSQC_RUNE1)
- drawpic(pos+[288,8], ibrunes[0], HUDSIZE_816, HUDRGB_DEF, hudalpha, 0);
- if (sitems2 & CSQC_RUNE2)
- drawpic(pos+[296,8], ibrunes[1], HUDSIZE_816, HUDRGB_DEF, hudalpha, 0);
- if (sitems2 & CSQC_RUNE3)
- drawpic(pos+[304,8], ibrunes[2], HUDSIZE_816, HUDRGB_DEF, hudalpha, 0);
- if (sitems2 & CSQC_RUNE4)
- drawpic(pos+[312,8], ibrunes[3], HUDSIZE_816, HUDRGB_DEF, hudalpha, 0);
-
- //should probably show team scores, but this mimics vanilla
- if (deathmatch) {
- // Move to space above powerups
- pos_x += 194;
-
- // Loop through 4 players
- for (float i = -1; i >= -4; i--) {
- // Read frag score of next player
- player_frags = getplayerkeyvalue(i, "frags");
- // No frags? stop loop
- if (player_frags == "") break;
- // Read deathmatch player top/bottom skin colours
- topcol = stov(getplayerkeyvalue(i, "topcolor_rgb"));
- botcol = stov(getplayerkeyvalue(i, "bottomcolor_rgb"));
- // Draw skin colours (alpha was 0.75 hardcoded)
- drawfill(pos+[0,1], [28,3], topcol, 0.75, 0);
- drawfill(pos+[0,4], [28,4], botcol, 0.75, 0);
- // Draw frag score (New global small font function)
- Hud_DrawNoFont8(pos + '2 0 0', stof(player_frags), 3, FALSE, HUDFONT_WHITE);
- // Find player entity attached to this HUD
- if (player_localentnum == stof(getplayerkeyvalue(i, "viewentity"))) {
- // special characters = []
- drawcharacter(pos+[-4,0], 0xe010, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- drawcharacter(pos+[24,0], 0xe011, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- }
- // Move forward to next hud space
- pos_x += 8*4;
- }
- }
-};
-
-//======================================================================
-// Scoreboard Bar (shows monster/secret quantities and map info)
-//----------------------------------------------------------------------
-void(vector pos, float bx, float by, float bwidth, float bheight, float pixelspeed, string draw_str) Hud_ScrollTextBox =
-{
- local float str_width, str_double, str_speed;
- local string wide_str;
-
- // draw debug visual box to show area on screen
- //drawfill( pos+[bx,by], [bwidth,bheight], HUDRGB_DEF, 0.1, 0);
-
- // Find out width of string in pixels (using font 8)
- str_width = stringwidth( draw_str, TRUE, HUDSIZE_8);
- // String less than window width?
- if (str_width < bwidth) {
- // Center the map name string in the box area
- str_double = (bwidth - str_width) / 2;
- // Display string normally (no scrolling required)
- drawstring( pos+[bx+str_double, by], draw_str, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- }
- else {
- // Create double length string with boundary marker
- wide_str = strcat(draw_str, " /// ", draw_str);
- // Setup clip (scissor) area for exclusive drawing
- drawsetcliparea( pos_x + bx, pos_y + by, bwidth, bheight);
- str_double = stringwidth( wide_str, TRUE, HUDSIZE_8);
- // create offset of string to make it look like its scrolling
- str_speed = mod(cltime * pixelspeed, (str_double - str_width));
- // draw string (with offset) inside of clip (scissor) area only
- drawstring( pos+[bx - str_speed, by], wide_str, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- // Reset clip string area to default
- drawresetcliparea();
- }
-};
-
-//----------------------------------------------------------------------
-// Quakespasm scoreboard layout (no time)
-//----------------------------------------------------------------------
-void(vector pos) Hud_QSScores_SBar =
-{
- local string skill_str, map_str;
- local float digit;
-
- // Clear status bar ready for map info/scores
- drawpic(pos, backgrd[2], HUDSIZE_320, HUDRGB_DEF, baralpha, 0);
- // Display headings
- drawstring(pos+[8,12], "Kills:", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- drawstring(pos+[80,12], "/", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- drawstring(pos+[132,12], "Skill ", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- drawstring(pos+[208,12], "Secrets:", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- drawstring(pos+[288,12], "/", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- // Display monster/secret totals
- Hud_DrawNoFont8(pos+[56,12], getstatf(CLIENT_KILLEDMONSTERS), 3, FALSE, HUDFONT_WHITE);
- if (getstatf(CLIENT_TOTALMONSTERS) < 100) digit = 2;
- else digit = 3;
- Hud_DrawNoFont8(pos+[88,12], getstatf(CLIENT_TOTALMONSTERS), digit, FALSE, HUDFONT_WHITE);
- Hud_DrawNoFont8(pos+[272,12], getstatf(CLIENT_FOUNDSECRETS), 2, FALSE, HUDFONT_WHITE);
- Hud_DrawNoFont8(pos+[296,12], getstatf(CLIENT_TOTALSECRETS), 2, FALSE, HUDFONT_WHITE);
- // Display map skill level
- skill_str = autocvar(skill, "1");
- drawstring(pos+[180,12], skill_str, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
-
- // Level designers Map name + File name
- map_str = strcat(world.message, " (", mapname, ")");
- Hud_ScrollTextBox(pos, 8, 4, 304, 8, 16, map_str);
-};
-
-//----------------------------------------------------------------------
-// The original ID scoreboard layout (no skill, map filename)
-//----------------------------------------------------------------------
-void(vector pos) Hud_IDScores_SBar =
-{
- local float nsecs, nmins;
-
- // Clear status bar ready for map info/scores
- drawpic(pos, backgrd[2], HUDSIZE_320, HUDRGB_DEF, baralpha, 0);
- // Display headings
- drawstring(pos+[8,4], "Monsters:", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- drawstring(pos+[104,4], "/", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- drawstring(pos+[8,12], "Secrets :", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- drawstring(pos+[104,12], "/", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- drawstring(pos+[184,4], "Time :", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- drawstring(pos+[256,4], ":", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- // Display monster/secret totals
- Hud_DrawNoFont8(pos+[80,4], getstatf(CLIENT_KILLEDMONSTERS), 3, FALSE, HUDFONT_WHITE);
- Hud_DrawNoFont8(pos+[112,4], getstatf(CLIENT_TOTALMONSTERS), 3, FALSE, HUDFONT_WHITE);
- Hud_DrawNoFont8(pos+[80,12], getstatf(CLIENT_FOUNDSECRETS), 3, FALSE, HUDFONT_WHITE);
- Hud_DrawNoFont8(pos+[112,12], getstatf(CLIENT_TOTALSECRETS), 3, FALSE, HUDFONT_WHITE);
- // Work out time passed
- nmins = floor(time/60);
- nsecs = floor(time - nmins*60);
- Hud_DrawNoFont8(pos+[232,4], nmins, 3, FALSE, HUDFONT_WHITE);
- Hud_DrawNoFont8(pos+[264,4], nsecs, 2, TRUE, HUDFONT_WHITE);
- // Level designers Map name
- Hud_ScrollTextBox(pos, 140, 12, 176, 8, 16, world.message);
-};
-
-//======================================================================
-// Deathmatch scoreboard
-//----------------------------------------------------------------------
-vector(string picname, float height) Hud_AspectSize =
-{
- local vector sz;
- sz = drawgetimagesize(picname);
- return [sz_x * height/sz_y, height];
-};
-
-//----------------------------------------------------------------------
-void(string picname, float screenwidth, vector pos, float height) Hud_CentrePic =
-{
- local vector sz;
- sz = Hud_AspectSize(picname, height);
- pos_x += (screenwidth-sz_x)/2;
- drawpic(pos, picname, sz, HUDRGB_DEF, hudalpha, 0);
-};
-
-//----------------------------------------------------------------------
-void(vector virtmin, vector virtsize) Hud_DMScoreboard =
-{
- local float isspec;
- local vector pos, topcol, botcol;
- string player_name, player_frags, player_ping;
-
- // Working copy
- pos = virtmin;
-
- // Check for 16 players?
- player_name = getplayerkeyvalue(-16, "name");
- if (player_name == "") pos_y += (virtsize_y-200)/2;
-
- // Only draw the header when its not a really big game
- player_name = getplayerkeyvalue(-24, "name");
- if (player_name == "") {
- pos_y += 8;
- // Display header (ranking.lmp) gfx for DM scoreboard
- Hud_CentrePic(backlmp[0], virtsize_x, pos, 24);
- // A double update of Y, only spike knows why!?!
- pos_y += 24; pos_y += 10;
- }
-
- // Another double X update, no idea why!
- pos_x += (virtsize_x-320)/2;
- pos_x += 80;
-
- //negative numbers are players sorted by frags.
- for (float i = -1; ; i--, pos_y += 10) {
- // Check for next player name
- player_name = getplayerkeyvalue(i, "name");
- // No more in list, end loop
- if (player_name == "") break;
-
- // Read player stats (frag/ping)
- isspec = stof(getplayerkeyvalue(i, "*spectator"));
- player_frags = getplayerkeyvalue(i, "frags");
- player_ping = getplayerkeyvalue(i, "ping");
- // Read deathmatch player top/bottom skin colours
- topcol = stov(getplayerkeyvalue(i, "topcolor_rgb"));
- botcol = stov(getplayerkeyvalue(i, "bottomcolor_rgb"));
-
- // Re-format the player name (no case conversion, force red)
- player_name = strconv(0,2,2, player_name);
- // Draw frag score (New global small font function)
- Hud_DrawNoFont8(pos-[8*5,0], stof(player_ping), 3, FALSE, HUDFONT_WHITE);
-
- // Which type of player? Spectator or Active?
- if (isspec)
- drawstring(pos+[4,0], "spec", [8,8], HUDRGB_DEF, hudalpha, 0);
- else
- {
- // Draw skin colours (alpha was 0.75 hardcoded)
- drawfill(pos+[0,0], [40,4], topcol, 0.75, 0);
- drawfill(pos+[0,4], [40,4], botcol, 0.75, 0);
-
- // Draw frag score (New global small font function)
- Hud_DrawNoFont8(pos+[8,0], stof(player_frags), 3, FALSE, HUDFONT_WHITE);
- // Find player entity attached to this HUD
- if (player_localentnum == stof(getplayerkeyvalue(i, "viewentity"))) {
- // special characters = []
- drawcharacter(pos+[0,0], 0xe010, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- drawcharacter(pos+[32,0], 0xe011, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- }
- }
- // Finally draw player name
- drawstring(pos+[64,0], player_name, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
- }
-};
-
-//======================================================================
-// Final Intermission
-//----------------------------------------------------------------------
-void(vector virtmin, vector virtsize) Hud_Intermission =
-{
- local vector pos;
- // Create positions based on virtual screen
- pos = virtmin + (virtsize-[320,200])/2;
-
- // Draw Intermission title and table info (Time/secret/kill)
- Hud_CentrePic(backlmp[1], 320, pos+[0,24], 24);
- drawpic(pos+[0,56], backlmp[2], [160,144], HUDRGB_DEF, hudalpha, 0);
-
- // Generate complete string and then draw 1 character at time
- // Uses Sprintf function to feed values into final string
- // This function should be supported by Advanced engines
- Hud_DrawCharFont24(pos+[144, 64], sprintf("%3.0f:%02.0f", intermission_time/60, intermission_time%60));
- Hud_DrawCharFont24(pos+[144, 104], sprintf("%3.0f/%.0f", getstatf(CLIENT_FOUNDSECRETS), getstatf(CLIENT_TOTALSECRETS)));
- Hud_DrawCharFont24(pos+[144, 144], sprintf("%3.0f/%.0f", getstatf(CLIENT_KILLEDMONSTERS), getstatf(CLIENT_TOTALMONSTERS)));
-};
-
-//======================================================================
-// Speedometer CEV
-//----------------------------------------------------------------------
-void(vector pos) Hud_Speedometer =
-{
- local vector v;
-
- // requires support in ssqc WorldSpawn
- v_x = getstatf(CLIENT_VELOCITY_X);
- v_y = getstatf(CLIENT_VELOCITY_Y);
- v_z = 0;
-
- Hud_DrawNoFont8(pos, vlen (v), 3, FALSE, HUDFONT_WHITE);
-};
-
-//======================================================================
-// MAIN ENTRY POINT FOR HUD!!!
-//----------------------------------------------------------------------
-void(vector virtsize, float showscores) CSQC_DrawHud =
-{
- local vector pos, pos_speedo;
- local float oitems, hudviewsize, i;
-
- // Save previous HUD versions for flash function
- oitems = sitems;
-
- //------------------------------------------------------------------
- // All variables have to be specially setup and passed between
- // progs and csprogs as they are not connected in VM space
- // By default CSQC has 30 (most commonly used) parameters setup
- // Unfortunately some of them need to be converted (bitswapped)
- // to make them reaable again (I blame spike for this mess)
- // The downside to this bitswapping mess is that the serverflags
- // is not passed to CSQC completely, only the first 4bits (runes)
- //------------------------------------------------------------------
- sitems = getstatbits(CLIENT_ITEMS, 0, 23);
- sitems2 = getstatbits(CLIENT_ITEMS, 23, 9);
- sweapon = getstatf(CLIENT_ACTIVEWEAPON);
- shealth = getstatf(CLIENT_HEALTH);
-
- // Don't show HUD, intermission or dead
- if (intermission || shealth <= 0) return;
-
- //------------------------------------------------------------------
- // Read console variable for background HUD alpha
- baralpha = cvar("scr_sbaralpha");
- if (baralpha == 0) baralpha = 0.75;
- // Default is 1 for everything else
- hudalpha = 1;
-
- //------------------------------------------------------------------
- // Check if any weapons have been added to the inventory
- // Update time so the flash function can detect it
- // Check for player count for splitscreen!?! QSS/FTE feature
- if (numclientseats <= 1) {
- // Player alive and inventory changd?
- if (shealth && sitems != oitems) {
- // Go through all weapon flash counters
- for (i = 0; i < WPN_ICONS; i++) {
- // Found weapon and its new?
- if ((sitems & (1<<i)) && !(oitems & (1<<i)))
- // Reset timer
- flashtime[i] = time;
- }
- }
- }
-
- //------------------------------------------------------------------
- // Find out how much of the HUD is being displayed
- // 100 = InfoBar & StatusBar (ALL=Default)
- // 110 = StatusBar Only
- // 120 = Speedometer
- // 130 = Nothing
- //------------------------------------------------------------------
- // Read current HUD size
- hudviewsize = cvar("viewsize");
- // Any HUD to display?
- if (hudviewsize < 130) {
- // Override scoreboard - check if no player health
- if (shealth <= 0) showscores = TRUE;
- // Find out mid point of screen
- pos_x = (virtsize_x-320)/2;
- pos_y = virtsize_y;
- pos_z = 0;
-
- // trying to center the speedometer display just below
- // the crosshair. This doesn't seem to be right but it
- // works on my 960x720 window. CEV.
- pos_speedo_x = virtsize_x/2.0;
- pos_speedo_y = virtsize_y/2.0;
- pos_speedo_z = 0;
- Hud_Speedometer(pos_speedo - [8*1.5,-8]);
- if (hudviewsize < 120) {
- // Either show Sbar or Scores (bars are centered)
- if (showscores) Hud_QSScores_SBar(pos - '0 24 0');
- else Hud_DrawSBar(pos - '0 24 0', virtsize);
- }
- // Can the Info Bar be displayed?
- if (hudviewsize < 110)
- Hud_DrawIBar(pos - '0 48 0', virtsize);
- }
-};
-
-//----------------------------------------------------------------------
-void(vector virtsize, float showscores) CSQC_DrawScores =
-{
- shealth = getstatf(CLIENT_HEALTH);
- if (intermission || showscores || shealth <= 0) {
- if (deathmatch) Hud_DMScoreboard('0 0 0', virtsize);
- else if (intermission) Hud_Intermission('0 0 0', virtsize);
- }
-};
-
-//----------------------------------------------------------------------
-void(float vwidth, float vheight, float notmenu) CSQC_UpdateView =
-{
- local vector ssize;
- ssize_x = vwidth; ssize_y = vheight; ssize_z = 0;
-
- // Is the CSQC functionality enabled/disabled?
- nocsqc = cvar("cl_nocsqc");
-
- clearscene();
- addentities(MASK_ENGINE|MASK_VIEWMODEL);
- setproperty(VF_MIN, '0 0');
- setproperty(VF_SIZE, ssize);
- // If hud is disabled, draw engine hud instead
- setproperty(VF_DRAWENGINESBAR, nocsqc);
- setproperty(VF_DRAWCROSSHAIR, TRUE);
- renderscene();
-
- // Revert back to using engine HUD?
- if (nocsqc > 0) return;
-
- // Required for DP engine
- if (detectDP == TRUE) {
- ssize_x = cvar("vid_conwidth");
- ssize_y = cvar("vid_conheight");
- }
-
- // Used on intermission screen later
- if (!intermission) intermission_time = time;
- // Read deathmatch variable and create csprogs coop variable
- // csprogs has no knowledge of the coop variable
- deathmatch = stof(serverkey("deathmatch"));
- coop = !deathmatch && maxclients > 1;
-
- // Draw the HUDs and scoreboards
- CSQC_DrawHud(ssize, sb_showscores);
- CSQC_DrawScores(ssize, sb_showscores);
-};
-
-//----------------------------------------------------------------------
-// Registers HUD gfx images (all setup in string arrays)
-//----------------------------------------------------------------------
-void(float apilevel, string enginename, float engineversion) CSQC_Init =
-{
- local float i, wadonly;
-
- // Is the CSQC functionality enabled/disabled?
- nocsqc = cvar("cl_nocsqc");
- // Revert back to using engine HUD?
- if (nocsqc > 0) return;
-
- // Send ping back to server that CSQC client is alive
- // This can be used on the server side to detect CSQC
- // and change functions for new features
- localcmd(strcat("cmd ", CSQC_PING, "\n"));
-
- // precache from gfx.wad ONLY!?!
- wadonly = TRUE;
-
- // Cache all string tables
- for (i = 0; i < 14; i++) {
- // HUD background images (320 wide+)
- if (i < backgrd.length) precache_pic(backgrd[i], wadonly);
- // Large 24x24 brown/red numbers
- if (i < number.length) {
- precache_pic(number[i], wadonly);
- precache_pic(anumber[i], wadonly);
- }
- // Large 24x24 extra font characters (intermission)
- if (i < extrachar.length) precache_pic(extrachar[i], wadonly);
- // Large 24x24 player face
- if (i < facetab.length) precache_pic(facetab[i], wadonly);
- // Large 24x24 icons
- if (i < sbitems.length) precache_pic(sbitems[i], wadonly);
- // Small 16x16 icons
- if (i < ibitems.length) precache_pic(ibitems[i], wadonly);
- // Special 8x16 runes
- if (i < ibrunes.length) precache_pic(ibrunes[i], wadonly);
- // All weapon setups (on/off/flashing)
- if (i < wpnnames.length) {
- precache_pic(strcat(wpnselect[0], wpnnames[i]),wadonly);
- precache_pic(strcat(wpnselect[1], wpnnames[i]),wadonly);
- precache_pic(strcat(wpnflash[0], wpnnames[i]), wadonly);
- precache_pic(strcat(wpnflash[1], wpnnames[i]), wadonly);
- precache_pic(strcat(wpnflash[2], wpnnames[i]), wadonly);
- precache_pic(strcat(wpnflash[3], wpnnames[i]), wadonly);
- precache_pic(strcat(wpnflash[4], wpnnames[i]), wadonly);
- }
- }
-};
-
-//----------------------------------------------------------------------
-// Wrapper for CSQC_Init to try and detect DP engine
-//----------------------------------------------------------------------
-__wrap void(float apilevel, string enginename, float engineversion) CSQC_Init =
-{
- // Try to detect DP engine (needed for CSQC_UpdateView later)
- if (!apilevel && !enginename && !engineversion) detectDP = TRUE;
- // Execute previous CSQC_Init function
- prior(apilevel, enginename, engineversion);
-
- registercommand("+showscores");
- registercommand("+showscores");
- registercommand("+showteamscores");
- registercommand("+showteamscores");
-};
-
-//----------------------------------------------------------------------
-// Wrapper for CSQC_ConsoleCommand to show different scoreboards
-//----------------------------------------------------------------------
-__wrap float(string str) CSQC_ConsoleCommand =
-{
- if (prior(str))
- return TRUE;
- string c = argv(0);
- if (c == "+showscores")
- sb_showscores |= 1;
- else if (c == "-showscores")
- sb_showscores &~= 1;
- else if (c == "+showteamscores")
- sb_showscores |= 2;
- else if (c == "-showteamscores")
- sb_showscores &~= 2;
- else return FALSE;
- return TRUE;
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/csqc/csqc_progs.src

diff --git a/qc-server/csqc/csqc_progs.src b/qc-server/csqc/csqc_progs.src
deleted file mode 100644
index d23fe5d..0000000
--- a/qc-server/csqc/csqc_progs.src
+++ /dev/null
@@ -1,7 +0,0 @@
-../../csprogs.dat
-
-csqc_fteopts.qc
-csqc_defsclient.qc
-csqc_defs.qc
-// didn't import csqc_hudad.qc
-csqc_hudvanilla.qc

Return to the top of this page or return to the overview of this repo.

Diff qc-server/custom_mdls.qc

diff --git a/qc-server/custom_mdls.qc b/qc-server/custom_mdls.qc
deleted file mode 100644
index 266aa92..0000000
--- a/qc-server/custom_mdls.qc
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
-
-========================================================================
-
-MAPPER-SETTABLE CUSTOM MODELS FOR MONSTERS
-
-========================================================================
-*/
-
-/*
-================
-precache_model_custom
-================
-*/
-void(.string mdl_field, string default_file) precache_model_custom =
-{
- if (self.mdl_field != "")
- precache_model (self.mdl_field);
- else
- precache_model (default_file);
-};
-
-
-void(string default_file) precache_head_model = { precache_model_custom (mdl_head, default_file); };
-void(string default_file) precache_body_model = { precache_model_custom (mdl_body, default_file); };
-void(string default_file) precache_proj_model = { precache_model_custom (mdl_proj, default_file); };
-void(string default_file) precache_gib1 = { precache_model_custom (mdl_gib1, default_file); };
-void(string default_file) precache_gib2 = { precache_model_custom (mdl_gib2, default_file); };
-void(string default_file) precache_gib3 = { precache_model_custom (mdl_gib3, default_file); };
-
-
-/*
-================
-precache_model2_custom
-================
-*/
-void(.string mdl_field, string default_file) precache_model2_custom =
-{
- if (self.mdl_field != "")
- precache_model2 (self.mdl_field);
- else
- precache_model2 (default_file);
-};
-
-
-void(string default_file) precache_head_model2 = { precache_model2_custom (mdl_head, default_file); };
-void(string default_file) precache_body_model2 = { precache_model2_custom (mdl_body, default_file); };
-void(string default_file) precache_proj_model2 = { precache_model2_custom (mdl_proj, default_file); };
-void(string default_file) precache_exproj_model2 = { precache_model2_custom (mdl_exproj, default_file); };
-
-
-/*
-================
-model_custom
-================
-*/
-void(.string mdl_field, string default_file) model_custom =
-{
- if (self.mdl_field != "")
- {
- setmodel (self, self.mdl_field);
- // dprint("CUSTOM MODEL LOADED\n");
- }
- else
- setmodel (self, default_file);
-};
-
-void(string default_file) body_model = { model_custom (mdl_body, default_file); };
-// void(string default_file) head_model = { model_custom (mdl_head, default_file); };
-void(string default_file) proj_model = { model_custom (mdl_proj, default_file); };

Return to the top of this page or return to the overview of this repo.

Diff qc-server/custom_snd.qc

diff --git a/qc-server/custom_snd.qc b/qc-server/custom_snd.qc
deleted file mode 100644
index 920d093..0000000
--- a/qc-server/custom_snd.qc
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
-========================================================================
-
-MAPPER-SETTABLE CUSTOM SOUND EFFECTS FOR MONSTERS
-
-========================================================================
-
-
-This file was created for progs_dump by Ian "iw" Walshaw, January 2020.
-
-TODO: iw to add descriptive comments to this file.
-
-
-========================================================================
-*/
-
-
-/*
-================
-precache_sound_custom
-================
-*/
-void(.string snd_field, string default_file) precache_sound_custom =
-{
- if (self.snd_field != "")
- precache_sound (self.snd_field);
- else
- precache_sound (default_file);
-};
-
-
-void(string default_file) precache_sound_attack = { precache_sound_custom (snd_attack, default_file); };
-void(string default_file) precache_sound_death = { precache_sound_custom (snd_death, default_file); };
-void(string default_file) precache_sound_hit = { precache_sound_custom (snd_hit, default_file); };
-void(string default_file) precache_sound_idle = { precache_sound_custom (snd_idle, default_file); };
-void(string default_file) precache_sound_land = { precache_sound_custom (snd_land, default_file); };
-void(string default_file) precache_sound_misc = { precache_sound_custom (snd_misc, default_file); };
-void(string default_file) precache_sound_misc1 = { precache_sound_custom (snd_misc1, default_file); };
-void(string default_file) precache_sound_misc2 = { precache_sound_custom (snd_misc2, default_file); };
-void(string default_file) precache_sound_misc3 = { precache_sound_custom (snd_misc3, default_file); };
-void(string default_file) precache_sound_move = { precache_sound_custom (snd_move, default_file); };
-void(string default_file) precache_sound_pain = { precache_sound_custom (snd_pain, default_file); };
-void(string default_file) precache_sound_sight = { precache_sound_custom (snd_sight, default_file); };
-
-
-/*
-================
-precache_sound2_custom
-================
-*/
-void(.string snd_field, string default_file) precache_sound2_custom =
-{
- if (self.snd_field != "")
- precache_sound2 (self.snd_field);
- else
- precache_sound2 (default_file);
-};
-
-
-void(string default_file) precache_sound2_attack = { precache_sound2_custom (snd_attack, default_file); };
-void(string default_file) precache_sound2_death = { precache_sound2_custom (snd_death, default_file); };
-void(string default_file) precache_sound2_hit = { precache_sound2_custom (snd_hit, default_file); };
-void(string default_file) precache_sound2_idle = { precache_sound2_custom (snd_idle, default_file); };
-void(string default_file) precache_sound2_land = { precache_sound2_custom (snd_land, default_file); };
-void(string default_file) precache_sound2_misc = { precache_sound2_custom (snd_misc, default_file); };
-void(string default_file) precache_sound2_misc1 = { precache_sound2_custom (snd_misc1, default_file); };
-void(string default_file) precache_sound2_misc2 = { precache_sound2_custom (snd_misc2, default_file); };
-void(string default_file) precache_sound2_misc3 = { precache_sound2_custom (snd_misc3, default_file); };
-void(string default_file) precache_sound2_move = { precache_sound2_custom (snd_move, default_file); };
-void(string default_file) precache_sound2_pain = { precache_sound2_custom (snd_pain, default_file); };
-void(string default_file) precache_sound2_sight = { precache_sound2_custom (snd_sight, default_file); };
-
-
-/*
-================
-sound_custom
-================
-*/
-void(.string snd_field, entity e, float chan, string default_file,
- float vol, float atten) sound_custom =
-{
- if (e.snd_field != "")
- sound (e, chan, e.snd_field, vol, atten);
- else
- sound (e, chan, default_file, vol, atten);
-};
-
-
-void(entity e, float chan, string default_file, float vol, float atten) sound_attack = { sound_custom (snd_attack, e, chan, default_file, vol, atten); };
-void(entity e, float chan, string default_file, float vol, float atten) sound_death = { sound_custom (snd_death, e, chan, default_file, vol, atten); };
-void(entity e, float chan, string default_file, float vol, float atten) sound_hit = { sound_custom (snd_hit, e, chan, default_file, vol, atten); };
-void(entity e, float chan, string default_file, float vol, float atten) sound_idle = { sound_custom (snd_idle, e, chan, default_file, vol, atten); };
-void(entity e, float chan, string default_file, float vol, float atten) sound_land = { sound_custom (snd_land, e, chan, default_file, vol, atten); };
-void(entity e, float chan, string default_file, float vol, float atten) sound_misc = { sound_custom (snd_misc, e, chan, default_file, vol, atten); };
-void(entity e, float chan, string default_file, float vol, float atten) sound_misc1 = { sound_custom (snd_misc1, e, chan, default_file, vol, atten); };
-void(entity e, float chan, string default_file, float vol, float atten) sound_misc2 = { sound_custom (snd_misc2, e, chan, default_file, vol, atten); };
-void(entity e, float chan, string default_file, float vol, float atten) sound_misc3 = { sound_custom (snd_misc3, e, chan, default_file, vol, atten); };
-void(entity e, float chan, string default_file, float vol, float atten) sound_move = { sound_custom (snd_move, e, chan, default_file, vol, atten); };
-void(entity e, float chan, string default_file, float vol, float atten) sound_pain = { sound_custom (snd_pain, e, chan, default_file, vol, atten); };
-void(entity e, float chan, string default_file, float vol, float atten) sound_sight = { sound_custom (snd_sight, e, chan, default_file, vol, atten); };

Return to the top of this page or return to the overview of this repo.

Diff qc-server/cutscene.qc

diff --git a/qc-server/cutscene.qc b/qc-server/cutscene.qc
deleted file mode 100644
index bbc416c..0000000
--- a/qc-server/cutscene.qc
+++ /dev/null
@@ -1,939 +0,0 @@
-// Heavily modified for Drake.
-
-// player_run prototype is in proto.qc.
-void() DHM_CalcMoveDone;
-void() move_camera;
-//- - - - - - - - - - - - - - - - - - -
-// This resets air capacity and drowning damage.
-void(entity ent) more_air =
-{
-//- - - - - - - - -
- ent.air_finished = time + 12;
- ent.dmg = 2; // initial water damage
-};
-
-// ============================================ //
-// | Movie camera trigger - dhm | //
-// ============================================ //
-
-
-// 'o' should be other, who in turn is the player who touched camera trigger.
-void(entity o) spawn_dummy =
-{
-local entity s;
-
- s = spawn ();
-// s.origin = o.origin;
- s.velocity = o.velocity;
- s.angles = o.angles;
- s.health = o.health;
- s.weapon = o.weapon;
- s.classname = "dummy";
- s.movetype = MOVETYPE_NONE;
- s.solid = SOLID_NOT;
- setmodel (s, "progs/player.mdl"); // set temp player model in case camera can see -- dumptruck_ds
- if (s.weapon == IT_AXE)
- {
- s.frame = 0; // standing there with axe -- dumptruck_ds
- }
- else
- s.frame = 12; // standing there with gun -- dumptruck_ds
- s.weaponmodel = o.weaponmodel;
- s.flags = o.flags;
- s.effects = o.effects;
- s.items = o.items;
- s.enemy = o.enemy; // PM: o.enemy changed to camera later.
-
-// Save powerups
-// Pentagram
- if (o.invincible_finished)
- { s.invincible_finished = o.invincible_finished - time;
- if (o.invincible_time)
- s.invincible_time = o.invincible_time - time;
- }
- else
- s.invincible_finished = s.invincible_time = 0;
-// Ring of Shadows
- if (o.invisible_finished)
- { s.invisible_finished = o.invisible_finished - time;
- if (o.invisible_time)
- s.invisible_time = o.invisible_time - time;
- }
- else
- s.invisible_finished = s.invisible_time = 0;
-// Quad Damage
- if (o.super_damage_finished)
- { s.super_damage_finished = o.super_damage_finished - time;
- if (o.super_time)
- s.super_time = o.super_time - time;
- }
- else
- s.super_damage_finished = s.super_time = 0;
-// Biosuit
- if (o.radsuit_finished)
- { s.radsuit_finished = o.radsuit_finished - time;
- if (o.rad_time)
- s.rad_time = o.rad_time - time;
- }
- else
- s.radsuit_finished = s.rad_time = 0;
-// // Empathy Shields
-// if (o.thorns_finished)
-// { s.thorns_finished = o.thorns_finished - time;
-// if (o.thorns_time)
-// s.thorns_time = o.thorns_time - time;
-// }
-// else
-// s.thorns_finished = s.thorns_time = 0;
-// // Cross of Deflection
-// if (o.cross_finished)
-// { s.cross_finished = o.cross_finished - time;
-// if (o.cross_time)
-// s.cross_time = o.cross_time - time;
-// }
-// else
-// s.cross_finished = s.cross_time = 0;
-// // Dark Angel Wings
-// if (o.wing_finished)
-// { s.wing_finished = o.wing_finished - time;
-// if (o.wing_time)
-// s.wing_time = o.wing_time - time;
-// }
-// else
-// s.wing_finished = s.wing_time = 0;
-// // Amulet of Reflection
-// if (o.mirror_finished)
-// { s.mirror_finished = o.mirror_finished - time;
-// if (o.mirror_time)
-// s.mirror_time = o.mirror_time - time;
-// }
-// else
-// s.mirror_finished = s.mirror_time = 0;
-// // Tome of Power
-// if (o.tome_finished)
-// { s.tome_finished = o.tome_finished - time;
-// if (o.tome_time)
-// s.tome_time = o.tome_time - time;
-// }
-// else
-// s.tome_finished = s.tome_time = 0;
-
-// FIXME: Called during touch func, don't set directly?
- setorigin (s, o.origin);
-
-// PM: Link player to dummy, for now.
- if (o) //.classname == "player")
- if (!o.trigger_field)
- o.trigger_field = s;
-};
-
-// PM: Removed 'name_player'; no longer needed.
-
-void() go_back =
-{
-local entity t, c, cvars, old;
-local string val;
-
- t = find (world, classname, "dummy");
- if (!t)
- objerror ("couldn't find dummy");
- t.solid = SOLID_NOT; // So player won't bounce back.
- setmodel (t, ""); // remove temp player model upon return -- dumptruck_ds
-
- c = find (world, classname, "camera");
- if (!c)
- objerror ("couldn't find camera");
-
- c.oldorigin = t.origin; // So player won't bounce back to cam.
-
-// FIXME: Check the new vars.
- setorigin (c, t.origin);
- c.velocity = t.velocity;
- c.view_ofs = '0 0 22'; // PM: Morph should take care of itself.
- c.angles_x = t.angles_x;
- c.angles_y = t.angles_y;
- c.angles_z = 0;
- c.health = t.health;
- c.weapon = t.weapon;
- c.weaponframe = 0;
- c.weaponmodel = t.weaponmodel;
- c.flags = t.flags;
- c.effects = t.effects;
- c.items = t.items;
- c.enemy = t.enemy; // PM: Restore client's original enemy.
-
-// Restore powerups
- if (t.invincible_finished)
- { c.invincible_finished = time + t.invincible_finished;
- if (t.invincible_time)
- c.invincible_time = time + t.invincible_time;
- }
- if (t.invisible_finished)
- { c.invisible_finished = time + t.invisible_finished;
- if (t.invisible_time)
- c.invisible_time = time + t.invisible_time;
- }
- if (t.super_damage_finished)
- { c.super_damage_finished = time + t.super_damage_finished;
- if (t.super_time)
- c.super_time = time + t.super_time;
- }
- if (t.radsuit_finished)
- { c.radsuit_finished = time + t.radsuit_finished;
- if (t.rad_time)
- c.rad_time = time + t.rad_time;
- }
- // if (t.thorns_finished)
- // { c.thorns_finished = time + t.thorns_finished;
- // if (t.thorns_time)
- // c.thorns_time = time + t.thorns_time;
- // }
- // if (t.cross_finished)
- // { c.cross_finished = time + t.cross_finished;
- // if (t.cross_time)
- // c.cross_time = time + t.cross_time;
- // }
- // if (t.wing_finished)
- // { c.wing_finished = time + t.wing_finished;
- // if (t.wing_time)
- // c.wing_time = time + t.wing_time;
- // }
- // if (t.mirror_finished)
- // { c.mirror_finished = time + t.mirror_finished;
- // if (t.mirror_time)
- // c.mirror_time = time + t.mirror_time;
- // }
- // if (t.tome_finished)
- // { c.tome_finished = time + t.tome_finished;
- // if (t.tome_time)
- // c.tome_time = time + t.tome_time;
- // }
-
- c.fixangle = 1; // turn this way immediately
- c.takedamage = DAMAGE_AIM;
- c.solid = SOLID_SLIDEBOX;
- c.movetype = MOVETYPE_WALK;
- c.nextthink = time;
- c.think = player_run; // PM: Reset player anim frames.
- more_air (c); // No gasping from you!
-
- // c.xfl = c.xfl | XFL_ITEMS; // Restore pickup again. Drake -- dumptruck_ds
-
-// Yes, you CAN change the classname here since the 'find' command already
-// found the camera. It is best to change the classname back to player now.
- c.classname = "player";
- cutscene = 0; // Cutscene OFF
- stuffcmd (c, "-forward\n");
- stuffcmd (c, "-strafe\n");
-
-// Look for any CVARSET entities to restore old cvars that
-// were changed for the cut-scene
- if (c.ideal_yaw == -1)
- {
- cvars = find(world, classname, "cvar_done");
- while (cvars) // != world)
- {
- if (!cvars.message)
- cvars.message = cvars.model;
- cvar_set (cvars.netname, cvars.script);
- old = cvars;
- cvars = find (cvars, classname, "cvar_done");
- remove (old);
- }
- c.ideal_yaw = 0;
- }
-
- val = ftos (c.cnt);
- cvar_set ("viewsize", val); //restore old viewsize
-// stuffcmd (c, "sizedown\nsizeup\n"); //hack-fix for GLquake
-
- t.nextthink = time + 0.1;
- t.think = SUB_Remove;
- remove (self);
-};
-
-//===============
-// This routine short-circuits player turning and movement while in camera
-// mode. self.oldorigin is used as self.angles, and self.mangle is used as
-// self.velocity. This allows me to compute these figures in code, and
-// overwrite what the game thinks they should be. Called from 'client.qc'.
-//===============
-void() look_ahead =
-{
-// PM: Vision style cam sets angles to mangle and velocity to zeroes.
-// The camera in vision mode cutscenes cannot move.
-// if (vision)
-// {
-// self.angles = self.enemy.mangle;
-// self.fixangle = 1;
-// // self.nextthink removed since it's done in PlayerPreThink.
-// return;
-// }
-
-// PM: Using Zerstorer style cutscene code...
- self.angles = self.oldorigin;
- self.velocity = self.mangle;
- self.fixangle = 1;
- cvar_set ("viewsize", "120"); //keep screen maximized
-
- if (self.delay == 0)
- {
- local vector looky;
-
- looky_x = self.movedir_x - self.origin_x;
- looky_y = self.movedir_y - self.origin_y;
- looky_z = self.origin_z - self.movedir_z;
- self.oldorigin = vectoangles (looky);
- }
-};
-
-// This is a modified SUB_CalcMove routine.
-void(vector tdest, float tspeed, entity cam) DHM_CalcMove =
-{
-local vector vdestdelta;
-local float len, traveltime;
-
- self.finaldest = tdest;
- self.think = DHM_CalcMoveDone;
-
- if (tdest == cam.origin)
- {
- cam.velocity = cam.mangle = '0 0 0';
- self.nextthink = time + 0.01;
- return;
- }
-
-// set destdelta to the vector needed to move
- vdestdelta = tdest - cam.origin;
-
-// calculate length of vector
- len = vlen (vdestdelta);
-
-// divide by speed to get time to reach dest
- traveltime = len / tspeed;
-
- if (traveltime < 0.1)
- {
- cam.velocity = cam.mangle = '0 0 0';
- self.nextthink = time + 0.01;
- return;
- }
-
-// set nextthink to trigger a think when dest is reached
- self.nextthink = time + traveltime;
-
-// scale the destdelta vector by the time spent traveling to get velocity
- cam.velocity = cam.mangle = vdestdelta * (1/traveltime);
-};
-
-//- - - - - - - - -
-// Zerstorer-only cutscene code.
-void() wait_camera =
-{
- if (!self.wait)
- {move_camera (); return;}
-
- self.nextthink = time + self.wait;
- self.think = move_camera;
-};
-
-//============
-// After moving, set origin to exact final destination
-//============
-void() DHM_CalcMoveDone =
-{
- if (!cutscene) // Old check: if (self.enemy.classname != "camera")
- {remove (self); return;}
-
- setorigin(self.enemy, self.finaldest);
- self.enemy.velocity = self.enemy.mangle = '0 0 0';
-
- if (self.cnt == -1)
- {remove (self); return;}
-
- self.nextthink = time + 0.01;
- self.think = wait_camera;
-};
-
-void() move_camera =
-{
-local entity cpt, fpt;
-local vector looky;
-
- if (!cutscene) // Old check: if (self.enemy.classname != "camera")
- {remove (self); return;}
-
- cpt = find (world, targetname, self.target);
- if (!cpt.target) //if this is the end of the line, stop camera
- {
- self.think = SUB_Null;
- self.enemy.velocity = '0 0 0';
- self.enemy.mangle = '0 0 0'; //mangle == velocity in cut-scene
- DHM_CalcMoveDone();
- self.cnt = -1; // remove control entity in DHM_CalcMoveDone
- //return;
- }
- if (cpt.focal_point) //is there a new focal point?
- {
- fpt = find (world, targetname, cpt.focal_point);
- if (!fpt)
- objerror("Couldn't find new focal point!");
-
- self.enemy.movedir = fpt.origin;
- looky_x = self.enemy.movedir_x - self.enemy.origin_x;
- looky_y = self.enemy.movedir_y - self.enemy.origin_y;
- looky_z = self.enemy.origin_z - self.enemy.movedir_z;
- self.enemy.oldorigin = vectoangles (looky);
- self.enemy.angles = self.enemy.oldorigin; //oldorigin == angles in CS
- }
-// Check for auto-focus or still camera angle
- if (cpt.delay)
- self.enemy.delay = cpt.delay;
- else
- self.enemy.delay = 0;
-
- self.target = cpt.target;
- self.wait = cpt.wait;
- if(cpt.speed)
- self.speed = cpt.speed;
- DHM_CalcMove (cpt.origin, self.speed, self.enemy);
-};
-//- - - - - - - - -
-
-void() go_camera =
-{
-local vector looky;
-
- cutscene = 1; // Cutscene ON.
-
-// Don't let player-turned-camera pick up items.
- // self.xfl = self.xfl - (self.xfl & XFL_ITEMS);
-
-// Change the player into a camera
-// PM: Ok, you win! Too much stuff checks for 'player', so use 'camera'
-// to be safe. Just make sure alignment stuff doesn't break, namely
-// friendly monsters getting mad at a player when they shouldn't.
- self.classname = "camera";
- self.velocity = '0 0 0';
- self.view_ofs = '0 0 0';
- // PM: Change the modelindex to a non-zero number that points to an
- // invisible model so that the camera entity is invisible if seen
- // because of reflective textures or builtin chasecam (chase_active 1).
- // Requires my custom invisible model (which is a sprite).
- self.modelindex = mindex_inviso;
- // Turn off glowing effects.
- self.effects = 0;
- self.items = 0;
- self.weaponmodel = ""; // Remove weapon from the screen.
-//- - - - - - - - - - - - - - - - - - -
-// if (vision)
-// {
-// self.angles = self.enemy.mangle;
-// self.fixangle = 1;
-// self.movetype = MOVETYPE_NONE;
-// self.takedamage = DAMAGE_NO;
-// self.solid = SOLID_NOT;
-// self.weaponmodel= "";
-
- // Removed thinking since it's done by PlayerPreThink->Cutscene_Think.
-// }
-//- - - - - - - - - - - - - - - - - - -
-// else // Default to Zerstorer style cutscene.
- {
- looky_x = self.movedir_x - self.enemy.origin_x;
- looky_y = self.movedir_y - self.enemy.origin_y;
- looky_z = self.enemy.origin_z - self.movedir_z;
- self.oldorigin = vectoangles (looky);
- self.angles = self.oldorigin; //oldorigin == angles in CS
-
- // Check if camera is auto-focus or not
- if (self.enemy.delay)
- self.delay = self.enemy.delay;
- else
- self.delay = 0;
-
- self.velocity = self.mangle = '0 0 0';
-
- self.dmg = 0; // PM: Do we need this?
- self.fixangle = 1; // turn this way immediately
- self.movetype = MOVETYPE_NOCLIP;
- self.takedamage = DAMAGE_NO;
- // PM: Solid cannot be 0 or else camera can't trigger stuff by touch.
-
- // Spawn a control function to handle moving the camera
- if (self.enemy.target)
- {
- local entity control;
-
- control = spawn();
- control.classname = "camcontrol";
- control.enemy = self;
- control.target = self.enemy.target;
- control.speed = self.enemy.speed;
- control.nextthink = time + self.enemy.wait + 0.05;
- control.think = move_camera;
- }
- }
-
-// Setting script_count to 0 is what triggers the script to play,
-// It will then play the script number.
- if (!self.script)
- dprint ("trigger_camera needs a script number!");
- self.script_count = 0;
-
- self.cnt = cvar("viewsize");
- cvar_set ("viewsize", "120"); //Full screen
- // PM: Vision sets 'v_idlescale' for swaying screen. Not in Drake!
- stuffcmd (self, "sizedown\nsizeup\n"); //hack-fix for GLquake
- stuffcmd (self, "+strafe\n");
-
- setorigin (self, self.enemy.origin);
-
-//- - - - - - - - -
-// PM: Space invasion prevention.
-// Make the dummy solid to prevent monsters or other junk from occupying
-// the space where the player stood before the cutscene started.
-// After all, the player will be placed back when the cutscene ends,
-// and we don't want him stuck inside a monster or something.
-//
-// We need to wait until after the player becomes the camera, before we can
-// make the dummy solid. If we make the dummy solid as it spawned, the
-// player could get stuck inside the dummy (instead of moving) between
-// trigger activation and transformation to camera.
-//
-// In Vision code, player becomes camera a frame or so after trigger
-// activation. In Zer code, player becomes camera at the same time
-// the trigger activates.
-//
-// Note: If you still have trouble getting a Vision cutscene to work in a
-// certain level, move the following code to the top of 'look_ahead'.
-// Doing so would be less than ideal since the check would get called every
-// frame during the cutscene, instead of just once here.
-// The only level that still has problems with dummy made solid now
-// is 'vision.bsp', which has its own pak. Tronyn's maps, the levels
-// that really matter, have no problems.
-//- - - - - - - - -
-// 'self' is the player-turned-camera entity.
- // '!self.trigger_field' is the world, and its classname is worldspawn.
- if (self.trigger_field.classname == "dummy")
- {
- self.trigger_field.solid = SOLID_BBOX;
- setsize (self.trigger_field, self.mins, self.maxs);
-
- self.trigger_field = world; // Unlink now that it's done.
- }
-//- - - - - - - - -
-};
-
-// PM: Called from either touch or use.
-void(entity who) camera_activate =
-{
-// only activate for player, 1st time touched
- if (who.health <= 0)
- return;
- if (who.deadflag) // In case of Alien Quake facehugger kill.
- return;
- if (who.classname != "player")
- return;
-
-// You can't touch/use this again.
- self.touch = self.use = SUB_Null;
-
-// If player is on ground, take him off ground so no one gets confused
- who.flags = who.flags - (who.flags & FL_ONGROUND);
-
-// put a dummy where the player was
- spawn_dummy (who);
-
-// find camera
- local entity t;
-
- t = find (world, targetname, self.target);
-// if (vision)
-// {
-// if (!t)
-// objerror ("couldn't find target");
-// }
-// else
- {
- local entity fpt;
-
- while ((t != world) && (t.classname != "info_movie_camera"))
- t = find (t, targetname, self.target);
- if (!t)
- objerror ("couldn't find target");
-
- // find focal point
- fpt = find (world, targetname, self.focal_point);
- if (!fpt)
- objerror ("You must have a focal point!\n");
- else
- who.movedir = fpt.origin; //movedir used to calc focal dir
- }
-
-// Go to the camera - not in this function, because touch functions are
-// called while looping through c code, and you don't want to move the
-// player, or something like that?
- who.enemy = t; //save camera position, etc.
- who.script = self.script; //save script number
- who.script_delay = self.script_delay; //save delay for page 1
-
-// if (vision)
-// { // PM: Don't try instant start because that breaks soeexit.bsp.
-// who.nextthink = time + 0.05;
-// who.think = go_camera;
-// }
-// else
- SUB_Think (who, go_camera);
-
- activator = self;
- SUB_UseTargets ();
-
-//Remove the trigger_camera from level
- self.nextthink = time + 0.1;
- self.think = SUB_Remove;
-};
-
-void() camera_touch =
-{
- if (self.targetname)
- if (self.nextthink < time)
- return;
- if (self.cnt == -1)
- return;
- camera_activate (other);
-};
-void() camera_point_touch = {camera_activate (other);};
-
-//============
-// --> QUAKED info_movie_camera (.5 .5 .5) (-8 -8 -8) (8 8 32) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-// This is the destination marker for a camera. It should have a "targetname"
-// field with the same value as a camera-trigger's "target" field.
-//============
-void() imc_touch =
-{
-local string temps;
-
- if (other.classname != "camera")
- return;
- temps = self.target;
- self.target = self.message;
- SUB_UseTargets();
- self.target = temps;
- if (self.cnt)
- return;
-
- self.think = SUB_Remove;
- self.nextthink = time + 10;
- self.solid = SOLID_NOT;
-};
-
-void() info_movie_camera =
-{
-// this does nothing, just serves as a target spot
-// if (vision)
-// return;
-
-// ...more than a spot in Zer mode.
- //self.use = SUB_Null;
- self.solid = SOLID_TRIGGER;
- setorigin(self, self.origin);
- setsize(self, '-8 -8 -8', '8 8 8');
- self.touch = imc_touch;
-};
-
-void() camera_use =
-{
- local entity pl;
-
- pl = find(world, classname, "player"); // Only one in single-player.
- camera_activate (pl);
-
-// Old code.
-// self.nextthink = time + 100000;
-// force_retouch = 2; // make sure even still objects get hit
-// self.think = SUB_Null;
-};
-
-//- - - - - - - - -
-// Zerstorer-only cutscene code.
-void() gocam_use =
-{
-local entity control, temp;
-
- control = find(world, classname, "camcontrol");
- if (control == world)
- dprint ("Can't find camcontrol!\n");
-
- temp = self;
- self = control;
- DHM_CalcMoveDone ();
- self = temp;
- self.nextthink = time + 0.1;
- self.think = SUB_Remove;
-};
-
-void() trigger_gocamera = {self.use = gocam_use;};
-
-/*QUAKED info_focal_point (.5 .5 .5) (-8 -8 -8) (8 8 32) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-This is the point that the camera will face. It should have a "targetname"
-field with the same value as a camera-trigger's "focal_point" field.
-*/
-// PM: This entity is kept only for map compatibility reasons.
-// Otherwise, this entity is redundant. Use 'info_notnull' instead.
-void() info_focal_point = {}; // just holds a spot for the focal point.
-
-void(float pt) trigger_camera_spawn =
-{
-// Update: Don't let dmsp muck up cutscenes and vice versa.
- if (deathmatch || coop)
- {remove (self); return;} // PM: Fix -- abort if removed.
-
- if (pt)
- { // The new way, this is for you Tronyn.
- InitPointTrigger ();
- if (!self.targetname)
- self.touch = camera_point_touch;
- }
- else
- { // The old way...
- InitTrigger ();
- // PM: Must always allow touch because some old maps need it.
- self.touch = camera_touch;
- }
- // find the destination
- if (!self.target)
- objerror ("Camera trigger with no target");
- self.use = camera_use;
-};
-
-/*QUAKED trigger_camera (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-A player touching this will be transported to the corresponding
-info_movie_camera entity. You must set the "target" field, and put a
-info_movie_camera with a "targetname" field that matches. The "script"
-key gives a starting script number, and the "script_delay" key is the
-amount of time(seconds) to stay on the first script page.
-
-If the trigger_camera has a targetname, it will only enter camera mode
-after it has been fired.
-*/
-void() trigger_camera = {trigger_camera_spawn (FALSE);};
-
-/*QUAKED trigger_camera_point (.5 .5 .5) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-When this is triggered the player will be transported to the corresponding
-info_movie_camera entity. You must set the "target" field, and put a
-info_movie_camera with a "targetname" field that matches. The "script"
-key gives a starting script number, and the "script_delay" key is the
-amount of time(seconds) to stay on the first script page.
-*/
-void() trigger_camera_point = {trigger_camera_spawn (TRUE);};
-
-//----------------------------------
-// Scripting function - dhm
-//----------------------------------
-// The original timing idea for scripts was inspired by Zoid. Study the
-// code for Zoid's CTF, it is an excellent example of good Quake-C coding.
-// Also look at all of Quake Command's stuff. Wedge rules.
-//----------------------------------
-// Script_play is called from PlayerPreThink()
-// 'self' is the player (camera)
-//----------------------------------
-void() Script_play =
-{
-local entity scrpt;
-
- scrpt = find (world, script_num, self.script);
- if (!scrpt)
- dprint ("Error: script not found!");
-
- // If script has a target, trigger it once.
-// if (!vision)
- if (scrpt.target)
- {
- local entity temp;
-
- temp = self;
- self = scrpt;
- SUB_UseTargets ();
- self.target = world.null_string;
- self = temp;
- }
-
- self.script_delay = scrpt.script_delay;
- self.script_time = time + 1;
- self.script_count = self.script_count + 1;
- centerprint (self, scrpt.message);
-
- if (self.script_count == self.script_delay)
- {
- self.script = scrpt.next_script;
- if (self.script != "0")
- self.script_count = 0;
- else
- {
- scrpt.nextthink = time + 3;
- scrpt.classname = "going_back";
- scrpt.think = go_back;
- }
- }
-};
-
-
-//- - - - - - - - -
-// PM: Player thinking during a cutscene. Called by 'PlayerPreThink'.
-void() Cutscene_Think =
-{
- /* --------------------------------------------
- If we are in camera mode, play the script.
- -------------------------------------------- */
- // PM: Allow player to stop cutscene on any map.
- if (self.impulse)
- if (self.script_count != 1000000)
- {
- local entity goback; // PM: dhm's cutscene code.
-
- self.script_count = 1000000;
- // if (world.model == "maps/soeexit.bsp")
- // { // Hack: Jump directly to intermission/credits.
- // NextLevel ();
- // return;
- // }
- // If cut-scene has ended, and user tries to exit, don't
- // spawn a second go_back control entity.
- goback = find(world, classname, "going_back");
- if (!goback)
- {
- sprint(self, "...\n");
- goback = spawn();
- goback.nextthink = time + 1.5;
- goback.think = go_back;
- self.impulse = 0; // PM: New -- just kill cutscene.
- }
- }
-
- if (cutscene) // PM: Vision didn't look_ahead here, but do it
- look_ahead (); // anyway instead of thinking about it.
- if (self.script_count < self.script_delay)
- if (self.script_time < time)
- Script_play ();
-};
-
-void() script_sound_play =
-{
- if (self.noise != "")
- sound (other, CHAN_AUTO, self.noise, 1, ATTN_NONE);
- else
- sound (other, CHAN_AUTO, self.noise1, 1, ATTN_NONE);
-};
-//- - - - - - - - -
-//============
-// --> QUAKED info_script_sound (.5 .5 .5) (-8 -8 -8) (8 8 32) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-// This is the noise player for a script.
-
-void() info_script_sound =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
- //play all the sounds available for a normal trigger
- if (self.sounds == 0)
- {
- precache_sound ("misc/null.wav");
- self.noise = "misc/null.wav";
- }
- else if (self.sounds == 1)
- {
- precache_sound ("misc/secret.wav");
- self.noise = "misc/secret.wav";
- }
- else if (self.sounds == 2)
- {
- precache_sound ("misc/talk.wav");
- self.noise = "misc/talk.wav";
- }
- else if (self.sounds == 3)
- {
- precache_sound ("misc/trigger1.wav");
- self.noise = "misc/trigger1.wav";
- }
- else if (self.sounds == 4)
- {
- if (!self.noise1) //dumptruck_ds
- {
- objerror ("no soundfile set in noise1!\n");
- remove(self);
- return;
- }
- else
- precache_sound (self.noise1);
- self.noise = self.noise1;
- }
- self.use = script_sound_play;
-};
-
-//============
-// --> QUAKED info_script (.5 .5 .5) (-8 -8 -8) (8 8 32)
-// This is the destination marker for a script.
-// It should have a "script_num" field that signifies the script number, and
-// a "next_script" to signal the next script ("0" if this is the last page of
-// the script), a "script_delay" to signify how many seconds to display this
-// page, and of course a "message" field with the text to display.
-//
-// PM: Use 'info_notnull' instead.
-//============
-void() info_script =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-};
-
-
-// ------------------------------ //
-// | trigger_cvarset | //
-// ------------------------------ //
-//============
-// --> QUAKED trigger_cvarset (.5 .5 .5) (-8 -8 -8) (8 8 32)
-// You can set any CVAR on the server with this trigger. Put the CVAR name
-// in "netname" and put the value in "message". Useful CVAR's are
-// sv_gravity, sv_friction, fov, and v_idlescale.
-//============
-void() change_cvar =
-{
-local entity check;
-
- cvar_set (self.netname, self.message);
- bprint("\n\n\n\n");
-
- self.classname = "cvar_done";
- check = find(world, classname, "player");
- if (!check)
- check = find(world, classname, "camera");
-
- check.ideal_yaw = -1;
-
- self.nextthink = time + 0.02;
- self.think = SUB_UseTargets;
-};
-
-void() cvarset_touch =
-{
- if (self.cnt > time || other.health <= 0 || other.classname != "player")
- return;
-
- change_cvar ();
-};
-
-void() trigger_cvarset =
-{
- if (deathmatch || coop)
- remove (self);
-
- InitTrigger ();
- self.use = change_cvar;
-};
-
-
-// PM: Removed gravity and earthquake entities.
-
-//===========================/ END OF FILE /===========================//

Return to the top of this page or return to the overview of this repo.

Diff qc-server/defs_builtins.qc

diff --git a/qc-server/defs_builtins.qc b/qc-server/defs_builtins.qc
deleted file mode 100644
index e220cfb..0000000
--- a/qc-server/defs_builtins.qc
+++ /dev/null
@@ -1,223 +0,0 @@
-/*==============================================================================
- BUILTIN FUNCTIONS
-==============================================================================*/
-
-void(vector ang) makevectors = #1; // sets v_forward, etc globals
-void(entity e, vector o) setorigin = #2;
-void(entity e, string m) setmodel = #3; // set movetype and solid first
-void(entity e, vector min, vector max) setsize = #4;
- // #5 was removed
-void() break = #6;
-float() random = #7; // returns 0 - 1
-void(entity e, float chan, string samp, float vol, float atten) sound = #8;
-vector(vector v) normalize = #9;
-void(string e) error = #10;
-void(string e) objerror = #11;
-float(vector v) vlen = #12;
-float(vector v) vectoyaw = #13;
-entity() spawn = #14;
-void(entity e) remove = #15;
-
-// sets trace_* globals
-// nomonsters can be:
-// An entity will also be ignored for testing if forent == test,
-// forent->owner == test, or test->owner == forent
-// a forent of world is ignored
-void(vector v1, vector v2, float nomonsters, entity forent) traceline = #16;
-entity() checkclient = #17; // returns a client to look for
-entity(entity start, .string fld, string match) find = #18;
-string(string s) precache_sound = #19;
-string(string s) precache_model = #20;
-void(entity client, string s) stuffcmd = #21;
-entity(vector org, float rad) findradius = #22;
-void(string s) bprint = #23;
-void(entity client, string s) sprint = #24;
-void(string s) dprint = #25;
-string(float f) ftos = #26;
-string(vector v) vtos = #27;
-void() coredump = #28; // prints all edicts
-void() traceon = #29; // turns statment trace on
-void() traceoff = #30;
-void(entity e) eprint = #31; // prints an entire edict
-float(float yaw, float dist) walkmove = #32; // returns TRUE or FALSE
- // #33 was removed
-float() droptofloor = #34; // TRUE if landed on floor
-void(float style, string value) lightstyle = #35;
-float(float v) rint = #36; // round to nearest int
-float(float v) floor = #37; // largest integer <= v
-float(float v) ceil = #38; // smallest integer >= v
- // #39 was removed
-float(entity e) checkbottom = #40; // true if self is on ground
-float(vector v) pointcontents = #41; // returns a CONTENT_*
- // #42 was removed
-float(float f) fabs = #43;
-vector(entity e, float speed) aim = #44;// returns the shooting vector
-float(string s) cvar = #45; // return cvar.value
-void(string s) localcmd = #46; // put string into local que
-entity(entity e) nextent = #47; // for looping through all ents
-void(vector o, vector d, float color, float count) particle = #48; // particles
-void() ChangeYaw = #49; // turn to ideal_yaw at yaw_speed
- // #50 was removed
-vector(vector v) vectoangles = #51;
-
-//======================================================================
-// direct client message generation
-//======================================================================
-void(float to, float f) WriteByte = #52;
-void(float to, float f) WriteChar = #53;
-void(float to, float f) WriteShort = #54;
-void(float to, float f) WriteLong = #55;
-void(float to, float f) WriteCoord = #56;
-void(float to, float f) WriteAngle = #57;
-void(float to, string s) WriteString = #58;
-void(float to, entity s) WriteEntity = #59;
-
-//======================================================================
-// broadcast client message generation
-//======================================================================
-// void(float f) bWriteByte = #59;
-// void(float f) bWriteChar = #60;
-// void(float f) bWriteShort = #61;
-// void(float f) bWriteLong = #62;
-// void(float f) bWriteCoord = #63;
-// void(float f) bWriteAngle = #64;
-// void(string s) bWriteString = #65;
-// void(entity e) bWriteEntity = #66;
-
-// Part of DP_QC_SINCOSSQRTPOW Forgive me father, for I have
-// trigonometry homework.
-// from fteextensions.qc -- CEV
-float(float angle) sin = #60;
-// Part of DP_QC_SINCOSSQRTPOW
-float(float angle) cos = #61;
-// Part of DP_QC_SINCOSSQRTPOW
-float(float value) sqrt = #62;
-
-void(float step) movetogoal = #67;
-string(string s) precache_file = #68; // no effect except for -copy
-void(entity e) makestatic = #69;
-void(string s) changelevel = #70;
- // #71 was removed
-void(string var, string val) cvar_set = #72; // sets cvar.value
-
-//======================================================================
-// Centerprint
-//
-// The following function definitions allow the engine's builtin
-// centerprint function (builtin #73) to be called with different
-// numbers of string arguments. The string that will be printed is the
-// concatenation of the string arguments.
-//
-// These definitions work because builtin #73 is implemented in such
-// a way that it can accept multiple string arguments in this manner,
-// even though the original QuakeC code didn't take advantage of this
-// fact. A maximum of seven string arguments can be passed because
-// a function is limited to a total of eight arguments (and the first
-// argument is the client). Note that in the original engine, all of
-// the strings for a centerprint message are concatenated into a single
-// 256-char buffer, therefore excessively long messages should be
-// avoided. -- iw
-
-.float suppressCenterPrint;
-
-void(entity client, string s1) centerprint_builtin = #73;
-void(entity client, string s1, string s2) centerprint_builtin2 = #73;
-void(entity client, string s1, string s2, string s3) centerprint_builtin3 = #73;
-void(entity client, string s1, string s2, string s3, string s4)
- centerprint_builtin4 = #73;
-void(entity client, string s1, string s2, string s3, string s4, string s5)
- centerprint_builtin5 = #73;
-void(entity client, string s1, string s2, string s3, string s4, string s5,
- string s6) centerprint_builtin6 = #73;
-void(entity client, string s1, string s2, string s3, string s4, string s5,
- string s6, string s7) centerprint_builtin7 = #73;
-
-void(entity client, string s1) centerprint =
-{
- // Is the centerprint message being used by something else?
- if (!client.suppressCenterPrint)
- {
- centerprint_builtin(client, s1);
- }
- else
- {
- // Send message to client console instead
- sprint(client, "(centerprint) ");
- sprint(client, s1);
- sprint(client, "\n");
- }
-}
-
-void(entity client, string s1, string s2) centerprint2 =
-{
- // Is the centerprint message being used by something else?
- if (!client.suppressCenterPrint)
- {
- centerprint_builtin2(client, s1, s2);
- }
- else
- {
- // Send message to client console instead
- sprint(client, "(centerprint) ");
- sprint(client, s1);
- sprint(client, s2);
- sprint(client, "\n");
- }
-}
-
-//======================================================================
-
-void(vector pos, string samp, float vol, float atten) ambientsound = #74;
-string(string s) precache_model2 = #75; // registered version only
-string(string s) precache_sound2 = #76; // registered version only
-string(string s) precache_file2 = #77; // registered version only
-void(entity e) setspawnparms = #78; // set parm1... to the values at
- // level start for coop respawn
-
-// Part of DP_QC_TRACEBOX Exactly like traceline, but a box instead
-// of a uselessly thin point. Acceptable sizes are limited by bsp format,
-// q1bsp has strict acceptable size values.
-// brought in from fteextensions.qc -- CEV
-void(vector start, vector mins, vector maxs, vector end, float nomonsters, entity ent) tracebox = #90;
-
-// Part of DP_QC_MINMAXBOUND Returns the lowest value of its arguments.
-float(float a, float b, ...) min = #94;
-// Part of DP_QC_MINMAXBOUND Returns the highest value of its arguments.
-float(float a, float b, ...) max = #95;
-// Part of DP_QC_MINMAXBOUND Returns val, unless minimum is higher,
-// or maximum is less.
-float(float minimum, float val, float maximum) bound = #96;
-// Part of DP_QC_SINCOSSQRTPOW
-float(float value, float exp) pow = #97;
-
-// for CSQC interaction -- CEV
-void(float num, float type, .__variant fld) clientstat = #232;
-
-// Triggers a touch events between self and every SOLID_TRIGGER entity
-// that it is in contact with. This should typically just be the
-// triggers touch functions. Also optionally updates the origin of the
-// moved entity.
-void(optional entity ent, optional vector neworigin) touchtriggers = #279;
-
-// Part of DP_SV_PRINT Unconditionally print on the local system's
-// console, even in ssqc (doesn't care about the value of the
-// developer cvar).
-void(string s, ...) print = #339;
-
-// Look up a key in the server's public serverinfo string
-string(string key) serverkey = #354;
-
-// from fteextensions.qc, all part of DP_QC_ASINACOSATANATAN2TAN -- CEV
-float(float s) asin = #471;
-float(float c) acos = #472;
-float(float t) atan = #473;
-float(float c, float s) atan2 = #474;
-// float(float a) tan = #475;
-
-// Part of DP_QC_SPRINTF
-string(string fmt, ...) sprintf = #627;
-
-// Part of FTE_QC_CROSSPRODUCT
-// Small helper function to calculate the crossproduct of two vectors.
-vector(vector v1, vector v2) crossproduct = #0:crossproduct;
-

Return to the top of this page or return to the overview of this repo.

Diff qc-server/defs_entvars.qc

diff --git a/qc-server/defs_entvars.qc b/qc-server/defs_entvars.qc
deleted file mode 100644
index 59f5812..0000000
--- a/qc-server/defs_entvars.qc
+++ /dev/null
@@ -1,115 +0,0 @@
-/*==============================================================================
- SOURCE FOR ENTVARS_T C STRUCTURE
-==============================================================================*/
-
-//======================================================================
-// system fields (*** = do not set in prog code, maintained by C code)
-//======================================================================
-.float modelindex; // *** model index in the precached list
-.vector absmin, absmax; // *** origin + mins / maxs
-
-.float ltime; // local time for entity
-.float movetype;
-.float solid;
-
-.vector origin; // ***
-.vector oldorigin; // ***
-.vector velocity;
-.vector angles;
-.vector avelocity;
-
-.vector punchangle; // temp angle adjust from dmg or recoil
-
-.string classname; // spawn function
-.string model;
-.float frame;
-.float skin;
-.float effects;
-
-.vector mins, maxs; // bounding box extents relative to org
-.vector size; // maxs - mins
-
-.void() touch;
-.void() use;
-.void() think;
-.void() blocked; // for doors or plats, called when
- // can't push other
-.float nextthink;
-.entity groundentity;
-
-// stats
-.float health;
-.float frags;
-.float weapon; // one of the IT_SHOTGUN, etc flags
-.string weaponmodel;
-.float weaponframe;
-.float currentammo;
-.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
-
-.float items; // bit flags
- // next three comments from AD
-.float takedamage; // Check by many functions for damage
-.entity chain; // Can be overwritten by find command
-.float deadflag; // Used by client functions
-
-.vector view_ofs; // add to origin to get eye point
-
-.float button0; // fire
-.float button1; // use
-.float button2; // jump
-
-.float impulse; // weapon changes
-
-.float fixangle; // Make an entity instantly turn
-.vector v_angle; // view / targeting angle for players
-.float idealpitch; // calc pitch angle for lookup up slopes
-
-.string netname;
-
-.entity enemy; // current entity enemy
-
-.float flags; // FL bitflag operations
-
-.float colormap;
-.float team;
-
-.float max_health; // players maximum health is stored here
-
-.float teleport_time; // teleport exit +back timer
-
-.float armortype; // save this fraction of incoming damage
-.float armorvalue;
-
-.float waterlevel; // 0: none, 1: feet, 2: waist, 3: eyes
-.float watertype; // a contents value
-
-.float ideal_yaw; // ideal direction for entity to face
-.float yaw_speed; // speed (in degrees) turning towards
-
-.entity aiment;
-
-.entity goalentity; // a movetarget or an enemy
-
-.float spawnflags; // mostly custom options for each entity
-
-.string target;
-.string targetname;
-
-// damage is accumulated through a frame. and sent as one single
-// message, so the super shotgun doesn't generate huge messages
-.float dmg_take;
-.float dmg_save;
-.entity dmg_inflictor;
-
-.entity owner; // who launched a missile
-.vector movedir; // mostly for doors, but also
- // used for waterjump
-.string message; // trigger messages
-
-.float sounds; // a cd track number or sound number
-
-.string noise, noise1, noise2, noise3; // contains names of wavs to play
-
-//================================================
-void end_sys_fields; // flag for structure dumping
-//================================================

Return to the top of this page or return to the overview of this repo.

Diff qc-server/defs_globalvars.qc

diff --git a/qc-server/defs_globalvars.qc b/qc-server/defs_globalvars.qc
deleted file mode 100644
index fac70c6..0000000
--- a/qc-server/defs_globalvars.qc
+++ /dev/null
@@ -1,86 +0,0 @@
-/*==============================================================================
- SOURCE FOR GLOBALVARS_T C STRUCTURE
-==============================================================================*/
-
-//======================================================================
-// system globals
-//======================================================================
-entity self;
-entity other;
-entity world;
-float time;
-float frametime;
-
-// force all entities to touch triggers next frame. this is needed because
-// non-moving things don't normally scan for triggers, and when a trigger is
-// created (like a teleport trigger), it needs to catch everything.
-// decremented each frame, so set to 2 to guarantee everything is touched.
-float force_retouch;
-
-string mapname;
-
-float deathmatch;
-float coop;
-float teamplay;
-
-float serverflags; // propagated from level to level, used
- // to keep track of completed episodes
-float total_secrets;
-float total_monsters;
-
-float found_secrets; // number of secrets found
-float killed_monsters; // number of monsters killed
-
-
-// spawnparms are used to encode information about clients across server
-// level changes
-float parm1, parm2, parm3, parm4, parm5, parm6, parm7, parm8,
- parm9, parm10, parm11, parm12, parm13, parm14, parm15, parm16;
-
-//======================================================================
-// global variables set by built in functions
-//======================================================================
-vector v_forward, v_up, v_right; // set by makevectors()
-
-// set by traceline / tracebox // comments below copied from AD
-float trace_allsolid; // both start and end were in a solid
-float trace_startsolid; // the start point was in a solid
-float trace_fraction; // how much of the vector (% from 0 to 1
- // was traced before it hit something
-vector trace_endpos; // the final position
-vector trace_plane_normal; // the normal of the surface it hit
-float trace_plane_dist; // used for angled surfaces (?)
-entity trace_ent; // the entity it hit (world if nothing)
-float trace_inopen; // if some portion of the trace is
- // in the air
-float trace_inwater; // if some portion of the trace is
- // in water
-
-entity msg_entity; // destination of single entity writes
-
-//======================================================================
-// required prog functions
-//======================================================================
-void() main; // only for testing
-
-void() StartFrame;
-
-void() PlayerPreThink;
-void() PlayerPostThink;
-
-void() ClientKill;
-void() ClientConnect;
-void() PutClientInServer; // call after setting the parm1... parms
-void() ClientDisconnect;
-
-void() SetNewParms; // called when a client first connects
- // to a server. set parms so they can be
- // saved off for restarts
-
-void() SetChangeParms; // call to set parms for self so they
- // can be saved for a level transition
-
-
-//================================================
-void end_sys_globals; // flag for structure dumping
-//================================================

Return to the top of this page or return to the overview of this repo.

Diff qc-server/defs_misc.qc

diff --git a/qc-server/defs_misc.qc b/qc-server/defs_misc.qc
deleted file mode 100644
index ffd7c28..0000000
--- a/qc-server/defs_misc.qc
+++ /dev/null
@@ -1,676 +0,0 @@
-/*==============================================================================
- VARS NOT REFERENCED BY C CODE
-==============================================================================*/
-
-// inspired by Copper
-string version = "\nprogs_dump devkit\nversion 3.0.0";
-
-// constants
-float FALSE = 0;
-float TRUE = 1;
-float NEGATIVE = -1;
-
-// worldtype values
-float WORLDTYPE_MEDIEVAL = 0;
-float WORLDTYPE_METAL = 1;
-float WORLDTYPE_BASE = 2;
-
-// edict.flags
-float FL_FLY = 1;
-float FL_SWIM = 2;
-float FL_CLIENT = 8; // set for all client edicts
-float FL_INWATER = 16; // for enter / leave water splash
-float FL_MONSTER = 32;
-float FL_GODMODE = 64; // player cheat
-float FL_NOTARGET = 128; // player cheat
-float FL_ITEM = 256; // extra wide size for bonus items
-float FL_ONGROUND = 512; // standing on something
-float FL_PARTIALGROUND = 1024; // not all corners are valid
-float FL_WATERJUMP = 2048; // player jumping out of water
-float FL_JUMPRELEASED = 4096; // for jump debouncing
-float FL_DOUBLEJUMPED = 8192; // player has doublejumped
-float FL_WALLJUMP = 16384; // player has jumped off a wall
-float FL_NOCENTERPRINT = 65536; // don't centerprint entity's message
- // field when its targets are used
-// edict.movetype values
-float MOVETYPE_NONE = 0; // never moves
-//float MOVETYPE_ANGLENOCLIP = 1;
-//float MOVETYPE_ANGLECLIP = 2;
-float MOVETYPE_WALK = 3; // players only
-float MOVETYPE_STEP = 4; // discrete, not real time unless fall
-float MOVETYPE_FLY = 5;
-float MOVETYPE_TOSS = 6; // gravity
-float MOVETYPE_PUSH = 7; // no clip to world, push and crush
-float MOVETYPE_NOCLIP = 8;
-float MOVETYPE_FLYMISSILE = 9; // fly with extra size against monsters
-float MOVETYPE_BOUNCE = 10;
-float MOVETYPE_BOUNCEMISSILE = 11; // bounce with extra size
-
-// edict.solid values
-float SOLID_NOT = 0; // no interaction with other objects
-float SOLID_TRIGGER = 1; // touch on edge, but not blocking
-float SOLID_BBOX = 2; // touch on edge, block
-float SOLID_SLIDEBOX = 3; // touch on edge, but not an onground
-float SOLID_BSP = 4; // bsp clip, touch on edge, block
-
-// range values
-float RANGE_MELEE = 0;
-float RANGE_NEAR = 1;
-float RANGE_MID = 2;
-float RANGE_FAR = 3;
-
-// deadflag values
-float DEAD_NO = 0;
-float DEAD_DYING = 1;
-float DEAD_DEAD = 2;
-float DEAD_RESPAWNABLE = 3;
-
-// takedamage values
-float DAMAGE_NO = 0;
-float DAMAGE_YES = 1;
-float DAMAGE_AIM = 2;
-
-// items
-float IT_AXE = 4096;
-float IT_SHOTGUN = 1;
-float IT_SUPER_SHOTGUN = 2;
-float IT_NAILGUN = 4;
-float IT_SUPER_NAILGUN = 8;
-float IT_GRENADE_LAUNCHER = 16;
-float IT_ROCKET_LAUNCHER = 32;
-float IT_LIGHTNING = 64;
-float IT_EXTRA_WEAPON = 128;
-
-float IT_SHELLS = 256;
-float IT_NAILS = 512;
-float IT_ROCKETS = 1024;
-float IT_CELLS = 2048;
-
-float IT_ARMOR1 = 8192;
-float IT_ARMOR2 = 16384;
-float IT_ARMOR3 = 32768;
-float IT_SUPERHEALTH = 65536;
-
-float IT_KEY1 = 131072;
-float IT_KEY2 = 262144;
-
-float IT_INVISIBILITY = 524288;
-float IT_INVULNERABILITY = 1048576;
-float IT_SUIT = 2097152;
-float IT_QUAD = 4194304;
-
-// point content values
-float CONTENT_EMPTY = -1;
-float CONTENT_SOLID = -2;
-float CONTENT_WATER = -3;
-float CONTENT_SLIME = -4;
-float CONTENT_LAVA = -5;
-float CONTENT_SKY = -6;
-
-float STATE_TOP = 0;
-float STATE_BOTTOM = 1;
-float STATE_UP = 2;
-float STATE_DOWN = 3;
-
-vector VEC_ORIGIN = '0 0 0';
-// Player
-vector VEC_HULL_MIN = '-16 -16 -24';
-vector VEC_HULL_MAX = '16 16 32';
-vector VEC_HULL_SIZE = '32 32 56';
-// Ogres, Shalrath, Demon, Shambler
-vector VEC_HULL2_MIN = '-32 -32 -24';
-vector VEC_HULL2_MAX = '32 32 64';
-vector VEC_HULL2_SIZE = '64 64 88';
-
-// protocol bytes
-float SVC_UPDATESTAT = 3; // required by Hipnotic code
-float SVC_SETVIEWPORT = 5; // Camera Hip. Drake devkit dumptruck_ds
-float SVC_SETVIEWANGLES = 10; // Camera Hip. Drake devkit dumptruck_ds
-float SVC_TEMPENTITY = 23;
-float SVC_KILLEDMONSTER = 27;
-float SVC_FOUNDSECRET = 28;
-float SVC_INTERMISSION = 30;
-float SVC_FINALE = 31;
-float SVC_CDTRACK = 32;
-float SVC_SELLSCREEN = 33;
-float SVC_CUTSCENE = 34; // Hipnotic Drake devkit -- dumptruck_ds
-
-float TE_SPIKE = 0;
-float TE_SUPERSPIKE = 1;
-float TE_GUNSHOT = 2;
-float TE_EXPLOSION = 3;
-float TE_TAREXPLOSION = 4;
-float TE_LIGHTNING1 = 5;
-float TE_LIGHTNING2 = 6;
-float TE_WIZSPIKE = 7;
-float TE_KNIGHTSPIKE = 8;
-float TE_LIGHTNING3 = 9;
-float TE_LAVASPLASH = 10;
-float TE_TELEPORT = 11;
-float TE_EXPLOSION2 = 12; // from doe -- dumptruck_ds
-
-// sound channels
-// channel 0 never willingly overrides
-// other channels (1-7) always override a playing sound on that channel
-float CHAN_AUTO = 0;
-float CHAN_WEAPON = 1;
-float CHAN_VOICE = 2;
-float CHAN_ITEM = 3;
-float CHAN_BODY = 4;
-
-float ATTN_NONE = 0;
-float ATTN_NORM = 1;
-float ATTN_IDLE = 2;
-float ATTN_STATIC = 3;
-
-// update types
-float UPDATE_GENERAL = 0;
-float UPDATE_STATIC = 1;
-float UPDATE_BINARY = 2;
-float UPDATE_TEMP = 3;
-
-// entity effects
-float EF_BRIGHTFIELD = 1;
-float EF_MUZZLEFLASH = 2;
-float EF_BRIGHTLIGHT = 4;
-float EF_DIMLIGHT = 8;
-
-// messages
-float MSG_BROADCAST = 0; // unreliable to all
-float MSG_ONE = 1; // reliable to one (msg_entity)
-float MSG_ALL = 2; // reliable to all
-float MSG_INIT = 3; // write to the init string
-
-// spawnflags for func_movewall
-float MOVEWALL_VISIBLE = 1;
-float MOVEWALL_TOUCH = 2;
-float MOVEWALL_NONBLOCKING = 4;
-
-// known_release values -- iw
-float KNOWN_RELEASE_NOT = 0;
-float KNOWN_RELEASE_ID1 = 1;
-float KNOWN_RELEASE_FUNC_MAPJAMX = 2;
-
-// interfacing with CSQC -- CEV
-const float CLIENT_VELOCITY_X = 64;
-const float CLIENT_VELOCITY_Y = 65;
-
-const float EV_VOID = 0;
-const float EV_STRING = 1;
-const float EV_FLOAT = 2;
-const float EV_VECTOR = 3;
-const float EV_ENTITY = 4;
-const float EV_FIELD = 5;
-const float EV_FUNCTION = 6;
-const float EV_POINTER = 7;
-const float EV_INTEGER = 8;
-
-//======================================================================
-// globals
-//======================================================================
-float movedist;
-float gameover; // set when a rule exits
-
-string string_null; // null string
-// float empty_float;
-
-entity newmis; // set by launch_spike after spawning it
-entity activator; // entity that activated a trigger or
- // brush
-entity damage_attacker; // set by T_Damage
-float framecount;
-
-float skill;
-
-float known_release; // unique ID for a release;
- // see values above -- iw
-
-//======================================================================
-// world fields (FIXME: make globals)
-//======================================================================
-.string wad;
-.string map;
-.float worldtype; // 0=medieval 1=metal 2=base
-.float skip_id1_overrides;
-.string killtarget;
-
-//======================================================================
-// quakeed fields
-//======================================================================
-.float light_lev; // not used ingame, parsed by light util
-.float style;
-
-//======================================================================
-// monster ai
-//======================================================================
-.void() th_stand;
-.void() th_walk;
-.void() th_run;
-.void() th_missile;
-.void() th_melee;
-.void(entity attacker, float damage) th_pain;
-.void() th_die;
-
-.entity oldenemy; // mad at this player before taking
- // damage
-.float speed;
-
-.float lefty;
-
-.float search_time;
-.float attack_state;
-
-float AS_STRAIGHT = 1;
-float AS_SLIDING = 2;
-float AS_MELEE = 3;
-float AS_MISSILE = 4;
-float AS_TURRET = 5;
-
-//======================================================================
-// player only fields
-//======================================================================
-.float walkframe;
-
-.float attack_finished;
-.float pain_finished;
-
-.float invincible_finished;
-.float invisible_finished;
-.float super_damage_finished;
-.float radsuit_finished;
-
-.float invincible_time, invincible_sound;
-.float invisible_time, invisible_sound;
-.float super_time, super_sound;
-.float rad_time;
-.float fly_sound;
-
-.float axhitme;
-
-// set to time+0.2 whenever a client fires a weapon or takes damage.
-// Used to alert monsters that otherwise would let the player go
-.float show_hostile;
-
-.float jump_flag; // player jump flag
-.float swim_flag; // player swimming sound flag
-.float air_finished; // when time > air_finished, drown
-.float bubble_count; // keeps track of the number of bubbles
-.string deathtype; // keeps track of how the player died
-
-.float jump_time; // last time the player jumped -- CEV
-.vector primal_velocity; // velocity before engine physics -- CEV
-.float primal_speed; // speed before engine physics -- CEV
-.float boost_time; // time to simulate low friction -- CEV
-
-float input_timelength; // from fteextensions.qc -- CEV
-vector input_angles; /* +x=DOWN */
-vector input_movevalues;
-float input_buttons;
-float input_impulse;
-
-//======================================================================
-// object stuff
-//======================================================================
-.string mdl;
-.vector mangle; // angle at start
-.vector oldorigin; // only used by secret door
-.string origmodel; // switchables brushes (added by bmFbr)
-.float t_length, t_width;
-
-//======================================================================
-// doors, etc
-//======================================================================
-.vector /*dest,*/ dest1, dest2;
-.float wait; // time from firing to restarting
-.float delay; // time from activation to firing
-.entity trigger_field; // door's trigger entity
-.string noise4;
-.float aflag;
-.float dmg; // damage done by door when hit
-
-//======================================================================
-// monsters
-//======================================================================
-.float pausetime;
-.entity movetarget;
-.float homing;
-.float projexpl;
-.float proj_speed_mod;
-.float proj_basespeed;
-.float infight_mode;
-
-//======================================================================
-// misc
-//======================================================================
-.float cnt; // misc flag
-
-//======================================================================
-// subs
-//======================================================================
-.void() think1;
-.vector finaldest, finalangle;
-
-//======================================================================
-// triggers
-//======================================================================
-.float count; // for counting triggers
-
-//======================================================================
-// plats / doors / buttons
-//======================================================================
-.float lip;
-.float state;
-.vector pos1, pos2; // top and bottom positions
-.float height;
-
-//======================================================================
-// plat2 fields // progs_dump
-//======================================================================
-.float plat2Called;
-.float plat2LastMove;
-.float plat2GoTime;
-.float plat2GoTo;
-
-//======================================================================
-// elevator fields // progs_dump
-//======================================================================
-.float elevatorLastUse;
-.float elevatorOnFloor;
-.float elevatorToFloor;
-.vector elevatorDestination;
-
-//======================================================================
-// fog // progs_dump
-//======================================================================
-.vector fog_color, fog_color2;
-.float fog_density, fog_density2;
-.float skyfog_density, skyfog_density2;
-.entity fogblend_entity;
-.float distance;
-
-//======================================================================
-// sounds
-//======================================================================
-.float waitmin /*, waitmax*/;
-// .float distance;
-.float volume;
-
-//======================================================================
-// support for item_key_custom -- iw
-//======================================================================
-.string keyname;
-.float customkeys;
-
-//======================================================================
-// variables for enhanced triggering from Custents -- dumptruck_ds
-//======================================================================
-.string target2; // second target's name
-.string target3; // third target's name
-.string target4; // fourth target's name
-.string targetname2; // second name
-.string targetname3; // third name
-.string targetname4; // fourth name
-.string killtarget2; // second target to kill
-string lastnameused; // the targetname that was last used
- // to trigger somthing
-
-//======================================================================
-// switchable shadow
-//======================================================================
-.float switchshadstyle;
-.float shadowoff;
-.entity shadowcontroller;
-.float speed2;
-
-void() misc_shadowcontroller;
-void() misc_shadowcontroller_use;
-void() shadow_fade_in;
-void() shadow_fade_out;
-string(float num) lightstyle_fade_lookup;// add. by bmFbr for switchable shadows
-
-//======================================================================
-// misc pd_additions
-//======================================================================
-.float reset_items; // dumptruck_ds
-.float spawn_angry; // dumptruck_ds
-.string mdl_debris; // dumptruck_ds
-.float keep_ammo; // dumptruck_ds
-.string obit_name; // dumptruck_ds
-.string obit_method; // dumptruck_ds
-.float damage_mod; // dumptruck_ds
-
-/*==============================================================================
- subs.qc
-==============================================================================*/
-void(vector tdest, float tspeed, void() func) SUB_CalcMove;
-void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt;
-void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove;
-void() SUB_CalcMoveDone;
-void() SUB_CalcAngleMoveDone;
-void() SUB_Null;
-void() SUB_UseTargets;
-void() SUB_Remove;
-
-/*==============================================================================
- combat.qc
-==============================================================================*/
-void(entity targ, entity inflictor, entity attacker, float damage) T_Damage;
-float (entity e, float healamount, float ignore) T_Heal; // health function
-float(entity targ, entity inflictor) CanDamage;
-void() DummyFunction =
-{
- // gets rid of the last compiler warnings ; - )
- local string w;
- local float l;
- w = self.wad;
- l = self.light_lev;
-}
-.float is_waiting; // Supa, triggers, wait until activated
- // before we can trigger?
-.float gravity; // from custdefs.qc by way of Hipnotic
-float STAT_TOTALMONSTERS = 12; // required by Hipnotic code
-
-// dumptruck_ds from Rogue eod defs
-
-/*============================================================================
- johnfitz new defs from Rubicon2
-============================================================================*/
-float BREAKABLE_NO_MONSTERS = 1;
-
-.float wantedgravity; // thanks Spike!
-.float onladder;
-// .float ladder_step_finished; // footsteps on ladder -- dumptruck_ds
-
-// dumptruck_ds defs for breakables in rubcon2.qc
-// -- thanks to Qmaster and the Arcane Dimensions team
-/*
-.string break_template1_e;
-.string break_template2_e;
-.string break_template3_e;
-.string break_template4_e;
-.string break_template5_e;
-.string find_brk_template_model;
-*/
-
-// from remakequake -- dumptruck_ds
-
-.vector dest, dest1, dest2;
-
-void(string type, string text) print_self =
-{
- dprint (type);
- dprint (" '");
- dprint (self.classname);
- dprint ("' ");
- dprint (text);
- dprint (" at ");
- dprint (vtos(self.origin));
- dprint ("\n");
-};
-
-// TODO CEV
-void() monster_pain_use; // dumptruck_ds
-void() SUB_UsePain; // dumptruck_ds
-.float pain_threshold; // dumptruck_ds
-.string pain_target; // dumptruck_ds
-.float color; // Hipnotic
-.float megahealth_rottime; // dumptruck_ds
-.float alpha; // from RennyC func_fall in dtmisc.qc
-.float ltrailLastUsed; // from DOE lighnin
-.float style2; // c0burn's switchable lights
-.float sight_trigger; // dumptruck_ds
-.float keep_ammo; // dumptruck_ds
-.float berserk; // dumptruck_ds
-nosave float *world_sounds; // via Spike fun times! nosave=noclobber
-void() trigger_changemusic; // dumptruck_ds
-void() onlookat_touch; // dumptruck_ds
-
-// Drake Cutscenes -- Borrowed from Zerstorer.
-.string script; // dhm - denotes which script to read.
-.string next_script; // dhm - denotes the current script.
-.string script_num; // dhm - number for info_scripts.
-// .string camera_point; // dhm - target for camera to move to.
-.string focal_point; // dhm - focus point for camera.
-.float script_delay; // dhm - time until next script.
-.float script_time; // dhm - used for script timing.
-.float script_count; // dhm - ditto.
-// cutscene.qc - - -
-void() Cutscene_Think;
-float cutscene; // Set to TRUE during a cutscene.
-float mindex_inviso; // Invisible (null sprite)
-.string null_string; // Replace 'string_null' with
- // 'world.null_string'. null string,
- // nothing should be held here.
-// from Custents
-// variable for healing trigger
-.float heal_timer;
-.float heal_amount;
-.float health_max;
-// Constants for the healing trigger
-float HEAL_START_ON = 1;
-float HEAL_PLAYER_ONLY = 2;
-float HEAL_MONSTER_ONLY = 4;
-
-// Custom Monster Sounds START -- dumptruck_ds
-.string snd_death;
-.string snd_pain;
-.string snd_sight;
-.string snd_attack;
-.string snd_hit;
-.string snd_idle;
-.string snd_land;
-.string snd_move;
-.string snd_misc;
-.string snd_misc1;
-.string snd_misc2;
-.string snd_misc3;
-// Custom Monster Sounds END -- dumptruck_ds
-
-// Custom Model Start -- dumptruck_ds
-.string mdl_head;
-.string mdl_body;
-.string mdl_proj;
-.string mdl_exproj;
-.float skin_head;
-.float skin_proj;
-.float skin_exproj;
-.string mdl_gib1;
-.string mdl_gib2;
-.string mdl_gib3;
-// addition by bmFbr for custom model bounding box definition
-.vector mdlsz, centeroffset;
-// Custom Model End -- dumptruck_ds
-
-.float shardvalue; // ammo shard value
-
-.float drop_item; // key DropStuff
-
-float SPAWN_SILENTLY = 2097152;
-float TRIGGER_CENTERPRINTALL = 1048576;
-
-// entity state
-.float estate;
-.void() dormant_use;
-float STATE_ACTIVE = 0;
-float STATE_INACTIVE = 1;
-float STATE_INVISIBLE = 8;
-
-.float prevstate;
-
-void(entity client, float density, vector color) fog_save;
-void(entity client, float density) skyfog_save;
-void(entity client, entity fogger) fog_setFromEnt;
-void(entity client, float density, vector color) fog_set;
-void(entity client, float density) skyfog_set;
-
-nosave float cleanUpClientStuff;
-nosave float gamestarted;
-
-.string include;
-.string type;
-
-.float last_setstate_frame = light_lev;
-.entity last_setstate = aiment;
-
-// 1998-07-03 hurt_touch fix by Robert Field start
-//
-// triggers.qc
-//
-.float hurt_together_time;
-.float hurt_nextthink;
-// 1998-07-03 hurt_touch fix by Robert Field end
-
-float I_AM_TURRET = 262144; // dumptruck_ds
-.void() th_turret;
-
-.entity animcontroller;
-.entity rotatecontroller;
-.float multiplier;
-
-.float first_frame, last_frame;
-.float first_frame2, last_frame2;
-.float frtime, frtime2;
-.float animtype, animtype2;
-.vector cmins, cmaxs;
-.vector cust_avelocity;
-.float touch_time;
-
-// cshift controller
-.entity csfcontroller;
-
-.vector csf_color;
-.float csf_density;
-
-void(entity client) csf_apply;
-void(entity client, float density, vector color, float spd) csf_fade;
-void(entity client, float density, vector color) csf_set;
-
-.float fade_amt;
-
-// worldspawn default mdls
-.string h_vial_mdl;
-.string h_25_mdl;
-.string h_15_mdl;
-.string h_mega_mdl;
-
-.string s_sm_mdl;
-.string s_lg_mdl;
-
-.string n_sm_mdl;
-.string n_lg_mdl;
-
-.string r_sm_mdl;
-.string r_lg_mdl;
-
-.string c_sm_mdl;
-.string c_lg_mdl;
-
-.string a_shr_mdl;
-.string a_grn_mdl;
-.string a_ylw_mdl;
-.string a_red_mdl;
-
-.entity infight_activator;
-
-.void() customphysics;
-

Return to the top of this page or return to the overview of this repo.

Diff qc-server/doe_elbutton.qc

diff --git a/qc-server/doe_elbutton.qc b/qc-server/doe_elbutton.qc
deleted file mode 100644
index 62cd91d..0000000
--- a/qc-server/doe_elbutton.qc
+++ /dev/null
@@ -1,157 +0,0 @@
-// elevator button
-// pmack
-// sept 96
-
-float ELVTR_DOWN = 1;
-
-void() elvtr_button_wait;
-void() elvtr_button_return;
-
-void() elvtr_button_wait =
-{
- elv_butn_dir = 0;
- if (self.spawnflags & ELVTR_DOWN)
- elv_butn_dir = -1;
- else
- elv_butn_dir = 1;
-
- self.state = STATE_TOP;
- self.nextthink = self.ltime + self.wait;
- self.think = elvtr_button_return;
- activator = self.enemy;
- SUB_UseTargets();
- self.frame = 1; // use alternate textures
-};
-
-void() elvtr_button_done =
-{
- self.state = STATE_BOTTOM;
-};
-
-void() elvtr_button_return =
-{
- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos1, self.speed, elvtr_button_done);
- self.frame = 0; // use normal textures
- if (self.health)
- self.takedamage = DAMAGE_YES; // can be shot again
-};
-
-
-void() elvtr_button_blocked =
-{ // do nothing, just don't ome all the way back out
-};
-
-
-void() elvtr_button_fire =
-{
- if (self.state == STATE_UP || self.state == STATE_TOP)
- return;
-
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
-
- self.state = STATE_UP;
- SUB_CalcMove (self.pos2, self.speed, elvtr_button_wait);
-};
-
-
-void() elvtr_button_use =
-{
- self.enemy = activator;
- elvtr_button_fire ();
-};
-
-void() elvtr_button_touch =
-{
- if (other.classname != "player")
- return;
- self.enemy = other;
- elvtr_button_fire ();
-};
-
-void() elvtr_button_killed =
-{
- self.enemy = damage_attacker;
- self.health = self.max_health;
- self.takedamage = DAMAGE_NO; // wil be reset upon return
- elvtr_button_fire ();
-};
-
-
-/*QUAKED func_elvtr_button (0 .5 .8) ? ELVTR_DOWN X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-ELEVATOR BUTTON ONLY!
-
-ELVTR_DOWN causes this to be a DOWN button.
-Default is UP.
-
-When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again.
-
-"angle" determines the opening direction
-"target" all entities with a matching targetname will be used
-"speed" override the default 40 speed
-"wait" override the default 1 second wait (-1 = never return)
-"lip" override the default 4 pixel lip remaining at end of move
-"health" if set, the button must be killed instead of touched
-"sounds"
-0) steam metal
-1) wooden clunk
-2) metallic click
-3) in-out
-*/
-void() func_elvtr_button =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.sounds == 0)
- {
- precache_sound ("buttons/airbut1.wav");
- self.noise = "buttons/airbut1.wav";
- }
- if (self.sounds == 1)
- {
- precache_sound ("buttons/switch21.wav");
- self.noise = "buttons/switch21.wav";
- }
- if (self.sounds == 2)
- {
- precache_sound ("buttons/switch02.wav");
- self.noise = "buttons/switch02.wav";
- }
- if (self.sounds == 3)
- {
- precache_sound ("buttons/switch04.wav");
- self.noise = "buttons/switch04.wav";
- }
-
- SetMovedir ();
-
- self.movetype = MOVETYPE_PUSH;
- self.solid = SOLID_BSP;
- setmodel (self, self.model);
-
- self.blocked = elvtr_button_blocked;
- self.use = elvtr_button_use;
-
- if (self.health)
- {
- self.max_health = self.health;
- self.th_die = elvtr_button_killed;
- self.takedamage = DAMAGE_YES;
- }
- else
- self.touch = elvtr_button_touch;
-
- if (!self.speed)
- self.speed = 40;
- if (!self.wait)
- self.wait = 1;
- if (!self.lip)
- self.lip = 4;
-
- self.state = STATE_BOTTOM;
-
- self.pos1 = self.origin;
- self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/doe_ltrail.qc

diff --git a/qc-server/doe_ltrail.qc b/qc-server/doe_ltrail.qc
deleted file mode 100644
index 0a3f0d9..0000000
--- a/qc-server/doe_ltrail.qc
+++ /dev/null
@@ -1,194 +0,0 @@
-// lightning trail
-// pmack
-// sept 96
-
-// float ltrailLastUsed; -- now an entity field.
-
-float LT_TOGGLE = 1;
-float LT_ACTIVE = 2;
-
-void() ltrail_chain =
-{
- SUB_UseTargets();
-
- self.think = SUB_Null;
-};
-
-void() ltrail_fire =
-{
- local entity myTarget;
-
- if (self.classname != "ltrail_end")
- {
- if (!self.sounds)
- sound (self, CHAN_VOICE, "weapons/lhit.wav", 1, ATTN_NORM);
- myTarget = find(world, targetname, self.target);
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
- WriteEntity (MSG_BROADCAST, self);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- WriteCoord (MSG_BROADCAST, myTarget.origin_x);
- WriteCoord (MSG_BROADCAST, myTarget.origin_y);
- WriteCoord (MSG_BROADCAST, myTarget.origin_z);
- LightningDamage (self.origin, myTarget.origin, self, self.currentammo);
- }
-
- if ( self.items < time)
- {
- self.think = ltrail_chain;
- self.nextthink = time + self.frags;
- }
- else
- {
- self.think = ltrail_fire;
- self.nextthink = time + 0.05;
- }
-};
-
-void() ltrail_start_fire =
-{
- // if it's a toggle ltrail, we ignore triggers from ltrail_end's
- // when toggled off.
- if (self.spawnflags & LT_TOGGLE)
- {
- // user is not a lightning trail - change activity state.
- if ( other.classname != "ltrail_end" )
- {
- if (self.spawnflags & LT_ACTIVE)
- // currently active
- {
- self.spawnflags = self.spawnflags - LT_ACTIVE;
- return;
- }
- else
- // not active
- {
- self.spawnflags = self.spawnflags + LT_ACTIVE;
- }
- }
- // user is lightning trail, but trail has been turned off.
- // ignore the message.
- else if (!(self.spawnflags & LT_ACTIVE))
- return;
- }
-
- if (self.classname == "ltrail_start")
- {
- self.items = time + self.weapon;
- ltrail_fire();
- self.ltrailLastUsed = time;
- }
- else if (self.classname == "ltrail_relay")
- {
- self.items = time + self.weapon;
- ltrail_fire();
- }
- else
- {
- self.think = ltrail_chain;
- self.nextthink = time + self.frags;
- }
-};
-
-/*QUAKED ltrail_start (0 1 0) (-8 -8 -8) (8 8 8) LT_TOGGLE START_ON X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Starting point of a lightning trail.
-Set currentammo to amount of damage you want the lightning to do.
-Default is 25.
-
-Set frags to amount of time before next item is triggered.
-Default is 0.3 seconds.
-
-Set weapon to amount of time to be firing the lightning.
-Default is 0.3 seconds.
-
-Set the LT_TOGGLE checkbox if you want the lightning shooter to continuously fire until triggered again.
-*/
-void() ltrail_start =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.ltrailLastUsed = time;
-
- precache_sound ("weapons/lhit.wav");
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_BBOX;
- self.use = ltrail_start_fire;
-
- if (self.currentammo == 0)
- self.currentammo = 25;
-
- if (self.weapon == 0)
- self.weapon = 0.3;
-
- if (self.frags == 0)
- self.frags = 0.3;
-
- if (self.spawnflags & LT_ACTIVE)
- {
- self.items = time + 99999999;
- self.think = ltrail_fire;
- self.nextthink = time + 0.1;
- }
-};
-
-/*QUAKED ltrail_relay (0 1 0) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Relay point of a lightning trail.
-Set currentammo to amount of damage you want the lightning to do.
-Default is 25.
-
-Set frags to amount of time before next item is triggered.
-Default is 0.3 seconds.
-
-Set weapon to amount of time to be firing the lightning.
-Default is 0.3 seconds.
-*/
-void() ltrail_relay =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("weapons/lhit.wav");
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_BBOX;
- self.use = ltrail_start_fire;
-
- if (self.currentammo == 0)
- self.currentammo = 25;
-
- if (self.weapon == 0)
- self.weapon = 0.3;
-
- if (self.frags == 0)
- self.frags = 0.3;
-};
-
-/*QUAKED ltrail_end (0 1 0) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Ending point of a lightning trail.
-Does not fire any lightning.
-
-Set frags to amount of time before next item is triggered.
-Default is 0.3 seconds.
-*/
-void() ltrail_end =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("weapons/lhit.wav");
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_BBOX;
- self.use = ltrail_start_fire;
-
- if (self.currentammo == 0)
- self.currentammo = 25;
-
- if (self.weapon == 0)
- self.weapon = 0.3;
-
- if (self.frags == 0)
- self.frags = 0.3;
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/doe_plats.qc

diff --git a/qc-server/doe_plats.qc b/qc-server/doe_plats.qc
deleted file mode 100644
index 70225cd..0000000
--- a/qc-server/doe_plats.qc
+++ /dev/null
@@ -1,630 +0,0 @@
-// newplats.qc
-// pmack
-// september 1996
-
-// TYPES
-
-float DN_N_WAIT = 1;
-float PLT_TOGGLE = 2;
-float ELEVATOR = 4;
-float START_AT_TOP = 8;
-float PLAT2 = 16;
-float PLAT2_BOTTOM = 32;
-
-float elv_butn_dir;
-
-// ==================================
-// down N and wait code
-// ==================================
-
-void() dn_and_wait_go_up;
-void() dn_and_wait_go_down;
-void() dn_and_wait_crush;
-
-void() dn_and_wait_hit_top =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_TOP;
-};
-
-void() dn_and_wait_hit_bottom =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_BOTTOM;
- self.think = dn_and_wait_go_up;
- self.nextthink = self.ltime + self.health;
-};
-
-void() dn_and_wait_go_down =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos2, self.speed, dn_and_wait_hit_bottom);
-};
-
-void() dn_and_wait_go_up =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_UP;
- SUB_CalcMove (self.pos1, self.speed, dn_and_wait_hit_top);
-};
-
-void() dn_and_wait_crush =
-{
- T_Damage (other, self, self, 1);
-
- if (self.state == STATE_UP)
- dn_and_wait_go_down ();
- else if (self.state == STATE_DOWN)
- dn_and_wait_go_up ();
- else
- objerror ("plat_new_crush: bad self.state\n");
-};
-
-void() dn_and_wait_use =
-{
- if (self.state != STATE_TOP)
- return;
-
- dn_and_wait_go_down ();
-};
-
-// ==================================
-// toggle type code
-// ==================================
-
-void() toggle_go_up;
-void() toggle_go_down;
-void() toggle_crush;
-
-void() toggle_hit_top =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_TOP;
-};
-
-void() toggle_hit_bottom =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_BOTTOM;
-};
-
-void() toggle_go_down =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos2, self.speed, toggle_hit_bottom);
-};
-
-void() toggle_go_up =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_UP;
- SUB_CalcMove (self.pos1, self.speed, toggle_hit_top);
-};
-
-void() toggle_crush =
-{
- T_Damage (other, self, self, 1);
-
- if (self.state == STATE_UP)
- toggle_go_down ();
- else if (self.state == STATE_DOWN)
- toggle_go_up ();
- else
- objerror ("plat_new_crush: bad self.state\n");
-};
-
-void() toggle_use =
-{
- if (self.state == STATE_TOP)
- toggle_go_down ();
- else if(self.state == STATE_BOTTOM)
- toggle_go_up ();
-};
-
-// ==================================
-// elvtr type code
-// ==================================
-
-void() elvtr_crush;
-
-void() elvtr_stop =
-{
- self.elevatorOnFloor = self.elevatorToFloor;
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_BOTTOM;
- self.elevatorLastUse = time;
-};
-
-void() elvtr_go =
-{
- self.elevatorDestination = self.pos2;
- self.elevatorDestination_z = self.pos2_z +
- (self.height * self.elevatorToFloor);
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_UP;
- SUB_CalcMove (self.elevatorDestination, self.speed, elvtr_stop);
- self.elevatorLastUse = time;
-};
-
-void() elvtr_crush =
-{
- local float tmp;
-
-// T_Damage (other, self, self, 1);
-
- // the elevator is changing direction, so swap the floor it's coming
- // from and the floor it's going to -- iw
- tmp = self.elevatorOnFloor;
- self.elevatorOnFloor = self.elevatorToFloor;
- self.elevatorToFloor = tmp;
-
- elvtr_go ();
-};
-
-// ===============
-// elevator use function
-// self = plat, other = elevator button, other.enemy = player
-// ===============
-void() elvtr_use =
-{
- local float tempDist, elvPos, btnPos;
-
- // the original DoE code allowed an elevator to be activated again
- // when it was in the process of moving between floors (assuming the
- // wait period was over); this resulted in sometimes unintuitive
- // behavior, so, the following test prevents this -- iw
- if (self.elevatorToFloor != self.elevatorOnFloor)
- return;
-
- // the original DoE code had a hard-coded two second wait period;
- // this has been changed for progs_dump so that self.wait is used
- // instead -- iw
- if ((self.elevatorLastUse + self.wait) > time)
- return;
-
- self.elevatorLastUse = time;
-
- if (elv_butn_dir == 0)
- return;
-
- elvPos = (self.absmin_z + self.absmax_z) * 0.5;
- btnPos = (other.absmin_z + other.absmax_z) * 0.5;
-
- if (elvPos > btnPos)
- {
- tempDist = (elvPos - btnPos) / self.height;
- tempDist = ceil ( tempDist);
- self.elevatorToFloor = self.elevatorOnFloor - tempDist;
- elvtr_go ();
- return;
- }
- else
- {
- tempDist = btnPos - elvPos;
- if (tempDist > self.height)
- {
- tempDist = tempDist / self.height;
- tempDist = floor ( tempDist );
- self.elevatorToFloor = self.elevatorOnFloor + tempDist;
- elvtr_go ();
- return;
- }
- }
-
- if (elv_butn_dir == -1)
- {
- if(self.elevatorOnFloor > 0)
- {
- self.elevatorToFloor = self.elevatorOnFloor - 1;
- elvtr_go ();
- }
- }
- else if(elv_butn_dir == 1)
- {
- if(self.elevatorOnFloor < (self.cnt - 1))
- {
- self.elevatorToFloor = self.elevatorOnFloor + 1;
- elvtr_go ();
- }
- }
-};
-
-// ==================================
-// PLAT2 type code
-// ==================================
-
-void() plat2_center_touch;
-void() plat2_go_up;
-void() plat2_go_down;
-void() plat2_crush;
-
-void() plat2_spawn_inside_trigger =
-{
- local entity trigger;
- local vector tmin, tmax;
-
-//
-// middle trigger
-//
- trigger = spawn();
- trigger.touch = plat2_center_touch;
- trigger.movetype = MOVETYPE_NONE;
- trigger.solid = SOLID_TRIGGER;
- trigger.enemy = self;
-
- tmin = self.mins + '25 25 0';
- tmax = self.maxs - '25 25 -8';
- tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8);
-
- if (self.spawnflags & PLAT_LOW_TRIGGER)
- tmax_z = tmin_z + 8;
-
- if (self.size_x <= 50)
- {
- tmin_x = (self.mins_x + self.maxs_x) / 2;
- tmax_x = tmin_x + 1;
- }
- if (self.size_y <= 50)
- {
- tmin_y = (self.mins_y + self.maxs_y) / 2;
- tmax_y = tmin_y + 1;
- }
-
- setsize (trigger, tmin, tmax);
-};
-
-void() plat2_hit_top =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_TOP;
-
- self.plat2LastMove = time;
- if(self.plat2Called == 1)
- {
- self.think = plat2_go_down;
- self.nextthink = self.ltime + 1.5;
- self.plat2Called = 0;
- self.plat2LastMove = 0; // allow immediate move
- }
- else if(!(self.spawnflags & START_AT_TOP))
- {
- self.think = plat2_go_down;
- self.nextthink = self.ltime + self.delay;
- self.plat2Called = 0;
- }
-};
-
-void() plat2_hit_bottom =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_BOTTOM;
-
- self.plat2LastMove = time;
- if(self.plat2Called == 1)
- {
- self.think = plat2_go_up;
- self.nextthink = self.ltime + 1.5;
- self.plat2Called = 0;
- self.plat2LastMove = 0; // allow immediate move
- }
- else if(self.spawnflags & START_AT_TOP)
- {
- self.think = plat2_go_up;
- self.nextthink = self.ltime + self.delay;
- self.plat2Called = 0;
- }
-};
-
-void() plat2_go_down =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos2, self.speed, plat2_hit_bottom);
-};
-
-void() plat2_go_up =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_UP;
- SUB_CalcMove (self.pos1, self.speed, plat2_hit_top);
-};
-
-void() plat2_use =
-{
- if(self.state > 4)
- self.state = self.state - 10;
-
- self.use = SUB_Null;
-};
-
-void() plat2_center_touch =
-{
- local float otherState;
- local vector platPosition;
-
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- // at this point, self is the trigger. self.enemy is the plat.
- // this changes self to be the plat, other is the player.
- self = self.enemy;
-
- if ((self.plat2LastMove + 2) > time)
- return;
-
- if (self.state > 4) // disabled.
- return;
-
- if (self.plat2GoTo > STATE_BOTTOM)
- {
- if (self.plat2GoTime < time)
- {
- if (self.plat2GoTo == STATE_UP)
- plat2_go_up();
- else
- plat2_go_down();
-
- self.plat2GoTo = 0;
- }
- return;
- }
-
- if (self.state > STATE_BOTTOM) // STATE_UP or STATE_DOWN
- return;
-
- platPosition = (self.absmax + self.absmin) * 0.5;
-
- if (self.state == STATE_TOP)
- {
- otherState = STATE_TOP;
- if ( platPosition_z > other.origin_z )
- otherState = STATE_BOTTOM;
- }
- else
- {
- otherState = STATE_BOTTOM;
- if ( (other.origin_z - platPosition_z) > self.height)
- otherState = STATE_TOP;
- }
-
- if (self.state == otherState)
- {
- self.plat2Called = 0;
- self.plat2GoTime = time + 0.5;
- }
- else
- {
- self.plat2GoTime = time + 0.1;
- self.plat2Called = 1;
- }
-
- if (self.state == STATE_BOTTOM)
- self.plat2GoTo = STATE_UP;
- else if(self.state == STATE_TOP)
- self.plat2GoTo = STATE_DOWN;
-};
-
-void() plat2_crush =
-{
- T_Damage (other, self, self, 1);
-
- if (self.state == STATE_UP)
- plat2_go_down ();
- else if (self.state == STATE_DOWN)
- plat2_go_up ();
- else
- objerror ("plat2_crush: bad self.state\n");
-};
-
-// ==================================
-// Common Plat Code
-// ==================================
-
-/*QUAKED func_new_plat (0 .5 .8) ? DN_N_WAIT PLT_TOGGLE ELEVATOR START_AT_TOP PLAT2 P2_BOTTOM X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-
---------------
-DN_N_WAIT is a plat that starts at the top and when triggered, goes down, waits, then comes back up.
-health - number of seconds to wait (default 5)
---------------
-PLT_TOGGLE is a plat that will change between the top and bottom each time it is triggered.
---------------
-ELEVATOR is an elevator plat. You can have as many levels as you want but they must be all the same distance away. Use elevator button entity as the trigger.
-cnt is the number of floors
-height is the distance between floors
-wait is the number of seconds before the elevator can be activated again after starting or stopping (default 0)
-
-START_AT_TOP is an optional flag for elevators. It just tells the elevator that it's position is the top floor. (Default is the bottom floor) USE THIS ONLY WITH ELEVATORS!
--------------
-PLAT2 is a fixed version of the original plat. If you want the plat to start at the bottom and move to the top on demand, use a negative height. That will tell Quake to lower the plat at spawn time. Always place this plat type in the top position when making the map. This will ensure correct lighting, hopefully. If a plat2 is the target of a trigger, it will be disabled until it has been triggered. Delay is the wait before the plat returns to original position.
-
-If you don't want to bother figuring out the height, don't put a
-value in the height
-
-delay default 3
-speed default 150
-cnt default 2
-
-P2_BOTTOM is an optional switch to have an auto-sized plat2 start at the bottom.
---------------
-Plats are always drawn in the extended position, so they will light correctly.
-
-If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat.
-
-If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determined by the model's height.
-Set "sounds" to one of the following:
-1) base fast
-2) chain slow
-*/
-
-void() func_new_plat =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
-//local entity t;
-local float negativeHeight;
-
- negativeHeight = 0;
-
- if (!self.t_length)
- self.t_length = 80;
- if (!self.t_width)
- self.t_width = 10;
-
- if (self.sounds == 0)
- self.sounds = 2;
-// FIX THIS TO LOAD A GENERIC PLAT SOUND
-
- if (self.sounds == 1) {
- if (!self.noise || self.noise == "") self.noise = "plats/plat1.wav";
- if (!self.noise1 || self.noise1 == "") self.noise1 = "plats/plat2.wav";
- }
- else if (self.sounds == 2) {
- if (!self.noise || self.noise == "") self.noise = "plats/medplat1.wav";
- if (!self.noise1 || self.noise1 == "") self.noise1 = "plats/medplat2.wav";
- }
- else if (self.sounds == 3) { // base door sound
- if (!self.noise || self.noise == "") self.noise = "doors/hydro1.wav";
- if (!self.noise1 || self.noise1 == "") self.noise1 = "doors/hydro2.wav";
- }
- else if (self.sounds == 4) { // func_train sounds
- if (!self.noise || self.noise == "") self.noise = "plats/train1.wav";
- if (!self.noise1 || self.noise1 == "") self.noise1 = "plats/train2.wav";
- }
- else {
- if (!self.noise || self.noise == "") self.noise = "misc/null.wav";
- if (!self.noise1 || self.noise1 == "") self.noise1 = "misc/null.wav";
- }
-
- precache_sound(self.noise);
- precache_sound(self.noise1);
-
-
- self.mangle = self.angles;
- self.angles = '0 0 0';
-
- self.classname = "plat";
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- setorigin (self, self.origin);
- setmodel (self, self.model);
- setsize (self, self.mins , self.maxs);
-
- if (!self.speed)
- self.speed = 150;
-
-// pos1 is the top position, pos2 is the bottom
- self.pos1 = self.origin;
- self.pos2 = self.origin;
-
- if (self.height < 0)
- {
- negativeHeight = 1;
- self.height = 0 - self.height;
- }
-
- if (self.height)
- self.pos2_z = self.origin_z - self.height;
- else
- {
- negativeHeight = 1;
- self.height = self.size_z - 8;
- self.pos2_z = self.origin_z - self.height;
- }
-
- if (self.spawnflags & DN_N_WAIT)
- {
- self.use = dn_and_wait_use;
- self.blocked = dn_and_wait_crush;
-
- if (negativeHeight == 1)
- {
- self.state = STATE_BOTTOM;
- setorigin (self, self.pos2);
- }
- else
- self.state = STATE_TOP;
-
- if (!self.health)
- self.health = 5;
- }
- else if (self.spawnflags & PLT_TOGGLE)
- {
- self.use = toggle_use;
- self.blocked = toggle_crush;
- if (negativeHeight == 1)
- {
- setorigin (self, self.pos2);
- self.state = STATE_BOTTOM;
- }
- else
- {
- self.state = STATE_TOP;
- }
- }
- else if (self.spawnflags & ELEVATOR)
- {
- self.elevatorLastUse = 0;
-
- // allow the mapper to set self.wait, but don't allow a negative
- // wait period -- iw
- if (self.wait < 0)
- self.wait = 0;
-
- if (self.spawnflags & START_AT_TOP)
- {
- self.pos1 = self.origin;
- self.pos2 = self.origin;
- self.pos2_z = self.origin_z - (self.height * (self.cnt - 1));
- self.elevatorOnFloor = self.cnt - 1;
- self.elevatorToFloor = self.elevatorOnFloor;
- }
- else
- {
- self.pos1 = self.origin;
- self.pos2 = self.origin;
- self.pos1_z = self.origin_z + (self.height * (self.cnt - 1));
- self.elevatorOnFloor = 0;
- self.elevatorToFloor = self.elevatorOnFloor;
- }
-
- self.use = elvtr_use;
- self.blocked = elvtr_crush;
- }
- else if (self.spawnflags & PLAT2)
- {
- plat2_spawn_inside_trigger (); // the "start moving" trigger
- self.plat2Called = 0;
- self.plat2LastMove = 0;
- self.plat2GoTo = 0;
- self.plat2GoTime = 0;
- self.blocked = plat2_crush;
-
- if (!self.delay)
- self.delay = 3;
-
- if (negativeHeight == 1)
- {
- self.state = STATE_BOTTOM;
- // make sure START_AT_TOP isn't set. We need that...
- self.spawnflags = PLAT2;
- setorigin (self, self.pos2);
- }
- else
- {
- // default position is top.
- self.spawnflags = self.spawnflags | START_AT_TOP;
- self.state = STATE_TOP;
- }
-
- if (self.targetname != "")
- {
- self.use = plat2_use;
- self.state = self.state + 10;
- }
- }
-
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/doors.qc

diff --git a/qc-server/doors.qc b/qc-server/doors.qc
deleted file mode 100644
index b04f606..0000000
--- a/qc-server/doors.qc
+++ /dev/null
@@ -1,945 +0,0 @@
-
-float DOOR_START_OPEN = 1;
-float DOOR_DONT_LINK = 4;
-float DOOR_GOLD_KEY = 8;
-float DOOR_SILVER_KEY = 16;
-float DOOR_TOGGLE = 32;
-float DOOR_DOOM_STYLE_UNLOCK = 64;
-/*
-
-Doors are similar to buttons, but can spawn a fat trigger field around them
-to open without a touch, and they link together to form simultanious
-double/quad doors.
-
-Door.owner is the master door. If there is only one door, it points to itself.
-If multiple doors, all will point to a single one.
-
-Door.enemy chains from the master door through all doors linked in the chain.
-
-*/
-
-/*
-=============================================================================
-
-THINK FUNCTIONS
-
-=============================================================================
-*/
-
-void() door_go_down;
-void() door_go_up;
-
-void() door_blocked =
-{
- T_Damage (other, self, self, self.dmg);
-
-// if a door has a negative wait, it would never come back if blocked,
-// so let it just squash the object to death real fast
- if (self.wait >= 0)
- {
- if (self.state == STATE_DOWN)
- door_go_up ();
- else
- door_go_down ();
- }
-};
-
-
-void() door_hit_top =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_TOP;
- if (self.spawnflags & DOOR_TOGGLE)
- return; // don't come down automatically
- self.think = door_go_down;
- self.nextthink = self.ltime + self.wait;
-};
-
-void() door_hit_bottom =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_BOTTOM;
-};
-
-void() door_go_down =
-{
- entity shadow;
- entity oldself;
-
- sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
- if (self.max_health)
- {
- self.takedamage = DAMAGE_YES;
- self.health = self.max_health;
- }
-
- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos1, self.speed, door_hit_bottom);
-
- if(self.switchshadstyle) {
- shadow = self.shadowcontroller;
- oldself = self;
- self = shadow;
-
- if(oldself.spawnflags & DOOR_START_OPEN) {
- shadow_fade_out();
- shadow.shadowoff = 1;
- } else {
- shadow_fade_in();
- shadow.shadowoff = 0;
- }
-
- self = oldself;
-
- }
-};
-
-void() door_go_up =
-{
- entity shadow;
- entity oldself;
-
- if (self.state == STATE_UP)
- return; // allready going up
-
- if (self.state == STATE_TOP)
- { // reset top wait time
- self.nextthink = self.ltime + self.wait;
- return;
- }
-
- sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
- self.state = STATE_UP;
- SUB_CalcMove (self.pos2, self.speed, door_hit_top);
-
- SUB_UseTargets();
-
- if(self.switchshadstyle) {
- shadow = self.shadowcontroller;
- oldself = self;
- self = shadow;
-
- if(oldself.spawnflags & DOOR_START_OPEN) {
- shadow_fade_in();
- shadow.shadowoff = 0;
- } else {
- shadow_fade_out();
- shadow.shadowoff = 1;
- }
-
- self = oldself;
- }
-};
-
-
-void() door_group_go_down = {
- local entity oself, starte;
-
- oself = self;
- starte = self;
-
- do
- {
- door_go_down ();
- self = self.enemy;
- } while ( (self != starte) && (self != world) );
- self = oself;
-
-};
-
-void() door_group_go_up = {
- local entity oself, starte;
-
- oself = self;
- starte = self;
-
- do
- {
- door_go_up ();
- self = self.enemy;
- } while ( (self != starte) && (self != world) );
-
- self = oself;
-};
-
-/*
-=============================================================================
-
-ACTIVATION FUNCTIONS
-
-=============================================================================
-*/
-
-void() door_fire =
-{
-
- if (self.owner != self)
- objerror ("door_fire: self.owner != self");
-
- if (self.estate != STATE_ACTIVE)
- return;
-// self.noise4 is now played in keylock_try_to_unlock -- iw
-
- self.message = string_null; // no more message
-
-
- if (self.spawnflags & DOOR_TOGGLE)
- {
- if (self.state == STATE_UP || self.state == STATE_TOP)
- {
- door_group_go_down();
- return;
- }
- }
-
- // trigger all paired doors
- door_group_go_up();
-};
-
-
-void() door_use =
-{
- local entity oself;
-
- self.message = ""; // door message are for touch only
- self.owner.message = "";
- self.enemy.message = "";
- oself = self;
- self = self.owner;
- door_fire ();
- self = oself;
-};
-
-
-void() door_trigger_touch =
-{
- if (other.health <= 0)
- return;
-
- if (other.movetype == MOVETYPE_NOCLIP) // from copper -- dumptruck_ds
- return;
-
- if (time < self.attack_finished)
- return;
- self.attack_finished = time + 1;
-
- activator = other;
-
- self = self.owner;
- door_use ();
-};
-
-
-void() door_killed =
-{
- local entity oself;
-
- oself = self;
- self = self.owner;
- self.health = self.max_health;
- self.takedamage = DAMAGE_NO; // wil be reset upon return
- door_use ();
- self = oself;
-};
-
-
-/*
-================
-door_unlock
-
-Perform the actions which should be performed when self is successfully
-unlocked with a key.
-
-This function exists so that it can be passed as an argument to the new
-keylock_try_to_unlock function. This code was previously part of the
-door_touch function. -- iw
-================
-*/
-void() door_unlock =
-{
- if (!(self.spawnflags & DOOR_DOOM_STYLE_UNLOCK))
- {
- self.touch = SUB_Null;
- if (self.enemy)
- self.enemy.touch = SUB_Null; // get paired door
- }
- door_use ();
-};
-
-
-/*
-================
-door_touch
-
-Prints messages and opens key doors
-================
-*/
-void() door_touch =
-{
- // if (other.classname != "player")
- // return;
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- if (self.owner.attack_finished > time)
- return;
-
- self.owner.attack_finished = time + 2;
-
- if (self.owner.message != "")
- {
- centerprint (other, self.owner.message);
- sound (other, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
- }
-
-// key door stuff
- if (!keylock_has_key_set ())
- return;
-
- keylock_try_to_unlock (other, "", door_unlock);
-};
-
-
-
-/*
-=============================================================================
-ENTITY STATE FUNCTIONS
-=============================================================================
-*/
-
-void(entity e, float closealldoors) door_estate_lock = {
- local entity oself, next;
-
- if (e.owner.estate == STATE_INACTIVE) return;
-
- // blocks linked doors from updating the same owner repeatedly
- if (e.owner.last_setstate == self && e.owner.last_setstate_frame == framecount) return;
-
- oself = self;
- self = e.owner;
-
- self.estate = STATE_INACTIVE;
-
- self.last_setstate = oself;
- self.last_setstate_frame = framecount;
-
- self.prevstate = self.state;
-
- if (self.state == STATE_UP || self.state == STATE_TOP) {
- if (
- // don't close wait -1 nor toggleable doors...
- !(self.wait == -1 || (self.spawnflags & DOOR_TOGGLE))
- // ...unless the trigger_setstate has a "Close all doors" spawnflag on
- || closealldoors
- )
- door_group_go_down();
-
- }
-
- if (self.max_health) {
- next = self;
- do {
- //e.health = 0;
- next.takedamage = DAMAGE_NO;
- next = next.enemy;
- } while ( (next != self) && (next != world) );
- }
-
- self = oself;
-
-}
-
-void(entity e, float openalldoors) door_estate_unlock = {
- local entity oself, next;
-
- if (e.owner.estate == STATE_ACTIVE) return;
-
- // blocks linked doors from updating the same owner repeatedly
- if (e.owner.last_setstate == self && e.owner.last_setstate_frame == framecount) return;
-
- oself = self;
- self = e.owner;
-
- self.last_setstate = oself;
- self.last_setstate_frame = framecount;
-
- if (self.prevstate == STATE_UP || self.prevstate == STATE_TOP) {
- if (
- (self.wait == -1 || (self.spawnflags & DOOR_TOGGLE))
- && openalldoors
- ) door_group_go_up();
- }
-
- if (self.max_health) {
- next = self;
- do {
- next.health = next.max_health;
- next.takedamage = DAMAGE_YES;
- next = next.enemy;
- } while ( (next != self) && (next != world) );
- }
-
- self.estate = STATE_ACTIVE;
- self = oself;
-}
-
-
-/*
-=============================================================================
-
-SPAWNING FUNCTIONS
-
-=============================================================================
-*/
-
-
-entity(vector fmins, vector fmaxs) spawn_field =
-{
- local entity trigger;
- local vector t1, t2;
-
- trigger = spawn();
- trigger.movetype = MOVETYPE_NONE;
- trigger.solid = SOLID_TRIGGER;
- trigger.owner = self;
- trigger.touch = door_trigger_touch;
-
- t1 = fmins;
- t2 = fmaxs;
- setsize (trigger, t1 - '60 60 8', t2 + '60 60 8');
- return (trigger);
-};
-
-
-float (entity e1, entity e2) EntitiesTouching =
-{
- if (e1.mins_x > e2.maxs_x)
- return FALSE;
- if (e1.mins_y > e2.maxs_y)
- return FALSE;
- if (e1.mins_z > e2.maxs_z)
- return FALSE;
- if (e1.maxs_x < e2.mins_x)
- return FALSE;
- if (e1.maxs_y < e2.mins_y)
- return FALSE;
- if (e1.maxs_z < e2.mins_z)
- return FALSE;
- return TRUE;
-};
-
-
-/*
-=============
-LinkDoors
-
-
-=============
-*/
-void() LinkDoors =
-{
- local entity t, starte;
- local vector cmins, cmaxs;
-
- if (self.enemy)
- return; // already linked by another door
- if (self.spawnflags & 4)
- {
- self.owner = self.enemy = self;
- return; // don't want to link this door
- }
-
- cmins = self.mins;
- cmaxs = self.maxs;
-
- starte = self;
- t = self;
-
- do
- {
- self.owner = starte; // master door
-
- if (self.health)
- starte.health = self.health;
- if (self.targetname != "")
- starte.targetname = self.targetname;
- if (self.message != "")
- starte.message = self.message;
-
- t = find (t, classname, self.classname);
- if (!t)
- {
- self.enemy = starte; // make the chain a loop
-
- // shootable, fired, or key doors just needed the owner/enemy links,
- // they don't spawn a field
-
- self = self.owner;
-
- if (self.health)
- return;
- if (self.targetname != "")
- return;
- if (keylock_has_key_set ())
- return;
-
- self.owner.trigger_field = spawn_field(cmins, cmaxs);
-
- return;
- }
-
- if (EntitiesTouching(self,t))
- {
- if (t.enemy)
- objerror ("cross connected doors");
-
- self.enemy = t;
- self = t;
-
- if (t.mins_x < cmins_x)
- cmins_x = t.mins_x;
- if (t.mins_y < cmins_y)
- cmins_y = t.mins_y;
- if (t.mins_z < cmins_z)
- cmins_z = t.mins_z;
- if (t.maxs_x > cmaxs_x)
- cmaxs_x = t.maxs_x;
- if (t.maxs_y > cmaxs_y)
- cmaxs_y = t.maxs_y;
- if (t.maxs_z > cmaxs_z)
- cmaxs_z = t.maxs_z;
- }
- } while (1 );
-
-};
-
-
-/*QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK GOLD_KEY SILVER_KEY TOGGLE X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-if two doors touch, they are assumed to be connected and operate as a unit.
-
-TOGGLE causes the door to wait in both the start and end states for a trigger event.
-
-START_OPEN causes the door to move to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors).
-
-Key doors are always wait -1.
-
-"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet
-"angle" determines the opening direction
-"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door.
-"health" if set, door must be shot open
-"speed" movement speed (100 default)
-"wait" wait before returning (3 default, -1 = never return)
-"lip" lip remaining at end of move (8 default)
-"dmg" damage to inflict when blocked (2 default)
-"cnt" if 1, leave a used key in the player's inventory (0 default)
-"keyname" if set, this is the keyname of the item_key_custom which unlocks this entity
-"noise1" sound file for the "stop moving" sound (if set, overrides "sounds")
-"noise2" sound file for the "move" sound (if set, overrides "sounds")
-"noise3" sound file for the "key required" sound (default is per worldtype)
-"noise4" sound file for the "key used" sound (default is per worldtype)
-"sounds"
-0) no sound
-1) stone
-2) base
-3) stone chain
-4) screechy metal
-*/
-
-void() func_door =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- local string default_noise1;
- local string default_noise2;
- entity shadow;
- entity oldself;
-
-// self.noise3 and self.noise4 can now be overridden by the mapper, but
-// will be set to default values in keylock_init if necessary -- iw
- keylock_init ();
-
-// self.noise1 and self.noise2 can now be overridden by the mapper -- iw
- default_noise1 = "misc/null.wav";
- default_noise2 = "misc/null.wav";
- if (self.sounds == 1)
- {
- default_noise1 = "doors/drclos4.wav";
- default_noise2 = "doors/doormv1.wav";
- }
- if (self.sounds == 2)
- {
- default_noise1 = "doors/hydro2.wav";
- default_noise2 = "doors/hydro1.wav";
- }
- if (self.sounds == 3)
- {
- default_noise1 = "doors/stndr2.wav";
- default_noise2 = "doors/stndr1.wav";
- }
- if (self.sounds == 4)
- {
- default_noise1 = "doors/ddoor2.wav";
- default_noise2 = "doors/ddoor1.wav";
- }
-
- if (self.noise1 == "")
- self.noise1 = default_noise1;
- if (self.noise2 == "")
- self.noise2 = default_noise2;
-
- precache_sound (self.noise1);
- precache_sound (self.noise2);
-
- SetMovedir ();
-
- self.max_health = self.health;
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- setorigin (self, self.origin);
- setmodel (self, self.model);
- //self.classname = "door";
-
- self.blocked = door_blocked;
- self.use = door_use;
-
- if (self.spawnflags & DOOR_SILVER_KEY){
- keylock_set_silver_key ();
-
- if (self.keyname != "") {
- self.netname = self.keyname;
- self.keyname = "";
- }
- }
- if (self.spawnflags & DOOR_GOLD_KEY){
- keylock_set_gold_key ();
-
- if (self.keyname != "") {
- self.netname = self.keyname;
- self.keyname = "";
- }
- }
-
-// support for item_key_custom -- iw
- if (self.keyname != "")
- {
- keylock_set_custom_key (self.keyname);
- self.keyname = ""; // this should not be referenced again
- }
-
- if (!self.speed)
- self.speed = 100;
- if (!self.wait)
- self.wait = 3;
- if (!self.lip)
- self.lip = 8;
- if (!self.dmg)
- self.dmg = 2;
-
- self.pos1 = self.origin;
- self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
-
-// DOOR_START_OPEN is to allow an entity to be lighted in the closed position
-// but spawn in the open position
- if (self.spawnflags & DOOR_START_OPEN)
- {
- setorigin (self, self.pos2);
- self.pos2 = self.pos1;
- self.pos1 = self.origin;
- }
-
- self.state = STATE_BOTTOM;
-
- if (self.health)
- {
- self.takedamage = DAMAGE_YES;
- self.th_die = door_killed;
- }
-
- if (self.spawnflags & DOOR_DOOM_STYLE_UNLOCK)
- self.cnt = 1;
-
- if (keylock_has_key_set ())
- {
- if (!(self.spawnflags & DOOR_DOOM_STYLE_UNLOCK))
- {
- self.wait = -1;
- }
- }
- self.touch = door_touch;
-
-// LinkDoors can't be done until all of the doors have been spawned, so
-// the sizes can be detected properly.
- self.think = LinkDoors;
- self.nextthink = self.ltime + 0.1;
-
- // creates a shadow controller entity for the door if it has switchable shadows
- if(self.switchshadstyle) {
-
- shadow = spawn();
-
- self.shadowcontroller = shadow;
-
- shadow.classname = "misc_shadowcontroller";
- shadow.switchshadstyle = self.switchshadstyle;
- shadow.speed = vlen(self.pos2 - self.pos1) / self.speed;
-
- if(self.spawnflags & DOOR_START_OPEN) shadow.spawnflags = 1;
- else shadow.spawnflags = 0;
-
-
- oldself = self;
-
- self = shadow;
- misc_shadowcontroller();
-
- self = oldself;
- }
-};
-
-/*
-=============================================================================
-
-SECRET DOORS
-
-=============================================================================
-*/
-
-void() fd_secret_move1;
-void() fd_secret_move2;
-void() fd_secret_move3;
-void() fd_secret_move4;
-void() fd_secret_move5;
-void() fd_secret_move6;
-void() fd_secret_done;
-
-float SECRET_OPEN_ONCE = 1; // stays open
-float SECRET_1ST_LEFT = 2; // 1st move is left of arrow
-float SECRET_1ST_DOWN = 4; // 1st move is down from arrow
-float SECRET_NO_SHOOT = 8; // only opened by trigger
-float SECRET_YES_SHOOT = 16; // shootable even if targeted
-
-
-void () fd_secret_use =
-{
- local float temp;
-
- self.health = 10000;
-
- // exit if still moving around...
- if (self.origin != self.oldorigin)
- return;
-
- self.message = string_null; // no more message
-
- SUB_UseTargets(); // fire all targets / killtargets
-
- if (!(self.spawnflags & SECRET_NO_SHOOT))
- {
- self.th_pain = SUB_NullPain;
- self.takedamage = DAMAGE_NO;
- }
- self.velocity = '0 0 0';
-
- // Make a sound, wait a little...
-
- sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.nextthink = self.ltime + 0.1;
-
- temp = 1 - (self.spawnflags & SECRET_1ST_LEFT); // 1 or -1
- makevectors(self.mangle);
-
- if (!self.t_width)
- {
- if (self.spawnflags & SECRET_1ST_DOWN)
- self. t_width = fabs(v_up * self.size);
- else
- self. t_width = fabs(v_right * self.size);
- }
-
- if (!self.t_length)
- self. t_length = fabs(v_forward * self.size);
-
- if (self.spawnflags & SECRET_1ST_DOWN)
- self.dest1 = self.origin - v_up * self.t_width;
- else
- self.dest1 = self.origin + v_right * (self.t_width * temp);
-
- self.dest2 = self.dest1 + v_forward * self.t_length;
- SUB_CalcMove(self.dest1, self.speed, fd_secret_move1);
- sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
-};
-
-void(entity attacker, float damage) fd_secret_pain = { fd_secret_use(); };
-
-// Wait after first movement...
-void () fd_secret_move1 =
-{
- self.nextthink = self.ltime + 1.0;
- self.think = fd_secret_move2;
- sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
-};
-
-// Start moving sideways w/sound...
-void () fd_secret_move2 =
-{
- sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
- SUB_CalcMove(self.dest2, self.speed, fd_secret_move3);
-};
-
-// Wait here until time to go back...
-void () fd_secret_move3 =
-{
- sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
- if (!(self.spawnflags & SECRET_OPEN_ONCE))
- {
- self.nextthink = self.ltime + self.wait;
- self.think = fd_secret_move4;
- }
-};
-
-// Move backward...
-void () fd_secret_move4 =
-{
- sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
- SUB_CalcMove(self.dest1, self.speed, fd_secret_move5);
-};
-
-// Wait 1 second...
-void () fd_secret_move5 =
-{
- self.nextthink = self.ltime + 1.0;
- self.think = fd_secret_move6;
- sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
-};
-
-void () fd_secret_move6 =
-{
- sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
- SUB_CalcMove(self.oldorigin, self.speed, fd_secret_done);
-};
-
-void () fd_secret_done =
-{
- if (!self.targetname || self.spawnflags&SECRET_YES_SHOOT)
- {
- self.health = 10000;
- self.takedamage = DAMAGE_YES;
- self.th_pain = fd_secret_pain;
- }
- sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
-};
-
-void () secret_blocked =
-{
- if (time < self.attack_finished)
- return;
- self.attack_finished = time + 0.5;
- T_Damage (other, self, self, self.dmg);
-};
-
-/*
-================
-ouch
-
-Prints messages
-================
-*/
-void() secret_touch =
-{
-
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- if (self.attack_finished > time)
- return;
-
- self.attack_finished = time + 2;
-
- if (self.message != "")
- {
- centerprint (other, self.message);
- sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
- }
-};
-
-
-/*QUAKED func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Basic secret door. Slides back, then to the side. Angle determines direction.
-wait = # of seconds before coming back
-1st_left = 1st move is left of arrow
-1st_down = 1st move is down from arrow
-always_shoot = even if targeted, keep shootable
-t_width = override WIDTH to move back (or height if going down)
-t_length = override LENGTH to move sideways
-"dmg" damage to inflict when blocked (2 default)
-
-If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage.
-"sounds"
-1) medieval
-2) metal
-3) base
-*/
-
-void () func_door_secret =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.sounds == 0)
- self.sounds = 3;
- if (self.sounds == 1)
- {
- precache_sound ("doors/latch2.wav");
- precache_sound ("doors/winch2.wav");
- precache_sound ("doors/drclos4.wav");
- self.noise1 = "doors/latch2.wav";
- self.noise2 = "doors/winch2.wav";
- self.noise3 = "doors/drclos4.wav";
- }
- if (self.sounds == 2)
- {
- precache_sound ("doors/airdoor1.wav");
- precache_sound ("doors/airdoor2.wav");
- self.noise2 = "doors/airdoor1.wav";
- self.noise1 = "doors/airdoor2.wav";
- self.noise3 = "doors/airdoor2.wav";
- }
- if (self.sounds == 3)
- {
- precache_sound ("doors/basesec1.wav");
- precache_sound ("doors/basesec2.wav");
- self.noise2 = "doors/basesec1.wav";
- self.noise1 = "doors/basesec2.wav";
- self.noise3 = "doors/basesec2.wav";
- }
-
- if (!self.dmg)
- self.dmg = 2;
-
- // Magic formula...
- self.mangle = self.angles;
- self.angles = '0 0 0';
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- //self.classname = "door";
- setmodel (self, self.model);
- setorigin (self, self.origin);
-
- self.touch = secret_touch;
- self.blocked = secret_blocked;
- self.speed = 50;
- self.use = fd_secret_use;
- if ( !self.targetname || self.spawnflags&SECRET_YES_SHOOT)
- {
- self.health = 10000;
- self.takedamage = DAMAGE_YES;
- self.th_pain = fd_secret_pain;
- self.th_die = fd_secret_use;
- }
- self.oldorigin = self.origin;
- if (!self.wait)
- self.wait = 5; // 5 seconds before closing
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/dtmisc.qc

diff --git a/qc-server/dtmisc.qc b/qc-server/dtmisc.qc
deleted file mode 100644
index c850f83..0000000
--- a/qc-server/dtmisc.qc
+++ /dev/null
@@ -1,1176 +0,0 @@
-//a collection of various pieces of mods and some new code -- dumptruck_ds
-
-/* Miscelanneous QuickC program
- Copyright (c)1996 Hipnotic Interactive, Inc.
- All rights reserved.
- Distributed (unsupported) on 3.12.97
-*/
-
-void() play_sound_use =
- {
- if (self.spawnflags & 1)
- {
- if (self.state == 0)
- {
- self.state = 1;
- sound (self, self.impulse, self.noise, self.volume, self.speed);
- }
- else
- {
- self.state = 0;
- sound (self, self.impulse, "misc/null.wav", self.volume, self.speed);
- }
- }
- else
- {
- sound (self, self.impulse, self.noise, self.volume, self.speed);
- }
- };
-
-void() PlaySoundThink =
- {
- local float t;
- t = self.wait * random();
- if (t < self.delay)
- t = self.delay;
- self.nextthink = time + t;
- play_sound_use();
- };
-
-/*QUAKED play_sound_triggered (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) toggle
-play a sound when it is used
-"toggle" determines whether sound should be stopped when triggered again
-"volume" how loud (1 default full volume)
-"noise" sound to play
-"impulse" channel on which to play sound (0-7) (0 automatic is default)
-"speed" attenuation factor
- -1 - no attenuation
- 1 - normal
- 2 - idle
- 3 - static
-*/
-void() play_sound_triggered =
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.noise) //dumptruck_ds
- {
- objerror ("no soundfile set in noise!\n");
- remove(self);
- return;
- }
-
- precache_sound (self.noise);
- precache_sound ("misc/null.wav");
- if (self.volume == 0)
- self.volume = 1;
- if (self.speed == 0)
- self.speed = 1;
- if (self.speed == -1)
- // self.speed = 0;
- self.speed = ATTN_NONE;
- if (self.spawnflags & 1)
- if (self.impulse == 0)
- self.impulse = 7;
- self.use = play_sound_use;
- };
-
-/*QUAKED play_sound (0.3 0.1 0.6) (-8 -8 -8) (8 8 8)
-play a sound on a periodic basis
-"volume" how loud (1 default full volume)
-"noise" sound to play
-"wait" random time between sounds (default 20)
-"delay" minimum delay between sounds (default 2)
-"impulse" channel on which to play sound (0-7) (0 automatic is default)
-"speed" attenuation factor
- -1 - no attenuation
- 1 - normal
- 2 - idle
- 3 - static
-*/
-void() play_sound =
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- local float t;
-
- if (!self.noise) //dumptruck_ds
- {
- objerror ("no soundfile set in noise!\n");
- remove(self);
- return;
- }
-
-
- play_sound_triggered();
- if (self.wait == 0)
- self.wait = 20;
- if (self.delay == 0)
- self.delay = 2;
- self.think = PlaySoundThink;
- t = self.wait * random();
- if (t < self.delay)
- t = self.delay;
- self.nextthink = time + t;
- };
-
-
- //johnfitz -- ambient_general (this is from Rubicon Rumble dev kit)
-
-/*QUAKED ambient_general (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Plays any looped sound
-
-Keys:
-
-"noise" is the wav file to play
-
-"volume" default 1
-
-"speed" attenuation, default 3
-*/
-void () ambient_general =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.noise) //dumptruck_ds
- {
- objerror ("no soundfile set in noise!\n");
- remove(self);
- return;
- }
-
- precache_sound (self.noise);
- if (!self.speed)
- {
- self.speed = ATTN_NORM;
- }
- if (self.speed == 0)
- self.speed = 1;
- if (self.speed == -1)
- // self.speed = 0;
- self.speed = ATTN_NONE;
- if (!self.volume)
- {
- self.volume = 0.5;
- }
- ambientsound (self.origin, self.noise, self.volume, self.speed);
- remove(self);
-};
-//johnfitz
-
-/*QUAKED tele_fog (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
-
-When triggered, tele_fog shows the teleport particle effects and sounds.
-
-Use this when killtageting an entity if the player can see.
-
-*/
-
-void () play_tfog = //thanks Khreathor -- dumptruck_ds
-
-{
- spawn_tfog(self.origin);
-}
-
-void() tele_fog =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = play_tfog;
-};
-
-/*QUAKED play_tele (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
-
-When triggered, tele_fog shows the teleport particle effects and sounds.
-Same os tele_fog.
-
-Use this when killtageting an entity if the player can see.
-
-*/
-void() play_tele = //same as tele_fog, added for "play_xxxx" consistancy
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = play_tfog;
-};
-
-/*QUAKED play_explosion (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
-
-When triggered, creates a explosion at it's origin. Causes damage.
-
-*/
-
-void () play_explosion_fx = //thanks Khreathor -- dumptruck_ds
-
-{
- self.owner = self; // GrenadeExplode uses self.owner as the attacker -- iw
- GrenadeExplode();
-}
-
-void() play_explosion =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = play_explosion_fx;
-};
-
-/*QUAKED play_lavasplash (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
-
-When triggered, plays the lavasplash effect from E1M7.
-
-Use noise key for a custom sound.
-
-*/
-
-void () play_lavasplash_fx = //thanks Khreathor -- dumptruck_ds
-{
- if (self.noise != "")
- {
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
- else
- {
- sound (self, CHAN_AUTO, "boss1/out1.wav", 1, ATTN_NORM);
- }
-WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
-WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
-WriteCoord (MSG_BROADCAST, self.origin_x);
-WriteCoord (MSG_BROADCAST, self.origin_y);
-WriteCoord (MSG_BROADCAST, self.origin_z);
-};
-
-void () play_lavasplash =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.noise != "") precache_sound (self.noise);
- precache_sound("boss1/out1.wav");
- self.use = play_lavasplash_fx;
-};
-
-/*QUAKED meat_shower (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
-
-When triggered, plays a gib effect.
-
-Use style 0 for normal and 1 for extra large. fly_sound 0 is silent, 1 for regular gib sounds.
-
-*/
-
-void () play_meatspray = //-- dumptruck_ds -- thanks to Spike for helping with errors
-{
- if (self.style == 1)
- {
- ThrowGib ("progs/gib1.mdl", random()*-80);
- ThrowGib ("progs/gib2.mdl", random()*-80);
- ThrowGib ("progs/gib3.mdl", random()*-80);
- ThrowGib ("progs/gib1.mdl", random()*-75);
- ThrowGib ("progs/gib2.mdl", random()*-75);
- ThrowGib ("progs/gib3.mdl", random()*-75);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", random()*-65);
- ThrowGib ("progs/gib2.mdl", random()*-65);
- ThrowGib ("progs/gib3.mdl", random()*-65);
- }
- {
- if (self.fly_sound != 1)
- return;
- }
- {
- if (random() < 0.5)
- sound (self, CHAN_VOICE, "player/gib.wav", 1, ATTN_NORM);
- else
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
-}
-};
-
-void() meat_shower =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = play_meatspray;
-}
-
-/*QUAKED play_gibs (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
-
-When triggered, plays a gib effect. Same as meat_shower.
-
-Use style 0 for normal and 1 for extra large. fly_sound 0 is silent, 1 for regular gib sounds.
-
-*/
-void() play_gibs = //same as meat_shower, added for "play_xxxx" consistancy
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = play_meatspray;
-}
-
-void() mflash_use =
-{
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- if (self.noise != "")
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
-};
-
-/*QUAKED play_mflash (0 .5 .8) (-8 -8 -8) (8 8 8)
-triggable muzzle flash effect entity
-*/
-
-void() play_mflash =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/s_null.spr");
- if (self.noise != "") precache_sound (self.noise);
-
- setmodel (self, "progs/s_null.spr");
- setorigin (self, self.origin);
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- setsize (self, '0 0 0', '0 0 0');
- self.use = mflash_use;
-};
-
-//
-// play_bfield triggerable effect
-//
-
-void() bfield_toggle =
-{
- if (!self.state)
- {
- self.state = 1;
- self.effects = self.effects | EF_BRIGHTFIELD;
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
- else
- {
- self.state = 0;
- self.effects = self.effects - (self.effects & EF_BRIGHTFIELD);
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
-};
-
-/*QUAKED play_bfield (0 .5 .8) (-8 -8 -8) (8 8 8)
-a triggerable, spherical field of yellow particles
-state 1 = start on
-*/
-
-void() play_bfield =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/s_null.spr");
- if (self.noise != "") precache_sound (self.noise);
-
- setmodel (self, "progs/s_null.spr");
- setorigin( self, self.origin);
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- setsize (self, '0 0 0', '0 0 0');
- if (self.state)
- self.effects = self.effects | EF_BRIGHTFIELD;
- self.use = bfield_toggle;
-};
-
-//
-// play_brlight triggerable effect
-//
-
-void() brlight_toggle = //dumptruck_ds -- thanks to c0burn
-{
- if (!self.state)
- {
- self.state = 1;
- self.effects = self.effects | EF_BRIGHTLIGHT;
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
- else
- {
- self.state = 0;
- self.effects = self.effects - (self.effects & EF_BRIGHTLIGHT);
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
-};
-
-/*QUAKED play_brlight (0 .5 .8) (-8 -8 -8) (8 8 8)
-a triggerable bright lighting effect
-state 1 = start on
-*/
-
-void() play_brlight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/s_null.spr");
- if (self.noise != "") precache_sound (self.noise);
-
- setmodel (self, "progs/s_null.spr");
- setorigin (self, self.origin);
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- setsize (self, '0 0 0', '0 0 0');
- if (self.state)
- self.effects = self.effects | EF_BRIGHTLIGHT;
- self.use = brlight_toggle;
-};
-//
-// play_dimlight triggerable effect
-//
-void() dim_toggle =
-{
- if (!self.state)
- {
- self.state = 1;
- self.effects = self.effects | EF_DIMLIGHT;
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
- else
- {
- self.state = 0;
- self.effects = self.effects - (self.effects & EF_DIMLIGHT);
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
-};
-
-/*QUAKED play_dimlight (0 .5 .8) (-8 -8 -8) (8 8 8)
-a triggerable lighting effect
-state 1 = start on
-*/
-
-void() play_dimlight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/s_null.spr");
- if (self.noise != "") precache_sound (self.noise);
-
- setmodel (self, "progs/s_null.spr");
- // setorigin (self, self.origin);
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- setsize (self, '0 0 0', '0 0 0');
- if (self.state)
- self.effects = self.effects | EF_DIMLIGHT;
- setorigin (self, self.origin);
- self.use = dim_toggle;
-};
-
-/* misc gore */
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-/*
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-deadstuff version 1.0 - tony collen - manero@canweb.net - EfNet IRC #QuakeEd or #Trinity
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-*/
-
-/*QUAKED gib_head_demon (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_demon.mdl");
-}
-*/
-void() gib_head_demon =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_demon.mdl");
- setmodel(self, "progs/h_demon.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-13.64 -16.77 -0.11','17.44 16.22 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_dog (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_dog.mdl");
-}
-*/
-void() gib_head_dog =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_dog.mdl");
- setmodel(self, "progs/h_dog.mdl");
- self.frame = 0; //was 1 -- dumptruck_ds
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-9.66 -11.89 -0.2','6.57 7.96 13.29');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_army (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_guard.mdl");
-}
-*/
-void() gib_head_army =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_guard.mdl");
- setmodel(self, "progs/h_guard.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-9.67 -8.27 -0.28','4.05 4.8 13.41');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_hell_knight (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_hellkn.mdl");
-}*/
-void() gib_head_hell_knight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_hellkn.mdl");
- setmodel(self, "progs/h_hellkn.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-7.9 -12.97 -0.63','10.55 8.87 21.06');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_knight (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_knight.mdl");
-}*/
-void() gib_head_knight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_knight.mdl");
- setmodel(self, "progs/h_knight.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-8.17 -7.47 -0.13','8.36 6.5 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_enforcer (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_mega.mdl");
-}
-*/
-void() gib_head_enforcer =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_mega.mdl");
- setmodel(self, "progs/h_mega.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-10.63 -10.23 -0.05','9.27 8.25 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_ogre (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_ogre.mdl");
-}*/
-void() gib_head_ogre =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_ogre.mdl");
- setmodel(self, "progs/h_ogre.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-12.35 -15.7 -0.17','10.67 13.88 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_player (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_player.mdl");
-}*/
-void() gib_head_player =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_player.mdl");
- setmodel(self, "progs/h_player.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-9.67 -12.38 -2.1','11.49 50.7 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_shalrath (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_shal.mdl");
-}*/
-void() gib_head_shalrath =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_shal.mdl");
- setmodel(self, "progs/h_shal.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-19.85 -19.09 -1.44','13.72 16.8 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_shambler (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_shams.mdl");
-}*/
-void() gib_head_shambler =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_shams.mdl");
- setmodel(self, "progs/h_shams.mdl");
- self.frame = 0; //was 1, caused an error -- dumptruck_ds
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-15.15 -20.638 -0.45','21.44 21.76 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_wizard (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_wizard.mdl");
-}*/
-void() gib_head_wizard =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_wizard.mdl");
- setmodel(self, "progs/h_wizard.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-10.41 -8.66 -0.54','6.52 10.82 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_misc_1 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/gib1.mdl");
-}*/
-void() gib_misc_1 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/gib1.mdl");
- setmodel(self, "progs/gib1.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-3.57 -8.06 -3.34','3.69 8.31 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_misc_2 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/gib2.mdl");
-}*/
-void() gib_misc_2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/gib2.mdl");
- setmodel(self, "progs/gib2.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-12.68 -14.83 -6.19','13.53 14.57 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_misc_3 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/gib3.mdl");
-}*/
-void() gib_misc_3 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/gib3.mdl");
- setmodel(self, "progs/gib3.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-18.95 -15.92 -3.13','13.17 15.66 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-/* END Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-// /*==============================================================================
-// func_fall from RennyC
-//
-// A brush that drops and fades away when touched or triggered.
-//
-// dumptruck_ds
-// noise = sound to play when triggered
-// wait = wait this long before falling
-// ==============================================================================*/
-float DONT_FADE = 1;
-float SILENT = 2;
-
-void() func_fall_think =
-{
- if (self.cnt == TRUE && self.attack_finished < time)
- {
- self.solid = SOLID_BBOX;
- // self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_TOSS;
-
- if (!(self.spawnflags & DONT_FADE))
- {
-
- if (self.alpha > 0.1)
- self.alpha = self.alpha - 0.03;
- else
- {
- remove(self);
- return;
- }
- }
- }
- self.nextthink = time + 0.1;
-};
-
-void() fall_touch =
-{
- if (other.classname == "player")
- {
- if (!(other.flags & FL_ONGROUND))
- other.flags = other.flags | FL_ONGROUND;
- }
-
- else if (other.flags & FL_MONSTER)
- T_Damage (other, self, other, 50000);
-
- else
- return;
-
- if (self.cnt == TRUE)
- return;
-
- self.attack_finished = time + self.wait;
- self.cnt = TRUE;
-
- if (!(self.spawnflags & SILENT))
- {
- if (self.noise != "")
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- else
- sound (self, CHAN_AUTO, "buttons/switch21.wav", 1, ATTN_NORM);
- }
-};
-
-void() fall_use = // thanks again RennyC for help on revisions --dumptruck_ds
- {
- self.attack_finished = time + self.wait;
- self.cnt = TRUE;
-
- if (self.noise != "")
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- else
- sound (self, CHAN_AUTO, "buttons/switch21.wav", 1, ATTN_NORM);
- };
-
-/*QUAKED func_fall (0 .5 .8) ? DONT_FADE X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-A brush that drops and fades away when touched and/or triggered.
-Add some spice to your jumping puzzles or other scripted sequences!
-Monsters will not trigger func_fall but will be gibbed if one falls on them.
-NOTE: When a func_fall brush touches another brush or entity it will stop, which can look odd in certain situations.
-noise = sound to play when triggered, the default is a switch sound.
-wait = wait this long before falling.
-Use the DONT_FADE spawnflag if desired.
-
-Falling brush upon touch
-*/
-
-void() func_fall =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound("buttons/switch21.wav");
- if (self.noise != "") precache_sound (self.noise);
-
-
- self.alpha = 1;
- self.cnt = FALSE;
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- self.think = func_fall_think;
- self.nextthink = time;
- self.touch = fall_touch;
- self.use = fall_use;
- setmodel (self, self.model);
-};
-
-//=START PARTICLE-STREAM==================================================
-// from Zerstrorer mod -- dumptruck_ds
-
-void(vector start, vector end, float color1, float color2, float pdensity) Particle_Beam =
-{
-local vector spray, next;
-local float dist, loop, clr;
-
- clr = color1;
- spray = start - end;
- dist = vlen(spray);
- loop = dist / 24;
- spray = normalize(spray);
- next = spray * 24;
- while(loop > 0)
- {
- particle (end, spray, clr, pdensity);
- end = end + next;
- loop = loop - 1;
- if (clr == color1)
- clr = color2;
- else
- clr = color1;
- }
-};
-
-
-void() particle_use =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- Particle_Beam(self.origin, self.enemy.origin, self.dmg, self.cnt, 15); // was 40 - too many particles for my taste --dumptruck_ds
-};
-
-void() particle_stream_start =
-{
-local entity pspot;
-
- pspot = find(world, targetname, self.target);
- if(!pspot)
- {
- dprint("Particle stream can't find target!");
- return;
- }
-
- self.enemy = pspot;
-};
-
-/*QUAKED misc_particle_stream (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-A particle stream! It appears when triggered. This entity is
-one end of the stream, target another entity as the other end-point.
-I used the info_notnull, but you should be able to target anything
-(like monsters).
-
-"target" This entities origin is the end-point of the stream
-"dmg" 1st Color - Use if you want a single color stream
-"cnt" 2nd Color - Mixes particles of both colors
-"noise" Sound to play when triggered
-*/
-void() misc_particle_stream =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if(!self.target)
- objerror("misc_particle_stream with not target!");
-
- if(!self.dmg)
- self.dmg = 73;
- if(!self.cnt)
- self.cnt = self.dmg;
- if(!self.noise)
- self.noise = "misc/null.wav";
-
- precache_sound(self.noise);
-
- self.use = particle_use;
- self.think = particle_stream_start;
- self.nextthink = time + 0.2;
-};
-// from custents, modified by dumptruck_ds
-//##########################################
-//#### HEAL TRIGGER ####
-//##########################################
-// Original entity submitted by Jan Martin Mathiassen, aka. TGR
-
-void() heal_think =
-{
- if (self.cnt == self.count)
- {
- dprint("trigger_heal think: full\n");
- self.think = SUB_Null;
- return;
- }
- local float recharge_amount = self.speed;
- if (self.count < (self.cnt + self.speed))
- {
- recharge_amount = self.count - self.cnt;
- }
- dprint("trigger_heal think: [max: ");
- dprint(ftos(self.count));
- dprint(", current: ");
- dprint(ftos(self.cnt));
- dprint(", recharging: ");
- dprint(ftos(recharge_amount));
- dprint("]\n");
-
- self.cnt = self.cnt + recharge_amount;
- self.nextthink = time + self.delay;
-};
-
-void() heal_touch =
-{
- if (self.estate != STATE_ACTIVE)
- return;
- if (other.movetype == MOVETYPE_NOCLIP) // from Copper -- dumptruck_ds
- return FALSE;
- if(self.spawnflags & HEAL_PLAYER_ONLY && other.classname != "player")
- return;
- if(self.spawnflags & HEAL_MONSTER_ONLY && !(other.flags & FL_MONSTER))
- return;
- if(other.classname != "player" && !(other.flags & FL_MONSTER))
- return;
-
- if(other.heal_timer > time)
- return;
-
- if(self.count && self.cnt <= 0)
- {
- if(self.message2)
- centerprint(other, self.message2);
- return;
- }
-
- if ((other.takedamage) && (other.health < self.health_max))
- {
-
- if (self.noise != "")
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- else
- sound (self, CHAN_AUTO, "items/r_item1.wav", 1, ATTN_NORM);
- local float calculated_healing;
- if ((other.health + self.heal_amount) > self.health_max)
- {
- calculated_healing = self.health_max - other.health;
- }
- else
- {
- calculated_healing = self.heal_amount;
- }
-
- if (self.count)
- {
-
- if (calculated_healing > self.cnt)
- {
- calculated_healing = self.cnt;
- }
- self.cnt = self.cnt - calculated_healing;
- if (self.delay)
- {
- self.think = heal_think;
- self.nextthink = time + self.delay;
- }
- dprint("trigger_heal used: [max: ");
- dprint(ftos(self.count));
- dprint(", current: ");
- dprint(ftos(self.cnt));
- dprint(", using: ");
- dprint(ftos(calculated_healing));
- dprint("]\n");
- }
- if (self.message)
- {
- centerprint(other, self.message);
- }
- T_Heal (other, calculated_healing, 1);
- other.heal_timer = time + self.wait;
- }
-};
-
-void() heal_toggle=
-{
- if(self.touch == SUB_Null)
- self.touch = heal_touch;
- else
- self.touch = SUB_Null;
-};
-
-/*QUAKED trigger_heal (.5 .5 .5) ? HEAL_START_ON HEAL_PLAYER_ONLY HEAL_MONSTER_ONLY X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Any object touching this will be healed
-heal_amount -- the amount to heal each time (default 5)
-wait -- the time between each healing (default 1)
-health_max -- the upper limit for the healing (default 100, max 250)
-sounds -- set to 1 to enable the noise1 field for custom healing sound
-noise -- path to custom sound file
-message -- message to print on heal
-count -- maximum heal before exhausted
-speed -- amount to recharge at a time
-delay -- time before recharging
-message2 -- message to print when exhausted
-*/
-void() trigger_heal =
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
- //play custom sound for healing if noise key exists
- precache_sound("items/r_item1.wav");
- if (self.noise != "") precache_sound (self.noise);
-
- InitTrigger ();
-
- if (self.wait == 0)
- self.wait = 1;
- if (self.heal_amount == 0)
- self.heal_amount = 5;
- if (self.health_max == 0)
- self.health_max = 100;
- else if (self.health_max > 250)
- self.health_max = 250;
-
- if (self.count)
- {
- self.cnt = self.count;
-
- if (self.speed && !self.delay)
- {
- self.delay = 10;
- } else if (!self.speed && self.delay)
- {
- self.speed = 5;
- }
- }
-
- // if(self.targetname)
- // {
- // self.use = heal_toggle;
- // if(self.spawnflags & HEAL_START_ON)
- // self.touch = heal_touch;
- // else
- // self.touch = SUB_Null;
- // }
- // else
- self.touch = heal_touch;
-
- SUB_CheckWaiting();
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/dtquake.qc

diff --git a/qc-server/dtquake.qc b/qc-server/dtquake.qc
deleted file mode 100644
index e3b0c83..0000000
--- a/qc-server/dtquake.qc
+++ /dev/null
@@ -1,103 +0,0 @@
-// /*this is a point entity from Rubicon Rumble Pack Devkit; REQUIRES A TARGETNAME*/
-//
-// // ===== TRIGGER_SHAKE =======================================================
-//
-float VIEWONLY = 1;
-
-void() shake_think =
-{
- if (self.attack_finished < time) // Done
- {
- self.nextthink = -1;
-
- if (self.noise1 != "")
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
-
- return;
- }
-
- local entity plyr;
-
- // Shake all players in the effect radius...
-
- plyr = findradius(self.origin, self.count);
-
- while(plyr)
- {
- if (plyr.flags & FL_CLIENT)
- {
- local float d;
-
- // Scale effect by distance
- d = vlen(self.origin - plyr.origin);
- d = (self.count - d)/self.count;
-
- if (d > 0)
- {
- // shake up the view
- plyr.punchangle_x = -1 * (random() + (0.025*self.dmg*d));
-
- // push the player around
- if (plyr.flags & FL_ONGROUND && !(self.spawnflags & VIEWONLY))
- {
- d = self.dmg*d;
- plyr.velocity_x = plyr.velocity_x + (random()*d*2 - d);
- plyr.velocity_y = plyr.velocity_y + (random()*d*2 - d);
- plyr.velocity_z = plyr.velocity_z + (random()*d);// always push up
- }
- }
- }
-
- plyr = plyr.chain;
- }
-
- // keep going
- self.nextthink = time + 0.1;
-};
-
-void() shake_use =
-{
- if (self.attack_finished > time) return;// already active
-
- // Start...
-
- if (self.noise != "")
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
-
- self.attack_finished = time + self.wait;
- self.nextthink = time + 0.1;
-};
-
-/*QUAKED trigger_shake (.5 0 .5) (-8 -8 -8) (8 8 8) VIEWONLY X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Earthquake trigger - shakes players in it's radius when active.
-Strength of tremor is greatest at the centre.
-dmg Strength at center (default is 120)
-wait Duration of shake (default is 1)
-count Affect radius (defalt is 200)
-noise Noise to play when starting to shake
-noise1 Noise to play when stopping
-targetname Must be triggered
-Spawnflags
-VIEWONLY Shakes the view, but player movement is not affected
-*/
-void() trigger_shake =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.targetname) objerror("trigger_shake without name");
-
- if (self.noise != "") precache_sound (self.noise);
- if (self.noise1 != "") precache_sound (self.noise1);
-
- if (!self.dmg) self.dmg = 120;
- if (self.count <= 0) self.count = 200;
- if (self.wait <= 0) self.wait = 1.0;
-
- setorigin(self, self.origin);
-
- self.nextthink = -1;
- self.think = shake_think;
- self.use = shake_use;
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/fight.qc

diff --git a/qc-server/fight.qc b/qc-server/fight.qc
deleted file mode 100644
index bbd7ecc..0000000
--- a/qc-server/fight.qc
+++ /dev/null
@@ -1,509 +0,0 @@
-
-/*
-
-A monster is in fight mode if it thinks it can effectively attack its
-enemy.
-
-When it decides it can't attack, it goes into hunt mode.
-
-*/
-
-float(float v) anglemod;
-
-void() knight_atk1;
-void() knight_runatk1;
-void() ogre_smash1;
-void() ogre_swing1;
-
-void() sham_smash1;
-void() sham_swingr1;
-void() sham_swingl1;
-
-float() DemonCheckAttack;
-void(float side) Demon_Melee;
-
-void(vector dest) ChooseTurn;
-
-void() ai_face;
-
-
-float enemy_vis, enemy_infront, enemy_range;
-float enemy_yaw;
-void() zombie_turret_missile;
-
-void() knight_attack =
-{
- local float len;
-
-// decide if now is a good swing time
- len = vlen(self.enemy.origin+self.enemy.view_ofs - (self.origin+self.view_ofs));
-
- if (len<80)
- knight_atk1 ();
- else
- knight_runatk1 ();
-};
-
-//=============================================================================
-
-/*
-===========
-CheckAttack
-
-The player is in view, so decide to move or launch an attack
-Returns FALSE if movement should continue
-============
-*/
-float() CheckAttack =
-{
- local vector spot1, spot2;
- local entity targ;
- local float chance;
-
- if (self.spawnflags & I_AM_TURRET) //dumptruck_ds
- {
- // dprint("CheckAttack...\n");
- if ((self.classname) == ("monster_enforcer"))
- {
- if (self.style == 4) // lightning can only go so far
- {
- if (vlen(spot1 - spot2) > 900)
- {
- return FALSE;
- }
- }
- self.attack_state = AS_MISSILE;
- }
- else if ((self.classname) == ("monster_hell_knight"))
- {
- if (self.style == 1) // lightning can only go so far
- {
- if (vlen(spot1 - spot2) > 900)
- {
- return FALSE;
- }
- }
- // self.attack_state = AS_MISSILE;
- self.th_turret ();
- }
- else if ((self.classname) == ("monster_shalrath"))
- {
- self.th_turret ();
- }
- else if ((self.classname) == ("monster_zombie"))
- {
- // dprint("CheckAttack...\n");
- zombie_turret_missile();
- }
- SUB_AttackFinished (2*random());
- return TRUE;
- }
-
- targ = self.enemy;
-
-// see if any entities are in the way of the shot
- spot1 = self.origin + self.view_ofs;
- spot2 = targ.origin + targ.view_ofs;
-
- traceline (spot1, spot2, FALSE, self);
-
- if ((self.spawnflags & I_AM_TURRET) && (trace_ent != targ))
- {
- // dprint("trace_ent...\n");
- self.attack_state = AS_TURRET;
- return FALSE;
- }
-
- if (trace_inopen && trace_inwater)
- return FALSE; // sight line crossed contents
-
- if (trace_ent != targ)
- return FALSE; // don't have a clear shot
-
- if (enemy_range == RANGE_MELEE)
- { // melee attack
- if (self.th_melee)
- {
- if (self.classname == "monster_knight")
- knight_attack ();
- else
- self.th_melee ();
- return TRUE;
- }
- }
-
-// missile attack
- if (!self.th_missile)
- return FALSE;
-
- if (time < self.attack_finished)
- return FALSE;
-
- if (enemy_range == RANGE_FAR)
- return FALSE;
-
- if (enemy_range == RANGE_MELEE)
- {
- chance = 0.9;
- self.attack_finished = 0;
- }
- else if (enemy_range == RANGE_NEAR)
- {
- if (self.th_melee)
- chance = 0.2;
- else
- chance = 0.4;
- }
- else if (enemy_range == RANGE_MID)
- {
- if (self.th_melee)
- chance = 0.05;
- else
- chance = 0.1;
- }
- else
- chance = 0;
-
- if (random () < chance)
- {
- self.th_missile ();
- SUB_AttackFinished (2*random());
- return TRUE;
- }
-
- return FALSE;
-};
-
-
-/*
-=============
-ai_face
-
-Stay facing the enemy
-=============
-*/
-void() ai_face =
-{
- self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
- ChangeYaw ();
-};
-
-/*
-=============
-ai_charge
-
-The monster is in a melee attack, so get as close as possible to .enemy
-=============
-*/
-float (entity targ) visible;
-float(entity targ) infront;
-float(entity targ) range;
-
-void(float d) ai_charge =
-{
- ai_face ();
- movetogoal (d); // done in C code...
-};
-
-void() ai_charge_side =
-{
- local vector dtemp;
- local float heading;
-
-// aim to the left of the enemy for a flyby
-
- self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
- ChangeYaw ();
-
- makevectors (self.angles);
- dtemp = self.enemy.origin - 30*v_right;
- heading = vectoyaw(dtemp - self.origin);
-
- walkmove(heading, 20);
-};
-
-
-/*
-=============
-ai_melee
-
-=============
-*/
-void() ai_melee =
-{
- local vector delta;
- local float ldmg;
-
- if (!self.enemy)
- return; // removed before stroke
-
- delta = self.enemy.origin - self.origin;
-
- if (vlen(delta) > 60)
- return;
-
- ldmg = (random() + random() + random()) * 3;
- T_Damage (self.enemy, self, self, ldmg);
-};
-
-
-void() ai_melee_side =
-{
- local vector delta;
- local float ldmg;
-
- if (!self.enemy)
- return; // removed before stroke
-
- ai_charge_side();
-
- delta = self.enemy.origin - self.origin;
-
- if (vlen(delta) > 60)
- return;
- if (!CanDamage (self.enemy, self))
- return;
- ldmg = (random() + random() + random()) * 3;
- T_Damage (self.enemy, self, self, ldmg);
-};
-
-
-//=============================================================================
-
-/*
-===========
-SoldierCheckAttack
-
-The player is in view, so decide to move or launch an attack
-Returns FALSE if movement should continue
-============
-*/
-float() SoldierCheckAttack =
-{
- local vector spot1, spot2;
- local entity targ;
- local float chance;
-
- // dprint("SoldierAttack\n");
- if (self.spawnflags & I_AM_TURRET) //dumptruck_ds
- {
- // self.th_turret ();
- self.attack_state = AS_MISSILE;
- SUB_AttackFinished (1 + random());
- if (random() < 0.3)
- self.lefty = !self.lefty;
- return TRUE;
- }
-
- targ = self.enemy;
-
-// see if any entities are in the way of the shot
- spot1 = self.origin + self.view_ofs;
- spot2 = targ.origin + targ.view_ofs;
-
- traceline (spot1, spot2, FALSE, self);
-
- if (trace_inopen && trace_inwater)
- return FALSE; // sight line crossed contents
-
- if ((self.spawnflags & I_AM_TURRET) && (trace_ent != targ))
- {
- // dprint("trace_ent...\n");
- self.attack_state = AS_TURRET;
- return FALSE;
- }
-
- if (trace_ent != targ)
- return FALSE; // don't have a clear shot
-
-// missile attack
- if (time < self.attack_finished)
- return FALSE;
-
- if (enemy_range == RANGE_FAR)
- return FALSE;
-
- if (enemy_range == RANGE_MELEE)
- chance = 0.9;
- else if (enemy_range == RANGE_NEAR)
- chance = 0.4;
- else if (enemy_range == RANGE_MID)
- chance = 0.05;
- else
- chance = 0;
-
- if (random () < chance)
- {
- self.th_missile ();
- SUB_AttackFinished (1 + random());
- if (random() < 0.3)
- self.lefty = !self.lefty;
-
- return TRUE;
- }
-
- return FALSE;
-};
-//=============================================================================
-
-/*
-===========
-ShamCheckAttack
-
-The player is in view, so decide to move or launch an attack
-Returns FALSE if movement should continue
-============
-*/
-float() ShamCheckAttack =
-{
- local vector spot1, spot2;
- local entity targ;
-
- if (enemy_range == RANGE_MELEE)
- {
- if (CanDamage (self.enemy, self))
- {
- self.attack_state = AS_MELEE;
- return TRUE;
- }
- }
-
- if (self.spawnflags & I_AM_TURRET)
- {
- self.attack_state = AS_MISSILE;
- SUB_AttackFinished (2 + 2*random());
- return TRUE;
- }
-
- if (time < self.attack_finished)
- return FALSE;
-
- if (!enemy_vis)
- return FALSE;
-
- targ = self.enemy;
-
-// see if any entities are in the way of the shot
- spot1 = self.origin + self.view_ofs;
- spot2 = targ.origin + targ.view_ofs;
-
-
- if (self.style == 0)
- {
- if (vlen(spot1 - spot2) > 600)
- return FALSE;
- }
- if (self.spawnflags & I_AM_TURRET)
- {
- if (vlen(spot1 - spot2) > 900)
- return FALSE;
- }
-
- // return FALSE;
-
- traceline (spot1, spot2, FALSE, self);
-
- if (trace_inopen && trace_inwater)
- return FALSE; // sight line crossed contents
-
- if ((self.spawnflags & I_AM_TURRET) && (trace_ent != targ))
- {
- // dprint("trace_ent...\n");
- self.attack_state = AS_TURRET;
- return FALSE;
- }
- if (trace_ent != targ)
- {
- return FALSE; // don't have a clear shot
- }
-
-// missile attack
- if (self.style == 0 && enemy_range == RANGE_FAR)
- return FALSE;
-
- self.attack_state = AS_MISSILE;
- SUB_AttackFinished (2 + 2*random());
- return TRUE;
-};
-
-//============================================================================
-
-/*
-===========
-OgreCheckAttack
-
-The player is in view, so decide to move or launch an attack
-Returns FALSE if movement should continue
-============
-*/
-float() OgreCheckAttack =
-{
- local vector spot1, spot2;
- local entity targ;
- local float chance;
-
- // dprint("OgreCheckAttack\n");
- if (self.spawnflags & I_AM_TURRET) //dumptruck_ds
- {
- self.attack_state = AS_MISSILE;
- SUB_AttackFinished (2 + 2*random());
- return TRUE;
- }
-
- if (enemy_range == RANGE_MELEE)
- {
- if (CanDamage (self.enemy, self))
- {
- self.attack_state = AS_MELEE;
- return TRUE;
- }
- }
-
- if (time < self.attack_finished)
- return FALSE;
-
- if (!enemy_vis)
- return FALSE;
-
- targ = self.enemy;
-
-// see if any entities are in the way of the shot
- spot1 = self.origin + self.view_ofs;
- spot2 = targ.origin + targ.view_ofs;
-
- traceline (spot1, spot2, FALSE, self);
-
- if (trace_inopen && trace_inwater)
- return FALSE; // sight line crossed contents
-
- if ((self.spawnflags & I_AM_TURRET) && (trace_ent != targ))
- {
- // dprint("trace_ent...\n");
- self.attack_state = AS_TURRET;
- return FALSE;
- }
-
- if (trace_ent != targ)
- {
- return FALSE; // don't have a clear shot
- }
-
-
-// missile attack
- if (time < self.attack_finished)
- return FALSE;
-
- if (enemy_range == RANGE_FAR)
- return FALSE;
-
- else if (enemy_range == RANGE_NEAR)
- chance = 0.10;
- else if (enemy_range == RANGE_MID)
- chance = 0.05;
- else
- chance = 0;
-
- self.attack_state = AS_MISSILE;
- SUB_AttackFinished (1 + 2*random());
- return TRUE;
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/fog.qc

diff --git a/qc-server/fog.qc b/qc-server/fog.qc
deleted file mode 100644
index ca6bf95..0000000
--- a/qc-server/fog.qc
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
-====================
-
-Fog controllers
-Based on Copper's fog by Lunaran
-Changed by bmFbr
-
-====================
-*/
-
-float FOG_INTERVAL = 0.04166667; // 1/24;
-/*FGD
-@baseclass = Fog [
- fog_density(string) : "Fog Density"
- fog_color(string) : "Fog Color"
-]
-@baseclass = FogShift [
- fog_density(string) : "Start Fog Density"
- fog_color(string) : "Start Fog Color"
- fog_density2(string) : "End Fog Density"
- fog_color2(string) : "End Fog Color"
-]
-*/
-
-/*
-================
-fog_save
-================
-*/
-void( entity client, float density, vector color ) fog_save =
-{
- if (client.classname != "player") return;
-
- // save whatever we set the client's fog to in case of saves/loads
- client.fog_density = density;
- client.fog_color = color;
-}
-
-void( entity client ) fog_save_to_previous =
-{
- if (client.classname != "player") return;
-
- // copies the current fog to the secondary fields to transition from the current fog
- client.fog_density2 = client.fog_density;
- client.fog_color2 = client.fog_color;
-}
-
-void( entity client, float density) skyfog_save =
-{
- if (client.classname != "player") return;
-
- client.skyfog_density = density;
-}
-
-void( entity client ) skyfog_save_to_previous =
-{
- if (client.classname != "player") return;
-
- client.skyfog_density2 = client.skyfog_density;
-}
-/*
-================
-fog_setFromEnt
-================
-*/
-void( entity client, entity fogger ) fog_setFromEnt =
-{
- float density;
- //
- // Don't set the fog if the entity has no values, because it might be a custom map with
- // _fog on the worldspawn instead.
- // To actually get an entity to clear the fog, density to -1.
- // The same applies to skyfog
-
- //eprint(fogger);
-
- //dprint3("fog_density: ", ftos(fogger.fog_density*100), "\n");
- if (fogger.fog_density) {
- dprint("setting fog\n");
- density = zeroconvert(fogger.fog_density);
- fog_set(client, density, fogger.fog_color);
- }
-
- //dprint3("skyfog_density: ", ftos(fogger.skyfog_density*100), "\n");
- if (fogger.skyfog_density) {
- dprint("setting skyfog\n");
- density = zeroconvert(fogger.skyfog_density);
- skyfog_set(client, density);
- }
-}
-
-/*
-================
-fog_set
-================
-*/
-void( entity client, float density, vector color) fog_set =
-{
- if (client.classname != "player") return;
-
- //dprint9("Setting fog: ", ftos(density), " ", ftos(color_x), " ", ftos(color_y), " ", ftos(color_z), "\n");
-
- stuffcmd(client, "\nfog ");
- stuffcmd_float(client, density);
- stuffcmd(client, " ");
- stuffcmd_float(client, color_x);
- stuffcmd(client, " ");
- stuffcmd_float(client, color_y);
- stuffcmd(client, " ");
- stuffcmd_float(client, color_z);
- stuffcmd(client, "\n");
-
- fog_save(client, density, color);
-}
-
-
-void( entity client, float density) skyfog_set =
-{
- if (client.classname != "player") return;
-
- //dprint3("Setting skyfog: ", ftos(density), "\n");
-
- stuffcmd(client, "\nr_skyfog ");
- stuffcmd_float(client, density);
- stuffcmd(client, "\n");
-
- skyfog_save(client, density);
-}
-
-/*
-================
-fog_blendTouch
-================
-*/
-void() fog_blendTouch =
-{
- if (other.classname != "player")
- return;
-
- if (other.health <= 0)
- return;
-
- if (self.estate != STATE_ACTIVE)
- return;
-
- // fix for only first client getting a fog change when multiple coop clients are touching this at once
- if (time != self.rad_time) // because fog is rad
- if (time < self.attack_finished)
- return;
-
- float f, lerp_density, leaving;
- float lerp_sdensity;
- float ent_density, ent_density2, ent_sdensity, ent_sdensity2;
- vector dorg, mid, ovel;
- vector lerp_color;
-
- ent_density = zeroconvert(self.fog_density);
- ent_density2 = zeroconvert(self.fog_density2);
-
- ent_sdensity = zeroconvert(self.skyfog_density);
- ent_sdensity2 = zeroconvert(self.skyfog_density2);
-
- // if you run/fall through a fogblend fast enough you can come out the other side
- // partially blended, so check if player will exit the trigger bounds before the
- // next touch (same class of bug as leaping through lasers in Q2)
- ovel = other.velocity * FOG_INTERVAL;
- leaving = ( (other.absmax_x + ovel_x < self.absmin_x) ||
- (other.absmax_y + ovel_y < self.absmin_y) ||
- (other.absmax_z + ovel_z < self.absmin_z) ||
- (other.absmin_x + ovel_x > self.absmax_x) ||
- (other.absmin_y + ovel_y > self.absmax_y) ||
- (other.absmin_z + ovel_z > self.absmax_z) );
-
- if (leaving)
- {
- // last chance to set fog correctly, so snap it to the final values
- leaving = other.velocity * self.movedir;
- if (leaving > 0)
- {
- lerp_density = ent_density2;
- lerp_color = self.fog_color2;
- lerp_sdensity = ent_sdensity2;
- }
- else
- {
- lerp_density = ent_density;
- lerp_color = self.fog_color;
- lerp_sdensity = ent_sdensity;
- }
- }
- else
- {
- // in transition, blend proportionally between the two fogs
- mid = (self.mins + self.maxs) * 0.5;
- dorg = other.origin + other.view_ofs - mid;
-
- f = dorg * self.movedir;
- f = (f / self.distance) + 0.5;
-
- lerp_density = lerp(ent_density, ent_density2, f);
- lerp_color = lerpVector(self.fog_color, self.fog_color2, f);
- lerp_sdensity = lerp(ent_sdensity, ent_sdensity2, f);
- }
-
- if (self.fog_density || self.fog_density2) fog_set(other, lerp_density, lerp_color);
- if (self.skyfog_density || self.skyfog_density2) skyfog_set(other, lerp_sdensity);
-
- self.rad_time = time;
- self.attack_finished = time + FOG_INTERVAL;
-
- // reset client's fogblend_entity in case it's currently being transitioned by another entity
- other.fogblend_entity = world;
-}
-
-
-/*QUAKED trigger_fogblend (.5 .5 .2) ?
-Acts as a smoothly blending portal between two zones of different fog. Sets the fog for any client passing through it, blending their global fog settings between "fog_color"/"fog_density" and "fog_color2"/"fog_density2" proportional to their position within the trigger.
-The axis of motion on which the blend happens is defined by "angle", pointing to whatever zone has color2 and density2. Trigger therefore has two 'sides' - the side that "angle" points to, and the opposite side.
-
-"distance" - override the length of the blend period in world units - defaults to bounds size
- on 'angle' otherwise. this is only useful for diagonal triggers.
-
-CAVEATS:
-- will 'stuffcmd' 2 dozen times per frame so try not to make these huge
-- a bug in most quake engine ports will reset the eye position smoothing that happens when climbing stairs or riding a plat on every frame that a 'stuffcmd' is sent, so fog transitions during upwards motion will cause noticeable stuttering.
-*/
-/*FGD
-@SolidClass base(Appearflags, Targetname, Target, FogShift) = trigger_fogblend :
-"Trigger: Fog Blend
-Acts as a smoothly blending portal between two zones of different fog. Sets the fog for any client passing through it, blending their global fog settings between start and end values proportional to their position within the trigger.
-
-- will 'stuffcmd' 2 dozen times per frame so try not to make these huge
-- a bug in most quake engine ports will reset the eye position smoothing that happens when climbing stairs or riding a plat on every frame that a 'stuffcmd' is sent, so fog transitions during upwards motion will cause noticeable stuttering."
-[
- distance(integer) : "Length of blend distance (defaults to size of trigger)"
- angle(integer) : "Axis of motion of blend (points toward end values)"
-]
-*/
-void() trigger_fogblend =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.angles == '0 0 0') // InitTrigger assumes angle 0 means no angle
- self.angles = '0 360 0';
-
- InitTrigger ();
- self.touch = fog_blendTouch;
- self.distance = zeroconvertdefault(self.distance, BoundsAngleSize(self.movedir, self.size));
-
- SUB_CheckWaiting();
-}
-
-
-/*
-================
-fog_blendTimeThink
-used by both trigger_fog and target_fogblend
-================
-*/
-
-float FOGBLEND_ONEWAY = 1;
-float FOGBLEND_REVERSE = 2;
-float FOGBLEND_ALLCLIENTS = 4;
-float FOGBLEND_BLENDTO = 8;
-
-void(entity cl, float sTo, float f) skyfog_blendSetFraction = {
- float s;
-
- s = lerpHermite(cl.skyfog_density2, sTo, f);
-
- //eprint(cl);
- //dprint3("Fraction skyfog density: ", ftos(s), "\n");
-
- skyfog_set(cl, s);
-};
-
-void(entity cl, vector cTo, float dTo, float f) fog_blendSetFraction = {
- float d;
- vector c;
-
- d = lerpHermite(cl.fog_density2, dTo, f);
- c = lerpVectorHermite(cl.fog_color2, cTo, f);
-
- /*
- eprint(cl);
- dprint3("fog density: ", ftos(d), "\n");
- dprint3("color: ", vtos(c), "\n");
- dprint3("fraction: ", ftos(f), "\n");
- */
-
- fog_set(cl, d, c);
-};
-
-void() fog_blendTimeThink = {
- float f;
- float dTo, sTo;
- vector cTo;
-
- if (time >= self.pain_finished) {
- f = 1;
- }
- else {
- self.nextthink = time + FOG_INTERVAL;
- if (self.state && self.speed)
- f = 1 - (self.pain_finished - time) / self.speed;
- else if (self.speed2)
- f = 1 - (self.pain_finished - time) / self.speed2;
- else
- f = 1;
- }
-
- if (self.state) {
- dTo = self.fog_density2;
- cTo = self.fog_color2;
- sTo = self.skyfog_density2;
- }
- else {
- dTo = self.fog_density;
- cTo = self.fog_color;
- sTo = self.skyfog_density;
- }
-
- if (self.spawnflags & FOGBLEND_ALLCLIENTS) {
- entity pl;
- pl = nextent(world);
- while (pl.flags & FL_CLIENT) {
- if (pl.fogblend_entity == self) {
- if (dTo && !(pl.fog_density2 == dTo && pl.fog_color2 == cTo))
- fog_blendSetFraction(pl, cTo, zeroconvert(dTo), f);
-
- if (sTo)
- skyfog_blendSetFraction(pl, zeroconvert(sTo), f);
-
- if (time >= self.pain_finished)
- pl.fogblend_entity = world;
- }
-
- pl = nextent(pl);
- }
- }
- else {
- if (self.enemy.fogblend_entity == self) {
- if (dTo && !(self.enemy.fog_density2 == dTo && self.enemy.fog_color2 == cTo))
- fog_blendSetFraction(self.enemy, cTo, zeroconvert(dTo), f);
-
- if (sTo)
- skyfog_blendSetFraction(self.enemy, zeroconvert(sTo), f);
-
- if (time >= self.pain_finished) {
- self.enemy.fogblend_entity = world;
-
- }
- }
- }
-
- if (self.classname == "fog_controller"){
- if (self.enemy.fogblend_entity != self || time >= self.pain_finished) {
- remove(self);
- return;
- }
- }
-};
-
-
-
-/**************************************
-
-target_fogblend
-
-**************************************/
-
-void() target_fogblend_use = {
-
- self.enemy = activator;
- if (self.enemy.classname != "player") return;
-
-
- if (!(self.spawnflags & FOGBLEND_ONEWAY))
- self.state = 1 - self.state;
-
- if (self.state)
- self.pain_finished = time + self.delay + self.speed;
- else
- self.pain_finished = time + self.delay + self.speed2;
-
-
- if (self.spawnflags & FOGBLEND_ALLCLIENTS) {
- entity pl;
- pl = nextent(world);
- while (pl.flags & FL_CLIENT) {
- if (self.fog_density) fog_save_to_previous(pl);
- if (self.skyfog_density) skyfog_save_to_previous(pl);
-
- pl.fogblend_entity = self;
-
- pl = nextent(pl);
- }
- }
- else {
- if (self.fog_density) fog_save_to_previous(self.enemy);
- if (self.skyfog_density) skyfog_save_to_previous(self.enemy);
-
- self.enemy.fogblend_entity = self;
- }
-
- self.nextthink = time + self.delay;
-};
-
-
-
-
-/*QUAKED target_fogblend (.5 .5 .2) (-8 -8 -8) (8 8 8) ONE_WAY REVERSE GLOBAL BLENDTO
-Blends the fog for a client. activator's fog will be blended from "fog_color" and "fog_density"
-to "fog_color2" and "fog_density2". Triggering again will blend it back, unless ONE_WAY is set.
-Set REVERSE if you're tired of swapping the values by hand.
-Set GLOBAL to affect all clients in multiplayer, not just the activator.
-
-"delay" - pause before beginning to blend
-"speed" - time to spend blending, -1 for an instant change to fog2.
-"speed2" - time to spend blending back, if different than "speed". -1 for instant.
-
-CAVEATS:
-- will 'stuffcmd' 2 dozen times per frame so try not to make this take too long
-- a bug in most quake engine ports will reset the eye position smoothing that happens when climbing stairs or riding a plat on every frame that a 'stuffcmd' is sent, so fog transitions during upwards motion will cause noticeable stuttering.
-*/
-/*FGD
-@PointClass base(Appearflags, Targetname, Target, FogShift) color(128 128 50) = target_fogblend :
-"Target: Fog Blend
-Activator's fog will be blended over time from start to end values.
-
-- will 'stuffcmd' 2 dozen times per frame so try not to make this take too long
-- a bug in most quake engine ports will reset the eye position smoothing that happens when climbing stairs or riding a plat on every frame that a 'stuffcmd' is sent, so fog transitions during upwards motion will cause noticeable stuttering."
-[
- spawnflags(flags) = [
- 1 : "One-Way Only" : 0
- 2 : "Reverse Start/End" : 0
- 4 : "All clients" : 0
- ]
- delay(string) : "Pause before starting blend"
- speed(string) : "Time to blend (-1 for instant)"
- speed2(string) : "Time to blend back, if different (-1 for instant)"
-]
-*/
-void() target_fogblend =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.fog_density && !self.skyfog_density) {
- objerror("Neither fog density nor skyfog density set");
- return;
- }
-
- self.use = target_fogblend_use;
- self.think = fog_blendTimeThink;
-
- if (self.spawnflags & FOGBLEND_REVERSE)
- self.state = 1;
- else
- self.state = 0;
-
- if (self.spawnflags & FOGBLEND_ONEWAY)
- self.state = 1 - self.state;
-
- if (!self.speed) self.speed = 1;
- if (!self.speed2) self.speed2 = self.speed;
-
- if (self.speed == -1) self.speed = 0;
- if (self.speed2 == -1) self.speed2 = 0;
-}
-
-
-
-/**************************************
-
-trigger_fog
-
-**************************************/
-
-void() trigger_fog_touch = {
- if (self.estate != STATE_ACTIVE)
- return;
-
- if (!(other.flags & FL_CLIENT))
- return;
-
- // fog already set to this value
- if (other.fog_color == self.fog_color && other.fog_density == self.fog_density)
- return;
-
- // transition already occurring from this trigger
- if (other.fogblend_entity.owner == self)
- return;
-
- if (self.fog_density) fog_save_to_previous(other);
- if (self.skyfog_density) skyfog_save_to_previous(other);
-
- // spawn a temp entity to control the transition for this client
- entity controller;
-
- controller = spawn();
- controller.classname = "fog_controller";
- controller.owner = self;
- controller.enemy = other;
- controller.speed2 = self.speed; // speed2 is used when state is 0
- controller.fog_color = self.fog_color;
- controller.fog_density = self.fog_density;
- controller.skyfog_density = self.skyfog_density;
-
- controller.pain_finished = time + self.delay + self.speed;
-
- controller.think = fog_blendTimeThink;
- controller.nextthink = time + controller.delay;
-
- other.fogblend_entity = controller;
-};
-
-/*QUAKED trigger_fog (.5 .5 .2) ?
-Smoothly blends touching client's currently applied fog to "fog_color" and "fog_density" over time.
-
-"delay" - pause before beginning to blend.
-"speed" - time to spend blending, -1 for an instant change.
-
-CAVEATS:
-- will 'stuffcmd' 2 dozen times per second so try not to make these huge
-- a bug in most quake engine ports will reset the eye position smoothing that happens when climbing stairs or riding a plat on every frame that a 'stuffcmd' is sent, so fog transitions during upwards motion will cause noticeable stuttering.
-*/
-
-void() trigger_fog = {
-
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.fog_density && !self.skyfog_density) {
- objerror("Neither fog density nor skyfog density set");
- return;
- }
- InitTrigger ();
- self.touch = trigger_fog_touch;
- if (!self.speed) self.speed = 1;
-
- SUB_CheckWaiting();
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/fteopts.qc

diff --git a/qc-server/fteopts.qc b/qc-server/fteopts.qc
deleted file mode 100644
index 8f7324f..0000000
--- a/qc-server/fteopts.qc
+++ /dev/null
@@ -1,2 +0,0 @@
-#define FTE
-#pragma TARGET FTE

Return to the top of this page or return to the overview of this repo.

Diff qc-server/fteqcc.ini

diff --git a/qc-server/fteqcc.ini b/qc-server/fteqcc.ini
deleted file mode 100644
index 2dd0b2c..0000000
--- a/qc-server/fteqcc.ini
+++ /dev/null
@@ -1,240 +0,0 @@
-optimisation t off # c = a*b is performed in one operation rather than two, and can
- # cause older decompilers to fail.
-optimisation i off # if (!a) was traditionally compiled in two statements. This optimisation
- # does it in one, but can cause some decompilers to get confused.
-optimisation p off # In the original qcc, function parameters were specified as a vector
- # store even for floats. This fixes that.
-optimisation c default # This optimisation strips out the names of constants (but not strings)
- # from your progs, resulting in smaller files. It makes decompilers
- # leave out names or fabricate numerical ones.
-optimisation cs default # This optimisation strips out the names of string constants from
- # your progs. However, this can break addons, so don't use it in
- # those cases.
-optimisation d off # This will merge definitions of constants which are the same value.
- # Pay extra attention to assignment to constant warnings.
-optimisation s off # This will compact the string table that is stored in the progs.
- # It will be considerably smaller with this.
-optimisation l default # Strips out local names and definitions. Most decompiles will break
- # on this.
-optimisation n default # This strips out the names of functions which are never called.
- # Doesn't make much of an impact though.
-optimisation f default # This strips out the filenames of the progs. This can confuse the
- # really old decompilers, but is nothing to the more recent ones.
-optimisation u off # Removes the entries of unreferenced variables. Doesn't make a
- # difference in well maintained code.
-optimisation r off # Optimises the pr_globals count by overlapping temporaries. In
- # QC, every multiplication, division or operation in general produces
- # a temporary variable. This optimisation prevents excess, and in
- # the case of Hexen2's gamecode, reduces the count by 50k. This
- # is the most important optimisation, ever.
-optimisation a off # 5*6 actually emits an operation into the progs. This prevents
- # that happening, effectivly making the compiler see 30
-optimisation pf default # Strip out stuff wasted used in function calls and strings to the
- # precache_file builtin (which is actually a stub in quake).
-optimisation ro default # Functions ending in a return statement do not need a done statement
- # at the end of the function. This can confuse some decompilers,
- # making functions appear larger than they were.
-optimisation cj default # This optimisation plays an effect mostly with nested if/else statements,
- # instead of jumping to an unconditional jump statement, it'll jump
- # to the final destination instead. This will bewilder decompilers.
-optimisation sf default # Strips out the 'defs' of functions that were only ever called
- # directly. This does not affect saved games, but will prevent FTE_MULTIPROGS/mutators
- # from being able to hook functions.
-optimisation lo default # Store all locals in a single section of the pr_globals. Vastly
- # reducing it. This effectivly does the job of overlaptemps.
- # However, locals are no longer automatically initialised to 0 (and
- # never were in the case of recursion, but at least then its the
- # same type).
- # If locals appear uninitialised, fteqcc will disable this optimisation
- # for the affected functions, you can optionally get a warning about
- # these locals using: #pragma warning enable F302
-optimisation vc default # Where a function is called with just a vector, this causes the
- # function call to store three floats instead of one vector. This
- # can save a good number of pr_globals where those vectors contain
- # many duplicate coordinates but do not match entirly.
-optimisation cf default # Strip class field names. This will harm debugging and can result
- # in 'gibberish' names appearing in saved games. Has no effect on
- # engines other than FTEQW, which will not recognise these anyway.
-optimisation uf default # Strips any fields that have no references. This may result in
- # extra warnings at load time, or disabling support for mapper-specified
- # alpha in engines that do not provide that. FIXME: this is a little
- # pointless until relocs are properly implemented.
-keyword asm true # Disables the 'asm' keyword. Use the writeasm flag to see an example
- # of the asm.
-keyword break true # Disables the 'break' keyword.
-keyword case true # Disables the 'case' keyword.
-keyword class true # Disables the 'class' keyword.
-keyword const true # Disables the 'const' keyword.
-keyword continue true # Disables the 'continue' keyword.
-keyword default true # Disables the 'default' keyword.
-keyword entity true # Disables the 'entity' keyword.
-keyword enum true # Disables the 'enum' keyword.
-keyword enumflags true # Disables the 'enumflags' keyword.
-keyword extern true # Disables the 'extern' keyword. Use only on functions inside addons.
-keyword float true # Disables the 'float' keyword. (Disables the float keyword without
- # 'local' preceeding it)
-keyword for true # Disables the 'for' keyword. Syntax: for(assignment; while; increment)
- # {codeblock;}
-keyword goto true # Disables the 'goto' keyword.
-keyword int true # Disables the 'int' keyword.
-keyword integer true # Disables the 'integer' keyword.
-keyword noref true # Disables the 'noref' keyword.
-keyword unused false # Disables the 'unused' keyword. 'unused' means that the variable
- # is unused, you're aware that its unused, and you'd rather not
- # know about all the warnings this results in.
-keyword used false # Disables the 'used' keyword. 'used' means that the variable is
- # used even if the qcc can't see how - thus preventing it from ever
- # being stripped.
-keyword static true # Disables the 'static' keyword. 'static' means that a variable
- # has altered scope. On globals, the variable is visible only to
- # the current .qc file. On locals, the variable's value does not
- # change between calls to the function. On class variables, specifies
- # that the field is a scoped global instead of a local. On class
- # functions, specifies that 'this' is expected to be invalid and
- # that the function will access any memembers via it.
-keyword nonstatic true # Disables the 'nonstatic' keyword. 'nonstatic' acts upon globals+functions,
- # reverting the defaultstatic pragma on a per-variable basis. For
- # use by people who prefer to keep their APIs explicit.
-keyword ignore false # Disables the 'ignore' keyword. 'ignore' is expected to typically
- # be hidden behind a 'csqconly' define, and in such a context can
- # be used to conditionally compile functions a little more gracefully.
- # The opposite of the 'used' keyword. These variables/functions/members
- # are ALWAYS stripped, and effectively ignored.
-keyword nosave true # Disables the 'nosave' keyword.
-keyword inline true # Disables the 'inline' keyword.
-keyword strip true # Disables the 'strip' keyword.
-keyword shared true # Disables the 'shared' keyword.
-keyword state false # Disables the 'state' keyword.
-keyword optional true # Disables the 'optional' keyword.
-keyword inout false # Disables the 'inout' keyword.
-keyword string true # Disables the 'string' keyword.
-keyword struct true # Disables the 'struct' keyword.
-keyword switch true # Disables the 'switch' keyword.
-keyword thinktime false # Disables the 'thinktime' keyword which is used in HexenC
-keyword until false # Disables the 'until' keyword which is used in HexenC
-keyword loop false # Disables the 'loop' keyword which is used in HexenC
-keyword typedef true # Disables the 'typedef' keyword.
-keyword union true # Disables the 'union' keyword.
-keyword var true # Disables the 'var' keyword.
-keyword vector true # Disables the 'vector' keyword.
-keyword wrap true # Disables the 'wrap' keyword.
-keyword weak true # Disables the 'weak' keyword.
-keyword accumulate false # Disables the 'accumulate' keyword.
-flag acc false # Reacc is a pascall like compiler. It was released before the Quake
- # source was released. This flag has a few effects. It sorts all
- # qc files in the current directory into alphabetical order to compile
- # them. It also allows Reacc global/field distinctions, as well
- # as allows | for linebreaks. Whilst case insensitivity and lax
- # type checking are supported by reacc, they are seperate compiler
- # flags in fteqcc.
-flag qccx false # WARNING: This syntax makes mods inherantly engine specific.
- # Do NOT use unless you know what you're doing.This is provided
- # for compatibility only
- # Any entity hacks will be unsupported in FTEQW, DP, and others,
- # resulting in engine crashes if the code in question is executed.
-flag kce true # If you want keywords to NOT be disabled when they a variable by
- # the same name is defined, check here.
-flag parms false # if PARM0 PARM1 etc should be defined by the compiler. These are
- # useful if you make use of the asm keyword for function calls,
- # or you wish to create your own variable arguments. This is an
- # easy way to break decompilers.
-flag autoproto false # Causes compilation to take two passes instead of one. The first
- # pass, only the definitions are read. The second pass actually
- # compiles your code. This means you never have to remember to prototype
- # functions again.
-flag wasm false # Writes out a qc.asm which contains all your functions but in assembler.
- # This is a great way to look for bugs in fteqcc, but can also be
- # used to see exactly what your functions turn into, and thus how
- # to optimise statements better.
-flag annotate false # Annotate source code with assembler statements on compile (requires
- # gui).
-flag nullemptystr false # Empty string immediates will have the raw value 0 instead of 1.
-flag ifstring true # Causes if(string) to behave identically to if(string!=) This is
- # most useful with addons of course, but also has adverse effects
- # with FRIK_FILE's fgets, where it becomes impossible to determin
- # the end of the file. In such a case, you can still use asm {IF
- # string 2;RETURN} to detect eof and leave the function.
-flag iffloat false # Fixes certain floating point logic.
-flag ifvector true # Fixes conditional vector logic.
-flag vectorlogic true # Fixes conditional vector logic.
-flag brokenarray false # Treat references to arrays as references to the first index of
- # said array, to replicate an old fteqcc bug.
-flag rootconstructor false # When enabled, the root constructor should be called first like
- # in c++.
-flag caseinsens false # Causes fteqcc to become case insensitive whilst compiling names.
- # It's generally not advised to use this as it compiles a little
- # more slowly and provides little benefit. However, it is required
- # for full reacc support.
-flag lax false # Disables many errors (generating warnings instead) when function
- # calls or operations refer to two normally incompatible types.
- # This is required for reacc support, and can also allow certain
- # (evil) mods to compile that were originally written for frikqcc.
-flag hashonly false # Allows use of only #constant for precompiler constants, allows
- # certain preqcc using mods to compile
-flag lo false # This changes the behaviour of your code. It generates additional
- # if operations to early-out in if statements. With this flag, the
- # line if (0 && somefunction()) will never call the function. It
- # can thus be considered an optimisation. However, due to the change
- # of behaviour, it is not considered so by fteqcc. Note that due
- # to inprecisions with floats, this flag can cause runaway loop
- # errors within the player walk and run functions (without iffloat
- # also enabled). This code is advised:
- # player_stand1:
- # if (self.velocity_x || self.velocity_y)
- # player_run
- # if (!(self.velocity_x || self.velocity_y))
-flag msvcstyle false # Generates warning and error messages in a format that msvc understands,
- # to facilitate ide integration.
-flag debugmacros false # Print out the contents of macros that are expanded. This can help
- # look inside macros that are expanded and is especially handy if
- # people are using preprocessor hacks.
-flag filetimes false # Recompiles the progs only if the file times are modified.
-flag fastarrays false # Generates extra instructions inside array handling functions to
- # detect engine and use extension opcodes only in supporting engines.
- # Adds a global which is set by the engine if the engine supports
- # the extra opcodes. Note that this applies to all arrays or none.
-flag assumeint false # Numerical constants are assumed to be integers, instead of floats.
-flag subscope false # Restrict the scope of locals to the block they are actually defined
- # within, as in C.
-flag verbose false # Lots of extra compiler messages.
-flag typeexplicit false # All type conversions must be explicit or directly supported by
- # instruction set.
-flag boundchecks true # Disable array index checks, speeding up array access but can result
- # in your code misbehaving.
-flag attributes false # WARNING: This syntax conflicts with vector constructors.
-flag assumevar false # Initialised globals will be considered non-const by default.
-flag ssp false # Treat ** as an operator for exponents, instead of multiplying
- # by a dereferenced pointer.
-flag cpriority false # QC treats !a&&b as equivelent to !(a&&b). When this is set, behaviour
- # will be (!a)&&b as in C. Other operators are also affected in
- # similar ways.
-flag allowuninit false # Permit optimisations that may result in locals being uninitialised.
- # This may allow for greater reductions in temps.
-flag nofileline false # Ignores #pragma file(foo) and #pragma line(foo), so that errors
- # and symbols reflect the actual lines, instead of the original
- # source.
-flag utf8 false # String immediates will use utf-8 encoding, instead of quake's
- # encoding.
-flag embedsrc false # Write the sourcecode into the output file. The resulting .dat
- # can be opened as a standard zip archive (or by fteqccgui).
- # Good for GPL compliance!
-showall off # Show all keyword options in the gui
-compileonstart off # Recompile on GUI startup
-log off # Write out a compile log
-enginebinary d:\Quakec\fteqw64.exe # Location of the engine binary to run. Change this to something
- # else to run a different engine, but not all support debugging.
-basedir d:\Quakec # The base directory of the game that contains your sub directory
-engineargs "-game progs_dump +exec fte.cfg"
- # The engine commandline to use when debugging. You'll likely want
- # to ensure this contains -window as well as the appropriate -game
- # argument.
-srcfile progs.src # The progs.src file to load to find ordering of other qc files.
-src # Additional subdir to read qc files from. Typically blank (ie:
- # the working directory).
-tabsize 8 # Specifies the size of tabs in scintilla windows.
-extramargins off # Enables line number and folding margins.
-hexen2 off # Enable the extra tweaks needed for compatibility with hexen2 engines.
-extendedopcodes off # Utilise an extended instruction set, providing support for pointers
- # and faster arrays and other speedups.
-parameters # Other additional parameters that are not supported by the gui.
- # Likely including -DFOO

Return to the top of this page or return to the overview of this repo.

Diff qc-server/func_bob.qc

diff --git a/qc-server/func_bob.qc b/qc-server/func_bob.qc
deleted file mode 100644
index 494cce3..0000000
--- a/qc-server/func_bob.qc
+++ /dev/null
@@ -1,198 +0,0 @@
-.float attack_timer;
-.float bsporigin; // All bmodel origins are 0,0,0 check this first
-.float distance;
-.float waitmin2;
-
-float BOB_COLLISION = 2; // Collision for misc_bob
-float BOB_NONSOLID = 4; // Non solid for func_bob
-
-/*QUAKED func_bob (0 .5 .8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-A SOLID bmodel that gently moves back and forth
--------- KEYS --------
-targetname : trigger entity (works with entity state system)
-angle : direction movement, use "360" for angle 0
-height : direction intensity (def=8)
-count : direction cycle timer (def=2s, minimum=1s)
-waitmin : Speed up scale (def=1) 1+=non linear
-waitmin2 : Slow down scale (def=0.75)
-delay : Starting time delay (def=0, -1=random)
-style : If set to 1, starts off and waits for trigger
-_dirt : -1 = will be excluded from dirtmapping
-_minlight : Minimum light level for any surface of the brush model
-_mincolor : Minimum light color for any surface (def='1 1 1' RGB)
-_shadow : Will cast shadows on other models and itself
-_shadowself : Will cast shadows on itself
--------- SPAWNFLAGS --------
-STARTOFF : Starts off and waits for trigger - DISABLED, Ripped out ESTATE System (RennyC)
--------- NOTES --------
-A SOLID bmodel that gently moves back and forth
-*/
-
-//----------------------------------------------------------------------
-void() func_bob_timer =
-{
- // Keep ticking in background, use local timer (faster)
- self.think = func_bob_timer;
-
- if (self.bsporigin)
- self.nextthink = self.ltime + 0.1;
- else
- self.nextthink = time + 0.1;
-
- // Has the cycle completed?
- if (self.attack_timer < time)
- {
- // Setup bob cycle and half way point for slowdown
- self.attack_timer = time + self.count;
- self.distance = time + (self.count * 0.5);
- // Flip direction of bmodel bob
- self.lefty = 1 - self.lefty;
- if (self.lefty < 1)
- self.t_length = self.height;
- else
- self.t_length = -self.height;
-
- // Always reset velocity and flags
- self.velocity = '0 0 0';
- self.flags = 0;
- }
-
- // Is the direction set?
- // This is a block condition to prevent the bmodel moving
- if (self.lefty != -1)
- {
- // Slow down velocity (gradually)
- if (self.distance < time)
- self.velocity = self.velocity * self.waitmin2;
- else
- {
- // Speed up velocity (linear/exponentially)
- self.t_length = self.t_length * self.waitmin;
- self.velocity = self.velocity + (self.movedir * self.t_length);
- }
- }
-};
-
-//----------------------------------------------------------------------
-void() func_bob_on =
-{
- // This may have been called as a "use" function, so don't allow it
- // to be called repeatedly -- iw
- self.use = SUB_Null;
-
- if (self.bsporigin)
- {
- self.movetype = MOVETYPE_PUSH;
- self.solid = SOLID_BSP;
- }
- else
- {
- self.movetype = MOVETYPE_FLY;
- self.solid = SOLID_BBOX;
- self.flags = 0; // Reset any onground flags
- }
-
- if (self.spawnflags & BOB_NONSOLID)
- self.solid = SOLID_NOT;
-
- setmodel (self, self.mdl);
- setsize (self, self.mins , self.maxs);
-
- self.think = func_bob_timer;
- if (self.bsporigin)
- self.nextthink = self.ltime + 0.1 + self.delay;
- else
- self.nextthink = time + 0.1 + self.delay;
-};
-
-//----------------------------------------------------------------------
-void() func_bob_off =
-{
- if (self.bsporigin)
- {
- self.movetype = MOVETYPE_PUSH;
- self.solid = SOLID_BSP;
- }
- else
- {
- self.movetype = MOVETYPE_FLY;
- self.solid = SOLID_BBOX;
- }
-
- if (self.spawnflags & BOB_NONSOLID)
- self.solid = SOLID_NOT;
-
- setmodel (self, self.mdl);
- setsize (self, self.mins , self.maxs);
- self.velocity = '0 0 0';
-
- if (self.style & 1)
- self.use = func_bob_on;
-};
-
-//----------------------------------------------------------------------
-void() func_bob =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.spawnflags = self.spawnflags | BOB_COLLISION;
- if (self.spawnflags & BOB_NONSOLID)
- self.spawnflags = self.spawnflags - (self.spawnflags & BOB_COLLISION);
-
- // Using a custom model?
- if (self.mdl == "")
- {
- self.bsporigin = TRUE;
- self.mdl = self.model;
- }
- else
- {
- self.bsporigin = FALSE;
- self.modelindex = 0;
- self.model = "";
- }
-
- SetMovedir ();
- self.movedir = normalize(self.movedir);
-
- if (self.height <= 0)
- self.height = 8; // Direction intensity
- if (self.count < 1)
- self.count = 2; // Direction switch timer
- if (self.waitmin <= 0)
- self.waitmin = 1; // Speed up
- if (self.waitmin2 <= 0)
- self.waitmin2 = 0.75; // Slow down
- if (self.delay < 0)
- self.delay = random() + random() + random();
-
- // Setup Entity State functionality - Nope! (RennyC)
- // if (self.targetname != "")
- // self.use = func_bob_on;
-
- if (!self.style) //added style key 1 for start off -- dumptruck_ds
- func_bob_on();
- else
- func_bob_off();
-};
-
-//----------------------------------------------------------------------
-
-/*QUAKED misc_bob (0 0.5 0.8) (-8 -8 -8) (8 8 8) X BOB_COLLISION BOB_NONSOLID X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path" : mdl, "skin" : skin, "frame": frame});
-}
-Same as func_bob but uses a custom model instead of a brush. Use the mdl key to set the path of the model.
-*/
-void() misc_bob =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.mdl == "")
- self.mdl = string_null;
- precache_model(self.mdl);
-
- func_bob();
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/func_brush.qc

diff --git a/qc-server/func_brush.qc b/qc-server/func_brush.qc
deleted file mode 100644
index e5f6aaf..0000000
--- a/qc-server/func_brush.qc
+++ /dev/null
@@ -1,80 +0,0 @@
-//this is on hold and not in progs.src
-// crashes in QS at the moment Jaycie is looking into it
-.float solidstate;
-.float visiblestate;
-
-float START_INVISIBLE = 1;
-float START_NONSOLID = 2;
-float START_ALTFRAMES = 4;
-float TOGGLE_VISIBILITY = 8;
-float TOGGLE_SOLIDITY = 16;
-float TOGGLE_FRAMES = 32;
-
-void() func_brush_use =
-{
- if (self.spawnflags & TOGGLE_VISIBILITY)
- {
- if (self.visiblestate == 1)
- {
- self.model = "";
- self.visiblestate = 0;
- }
- else
- {
- self.model = self.mdl;
- self.visiblestate = 1;
- }
- }
- if (self.spawnflags & TOGGLE_SOLIDITY)
- {
- if (self.solidstate == 1)
- {
- self.solid = SOLID_NOT;
- self.solidstate = 0;
- }
- else
- {
- self.solid = SOLID_BSP;
- setorigin(self, self.origin);
- self.solidstate = 1;
- }
- }
- if (self.spawnflags & TOGGLE_FRAMES)
- self.frame = 1 - self.frame;
-};
-
-void() func_brush =
-{
- self.angles = '0 0 0';
- self.movetype = MOVETYPE_NONE;
- self.use = func_brush_use;
- setmodel(self, self.model);
- self.mdl = self.model;
- setorigin(self, self.origin);
-
- if (self.spawnflags & START_INVISIBLE)
- {
- self.visiblestate = 0;
- self.model = "";
- }
- else
- {
- self.visiblestate = 1;
- }
-
- if (self.spawnflags & START_NONSOLID)
- {
- self.solidstate = 0;
- self.solid = SOLID_NOT;
- }
- else
- {
- self.solidstate = 1;
- self.solid = SOLID_BSP;
- }
-
- if (self.spawnflags & START_ALTFRAMES)
- self.frame = 1;
- else
- self.frame = 0;
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/func_fall2.qc

diff --git a/qc-server/func_fall2.qc b/qc-server/func_fall2.qc
deleted file mode 100644
index ac97023..0000000
--- a/qc-server/func_fall2.qc
+++ /dev/null
@@ -1,280 +0,0 @@
-.float alpha; // translucency in supported engines
-.entity char; // linker entity
-float PLAYER_TRIGGERED = 1;
-float MONSTER_TRIGGERED = 2;
-float FALL_BREAKABLE = 8; //VR
-// float FALL_SOLID = 16; //VR
-
-void() fall_break_fields;
-
-void() func_fall2_think =
-{
- self.waterlevel = self.watertype = 0; // turn off quake engine splash sound
-
- if (self.attack_finished < time)
- {
- if (self.target) // fire other targets
- SUB_UseAndForgetTargets();
- // SUB_UseTargets();
-
- self.solid = SOLID_NOT; // removed FALL_SOLID behavior -- dumptruck_ds
- if (self.pos1 != '0 0 0')
- self.avelocity = self.pos1; // apply stored avelocity vector values
-
- if (self.pos2 && !self.velocity) // Add velocity movement
- self.velocity = self.pos2;
-
- if (self.cnt > 0) // cnt over 0
- {
- if (self.cnt >= 2)
- {
- self.movetype = MOVETYPE_BOUNCE;
- if (self.velocity_z < self.lip)
- self.velocity_z = self.lip;
- }
- else // cnt is 1
- {
- self.movetype = MOVETYPE_NOCLIP;
- if (self.velocity_z > self.lip)
- self.velocity_z = self.velocity_z - self.speed * (frametime * 100);
- else
- self.velocity_z = self.lip;
- }
- }
- else // default behavior (cnt is 0)
- {
- self.movetype = MOVETYPE_TOSS;
- if (self.velocity_z < self.lip)
- self.velocity_z = self.lip;
- }
-
- if (self.pain_finished != -1)
- {
- if (self.alpha > 0.1)
- self.alpha = self.alpha - self.pain_finished;
- else
- {
- if (self.noise2)
- sound (self, CHAN_AUTO, self.noise2, 1, ATTN_NORM);
- remove(self);
- return;
- }
- }
-
- if (self.flags&FL_ONGROUND && self.spawnflags&FALL_BREAKABLE) { //VR
- self.spawnflags(-)1; //aka BREAKABLE_NO_MONSTERS
- self.spawnflags(-)2; //aka BREAK_EXPLODE
- self.mins = self.absmin; //because of how debris origin is calculated
- self.maxs = self.absmax;
- self.health = self.lip*0.1; //debris gets velocity from health
- self.cnt = self.count; //func_breakable uses cnt for quantity of debris to spawn
- func_breakable_die(); //removes self
- return;
- }
- }
-
- self.nextthink = self.ltime + 0.1;
-};
-
-void() fall2_touch =
-{
- if (!other.takedamage)
- return;
- if (other.classname != "player") // player activated only
- return;
- if (self.spawnflags & MONSTER_TRIGGERED) // disable on monster only, also fixes weird issue
- return;
-
- self.think = func_fall2_think;
- self.nextthink = self.ltime + 0.1;
-
- self.attack_finished = time + self.wait;
-
- // if (self.spawnflags&FALL_SOLID) { //VR
- // setsize(self, self.mins, self.maxs);
- // self.solid = SOLID_BBOX;
- // }
- // else
- // self.solid = SOLID_NOT;
-
- if (self.noise)
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
-
- self.touch = SUB_Null; // disable touch, only do this once!
-
- if (self.char)
- remove(self.char);
-};
-
-void() func_fall2_use =
-{
- self.think = func_fall2_think;
- self.nextthink = self.ltime + 0.1;
- self.touch = SUB_Null; // disable touch when used
-
- // if (self.spawnflags&FALL_SOLID) { //VR
- // setsize(self, self.mins, self.maxs);
- // self.solid = SOLID_BBOX;
- // }
- // else
- // self.solid = SOLID_NOT;
-
- self.attack_finished = time + self.wait;
- if (self.noise)
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
-};
-
-void() func_fall2_field_touch =
-{
- if (other.flags & FL_FLY) // flying monsters shouldn't trigger falling platforms
- return;
-
- if (other.flags & FL_MONSTER)
- {
- local entity oself;
-
- oself = self;
-
- self = self.owner;
- self.think = func_fall2_use;
- self.nextthink = self.owner.ltime + 0.1;
-
- self = oself;
-
- remove(self);
- }
-};
-
-/*QUAKED func_fall2 (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Falling brush by RennyC with additions from whirledtsar
-
-wait - how long until the brush begins falling
-noise - the sound to make when touched / activated
-noise2 - the sound to make before it's removed, pain_finished of -1 disables noise2 as the object stays forever
-cnt - 0 is default behavior (MOVETYPE_TOSS), 1 means collisions are disabled while falling (MOVETYPE_NOCLIP), 2 turns the brush into a bouncing entity (MOVETYPE_BOUNCE)
-pain_finished - default of 0.01, higher value has the object/brush fade out faster thus in turn affecting how long it stays. -1 stays forever
-speed - speed as to how fast something falls per game frame, default is 10, higher values mean faster falling. Only for cnt of 1 (MOVETYPE_NOCLIP).
-Recommended to use lip for max fall speed on MOVETYPE_TOSS/BOUNCE entities (cnt 0 and 2) as they follow Quake's default gravity
-lip - maximum fall speed that can be achieved, caps 'speed' variable. Default is -800
-avelocity - have it spin when activated using X, Y, Z vector coordinates. MOVETYPE_BOUNCE ignores avelocity !Use an origin brush for proper spin!
-
-spawnflags:
-Default behavior allows anyone to activate func_fall2 on touch ONLY
-1 - Player activated only
-2 - Monster activated only
-8 - break on impact (use style key for textures, see manual for more)
-16 - fall solid; remains solid on ground
-
-Able to .target other entities, including other func_fall2s
-*/
-
-void() func_fall2 =
-{
- //
- // This is a hack to have monsters be able to trigger it by fake touch - Thanks to Nahuel
- //
-
- // Don't spawn on player only or if I'm a targetable
- if (!(self.spawnflags & PLAYER_TRIGGERED) && !(self.targetname))
- {
- local entity func_fall2_field;
-
- func_fall2_field = spawn();
- func_fall2_field.owner = self;
- self.char = func_fall2_field; // Link 'em
- func_fall2_field.solid = SOLID_TRIGGER;
- setsize (func_fall2_field, self.absmin, self.absmax + '0 0 8');
- setorigin (func_fall2_field, self.origin);
- setmodel (func_fall2_field, self.model);
- func_fall2_field.touch = func_fall2_field_touch;
- }
-
- if (self.noise)
- precache_sound(self.noise);
- if (self.noise2)
- precache_sound(self.noise2);
-
- self.alpha = 1;
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
-
- if (!self.pain_finished)
- self.pain_finished = 0.01;
- if (!self.targetname)
- self.touch = fall2_touch; // .touch in this instance is for players only
- if (!self.speed)
- self.speed = 10;
- if (!self.lip)
- self.lip = -800;
- if (self.avelocity != '0 0 0')
- {
- self.pos1 = self.avelocity; // store it
- self.avelocity = '0 0 0';
- }
- if (self.spawnflags&FALL_BREAKABLE) { //VR
- self.pain_finished = -1; //dont fade if set to break
- fall_break_fields();
- }
- self.use = func_fall2_use;
-
- setmodel (self, self.model);
-};
-
-// * You may have to modify your multi_touch(); command in triggers.qc to allow
-// * both monsters & players to activate trigger_once/multiple. I recommend allowing
-// * the mapper themselves to select how that occurs. Default behavior is player only.
-
-void fall_break_fields ()
-{
- break_template_setup();
-
- self.mdl_debris = "progs/debris.mdl";
- precache_model (self.mdl_debris);
-
- if (self.noise1 != "") precache_sound(self.noise1);
-// adding new default sounds for "simple" breakables in 1.2.0 -- dumptruck_ds
-// here's genreic metal breaking
- if (self.style == 0 || self.style == 11 || self.style == 12 || self.style == 17 || self.style == 18 || self.style == 19
- || self.style == 24 || self.style == 31)
- if !(self.noise1)
- {
- precache_sound("break/metal2.wav");
- self.noise1 = "break/metal2.wav";
- }
- if (self.style == 3 || self.style == 4 || self.style == 5)
- if !(self.noise1)
- {
- precache_sound("break/wood1.wav");
- precache_sound("break/wood2.wav");
- if (random() > 0.6) // wood only randomized
- self.noise1 = "break/wood1.wav";
- else
- self.noise1 = "break/wood2.wav";
- }
- // glass sounds -- this is more of a shattering sound anyway
- if (self.style == 6 || self.style == 7 || self.style == 8 || self.style == 9 || self.style == 10)
- if !(self.noise1)
- {
- precache_sound("break/metal1.wav");
- self.noise1 = "break/metal1.wav";
- }
- if (self.style == 1 || self.style == 2 || self.style == 13 || self.style == 14
- || self.style == 15 || self.style == 16 || self.style == 20 || self.style == 21
- || self.style == 22 || self.style == 23)
- if !(self.noise1)
- {
- precache_sound("break/bricks1.wav");
- self.noise1 = "break/bricks1.wav";
- }
- if (self.style == 25 || self.style == 26 || self.style == 27 || self.style == 28 || self.style == 29 || self.style == 30)
- if !(self.noise1)
- {
- precache_sound("break/stones1.wav");
- self.noise1 = "break/stones1.wav";
- }
-
- if (!self.health)
- self.health = 20;
- if (!self.count)
- self.count = 5; // was 6 dumptruck_ds
-}

Return to the top of this page or return to the overview of this repo.

Diff qc-server/hip_count.qc

diff --git a/qc-server/hip_count.qc b/qc-server/hip_count.qc
deleted file mode 100644
index 0b91e46..0000000
--- a/qc-server/hip_count.qc
+++ /dev/null
@@ -1,219 +0,0 @@
-/* Counter QuickC program
- By Jim Dose' 9/13/96
- Copyright (c)1996 Hipnotic Interactive, Inc.
- All rights reserved.
- Do not distribute.
-*/
-
-float COUNTER_TOGGLE = 1;
-float COUNTER_LOOP = 2;
-float COUNTER_STEP = 4;
-float COUNTER_RESET = 8;
-float COUNTER_RANDOM = 16;
-float COUNTER_FINISHCOUNT = 32;
-float COUNTER_START_ON = 64;
-
-void() counter_on_use;
-void() counter_off_use;
-
-void() counter_think =
- {
- self.cnt = self.cnt + 1;
- if ( self.spawnflags & COUNTER_RANDOM )
- {
- self.state = random() * self.count;
- self.state = floor( self.state ) + 1;
- }
- else
- {
- self.state = self.cnt;
- }
-
- // fix func_counter and func_oncount handling of activator -- iw
- //activator = other;
- activator = self.enemy;
- SUB_UseTargets();
- self.nextthink = time + self.wait;
-
- if ( self.spawnflags & COUNTER_STEP )
- {
- counter_on_use();
- }
-
- if ( self.cnt >= self.count )
- {
- self.cnt = 0;
- if ( ( self.aflag ) || !( self.spawnflags & COUNTER_LOOP ) )
- {
- if (self.spawnflags & COUNTER_TOGGLE)
- {
- counter_on_use();
- }
- else
- {
- remove (self);
- }
- }
- }
- };
-
-// fix func_counter and func_oncount handling of activator -- iw
-void() counter_start_on_think =
- {
- activator = world; // to ensure it's not a random entity -- iw
- counter_off_use();
- };
-
-void() counter_on_use =
- {
- if ( ( self.cnt != 0 ) && ( self.spawnflags & COUNTER_FINISHCOUNT ) )
- {
- self.aflag = TRUE;
- return;
- }
-
- self.use = counter_off_use;
- self.think = SUB_Null;
- self.aflag = FALSE;
- };
-
-void() counter_off_use =
- {
- self.aflag = FALSE;
- if (self.spawnflags & COUNTER_TOGGLE)
- {
- self.use = counter_on_use;
- }
- else
- {
- self.use = SUB_Null;
- }
-
- if ( self.spawnflags & COUNTER_RESET )
- {
- self.cnt = 0;
- self.state = 0;
- }
- // fix func_counter and func_oncount handling of activator -- iw
- self.enemy = activator;
- self.think = counter_think;
- // fix "delay" making func_counter not work -- iw
- //if (self.delay)
- if (self.pausetime)
- {
- // fix "delay" making func_counter not work -- iw
- //self.nextthink = time + self.delay;
- self.nextthink = time + self.pausetime;
- }
- else
- {
- counter_think();
- }
- };
-
-float( entity counter ) counter_GetCount =
- {
- if ( counter.classname == "counter" )
- {
- return counter.state;
- }
- return 0;
- };
-
-/*QUAKED func_counter (0 0 0.5) (0 0 0) (32 32 32) TOGGLE LOOP STEP RESET RANDOM FINISHCOUNT START_ON X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-TOGGLE causes the counter to switch between an on and off state
-each time the counter is triggered.
-
-LOOP causes the counter to repeat infinitly. The count resets to zero
-after reaching the value in "count".
-
-STEP causes the counter to only increment when triggered. Effectively,
-this turns the counter into a relay with counting abilities.
-
-RESET causes the counter to reset to 0 when restarted.
-
-RANDOM causes the counter to generate random values in the range 1 to "count"
-at the specified interval.
-
-FINISHCOUNT causes the counter to continue counting until it reaches "count"
-before shutting down even after being set to an off state.
-
-START_ON causes the counter to be on when the level starts.
-
-"count" specifies how many times to repeat the event. If LOOP is set,
-it specifies how high to count before reseting to zero. Default is 10.
-
-"wait" the length of time between each trigger event. Default is 1 second.
-
-"delay" how much time to wait before firing after being switched on.
-*/
-
-void() func_counter =
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if ( !self.wait )
- {
- self.wait = 1;
- }
-
- self.count = floor( self.count );
- if ( self.count <= 0 )
- {
- self.count = 10;
- }
-
- // fix "delay" making func_counter not work -- iw
- self.pausetime = self.delay;
- self.delay = 0;
-
- self.cnt = 0;
- self.state = 0;
-
- self.classname = "counter";
- self.use = counter_off_use;
- self.think = SUB_Null;
- if ( self.spawnflags & COUNTER_START_ON )
- {
- // fix func_counter and func_oncount handling of activator -- iw
- //self.think = counter_off_use;
- self.think = counter_start_on_think;
- self.nextthink = time + 0.1;
- }
- };
-
-void() oncount_use =
- {
- if ( counter_GetCount( other ) == self.count )
- {
- // fix func_counter and func_oncount handling of activator -- iw
- //activator = other;
- SUB_UseTargets();
- }
- };
-
-/*QUAKED func_oncount (0 0 0.5) (0 0 0) (16 16 16)
-Must be used as the target for func_counter. When the counter
-reaches the value set by count, func_oncount triggers its targets.
-
-"count" specifies the value to trigger on. Default is 1.
-
-"delay" how much time to wait before firing after being triggered.
-*/
-
-void() func_oncount =
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.count = floor( self.count );
- if ( self.count <= 0 )
- {
- self.count = 1;
- }
-
- self.classname = "oncount";
- self.use = oncount_use;
- self.think = SUB_Null;
- };

Return to the top of this page or return to the overview of this repo.

Diff qc-server/hip_part.qc

diff --git a/qc-server/hip_part.qc b/qc-server/hip_part.qc
deleted file mode 100644
index e759742..0000000
--- a/qc-server/hip_part.qc
+++ /dev/null
@@ -1,316 +0,0 @@
-/* Particle effects QuickC program
- By Jim Dose' 9/19/96
- Copyright (c)1996 Hipnotic Interactive, Inc.
- All rights reserved.
- Do not distribute.
-*/
-
-//float START_OFF = 1;
-float USE_COUNT = 1;
-
-void () particlefield_XZ =
- {
- local vector pos;
- local vector start;
- local vector end;
-
- if ( ( self.spawnflags & USE_COUNT ) &&
- ( counter_GetCount( other ) != self.cnt ) )
- {
- return;
- }
-// dprint( "XZ\n" );
-
- self.ltime = time + 0.25;
- if ( self.noise != "" )
- {
- sound(self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- }
-
- // Only show particles if client is visible.
- // This helps to keep network traffic down to a minimum.
- if (!checkclient() )
- return;
-
- start = self.dest1 + self.origin;
- end = self.dest2 + self.origin;
- pos_y = start_y;
- pos_z = start_z;
- while( pos_z <= end_z )
- {
- pos_x = start_x;
- while( pos_x <= end_x )
- {
- particle ( pos, '0 0 0', self.color, self.count );
- pos_x = pos_x + 16;
- }
- pos_z = pos_z + 16;
- }
- };
-
-void () particlefield_YZ =
- {
- local vector pos;
- local vector start;
- local vector end;
-
- if ( ( self.spawnflags & USE_COUNT ) &&
- ( counter_GetCount( other ) != self.cnt ) )
- {
- return;
- }
-
-// dprint( "YZ: " );
-// dprint( vtos( self.dest1 ) );
-// dprint( " - " );
-// dprint( vtos( self.dest2 ) );
-// dprint( "\n" );
- self.ltime = time + 0.25;
- if ( self.noise != "" )
- {
- sound(self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- }
-
- // Only show particles if client is visible.
- // This helps to keep network traffic down to a minimum.
- if (!checkclient() )
- return;
-
- start = self.dest1 + self.origin;
- end = self.dest2 + self.origin;
- pos_x = start_x;
- pos_z = start_z;
- while( pos_z < end_z )
- {
- pos_y = start_y;
- while( pos_y < end_y )
- {
- particle ( pos, '0 0 0', self.color, self.count );
- pos_y = pos_y + 16;
- }
- pos_z = pos_z + 16;
- }
- };
-
-void () particlefield_XY =
- {
- local vector pos;
- local vector start;
- local vector end;
-
- if ( ( self.spawnflags & USE_COUNT ) &&
- ( counter_GetCount( other ) != self.cnt ) )
- {
- return;
- }
-
-// dprint( "XY\n" );
- self.ltime = time + 0.25;
- if ( self.noise != "" )
- {
- sound(self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- }
-
- // Only show particles if client is visible.
- // This helps to keep network traffic down to a minimum.
- if (!checkclient() )
- return;
-
-
- start = self.dest1 + self.origin;
- end = self.dest2 + self.origin;
- pos_x = start_x;
- pos_z = start_z;
- while( pos_x < end_x )
- {
- pos_y = start_y;
- while( pos_y < end_y )
- {
- particle ( pos, '0 0 0', self.color, self.count );
- pos_y = pos_y + 16;
- }
- pos_x = pos_x + 16;
- }
- };
-
-void () particlefield_touch =
- {
- if ( !self.dmg )
- return;
-
- if ( time > self.ltime)
- return;
-
- if (time < self.attack_finished)
- return;
- self.attack_finished = time + 0.5;
- T_Damage (other, self, self, self.dmg);
- };
-
-/*QUAKED func_particlefield (0 .5 .8) ? USE_COUNT X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Creates a brief particle flash roughly the size of the defining
-brush each time it is triggered.
-
-USE_COUNT when the activator is a func_counter, the field will only
-activate when count is equal to "cnt". Same as using a func_oncount
-to trigger.
-
-"cnt" is the count to activate on when USE_COUNT is set.
-"color" is the color of the particles. Default is 192 (yellow).
-"count" is the density of the particles. Default is 2.
-"noise" is the sound to play when triggered. Do not use a looping sound here.
-"dmg" is the amount of damage to cause when touched.
-*/
-
-void() func_particlefield =
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if ( !self.color )
- {
- self.color = 192;
- }
- if ( self.count == 0 )
- {
- self.count = 2;
- }
- self.classname = "particlefield";
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_NONE;
- setmodel (self, self.model);
- self.model = string_null;
-
- self.origin = ( self.mins + self.maxs ) * 0.5;
- setorigin (self, self.origin);
- self.dest = self.maxs - self.mins - '16 16 16';
- self.dest1 = self.mins + '8 8 8' - self.origin;
- self.dest2 = self.maxs + '7.9 7.9 7.9' - self.origin;
- setsize (self, self.mins, self.maxs);
- self.touch = particlefield_touch;
-// dprint( vtos( self.dest ) );
-// dprint( " " );
- if ( self.dest_x > self.dest_z )
- {
- if ( self.dest_y > self.dest_z )
- {
-// dprint( "XY1 - " );
-// dprint( ftos( self.cnt ) );
-// dprint( "\n" );
- self.use = particlefield_XY;
- self.dest1_z = ( self.dest1_z + self.dest2_z ) / 2;
- }
- else
- {
-// dprint( "XZ1 - " );
-// dprint( ftos( self.cnt ) );
-// dprint( "\n" );
- self.use = particlefield_XZ;
- self.dest1_y = ( self.dest1_y + self.dest2_y ) / 2;
- }
- }
- else
- {
- if ( self.dest_y > self.dest_x )
- {
-// dprint( "YZ2 - " );
-// dprint( ftos( self.cnt ) );
-// dprint( "\n" );
- self.use = particlefield_YZ;
- self.dest1_x = ( self.dest1_x + self.dest2_x ) / 2;
- }
- else
- {
-// dprint( "XZ2 - " );
-// dprint( ftos( self.cnt ) );
-// dprint( "\n" );
- self.use = particlefield_XZ;
- self.dest1_y = ( self.dest1_y + self.dest2_y ) / 2;
- }
- }
-
- if ( self.noise != "" )
- {
- precache_sound( self.noise );
- }
- self.ltime = time;
- };
-
-void () blocker_touch =
- {
- if ( !self.dmg )
- return;
-
- if (time < self.attack_finished)
- return;
- self.attack_finished = time + 0.5;
- T_Damage (other, self, self, self.dmg);
- sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- };
-
-void () blocker_use =
- {
- if ( !self.state )
- {
- self.state = 1;
- setorigin( self, self.origin - '8000 8000 8000' );
- // sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- }
- else
- {
- self.state = 0;
- setorigin( self, self.origin + '8000 8000 8000' );
- sound(self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- }
- };
-
-/*QUAKED func_togglewall (0 .5 .8) ? START_OFF X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Creates a invisible wall that can be toggled on and off.
-
-START_OFF wall doesn't block until triggered.
-
-"noise" is the sound to play when wall is turned off.
-"noise1" is the sound to play when wall is blocking.
-"dmg" is the amount of damage to cause when touched.
-*/
-
-void() func_togglewall =
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.classname = "togglewall";
- self.movetype = MOVETYPE_PUSH;
- self.mdl = self.model;
- setmodel (self, self.model);
- setsize (self, self.mins, self.maxs);
- setorigin (self, self.origin);
- self.touch = blocker_touch;
- self.use = blocker_use;
- if ( !self.noise )
- {
- self.noise = ("misc/null.wav");
- }
- if ( !self.noise1 )
- {
- self.noise1 = ("misc/null.wav");
- }
-
- precache_sound( self.noise );
- precache_sound( self.noise1 );
-
- self.solid = SOLID_BSP;
- self.model = string_null;
- if ( self.spawnflags & START_OFF )
- {
- self.state = 0;
- setorigin( self, self.origin + '8000 8000 8000' );
- }
- else
- {
- self.state = 1;
- sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- }
- };

Return to the top of this page or return to the overview of this repo.

Diff qc-server/hip_rotate.qc

diff --git a/qc-server/hip_rotate.qc b/qc-server/hip_rotate.qc
deleted file mode 100644
index 2f74ff9..0000000
--- a/qc-server/hip_rotate.qc
+++ /dev/null
@@ -1,1222 +0,0 @@
-/* Rotate QuickC program
- By Jim Dose' 10/17/96
- Copyright (c)1996 Hipnotic Interactive, Inc.
- All rights reserved.
- Distributed (unsupported) on 3.12.97
-*/
-
-float STATE_ACTIVE = 0;
-float STATE_INACTIVE = 1;
-float STATE_SPEEDINGUP = 2;
-float STATE_SLOWINGDOWN = 3;
-
-float STATE_CLOSED = 4;
-float STATE_OPEN = 5;
-float STATE_OPENING = 6;
-float STATE_CLOSING = 7;
-
-float STATE_WAIT = 0;
-float STATE_MOVE = 1;
-float STATE_STOP = 2;
-float STATE_FIND = 3;
-float STATE_NEXT = 4;
-
-float OBJECT_ROTATE = 0;
-float OBJECT_MOVEWALL = 1;
-float OBJECT_SETORIGIN = 2;
-
-// spawnflags for func_rotate_entity
-float ROTATE_ENTITY_TOGGLE = 1;
-float ROTATE_ENTITY_START_ON = 2;
-
-// spawnflags for path_rotate
-float PATH_ROTATE_ROTATION = 1;
-float PATH_ROTATE_ANGLES = 2;
-float PATH_ROTATE_STOP = 4;
-float PATH_ROTATE_NO_ROTATE = 8;
-float PATH_ROTATE_DAMAGE = 16;
-float PATH_ROTATE_MOVETIME = 32;
-float PATH_ROTATE_SET_DAMAGE = 64;
-
-// spawnflags for func_rotate_door
-float ROTATE_DOOR_STAYOPEN = 1;
-
-.float rotate_type;
-.vector neworigin;
-.vector rotate;
-.float endtime;
-.float duration;
-.vector finalangle;
-.string path;
-.string group;
-.string event;
-
-
-//=========================
-//
-// SUB_NormalizeAngles
-//
-//=========================
-
-vector (vector ang) SUB_NormalizeAngles =
-{
- while( ang_x > 360 )
- {
- ang_x = ang_x - 360;
- }
- while( ang_x < 0 )
- {
- ang_x = ang_x + 360;
- }
-
- while( ang_y > 360 )
- {
- ang_y = ang_y - 360;
- }
- while( ang_y < 0 )
- {
- ang_y = ang_y + 360;
- }
-
- while( ang_z > 360 )
- {
- ang_z = ang_z - 360;
- }
- while( ang_z < 0 )
- {
- ang_z = ang_z + 360;
- }
-
- return ang;
-};
-
-/*QUAKED info_rotate (0 0.5 0) (-4 -4 -4) (4 4 4) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Used as the point of rotation for rotatable objects.
-*/
-void() info_rotate =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
-// remove self after a little while, to make sure that entities that
-// have targeted it have had a chance to spawn
- self.nextthink = time + 2;
- self.think = SUB_Remove;
-};
-
-void() RotateTargets =
-{
- local entity ent;
- local vector vx;
- local vector vy;
- local vector vz;
- local vector org;
-
- makevectors (self.angles);
-
- ent = find( world, targetname, self.target);
- while( ent )
- {
- if ( ent.rotate_type == OBJECT_SETORIGIN )
- {
- org = ent.oldorigin;
- vx = ( v_forward * org_x );
- vy = ( v_right * org_y );
- vy = vy * -1;
- vz = ( v_up * org_z );
- ent.neworigin = vx + vy + vz;
- setorigin( ent, ent.neworigin + self.origin );
- }
- else if ( ent.rotate_type == OBJECT_ROTATE )
- {
- ent.angles = self.angles;
- org = ent.oldorigin;
- vx = ( v_forward * org_x );
- vy = ( v_right * org_y );
- vy = vy * -1;
- vz = ( v_up * org_z );
- ent.neworigin = vx + vy + vz;
- setorigin( ent, ent.neworigin + self.origin );
- }
- else
- {
- org = ent.oldorigin;
- vx = ( v_forward * org_x );
- vy = ( v_right * org_y );
- vy = vy * -1;
- vz = ( v_up * org_z );
- ent.neworigin = vx + vy + vz;
- ent.neworigin = self.origin - self.oldorigin + (ent.neworigin - ent.oldorigin);
- ent.velocity = (ent.neworigin-ent.origin)*25;
- }
- ent = find( ent, targetname, self.target);
- }
-};
-
-void() RotateTargetsFinal =
- {
- local entity ent;
-
- ent = find( world, targetname, self.target);
- while( ent )
- {
- ent.velocity = '0 0 0';
- if ( ent.rotate_type == OBJECT_ROTATE )
- {
- ent.angles = self.angles;
- }
- ent = find( ent, targetname, self.target);
- }
- };
-
-void() SetTargetOrigin =
- {
- local entity ent;
-
- ent = find( world, targetname, self.target);
- while( ent )
- {
- if ( ent.rotate_type == OBJECT_MOVEWALL )
- {
- setorigin( ent, self.origin - self.oldorigin +
- (ent.neworigin - ent.oldorigin) );
- }
- else
- {
- setorigin( ent, ent.neworigin + self.origin );
- }
- ent = find( ent, targetname, self.target);
- }
- };
-
-void() LinkRotateTargets =
- {
- local entity ent;
- local vector tempvec;
-
- self.oldorigin = self.origin;
- ent = find( world, targetname, self.target);
- while( ent )
- {
- if ( ent.classname == "rotate_object" )
- {
- ent.rotate_type = OBJECT_ROTATE;
- ent.oldorigin = ent.origin - self.oldorigin;
- ent.neworigin = ent.origin - self.oldorigin;
- ent.owner = self;
- }
- else if ( ent.classname == "func_movewall" )
- {
- ent.rotate_type = OBJECT_MOVEWALL;
- tempvec = ( ent.absmin + ent.absmax ) * 0.5;
- ent.oldorigin = tempvec - self.oldorigin;
- ent.neworigin = ent.oldorigin;
- ent.owner = self;
- }
- else
- {
- ent.rotate_type = OBJECT_SETORIGIN;
- ent.oldorigin = ent.origin - self.oldorigin;
- ent.neworigin = ent.origin - self.oldorigin;
- }
- ent = find (ent, targetname, self.target);
- }
- };
-
-void( entity ent, float amount ) hurt_setdamage =
- {
- ent.dmg = amount;
- if ( !amount )
- {
- ent.solid = SOLID_NOT;
- }
- else
- {
- ent.solid = SOLID_TRIGGER;
- }
- ent.nextthink = -1;
- };
-
-void( float amount ) SetDamageOnTargets =
- {
- local entity ent;
-
- ent = find( world, targetname, self.target);
- while( ent )
- {
- if ( ent.classname == "trigger_hurt" )
- {
- hurt_setdamage( ent, amount );
- }
- else if ( ent.classname == "func_movewall" )
- {
- ent.dmg = amount;
- }
- ent = find( ent, targetname, self.target);
- }
- };
-
-
-//************************************************
-//
-// Simple continual rotatation
-//
-//************************************************
-
-void() rotate_entity_think =
- {
- local float t;
-
- t = time - self.ltime;
- self.ltime = time;
-
- if ( self.state == STATE_SPEEDINGUP )
- {
- self.count = self.count + self.cnt * t;
- if ( self.count > 1 )
- {
- self.count = 1;
- }
-
- // get rate of rotation
- t = t * self.count;
- }
- else if ( self.state == STATE_SLOWINGDOWN )
- {
- self.count = self.count - self.cnt * t;
- if ( self.count < 0 )
- {
- RotateTargetsFinal();
- self.state = STATE_INACTIVE;
- self.think = SUB_Null;
- return;
- }
-
- // get rate of rotation
- t = t * self.count;
- }
-
- self.angles = self.angles + ( self.rotate * t );
- self.angles = SUB_NormalizeAngles( self.angles );
- RotateTargets();
- self.nextthink = time + 0.02;
- };
-
-void() rotate_entity_use =
- {
- // change to alternate textures
- self.frame = 1 - self.frame;
-
- if ( self.state == STATE_ACTIVE )
- {
- if ( self.spawnflags & ROTATE_ENTITY_TOGGLE )
- {
- if ( self.speed )
- {
- self.count = 1;
- self.state = STATE_SLOWINGDOWN;
- }
- else
- {
- self.state = STATE_INACTIVE;
- self.think = SUB_Null;
- }
- }
- }
- else if ( self.state == STATE_INACTIVE )
- {
- self.think = rotate_entity_think;
- self.nextthink = time + 0.02;
- self.ltime = time;
- if ( self.speed )
- {
- self.count = 0;
- self.state = STATE_SPEEDINGUP;
- }
- else
- {
- self.state = STATE_ACTIVE;
- }
- }
- else if ( self.state == STATE_SPEEDINGUP )
- {
- if ( self.spawnflags & ROTATE_ENTITY_TOGGLE )
- {
- self.state = STATE_SLOWINGDOWN;
- }
- }
- else
- {
- self.state = STATE_SPEEDINGUP;
- }
- };
-
-void() rotate_entity_firstthink =
- {
- LinkRotateTargets();
- if ( self.spawnflags & ROTATE_ENTITY_START_ON )
- {
- self.state = STATE_ACTIVE;
- self.think = rotate_entity_think;
- self.nextthink = time + 0.02;
- self.ltime = time;
- }
- else
- {
- self.state = STATE_INACTIVE;
- self.think = SUB_Null;
- }
- self.use = rotate_entity_use;
- };
-
-/*QUAKED func_rotate_entity (0 .5 .8) (-8 -8 -8) (8 8 8) TOGGLE START_ON X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Creates an entity that continually rotates. Can be toggled on and
-off if targeted.
-
-TOGGLE = allows the rotation to be toggled on/off
-
-START_ON = wether the entity is spinning when spawned. If TOGGLE is 0, entity can be turned on, but not off.
-
-If "deathtype" is set with a string, this is the message that will appear when a player is killed by the train.
-
-"rotate" is the rate to rotate.
-"target" is the center of rotation.
-"speed" is how long the entity takes to go from standing still to full speed and vice-versa.
-*/
-
-void() func_rotate_entity =
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_NONE;
-
- setmodel (self, self.model);
- setsize( self, self.mins, self.maxs );
-
- if ( self.speed != 0 )
- {
- self.cnt = 1 / self.speed;
- }
-
- self.think = rotate_entity_firstthink;
- self.nextthink = time + 0.1;
- self.ltime = time;
- };
-
-//************************************************
-//
-// Train with rotation functionality
-//
-//************************************************
-
-/*QUAKED path_rotate (0.5 0.3 0) (-8 -8 -8) (8 8 8) ROTATION ANGLES STOP NO_ROTATE DAMAGE MOVETIME SET_DAMAGE
- Path for rotate_train.
-
- ROTATION tells train to rotate at rate specified by "rotate". Use '0 0 0' to stop rotation.
-
- ANGLES tells train to rotate to the angles specified by "angles" while traveling to this path_rotate. Use values < 0 or > 360 to guarantee that it turns in a certain direction. Having this flag set automatically clears any rotation.
-
- STOP tells the train to stop and wait to be retriggered.
-
- NO_ROTATE tells the train to stop rotating when waiting to be triggered.
-
- DAMAGE tells the train to cause damage based on "dmg".
-
- MOVETIME tells the train to interpret "speed" as the length of time to take moving from one corner to another.
-
- SET_DAMAGE tells the train to set all targets damage to "dmg"
-
- "noise" contains the name of the sound to play when train stops.
- "noise1" contains the name of the sound to play when train moves.
- "event" is a target to trigger when train arrives at path_rotate.
-*/
-void() path_rotate =
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if ( self.noise != "" )
- {
- precache_sound( self.noise );
- }
- if ( self.noise1 != "" )
- {
- precache_sound( self.noise1 );
- }
- };
-
-
-void() rotate_train;
-void() rotate_train_next;
-void() rotate_train_find;
-
-void() rotate_train_think =
- {
- local float t;
- local float timeelapsed;
-
- t = time - self.ltime;
- self.ltime = time;
-
- if ( ( self.endtime ) && ( time >= self.endtime ) )
- {
- self.endtime = 0;
- if ( self.state == STATE_MOVE )
- {
- setorigin(self, self.finaldest);
- self.velocity = '0 0 0';
- }
-
- if (self.think1)
- self.think1();
- }
- else
- {
- timeelapsed = (time - self.cnt) * self.duration;
- if ( timeelapsed > 1 )
- timeelapsed = 1;
- setorigin( self, self.dest1 + ( self.dest2 * timeelapsed ) );
- }
-
- self.angles = self.angles + ( self.rotate * t );
- self.angles = SUB_NormalizeAngles( self.angles );
- RotateTargets();
-
- self.nextthink = time + 0.02;
- };
-
-void() rotate_train_use =
- {
- if (self.think1 != rotate_train_find)
- {
- if ( self.velocity != '0 0 0' )
- return; // already activated
- if ( self.think1 )
- {
- self.think1();
- }
- }
- };
-
-void() rotate_train_wait =
- {
- self.state = STATE_WAIT;
-
- if ( self.goalentity.noise != "" )
- {
- sound (self, CHAN_VOICE, self.goalentity.noise, 1, ATTN_NORM);
- }
- else
- {
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- }
- if ( self.goalentity.spawnflags & PATH_ROTATE_ANGLES )
- {
- self.rotate = '0 0 0';
- self.angles = self.finalangle;
- }
- if ( self.goalentity.spawnflags & PATH_ROTATE_NO_ROTATE )
- {
- self.rotate = '0 0 0';
- }
- self.endtime = self.ltime + self.goalentity.wait;
- self.think1 = rotate_train_next;
- };
-
-void() rotate_train_stop =
- {
- self.state = STATE_STOP;
-
- if ( self.goalentity.noise != "" )
- {
- sound (self, CHAN_VOICE, self.goalentity.noise, 1, ATTN_NORM);
- }
- else
- {
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- }
- if ( self.goalentity.spawnflags & PATH_ROTATE_ANGLES )
- {
- self.rotate = '0 0 0';
- self.angles = self.finalangle;
- }
- if ( self.goalentity.spawnflags & PATH_ROTATE_NO_ROTATE )
- {
- self.rotate = '0 0 0';
- }
-
- self.dmg = 0;
- self.think1 = rotate_train_next;
- };
-
-void() rotate_train_next =
-{
- local entity targ;
- local entity current;
- local vector vdestdelta;
- local float len, traveltime, div;
- local string temp;
-
- self.state = STATE_NEXT;
-
- current = self.goalentity;
- targ = find (world, targetname, self.path);
- if ( targ.classname != "path_rotate" )
- objerror( "Next target is not path_rotate" );
-
- if ( self.goalentity.noise1 != "" )
- {
- self.noise1 = self.goalentity.noise1;
- }
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
-
- self.goalentity = targ;
- self.path = targ.target;
- if (!self.path )
- objerror ("rotate_train_next: no next target");
-
- if ( targ.spawnflags & PATH_ROTATE_STOP )
- {
- self.think1 = rotate_train_stop;
- }
- else if (targ.wait)
- {
- self.think1 = rotate_train_wait;
- }
- else
- {
- self.think1 = rotate_train_next;
- }
-
- if ( current.event != "" )
- {
- // Trigger any events that should happen at the corner.
- temp = self.target;
- self.target = current.event;
- self.message = current.message;
- SUB_UseTargets();
- self.target = temp;
- self.message = string_null;
- }
-
- if ( current.spawnflags & PATH_ROTATE_ANGLES )
- {
- self.rotate = '0 0 0';
- self.angles = self.finalangle;
- }
-
- if ( current.spawnflags & PATH_ROTATE_ROTATION )
- {
- self.rotate = current.rotate;
- }
-
- if ( current.spawnflags & PATH_ROTATE_DAMAGE )
- {
- self.dmg = current.dmg;
- }
-
- if ( current.spawnflags & PATH_ROTATE_SET_DAMAGE )
- {
- SetDamageOnTargets( current.dmg );
- }
-
- if ( current.speed == -1 )
- {
- // Warp to the next path_corner
- setorigin( self, targ.origin );
- self.endtime = self.ltime + 0.01;
- SetTargetOrigin();
-
- if ( targ.spawnflags & PATH_ROTATE_ANGLES )
- {
- self.angles = targ.angles;
- }
-
- self.duration = 1; // 1 / duration
- self.cnt = time; // start time
- self.dest2 = '0 0 0'; // delta
- self.dest1 = self.origin; // original position
- self.finaldest = self.origin;
- }
- else
- {
- self.state = STATE_MOVE;
-
- self.finaldest = targ.origin;
- if (self.finaldest == self.origin)
- {
- self.velocity = '0 0 0';
- self.endtime = self.ltime + 0.1;
-
- self.duration = 1; // 1 / duration
- self.cnt = time; // start time
- self.dest2 = '0 0 0'; // delta
- self.dest1 = self.origin; // original position
- self.finaldest = self.origin;
- return;
- }
- // set destdelta to the vector needed to move
- vdestdelta = self.finaldest - self.origin;
-
- // calculate length of vector
- len = vlen (vdestdelta);
-
- if ( current.spawnflags & PATH_ROTATE_MOVETIME )
- {
- traveltime = current.speed;
- }
- else
- {
- // check if there's a speed change
- if (current.speed>0)
- self.speed = current.speed;
-
- if (!self.speed)
- objerror("No speed is defined!");
-
- // divide by speed to get time to reach dest
- traveltime = len / self.speed;
- }
-
- if (traveltime < 0.1)
- {
- self.velocity = '0 0 0';
- self.endtime = self.ltime + 0.1;
- if ( targ.spawnflags & PATH_ROTATE_ANGLES )
- {
- self.angles = targ.angles;
- }
- return;
- }
-
- // qcc won't take vec/float
- div = 1 / traveltime;
-
- if ( targ.spawnflags & PATH_ROTATE_ANGLES )
- {
- self.finalangle = SUB_NormalizeAngles( targ.angles );
- self.rotate = ( targ.angles - self.angles ) * div;
- }
-
- // set endtime to trigger a think when dest is reached
- self.endtime = self.ltime + traveltime;
-
- // scale the destdelta vector by the time spent traveling to get velocity
- self.velocity = vdestdelta * div;
-
- self.duration = div; // 1 / duration
- self.cnt = time; // start time
- self.dest2 = vdestdelta; // delta
- self.dest1 = self.origin; // original position
- }
- };
-
-void() rotate_train_find =
- {
- local entity targ;
-
- self.state = STATE_FIND;
-
- LinkRotateTargets();
-
- // the first target is the point of rotation.
- // the second target is the path.
- targ = find ( world, targetname, self.path);
- if ( targ.classname != "path_rotate" )
- objerror( "Next target is not path_rotate" );
-
- // Save the current entity
- self.goalentity = targ;
-
- if ( targ.spawnflags & PATH_ROTATE_ANGLES )
- {
- self.angles = targ.angles;
- self.finalangle = SUB_NormalizeAngles( targ.angles );
- }
-
- self.path = targ.target;
- setorigin (self, targ.origin );
- SetTargetOrigin();
- RotateTargetsFinal();
- self.think1 = rotate_train_next;
- if (!self.targetname)
- {
- // not triggered, so start immediately
- self.endtime = self.ltime + 0.1;
- }
- else
- {
- self.endtime = 0;
- }
-
- self.duration = 1; // 1 / duration
- self.cnt = time; // start time
- self.dest2 = '0 0 0'; // delta
- self.dest1 = self.origin; // original position
- };
-
-/*QUAKED func_rotate_train (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-In path_rotate, set speed to be the new speed of the train after it reaches
-the path change. If speed is -1, the train will warp directly to the next
-path change after the specified wait time. If MOVETIME is set on the
-path_rotate, the train to interprets "speed" as the length of time to
-take moving from one corner to another.
-
-"noise" contains the name of the sound to play when train stops.
-"noise1" contains the name of the sound to play when train moves.
-Both "noise" and "noise1" defaults depend upon "sounds" variable and
-can be overridden by the "noise" and "noise1" variable in path_rotate.
-
-Also in path_rotate, if STOP is set, the train will wait until it is
-retriggered before moving on to the next goal.
-
-Trains are moving platforms that players can ride.
-"path" specifies the first path_rotate and is the starting position.
-If the train is the target of a button or trigger, it will not begin moving until activated.
-The func_rotate_train entity is the center of rotation of all objects targeted by it.
-
-If "deathtype" is set with a string, this is the message that will appear when a player is killed by the train.
-
-speed default 100
-dmg default 0
-sounds
-1) ratchet metal
-*/
-
-void() rotate_train =
- {
- objerror ("rotate_train entities should be changed to rotate_object with\nfunc_rotate_train controllers\n");
- };
-
-void() func_rotate_train =
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.speed)
- self.speed = 100;
- if (!self.target)
- objerror ("rotate_train without a target");
-
- if ( !self.noise )
- {
- if (self.sounds == 0)
- {
- self.noise = ("misc/null.wav");
- }
-
- if (self.sounds == 1)
- {
- self.noise = ("plats/train2.wav");
- }
- }
- if ( !self.noise1 )
- {
- if (self.sounds == 0)
- {
- self.noise1 = ("misc/null.wav");
- }
- if (self.sounds == 1)
- {
- self.noise1 = ("plats/train1.wav");
- }
- }
-
- precache_sound( self.noise );
- precache_sound( self.noise1 );
-
- self.cnt = 1;
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_STEP;
- self.use = rotate_train_use;
-
- setmodel (self, self.model);
- setsize (self, self.mins, self.maxs);
- setorigin (self, self.origin);
-
-// start trains on the second frame, to make sure their targets have had
-// a chance to spawn
- self.ltime = time;
- self.nextthink = self.ltime + 0.1;
- self.endtime = self.ltime + 0.1;
- self.think = rotate_train_think;
- self.think1 = rotate_train_find;
- self.state = STATE_FIND;
-
- self.duration = 1; // 1 / duration
- self.cnt = 0.1; // start time
- self.dest2 = '0 0 0'; // delta
- self.dest1 = self.origin; // original position
-
-
- self.flags = self.flags | FL_ONGROUND;
- };
-
-//************************************************
-//
-// Moving clip walls
-//
-//************************************************
-
-void() rotate_door_reversedirection;
-void() rotate_door_group_reversedirection;
-
-void() movewall_touch =
- {
- if (time < self.owner.attack_finished)
- return;
-
- if ( self.dmg )
- {
- T_Damage (other, self, self.owner, self.dmg);
- self.owner.attack_finished = time + 0.5;
- }
- else if ( self.owner.dmg )
- {
- T_Damage (other, self, self.owner, self.owner.dmg);
- self.owner.attack_finished = time + 0.5;
- }
- };
-
-void() movewall_blocked =
- {
- local entity temp;
-
- if (time < self.owner.attack_finished)
- return;
-
- self.owner.attack_finished = time + 0.5;
-
- if ( self.owner.classname == "func_rotate_door" )
- {
- temp = self;
- self = self.owner;
- rotate_door_group_reversedirection();
- self = temp;
- }
-
- if ( self.dmg )
- {
- T_Damage (other, self, self.owner, self.dmg);
- self.owner.attack_finished = time + 0.5;
- }
- else if ( self.owner.dmg )
- {
- T_Damage (other, self, self.owner, self.owner.dmg);
- self.owner.attack_finished = time + 0.5;
- }
- };
-
-void() movewall_think =
- {
- self.ltime = time;
- self.nextthink = time + 0.02;
- };
-
-/*QUAKED func_movewall (0 .5 .8) ? VISIBLE TOUCH NONBLOCKING X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Used to emulate collision on rotating objects.
-
-VISIBLE causes brush to be displayed.
-
-TOUCH specifies whether to cause damage when touched by player.
-
-NONBLOCKING makes the brush non-solid. This is useless if VISIBLE is set.
-
-"dmg" specifies the damage to cause when touched or blocked.
-*/
-void() func_movewall =
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.angles = '0 0 0';
- self.movetype = MOVETYPE_PUSH;
- if ( self.spawnflags & MOVEWALL_NONBLOCKING )
- {
- self.solid = SOLID_NOT;
- }
- else
- {
- self.solid = SOLID_BSP;
- self.blocked = movewall_blocked;
- }
- if ( self.spawnflags & MOVEWALL_TOUCH )
- {
- self.touch = movewall_touch;
- }
- setmodel (self,self.model);
- if ( !( self.spawnflags & MOVEWALL_VISIBLE ) )
- {
- self.model = string_null;
- }
- self.think = movewall_think;
- self.nextthink = time + 0.02;
- self.ltime = time;
- };
-
-/*QUAKED rotate_object (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-This defines an object to be rotated. Used as the target of func_rotate_door.
-*/
-void() rotate_object =
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.classname = "rotate_object";
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_NONE;
- setmodel (self,self.model);
- setsize( self, self.mins, self.maxs );
- self.think = SUB_Null;
- };
-
-//************************************************
-//
-// Rotating doors
-//
-//************************************************
-
-void() rotate_door_think2 =
- {
- local float t;
-
- t = time - self.ltime;
- self.ltime = time;
-
- // change to alternate textures
- self.frame = 1 - self.frame;
-
- self.angles = self.dest;
-
- if ( self.state == STATE_OPENING )
- {
- self.state = STATE_OPEN;
- }
- else
- {
- if ( self.spawnflags & ROTATE_DOOR_STAYOPEN )
- {
- rotate_door_group_reversedirection();
- return;
- }
- self.state = STATE_CLOSED;
- }
-
- sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
- self.think = SUB_Null;
-
- RotateTargetsFinal();
- };
-
-void() rotate_door_think =
- {
- local float t;
-
- t = time - self.ltime;
- self.ltime = time;
-
- if ( time < self.endtime )
- {
- self.angles = self.angles + ( self.rotate * t );
- RotateTargets();
- }
- else
- {
- self.angles = self.dest;
- RotateTargets();
- self.think = rotate_door_think2;
- }
-
- self.nextthink = time + 0.01;
- };
-
-void() rotate_door_reversedirection =
- {
- local vector start;
-
- // change to alternate textures
- self.frame = 1 - self.frame;
-
- if ( self.state == STATE_CLOSING )
- {
- start = self.dest1;
- self.dest = self.dest2;
- self.state = STATE_OPENING;
- }
- else
- {
- start = self.dest2;
- self.dest = self.dest1;
- self.state = STATE_CLOSING;
- }
-
- sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
-
- self.rotate = ( self.dest - start ) * ( 1 / self.speed );
- self.think = rotate_door_think;
- self.nextthink = time + 0.02;
- self.endtime = time + self.speed - ( self.endtime - time );
- self.ltime = time;
- };
-
-void() rotate_door_group_reversedirection =
- {
- local string name;
-
- // tell all associated rotaters to reverse direction
- if ( self.group != "" )
- {
- name = self.group;
- self = find( world, group, name);
- while( self )
- {
- rotate_door_reversedirection();
- self = find( self, group, name);
- }
- }
- else
- {
- rotate_door_reversedirection();
- }
- };
-
-void() rotate_door_use =
- {
- local vector start;
-
- if ( ( self.state != STATE_OPEN ) && ( self.state != STATE_CLOSED ) )
- return;
-
- if ( !self.cnt )
- {
- self.cnt = 1;
- LinkRotateTargets();
- }
-
- // change to alternate textures
- self.frame = 1 - self.frame;
-
- if ( self.state == STATE_CLOSED )
- {
- start = self.dest1;
- self.dest = self.dest2;
- self.state = STATE_OPENING;
- }
- else
- {
- start = self.dest2;
- self.dest = self.dest1;
- self.state = STATE_CLOSING;
- }
-
- sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
-
- self.rotate = ( self.dest - start ) * ( 1 / self.speed );
- self.think = rotate_door_think;
- self.nextthink = time + 0.01;
- self.endtime = time + self.speed;
- self.ltime = time;
- };
-
-
-/*QUAKED func_rotate_door (0 .5 .8) (-8 -8 -8) (8 8 8) STAYOPEN X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Creates a door that rotates between two positions around a point of
-rotation each time it's triggered.
-
-STAYOPEN tells the door to reopen after closing. This prevents a trigger-
-once door from closing again when it's blocked.
-
-"dmg" specifies the damage to cause when blocked. Defaults to 2. Negative numbers indicate no damage.
-"speed" specifies how the time it takes to rotate
-
-"sounds"
-1) medieval (default)
-2) metal
-3) base
-*/
-
-void() func_rotate_door = // added slinet option - sounds 4 -- dumptruck_ds
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.target)
- {
- objerror( "rotate_door without target." );
- }
-
- self.dest1 = '0 0 0';
- self.dest2 = self.angles;
- self.angles = self.dest1;
-
- // default to 2 seconds
- if ( !self.speed )
- {
- self.speed = 2;
- }
-
- self.cnt = 0;
-
- if (!self.dmg)
- self.dmg = 2;
- else if ( self.dmg < 0 )
- {
- self.dmg = 0;
- }
-
- if (self.sounds == 0)
- {
- //If at least one custom sound is defined, then let's ignore the presets and go for the custom sounds,
- //otherwise let's use preset #1 by default
- if(self.noise1=="" && self.noise2=="" && self.noise3=="")
- {
- self.sounds = 1;
- }
- else
- {
- if(self.noise1=="") self.noise1 = "misc/null.wav";
- if(self.noise2=="") self.noise2 = "misc/null.wav";
- if(self.noise3=="") self.noise3 = "misc/null.wav";
- }
- }
- if (self.sounds == 1)
- {
- self.noise1 = "doors/latch2.wav";
- self.noise2 = "doors/winch2.wav";
- self.noise3 = "doors/drclos4.wav";
- }
- else if (self.sounds == 2)
- {
- self.noise2 = "doors/airdoor1.wav";
- self.noise1 = "doors/airdoor2.wav";
- self.noise3 = self.noise1;
- }
- else if (self.sounds == 3)
- {
- self.noise2 = "doors/basesec1.wav";
- self.noise1 = "doors/basesec2.wav";
- self.noise3 = self.noise1;
- }
- else if (self.sounds == 4)
- {
- self.noise1 = self.noise2 = self.noise3 = "misc/null.wav";
- }
- precache_sound (self.noise1);
- precache_sound (self.noise2);
- precache_sound (self.noise3);
-
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_NONE;
- setmodel (self, self.model);
- setorigin( self, self.origin );
- setsize( self, self.mins, self.maxs );
- self.state = STATE_CLOSED;
- self.use = rotate_door_use;
- self.think = SUB_Null;
- };

Return to the top of this page or return to the overview of this repo.

Diff qc-server/hip_trig.qc

diff --git a/qc-server/hip_trig.qc b/qc-server/hip_trig.qc
deleted file mode 100644
index f8a3dec..0000000
--- a/qc-server/hip_trig.qc
+++ /dev/null
@@ -1,238 +0,0 @@
-//Selections from hiptrig.qc NOT the entire file
-
-/* Trigger QuickC program
- By Jim Dose' 12/2/96
- Copyright (c)1996 Hipnotic Interactive, Inc.
- All rights reserved.
- Do not distribute.
-*/
-
-float USE_SILV_KEY = 8;
-float USE_GOLD_KEY = 16;
-
-/*
-================
-keytrigger_unlock
-
-Perform the actions which should be performed when self is successfully
-unlocked with a key.
-
-This function exists so that it can be passed as an argument to the new
-keylock_try_to_unlock function. This code was previously part of the
-keytrigger_use function. -- iw
-================
-*/
-void() keytrigger_unlock =
-{
- // we can't just remove (self) here, because this is a touch function
- // called while C code is looping through area links...
- self.touch = SUB_Null;
- self.use = SUB_Null;
- self.nextthink = time + 0.1;
- self.think = SUB_Remove;
- self.message = "";
-
- SUB_UseTargets();
-};
-
-void() keytrigger_use =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- if (self.attack_finished > time)
- return;
-
- self.attack_finished = time + 2;
- keylock_try_to_unlock (activator, self.message, keytrigger_unlock);
-};
-
-void() keytrigger_touch =
-{
- activator = other;
- keytrigger_use();
-};
-
-/*QUAKED trigger_usekey (0 .5 0) ? X X X USE_SILV_KEY USE_GOLD_KEY X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Variable sized single use trigger that requires a key to trigger targets. Must be targeted at one or more entities.
-
-"cnt" if 1, leave a used key in the player's inventory (0 default).
-"keyname" if set, this is the keyname of the item_key_custom which unlocks this entity.
-"message" is printed when the trigger is touched without having the right key.
-"noise1" sound file for the "key required" sound (default is per worldtype).
-"noise2" sound file for the "key used" sound (default is per worldtype).
-*/
-
-void() trigger_usekey =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
-// the keylock_* functions use self.noise3 and self.noise4 internally,
-// but trigger_usekey doesn't use the self.noise1 or self.noise2 fields
-// for anything, so we allow the mapper to specify custom sound files by
-// setting self.noise1 and self.noise2, but we move those values into
-// self.noise3 and self.noise4 -- iw
- self.noise3 = self.noise1;
- self.noise4 = self.noise2;
- self.noise1 = "";
- self.noise2 = "";
-
- keylock_init ();
-
- if (self.spawnflags & USE_SILV_KEY) {//dumptruck_ds
- keylock_set_silver_key ();
-
- if (self.keyname != "") {
- self.netname = self.keyname;
- self.keyname = "";
- }
- }
- if (self.spawnflags & USE_GOLD_KEY) {//dumptruck_ds
- keylock_set_gold_key ();
-
- if (self.keyname != "") {
- self.netname = self.keyname;
- self.keyname = "";
- }
- }
-
-// support for item_key_custom -- iw
- if (self.keyname != "")
- {
- keylock_set_custom_key (self.keyname);
- self.keyname = ""; // this should not be referenced again
- }
-
- if (!keylock_has_key_set ())
- {
- objerror ("no key specified!");
- return;
- }
-
- self.use = keytrigger_use;
- self.touch = keytrigger_touch;
-
- InitTrigger ();
- SUB_CheckWaiting();
-};
-
-// void() remove_touch =
-// {
-// if (other.flags & self.cnt)
-// return;
-// other.touch = SUB_Null;
-// other.model = "";
-// remove(self);
-// };
-//
-// /*QUAKED trigger_remove (.5 .5 .5) ? ignoremonsters ignoreplayers
-// Variable sized trigger that removes the thing
-// that touches it. Does not affect monsters or
-// players.
-// */
-// void() trigger_remove =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// self.cnt = FL_CLIENT|FL_MONSTER;
-// if (self.spawnflags & 1)
-// self.cnt = self.cnt - FL_MONSTER;
-// if (self.spawnflags & 2)
-// self.cnt = self.cnt - FL_CLIENT;
-// InitTrigger ();
-// self.touch = remove_touch;
-// };
-
-/*
-==============================================================================
-
-trigger_setgravity
-
-==============================================================================
-*/
-float DT_GRAVTOFF = 8; // trigger will start off
-
-void() grav_toggle = //dumptruck_ds based on hipnotic blocker_use
-{
- if (self.estate != STATE_ACTIVE)
- self.estate = STATE_ACTIVE;
- else
- self.estate = STATE_INACTIVE;
-
-};
-
-void() trigger_gravity_touch =
-{
- // from Copper -- dumptruck_ds
- // if (!CheckValidTouch()) return;
-
- if (self.estate != STATE_ACTIVE) return;
-
- local float grav;
-
-// This is commented out so that the changing gravity will
-// affect everything, if you don't want to use all affecting
-// gravity changes, then uncomment these two lines.
-// if (other.classname != "player")
-// return;
-
- if (self.gravity == -1)
- grav = 1;
- else
- grav = self.gravity;
-
- // the player's gravity is now managed in PlayerPreThink(), however
- // other entities don't have special gravity management, so their
- // gravity is still set directly -- iw
- if (other.classname == "player")
- other.wantedgravity = grav;
- else
- other.gravity = grav;
-};
-
-/*QUAKED trigger_setgravity (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-set the gravity of a player
-
-"gravity" what to set the players gravity to
- - 0 (default) normal gravity
- - 1 no gravity
- - 2 almost no gravity
- - 10 is a good setting
- - ...
- - 101 normal gravity
- - 102 slightly higher gravity
- - ...
- - 1000 very high gravity
-
- NOTE: the amount of gravity can only be changed by touching another
- trigger_setgravity with a different setting. The gravity key defaults to 0
- which is normal gravity. Lower numbers (e.g. 25) equal lower gravity. Setting
- 100 is normal gravity. Numbers above 100 will make the player “heavier”, i.e.
- harder to jump. If you want multiple trigger setgravity triggers in one room or
- area, make sure the brushes are not touching each other. This can cause the
- triggers not to work properly.
-
-*/
-void() trigger_setgravity =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- InitTrigger ();
-
- self.use = grav_toggle; // dumptruck_ds
- self.touch = trigger_gravity_touch;
-
- if ( self.spawnflags & DT_GRAVTOFF ) //dumptruck_ds
- self.estate = STATE_INACTIVE;
-
- if (!self.gravity)
- self.gravity = -1;
- else
- self.gravity = ((self.gravity - 1) / 100);
-
- SUB_CheckWaiting();
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/intermission.qc

diff --git a/qc-server/intermission.qc b/qc-server/intermission.qc
deleted file mode 100644
index 33b8565..0000000
--- a/qc-server/intermission.qc
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
-=============================================================================
-
- LEVEL CHANGING / INTERMISSION
-
-=============================================================================
-*/
-
-float intermission_running;
-float intermission_exittime;
-entity used_exit;
-
-
-/*QUAKED info_intermission (1 0.5 0.5) (-16 -16 -16) (16 16 16) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-This is the camera point for the intermission.
-Use mangle instead of angle, so you can set pitch or roll as well as yaw. 'pitch roll yaw'
-*/
-void() info_intermission =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-};
-
-
-void() info_intermissiontext =
-{
- if (self.message == "" || self.cnt == 0)
- {
- objerror("endscreen lacks required fields");
- }
-}
-
-void(string message) ShowIntermissionMessage =
-{
- WriteByte (MSG_ALL, SVC_FINALE);
- WriteString (MSG_ALL, message);
-}
-
-void() StartMessageIntermission =
-{
- WriteByte (MSG_ALL, SVC_CDTRACK);
- WriteByte (MSG_ALL, 2);
- WriteByte (MSG_ALL, 3);
-}
-
-void() Episode1End =
-{
- StartMessageIntermission();
- if (!cvar("registered"))
- {
- ShowIntermissionMessage("As the corpse of the monstrous entity\nChthon sinks back into the lava whence\nit rose, you grip the Rune of Earth\nMagic tightly. Now that you have\nconquered the Dimension of the Doomed,\nrealm of Earth Magic, you are ready to\ncomplete your task in the other three\nhaunted lands of Quake. Or are you? If\nyou don't register Quake, you'll never\nknow what awaits you in the Realm of\nBlack Magic, the Netherworld, and the\nElder World!");
- }
- else
- {
- ShowIntermissionMessage("As the corpse of the monstrous entity\nChthon sinks back into the lava whence\nit rose, you grip the Rune of Earth\nMagic tightly. Now that you have\nconquered the Dimension of the Doomed,\nrealm of Earth Magic, you are ready to\ncomplete your task. A Rune of magic\npower lies at the end of each haunted\nland of Quake. Go forth, seek the\ntotality of the four Runes!");
- }
-}
-
-void() Episode2End =
-{
- StartMessageIntermission();
- ShowIntermissionMessage("The Rune of Black Magic throbs evilly in\nyour hand and whispers dark thoughts\ninto your brain. You learn the inmost\nlore of the Hell-Mother; Shub-Niggurath!\nYou now know that she is behind all the\nterrible plotting which has led to so\nmuch death and horror. But she is not\ninviolate! Armed with this Rune, you\nrealize that once all four Runes are\ncombined, the gate to Shub-Niggurath's\nPit will open, and you can face the\nWitch-Goddess herself in her frightful\notherworld cathedral.");
-}
-
-void() Episode3End =
-{
- StartMessageIntermission();
- ShowIntermissionMessage("The charred viscera of diabolic horrors\nbubble viscously as you seize the Rune\nof Hell Magic. Its heat scorches your\nhand, and its terrible secrets blight\nyour mind. Gathering the shreds of your\ncourage, you shake the devil's shackles\nfrom your soul, and become ever more\nhard and determined to destroy the\nhideous creatures whose mere existence\nthreatens the souls and psyches of all\nthe population of Earth.");
-
-}
-
-void() Episode4End =
-{
- StartMessageIntermission();
- ShowIntermissionMessage("Despite the awful might of the Elder\nWorld, you have achieved the Rune of\nElder Magic, capstone of all types of\narcane wisdom. Beyond good and evil,\nbeyond life and death, the Rune\npulsates, heavy with import. Patient and\npotent, the Elder Being Shub-Niggurath\nweaves her dire plans to clear off all\nlife from the Earth, and bring her own\nfoul offspring to our world! For all the\ndwellers in these nightmare dimensions\nare her descendants! Once all Runes of\nmagic power are united, the energy\nbehind them will blast open the Gateway\nto Shub-Niggurath, and you can travel\nthere to foil the Hell-Mother's plots\nin person.");
-}
-
-float() RunId1Intermissions =
-{
- if (world.skip_id1_overrides == 0)
- {
- if (world.model == "maps/e1m7.bsp")
- {
- Episode1End();
- return 1;
- }
- else if (world.model == "maps/e2m6.bsp")
- {
- Episode2End();
- return 1;
- }
- else if (world.model == "maps/e3m6.bsp")
- {
- Episode3End();
- return 1;
- }
- else if (world.model == "maps/e4m7.bsp")
- {
- Episode4End();
- return 1;
- }
- }
- return 0;
-}
-
-/*
-============
-FindIntermission
-
-Returns the entity to view from
-============
-*/
-entity() FindIntermission =
-{
- local entity spot;
- local float cyc;
-
-// look for info_intermission first
- spot = find (world, classname, "info_intermission");
- if (spot)
- { // pick a random one
- cyc = random() * 4;
- while (cyc > 1)
- {
- spot = find (spot, classname, "info_intermission");
- if (!spot)
- spot = find (spot, classname, "info_intermission");
- cyc = cyc - 1;
- }
- return spot;
- }
-
-// then look for the start position
- spot = find (world, classname, "info_player_start");
- if (spot)
- return spot;
-
-// testinfo_player_start is only found in regioned levels
- spot = find (world, classname, "testplayerstart");
- if (spot)
- return spot;
-
- objerror ("FindIntermission: no spot");
- return world;// just to suppress the compiler warning
-};
-
-
-string nextmap;
-void() GotoNextMap =
-{
- if (cvar("samelevel")) // if samelevel is set, stay on same level
- changelevel (mapname);
- else
- changelevel (nextmap);
-};
-
-float(float start) ShowIntermissionTextEntity =
-{
- if (!(used_exit.spawnflags & 2))
- {
- local entity end_message;
- for (end_message = world; (end_message = find(end_message, classname, "info_intermissiontext"));)
- {
- if (end_message.cnt == (intermission_running - 1))
- {
- if (start == 1)
- {
- StartMessageIntermission();
- }
- ShowIntermissionMessage(end_message.message);
- return 1;
- }
- }
- }
- return 0;
-}
-
-void() ExitIntermission =
-{
-// skip any text in deathmatch
- if (deathmatch)
- {
- GotoNextMap ();
- return;
- }
-
-
-
- intermission_exittime = time + 1;
- intermission_running = intermission_running + 1;
-//
-// run some text if at the end of an episode
-//
- if (intermission_running == 2)
- {
- if (RunId1Intermissions() == 1)
- {
- return;
- }
- else
- {
- if (used_exit.message != "") // favor message on changelevel
- {
- StartMessageIntermission();
- ShowIntermissionMessage(used_exit.message);
- return;
- }
- if (ShowIntermissionTextEntity(1))
- {
- return;
- }
- }
-
- GotoNextMap();
- }
-
- if (intermission_running == 3)
- {
- if (!cvar("registered"))
- { // shareware episode has been completed, go to sell screen
- WriteByte (MSG_ALL, SVC_SELLSCREEN);
- return;
- }
- if (ShowIntermissionTextEntity(0))
- {
- return;
- }
- if ( (serverflags&15) == 15)
- {
- ShowIntermissionMessage("Now, you have all four Runes. You sense\ntremendous invisible forces moving to\nunseal ancient barriers. Shub-Niggurath\nhad hoped to use the Runes Herself to\nclear off the Earth, but now instead,\nyou will use them to enter her home and\nconfront her as an avatar of avenging\nEarth-life. If you defeat her, you will\nbe remembered forever as the savior of\nthe planet. If she conquers, it will be\nas if you had never been born.");
- return;
-
- }
-
- }
-
- if (intermission_running > 3)
- {
- if (ShowIntermissionTextEntity(0))
- {
- return;
- }
- }
-
- GotoNextMap();
-};
-
-/*
-============
-IntermissionThink
-
-When the player presses attack or jump, change to the next level
-============
-*/
-void() IntermissionThink =
-{
- if (time < intermission_exittime)
- return;
-
- if (!self.button0 && !self.button1 && !self.button2)
- return;
-
- ExitIntermission ();
-};
-
-void() execute_changelevel =
-{
- used_exit = self;
- local entity pos;
-
- intermission_running = 1;
-
-// enforce a wait time before allowing changelevel
- if (deathmatch)
- intermission_exittime = time + 5;
- else
- intermission_exittime = time + 2;
-
- WriteByte (MSG_ALL, SVC_CDTRACK);
- WriteByte (MSG_ALL, 3);
- WriteByte (MSG_ALL, 3);
-
- pos = FindIntermission ();
-
- other = find (world, classname, "player");
- while (other != world)
- {
- other.view_ofs = '0 0 0';
- other.angles = other.v_angle = pos.mangle;
- other.fixangle = TRUE; // turn this way immediately
- other.nextthink = time + 0.5;
- other.takedamage = DAMAGE_NO;
- other.solid = SOLID_NOT;
- other.movetype = MOVETYPE_NONE;
- other.modelindex = 0;
- setorigin (other, pos.origin);
- other = find (other, classname, "player");
- fog_setFromEnt(other, pos);
- }
- // Drake -- dumptruck_ds
- if (cutscene)
- { // If player was in a cutscene when the level ended, restore viewsize.
- pos = find (world, classname, "camera");
- if (pos)
- {
- local string val;
-
- val = ftos (pos.cnt);
- cvar_set ("viewsize", val);
- }
- }
-
- WriteByte (MSG_ALL, SVC_INTERMISSION);
-};
-
-
-void() changelevel_touch =
-{
- if (self.estate != STATE_ACTIVE) return;
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- if ((cvar("noexit") == 1) || ((cvar("noexit") == 2) && (mapname != "start")))
- {
- T_Damage (other, self, self, 50000);
- return;
- }
-
- if (coop || deathmatch)
- {
- bprint (other.netname);
- bprint (" exited the level\n");
- }
-
- nextmap = self.map;
-
- SUB_UseTargets ();
- if ( (self.spawnflags & 16) && (deathmatch == 0) ) //use info_player_start2 -- dumptruck_ds
- {
- sigil_touch2();
- }
-
- if ( (self.spawnflags & 1) && (deathmatch == 0) )
- { // NO_INTERMISSION
- GotoNextMap();
- return;
- }
-
-
- self.touch = SUB_Null;
-
-// we can't move people right now, because touch functions are called
-// in the middle of C movement code, so set a think time to do it
- self.think = execute_changelevel;
- self.nextthink = time + 0.1;
-};
-
-void() dt_exit_toggle = //dumptruck_ds based on hipnotic blocker_use
-{
- if (self.estate != STATE_ACTIVE)
- {
- self.is_waiting = 0;
- self.estate = STATE_ACTIVE;
- }
- else
- {
- self.is_waiting = 1;
- self.estate = STATE_INACTIVE;
- }
-};
-
-
-float DT_EXITOFF = 8;
-/*QUAKED trigger_changelevel (0.5 0.5 0.5) ? NO_INTERMISSION X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-When the player touches this, he gets sent to the map listed in the "map" variable. Unless the NO_INTERMISSION flag is set, the view will go to the info_intermission spot and display stats.
-*/
-void() trigger_changelevel =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & DT_EXITOFF) //dumptruck_ds
- {
- self.is_waiting = 1;
- }
- SUB_CheckWaiting();
-
- self.use = dt_exit_toggle;
- if (!self.map)
- objerror ("changelevel trigger doesn't have map");
-
-
- InitTrigger ();
- self.flags = self.flags | FL_NOCENTERPRINT;
- self.touch = changelevel_touch;
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/items.qc

diff --git a/qc-server/items.qc b/qc-server/items.qc
deleted file mode 100644
index 7bbbf1f..0000000
--- a/qc-server/items.qc
+++ /dev/null
@@ -1,2441 +0,0 @@
-void (vector org) spawn_tfog;
-void() W_SetCurrentAmmo;
-/* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
-BE .8 .3 .4 IN COLOR */
-
-float ITEM_SPAWNSILENT = 32;
-float ITEM_SPAWNED = 64;
-float ITEM_SUSPENDED = 128;
-float ITEM_RESPAWNDM = 16384;
-float ITEM_DONTDROP = 8388608;
-
-.vector particles_offset;
-
-void() SUB_regen =
-{
- self.model = self.mdl; // restore original model
- self.solid = SOLID_TRIGGER; // allow it to be touched again
- if (deathmatch || (self.spawnflags & ITEM_RESPAWNDM)) // Respawn with DM effects
- sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM); // play respawn sound
- else
- spawn_tfog (self.origin + self.particles_offset); // play teleport sound and display particles
- setorigin (self, self.origin);
-};
-
-// Supa, Quoth respawning items support Respawn item like in DM if 'ritem' TRUE,
-// override respawn time with 'respawndelay' if set, inc 'cnt' with each respawn
-// and if 'respawncount' is set we'll remove the item if cnt > respawncount
-// remember that SUB_Regen is already set on every item that can respawn, all we
-// need to do is give a nextthink time in order to trigger it
-.float ritem,
- respawndelay,
- respawncount;
-
-void(entity whatitem, float defaultdelay) CheckItemRespawn =
-{
- if (!whatitem.ritem) // respawn item if true, otherwise abort
- return;
-
- whatitem.cnt = whatitem.cnt + 1; // inc before check to account for zero indexing
-
- if (whatitem.respawncount) // limited respawns
- if (whatitem.respawncount < whatitem.cnt)
- return;
-
- // okay, we're clear to set up a respawn
-
- if (whatitem.respawndelay) // custom respawn delay?
- whatitem.nextthink = time + whatitem.respawndelay;
- else
- whatitem.nextthink = time + defaultdelay;
-};
-
-
-/*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
-prints a warning message when spawned
-*/
-void() noclass =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- dprint ("noclass spawned at");
- dprint (vtos(self.origin));
- dprint ("\n");
- remove (self);
-};
-
-/*
-============
-DelaySpawnItem //this is from rmq-items.qc
-
-Makes a SPAWNED item ready for pickup on a trigger event - modified a bit -- dumptruck_ds
-============
-*/
-void() DelaySpawnItem =
-{
- self.solid = SOLID_TRIGGER;
- setmodel (self, self.mdl);
- setsize (self, self.pos1, self.pos2);
-
- if (!(self.spawnflags & ITEM_SPAWNSILENT)) // SILENT, gb
- // sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);
- spawn_tfog (self.origin + self.particles_offset);
-
- if (self.spawnflags & ITEM_SUSPENDED)
- self.movetype = MOVETYPE_FLY;
- else
- self.movetype = MOVETYPE_TOSS;
-
- self.use = SUB_Null;
-};
-
-
-// Supa, restore old hull and lock movement
-void() RefreshHull =
-{
- // setsize (self, self.dest, self.dest2);
- setsize (self, '0 0 0', '32 32 56'); //dumptruck_ds -- fix for bounding boxes
-
- self.movetype = MOVETYPE_NONE;
- self.velocity = '0 0 0';
-};
-
-
-/*
-============
-PlaceItem
-
-plants the object on the floor
-============
-*/
-void() PlaceItem =
-{
- // local float oldz;
- self.mdl = self.model; // so it can be restored on respawn
- self.flags = FL_ITEM; // make extra wide
- self.solid = SOLID_TRIGGER;
- self.velocity = '0 0 0';
-
- if (self.spawnflags & ITEM_SUSPENDED) //ijed Don't drop spawnflag
- {
- self.movetype = MOVETYPE_FLY;
- }
- else
- {
- // The following hack for item_health was inherited from the RMQ
- // code, and was here when the func_mapjamx maps were created.
- // It would have been nice to remove this code entirely, because
- // progs_dump doesn't need it, and it breaks item_health's
- // collision with entities that have MOVETYPE_PUSH. However,
- // removing this code would cause some of the item_health
- // entities in some of the func_mapjamx maps to "fall out of the
- // level", because they're accidentally touching solid surfaces.
- // So, to maintain backwards-compatibility, this code has been
- // left in, but will only be run if one of the func_mapjamx maps
- // is being played. -- iw
- //
- if (known_release == KNOWN_RELEASE_FUNC_MAPJAMX)
- {
- if (self.classname == "item_health") // Supa, CTF
- {
-
- // hacking around hull issues..
- setsize (self, '0 0 0', '0 0 0'); // void hull for now
-
- self.think = RefreshHull;
- self.nextthink = time + 0.2;
- }
- }
-
- self.movetype = MOVETYPE_TOSS;
-
- if (!(self.spawnflags & ITEM_DONTDROP))
- {
- setorigin (self, self.origin + '0 0 6');
-
- if (!droptofloor())
- {
- print_self ("bonus item", "fell out of level");
- remove(self);
- return;
- }
- }
- }
-
- if ((self.spawnflags & ITEM_SPAWNED)) // SPAWNED, gb
- {
- self.pos1 = self.mins;
- self.pos2 = self.maxs;
-
- self.model = "";
- self.solid = SOLID_NOT;
-
- if (self.spawnflags & ITEM_DONTDROP) self.movetype = MOVETYPE_NONE;
-
- self.use = DelaySpawnItem;
- }
-};
-
-
-/*
-============
-StartItem
-
-Sets the clipping size and plants the object on the floor
-============
-*/
-void() StartItem =
-{
- self.nextthink = time + 0.3; // items start after other solids || was 0.2 -- dumptruck_ds
- self.think = PlaceItem;
-};
-
-/*
-=========================================================================
-
-HEALTH BOX
-
-=========================================================================
-*/
-//
-// T_Heal: add health to an entity, limiting health to max_health
-// "ignore" will ignore max_health limit
-//
-float (entity e, float healamount, float ignore) T_Heal =
-{
- if (e.health <= 0)
- return 0;
- if ((!ignore) && (e.health >= other.max_health))
- return 0;
- healamount = ceil(healamount);
-
- e.health = e.health + healamount;
- if ((!ignore) && (e.health >= other.max_health))
- e.health = other.max_health;
-
- if (e.health > 250)
- e.health = 250;
- return 1;
-};
-
-/*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) ROTTEN MEGAHEALTH X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ( {{ spawnflags & 1 -> { "path" : "maps/b_bh10.bsp" }, spawnflags & 2 -> { "path" : "maps/b_bh100.bsp" },
- "maps/b_bh25.bsp" }} );
-}
-Health box. Normally gives 25 points.
-Rotten box heals 15 points.
-Megahealth will add 100 health, then start to
-rot the player back down to 100 health after 5 seconds.
-*/
-
-float H_ROTTEN = 1;
-float H_MEGA = 2;
-float H_VIAL = 4;
-.float healamount, healtype;
-void() health_touch;
-// void() item_megahealth_rot;
-
-void() item_health =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = health_touch;
-
-
-
- if (self.spawnflags & H_ROTTEN)
- {
- if (!self.mdl_body && world.h_15_mdl)
- {
- self.mdl_body = world.h_15_mdl;
- }
- // precache_model("maps/b_bh10.bsp"); // dumptruck_ds custom health models and sounds START
- if (world.style)
- {
- precache_body_model ("progs/h_mdls/m_h15.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/h_mdls/m_h15.mdl");
- }
- else
- {
- // setmodel(self, "maps/b_bh10.bsp");
- precache_body_model ("maps/b_bh10.bsp");
- body_model ("maps/b_bh10.bsp");
- }
- // precache_sound("items/r_item1.wav");
- precache_sound_misc("items/r_item1.wav");
- // self.noise = "items/r_item1.wav";
- if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
- self.snd_misc = "items/r_item1.wav";
- self.noise = self.snd_misc;
-
- // if !(self.healamount) //set your custom health amount here -- dumptruck_ds
- self.healamount = 15;
- self.healtype = 0;
- if !(self.particles_offset)
- self.particles_offset = '16 16 8'; // dumptruck_ds custom health models and sounds END
-
- }
- else
- if (self.spawnflags & H_MEGA)
- {
- if (!self.mdl_body && world.h_mega_mdl)
- {
- self.mdl_body = world.h_mega_mdl;
- }
- // precache_model("maps/b_bh100.bsp");
- if (world.style)
- {
- precache_body_model ("progs/h_mdls/m_h100.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/h_mdls/m_h100.mdl");
- }
- else
- {
- // setmodel(self, "maps/b_bh100.bsp");
- precache_body_model ("maps/b_bh100.bsp");
- body_model ("maps/b_bh100.bsp");
- }
- precache_sound_misc("items/r_item2.wav");
- // self.noise = "items/r_item2.wav";
- if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
- self.snd_misc = "items/r_item2.wav";
- self.noise = self.snd_misc;
-
- // if !(self.healamount) //set your custom health amount here -- dumptruck_ds
- self.healamount = 100;
- self.healtype = 2;
- if !(self.particles_offset)
- self.particles_offset = '16 16 16';
- }
- else
- {
- if (!self.mdl_body && world.h_25_mdl)
- {
- self.mdl_body = world.h_25_mdl;
- }
- if (world.style)
- {
- precache_body_model ("progs/h_mdls/m_h25.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/h_mdls/m_h25.mdl");
- }
- else
- {
- precache_body_model ("maps/b_bh25.bsp");
- body_model ("maps/b_bh25.bsp");
- }
- precache_sound_misc("items/health1.wav");
- if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
- self.snd_misc = "items/health1.wav";
- self.noise = self.snd_misc;
-
- self.healamount = 25;
- self.healtype = 1;
- if !(self.particles_offset)
- self.particles_offset = '16 16 8'; // dumptruck_ds custom health models and sounds END
- }
- setsize (self, '0 0 0', '32 32 56');
- StartItem ();
-};
-
-void() item_health_vial =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = health_touch;
-
- if (!self.mdl_body && world.h_vial_mdl)
- {
- self.mdl_body = world.h_vial_mdl;
- }
-
- precache_body_model ("progs/h_mdls/pd_vial.mdl"); // model from Hexen 2 -- dumptruck_ds
- body_model("progs/h_mdls/pd_vial.mdl");
- precache_sound_misc("items/r_item1.wav");
- if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
- self.snd_misc = "items/r_item1.wav";
- self.noise = self.snd_misc;
-
- self.healamount = 5;
- self.healtype = 2; // over heal and count down like mega health -- dumptruck_ds
- setsize (self, '-16 -16 0', '16 16 56');
- if !(self.particles_offset)
- self.particles_offset = '0 0 0';
- StartItem ();
-};
-
-void() health_touch =
-{
- local float amount;
- local string s;
- amount = self.healamount;
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- if (self.healtype == 2) // Megahealth? Ignore max_health...
- {
- if (other.health >= 250)
- return;
- if (!T_Heal(other, amount, 1))
- return;
- }
- else
- {
- if (!T_Heal(other, amount, 0))
- return;
- }
-
- sprint(other, "You receive ");
- s = ftos(amount);
- sprint(other, s);
- sprint(other, " health\n");
-
-// health touch sound
- // sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
- sound_misc(other, CHAN_AUTO, self.noise, 1, ATTN_NORM); //custom sounds -- dumptruck_ds
-
- stuffcmd (other, "bf\n");
-
- self.model = string_null;
- self.solid = SOLID_NOT;
-
- self.think = SUB_regen;
-
- // Megahealth = rot down the player's super health
- if (self.healtype == 2)
- {
- other.megahealth_rottime = time + 5; //thanks ydrol!!!
- other.items = other.items | IT_SUPERHEALTH;
- self.owner = other;
-
- // Regarding the deathmatch respawn time below: id's original
- // code made the megahealth respawn 20 seconds after the health
- // of the player who collected it finished rotting down.
- // However, this mod has already got rid of the weird old
- // megahealth behavior whereby it monitored the player who
- // touched it, so the original respawn logic isn't applicable.
- // As a solution, the code below uses a respawn time of 125
- // seconds for deathmatch, because that was the worst-case
- // scenario of id's original code (5 seconds before the player's
- // health started to rot, plus 100 seconds to rot down 100
- // health points, plus the original 20 second delay before the
- // item respawned). -- iw
- //
- if (!deathmatch)
- CheckItemRespawn(self, 30);
- else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
- self.nextthink = time + 125;
- }
- else
- {
- if (!deathmatch)
- CheckItemRespawn(self, 30);
- else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
- self.nextthink = time + 20;
- }
-
- activator = other;
- SUB_UseTargets(); // fire all targets / killtargets
-};
-
-/*
-===============================================================================
-
-ARMOR
-
-===============================================================================
-*/
-
-void() armor_touch;
-void() shard_touch;
-
-
-void() shard_touch = // this from RMQ shard_touch
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- local float bit;
-
- if ((other.items & IT_ARMOR1) ||
- (other.items & IT_ARMOR2) ||
- (other.items & IT_ARMOR3) ) // has armor
- {
- // Supa, check bounds, original armourvalue + 25
- if (other.items & IT_ARMOR1 && other.armorvalue >= 125) return;
- if (other.items & IT_ARMOR2 && other.armorvalue >= 175) return;
- if (other.items & IT_ARMOR3 && other.armorvalue >= 225) return;
-
- other.armorvalue = other.armorvalue + 5; // was 2, RMQ team
-
- // Supa, now cap armourvalue to bounds
- if (other.items & IT_ARMOR1 && other.armorvalue >= 125) other.armorvalue = 125;
- else if (other.items & IT_ARMOR2 && other.armorvalue >= 175) other.armorvalue = 175;
- else if (other.items & IT_ARMOR3 && other.armorvalue >= 225) other.armorvalue = 225;
- }
- else
- {
- other.armortype = 0.3; // shard = Green armor level
- other.armorvalue = 5;
- bit = IT_ARMOR1;
- other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
- }
- self.solid = SOLID_NOT;
- self.model = string_null;
-
- // Supa, SP respawning items support
- if (!deathmatch)
- CheckItemRespawn(self, 30);
- else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
- self.nextthink = time + 20;
- self.think = SUB_regen;
-
- if (self.obit_name != "")
- {
- sprint (other, "You got ");
- sprint (other, self.obit_name); // custom armor name
- sprint (other, "\n");
- }
- else
- sprint(other, "You got armor\n");
- // armor touch sound
- // sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM); // dumptruck_ds custom models and sounds START
- if (self.snd_misc != "")
- sound_misc(other, CHAN_AUTO, self.snd_misc, 1, ATTN_NORM);
- else
- sound_misc(other, CHAN_AUTO,"dump/armsh1.wav", 1, ATTN_NORM); // dumptruck_ds custom models and sounds END
- stuffcmd (other, "bf\n");
-
- activator = other;
- SUB_UseTargets(); // fire all targets / killtargets
-};
-
-void() armor_touch =
-{
- local float type, value, bit;
-
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- if (self.classname == "item_armor1")
- {
- type = 0.3;
- value = 100;
- bit = IT_ARMOR1;
- }
- else if (self.classname == "item_armor2")
- {
- type = 0.6;
- value = 150;
- bit = IT_ARMOR2;
- }
- else if (self.classname == "item_armorInv")
- {
- type = 0.8;
- value = 200;
- bit = IT_ARMOR3;
- }
- else
- {
- dprint ("WARNING: armor_touch: unknown classname: ");
- dprint (self.classname);
- dprint ("\n");
- return;
- }
-
- if (other.armortype*other.armorvalue >= type*value)
- return;
-
- other.armortype = type;
- other.armorvalue = value;
-
- other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
-
- self.solid = SOLID_NOT;
- self.model = string_null;
- // Supa, SP respawning items support
- if (!deathmatch)
- CheckItemRespawn(self, 30);
- else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
- self.nextthink = time + 20;
- self.think = SUB_regen;
-
- if (self.obit_name != "")
- {
- sprint (other, "You got ");
- sprint (other, self.obit_name); // custom armor name
- sprint (other, "\n");
- }
- else
- sprint(other, "You got armor\n");
-// armor touch sound
- // sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM); // dumptruck_ds custom models and sounds START
- if (self.snd_misc != "")
- sound_misc(other, CHAN_ITEM, self.snd_misc, 1, ATTN_NORM);
- else
- sound_misc(other, CHAN_ITEM,"items/armor1.wav", 1, ATTN_NORM); // dumptruck_ds custom models and sounds END
- stuffcmd (other, "bf\n");
-
- activator = other;
- SUB_UseTargets(); // fire all targets / killtargets
-};
-
-/*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/armor.mdl");
-}
-*/
-
-void() item_armor_shard =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.mdl_body && world.a_shr_mdl)
- {
- self.mdl_body = world.a_shr_mdl;
- }
-
- self.touch = shard_touch;
- // precache_model ("progs/armor.mdl"); // dumptruck_ds custom models and sounds START
- precache_body_model ("progs/armshr.mdl");
- // setmodel (self, "progs/armor.mdl");
- body_model ("progs/armshr.mdl");
- precache_sound_misc ("dump/armsh1.wav");
- if !(self.skin) // dumptruck_ds custom models and sounds END
- self.skin = 0;
- setsize (self, '-16 -16 0', '16 16 56');
- StartItem ();
-};
-
-void() item_armor1 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.mdl_body && world.a_grn_mdl)
- {
- self.mdl_body = world.a_grn_mdl;
- }
-
- self.touch = armor_touch;
- // precache_model ("progs/armor.mdl"); // dumptruck_ds custom models and sounds START
- precache_body_model ("progs/armor.mdl");
- // setmodel (self, "progs/armor.mdl");
- body_model ("progs/armor.mdl");
- precache_sound_misc ("items/armor1.wav");
- if !(self.skin) // dumptruck_ds custom models and sounds END
- self.skin = 0;
- setsize (self, '-16 -16 0', '16 16 56');
- StartItem ();
-};
-
-/*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model({ "path": ":progs/armor.mdl", "skin": 1 }); }
-*/
-
-void() item_armor2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.mdl_body && world.a_ylw_mdl)
- {
- self.mdl_body = world.a_ylw_mdl;
- }
-
- self.touch = armor_touch;
- // precache_model ("progs/armor.mdl"); // dumptruck_ds custom models and sounds START
- precache_body_model ("progs/armor.mdl");
- // setmodel (self, "progs/armor.mdl");
- body_model ("progs/armor.mdl");
- if !(self.skin) // dumptruck_ds custom models and sounds END
- self.skin = 1;
- precache_sound_misc ("items/armor1.wav");
- setsize (self, '-16 -16 0', '16 16 56');
- StartItem ();
-};
-
-/*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model({ "path": ":progs/armor.mdl", "skin": 2 });
-}
-*/
-
-void() item_armorInv =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.mdl_body && world.a_red_mdl)
- {
- self.mdl_body = world.a_red_mdl;
- }
-
- self.touch = armor_touch;
- // precache_model ("progs/armor.mdl"); // dumptruck_ds custom models and sounds START
- precache_body_model ("progs/armor.mdl");
- // setmodel (self, "progs/armor.mdl");
- body_model ("progs/armor.mdl");
- if !(self.skin) // dumptruck_ds custom models and sounds END
- self.skin = 2;
- precache_sound_misc ("items/armor1.wav");
- setsize (self, '-16 -16 0', '16 16 56');
- StartItem ();
-};
-
-/*
-===============================================================================
-
-WEAPONS
-
-===============================================================================
-*/
-
-void() bound_other_ammo =
-{
- if (other.ammo_shells > 100)
- other.ammo_shells = 100;
- if (other.ammo_nails > 200)
- other.ammo_nails = 200;
- if (other.ammo_rockets > 100)
- other.ammo_rockets = 100;
- if (other.ammo_cells > 100)
- other.ammo_cells = 100;
-};
-
-
-float(float w) RankForWeapon =
-{
- if (self.waterlevel <= 1 && w == IT_LIGHTNING) // 1997-12-23 Thunderbolt fix by Maddes recognize waterlevel
- return 1;
- if (w == IT_ROCKET_LAUNCHER)
- return 2;
- if (w == IT_SUPER_NAILGUN)
- return 3;
- if (w == IT_GRENADE_LAUNCHER)
- return 4;
- if (w == IT_SUPER_SHOTGUN)
- return 5;
- if (w == IT_NAILGUN)
- return 6;
- if (w == IT_SHOTGUN)
- return 7;
- return 8;
-};
-
-/*
-=============
-Deathmatch_Weapon
-
-Deathmatch weapon change rules for picking up a weapon
-
-.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
-=============
-*/
-void(float old, float new) Deathmatch_Weapon =
-{
- local float or, nr;
-
-// change self.weapon if desired
- or = RankForWeapon (self.weapon);
- nr = RankForWeapon (new);
- if ( nr < or )
- self.weapon = new;
-};
-
-/*
-=============
-weapon_touch
-=============
-*/
-float() W_BestWeapon;
-
-void() weapon_touch =
-{
- local float hadammo, best, new, old;
- local entity stemp;
- local float leave;
-
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- if (!(other.flags & FL_CLIENT))
- return;
-
-// if the player was using his best weapon, change up to the new one if better
- stemp = self;
- self = other;
- best = W_BestWeapon();
- self = stemp;
-
- if (deathmatch == 2 || coop)
- {
- leave = 1;
-
- // fix weapon items never firing their targets in coop or
- // "deathmatch 2" -- iw
- activator = other;
- SUB_UseAndForgetTargets ();
- }
- else
- {
- leave = 0;
- }
-
- // johnfitz added for axe, shotgun items --dumptruck_ds from RRP /rubicon2
- if (self.classname == "weapon_axe")
- {
- if (leave && (other.items & IT_AXE) )
- return;
- new = IT_AXE;
- }
- else if (self.classname == "weapon_shotgun")
- {
- if (leave && (other.items & IT_SHOTGUN) )
- return;
- hadammo = other.ammo_shells;
- new = IT_SHOTGUN;
- other.ammo_shells = other.ammo_shells + 5;
- }
- // johnfitz
-
- else if (self.classname == "weapon_nailgun")
- {
- if (leave && (other.items & IT_NAILGUN) )
- return;
- hadammo = other.ammo_nails;
- new = IT_NAILGUN;
- other.ammo_nails = other.ammo_nails + 30;
- }
- else if (self.classname == "weapon_supernailgun")
- {
- if (leave && (other.items & IT_SUPER_NAILGUN) )
- return;
- hadammo = other.ammo_rockets;
- new = IT_SUPER_NAILGUN;
- other.ammo_nails = other.ammo_nails + 30;
- }
- else if (self.classname == "weapon_supershotgun")
- {
- if (leave && (other.items & IT_SUPER_SHOTGUN) )
- return;
- hadammo = other.ammo_rockets;
- new = IT_SUPER_SHOTGUN;
- other.ammo_shells = other.ammo_shells + 5;
- }
- else if (self.classname == "weapon_rocketlauncher")
- {
- if (leave && (other.items & IT_ROCKET_LAUNCHER) )
- return;
- hadammo = other.ammo_rockets;
- new = IT_ROCKET_LAUNCHER;
- other.ammo_rockets = other.ammo_rockets + 5;
- }
- else if (self.classname == "weapon_grenadelauncher")
- {
- if (leave && (other.items & IT_GRENADE_LAUNCHER) )
- return;
- hadammo = other.ammo_rockets;
- new = IT_GRENADE_LAUNCHER;
- other.ammo_rockets = other.ammo_rockets + 5;
- }
- else if (self.classname == "weapon_lightning")
- {
- if (leave && (other.items & IT_LIGHTNING) )
- return;
- hadammo = other.ammo_rockets;
- new = IT_LIGHTNING;
- other.ammo_cells = other.ammo_cells + 15;
- }
- else
- {
- objerror ("weapon_touch: unknown classname");
- return;
- }
-
- sprint (other, "You got the ");
- sprint (other, self.netname);
- sprint (other, "\n");
-// weapon touch sound
- sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
- stuffcmd (other, "bf\n");
-
- bound_other_ammo ();
-
-// change to the weapon
- old = other.items;
- other.items = other.items | new;
-
- stemp = self;
- self = other;
-
-// 1997-12-23 Thunderbolt fix by Maddes start
-/* don't separate between SinglePlayer/Coop and Deathmatch
- if (!deathmatch)
- self.weapon = new;
- else
-*/
-// 1997-12-23 Thunderbolt fix by Maddes end
- Deathmatch_Weapon (old, new);
-
- W_SetCurrentAmmo();
-
- self = stemp;
-
- if (leave)
- return;
-
-// remove it in single player, or setup for respawning in deathmatch
- self.model = string_null;
- self.solid = SOLID_NOT;
- // Supa, SP respawning items support
- if (!deathmatch)
- CheckItemRespawn(self, 30);
- else if (deathmatch == 1) // weapons never disappear in "deathmatch 2"
- self.nextthink = time + 30;
-
- self.think = SUB_regen;
-
- activator = other;
- SUB_UseTargets(); // fire all targets / killtargets
-};
-
-// johnfitz new items -- dumptruck_ds from RRP and rubicon2
-/*QUAKED weapon_axe (0 .5 .8) (-16 -16 0) (16 16 32)
-Axe
-*/
-void() weapon_axe =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/g_axe.mdl");
- setmodel (self, "progs/g_axe.mdl");
- self.weapon = IT_AXE;
- self.netname = "Axe";
- self.touch = weapon_touch;
- setsize (self, '-16 -16 0', '16 16 56');
- StartItem ();
-};
-/*QUAKED weapon_shotgun (0 .5 .8) (-16 -16 0) (16 16 32) X STYLE_1 STYLE_2 X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/g_shotgn.mdl"); }
-This is a pickup model that should be used when you want a player to spawn with only an axe and then later get the shotgun: (trigger_take_weapon or reset_items 2 in worldspawn). There are two models to choose from. Spawnflag 2 (the default) selects an unused “classic look” model from Rubicon 2 by metlslime. Spawnflag 4 is an alternate from Slapmap and has been used in a few mods.
-Single-barrelled Shotgun
-Shotgun
-*/
-
-void() weapon_shotgun =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/g_shotgu.mdl");
- setmodel (self, "progs/g_shotgu.mdl"); //new shotgun model by Starshipwaters -dumptruck_ds - removed 2 older shotguns that used spawnflags
- self.weapon = IT_SHOTGUN;
- self.netname = "Shotgun";
- self.touch = weapon_touch;
- setsize (self, '-16 -16 0', '16 16 56');
- StartItem ();
-};
-// johnfitz
-
-/*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/g_shot.mdl"); }
-Double-barrelled Shotgun
-*/
-
-void() weapon_supershotgun =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/g_shot.mdl");
- setmodel (self, "progs/g_shot.mdl");
- self.weapon = IT_SUPER_SHOTGUN;
- self.netname = "Double-barrelled Shotgun";
- self.touch = weapon_touch;
- setsize (self, '-16 -16 0', '16 16 56');
- self.particles_offset = '0 0 33';
- StartItem ();
-};
-
-/*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/g_nail.mdl"); }
-Nailgun
-*/
-
-void() weapon_nailgun =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/g_nail.mdl");
- setmodel (self, "progs/g_nail.mdl");
- self.weapon = IT_NAILGUN;
- self.netname = "nailgun";
- self.touch = weapon_touch;
- setsize (self, '-16 -16 0', '16 16 56');
- self.particles_offset = '0 0 31';
- StartItem ();
-};
-
-/*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/g_nail2.mdl"); }
-Perforator
-*/
-
-void() weapon_supernailgun =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/g_nail2.mdl");
- setmodel (self, "progs/g_nail2.mdl");
- self.weapon = IT_SUPER_NAILGUN;
- self.netname = "Super Nailgun";
- self.touch = weapon_touch;
- setsize (self, '-16 -16 0', '16 16 56');
- self.particles_offset = '0 0 34';
- StartItem ();
-};
-
-/*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/g_rock.mdl"); }
-Grenade Launcher
-*/
-
-void() weapon_grenadelauncher =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/g_rock.mdl");
- setmodel (self, "progs/g_rock.mdl");
- self.weapon = 3;
- self.netname = "Grenade Launcher";
- self.touch = weapon_touch;
- setsize (self, '-16 -16 0', '16 16 56');
- self.particles_offset = '0 0 28';
- StartItem ();
-};
-
-/*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/g_rock2.mdl"); }
-Rocket Launcher
-*/
-
-void() weapon_rocketlauncher =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/g_rock2.mdl");
- setmodel (self, "progs/g_rock2.mdl");
- self.weapon = 3;
- self.netname = "Rocket Launcher";
- self.touch = weapon_touch;
- setsize (self, '-16 -16 0', '16 16 56');
- self.particles_offset = '0 0 32';
- StartItem ();
-};
-
-
-/*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/g_light.mdl"); }
-Thunderbolt
-*/
-
-void() weapon_lightning =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/g_light.mdl");
- setmodel (self, "progs/g_light.mdl");
- self.weapon = 3;
- self.netname = "Thunderbolt";
- self.touch = weapon_touch;
- setsize (self, '-16 -16 0', '16 16 56');
- self.particles_offset = '0 0 31';
- StartItem ();
-};
-
-
-/*
-===============================================================================
-
-AMMO
-
-===============================================================================
-*/
-
-void() ammo_touch =
-{
-local entity stemp;
-local float best;
-
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
-// if the player was using his best weapon, change up to the new one if better
- stemp = self;
- self = other;
- best = W_BestWeapon();
- self = stemp;
-
-
-// shotgun
- if (self.weapon == 1)
- {
- if (other.ammo_shells >= 100)
- return;
- other.ammo_shells = other.ammo_shells + self.aflag;
- }
-
-// spikes
- if (self.weapon == 2)
- {
- if (other.ammo_nails >= 200)
- return;
- other.ammo_nails = other.ammo_nails + self.aflag;
- }
-
-// rockets
- if (self.weapon == 3)
- {
- if (other.ammo_rockets >= 100)
- return;
- other.ammo_rockets = other.ammo_rockets + self.aflag;
- }
-
-// cells
- if (self.weapon == 4)
- {
- if (other.ammo_cells >= 100)
- return;
- other.ammo_cells = other.ammo_cells + self.aflag;
- }
-
- bound_other_ammo ();
-
- sprint (other, "You got the ");
- sprint (other, self.netname);
- sprint (other, "\n");
-// ammo touch sound
- sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
- stuffcmd (other, "bf\n");
-
-// change to a better weapon if appropriate
-
- if ( other.weapon == best )
- {
- stemp = self;
- self = other;
- self.weapon = W_BestWeapon();
- W_SetCurrentAmmo ();
- self = stemp;
- }
-
-// if changed current ammo, update it
- stemp = self;
- self = other;
- W_SetCurrentAmmo();
- self = stemp;
-
-// remove it in single player, or setup for respawning in deathmatch
- self.model = string_null;
- self.solid = SOLID_NOT;
- if (!deathmatch)
- CheckItemRespawn(self, 30);
- else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
- self.nextthink = time + 30;
- self.think = SUB_regen;
-
- activator = other;
- SUB_UseTargets(); // fire all targets / killtargets
-};
-
-
-
-
-float WEAPON_BIG2 = 1;
-
-/*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) LARGE_BOX X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ( {{ spawnflags & 1 -> { "path" : "maps/b_shell1.bsp" }, "maps/b_shell0.bsp" }} );
-}
-Box of 20 shells.
-LARGE_BOX is a box of 40 shells.
-*/
-
-void() item_shells =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = ammo_touch;
-
-
-
- if (self.spawnflags & WEAPON_BIG2)
- {
- if (!self.mdl_body && world.s_lg_mdl) self.mdl_body = world.s_lg_mdl;
- if (world.style)
- {
- precache_body_model ("progs/a_mdls/m_shell2.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/a_mdls/m_shell2.mdl");
- }
- // precache_model ("maps/b_shell1.bsp");
- // setmodel (self, "maps/b_shell1.bsp");
- else
- {
- precache_body_model ("maps/b_shell1.bsp");
- body_model ("maps/b_shell1.bsp");
- }
- if !(self.particles_offset)
- self.particles_offset = '16 16 16';
- self.aflag = 40;
- }
- else
- {
- if (!self.mdl_body && world.s_sm_mdl) self.mdl_body = world.s_sm_mdl;
- if (world.style)
- {
- precache_body_model ("progs/a_mdls/m_shell1.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/a_mdls/m_shell1.mdl");
- }
- else
- {
- precache_body_model ("maps/b_shell0.bsp");
- body_model ("maps/b_shell0.bsp");
- }
- // precache_model ("maps/b_shell0.bsp");
- // setmodel (self, "maps/b_shell0.bsp");
- if !(self.particles_offset)
- self.particles_offset = '12 12 12';
- self.aflag = 20;
- }
- self.weapon = 1;
- self.netname = "shells";
- setsize (self, '0 0 0', '32 32 56');
- StartItem ();
-};
-
-/*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) LARGE_BOX X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ( {{ spawnflags & 1 -> { "path" : "maps/b_nail1.bsp" }, "maps/b_nail0.bsp" }} );
-}
-Box of 25 nails.
-LARGE_BOX is a box of 50 nails.
-*/
-
-void() item_spikes =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = ammo_touch;
-
- if (self.spawnflags & WEAPON_BIG2)
- {
- if (!self.mdl_body && world.n_lg_mdl) self.mdl_body = world.n_lg_mdl;
- if (world.style)
- {
- precache_body_model ("progs/a_mdls/m_nails2.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/a_mdls/m_nails2.mdl");
- }
- else
- {
- precache_body_model ("maps/b_nail1.bsp");
- body_model ("maps/b_nail1.bsp");
- }
- // precache_model ("maps/b_nail1.bsp");
- // setmodel (self, "maps/b_nail1.bsp");
- if !(self.particles_offset)
- self.particles_offset = '16 16 16';
- self.aflag = 50;
- }
- else
- {
-
- if (!self.mdl_body && world.n_sm_mdl) self.mdl_body = world.n_sm_mdl;
- if (world.style)
- {
- precache_body_model ("progs/a_mdls/m_nails1.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/a_mdls/m_nails1.mdl");
- }
- else
- {
- precache_body_model ("maps/b_nail0.bsp");
- body_model ("maps/b_nail0.bsp");
- }
- // precache_model ("maps/b_nail0.bsp");
- // setmodel (self, "maps/b_nail0.bsp");
- if !(self.particles_offset)
- self.particles_offset = '12 12 12';
- self.aflag = 25;
- }
- self.weapon = 2;
- self.netname = "nails";
- setsize (self, '0 0 0', '32 32 56');
- StartItem ();
-};
-
-/*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) LARGE_BOX X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ( {{ spawnflags & 1 -> { "path" : "maps/b_rock1.bsp" }, "maps/b_rock0.bsp" }} );
-}
-*/
-
-void() item_rockets =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = ammo_touch;
-
- if (self.spawnflags & WEAPON_BIG2)
- {
-
- if (!self.mdl_body && world.r_lg_mdl) self.mdl_body = world.r_lg_mdl;
- if (world.style)
- {
- precache_body_model ("progs/a_mdls/m_rock2.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/a_mdls/m_rock2.mdl");
- }
- else
- {
- precache_body_model ("maps/b_rock1.bsp");
- body_model ("maps/b_rock1.bsp");
- }
- // precache_model ("maps/b_rock1.bsp");
- // setmodel (self, "maps/b_rock1.bsp");
- self.particles_offset = '16 8 16';
- self.aflag = 10;
- }
- else
- {
- if (!self.mdl_body && world.r_sm_mdl) self.mdl_body = world.r_sm_mdl;
- if (world.style)
- {
- precache_body_model ("progs/a_mdls/m_rock1.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/a_mdls/m_rock1.mdl");
- }
- else
- {
- precache_body_model ("maps/b_rock0.bsp");
- body_model ("maps/b_rock0.bsp");
- }
- // precache_model ("maps/b_rock0.bsp");
- // setmodel (self, "maps/b_rock0.bsp");
- if !(self.particles_offset)
- self.particles_offset = '8 8 16';
- self.aflag = 5;
- }
- self.weapon = 3;
- self.netname = "rockets";
- setsize (self, '0 0 0', '32 32 56');
- StartItem ();
-};
-
-
-/*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) LARGE_BOX X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ( {{ spawnflags & 1 -> { "path" : "maps/b_batt1.bsp" }, "maps/b_batt0.bsp" }} );
-}
-Box of 6 cells.
-LARGE_BOX is a box of 12 cells.
-*/
-
-void() item_cells =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = ammo_touch;
-
- if (self.spawnflags & WEAPON_BIG2)
- {
- if (!self.mdl_body && world.c_lg_mdl) self.mdl_body = world.c_lg_mdl;
- if (world.style)
- {
- precache_body_model ("progs/a_mdls/m_cells2.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/a_mdls/m_cells2.mdl");
- }
- else
- {
- precache_body_model ("maps/b_batt1.bsp");
- body_model ("maps/b_batt1.bsp");
- }
- // precache_model ("maps/b_batt1.bsp");
- // setmodel (self, "maps/b_batt1.bsp");
- if !(self.particles_offset)
- self.particles_offset = '16 16 16';
- self.aflag = 12;
- }
- else
- {
- if (!self.mdl_body && world.c_sm_mdl) self.mdl_body = world.c_sm_mdl;
- if (world.style)
- {
- precache_body_model ("progs/a_mdls/m_cells2.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/a_mdls/m_cells2.mdl");
- }
- else
- {
- precache_body_model ("maps/b_batt0.bsp");
- body_model ("maps/b_batt0.bsp");
- }
- // precache_model ("maps/b_batt0.bsp");
- // setmodel (self, "maps/b_batt0.bsp");
- if !(self.particles_offset)
- self.particles_offset = '12 12 12';
- self.aflag = 6;
- }
- self.weapon = 4;
- self.netname = "cells";
- setsize (self, '0 0 0', '32 32 56');
- StartItem ();
-};
-
-
-/*
-===============================================================================
-
-KEYS
-
-===============================================================================
-*/
-
-
-void() key_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
-// support for item_key_custom -- iw
- if (HasKeys (other, self.items, self.customkeys))
- return;
-
- sprint (other, "You got the ");
- sprint (other, self.netname);
- sprint (other,"\n");
-
- sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
- stuffcmd (other, "bf\n");
-
-// support for item_key_custom -- iw
- GiveKeys (other, self.items, self.customkeys);
-
- if (!coop)
- {
- self.solid = SOLID_NOT;
- self.model = string_null;
- }
-
- activator = other;
-// fix key items firing their targets multiple times in coop -- iw
-// SUB_UseTargets(); // fire all targets / killtargets
- SUB_UseAndForgetTargets();
-};
-
-
-void() key_setsounds =
-{
-// support for item_key_custom -- iw
- if (self.noise != "")
- {
- precache_sound (self.noise);
- return;
- }
-
- if (world.worldtype == WORLDTYPE_MEDIEVAL)
- {
- precache_sound ("misc/medkey.wav");
- self.noise = "misc/medkey.wav";
- }
- if (world.worldtype == WORLDTYPE_METAL)
- {
- precache_sound ("misc/runekey.wav");
- self.noise = "misc/runekey.wav";
- }
- if (world.worldtype == WORLDTYPE_BASE)
- {
- precache_sound2 ("misc/basekey.wav");
- self.noise = "misc/basekey.wav";
- }
-};
-
-
-/*
-============
-key_start
-
-Finish initializing self as a key item. -- iw
-============
-*/
-void() key_start =
-{
- key_setsounds ();
- self.particles_offset = '0 0 18';
- self.touch = key_touch;
- setsize (self, '-16 -16 -24', '16 16 32');
- StartItem ();
-};
-
-
-/*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/w_s_key.mdl"); }
-SILVER key
-In order for keys to work you MUST set your map's worldtype to one of the following:
-0: medieval
-1: metal
-2: base
-*/
-
-void() item_key1 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (world.worldtype == WORLDTYPE_MEDIEVAL)
- {
- precache_body_model ("progs/w_s_key.mdl");
- body_model ("progs/w_s_key.mdl");
- }
- else if (world.worldtype == WORLDTYPE_METAL)
- {
- precache_body_model ("progs/m_s_key.mdl");
- body_model ("progs/m_s_key.mdl");
- }
- else if (world.worldtype == WORLDTYPE_BASE)
- {
- precache_body_model2 ("progs/b_s_key.mdl");
- body_model ("progs/b_s_key.mdl");
- }
-
- if (self.keyname != "") self.netname = self.keyname;
- else self.netname = SilverKeyName ();
-
- self.items = IT_KEY1;
-
-// support for item_key_custom -- iw
- self.customkeys = 0; // ignore any mapper-set value
- self.noise = ""; // ignore any mapper-set value
-
- key_start ();
-};
-
-
-/*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/w_g_key.mdl");
-}
-GOLD key
-In order for keys to work you MUST set your map's worldtype to one of the following:
-0: medieval
-1: metal
-2: base
-*/
-
-void() item_key2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (world.worldtype == WORLDTYPE_MEDIEVAL)
- {
- precache_body_model ("progs/w_g_key.mdl");
- body_model ("progs/w_g_key.mdl");
- }
- if (world.worldtype == WORLDTYPE_METAL)
- {
- precache_body_model ("progs/m_g_key.mdl");
- body_model ("progs/m_g_key.mdl");
- }
- if (world.worldtype == WORLDTYPE_BASE)
- {
- precache_body_model2 ("progs/b_g_key.mdl");
- body_model ("progs/b_g_key.mdl");
- }
-
- if (self.keyname != "") self.keyname = "";
- else self.netname = GoldKeyName ();
-
- self.items = IT_KEY2;
-
-// support for item_key_custom -- iw
- self.customkeys = 0; // ignore any mapper-set value
- self.noise = ""; // ignore any mapper-set value
-
- key_start ();
-};
-
-
-// item_key_custom is a brand-spanking-new entity class created for
-// progs_dump -- iw
-
-/*QUAKED item_key_custom (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path" : "progs/pd_w_key.mdl", "skin" : 1});
-}
-A customizable key item.
-
-"keyname" name of the key, e.g. "bronze key" (required)
-"mdl" model file (required)
-"noise" sound file for the pickup sound (default is per worldtype)
-"skin" skin index (default 0)
-
-The "keyname" value is used both for the pickup message and to associate
-the key with the entity that it unlocks.
-
-To make a func_door or trigger_usekey require this key, set the
-"keyname" value of that entity so that it matches the "keyname" value of
-the key.
-
-If different item_key_custom entities have the same "keyname" value,
-they will be treated as different copies of the same key and may be used
-interchangeably.
-
-A map may have a maximum of 23 unique "keyname" values across all
-entities.
-
-The behavior of an item_key_custom should be as the player expects
-(based on the behavior of the silver and gold keys), except for the fact
-that it will not appear as an icon in the player's status bar when
-picked up. This is a limitation of the engine.
-*/
-
-void() item_key_custom =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.keyname == "")
- {
- objerror ("no keyname specified");
- return;
- }
-
- if (self.mdl == "")
- {
- objerror ("no mdl specified");
- return;
- }
-
- precache_model (self.mdl);
- setmodel (self, self.mdl);
- self.mdl = ""; // this should not be referenced again
-
- self.netname = self.keyname;
- self.keyname = ""; // this should not be referenced again
-
- self.items = 0; // ignore any mapper-set value
- self.customkeys = CustomKeyFlag (self.netname);
-
- key_start ();
-};
-
-
-/*
-===============================================================================
-
-END OF LEVEL RUNES
-
-===============================================================================
-*/
-
-void() sigil_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- centerprint (other, "You got the rune!");
-
- sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
- stuffcmd (other, "bf\n");
- self.solid = SOLID_NOT;
- self.model = string_null;
- serverflags = serverflags | (self.spawnflags & 15);
- self.classname = ""; // so rune doors won't find it
-
- activator = other;
- SUB_UseTargets(); // fire all targets / killtargets
-};
-
-void() sigil_touch2 = //replacement for Skill Select Rune hack -- uses info_player_start2 if spawnflag 16 -- dumptruck_ds
-{
- if (other.classname != "player")
- return;
- if (other.health <= 0)
- return;
-
- // centerprint (other, "You got the rune!");
-
- // sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
- // stuffcmd (other, "bf\n");
- self.solid = SOLID_NOT;
- self.model = string_null;
- serverflags = serverflags | (self.spawnflags & 16);
- self.classname = ""; // so rune doors won't find it
-
- activator = other;
- // SUB_UseTargets(); // fire all targets / killtargets
-};
-
-
-/*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4 X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ( {{ spawnflags & 1 -> { "path" : "progs/end1.mdl" }, spawnflags & 2 -> { "path" : "progs/end2.mdl" },
- spawnflags & 4 -> { "path" : "progs/end3.mdl" }, spawnflags & 8 -> { "path" : "progs/end4.mdl" },
- "progs/end1.mdl" }} );
-}
-End of episode rune. Use in conjuction with func_bossgate and func_episodegate.
-Spawnflag must be set to the appropriate episode.
-Episode 1 - Dimension of the Doomed - Rune of Earth Magic
-Episode 2 - The Realm of Black Magic - Rune of Black Magic
-Episode 3 - The Netherworld - Rune of Hell Magic
-Episode 4 - The Elder World - Run of Elder Magic
-*/
-
-void() item_sigil =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.spawnflags)
- objerror ("no spawnflags");
-
- precache_sound ("misc/runekey.wav");
- self.noise = "misc/runekey.wav";
-
- if (self.spawnflags & 1)
- {
- precache_model ("progs/end1.mdl");
- setmodel (self, "progs/end1.mdl");
- }
- if (self.spawnflags & 2)
- {
- precache_model2 ("progs/end2.mdl");
- setmodel (self, "progs/end2.mdl");
- }
- if (self.spawnflags & 4)
- {
- precache_model2 ("progs/end3.mdl");
- setmodel (self, "progs/end3.mdl");
- }
- if (self.spawnflags & 8)
- {
- precache_model2 ("progs/end4.mdl");
- setmodel (self, "progs/end4.mdl");
- }
-
- self.touch = sigil_touch;
- setsize (self, '-16 -16 -24', '16 16 32');
- self.particles_offset = '0 0 18';
- StartItem ();
-};
-
-/*
-===============================================================================
-
-POWERUPS
-
-===============================================================================
-*/
-
-void() powerup_touch;
-
-
-void() powerup_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- sprint (other, "You got the ");
- sprint (other, self.netname);
- sprint (other,"\n");
-
- // if (deathmatch)
- // {
- // self.mdl = self.model;
- //
- // if ((self.classname == "item_artifact_invulnerability") ||
- // (self.classname == "item_artifact_invisibility"))
- // self.nextthink = time + 60*5;
- // else
- // self.nextthink = time + 60;
- //
- // self.think = SUB_regen;
- // }
-
- // Supa, SP respawning items support
- self.mdl = self.model;
- self.think = SUB_regen;
-
- if (!deathmatch)
- {
- local float spawndelay;
-
- if (self.classname == "item_artifact_invulnerability" ||
- self.classname == "item_artifact_invisibility" ) spawndelay = 300;
- // else if (self.classname == "item_grappling_hook" ) spawndelay = 30;
- else spawndelay = 60;
-
- CheckItemRespawn(self, spawndelay);
- }
- else
- {
- if ((self.classname == "item_artifact_invulnerability") ||
- (self.classname == "item_artifact_invisibility"))
- self.nextthink = time + 60*5;
- else
- self.nextthink = time + 60;
- }
-
- sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- stuffcmd (other, "bf\n");
- self.solid = SOLID_NOT;
- other.items = other.items | self.items;
- self.model = string_null;
-
-// do the apropriate action
- if (self.classname == "item_artifact_envirosuit")
- {
- other.rad_time = 1;
- other.radsuit_finished = time + 30;
- }
-
- if (self.classname == "item_artifact_invulnerability")
- {
- other.invincible_time = 1;
- other.invincible_finished = time + 30;
- }
-
- if (self.classname == "item_artifact_invisibility")
- {
- other.invisible_time = 1;
- other.invisible_finished = time + 30;
- }
-
- if (self.classname == "item_artifact_super_damage")
- {
- other.super_time = 1;
- other.super_damage_finished = time + 30;
- }
-
- activator = other;
- SUB_UseTargets(); // fire all targets / killtargets
-};
-
-/*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/invulner.mdl"); }
-Pentagram of Protection
-Player is invulnerable for 30 seconds
-*/
-void() item_artifact_invulnerability =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = powerup_touch;
-
- // precache_model ("progs/invulner.mdl");
- precache_body_model ("progs/invulner.mdl");
- precache_sound ("items/protect.wav");
- precache_sound ("items/protect2.wav"); // called in client.qc -- dumptruck_ds
- precache_sound ("items/protect3.wav"); // called in combat.qc -- dumptruck_ds
- self.noise = "items/protect.wav";
- // setmodel (self, "progs/invulner.mdl");
- body_model ("progs/invulner.mdl");
- self.netname = "Pentagram of Protection";
- self.items = IT_INVULNERABILITY;
- setsize (self, '-16 -16 -24', '16 16 32');
- if !(self.particles_offset) // t_fog fix for custom models dumptruck_ds
- self.particles_offset = '0 0 16';
- StartItem ();
-};
-
-/*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/suit.mdl"); }
-Biosuit
-Player takes no damage from water or slime for 30 seconds
-*/
-void() item_artifact_envirosuit =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = powerup_touch;
-
- precache_body_model ("progs/suit.mdl");
- precache_sound ("items/suit.wav");
- precache_sound ("items/suit2.wav");
- self.noise = "items/suit.wav";
- // setmodel (self, "progs/suit.mdl");
- body_model ("progs/suit.mdl");
- self.netname = "Biosuit";
- self.items = IT_SUIT;
- setsize (self, '-16 -16 -24', '16 16 32');
- if !(self.particles_offset) // t_fog fix for custom models dumptruck_ds
- self.particles_offset = '0 0 32';
- StartItem ();
-};
-
-
-/*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/invisibl.mdl"); }
-Ring of Shadows
-Player is invisible for 30 seconds
-*/
-void() item_artifact_invisibility =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = powerup_touch;
-
- precache_body_model ("progs/invisibl.mdl");
- precache_sound ("items/inv1.wav");
- precache_sound ("items/inv2.wav");
- precache_sound ("items/inv3.wav");
- self.noise = "items/inv1.wav";
- // setmodel (self, "progs/invisibl.mdl");
- body_model ("progs/invisibl.mdl");
- self.netname = "Ring of Shadows";
- self.items = IT_INVISIBILITY;
- setsize (self, '-16 -16 -24', '16 16 32');
- if !(self.particles_offset) // t_fog fix for custom models dumptruck_ds
- self.particles_offset = '0 0 0';
- StartItem ();
-};
-
-
-/*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/quaddama.mdl"); }
-Quad Damage
-Player does 4x damage for 30 seconds
-*/
-void() item_artifact_super_damage =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = powerup_touch;
-
- precache_body_model ("progs/quaddama.mdl");
- precache_sound ("items/damage.wav");
- precache_sound ("items/damage3.wav");
- self.noise = "items/damage.wav";
- // setmodel (self, "progs/quaddama.mdl");
- body_model ("progs/quaddama.mdl");
- if !(self.netname) // custom name -- dumptruck_ds
- self.netname = "Quad Damage";
- self.items = IT_QUAD;
- setsize (self, '-16 -16 -24', '16 16 32');
- if !(self.particles_offset) // t_fog fix for custom models dumptruck_ds
- self.particles_offset = '0 0 16';
- StartItem ();
-};
-
-
-
-/*
-===============================================================================
-
-PLAYER BACKPACKS
-
-===============================================================================
-*/
-
-void() BackpackTouch =
-{
- local string s;
- local float best, old, new;
- local entity stemp;
- local float acount;
- // from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
- return;
- if (other.classname != "player")
- return;
- if (other.health <= 0)
- return;
-
- acount = 0;
- sprint (other, "You get ");
-
- if (self.items)
- if ((other.items & self.items) == 0)
- {
- acount = 1;
- sprint (other, "the ");
- sprint (other, self.netname);
- }
-
-// if the player was using his best weapon, change up to the new one if better
- stemp = self;
- self = other;
- best = W_BestWeapon();
- self = stemp;
-
-// change weapons
- other.ammo_shells = other.ammo_shells + self.ammo_shells;
- other.ammo_nails = other.ammo_nails + self.ammo_nails;
- other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
- other.ammo_cells = other.ammo_cells + self.ammo_cells;
-
- new = self.items;
- if (!new)
- new = other.weapon;
- old = other.items;
- other.items = other.items | new;
-
- bound_other_ammo ();
-
- if (self.ammo_shells) // hack to fix an issue with custom Grunt, Ogre and Enf ammo types. - dumptruck_ds
- // if (self.ammo_shells < 100)
- {
- if (acount)
- sprint(other, ", ");
- acount = 1;
- s = ftos(self.ammo_shells);
- sprint (other, s);
- sprint (other, " shells");
- }
- if (self.ammo_nails)
- {
- if (acount)
- sprint(other, ", ");
- acount = 1;
- s = ftos(self.ammo_nails);
- sprint (other, s);
- sprint (other, " nails");
- }
- if (self.ammo_rockets)
- {
- if (acount)
- sprint(other, ", ");
- acount = 1;
- s = ftos(self.ammo_rockets);
- sprint (other, s);
- sprint (other, " rockets");
- }
- if (self.ammo_cells)
- {
- if (acount)
- sprint(other, ", ");
- acount = 1;
- s = ftos(self.ammo_cells);
- sprint (other, s);
- sprint (other, " cells");
- }
-
- sprint (other, "\n");
-// backpack touch sound
- sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
- stuffcmd (other, "bf\n");
-
-// remove the backpack, change self to the player
- remove(self);
- self = other;
-
-// change to the weapon
-// 1997-12-23 Thunderbolt fix by Maddes start
-/* don't separate between SinglePlayer/Coop and Deathmatch
- if (!deathmatch)
- self.weapon = new;
- else
-*/
-// 1997-12-23 Thunderbolt fix by Maddes end
- Deathmatch_Weapon (old, new);
-
- W_SetCurrentAmmo ();
-
-};
-
-/*
-===============
-DropStuff -- dumptruck_ds
-
-set drops_item on a monster to a number:
-
-1 = Silver Key
-2 = Gold Key
-3 = Health Vial
-4 = Armor Shard
-5 = Health Vial & Armor Shard
-6 = random combination of 3 Vials and/or Shards
-===============
-*/
-
-void() DropKey1 =
-{
- local entity item;
-
- item = spawn();
- item.origin = self.origin - '0 0 24';
-
- item.velocity_z = 300;
- item.velocity_x = -100 + (random() * 200);
- item.velocity_y = -100 + (random() * 200);
-
- if (world.worldtype == WORLDTYPE_MEDIEVAL)
- {
- // precache_model ("progs/w_s_key.mdl");
- setmodel (item, "progs/w_s_key.mdl");
- item.noise = "misc/medkey.wav";
- }
- else if (world.worldtype == WORLDTYPE_METAL)
- {
- // precache_model ("progs/m_s_key.mdl");
- setmodel (item, "progs/m_s_key.mdl");
- item.noise = "misc/runekey.wav";
- }
- else if (world.worldtype == WORLDTYPE_BASE)
- {
- // precache_model2 ("progs/b_s_key.mdl");
- setmodel (item, "progs/b_s_key.mdl");
- item.noise = "misc/basekey.wav";
- }
- item.netname = SilverKeyName ();
- item.effects = 8;
- item.flags = FL_ITEM;
- item.items = IT_KEY1;
- item.solid = SOLID_TRIGGER;
- item.movetype = MOVETYPE_TOSS;
- setsize (item, '-16 -16 0', '16 16 56');
- item.touch = key_touch;
-};
-
-void() DropKey2 =
-{
- local entity item;
-
- item = spawn();
- item.origin = self.origin - '0 0 24';
-
- item.velocity_z = 300;
- item.velocity_x = -100 + (random() * 200);
- item.velocity_y = -100 + (random() * 200);
-
- if (world.worldtype == WORLDTYPE_MEDIEVAL)
- {
- // precache_model ("progs/w_s_key.mdl");
- setmodel (item, "progs/w_g_key.mdl");
- item.noise = "misc/medkey.wav";
- }
- else if (world.worldtype == WORLDTYPE_METAL)
- {
- // precache_model ("progs/m_s_key.mdl");
- setmodel (item, "progs/m_g_key.mdl");
- item.noise = "misc/runekey.wav";
- }
- else if (world.worldtype == WORLDTYPE_BASE)
- {
- // precache_model2 ("progs/b_s_key.mdl");
- setmodel (item, "progs/b_g_key.mdl");
- item.noise = "misc/basekey.wav";
- }
- item.netname = GoldKeyName ();
- item.effects = 8;
- item.flags = FL_ITEM;
- item.items = IT_KEY2;
- item.solid = SOLID_TRIGGER;
- item.movetype = MOVETYPE_TOSS;
- setsize (item, '-16 -16 0', '16 16 56');
- item.touch = key_touch;
-};
-
-void() DropVial = //
-{
- local entity item;
-
- item = spawn();
- item.origin = self.origin - '0 0 24';
-
- item.velocity_z = 300;
- item.velocity_x = -100 + (random() * 200);
- item.velocity_y = -100 + (random() * 200);
-
- setmodel(item, "progs/h_mdls/pd_vial.mdl");
- item.solid = SOLID_TRIGGER;
- item.movetype = MOVETYPE_TOSS;
- setsize (item, '-16 -16 0', '16 16 56');
- item.touch = health_touch;
- item.healamount = 5;
- item.healtype = 0;
- item.noise = "items/r_item1.wav";
-
- StartItem ();
-};
-
-void() DropShard = //
-{
- local entity item;
-
- item = spawn();
- item.origin = self.origin - '0 0 24';
-
- item.velocity_z = 300;
- item.velocity_x = -100 + (random() * 200);
- item.velocity_y = -100 + (random() * 200);
-
- setmodel(item, "progs/armshr.mdl");
- item.solid = SOLID_TRIGGER;
- item.movetype = MOVETYPE_TOSS;
- setsize (item, '-16 -16 0', '16 16 56');
- item.touch = shard_touch;
- item.snd_misc = "dump/armsh1.wav";
-
- StartItem ();
-};
-
-void() DropStuff =
-{
- local float rand_drop;
-
- if (self.drop_item == 1)
- {
- DropKey1();
- }
- if (self.drop_item == 2)
- {
- DropKey2();
- }
- if (self.drop_item == 3)
- {
- DropVial();
- }
- if (self.drop_item == 4)
- {
- DropShard();
- }
- if (self.drop_item == 5)
- {
- DropVial();
- DropShard();
- }
- else if (self.drop_item == 6)
- {
- rand_drop = rint(random() * 3);
- if (rand_drop == 1)
- {
- DropShard();
- DropVial();
- DropVial();
- }
- else if (rand_drop == 2)
- {
- DropShard();
- DropShard();
- DropVial();
- }
- else if (rand_drop == 0)
- {
- DropShard();
- DropShard();
- DropShard();
- }
- else
- {
- DropVial();
- DropVial();
- DropVial();
- }
- }
- return;
-};
-
-/*
-===============
-DropBackpack
-===============
-*/
-void() DropBackpack =
-{
- local entity item;
-
- if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells))
- return; // nothing in it
-
- item = spawn();
- item.origin = self.origin - '0 0 24';
-
- item.items = self.weapon;
- if (item.items == IT_AXE)
- item.netname = "Axe";
- else if (item.items == IT_SHOTGUN)
- item.netname = "Shotgun";
- else if (item.items == IT_SUPER_SHOTGUN)
- item.netname = "Double-barrelled Shotgun";
- else if (item.items == IT_NAILGUN)
- item.netname = "Nailgun";
- else if (item.items == IT_SUPER_NAILGUN)
- item.netname = "Super Nailgun";
- else if (item.items == IT_GRENADE_LAUNCHER)
- item.netname = "Grenade Launcher";
- else if (item.items == IT_ROCKET_LAUNCHER)
- item.netname = "Rocket Launcher";
- else if (item.items == IT_LIGHTNING)
- item.netname = "Thunderbolt";
- else
- item.netname = "";
-
- item.ammo_shells = self.ammo_shells;
- item.ammo_nails = self.ammo_nails;
- item.ammo_rockets = self.ammo_rockets;
- item.ammo_cells = self.ammo_cells;
-
- item.velocity_z = 300;
- item.velocity_x = -100 + (random() * 200);
- item.velocity_y = -100 + (random() * 200);
-
- item.flags = FL_ITEM;
- item.solid = SOLID_TRIGGER;
- item.movetype = MOVETYPE_TOSS;
- setmodel (item, "progs/backpack.mdl");
- setsize (item, '-16 -16 0', '16 16 56');
- item.touch = BackpackTouch;
-
- item.nextthink = time + 120; // remove after 2 minutes
- item.think = SUB_Remove;
-};
-
-// dumptruck_ds
-float DEFAULT = 1;
-float SHELLS = 2;
-float NAILS = 4;
-float ROCKETS = 8;
-float CELLS = 16;
-
-void() item_backpack_message =
-{
-
- if (!CheckValidTouch()) return; // from Copper -- dumptruck_ds
-
- other.ammo_shells = other.ammo_shells + self.ammo_shells;
- other.ammo_nails = other.ammo_nails + self.ammo_nails;
- other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
- other.ammo_cells = other.ammo_cells + self.ammo_cells;
-
- if (self.netname != "")
- {
- sprint (other, "You got ");
- sprint (other, self.netname);
- sprint (other, "\n");
- }
- else
- sprint (other, "You got a backpack!\n");
-
- // backpack touch sound
- // sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
- sound_misc (other, CHAN_ITEM, self.snd_misc, 1, ATTN_NORM);
- stuffcmd (other, "bf\n");
- remove(self);
- self = other;
- bound_other_ammo();
- W_SetCurrentAmmo ();
-
-};
-// Some of this text is from Drake -- dumptruck_ds
-/*QUAKED item_backpack (0 .5 .8) (-16 -16 0) (16 16 72) SHELLS NAILS ROCKETS CELLS X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/backpack.mdl"); }
-By default, gives roughly half the ammo from the 4 standard pickups:
-
-10 Shells
-12 Nails
-2 Rockets
-3 Cells
-
-Or you can use the spawnflags to mix and match types.
-Override the spawnflags defaults by adding custom amounts to:
-
-ammo_shells
-ammo_nails
-ammo_rockets
-ammo_cells
-
-Can trigger spawn and suspend in air, but not respawn. You can set a skin
-index if you are using a custom model with skins.
-
-The default pickup message is `You got a backpack.` But you can
-set a custom message with the netname key. 'You got' will be the prefix
-and the mapper chooses the rest of the message.
-
-e.g. For 'You got a bunch of rockets!' the netname key would be
-'a bunch of rockets!'
-*/
-void() item_backpack =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
-
- self.flags = FL_ITEM;
- self.solid = SOLID_TRIGGER;
- self.movetype = MOVETYPE_TOSS;
- self.classname = "item_backpack";
- // self.netname = self.netname;
- if !(self.spawnflags)
- {
- objerror ("\bNO SPAWNFLAG SET ON item_backpack");
- return;
- }
-
- if (self.spawnflags & DEFAULT)
- {
- self.ammo_shells = 10;
- self.ammo_nails = 12;
- self.ammo_rockets = 2;
- self.ammo_cells = 3;
- }
-
- if (self.spawnflags & SHELLS)
- {
- if !(self.ammo_shells)
- {
- self.ammo_shells = 10;
- }
- }
- if (self.spawnflags & NAILS)
- {
- if !(self.ammo_nails)
- {
- self.ammo_nails = 12;
- }
- }
- if (self.spawnflags & ROCKETS)
- {
- if !(self.ammo_rockets)
- {
- self.ammo_rockets = 2;
- }
- }
- if (self.spawnflags & CELLS)
- {
- if !(self.ammo_cells)
- {
- self.ammo_cells = 3;
- }
- }
-
- self.touch = item_backpack_message;
-
- if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
- self.snd_misc = "weapons/lock4.wav";
- precache_sound_misc(self.snd_misc);
- precache_body_model ("progs/pd_bpack.mdl");
- body_model ("progs/pd_bpack.mdl");
- // setmodel (self, "progs/backpack.mdl");
- setsize (self, '-16 -16 0', '16 16 56');
- StartItem ();
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/keydata.qc

diff --git a/qc-server/keydata.qc b/qc-server/keydata.qc
deleted file mode 100644
index 4c78ea0..0000000
--- a/qc-server/keydata.qc
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
-========================================================================
-
-FUNCTIONS WHICH DEAL WITH KEY ITEM BITFLAGS AND NAMES
-
-========================================================================
-
-
-This file was created for progs_dump by Ian "iw" Walshaw, January 2020.
-
-It defines functions which deal with the bitflags and names which refer
-to the key items, including the new item_key_custom.
-
-These functions are a dependency of the updated code for the key items
-(in items.qc) and also the updated code for unlockable entities (in
-keylock.qc).
-
-
-========================================================================
-*/
-
-
-string() SilverKeyName;
-string() GoldKeyName;
-float(string key_name) CustomKeyFlag;
-entity(string key_name) SpawnCustomKeyDef;
-entity(string key_name) FindCustomKeyDef;
-float(entity client, float item_flags, float customkey_flags) HasKeys;
-void(entity client, float item_flags, float customkey_flags) GiveKeys;
-void(entity client) GiveAllKeys;
-void(entity client, float item_flags, float customkey_flags) RemoveKeys;
-
-
-// The highest bitflag that will be assigned to a custom key.
-float FINAL_CUSTOM_KEY = 4194304;
-
-// The highest bitflag that has been assigned to a custom key.
-float highest_custom_key;
-
-
-/*
-============
-SilverKeyName
-
-Return the name that should be used for the silver key as per
-world.worldtype. -- iw
-============
-*/
-string() SilverKeyName =
-{
- if (world.worldtype == WORLDTYPE_BASE)
- return "silver keycard";
- if (world.worldtype == WORLDTYPE_METAL)
- return "silver runekey";
- return "silver key";
-};
-
-
-/*
-============
-GoldKeyName
-
-Return the name that should be used for the gold key as per
-world.worldtype. -- iw
-============
-*/
-string() GoldKeyName =
-{
- if (world.worldtype == WORLDTYPE_BASE)
- return "gold keycard";
- if (world.worldtype == WORLDTYPE_METAL)
- return "gold runekey";
- return "gold key";
-};
-
-
-/*
-================
-CustomKeyFlag
-
-Return the bitflag that should be used to represent the custom key named
-key_name.
-
-More specifically, if this is the first time that this function has been
-called for the specified key_name, then return a bitflag which has not
-previously been returned by this function for any key_name. Otherwise,
-return the same bitflag that was previously returned for the specified
-key_name. -- iw
-================
-*/
-float(string key_name) CustomKeyFlag =
-{
- local entity key_def;
-
- key_def = FindCustomKeyDef (key_name);
- if (key_def == world)
- key_def = SpawnCustomKeyDef (key_name);
- return key_def.customkeys;
-};
-
-
-/*
-================
-SpawnCustomKeyDef
-
-Spawn and return a new custom_key_def entity which will define the
-custom key named key_name.
-
-The value of the entity's customkeys field will be a bitflag which has
-not yet been used to represent a custom key. -- iw
-================
-*/
-entity(string key_name) SpawnCustomKeyDef =
-{
- local entity key_def;
-
- if (highest_custom_key == FINAL_CUSTOM_KEY)
- error ("too many custom keys");
-
- if (highest_custom_key == 0)
- highest_custom_key = 1;
- else
- highest_custom_key = highest_custom_key * 2;
-
- key_def = spawn ();
- key_def.classname = "custom_key_def";
- key_def.netname = key_name;
- key_def.customkeys = highest_custom_key;
-
- return key_def;
-};
-
-
-/*
-================
-FindCustomKeyDef
-
-If a custom_key_def entity exists which defines the custom key named
-key_name, then find and return it, otherwise return world.
-
-If a custom_key_def entity is returned, then the value of its customkeys
-field will be the bitflag that should be used to represent the custom
-key named key_name. -- iw
-================
-*/
-entity(string key_name) FindCustomKeyDef =
-{
- local entity key_def;
-
- key_def = find (world, classname, "custom_key_def");
- while (key_def != world)
- {
- if (key_def.netname == key_name)
- return key_def;
- key_def = find (key_def, classname, "custom_key_def");
- }
- return world;
-};
-
-
-/*
-================
-HasKeys
-
-Return TRUE if the specified client has all of the non-custom keys
-represented by the item_flags and all of the custom keys represented by
-the customkey_flags, otherwise return FALSE. -- iw
-================
-*/
-float(entity client, float item_flags, float customkey_flags) HasKeys =
-{
- return (client.items & item_flags) == item_flags &&
- (client.customkeys & customkey_flags) == customkey_flags;
-};
-
-
-/*
-================
-GiveKeys
-
-Give the specified client all of the non-custom keys represented by the
-item_flags and all of the custom keys represented by the
-customkey_flags. -- iw
-================
-*/
-void(entity client, float item_flags, float customkey_flags) GiveKeys =
-{
- client.items = client.items | item_flags;
- client.customkeys = client.customkeys | customkey_flags;
-};
-
-
-/*
-================
-GiveAllKeys
-
-Give the specified client the silver key, the gold key, and all of the
-custom keys that have been defined for the current map. -- iw
-================
-*/
-void(entity client) GiveAllKeys =
-{
- GiveKeys (client, IT_KEY1 | IT_KEY2, highest_custom_key * 2 - 1);
-};
-
-
-/*
-================
-RemoveKeys
-
-Remove all of the non-custom keys represented by the item_flags and all
-of the custom keys represented by the customkey_flags from the specified
-client's inventory. -- iw
-================
-*/
-void(entity client, float item_flags, float customkey_flags) RemoveKeys =
-{
- client.items = client.items -
- (client.items & item_flags);
- client.customkeys = client.customkeys -
- (client.customkeys & customkey_flags);
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/keylock.qc

diff --git a/qc-server/keylock.qc b/qc-server/keylock.qc
deleted file mode 100644
index 1566671..0000000
--- a/qc-server/keylock.qc
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
-========================================================================
-
-COMMON CODE FOR ENTITIES WHICH CAN BE UNLOCKED WITH KEYS
-
-========================================================================
-
-
-This file was created for progs_dump by Ian "iw" Walshaw, December 2019.
-
-It defines functions which implement the logic of the player using a key
-to unlock a locked entity. These functions are based on parts of the
-func_door code from the original game.
-
-In the original game, func_door was the only type of entity which could
-be unlocked with a key, however progs_dump also has trigger_usekey,
-which previously duplicated the same unlocking logic as func_door. The
-functions in this file were written to eliminate that duplication;
-func_door and trigger_usekey have now both been refactored to call these
-functions.
-
-This file was created as part of the prep work for implementing
-item_key_custom, with the intention of removing as much duplication as
-possible in order to make the code easier to modify and extend.
-
-
-Fields Set By These Functions
------------------------------
-
-The functions in this file set the following fields, therefore code
-calling these functions must not use these fields for other purposes:
-
- - self.customkeys
- - self.items
- - self.netname
- - self.noise3
- - self.noise4
-
-
-========================================================================
-*/
-
-
-/*
-================
-keylock_init
-
-Initialize self for use with the other keylock_* functions.
-
-The following fields will be set to default values if they have not
-already been set:
-
- - self.noise3 (the "key required" sound file).
-
- - self.noise4 (the "key used" sound file).
-
-The default values are determined by world.worldtype. -- iw
-================
-*/
-void() keylock_init =
-{
- local string default_noise3;
- local string default_noise4;
-
- if (world.worldtype == WORLDTYPE_BASE)
- {
- default_noise3 = "doors/basetry.wav";
- default_noise4 = "doors/baseuse.wav";
- }
- else if (world.worldtype == WORLDTYPE_METAL)
- {
- default_noise3 = "doors/runetry.wav";
- default_noise4 = "doors/runeuse.wav";
- }
- else
- {
- default_noise3 = "doors/medtry.wav";
- default_noise4 = "doors/meduse.wav";
- }
-
- if (self.noise3 == "")
- self.noise3 = default_noise3;
- if (self.noise4 == "")
- self.noise4 = default_noise4;
-
- precache_sound (self.noise3);
- precache_sound (self.noise4);
-};
-
-
-/*
-================
-keylock_set_silver_key
-
-Make it so that the player will need to use the silver key in order to
-unlock self. -- iw
-================
-*/
-void() keylock_set_silver_key =
-{
- self.items = IT_KEY1;
- self.customkeys = 0; // support for item_key_custom -- iw
- self.netname = SilverKeyName ();
-};
-
-
-/*
-================
-keylock_set_gold_key
-
-Make it so that the player will need to use the gold key in order to
-unlock self. -- iw
-================
-*/
-void() keylock_set_gold_key =
-{
- self.items = IT_KEY2;
- self.customkeys = 0; // support for item_key_custom -- iw
- self.netname = GoldKeyName ();
-};
-
-
-// support for item_key_custom -- iw
-/*
-================
-keylock_set_custom_key
-
-Make it so that the player will need to use the custom key named
-key_name in order to unlock self. -- iw
-================
-*/
-void(string key_name) keylock_set_custom_key =
-{
- self.items = 0;
- self.customkeys = CustomKeyFlag (key_name);
- self.netname = key_name;
-};
-
-
-/*
-================
-keylock_has_key_set
-
-Return TRUE if one of the keylock_set_*_key functions has been called
-for self, otherwise return FALSE. -- iw
-================
-*/
-float() keylock_has_key_set =
-{
-// support for item_key_custom -- iw
- return self.items != 0 || self.customkeys != 0;
-};
-
-
-/*
-================
-keylock_try_to_unlock
-
-Handle the logic of the specified client trying to unlock self.
-
-More specifically, if the client has the correct key to unlock self,
-then do the following:
-
- 1. Remove the key from the client's inventory, unless self.cnt is
- non-zero, in which case leave it in the client's inventory.
-
- 2. Print a message to let the player know which key they used.
-
- 3. Play the "key used" sound effect (self.noise4).
-
- 4. Call the function specified as the success_func parameter, which
- should perform whatever entity-specific actions are required for
- self.
-
-Otherwise, if the client does not have the correct key to unlock self,
-then do the following:
-
- 1. Centerprint the message "You need the [key name]", unless the
- custom_message parameter is non-empty, in which case centerprint
- that instead.
-
- 2. Play the "key required" sound effect (self.noise3).
-
-The self.cnt functionality is a feature of progs_dump and was not part
-of the original game. -- iw
-================
-*/
-void(entity client, string custom_message,
- void() success_func) keylock_try_to_unlock =
-{
- local string s;
-
-// support for item_key_custom -- iw
- if (!HasKeys (client, self.items, self.customkeys))
- {
- if (custom_message != "")
- centerprint (client, custom_message);
- else
- centerprint2 (client, "You need the ", self.netname);
- sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
- return;
- }
-
-// the old code in door_touch included a comment from dumptruck_ds
-// thanking RennyC re self.cnt
- if (self.cnt)
- {
- s = "You used (and kept) the ";
- }
- else
- {
- // support for item_key_custom -- iw
- RemoveKeys (client, self.items, self.customkeys);
- s = "You used the ";
- }
-
- sprint (client, s);
- sprint (client, self.netname);
- sprint (client, "\n");
-
-// the old code in door_fire included a comment from dumptruck_ds
-// thanking c0burn re changing CHAN_VOICE to CHAN_ITEM
- sound (self, CHAN_ITEM, self.noise4, 1, ATTN_NORM);
-
- success_func ();
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/lights.qc

diff --git a/qc-server/lights.qc b/qc-server/lights.qc
deleted file mode 100644
index c2fd36a..0000000
--- a/qc-server/lights.qc
+++ /dev/null
@@ -1,503 +0,0 @@
-/*========================================
-lights.qc taken from c0burn's Slipgate mod -- dumptruck_ds
-========================================*/
-
-float START_OFF = 1;
-float FADE_IN_OUT = 2;
-float SILENT_TORCH = 4; // for silent torch -- dumptruck_ds
-
-/*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Used as a positional target for spotlights, etc.
-*/
-void() info_null =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- remove(self);
-};
-
-/*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Never used in the or
-*/
-void() info_notnull =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-};
-
-/*==========
-lightstyle_lookup
-==========*/
-string(float num) lightstyle_lookup =
-{
- switch (num)
- {
- // 0 normal
- case 0:
- return "m";
- break;
- // 1 FLICKER (first variety)
- case 1:
- return "mmnmmommommnonmmonqnmmo";
- break;
- // 2 SLOW STRONG PULSE
- case 2:
- return "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba";
- break;
- // 3 CANDLE (first variety)
- case 3:
- return "mmmmmaaaaammmmmaaaaaabcdefgabcdefg";
- break;
- // 4 FAST STROBE
- case 4:
- return "mamamamamama";
- break;
- // 5 GENTLE PULSE 1
- case 5:
- return "jklmnopqrstuvwxyzyxwvutsrqponmlkj";
- break;
- // 6 FLICKER (second variety)
- case 6:
- return "nmonqnmomnmomomno";
- break;
- // 7 CANDLE (second variety)
- case 7:
- return "mmmaaaabcdefgmmmmaaaammmaamm";
- break;
- // 8 CANDLE (third variety)
- case 8:
- return "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa";
- break;
- // 9 SLOW STROBE (fourth variety)
- case 9:
- return "aaaaaaaazzzzzzzz";
- break;
- // 10 FLUORESCENT FLICKER
- case 10:
- return "mmamammmmammamamaaamammma";
- break;
- // 11 SLOW PULSE NOT FADE TO BLACK
- case 11:
- return "abcdefghijklmnopqrrqponmlkjihgfedcba";
- break;
- // 12 BLINK OFF / ON (can be synced with animated textures, e.g. +0light and +1light)
- case 12:
- return "aamm"; // textures animate at 5fps but lights are 10fps...
- break;
- // DEFAULT
- default:
- return "a";
- break;
- }
-};
-
-/*==========
-setup_lightstyles
-
-Setup light animation tables. 'a' is total darkness, 'z' is maxbright.
-Styles 32+ are assigned by the light program for switchable lights.
-==========*/
-void() setup_lightstyles =
-{
- for (float i = 0; i <= 12; i++)
- {
- lightstyle(i, lightstyle_lookup(i));
- }
-};
-
-/*==========
-lightstyle_fade_lookup
-==========*/
-string(float num) lightstyle_fade_lookup =
-{
- switch (num)
- {
- case 0:
- return "a";
- break;
- case 1:
- return "b";
- break;
- case 2:
- return "c";
- break;
- case 3:
- return "d";
- break;
- case 4:
- return "e";
- break;
- case 5:
- return "f";
- break;
- case 6:
- return "g";
- break;
- case 7:
- return "h";
- break;
- case 8:
- return "i";
- break;
- case 9:
- return "j";
- break;
- case 10:
- return "k";
- break;
- case 11:
- return "l";
- break;
- case 12:
- return "m";
- break;
- default:
- error("count out of range\n");
- break;
- }
-};
-
-/*==========
-light_fade_in
-==========*/
-void() light_fade_in =
-{
- if (self.count < 0)
- self.count = 0;
- if (self.count > 12)
- self.count = 12;
-
- lightstyle(self.style, lightstyle_fade_lookup(self.count));
- self.count = self.count + 1;
- if (self.count > 12)
- return;
-
- self.think = light_fade_in;
- self.nextthink = time + self.speed;
-};
-
-/*==========
-light_fade_out
-==========*/
-void() light_fade_out =
-{
- if (self.count < 0)
- self.count = 0;
- if (self.count > 12)
- self.count = 12;
-
- lightstyle(self.style, lightstyle_fade_lookup(self.count));
- self.count = self.count - 1;
- if (self.count < 0)
- return;
-
- self.think = light_fade_out;
- self.nextthink = time + self.speed;
-};
-
-/*==========
-light_use
-
-using a light will turn it on and off
-==========*/
-void() light_use =
-{
- if (self.spawnflags & START_OFF)
- {
- self.spawnflags = self.spawnflags - START_OFF;
- if (self.spawnflags & FADE_IN_OUT && !self.style2)
- light_fade_in();
- else
- lightstyle(self.style, lightstyle_lookup(self.style2));
- }
- else
- {
- self.spawnflags = self.spawnflags + START_OFF;
- if (self.spawnflags & FADE_IN_OUT && !self.style2)
- light_fade_out();
- else
- lightstyle(self.style, "a");
- }
-};
-
-/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF FADE_IN_OUT X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Light
-
-==========
-Spawnflags
-==========
-START_OFF - switchable lights only - light is off by default
-FADE_IN_OUT - switchable lights only - light fades in and out. can't be combined with animated lights.
-
-==========
-Keys
-==========
-"light" "n"
-Set the light intensity. Negative values are also allowed and will cause the entity to subtract light cast by other entities. Default 300.
-
-"wait" "n"
-Scale the fade distance of the light by "n". Values of n > 1 make the light fade more quickly with distance, and values < 1 make the light fade more slowly (and thus reach further). Default 1.
-
-"delay" "n"
-Select an attenuation formaula for the light:
-0 => Linear attenuation (default)
-1 => 1/x attenuation
-2 => 1/(x^2) attenuation
-3 => No attenuation (same brightness at any distance)
-4 => "local minlight" - No attenuation and like minlight,
-it won't raise the lighting above it's light value.
-Unlike minlight, it will only affect surfaces within
-line of sight of the entity.
-5 => 1/(x^2) attenuation, but slightly more attenuated and
-without the extra bright effect that "delay 2" has
-near the source.
-
-"_falloff" "n"
-Sets the distance at which the light drops to 0, in map units.
-In this mode, "wait" is ignored and "light" only controls the brightness at the center of the light, and no longer affects the falloff distance.
-Only supported on linear attenuation (delay 0) lights currently.
-
-"_color" "r g b"
-Specify red(r), green(g) and blue(b) components for the colour of the light. RGB component values are between 0 and 255 (between 0 and 1 is also accepted). Default is white light ("255 255 255").
-
-"target" "name"
-Turns the light into a spotlight, with the direction of light being towards another entity with it�s "targetname" key set to "name".
-"mangle" "yaw pitch roll"
-Turns the light into a spotlight and specifies the direction of light using yaw, pitch and roll in degrees. Yaw specifies the angle around the Z-axis from 0 to 359 degrees and pitch specifies the angle from 90 (straight up) to -90 (straight down). Roll has no effect, so use any value (e.g. 0). Often easier than the "target" method.
-
-"angle" "n"
-Specifies the angle in degrees for a spotlight cone. Default 40.
-
-"_softangle" "n"
-Specifies the angle in degrees for an inner spotlight cone (must be less than the "angle" cone. Creates a softer transition between the full brightness of the inner cone to the edge of the outer cone. Default 0 (disabled).
-
-"targetname" "name"
-Turns the light into a switchable light, toggled by another entity targeting it�s name.
-
-"speed" "n"
-If the light is switchable and FADE_IN_OUT is set, the speed at which the light transitions. Default 0.1.
-
-"style" "n"
-Set the animated light style. Default 0.
-
-"style2" "n"
-Set the animated light style for a switchable light, because style will be overriden if a targetname is set. Default 0.
-
-"_anglescale" "n" | "_anglesense" "n"
-Sets a scaling factor for how much influence the angle of incidence of light on a surface has on the brightness of the surface. n must be between 0.0 and 1.0. Smaller values mean less attenuation, with zero meaning that angle of incidence has no effect at all on the brightness. Default 0.5.
-
-"_dirtscale" "n" | "_dirtgain" "n"
-Override the global "_dirtscale" or "_dirtgain" settings to change how this light is affected by dirtmapping (ambient occlusion). See descriptions of these keys in the worldspawn section.
-
-"_dirt" "n"
-Overrides the worldspawn setting of "_dirt" for this particular light. -1 to disable dirtmapping (ambient occlusion) for this light, making it illuminate the dirtmapping shadows. 1 to enable ambient occlusion for this light. Default is to defer to the worldspawn setting.
-
-"_deviance" "n"
-Split up the light into a sphere of randomly positioned lights within radius "n" (in world units). Useful to give shadows a wider penumbra. "_samples" specifies the number of lights in the sphere. The "light" value is automatically scaled down for most lighting formulas (except linear and non-additive minlight) to attempt to keep the brightness equal. Default is 0, do not split up lights.
-
-"_samples" "n"
-Number of lights to use for "_deviance". Default 16 (only used if "_deviance" is set).
-
-"_surface" "texturename"
-Makes surfaces with the given texture name emit light, by using this light as a template which is copied across those surfaces. Lights are spaced about 128 units (though possibly closer due to bsp splitting) apart and positioned 2 units above the surfaces.
-
-"_surface_offset" "n"
-Controls the offset lights are placed above surfaces for "_surface". Default 2.
-
-"_surface_spotlight" "n"
-For a surface light template (i.e. a light with "_surface" set), setting this to "1" makes each instance into a spotlight, with the direction of light pointing along the surface normal. In other words, it automatically sets "mangle" on each of the generated lights.
-
-"_project_texture" "texture"
-Specifies that a light should project this texture. The texture must be used in the map somewhere.
-
-"_project_mangle" "yaw pitch roll"
-Specifies the yaw/pitch/roll angles for a texture projection (overriding mangle).
-
-"_project_fov" "n"
-Specifies the fov angle for a texture projection. Default 90.
-
-"_bouncescale" "n"
-Scales the amount of light that is contributed by bounces. Default is 1.0, 0.0 disables bounce lighting for this light.
-
-"_sun" "n"
-Set to 1 to make this entity a sun, as an alternative to using the sunlight worldspawn keys. If the light targets an info_null entity, the direction towards that entity sets sun direction. The light itself is disabled, so it can be placed anywhere in the map.
-
-The following light properties correspond to these sunlight settings:
-light => _sunlight
-mangle => _sunlight_mangle
-deviance => _sunlight_penumbra
-_color => _sunlight_color
-_dirt => _sunlight_dirt
-_anglescale => _anglescale
-*/
-void() light =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- // default speed for fading in/out
- if (self.speed <= 0)
- self.speed = 0.1;
-
- // non-switchable light
- if (!self.targetname)
- {
- remove(self);
- return;
- }
-
- // switchable light
- if (self.style >= 32)
- {
- self.use = light_use;
- if (self.spawnflags & START_OFF)
- {
- self.count = 0;
- lightstyle(self.style, "a");
- }
- else
- {
- self.count = 12;
- lightstyle(self.style, lightstyle_lookup(self.style2));
- }
- }
-};
-
-/*QUAKED light_fluoro (0 1 0) (-8 -8 -8) (8 8 8) START_OFF FADE_IN_OUT X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Non-displayed light.
-Makes steady fluorescent humming sound.
-See the "light" entity for a full description.
-*/
-void() light_fluoro =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- ambient_light_buzz();
- light();
-};
-
-/*QUAKED light_fluorospark (0 1 0) (-8 -8 -8) (8 8 8) START_OFF FADE_IN_OUT X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Non-displayed light.
-Makes sparking, broken fluorescent sound.
-Can't be toggled.
-Default style is 10.
-See the "light" entity for a full description.
-*/
-void() light_fluorospark =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.style)
- self.style = 10;
- ambient_flouro_buzz();
- remove(self);
-};
-
-/*QUAKED light_globe (0 1 0) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Sphere globe light.
-Can't be toggled.
-See the "light" entity for a full description.
-*/
-void() light_globe =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/s_light.spr");
- setmodel(self, "progs/s_light.spr");
- makestatic(self);
-};
-
-/*QUAKED light_torch_small_walltorch (0 .5 0) (-10 -10 -20) (10 10 20) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model ("progs/flame.mdl"); }
-Short wall torch
-See the "light" entity for a full description.
-*/
-void() light_torch_small_walltorch =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- // precache_model("progs/flame.mdl");
- precache_body_model("progs/flame.mdl");
- // setmodel(self, "progs/flame.mdl");
- body_model("progs/flame.mdl");
- if !(self.spawnflags && SILENT_TORCH) // for silent torch -- dumptruck_ds
- FireAmbient ();
- makestatic(self);
-};
-
-/*QUAKED light_flame_large_yellow (0 1 0) (-10 -10 -12) (12 12 18) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model ( { "path" : "progs/flame2.mdl", "frame" : 1 } ); }
-Large yellow flame
-See the "light" entity for a full description.
-*/
-void() light_flame_large_yellow =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/flame2.mdl");
- setmodel (self, "progs/flame2.mdl");
- self.frame = 1;
- FireAmbient ();
- makestatic(self);
-};
-
-/*QUAKED light_flame_small_yellow (0 1 0) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model ("progs/flame2.mdl"); }
-Small yellow flame
-See the "light" entity for a full description.
-*/
-void() light_flame_small_yellow =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/flame2.mdl");
- setmodel(self, "progs/flame2.mdl");
- FireAmbient ();
- makestatic(self);
-};
-
-/*QUAKED light_flame_small_white (0 1 0) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model ("progs/flame2.mdl"); }
-Left for compatability
-Identical to "light_flame_small_yellow"
-*/
-void() light_flame_small_white =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- light_flame_small_yellow();
-};
-
-/*QUAKED light_sprite_flame (0 1 0) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model ("progs/s_flame.spr"); }
-Large flame spite*/
-void() light_sprite_flame =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/s_flame.spr");
- setmodel(self, "progs/s_flame.spr");
- FireAmbient ();
-
- self.frame = rint(random() * 13);
- self.first_frame = 0;
- self.last_frame = 13;
- self.speed = 0.05;
- self.think = misc_model_think;
- self.nextthink = time + 0.1;
-
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/math.qc

diff --git a/qc-server/math.qc b/qc-server/math.qc
deleted file mode 100644
index 13985d0..0000000
--- a/qc-server/math.qc
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * math.qc
- *
- * Author: Joshua Skelton joshua.skelton@gmail.com
- *
- * A collection of helpful math functions.
- */
-
-// Forward declarations
-float(float value, float minValue, float maxValue) clamp;
-float(float a, float b) mod;
-float(float x) sign;
-float(float value, float minValue, float maxValue) wrap;
-
-/*
- * clamp
- *
- * Limits the given value to the given range.
- *
- * value: A number
- *
- * minValue: The minimum value of the range
- *
- * maxValue: The maximum value of the range
- *
- * Returns: A number within the given range.
- */
-float(float value, float minValue, float maxValue) clamp = {
- if (value < minValue) {
- return minValue;
- }
- else if (value > maxValue) {
- return maxValue;
- }
-
- return value;
-};
-
-/*
- * mod
- *
- * Returns the remainder after the division of a by n
- *
- * a: The dividend
- *
- * b: The divisor
- *
- * Returns: The remainder of a divided by n
- */
-float(float a, float n) mod = {
- return a - (n * floor(a / n));
-};
-
-/*
- * sign
- *
- * Returns an indication of the sign of the given number.
- *
- * x: A number
- *
- * Returns: -1 if x < 0, 0 if x == 0, 1 if x > 0.
- */
-float(float x) sign = {
- if (x > 0) {
- return 1;
- }
- else if (x < 0) {
- return -1;
- }
-
- return 0;
-};
-
-/*
- * wrap
- *
- * Limits the given value to the given range and will wrap the value to the
- * the other end of the range if exceeded.
- *
- * value: A number
- *
- * minValue: The minimum value of the range
- *
- * maxValue: The maximum value of the range
- *
- * Returns: A number within the given range.
- */
-float(float value, float minValue, float maxValue) wrap = {
- local float range = maxValue - minValue;
-
- return mod(value - minValue, range + 1) + minValue;
-};
-
-
-
-float(float a, float b, float mix) lerp =
-{
- if (mix <= 0) return a;
- if (mix >= 1) return b;
- return (b * mix + a * ( 1 - mix ) );
-}
-
-vector(vector a, vector b, float mix) lerpVector =
-{
- if (mix <= 0) return a;
- if (mix >= 1) return b;
- return (b * mix + a * ( 1 - mix ) );
-}
-
-// for a relaxing lerp: hermite lerp.
-float(float a, float b, float mix) lerpHermite =
-{
- if (mix <= 0) return a;
- if (mix >= 1) return b;
-
- local float h01;
-
- h01 = mix * mix;
- h01 *= 3 - 2 * mix;
-
- return (b * h01 + a * ( 1 - h01 ) );
-}
-
-vector(vector a, vector b, float mix) lerpVectorHermite =
-{
- if (mix <= 0) return a;
- if (mix >= 1) return b;
-
- local float h01;
-
- h01 = mix * mix;
- h01 *= 3 - 2 * mix;
-
- return (b * h01 + a * ( 1 - h01 ) );
-}
-
-float(float anga, float angb) angledif =
-{
- float dif;
- dif = fabs(anga - angb);
- if (dif > 180)
- dif = 360 - dif;
- return dif;
-}
-
-float(vector ang, vector base_ang, vector offset) isInAngle = {
- if (angledif(ang_x, base_ang_x) > offset_x || angledif(ang_y, base_ang_y) > offset_y)
- return FALSE;
- else
- return TRUE;
-};
-
-
-// normalizes an angle vector to the 0/+359 range
-vector(vector ang) normalizeAngles = {
-
- ang_x = ang_x - floor(ang_x/360) * 360;
- ang_y = ang_y - floor(ang_y/360) * 360;
- ang_z = ang_z - floor(ang_z/360) * 360;
-
- /*
- while (ang_x > 360)
- ang_x = ang_x - 360;
-
- while (ang_x < 0)
- ang_x = ang_x + 360;
-
- while (ang_y > 360)
- ang_y = ang_y - 360;
-
- while (ang_y < 0)
- ang_y = ang_y + 360;
-
- while (ang_z > 360)
- ang_z = ang_z - 360;
-
- while (ang_z < 0)
- ang_z = ang_z + 360;
- */
- return ang;
-};
-
-// normalizes an angle vector to the -180/+179 range
-vector(vector ang) normalizeAngles180 = {
- ang_x = ((ang_x+180) - floor((ang_x+180)/360) * 360) - 180;
- ang_y = ((ang_y+180) - floor((ang_y+180)/360) * 360) - 180;
- ang_z = ((ang_z+180) - floor((ang_z+180)/360) * 360) - 180;
-
- /*
- while (ang_x > 180)
- ang_x = ang_x - 360;
-
- while (ang_x < -180)
- ang_x = ang_x + 360;
-
- while (ang_y > 180)
- ang_y = ang_y - 360;
-
- while (ang_y < -180)
- ang_y = ang_y + 360;
-
- while (ang_z > 180)
- ang_z = ang_z - 360;
-
- while (ang_z < -180)
- ang_z = ang_z + 360;
- */
- return ang;
-};
\ No newline at end of file

Return to the top of this page or return to the overview of this repo.

Diff qc-server/misc.qc

diff --git a/qc-server/misc.qc b/qc-server/misc.qc
deleted file mode 100644
index 062b6d0..0000000
--- a/qc-server/misc.qc
+++ /dev/null
@@ -1,1871 +0,0 @@
-// these were moved for various reasons -- dumptruck_ds
-// /*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4)
-// Used as a positional target for spotlights, etc.
-// */
-// /void() info_null =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// remove(self);
-// };
-//
-// /*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4)
-// Used as a positional target for lightning.
-// */
-// void() info_notnull =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-// };
-//
-// //============================================================================
-//
-// float START_OFF = 1;
-//
-// void() light_use =
-// {
-// if (self.spawnflags & START_OFF)
-// {
-// lightstyle(self.style, "m");
-// self.spawnflags = self.spawnflags - START_OFF;
-// }
-// else
-// {
-// lightstyle(self.style, "a");
-// self.spawnflags = self.spawnflags + START_OFF;
-// }
-// };
-//
-// /*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
-// Non-displayed light.
-// Default light value is 300
-// Default style is 0
-// If targeted, it will toggle between on or off.
-// */
-// void() light =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// if (!self.targetname)
-// { // inert light
-// remove(self);
-// return;
-// }
-//
-// if (self.style >= 32)
-// {
-// self.use = light_use;
-// if (self.spawnflags & START_OFF)
-// lightstyle(self.style, "a");
-// else
-// lightstyle(self.style, "m");
-// }
-// };
-//
-// /*QUAKED light_fluoro (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
-// Non-displayed light.
-// Default light value is 300
-// Default style is 0
-// If targeted, it will toggle between on or off.
-// Makes steady fluorescent humming sound
-// */
-// void() light_fluoro =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// if (self.style >= 32)
-// {
-// self.use = light_use;
-// if (self.spawnflags & START_OFF)
-// lightstyle(self.style, "a");
-// else
-// lightstyle(self.style, "m");
-// }
-//
-// precache_sound ("ambience/fl_hum1.wav");
-// ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC);
-// };
-//
-// /*QUAKED light_fluorospark (0 1 0) (-8 -8 -8) (8 8 8)
-// Non-displayed light.
-// Default light value is 300
-// Default style is 10
-// Makes sparking, broken fluorescent sound
-// */
-// void() light_fluorospark =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// if (!self.style)
-// self.style = 10;
-//
-// precache_sound ("ambience/buzz1.wav");
-// ambientsound (self.origin, "ambience/buzz1.wav", 0.5, ATTN_STATIC);
-// };
-//
-// /*QUAKED light_globe (0 1 0) (-8 -8 -8) (8 8 8)
-// Sphere globe light.
-// Default light value is 300
-// Default style is 0
-// */
-// void() light_globe =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// precache_model ("progs/s_light.spr");
-// setmodel (self, "progs/s_light.spr");
-// makestatic (self);
-// };
-//
-/*QUAKED FireAmbient (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
-*/
-void() FireAmbient =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/fire1.wav");
-// attenuate fast
- ambientsound (self.origin, "ambience/fire1.wav", 0.5, ATTN_STATIC);
-};
-
-/*QUAKED ambient_fire (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-ambinet fire sound effects added for consistency
-same as FireAmbient
-*/
-void() ambient_fire =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
-FireAmbient();
-};
-
-//
-// /*QUAKED light_torch_small_walltorch (0 .5 0) (-10 -10 -20) (10 10 20)
-// Short wall torch
-// Default light value is 200
-// Default style is 0
-// */
-// void() light_torch_small_walltorch =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// precache_model ("progs/flame.mdl");
-// setmodel (self, "progs/flame.mdl");
-// FireAmbient ();
-// makestatic (self);
-// };
-//
-// /*QUAKED light_flame_large_yellow (0 1 0) (-10 -10 -12) (12 12 18)
-// Large yellow flame ball
-// */
-// void() light_flame_large_yellow =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// precache_model ("progs/flame2.mdl");
-// setmodel (self, "progs/flame2.mdl");
-// self.frame = 1;
-// FireAmbient ();
-// makestatic (self);
-// };
-//
-// /*QUAKED light_flame_small_yellow (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
-// Small yellow flame ball
-// */
-// void() light_flame_small_yellow =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// precache_model ("progs/flame2.mdl");
-// setmodel (self, "progs/flame2.mdl");
-// FireAmbient ();
-// makestatic (self);
-// };
-//
-// /*QUAKED light_flame_small_white (0 1 0) (-10 -10 -40) (10 10 40) START_OFF
-// Small white flame ball
-// */
-// void() light_flame_small_white =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// precache_model ("progs/flame2.mdl");
-// setmodel (self, "progs/flame2.mdl");
-// FireAmbient ();
-// makestatic (self);
-// };
-//
-/*QUAKED light_candle (0 1 0) (-10 -10 -40) (10 10 40) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/candle.mdl"); }
-==========
-Spawnflags
-==========
-START_OFF - switchable lights only - light is off by default
-FADE_IN_OUT - switchable lights only - light fades in and out. can't be combined with animated lights.
-
-==========
-Keys
-==========
-"light" "n"
-Set the light intensity. Negative values are also allowed and will cause the entity to subtract light cast by other entities. Default 300.
-
-"wait" "n"
-Scale the fade distance of the light by "n". Values of n > 1 make the light fade more quickly with distance, and values < 1 make the light fade more slowly (and thus reach further). Default 1.
-
-"delay" "n"
-Select an attenuation formaula for the light:
-0 => Linear attenuation (default)
-1 => 1/x attenuation
-2 => 1/(x^2) attenuation
-3 => No attenuation (same brightness at any distance)
-4 => "local minlight" - No attenuation and like minlight,
-it won't raise the lighting above it's light value.
-Unlike minlight, it will only affect surfaces within
-line of sight of the entity.
-5 => 1/(x^2) attenuation, but slightly more attenuated and
-without the extra bright effect that "delay 2" has
-near the source.
-
-"_falloff" "n"
-Sets the distance at which the light drops to 0, in map units.
-In this mode, "wait" is ignored and "light" only controls the brightness at the center of the light, and no longer affects the falloff distance.
-Only supported on linear attenuation (delay 0) lights currently.
-
-"_color" "r g b"
-Specify red(r), green(g) and blue(b) components for the colour of the light. RGB component values are between 0 and 255 (between 0 and 1 is also accepted). Default is white light ("255 255 255").
-
-"target" "name"
-Turns the light into a spotlight, with the direction of light being towards another entity with it�s "targetname" key set to "name".
-"mangle" "yaw pitch roll"
-Turns the light into a spotlight and specifies the direction of light using yaw, pitch and roll in degrees. Yaw specifies the angle around the Z-axis from 0 to 359 degrees and pitch specifies the angle from 90 (straight up) to -90 (straight down). Roll has no effect, so use any value (e.g. 0). Often easier than the "target" method.
-
-"angle" "n"
-Specifies the angle in degrees for a spotlight cone. Default 40.
-
-"_softangle" "n"
-Specifies the angle in degrees for an inner spotlight cone (must be less than the "angle" cone. Creates a softer transition between the full brightness of the inner cone to the edge of the outer cone. Default 0 (disabled).
-
-"targetname" "name"
-Turns the light into a switchable light, toggled by another entity targeting it�s name.
-
-"speed" "n"
-If the light is switchable and FADE_IN_OUT is set, the speed at which the light transitions. Default 0.1.
-
-"style" "n"
-Set the animated light style. Default 0.
-
-"style2" "n"
-Set the animated light style for a switchable light, because style will be overriden if a targetname is set. Default 0.
-
-"_anglescale" "n" | "_anglesense" "n"
-Sets a scaling factor for how much influence the angle of incidence of light on a surface has on the brightness of the surface. n must be between 0.0 and 1.0. Smaller values mean less attenuation, with zero meaning that angle of incidence has no effect at all on the brightness. Default 0.5.
-
-"_dirtscale" "n" | "_dirtgain" "n"
-Override the global "_dirtscale" or "_dirtgain" settings to change how this light is affected by dirtmapping (ambient occlusion). See descriptions of these keys in the worldspawn section.
-
-"_dirt" "n"
-Overrides the worldspawn setting of "_dirt" for this particular light. -1 to disable dirtmapping (ambient occlusion) for this light, making it illuminate the dirtmapping shadows. 1 to enable ambient occlusion for this light. Default is to defer to the worldspawn setting.
-
-"_deviance" "n"
-Split up the light into a sphere of randomly positioned lights within radius "n" (in world units). Useful to give shadows a wider penumbra. "_samples" specifies the number of lights in the sphere. The "light" value is automatically scaled down for most lighting formulas (except linear and non-additive minlight) to attempt to keep the brightness equal. Default is 0, do not split up lights.
-
-"_samples" "n"
-Number of lights to use for "_deviance". Default 16 (only used if "_deviance" is set).
-
-"_surface" "texturename"
-Makes surfaces with the given texture name emit light, by using this light as a template which is copied across those surfaces. Lights are spaced about 128 units (though possibly closer due to bsp splitting) apart and positioned 2 units above the surfaces.
-
-"_surface_offset" "n"
-Controls the offset lights are placed above surfaces for "_surface". Default 2.
-
-"_surface_spotlight" "n"
-For a surface light template (i.e. a light with "_surface" set), setting this to "1" makes each instance into a spotlight, with the direction of light pointing along the surface normal. In other words, it automatically sets "mangle" on each of the generated lights.
-
-"_project_texture" "texture"
-Specifies that a light should project this texture. The texture must be used in the map somewhere.
-
-"_project_mangle" "yaw pitch roll"
-Specifies the yaw/pitch/roll angles for a texture projection (overriding mangle).
-
-"_project_fov" "n"
-Specifies the fov angle for a texture projection. Default 90.
-
-"_bouncescale" "n"
-Scales the amount of light that is contributed by bounces. Default is 1.0, 0.0 disables bounce lighting for this light.
-
-"_sun" "n"
-Set to 1 to make this entity a sun, as an alternative to using the sunlight worldspawn keys. If the light targets an info_null entity, the direction towards that entity sets sun direction. The light itself is disabled, so it can be placed anywhere in the map.
-
-The following light properties correspond to these sunlight settings:
-light => _sunlight
-mangle => _sunlight_mangle
-deviance => _sunlight_penumbra
-_color => _sunlight_color
-_dirt => _sunlight_dirt
-_anglescale => _anglescale
-
- //dumptruck_ds taken from honey (originally from Rogue)
-White candle
-*/
-void() light_candle =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/candle.mdl");
- setmodel (self, "progs/candle.mdl");
- makestatic (self);
-};
-
-void() model_candle_think =
-{
- self.frame = self.frame + 1;
- if (self.frame > 3)
- self.frame = 0;
- self.nextthink = time + 0.1;
-};
-
-void() model_candle =
-{
-
- precache_model ("progs/candle.mdl");
-
- setmodel (self, "progs/candle.mdl");
-
- self.think = model_candle_think;
- self.nextthink = time + 0.1;
-};
-
-
-//============================================================================
-
-
-/*QUAKED misc_fireball (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model ("progs/lavaball.mdl"); }
-Flying lava balls
-speed - set vertical speed of fireballs. default 1000.
-*/
-
-void() fire_fly;
-void() fire_touch;
-void() misc_fireball =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/lavaball.mdl");
- self.classname = "fireball";
-// 1998-08-14 Incorrect setting of nextthink fix by Maddes/Lord Sméagol
-// self.nextthink = time + (random() * 5);
- self.nextthink = time + 0.1 + (random() * 5);
-// 1998-08-14 Incorrect setting of nextthink fix by Maddes/Lord Sméagol
- self.think = fire_fly;
- if (!self.speed)
- self.speed = 1000; // fixed typo QIP - dumptruck_ds
-};
-
-void() fire_fly =
-{
-local entity fireball;
-
- fireball = spawn();
- fireball.solid = SOLID_TRIGGER;
- fireball.movetype = MOVETYPE_TOSS;
- fireball.velocity = '0 0 1000';
- fireball.velocity_x = (random() * 100) - 50;
- fireball.velocity_y = (random() * 100) - 50;
- fireball.velocity_z = self.speed + (random() * 200);
- fireball.classname = "fireball";
- setmodel (fireball, "progs/lavaball.mdl");
- setsize (fireball, '0 0 0', '0 0 0');
- setorigin (fireball, self.origin);
- fireball.nextthink = time + 5;
- fireball.think = SUB_Remove;
- fireball.touch = fire_touch;
-
- self.nextthink = time + (random() * 5) + 3;
- self.think = fire_fly;
-};
-
-
-void() fire_touch =
-{
- T_Damage (other, self, self, 20);
- remove(self);
-};
-
-//============================================================================
-
-
-void() barrel_explode =
-{
- self.takedamage = DAMAGE_NO;
- self.classname = "explo_box";
- // did say self.owner
- T_RadiusDamage (self, self, 160, world);
- sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
- particle (self.origin, '0 0 0', 75, 255);
-
- self.origin_z = self.origin_z + 32;
- BecomeExplosion ();
-};
-
-
-
-/*QUAKED misc_explobox (0 .5 .8) (0 0 0) (32 32 64) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model("maps/b_explob.bsp");
-}
-Explosive box
-*/
-
-void() misc_explobox =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- local float oldz;
-
- self.solid = SOLID_BBOX;
- self.movetype = MOVETYPE_NONE;
- precache_model ("maps/b_explob.bsp");
- setmodel (self, "maps/b_explob.bsp");
- precache_sound ("weapons/r_exp3.wav");
- self.health = 20;
- self.th_die = barrel_explode;
- self.takedamage = DAMAGE_AIM;
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
-
- self.origin_z = self.origin_z + 2;
- oldz = self.origin_z;
- droptofloor();
- if (oldz - self.origin_z > 250)
- {
- dprint ("item fell out of level at ");
- dprint (vtos(self.origin));
- dprint ("\n");
- remove(self);
- }
-};
-
-
-
-
-/*QUAKED misc_explobox2 (0 .5 .8) (0 0 0) (32 32 64) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model("maps/b_exbox2.bsp");
-}
-Smaller explosive box
-*/
-
-void() misc_explobox2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- local float oldz;
-
- self.solid = SOLID_BBOX;
- self.movetype = MOVETYPE_NONE;
- precache_model2 ("maps/b_exbox2.bsp");
- setmodel (self, "maps/b_exbox2.bsp");
- precache_sound ("weapons/r_exp3.wav");
- self.health = 20;
- self.th_die = barrel_explode;
- self.takedamage = DAMAGE_AIM;
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
-
- self.origin_z = self.origin_z + 2;
- oldz = self.origin_z;
- droptofloor();
- if (oldz - self.origin_z > 250)
- {
- dprint ("item fell out of level at ");
- dprint (vtos(self.origin));
- dprint ("\n");
- remove(self);
- }
-};
-
-/*==============================================================================
-trap_spikeshooter from Hipnotic -- with additions by dumptruck_ds
-==============================================================================*/
-
-//MED 11/09/96 added new spawnflags -- taken from hipdefs.qc - dumptruck_ds
-float SPAWNFLAG_SUPERSPIKE = 1;
-float SPAWNFLAG_LASER = 2;
-float SPAWNFLAG_LAVABALL = 4;
-float SPAWNFLAG_ROCKET = 8;
-float SPAWNFLAG_VOREBALL = 16;
-float SPAWNFLAG_GRENADE = 32;
-float SPAWNFLAG_GIBS = 64;
-float SPAWNFLAG_SILENT = 128;
-
-void() ShalMissileTouch = //moved from Shalrath to enable shooter version
-{
- if (other == self.owner)
- return; // don't explode on owner
-
- if (other.classname == "monster_zombie")
- T_Damage (other, self, self, 110);
- T_RadiusDamage (self, self.owner, 40, world);
- sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- BecomeExplosion ();
-
-
- // self.velocity = '0 0 0';
- // self.touch = SUB_Null;
- // setmodel (self, "progs/s_explod.spr");
- // self.solid = SOLID_NOT;
- // s_explode1 ();
-};
-
-void() ZombieGrenadeTouch = //moved from zombie.qc to enable shooter version
-{
- if (other == self.owner)
- return; // don't explode on owner
- if (other.takedamage)
- {
- T_Damage (other, self, self.owner, 10 );
- sound (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM);
- remove (self);
- return;
- }
- sound (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
- self.velocity = '0 0 0';
- self.avelocity = '0 0 0';
- self.touch = SUB_Remove;
-};
-
-
-void(vector org, vector vec) LaunchLaser;
-
-//MED 11/09/96 added lava ball and rocket
-//dumptruck_ds added voreball and grenades
-void() spikeshooter_use =
-{
- local entity lavaball;
- local entity voreball;
- local entity rockettrap;
- local entity gnade;
- local entity zgibs;
-
- if (self.spawnflags & SPAWNFLAG_LASER)
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "enforcer/enfire.wav", 1, ATTN_NORM);
- LaunchLaser (self.origin, self.movedir);
- newmis.spawnflags = self.spawnflags;
- }
- else if (self.spawnflags & SPAWNFLAG_LAVABALL)
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "boss1/throw.wav", 1, ATTN_NORM); //dms
- // sound (self, CHAN_VOICE, "knight/sword2.wav", 1, ATTN_NORM); //dms
- // sound (self, CHAN_VOICE, "weapons/ax1.wav", 1, ATTN_NORM); //dms
- lavaball = spawn();
- lavaball.movetype = MOVETYPE_FLYMISSILE;
- lavaball.solid = SOLID_BBOX;
- lavaball.classname = "lavaball";
- // set lavaball speed
- lavaball.velocity = self.movedir * 600; //was 300 dms
- lavaball.angles = vectoangles(lavaball.velocity);
- lavaball.owner = self;
- lavaball.touch = ShalMissileTouch;
- setmodel (lavaball, "progs/lavaball.mdl"); //dms
- setsize (lavaball, '0 0 0', '0 0 0');
- setorigin (lavaball, self.origin);
- lavaball.avelocity = '0 0 400';
- lavaball.nextthink = time + 5;
- lavaball.think = SUB_Remove;
- }
-
- else if (self.spawnflags & SPAWNFLAG_ROCKET)
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "weapons/sgun1.wav", 1, ATTN_NORM);
- rockettrap = spawn();
- rockettrap.movetype = MOVETYPE_FLYMISSILE;
- rockettrap.solid = SOLID_BBOX;
- rockettrap.classname = "rockettrap";
- // set rocket speed
- rockettrap.velocity = self.movedir * 1000;
- rockettrap.angles = vectoangles(rockettrap.velocity);
- rockettrap.owner = self;
- rockettrap.touch = T_MissileTouch;
- setmodel (rockettrap, "progs/missile.mdl"); //dms
- setsize (rockettrap, '0 0 0', '0 0 0');
- setorigin (rockettrap, self.origin);
- // rockettrap.avelocity = '0 0 400';
- rockettrap.nextthink = time + 5;
- rockettrap.think = SUB_Remove;
- }
- else if (self.spawnflags & SPAWNFLAG_VOREBALL)
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "shalrath/attack2.wav", 1, ATTN_NORM);
- voreball = spawn();
- voreball.movetype = MOVETYPE_FLYMISSILE;
- voreball.solid = SOLID_BBOX;
- voreball.classname = "voreball";
- // set voreball speed
- voreball.velocity = self.movedir * 600; //was 300 dms
- voreball.angles = vectoangles(voreball.velocity);
- voreball.owner = self;
- voreball.touch = ShalMissileTouch;
- setmodel (voreball, "progs/v_spike.mdl"); //dms
- setsize (voreball, '0 0 0', '0 0 0');
- setorigin (voreball, self.origin);
- voreball.avelocity = '0 0 400';
- voreball.nextthink = time + 5;
- voreball.think = SUB_Remove;
- }
-
- else if (self.spawnflags & SPAWNFLAG_GRENADE)
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "weapons/grenade.wav", 1, ATTN_NORM);
- gnade = spawn();
- gnade.movetype = MOVETYPE_BOUNCE;
- // gnade.movetype = MOVETYPE_FLYMISSILE;
- gnade.solid = SOLID_BBOX;
- gnade.classname = "gnade";
- // set grenade speed
- // gnade.velocity = self.movedir * 600; //was 300 dms
- gnade.velocity = self.movedir * 600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
- gnade.angles = vectoangles(gnade.velocity);
- gnade.owner = self;
- gnade.touch = GrenadeTouch;
- setmodel (gnade, "progs/grenade.mdl"); //dms
- setsize (gnade, '0 0 0', '0 0 0');
- setorigin (gnade, self.origin);
- gnade.avelocity = '300 300 300';
- gnade.nextthink = time + 2.5;
- gnade.think = GrenadeExplode;
- }
-
- else if (self.spawnflags & SPAWNFLAG_GIBS)
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "zombie/z_shot1.wav", 1, ATTN_NORM);
- zgibs = spawn ();
- zgibs.owner = self;
- zgibs.movetype = MOVETYPE_BOUNCE;
- zgibs.solid = SOLID_BBOX;
- zgibs.classname = "zgibs";
- setmodel (zgibs, "progs/zom_gib.mdl");
- setsize (zgibs, '0 0 0', '0 0 0');
- setorigin (zgibs, self.origin);
- zgibs.velocity = self.movedir * 600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
- zgibs.avelocity = '3000 1000 2000';
- zgibs.touch = ZombieGrenadeTouch;
- // set missile duration
- zgibs.nextthink = time + 2.5;
- zgibs.think = SUB_Remove;
- }
-
- else
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "weapons/spike2.wav", 1, ATTN_NORM);
- launch_spike (self.origin, self.movedir);
- newmis.velocity = self.movedir * 500;
- if (self.spawnflags & SPAWNFLAG_SUPERSPIKE)
- newmis.touch = superspike_touch;
- }
-};
-
-//MED 11/01/96 added state capability
-void() shooter_think =
-{
- if (self.state)
- {
- spikeshooter_use ();
- }
- self.nextthink = time + self.wait;
-};
-
-
-/*QUAKED trap_spikeshooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lavaball rocket silent X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-When triggered, fires a spike in the direction set in QuakeEd.
-Laser is only for REGISTERED.
-*/
-
-//MED 11/01/96 commented out setmovedir
-void() trap_spikeshooter =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.proj_speed_mod <= 0)
- self.proj_speed_mod = 1;
- SetMovedir ();
- self.use = spikeshooter_use;
- if (self.spawnflags & SPAWNFLAG_LASER)
- {
- precache_model2 ("progs/laser.mdl");
-
- precache_sound2 ("enforcer/enfire.wav");
- precache_sound2 ("enforcer/enfstop.wav");
- }
- else if (self.spawnflags & SPAWNFLAG_LAVABALL)
- {
- precache_model ("progs/lavaball.mdl");
- // precache_sound2 ("knight/sword2.wav"); //dms
- precache_sound2 ("boss1/throw.wav"); //dms
- }
- else if (self.spawnflags & SPAWNFLAG_ROCKET)
- {
- precache_model ("progs/missile.mdl");
- precache_sound ("weapons/sgun1.wav");
- }
- else if (self.spawnflags & SPAWNFLAG_VOREBALL)
- {
- precache_model ("progs/v_spike.mdl");
- precache_sound ("shalrath/attack2.wav");
- }
- else if (self.spawnflags & SPAWNFLAG_GRENADE)
- {
- precache_model ("progs/grenade.mdl");
- precache_sound ("weapons/grenade.wav"); // grenade launcher
- }
- else if (self.spawnflags & SPAWNFLAG_GIBS)
- {
- precache_model ("progs/zom_gib.mdl");
- precache_sound ("zombie/z_shot1.wav"); // Zombie gibs
- precache_sound ("zombie/z_miss.wav");
- precache_sound ("zombie/z_hit.wav");
- }
-
- else
- precache_sound ("weapons/spike2.wav");
-};
-
-
-/*QUAKED trap_shooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lavaball rocket silent X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Continuously fires spikes.
-"wait" time between spike (1.0 default)
-"nextthink" delay before firing first spike, so multiple shooters can be stagered.
-*/
-void() trap_shooter =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- trap_spikeshooter ();
-
- if (self.wait == 0)
- self.wait = 1;
-//MED 11/01/96 added state capability
- self.state = 1;
- self.nextthink = self.nextthink + self.wait + self.ltime;
- self.think = shooter_think;
-};
-
-//MED 11/01/96 added new use function
-void() trap_shooter_use =
- {
- self.state = 1 - self.state;
- };
-//MED 11/01/96 added new function
-/*QUAKED trap_switched_shooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lavaball rocket silent X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Continuously fires spikes.
-"wait" time between spike (1.0 default)
-"nextthink" delay before firing first spike, so multiple shooters can be stagered.
-"state" 0 initially off, 1 initially on. (0 default)
-*/
-void() trap_switched_shooter =
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- trap_spikeshooter ();
-
- if (self.wait == 0)
- self.wait = 1;
-//MED 11/01/96 added state capability
- self.nextthink = self.nextthink + self.wait + self.ltime;
- self.think = shooter_think;
- self.use = trap_shooter_use;
- };
-
-/*
-===============================================================================
-
-
-===============================================================================
-*/
-
-
-void() make_bubbles;
-void() bubble_remove;
-void() bubble_bob;
-
-/*QUAKED air_bubbles (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-air bubbles entity
-
-*/
-
-void() air_bubbles =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove (self);
- return;
- }
- precache_model ("progs/s_bubble.spr");
- self.nextthink = time + 1;
- self.think = make_bubbles;
-};
-
-void() make_bubbles =
-{
-local entity bubble;
-
- bubble = spawn();
- setmodel (bubble, "progs/s_bubble.spr");
- setorigin (bubble, self.origin);
- bubble.movetype = MOVETYPE_NOCLIP;
- bubble.solid = SOLID_NOT;
- bubble.velocity = '0 0 15';
- bubble.nextthink = time + 0.5;
- bubble.think = bubble_bob;
- bubble.touch = bubble_remove;
- bubble.classname = "bubble";
- bubble.frame = 0;
- bubble.cnt = 0;
- setsize (bubble, '-8 -8 -8', '8 8 8');
- self.nextthink = time + random() + 0.5;
- self.think = make_bubbles;
-};
-
-void() bubble_split =
-{
-local entity bubble;
- bubble = spawn();
- setmodel (bubble, "progs/s_bubble.spr");
- setorigin (bubble, self.origin);
- bubble.movetype = MOVETYPE_NOCLIP;
- bubble.solid = SOLID_NOT;
- bubble.velocity = self.velocity;
- bubble.nextthink = time + 0.5;
- bubble.think = bubble_bob;
- bubble.touch = bubble_remove;
- bubble.classname = "bubble";
- bubble.frame = 1;
- bubble.cnt = 10;
- setsize (bubble, '-8 -8 -8', '8 8 8');
- self.frame = 1;
- self.cnt = 10;
- if (self.waterlevel != 3)
- remove (self);
-};
-
-void() bubble_remove =
-{
- if (other.classname == self.classname)
- {
-// dprint ("bump");
- return;
- }
- remove(self);
-};
-
-void() bubble_bob =
-{
-local float rnd1, rnd2, rnd3;
-
-
- self.cnt = self.cnt + 1;
- if (self.cnt == 4)
- bubble_split();
- if (self.cnt == 20)
- remove(self);
-
- rnd1 = self.velocity_x + (-10 + (random() * 20));
- rnd2 = self.velocity_y + (-10 + (random() * 20));
- rnd3 = self.velocity_z + 10 + random() * 10;
-
- if (rnd1 > 10)
- rnd1 = 5;
- if (rnd1 < -10)
- rnd1 = -5;
-
- if (rnd2 > 10)
- rnd2 = 5;
- if (rnd2 < -10)
- rnd2 = -5;
-
- if (rnd3 < 10)
- rnd3 = 15;
- if (rnd3 > 30)
- rnd3 = 25;
-
- self.velocity_x = rnd1;
- self.velocity_y = rnd2;
- self.velocity_z = rnd3;
-
- self.nextthink = time + 0.5;
- self.think = bubble_bob;
-};
-
-/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>
-~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/
-
-/*QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8)
-
-Just for the debugging level. Don't use
-*/
-
-void() viewthing =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- precache_model ("progs/player.mdl");
- setmodel (self, "progs/player.mdl");
-};
-
-
-/*
-==============================================================================
-
-SIMPLE BMODELS
-
-==============================================================================
-*/
-
-void() func_wall_use =
-{ // change to alternate textures
- self.frame = 1 - self.frame;
-};
-
-/*QUAKED func_wall (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-This is just a solid wall if not inhibitted
-*/
-void() func_wall =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.angles = '0 0 0';
- self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
- self.solid = SOLID_BSP;
- self.use = func_wall_use;
- setmodel (self, self.model);
-};
-
-
-/*QUAKED func_illusionary (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-A simple entity that looks solid but lets you walk through it.
-*/
-void() func_illusionary =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.angles = '0 0 0';
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- setmodel (self, self.model);
- makestatic (self);
-};
-
-
-float GATE_REVERSE = 16; // For func_episodegate and func_bossgate appear when player has all runes
-
-/*QUAKED func_episodegate (0 .5 .8) ? E1 E2 E3 E4 REVERSE_FUNCTIONALITY
-This bmodel will appear if the episode has allready been completed, so players can't reenter it.
-*/
-void() func_episodegate =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & GATE_REVERSE)
- {
- self.spawnflags = self.spawnflags - GATE_REVERSE; // this is to avoid a possible issue with sigil_touch2
- if (serverflags & self.spawnflags)
- return; // Haven't gotten rune yet
- }
- else
- {
- if (!(serverflags & self.spawnflags))
- return; // can still enter episode
- }
- self.angles = '0 0 0';
- self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
- self.solid = SOLID_BSP;
- self.use = func_wall_use;
- setmodel (self, self.model);
-};
-
-/*QUAKED func_bossgate (0 .5 .8) ? X X X X REVERSE_FUNCTIONALITY
-This bmodel appears unless players have all of the episode sigils.
-*/
-void() func_bossgate =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & GATE_REVERSE)
- {
- if (!((serverflags & 15) == 15))
- {
- return; // not all complete
- }
- }
- else
- {
- if ( (serverflags & 15) == 15 )
- return; // all episodes completed
- }
- self.angles = '0 0 0';
- self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
- self.solid = SOLID_BSP;
- self.use = func_wall_use;
- setmodel (self, self.model);
-};
-
-/*****************
-func_togglevisiblewall
-
-A bmodel which you can toggle its visibility. Behaves much like a traditional func_wall in any other way,
-but you can target it to toggle visible/invisible.
-If the entity has a switchable shadow it also toggles.
-
-spawnflag 1: starts invisible
-spawnflag 2: set brush as non-solid
-
-******************/
-
-float TOGGLEVISWALL_STARTOFF = 1;
-float TOGGLEVISWALL_NOTSOLID = 2;
-
-void() func_togglevisiblewall_use =
-{
- if(!self.state) {
- if(!(self.spawnflags & TOGGLEVISWALL_NOTSOLID)) {
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- }
- setmodel (self, self.origmodel);
- if(self.switchshadstyle) lightstyle(self.switchshadstyle, "a");
- self.state = 1;
- } else {
-
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_NONE;
- setmodel (self, "");
- if(self.switchshadstyle) lightstyle(self.switchshadstyle, "m");
- self.state = 0;
- }
-
-};
-
-void() func_togglevisiblewall =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.angles = '0 0 0';
- self.use = func_togglevisiblewall_use;
-
- self.origmodel = self.model;
-
- if(self.spawnflags & TOGGLEVISWALL_STARTOFF) self.state = 1;
- else self.state = 0;
-
- if(self.spawnflags & TOGGLEVISWALL_NOTSOLID) {
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_NONE;
- }
-
- func_togglevisiblewall_use();
-
-};
-
-
-/*****************
-func_shadow
-
-An invisible bmodel that can be used to only cast shadows.
-
-******************/
-
-void() func_shadow = {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.angles = '0 0 0';
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
-
- self.modelindex = 0;
- self.model = "";
-
-}
-
-
-
-/********************
-misc_shadowcontroller
-
-Controls switchable shadows on any bmodel entity (except doors).
-Target entity must have set _switchableshadow set to 1.
-
-speed: Controls the time in seconds it takes to fade the shadow in. Default is 0.5, and setting it to -1 disables fading.
-speed2: Same as 'speed' but for the fade out animation. If unset it's the same value as 'speed'.
-spawnflag 1: target shadow starts as disabled
-
-*********************/
-
-float SHADOWCONTROLLER_STARTOFF = 1;
-
-void() shadow_fade_out =
-{
- if (self.count < 0)
- self.count = 0;
- if (self.count > 12)
- self.count = 12;
-
- dprint(ftos(self.count));dprint("\n");
-
- lightstyle(self.switchshadstyle, lightstyle_fade_lookup(self.count));
- self.count = self.count + self.dmg;
- if (self.count > 12)
- return;
-
- self.think = shadow_fade_out;
- self.nextthink = time + self.delay;
-};
-
-void() shadow_fade_in =
-{
- if (self.count < 0)
- self.count = 0;
- if (self.count > 12)
- self.count = 12;
-
- dprint(ftos(self.count));dprint("\n");
-
- lightstyle(self.switchshadstyle, lightstyle_fade_lookup(self.count));
- self.count = self.count - self.dmg;
- if (self.count < 0)
- return;
-
- self.think = shadow_fade_in;
- self.nextthink = time + self.delay;
-
-};
-
-void(float speed) misc_shadowcontroller_setsteps = {
- // self.delay -> time between steps
- // self.dmg -> step size
- if(speed >= 0.24) {
- self.delay = (speed/12);
- self.dmg = 1;
- }
- else if(speed >= 0.12) {
- self.delay = (speed/6);
- self.dmg = 2;
- }
- else if(speed >= 0.06) {
- self.delay = (speed/3);
- self.dmg = 4;
- }
- else if(speed >= 0.04) {
- self.delay = (speed/2);
- self.dmg = 6;
- }
- else {
- self.delay = 0;
- self.dmg = 12;
- }
-
-}
-
-void() misc_shadowcontroller_use = {
-
- if(self.shadowoff) {
- dprint("Fade in:\n");
-
- misc_shadowcontroller_setsteps(self.speed);
-
- shadow_fade_in();
-
- self.shadowoff = 0;
- } else {
- dprint("Fade out:\n");
-
- misc_shadowcontroller_setsteps(self.speed2);
-
- shadow_fade_out();
-
- self.shadowoff = 1;
- }
-}
-
-void() misc_shadowcontroller = {
- entity t1;
-
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
-
- // doesn't search for a target if switchshadstyle is already set
- // used for built-in shadow controllers
- if(!self.switchshadstyle) {
-
- // we need to find only the first target entity with switchable shadows set, since shadow lightstyles are bound by targetname
-
-
- t1 = find(world, targetname2, self.target);
-
- while(t1 != world && !t1.switchshadstyle) {
- t1 = find(t1, targetname2, self.target);
- }
-
- if(t1 == world) {
- t1 = find(world, targetname, self.target);
-
- while(t1 != world && !t1.switchshadstyle) {
- t1 = find(t1, targetname, self.target);
- }
- }
-
-
- if(t1 == world) {
- dprint("\b[misc_shadowcontroller]\b _switchableshadow not set in target ");dprint(self.target);dprint("\n");
- return;
- }
-
- self.switchshadstyle = t1.switchshadstyle;
- }
-
- if(!self.speed) self.speed = 0.5;
- if(!self.speed2) self.speed2 = self.speed;
-
- if(self.spawnflags & SHADOWCONTROLLER_STARTOFF) {
- lightstyle(self.switchshadstyle, "m");
-
- self.shadowoff = 1;
- self.count = 12;
-
- misc_shadowcontroller_setsteps(self.speed2);
- }
- else {
- lightstyle(self.switchshadstyle, "a");
- self.shadowoff = 0;
- self.count = 0;
- misc_shadowcontroller_setsteps(self.speed);
- }
-
- self.use = misc_shadowcontroller_use;
-}
-
-
-/*
-misc_infight
-
-target = monster that gets mad
-target2 = who target1 will be angry at
-
-spawnflag 1 = mutual hate, both targets get angry at each other instantly
-spawnflag 2 = maintain activator, makes it so the player that triggers the infighting sees centerprints triggered by it
-*/
-
-float INFIGHT_MUTUAL = 1;
-float INFIGHT_PLAYER_ACTIVATION = 2;
-
-void(entity t1, entity t2) make_angry_at =
-{
- if (t2.health > 0 && t1.health > 0) { // checks if targets are alive
- if (t1.enemy.classname == "player")
- t1.oldenemy = t1.enemy;
- t1.enemy = t2;
-
- entity oself = self;
- self = t1; // FoundTarget() only acts on self
- FoundTarget();
- self = oself;
- }
-};
-
-void() misc_infight_use =
-{
- local entity t1, t2;
-
- for (t1 = world; (t1 = find(t1, targetname, self.target)); )
- {
- for (t2 = world; (t2 = find(t2, targetname, self.target2)); )
- {
- // t1 = find(world, targetname, self.target);
- // t2 = find(world, targetname, self.target2);
-
- if (!t1)
- {
- dprint("[trigger_infight] Cannot find target, checking targetname2\n");
- t1 = find(world, targetname2, self.target);
- }
- if (!t1)
- {
- dprint("[trigger_infight] Cannot find target, checking targetname3\n");
- t1 = find(world, targetname3, self.target);
- }
- if (!t1)
- {
- dprint("[trigger_infight] Cannot find target, checking targetname4\n");
- t1 = find(world, targetname4, self.target);
- }
- if (!t1)
- {
- dprint("[trigger_infight] Cannot find target, exhausted all targetnames\n");
- return;
- }
- if (!t2)
- {
- dprint("[trigger_infight] Cannot find target2 checking targetname2\n");
- t2 = find(world, targetname2, self.target2);
- }
- if (!t2)
- {
- dprint("[trigger_infight] Cannot find target2 checking targetname3\n");
- t2 = find(world, targetname3, self.target2);
- }
- if (!t2)
- {
- dprint("[trigger_infight] Cannot find target2 checking targetname4\n");
- t2 = find(world, targetname4, self.target2);
- }
- if (!t2)
- {
- dprint("[trigger_infight] Cannot find target2, exhausted all targetnames\n");
- return;
- }
-
- make_angry_at(t1, t2);
-
- if (self.spawnflags & INFIGHT_PLAYER_ACTIVATION)
- {
- t1.infight_activator = activator;
- t2.infight_activator = activator;
- }
-
- if (self.spawnflags & INFIGHT_MUTUAL)
- make_angry_at(t2, t1);
- }
- }
-};
-
-void() misc_infight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = misc_infight_use;
-};
-
-
-
-
-
-//============================================================================
-/*QUAKED ambient_suck_wind (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_suck_wind =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/suck1.wav");
- ambientsound (self.origin, "ambience/suck1.wav", 1, ATTN_STATIC);
-};
-
-/*QUAKED ambient_drone (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_drone =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/drone6.wav");
- ambientsound (self.origin, "ambience/drone6.wav", 0.5, ATTN_STATIC);
-};
-
-/*QUAKED ambient_flouro_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_flouro_buzz =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/buzz1.wav");
- ambientsound (self.origin, "ambience/buzz1.wav", 1, ATTN_STATIC);
-};
-/*QUAKED ambient_drip (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_drip =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/drip1.wav");
- ambientsound (self.origin, "ambience/drip1.wav", 0.5, ATTN_STATIC);
-};
-/*QUAKED ambient_comp_hum (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-*/
-void() ambient_comp_hum =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/comp1.wav");
- ambientsound (self.origin, "ambience/comp1.wav", 1, ATTN_STATIC);
-};
-/*QUAKED ambient_light_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_light_buzz =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/fl_hum1.wav");
- ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC);
-};
-/*QUAKED ambient_swamp1 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_swamp1 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/swamp1.wav");
- ambientsound (self.origin, "ambience/swamp1.wav", 0.5, ATTN_STATIC);
-};
-/*QUAKED ambient_swamp2 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_swamp2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/swamp2.wav");
- ambientsound (self.origin, "ambience/swamp2.wav", 0.5, ATTN_STATIC);
-};
-/////////////////////////////////////////////////////////////
-////////// dumptruck_ds ////////////////////////////////////
-///////////////////////////////////////////////////////////
-
-/* Additions to Ambient Sound effects. These are hard coded into the engine and
- usually play back automatically when the sky or water textures are used. If
- you'd prefer to use these in custom setups, you can use the command line
- switch -nomabient in when you VIS your map to disable the hard coded sounds. */
-
-/*QUAKED ambient_water1 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_water1 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/water1.wav");
- ambientsound (self.origin, "ambience/water1.wav", 1, ATTN_STATIC);
-};
-/*QUAKED ambient_wind2 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_wind2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/wind2.wav");
- ambientsound (self.origin, "ambience/wind2.wav", 1, ATTN_STATIC);
-};
-/////////////////////////////////////////////////////////////
-////////// dumptruck_ds ////////////////////////////////////
-///////////////////////////////////////////////////////////
-
-/* The original ambient_thunder was included in Quake but the code was missing.
- This version is borrowed from the Zerstörer mod but modified to only play the
- original thumder1.wav included in the game. This is also different than the
- other ambient sounds as it plays back randomly as opposed to looping. You
- only need one of these in your level. It will play everywhere. */
-
-void() thunder_go_boom =
-{
- if (random() < 0.5)
- sound (self, CHAN_AUTO, "ambience/thunder1.wav", 0.7, ATTN_NONE);
- else
- sound (self, CHAN_AUTO, "ambience/thunder1.wav", 1, ATTN_NONE);
-
- self.think = thunder_go_boom;
- self.nextthink = time + 40*random();
-};
-
-/*QUAKED ambient_thunder (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-The original ambient_thunder was included in Quake but the code was missing.
-This version is borrowed from the Zerstörer mod but modified to only play the
-original thumder1.wav included in the game. This is also different than the
-other ambient sounds as it plays back randomly as opposed to looping. You
-only need one of these in your level. It will play everywhere.
-*/
-void() ambient_thunder =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- // changed from ambient to delayed sound (sounds better)
- precache_sound ("ambience/thunder1.wav");
- // precache_sound ("ambience/thunder2.wav"); this file in not included in the game
- self.think = thunder_go_boom;
- self.nextthink = time + random();
-};
-
-
-
-//============================================================================
-
-void() noise_think =
-{
- self.nextthink = time + 0.5;
- sound (self, 1, "enforcer/enfire.wav", 1, ATTN_NORM);
- sound (self, 2, "enforcer/enfstop.wav", 1, ATTN_NORM);
- sound (self, 3, "enforcer/sight1.wav", 1, ATTN_NORM);
- sound (self, 4, "enforcer/sight2.wav", 1, ATTN_NORM);
- sound (self, 5, "enforcer/sight3.wav", 1, ATTN_NORM);
- sound (self, 6, "enforcer/sight4.wav", 1, ATTN_NORM);
- sound (self, 7, "enforcer/pain1.wav", 1, ATTN_NORM);
-};
-
-/*QUAKED misc_noisemaker (1 0.5 0) (-10 -10 -10) (10 10 10) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-For optimzation testing, starts a lot of sounds.
-*/
-
-void() misc_noisemaker =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound2 ("enforcer/enfire.wav");
- precache_sound2 ("enforcer/enfstop.wav");
- precache_sound2 ("enforcer/sight1.wav");
- precache_sound2 ("enforcer/sight2.wav");
- precache_sound2 ("enforcer/sight3.wav");
- precache_sound2 ("enforcer/sight4.wav");
- precache_sound2 ("enforcer/pain1.wav");
- precache_sound2 ("enforcer/pain2.wav");
- precache_sound2 ("enforcer/death1.wav");
- precache_sound2 ("enforcer/idle1.wav");
-
- self.nextthink = time + 0.1 + random();
- self.think = noise_think;
-};
-
-
-/***********************************************
-
-target_autosave
-from Copper
-
-***********************************************/
-
-void() target_autosave_use =
-{
- if (self.enemy)
- {
- activator = self.enemy;
- self.enemy = world;
- }
- if (activator.classname != "player") return;
- if (time < 2) // make sure an autosave fired from a player start doesn't happen too early
- {
- //if (serverflags & SVFL_RESPAWNING)
- //{
- // dprint("RESPAWNING flag set, skipping autosave\n");
- // return;
- //}
- self.enemy = activator;
- self.think = target_autosave_use;
- self.nextthink = 2;
- return;
- }
- // sound(activator, CHAN_VOICE, "misc/sav.wav", 0.3, ATTN_NORM);
- autosave(activator, self.message);
-}
-
-void() toggle_autosave =
-{
- entity e = world;
- float printed = FALSE;
- do {
- e = find(e, classname, "target_autosave");
- if (!e) break;
-
- if (e.use == target_autosave_use)
- {
- e.use = SUB_Null;
- if (!printed)
- {
- bprint("Autosaves disabled\n");
- printed = TRUE;
- }
- } else {
- e.use = target_autosave_use;
- if (!printed)
- {
- bprint("Autosaves reenabled\n");
- printed = TRUE;
- }
- }
-
- } while (e != world);
-}
-
-/*QUAKED target_autosave (1 .0 .5) (-8 -8 -8) (8 8 8)
-Saves the game when triggered by a player. Never appears in multiplayer. the bprint tends to stomp any other prints on screen in most quake clients, so use a delayed trigger_relay if you fire this from an important pickup/trigger_counter/something else that puts text on screen more important than the autosave blurb.
-
-Keys:
-"message" change save file name, defaults to 'auto'
-*/
-/*FGD
-@Pointclass base(Target, Targetname, Appearflags) color(255 0 128) size(32 32 32) = target_autosave :
-"Saves the game when triggered by a player. Never appears in multiplayer.
-the bprint tends to stomp any other prints on screen in most quake clients, so use a delayed trigger_relay if you fire this from an important pickup/trigger_counter/something else that puts text on screen more important than the autosave blurb."
-[
- message(string) : "Change save filename" : "auto"
-]
-*/
-void() target_autosave =
-{
- if (deathmatch || coop)
- {
- remove(self);
- return;
- }
-
-
- if (self.message == string_null)
- self.message = "auto";
- // precache_sound2("misc/sav.wav");
- self.use = target_autosave_use;
-}
-
-
-/*
-=============================================================
-
-trigger_textstory
-
-=============================================================
-*/
-
-float TEXTSTORY_SILENT = 1;
-float TEXTSTORY_NOFADE = 2;
-
-void(entity controller) textstory_hide = {
- if (!self.enemy || !(self.enemy.flags & FL_CLIENT)) return;
-
- self.enemy.suppressCenterPrint = FALSE;
- centerprint(self.enemy, "");
-
- if (controller.noise2)
- sound(self.enemy, CHAN_BODY, controller.noise2, 1, ATTN_NORM);
-
- if (!(controller.spawnflags & TEXTSTORY_NOFADE))
- csf_fade(self.enemy, 0, '0 0 0', 0.5);
-
-};
-
-void(entity controller) textstory_show = {
- if (!self.enemy || !(self.enemy.flags & FL_CLIENT)) return;
-
- self.enemy.suppressCenterPrint = TRUE;
-
- centerprint_builtin(self.enemy, controller.message);
-
- if (!self.state) {
- if (controller.noise1)
- sound(self.enemy, CHAN_BODY, controller.noise1, 1, ATTN_NORM);
-
- if (!(controller.spawnflags & TEXTSTORY_NOFADE))
- if (!self.fade_amt) //custom fade amount --dumptruck_ds
- {
- csf_fade(self.enemy, 160, '0 0 0', 1);
- }
- else
- csf_fade(self.enemy, self.fade_amt, '0 0 0', 1);
- }
-
-
- self.state = 1;
-};
-
-//----------------------------------------
-
-void() trigger_textstory_hide = {
- textstory_hide(self);
-
- self.enemy = world;
- self.state = 0;
-};
-
-void() trigger_textstory_show = {
- textstory_show(self);
-
- self.think = trigger_textstory_hide;
- self.nextthink = time + 0.2;
-
-};
-
-void() trigger_textstory_touch = {
-
- if (!(other.flags & FL_CLIENT)) return;
- if (self.estate != STATE_ACTIVE) return;
-
- // don't show message if another player is already triggering it
- if (other != self.enemy && self.state == 1) return;
-
- if (self.mangle && !isInAngle(other.v_angle, self.mangle, self.view_ofs))
- return;
-
- if (self.attack_finished < time) {
-
- self.attack_finished = time + 0.1;
- self.enemy = other;
-
- trigger_textstory_show();
- }
-};
-
-void() trigger_textstory = {
- InitTrigger();
- self.touch = trigger_textstory_touch;
-
- if (self.view_ofs == '0 0 0')
- self.view_ofs = '90 90 0';
-
- if (self.mangle) self.mangle = normalizeAngles180(self.mangle);
-
- if (self.noise1 == "")
- self.noise1 = "misc/talk.wav";
-
- if (self.noise2 == "")
- self.noise2 = "misc/null.wav";
-
- if (self.spawnflags & TEXTSTORY_SILENT) {
- self.noise1 = "";
- self.noise2 = "";
- }
-
-
- if (self.noise1 != "")
- precache_sound (self.noise1);
- if (self.noise2 != "")
- precache_sound (self.noise2);
-
- SUB_CheckWaiting();
-};
-
-
-//-----------------------------
-
-
-void() target_textstory_helper_hide = {
-
- textstory_hide(self.owner);
- remove(self);
-};
-
-void() target_textstory_helper_show = {
- if (!self.enemy || !(self.enemy.flags & FL_CLIENT)) {
- remove(self);
- return;
- }
-
- textstory_show(self.owner);
-
- if (self.attack_finished < time) self.think = target_textstory_helper_hide;
-
- self.nextthink = time + 0.1;
-};
-
-void(entity tgt) target_textstory_spawn_helper = {
- entity e;
-
- e = spawn();
- e.classname = "target_textstory_helper";
- e.owner = self;
- e.think = target_textstory_helper_show;
- e.nextthink = time + 0.1;
- e.attack_finished = time + self.wait;
- e.enemy = tgt;
-};
-
-void() target_textstory_use = {
-
- if (!(activator.flags & FL_CLIENT)) return;
- if (self.estate != STATE_ACTIVE) return;
-
- entity t;
-
- if (self.spawnflags & TRIGGER_CENTERPRINTALL) {
- t = find(world, classname, "player");
- while (t) {
- target_textstory_spawn_helper(t);
- t = find(t, classname, "player");
- }
- }
- else
- target_textstory_spawn_helper(activator);
-};
-
-void() target_textstory = {
- if (self.noise1 == "")
- self.noise1 = "misc/talk.wav";
-
- if (self.noise2 == "")
- self.noise2 = "misc/null.wav";
-
- if (self.spawnflags & TEXTSTORY_SILENT) {
- self.noise1 = "";
- self.noise2 = "";
- }
-
- if (self.noise1 != "")
- precache_sound (self.noise1);
- if (self.noise2 != "")
- precache_sound (self.noise2);
-
- if (!self.wait)
- self.wait = 5;
-
- self.use = target_textstory_use;
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/misc_model.qc

diff --git a/qc-server/misc_model.qc b/qc-server/misc_model.qc
deleted file mode 100644
index 833b3dd..0000000
--- a/qc-server/misc_model.qc
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * misc_model.qc requires math.qc
- *
- * Author: Joshua Skelton joshua.skelton@gmail.com
- * Edited by: Inky 20201219 Minor changes for a better integration with my own code
- * Edited by: bmFbr for solid and gravity spawnflags and custom bbox sizes
- * Edited by: dumptruck_ds to add start and stop animations
- */
-
-// The starting frame of the animation
-.float first_frame;
-
-// The ending frame of the animation
-.float last_frame;
-
-// Forward declarations
-void() misc_model_think;
-
-/*QUAKED misc_model (0 0.5 0.8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path" : mdl, "skin" : skin, "frame": frame});
-}
-An entity for displaying models. A frame range can be given to animate the
-model.
-
-mdl: The model to display. Can be of type mdl, bsp, or spr.
-
-frame: The frame to display. Can be used to offset the animation.
-
-first_frame: The starting frame of the animation.
-
-last_frame: The last frame of the animation.
-*/
-
-float MISC_MODEL_GRAVITY = 1;
-float MISC_MODEL_SOLID = 2;
-float MISC_MODEL_BACK_AND_FORTH = 4;
-float MISC_MODEL_ONLY_ONCE = 8;
-float MISC_MODEL_PLAY_COUNT = 16;
-float MISC_MODEL_STARTOFF = 32;
-
-
-void() misc_model_use = {
- if (self.state == STATE_ACTIVE) {
- if (self.spawnflags & MISC_MODEL_SOLID) self.solid = SOLID_NOT;
- self.model = "";
-
- self.state = STATE_INVISIBLE;
- setorigin(self, self.origin);
- }
- else {
- if (self.spawnflags & MISC_MODEL_SOLID) self.solid = SOLID_BBOX;
- self.model = self.mdl;
-
- self.state = STATE_ACTIVE;
- setorigin(self, self.origin);
- }
-};
-
-void() misc_model = {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.mdl || self.mdl == "")
- objerror("Model not defined");
-
- if(!self.centeroffset) self.centeroffset = '0 0 0';
- if(!self.mdlsz) self.mdlsz = '32 32 32';
-
- vector vmin, vmax;
-
- vmin_x = self.centeroffset_x - (self.mdlsz_x / 2);
- vmin_y = self.centeroffset_y - (self.mdlsz_y / 2);
- vmin_z = self.centeroffset_z - (self.mdlsz_z / 2);
-
- vmax_x = self.centeroffset_x + (self.mdlsz_x / 2);
- vmax_y = self.centeroffset_y + (self.mdlsz_y / 2);
- vmax_z = self.centeroffset_z + (self.mdlsz_z / 2);
-
- precache_model(self.mdl);
- setmodel(self, self.mdl);
-
- setsize(self, vmin, vmax);
-
- if(self.spawnflags & MISC_MODEL_SOLID) self.solid = SOLID_BBOX;
- else self.solid = SOLID_NOT;
-
- if(self.spawnflags & MISC_MODEL_GRAVITY) self.movetype = MOVETYPE_TOSS;
- else self.movetype = MOVETYPE_NONE;
-
- self.use = misc_model_use;
-
- if (!self.frame) {
- self.frame = self.first_frame;
- }
-
- // Make static (not animate) if not given a frame range, and not affected by gravity
- // also remains active if it has a targetname (so it can be killtargeted/toggled)
- if (!self.last_frame
- && !(self.spawnflags & MISC_MODEL_GRAVITY)
- && !(self.spawnflags & MISC_MODEL_SOLID)
- && !self.targetname
- && !self.targetname2
- // && !(self.spawnflags & MISC_MODEL_DONTMAKESTATIC)
- ) makestatic(self);
- // Make static (not animate) if not given a frame range, and not affected by gravity
- //changed by bmFbr
- // if (!self.last_frame && !(self.spawnflags & MISC_MODEL_GRAVITY)) {
- // makestatic(self);
- // return;
- // }
-
- if (self.last_frame) { // if it as a custom animation range
- // Default animation speed to 10 fps
- if (!self.speed) {
- self.speed = 0.1;
- }
- self.nextthink = time + self.speed;
- self.think = misc_model_think;
- }
-
- if (self.spawnflags & MISC_MODEL_STARTOFF)
- self.state = STATE_ACTIVE;
- else
- self.state = STATE_INVISIBLE;
-
- misc_model_use();
-
-};
-
-/*
- * misc_model_think
- *
- * Handles animation for misc_model entity.
- */
-void() misc_model_think = {
- self.nextthink = time + fabs(self.speed);
- if (self.estate != STATE_ACTIVE) return;
-
- self.frame = self.frame + sign(self.speed);
-
- if (self.spawnflags & MISC_MODEL_BACK_AND_FORTH && self.frame < self.first_frame)
- {
- self.speed = -1 * self.speed;
- self.frame+=2;
- }
- else if (self.spawnflags & MISC_MODEL_BACK_AND_FORTH && self.frame > self.last_frame)
- {
- self.speed = -1 * self.speed;
- self.frame-=2;
- }
- else
- self.frame = wrap(self.frame, self.first_frame, self.last_frame);
-
- if(self.spawnflags & MISC_MODEL_ONLY_ONCE && self.frame==self.last_frame && self.last_frame!=self.first_frame)
- self.nextthink = -1;
-
- if(self.spawnflags & MISC_MODEL_PLAY_COUNT && self.frame==self.last_frame && self.last_frame!=self.first_frame)
- {
- if !(self.count)
- objerror ("Error: set count to the number of animation cycles!");
- self.cnt = self.cnt +1;
- dprint (ftos(self.cnt));
- dprint ("\n");
- if (self.cnt != self.count)
- return FALSE;
- else
- self.nextthink = -1;
- }
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/mobot.qc

diff --git a/qc-server/mobot.qc b/qc-server/mobot.qc
deleted file mode 100644
index f0bf1a5..0000000
--- a/qc-server/mobot.qc
+++ /dev/null
@@ -1,500 +0,0 @@
-// Using "bot" creation code for func_monster_spawner
-// most of the code is from a tutorial on creating a bot monster found here:
-// https://www.quaddicted.com/webarchive/minion.planetquake.gamespy.com/tutorial/tutor9.htm
-// I added the MobotSpawnPoint, retriggering and random gen with help from
-// kreathor, 4LT, Paril, Spoike and others on the Quake Mapping Discord.
-// ===================================================================
-// Big thanks to ryanscissorhands for helping fix telefragging issues!
-// ===================================================================
-
-float MOBOT_SPAWNER_RESET = 1;
-float MOBOT_DONT_SPAWN_ANGRY = 2;
-float MOBOT_DONT_ADD_KILL_COUNT = 4;
-float MOBOT_SILENT_SPAWN = 32;
-
-/*
-============
-MobotSpawnPoint
-
-Returns the entity to spawn at
-============
-*/
-entity() MobotSpawnPoint =
-{
- local entity spot;
-
- // spot = find (world, classname, "info_monster_spawnpoint");
- spot = find (world, targetname, self.target);
-
- if (!spot)
- objerror ("couldn't find target");
-
- return spot;
-};
-
-// ------------------------------------------------
-void() create_mobot =
-// ------------------------------------------------
-{
-
-local entity bot, spawn_spot;
-
-// start entity and place it in world
- bot = spawn();
- spawn_spot = MobotSpawnPoint();
- // spawn_spot = SelectSpawnPoint (); // let's not use deathmatch points for this -- dumptruck_ds
- bot.origin = spawn_spot.origin + '0 0 1';
- bot.angles = spawn_spot.angles;
- bot.fixangle = TRUE;
- bot.proj_speed_mod = 1;
- if (!(self.spawnflags & MOBOT_SILENT_SPAWN)) // SILENT
- spawn_tfog (bot.origin);
- spawn_tdeath (bot.origin, bot);
-
- if (self.style == 1) // spawn a Doggo
- {
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel(bot, "progs/dog.mdl");
- setsize (bot, '-32 -32 -24', '32 32 40');
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = dog_stand1;
- bot.th_walk = dog_walk1;
- bot.th_run = dog_run1;
- bot.th_die = dog_die;
- bot.th_melee = dog_atta1;
- bot.th_missile = dog_leap1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- bot.th_pain = dog_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 25;
-
- // polish him up
- bot.classname = "monster_dog";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- }
-
-if (self.style == 2) // spawn a Grunt
- {
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel(bot, "progs/soldier.mdl");
- setsize (bot, '-16 -16 -24', '16 16 40');
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = army_stand1;
- bot.th_walk = army_walk1;
- bot.th_run = army_run1;
- bot.th_die = army_die;
- // bot.th_melee = ogre_melee;
- bot.th_missile = army_atk1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- bot.th_pain = army_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 80;
-
- // polish him up
- bot.classname = "monster_army";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- }
-
-if (self.style == 3) // spawn an Enforcer
- {
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel(bot, "progs/enforcer.mdl");
- setsize (bot, VEC_HULL2_MIN, VEC_HULL2_MAX);
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = enf_stand1;
- bot.th_walk = enf_walk1;
- bot.th_run = enf_run1;
- bot.th_die = enf_die;
- // bot.th_melee = ogre_melee;
- bot.th_missile = enf_atk1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- bot.th_pain = enf_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 80;
-
- // polish him up
- bot.classname = "monster_enforcer";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- }
-
-if (self.style == 4) // spawn an Ogre
- {
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel(bot, "progs/ogre.mdl");
- setsize (bot, VEC_HULL2_MIN, VEC_HULL2_MAX);
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = ogre_stand1;
- bot.th_walk = ogre_walk1;
- bot.th_run = ogre_run1;
- bot.th_die = ogre_die;
- bot.th_melee = ogre_melee;
- bot.th_missile = ogre_nail1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- bot.th_pain = ogre_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 200;
-
- // polish him up
- bot.classname = "monster_ogre";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- }
-
-if (self.style == 5) // spawn an Fiend
- {
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel(bot, "progs/demon.mdl");
- setsize (bot, VEC_HULL2_MIN, VEC_HULL2_MAX);
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = demon1_stand1;
- bot.th_walk = demon1_walk1;
- bot.th_run = demon1_run1;
- bot.th_die = demon_die;
- bot.th_melee = Demon_MeleeAttack; // one of two attacks
- bot.th_missile = demon1_jump1; // jump attack
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- bot.th_pain = demon1_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 300;
-
- // polish him up
- bot.classname = "monster_demon1";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- }
-
-if (self.style == 6) // spawn a Wizard / Scrag
- {
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel(bot, "progs/wizard.mdl");
- setsize (bot, '-16 -16 -24', '16 16 40');
- bot.flags = bot.flags | FL_FLY;
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = wiz_stand1;
- bot.th_walk = wiz_walk1;
- bot.th_run = wiz_run1;
- bot.th_die = wiz_die;
- bot.th_missile = Wiz_Missile;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- bot.th_pain = Wiz_Pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 80;
-
- // polish him up
- bot.classname = "monster_wizard";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- bot.mdl_proj = "progs/w_spike.mdl";
-
- }
-
- if (self.style == 7) // spawn a Shambler
- {
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel(bot, "progs/shambler.mdl");
- setsize (bot, '-16 -16 -24', '16 16 40');
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = sham_stand1;
- bot.th_walk = sham_walk1;
- bot.th_run = sham_run1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- bot.th_pain = sham_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.th_die = sham_die;
- bot.th_missile = sham_magic1;
- bot.th_melee = sham_melee;
- bot.health = 600;
-
- // polish him up
- bot.classname = "monster_shambler";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 2';
- // bot.view_ofs = '0 0 22';
- }
-
-if (self.style == 8) // spawn a Knight
- {
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel(bot, "progs/knight.mdl");
- setsize (bot, '-16 -16 -24', '16 16 40');
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = knight_stand1;
- bot.th_walk = knight_walk1;
- bot.th_run = knight_run1;
- bot.th_die = knight_die;
- bot.th_melee = knight_atk1;
- // bot.th_missile = knight_atk1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- bot.th_pain = knight_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 75;
-
- // polish him up
- bot.classname = "monster_knight";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- }
-
-if (self.style == 9) // spawn a HellKnight
- {
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel(bot, "progs/hknight.mdl");
- setsize (bot, '-16 -16 -24', '16 16 40');
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = hknight_stand1;
- bot.th_walk = hknight_walk1;
- bot.th_run = hknight_run1;
- bot.th_melee = hknight_melee;
- bot.th_die = hknight_die;
- bot.th_missile = hknight_magicc1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- bot.th_pain = hknight_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 250;
-
- // polish him up
- bot.classname = "monster_hell_knight";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- }
-
-if (self.style == 11) // spawn a Zombie
- {
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel(bot, "progs/zombie.mdl");
- setsize (bot, '-16 -16 -24', '16 16 40');
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = zombie_start;
- bot.th_walk = zombie_walk1;
- bot.th_run = zombie_decide;
- bot.th_pain = zombie_pain;
- bot.th_die = zombie_die;
- bot.th_missile = zombie_missile;
- bot.health = 61;
-
- // polish him up
- bot.classname = "monster_zombie";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 2';
- // bot.view_ofs = '0 0 22';
- }
-if (self.style == 12) // spawn a Shalrath
- {
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel(bot, "progs/shalrath.mdl");
- setsize (bot, VEC_HULL2_MIN, VEC_HULL2_MAX);
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = shal_stand;
- bot.th_walk = shal_walk1;
- bot.th_run = shal_run1;
- bot.th_die = shalrath_die;
- bot.th_missile = shal_attack1;
- bot.homing = 1; //fix for func_monster_spawner setting Voreballs to non-homing
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- bot.th_pain = shalrath_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 400;
-
- // polish him up
- bot.classname = "monster_shalrath";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- }
-
-// begin his thinking
- bot.nextthink = time + 0.2; // this seems better with monster_use -- dumptruck_ds
- // bot.nextthink = time + 0.1 + random();
- if (!(self.spawnflags & MOBOT_DONT_SPAWN_ANGRY))
- {
- if (bot.classname != "monster_zombie") // required to avoid animation issues -- dumptruck_ds
- bot.think = monster_use;
- else
- bot.think = bot.th_walk;
- }
- else
- {
- bot.think = walkmonster_start_go;
- }
- if (!(self.spawnflags & MOBOT_DONT_ADD_KILL_COUNT))
- {
- monster_update_total (1); // repacement function from iw -- dumptruck_ds
- }
-};
-
-void() think_mobot =
- {
- dprint("mobot thinking\n");
- local entity nearby; // telefrag check thanks to ryanscissorhands for this code! -- dumptruck_ds
-
- nearby = findradius(self.origin, 128); // findradius (vector origin, float radius in Quake units)
-
- while (nearby)
- {
- if (nearby.takedamage)
- {
- dprint("monster waiting to spawn\n");
- self.think = think_mobot; // qss crash fix from paavohuhtala -- dumptruck_ds
- self.nextthink = time + 1; //delay the spawn by some amount;
- return;
- }
- nearby = nearby.chain;
- }
-
- self.count = self.count - 1;
-
- if (self.count < 0)
- {
- return;
- }
- if (self.count!=0)
- {
- if !(self.wait)
- self.nextthink = time + 5;
- else
- self.nextthink = time + self.wait;
-
- if (self.style2 == 1)
- {
- self.style = floor(random() * 12) + 1; // random monster!! -- dumptruck_ds
- create_mobot(); //thanks whirledtsar for your help on this -- dumptruck_ds
- }
- else
- create_mobot();
- }
- else {
- if (self.spawnflags & MOBOT_SPAWNER_RESET)
- {
- self.count = self.cnt;
- self.think = SUB_Null;
- }
- }
-
- self.think = think_mobot; // qthink I didn't realize I could do this! -- dumptruck_ds
- };
-
-/*QUAKED func_monster_spawner (.75 0 .75) (-8 -8 -8) (8 8 8) REUSABLE X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Spawns monsters to targeted info_monster_spawnpoint
-bot
-Choose Style
-• 1 (Dog (Default)
-• 2 (Grunt)
-• 3 (Enforcer)
-• 4 (Ogre)
-• 5 (Fiend)
-• 6 (Wizard)
-• 7 (Shambler)
-• 8 (Knight)
-• 9 (HellKnight)
-• 10 (Spawn)
-• 11 (Zombie)
-• 12 (Shalrath)
-
-Style 2 set to 1 overrides Style and chooses a random monster (excluding Zombies and Vores)
-
-Default time between spawns is 5 seconds; 12 for Zombies and Vores to reduce telefrags
-
-Can set Berserk to 1 to skip most pain animations.
-
-Can only use default health, models and sounds.
-*/
-void() func_monster_spawner =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if !(self.target)
- {
- objerror("func_monster_spawner needs a target");
- remove(self);
- return;
- }
-
- if !(self.style)
- self.style = 1;
-
- if (!self.count)
- self.count = 5;
- self.count = self.count + 1; // fixes count display
- self.cnt = self.count; // hold original count
-
- self.use = think_mobot;
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/monsters.qc

diff --git a/qc-server/monsters.qc b/qc-server/monsters.qc
deleted file mode 100644
index cc045ce..0000000
--- a/qc-server/monsters.qc
+++ /dev/null
@@ -1,518 +0,0 @@
-/* ALL MONSTERS SHOULD BE 1 0 0 IN COLOR */
-
-// name =[framenum, nexttime, nextthink] {code}
-// expands to:
-// name ()
-// {
-// self.frame=framenum;
-// self.nextthink = time + nexttime;
-// self.think = nextthink
-// <code>
-// };
-
-/*
-================
-monster_update_total
-
-Call this function to safely update total_monsters when the game is in
-progress. It adds "n" to total_monsters, then notifies all clients of
-the change. -- iw
-================
-*/
-void(float n) monster_update_total =
-{
- total_monsters = total_monsters + n;
-
- WriteByte (MSG_ALL, SVC_UPDATESTAT);
- WriteByte (MSG_ALL, STAT_TOTALMONSTERS);
- WriteLong (MSG_ALL, total_monsters);
-};
-
-/* From Preach's tutorial here: https://tomeofpreach.wordpress.com/2017/10/08/teleporting-monsters-flag/#more-2281 */
-
-//define Preach's new fields dumptruck_ds
-
-.string tele_model;
-.vector tele_mins;
-.vector tele_maxs;
-.float tele_solid;
-.float tele_movetype;
-
-void(vector org) spawn_tfog;
-void(vector org, entity death_owner) spawn_tdeath;
-
-void() monster_teleport_go =
-{
-self.solid = self.tele_solid;
-self.movetype = self.tele_movetype;
-setmodel(self, self.tele_model);
-setsize (self, self.tele_mins, self.tele_maxs);
-
-self.delay = 0; //fix for cumulative delays for counters etc. -- dumptruck_ds
-
-self.think1();
-//override the random delay some go functions apply
-self.nextthink = time + 0.1;
- {
- if !(self.spawnflags & SPAWN_SILENTLY)
- {
- if (self.wait == 0) //dumptruck_ds: if wait value is > 0 spawn silently or use a spawnflag
- spawn_tfog (self.origin);
- spawn_tdeath(self.origin, self);
- }
- }
-
-}
-
-void() monster_teleport_delay = //new from Qmaster func coding help thread
-{
-self.think = monster_teleport_go;
- if (self.delay == -1)
- {
- self.nextthink = time + 0.1 + random(); //if delay is set to -1 random delay from 0.1 to 1 second - dumptruck_ds
- return;
- }
-self.nextthink = time + 0.1 + self.delay;
-};
-
-/*
-================
-monster_teleport_check
-
-This detects and eliminates a common map bug: a trigger-spawned monster
-which can't be activated either because it has no targetname or because
-its targetname isn't targeted by any other entity. (This map bug would
-otherwise make it impossible for the player to get 100% kills.) -- iw
-================
-*/
-void() monster_teleport_check =
-{
- if (!SUB_IsTargeted ())
- {
- dprint ("WARNING: removed untargeted trigger-spawned ");
- dprint (self.classname);
- dprint (" at ");
- dprint (vtos (self.origin));
- dprint ("\n");
-
- remove (self);
- return;
- }
-
- // the targetname appears to be OK, so let's finish setting up the
- // trigger-spawned monster -- iw
- self.use = monster_teleport_delay; // qmaster
- monster_update_total (1);
-};
-
-float (void() monster_start_fn) monster_teleport =
-{
-if(!(self.spawnflags & 8))
- return FALSE;
-
-//PREACH: This monster is to be teleported in, so hide it
-self.tele_model= self.model;
-self.tele_mins = self.mins;
-self.tele_maxs = self.maxs;
-self.tele_solid = self.solid;
-self.tele_movetype = self.movetype;
-
-self.model = "";
-self.modelindex = 0;
-self.solid = SOLID_NOT;
-self.movetype = MOVETYPE_NONE;
-self.think1 = monster_start_fn;
-
-// wait for other entities to finish spawning, then check that
-// something targets this -- iw
-self.think = monster_teleport_check;
-self.nextthink = time + 0.1;
-
-return TRUE;
-}
-
-//end of Preach's new fields here
-
-// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
-/*
-================
-by: Philip Martin aka: Kryten
-When on top of monsters or players you slide. This is a QuakeC problem.
-The function below fixes that problem.
-based on code given to Kryten by: Michael Turitzin (MaNiAc)
-================
-*/
-void() monster_touch =
-{
- //can cause problems for monsters on top of a player, so only players
- if (other.classname != "player")
- return;
- if (other.health <= 0)
- return;
-
- if ((!(other.flags & FL_ONGROUND)) && ((other.absmin_z >= self.absmax_z - 2)))
- other.flags = other.flags + FL_ONGROUND;
-
- //you can add other stuff like pushable players/monsters here
-};
-// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
-
-/*
-================
-monster_use
-
-Using a monster makes it angry at the current activator
-================
-*/
-void() monster_use =
-{
- if (self.enemy)
- return;
- if (self.health <= 0)
- return;
- if (activator.items & IT_INVISIBILITY)
- return;
- if (activator.flags & FL_NOTARGET)
- return;
- if (activator.movetype == MOVETYPE_NOCLIP) // Copper -- dumptruck_ds
- return FALSE;
- if (activator.classname != "player")
- return;
-
-
-// delay reaction so if the monster is teleported, its sound is still
-// heard
- self.enemy = activator;
- self.nextthink = time + 0.1;
- self.think = FoundTarget;
-};
-
-/*
-================
-monster_death_use
-
-When a mosnter dies, it fires all of its targets with the current
-enemy as activator.
-================
-*/
-void() monster_death_use =
-{
-// fall to ground
- if (self.flags & FL_FLY)
- self.flags = self.flags - FL_FLY;
- if (self.flags & FL_SWIM)
- self.flags = self.flags - FL_SWIM;
-
- if (!self.target)
- return;
-
- if(self.infight_activator)
- {
- activator = self.infight_activator;
- }
- else
- {
- activator = self.enemy;
- }
- SUB_UseTargets ();
-};
-
-/*
-================
-monster_pain_use //dumptruck_ds
-
-When a monster reaches pain_threshold, it fires all of its pain_targets
-with the current enemy as activator.
-================
-*/
-void() monster_pain_use =
-{
- if (!self.pain_target)
- return;
-
- activator = self.enemy;
- SUB_UsePain ();
-};
-
-//============================================================================
-
-void() walkmonster_start_go =
-{
- self.origin_z = self.origin_z + 1; // raise off floor a bit
-//Preach's "check" here
-
-// if(time <= 0.5)
-if(!(self.spawnflags & 8))
-{
- droptofloor();
-
- if !(self.spawnflags & I_AM_TURRET) // fixes an incorrect dprint -- dumptruck_ds
- {
- if (!walkmove(0,0))
- {
- dprint ("\n\n");
- dprint (self.classname);
- dprint (" in wall at: ");
- dprint (vtos(self.origin));
- dprint ("\n\n");
- }
- }
-}
-
- self.takedamage = DAMAGE_AIM;
-
- self.ideal_yaw = self.angles * '0 1 0';
- if (!self.yaw_speed)
- self.yaw_speed = 20;
- self.view_ofs = '0 0 25';
- self.use = monster_use;
-
- self.flags = self.flags | FL_MONSTER;
-
- if (self.target != "")
- {
- self.goalentity = self.movetarget = find(world, targetname, self.target);
- self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
- if (!self.movetarget)
- {
- dprint ("Monster can't find target at ");
- dprint (vtos(self.origin));
- dprint ("\n");
- }
-// this used to be an objerror
- if (self.movetarget.classname == "path_corner")
- {
- self.th_walk ();
- }
- else
- {
- self.pausetime = 99999999;
- self.th_stand ();
- }
- }
- else
- {
- self.pausetime = 99999999;
- self.th_stand ();
- }
-
-// spread think times so they don't all happen at same time
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
-// self.nextthink = self.nextthink + random()*0.5;
- self.nextthink = time + 0.1 + random()*0.5;
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
- // if ((self.spawnflags & 8) && self.spawn_angry == 1) //dumptruck_ds -- using spawn_angry set to 1 in order to spawn in "angry" monsters
- // {
- // monster_use();
- // }
- local entity pl; //dumptruck_ds -- this is Shamblernaut's method
-
- pl = find (world, classname, "player");
-
- if (self.spawn_angry == 1)
- {
- activator = pl;
- monster_use();
- }
-};
-
-
-void() walkmonster_start =
-
- //Preach's tutorial
-{
-
- if (cvar("nomonsters")) {
- remove(self);
- return;
- }
-
- if(monster_teleport(walkmonster_start_go))
- return;
-
-// delay drop to floor to make sure all doors have been spawned
-// spread think times so they don't all happen at same time
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
-// self.nextthink = self.nextthink + random()*0.5;
- self.nextthink = time + 0.1 + random()*0.5;
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
- self.think = walkmonster_start_go;
- total_monsters = total_monsters + 1;
- /// Trigger enemy after spawn (khreathor)
-
-};
-
-
-
-void() flymonster_start_go =
-{
- self.takedamage = DAMAGE_AIM;
-
- self.ideal_yaw = self.angles * '0 1 0';
- if (!self.yaw_speed)
- self.yaw_speed = 10;
- self.view_ofs = '0 0 25';
- self.use = monster_use;
-
- self.flags = self.flags | FL_FLY;
- self.flags = self.flags | FL_MONSTER;
-
- if (!walkmove(0,0))
- {
- dprint ("flymonster in wall at: ");
- dprint (vtos(self.origin));
- dprint ("\n");
- }
-
- if (self.target != "")
- {
- self.goalentity = self.movetarget = find(world, targetname, self.target);
- if (!self.movetarget)
- {
- dprint ("Monster can't find target at ");
- dprint (vtos(self.origin));
- dprint ("\n");
- }
-// this used to be an objerror
- if (self.movetarget.classname == "path_corner")
- {
- self.th_walk ();
- }
- else
- {
- self.pausetime = 99999999;
- self.th_stand ();
- }
- }
- else
- {
- self.pausetime = 99999999;
- self.th_stand ();
- }
-
- self.nextthink = time + 0.1 + random()*0.5; // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol
-
-// if ((self.spawnflags & 8) && self.spawn_angry == 1) //dumptruck_ds -- using spawn_angry set to 1 in order to spawn in "angry" monsters
-// {
-// monster_use();
-// }
-//dumptruck_ds -- this is Shamblernaut's method
- local entity pl;
-
- pl = find (world, classname, "player");
-
- if (self.spawn_angry == 1)
- {
- activator = pl;
- monster_use();
- }
-
-};
-
-void() flymonster_start =
-{
- if (cvar("nomonsters")) {
- remove(self);
- return;
- }
-
- //Preach's tutorial
-
- if(monster_teleport(flymonster_start_go))
- return;
-
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
- self.flags = self.flags | FL_FLY; // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol
-
-// spread think times so they don't all happen at same time
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
-// self.nextthink = self.nextthink + random()*0.5;
- self.nextthink = time + 0.1 + random()*0.5;
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
- self.think = flymonster_start_go;
- total_monsters = total_monsters + 1;
-};
-
-
-void() swimmonster_start_go =
-{
- if (deathmatch)
- {
- remove(self);
- return;
- }
-
- self.takedamage = DAMAGE_AIM;
-
- self.ideal_yaw = self.angles * '0 1 0';
- if (!self.yaw_speed)
- self.yaw_speed = 10;
- self.view_ofs = '0 0 10';
- self.use = monster_use;
-
- self.flags = self.flags | FL_SWIM;
- self.flags = self.flags | FL_MONSTER;
-
- if (self.target != "")
- {
- self.goalentity = self.movetarget = find(world, targetname, self.target);
- if (!self.movetarget)
- {
- dprint ("Monster can't find target at ");
- dprint (vtos(self.origin));
- dprint ("\n");
- }
-// this used to be an objerror
- self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
- self.th_walk ();
- }
- else
- {
- self.pausetime = 99999999;
- self.th_stand ();
- }
-
-// spread think times so they don't all happen at same time
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
-// self.nextthink = self.nextthink + random()*0.5;
- self.nextthink = time + 0.1 + random()*0.5;
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
-// if ((self.spawnflags & 8) && self.spawn_angry == 1) //dumptruck_ds -- using spawn_angry set to 1 in order to spawn in "angry" monsters
-// {
-// monster_use();
-// }
-//dumptruck_ds -- this is Shamblernaut's method
- local entity pl;
-
- pl = find (world, classname, "player");
-
- if (self.spawn_angry == 1)
- {
- activator = pl;
- monster_use();
- }
-};
-
-void() swimmonster_start =
-{
- if (cvar("nomonsters")) {
- remove(self);
- return;
- }
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
- self.flags = self.flags | FL_SWIM; // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol
-
- //Preach's tutorial
-
- if(monster_teleport(swimmonster_start_go))
- return;
-
-// spread think times so they don't all happen at same time
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
-// self.nextthink = self.nextthink + random()*0.5;
- self.nextthink = time + 0.1 + random()*0.5;
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
- self.think = swimmonster_start_go;
- total_monsters = total_monsters + 1;
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/monsters/boss.qc

diff --git a/qc-server/monsters/boss.qc b/qc-server/monsters/boss.qc
deleted file mode 100644
index 9e88ac1..0000000
--- a/qc-server/monsters/boss.qc
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
-==============================================================================
-
-BOSS-ONE
-
-==============================================================================
-*/
-$cd id1/models/boss1
-$origin 0 0 -15
-$base base
-$skin skin
-$scale 5
-
-$frame rise1 rise2 rise3 rise4 rise5 rise6 rise7 rise8 rise9 rise10
-$frame rise11 rise12 rise13 rise14 rise15 rise16 rise17
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
-$frame walk9 walk10 walk11 walk12 walk13 walk14 walk15
-$frame walk16 walk17 walk18 walk19 walk20 walk21 walk22
-$frame walk23 walk24 walk25 walk26 walk27 walk28 walk29 walk30 walk31
-
-$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
-
-$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
-$frame attack9 attack10 attack11 attack12 attack13 attack14 attack15
-$frame attack16 attack17 attack18 attack19 attack20 attack21 attack22
-$frame attack23
-
-$frame shocka1 shocka2 shocka3 shocka4 shocka5 shocka6 shocka7 shocka8
-$frame shocka9 shocka10
-
-$frame shockb1 shockb2 shockb3 shockb4 shockb5 shockb6
-
-$frame shockc1 shockc2 shockc3 shockc4 shockc5 shockc6 shockc7 shockc8
-$frame shockc9 shockc10
-
-
-void(vector p) boss_missile;
-
-void() boss_face =
-{
-
-// go for another player if multi player
- if (self.enemy.health <= 0 || random() < 0.02)
- {
- self.enemy = find(self.enemy, classname, "player");
- if (!self.enemy)
- self.enemy = find(self.enemy, classname, "player");
- }
- ai_face();
-};
-
-void() boss_rise1 =[ $rise1, boss_rise2 ] {
-sound_move (self, CHAN_WEAPON, "boss1/out1.wav", 1, ATTN_NORM);
-};
-void() boss_rise2 =[ $rise2, boss_rise3 ] {
-sound_sight (self, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM);
-};
-void() boss_rise3 =[ $rise3, boss_rise4 ] {};
-void() boss_rise4 =[ $rise4, boss_rise5 ] {};
-void() boss_rise5 =[ $rise5, boss_rise6 ] {};
-void() boss_rise6 =[ $rise6, boss_rise7 ] {};
-void() boss_rise7 =[ $rise7, boss_rise8 ] {};
-void() boss_rise8 =[ $rise8, boss_rise9 ] {};
-void() boss_rise9 =[ $rise9, boss_rise10 ] {};
-void() boss_rise10 =[ $rise10, boss_rise11 ] {};
-void() boss_rise11 =[ $rise11, boss_rise12 ] {};
-void() boss_rise12 =[ $rise12, boss_rise13 ] {};
-void() boss_rise13 =[ $rise13, boss_rise14 ] {};
-void() boss_rise14 =[ $rise14, boss_rise15 ] {};
-void() boss_rise15 =[ $rise15, boss_rise16 ] {};
-void() boss_rise16 =[ $rise16, boss_rise17 ] {};
-void() boss_rise17 =[ $rise17, boss_missile1 ] {};
-
-void() boss_idle1 =[ $walk1, boss_idle2 ]
-{
-// look for other players
-};
-void() boss_idle2 =[ $walk2, boss_idle3 ] {boss_face();};
-void() boss_idle3 =[ $walk3, boss_idle4 ] {boss_face();};
-void() boss_idle4 =[ $walk4, boss_idle5 ] {boss_face();};
-void() boss_idle5 =[ $walk5, boss_idle6 ] {boss_face();};
-void() boss_idle6 =[ $walk6, boss_idle7 ] {boss_face();};
-void() boss_idle7 =[ $walk7, boss_idle8 ] {boss_face();};
-void() boss_idle8 =[ $walk8, boss_idle9 ] {boss_face();};
-void() boss_idle9 =[ $walk9, boss_idle10 ] {boss_face();};
-void() boss_idle10 =[ $walk10, boss_idle11 ] {boss_face();};
-void() boss_idle11 =[ $walk11, boss_idle12 ] {boss_face();};
-void() boss_idle12 =[ $walk12, boss_idle13 ] {boss_face();};
-void() boss_idle13 =[ $walk13, boss_idle14 ] {boss_face();};
-void() boss_idle14 =[ $walk14, boss_idle15 ] {boss_face();};
-void() boss_idle15 =[ $walk15, boss_idle16 ] {boss_face();};
-void() boss_idle16 =[ $walk16, boss_idle17 ] {boss_face();};
-void() boss_idle17 =[ $walk17, boss_idle18 ] {boss_face();};
-void() boss_idle18 =[ $walk18, boss_idle19 ] {boss_face();};
-void() boss_idle19 =[ $walk19, boss_idle20 ] {boss_face();};
-void() boss_idle20 =[ $walk20, boss_idle21 ] {boss_face();};
-void() boss_idle21 =[ $walk21, boss_idle22 ] {boss_face();};
-void() boss_idle22 =[ $walk22, boss_idle23 ] {boss_face();};
-void() boss_idle23 =[ $walk23, boss_idle24 ] {boss_face();};
-void() boss_idle24 =[ $walk24, boss_idle25 ] {boss_face();};
-void() boss_idle25 =[ $walk25, boss_idle26 ] {boss_face();};
-void() boss_idle26 =[ $walk26, boss_idle27 ] {boss_face();};
-void() boss_idle27 =[ $walk27, boss_idle28 ] {boss_face();};
-void() boss_idle28 =[ $walk28, boss_idle29 ] {boss_face();};
-void() boss_idle29 =[ $walk29, boss_idle30 ] {boss_face();};
-void() boss_idle30 =[ $walk30, boss_idle31 ] {boss_face();};
-void() boss_idle31 =[ $walk31, boss_idle1 ] {boss_face();};
-
-void() boss_missile1 =[ $attack1, boss_missile2 ] {boss_face();};
-void() boss_missile2 =[ $attack2, boss_missile3 ] {boss_face();};
-void() boss_missile3 =[ $attack3, boss_missile4 ] {boss_face();};
-void() boss_missile4 =[ $attack4, boss_missile5 ] {boss_face();};
-void() boss_missile5 =[ $attack5, boss_missile6 ] {boss_face();};
-void() boss_missile6 =[ $attack6, boss_missile7 ] {boss_face();};
-void() boss_missile7 =[ $attack7, boss_missile8 ] {boss_face();};
-void() boss_missile8 =[ $attack8, boss_missile9 ] {boss_face();};
-void() boss_missile9 =[ $attack9, boss_missile10 ] {boss_missile('100 100 200');};
-void() boss_missile10 =[ $attack10, boss_missile11 ] {boss_face();};
-void() boss_missile11 =[ $attack11, boss_missile12 ] {boss_face();};
-void() boss_missile12 =[ $attack12, boss_missile13 ] {boss_face();};
-void() boss_missile13 =[ $attack13, boss_missile14 ] {boss_face();};
-void() boss_missile14 =[ $attack14, boss_missile15 ] {boss_face();};
-void() boss_missile15 =[ $attack15, boss_missile16 ] {boss_face();};
-void() boss_missile16 =[ $attack16, boss_missile17 ] {boss_face();};
-void() boss_missile17 =[ $attack17, boss_missile18 ] {boss_face();};
-void() boss_missile18 =[ $attack18, boss_missile19 ] {boss_face();};
-void() boss_missile19 =[ $attack19, boss_missile20 ] {boss_face();};
-void() boss_missile20 =[ $attack20, boss_missile21 ] {boss_missile('100 -100 200');};
-void() boss_missile21 =[ $attack21, boss_missile22 ] {boss_face();};
-void() boss_missile22 =[ $attack22, boss_missile23 ] {boss_face();};
-void() boss_missile23 =[ $attack23, boss_missile1 ] {boss_face();};
-
-void() boss_shocka1 =[ $shocka1, boss_shocka2 ] {};
-void() boss_shocka2 =[ $shocka2, boss_shocka3 ] {};
-void() boss_shocka3 =[ $shocka3, boss_shocka4 ] {};
-void() boss_shocka4 =[ $shocka4, boss_shocka5 ] {};
-void() boss_shocka5 =[ $shocka5, boss_shocka6 ] {};
-void() boss_shocka6 =[ $shocka6, boss_shocka7 ] {};
-void() boss_shocka7 =[ $shocka7, boss_shocka8 ] {};
-void() boss_shocka8 =[ $shocka8, boss_shocka9 ] {};
-void() boss_shocka9 =[ $shocka9, boss_shocka10 ] {};
-void() boss_shocka10 =[ $shocka10, boss_missile1 ] {};
-
-void() boss_shockb1 =[ $shockb1, boss_shockb2 ] {};
-void() boss_shockb2 =[ $shockb2, boss_shockb3 ] {};
-void() boss_shockb3 =[ $shockb3, boss_shockb4 ] {};
-void() boss_shockb4 =[ $shockb4, boss_shockb5 ] {};
-void() boss_shockb5 =[ $shockb5, boss_shockb6 ] {};
-void() boss_shockb6 =[ $shockb6, boss_shockb7 ] {};
-void() boss_shockb7 =[ $shockb1, boss_shockb8 ] {};
-void() boss_shockb8 =[ $shockb2, boss_shockb9 ] {};
-void() boss_shockb9 =[ $shockb3, boss_shockb10 ] {};
-void() boss_shockb10 =[ $shockb4, boss_missile1 ] {};
-
-void() boss_shockc1 =[ $shockc1, boss_shockc2 ] {};
-void() boss_shockc2 =[ $shockc2, boss_shockc3 ] {};
-void() boss_shockc3 =[ $shockc3, boss_shockc4 ] {};
-void() boss_shockc4 =[ $shockc4, boss_shockc5 ] {};
-void() boss_shockc5 =[ $shockc5, boss_shockc6 ] {};
-void() boss_shockc6 =[ $shockc6, boss_shockc7 ] {};
-void() boss_shockc7 =[ $shockc7, boss_shockc8 ] {};
-void() boss_shockc8 =[ $shockc8, boss_shockc9 ] {};
-void() boss_shockc9 =[ $shockc9, boss_shockc10 ] {};
-void() boss_shockc10 =[ $shockc10, boss_death1 ] {};
-
-void() boss_death1 = [$death1, boss_death2] {
-sound_death (self, CHAN_VOICE, "boss1/death.wav", 1, ATTN_NORM);
-};
-void() boss_death2 = [$death2, boss_death3] {};
-void() boss_death3 = [$death3, boss_death4] {};
-void() boss_death4 = [$death4, boss_death5] {};
-void() boss_death5 = [$death5, boss_death6] {};
-void() boss_death6 = [$death6, boss_death7] {};
-void() boss_death7 = [$death7, boss_death8] {};
-void() boss_death8 = [$death8, boss_death9] {};
-void() boss_death9 = [$death9, boss_death10]
-{
- sound_move (self, CHAN_BODY, "boss1/out1.wav", 1, ATTN_NORM);
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-};
-
-void() boss_death10 = [$death9, boss_death10]
-{
- killed_monsters = killed_monsters + 1;
- WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // FIXME: reliable broadcast
- SUB_UseTargets ();
- remove (self);
-};
-
-void(vector p) boss_missile =
-{
- local vector offang;
- local vector org, vec, d;
- local float t;
-
- offang = vectoangles (self.enemy.origin - self.origin);
- makevectors (offang);
-
- org = self.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
-
-// lead the player on hard mode
- if (skill > 1)
- {
- t = vlen(self.enemy.origin - org) / 300;
- vec = self.enemy.velocity;
- vec_z = 0;
- d = self.enemy.origin + t * vec;
- }
- else
- {
- d = self.enemy.origin;
- }
-
- vec = normalize (d - org);
-
- launch_spike2 (org, vec, 300);
- // setmodel (newmis, "progs/lavaball.mdl");
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/lavaball.mdl");
- }
-
- if (!newmis.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
-
- newmis.avelocity = '200 100 300';
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- newmis.touch = T_MissileTouch; // rocket explosion
- sound_attack (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM);
-
-// check for dead enemy
- if (self.enemy.health <= 0)
- boss_idle1 ();
-};
-
-
-void() boss_awake =
-{
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
- self.takedamage = DAMAGE_NO;
-
- body_model ("progs/boss.mdl");
- // setmodel (self, "progs/boss.mdl"); //custom_mdl -- dumptruck_ds
- setsize (self, '-128 -128 -24', '128 128 256');
-
- if (skill == 0)
- self.health = 1;
- else
- self.health = 3;
-
- self.enemy = activator;
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- self.yaw_speed = 20;
- boss_rise1 ();
-};
-
-
-/*QUAKED monster_boss (1 0 0) (-128 -128 -24) (128 128 256)
-*/
-void() monster_boss =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- // precache_model ("progs/boss.mdl");
- precache_body_model ("progs/boss.mdl");
- precache_head_model ("progs/h_boss.mdl");
-
- precache_model ("progs/lavaball.mdl");
-
- precache_sound ("weapons/rocket1i.wav");
- precache_sound_move ("boss1/out1.wav");
- precache_sound_sight ("boss1/sight1.wav");
- precache_sound ("misc/power.wav");
- precache_sound_attack ("boss1/throw.wav");
- precache_sound_pain ("boss1/pain.wav");
- precache_sound_death ("boss1/death.wav");
-
- total_monsters = total_monsters + 1;
-
- self.flags = FL_MONSTER;
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
- self.use = boss_awake;
-};
-
-//===========================================================================
-
-entity le1, le2;
-float lightning_end;
-
-void() lightning_fire =
-{
- local vector p1, p2;
-
- if (time >= lightning_end)
- { // done here, put the terminals back up
- self = le1;
- door_go_down ();
- self = le2;
- door_go_down ();
- return;
- }
-
- p1 = (le1.mins + le1.maxs) * 0.5;
- p1_z = le1.absmin_z - 16;
-
- p2 = (le2.mins + le2.maxs) * 0.5;
- p2_z = le2.absmin_z - 16;
-
- // compensate for length of bolt
- p2 = p2 - normalize(p2-p1)*100;
-
- self.nextthink = time + 0.1;
- self.think = lightning_fire;
-
- WriteByte (MSG_ALL, SVC_TEMPENTITY);
- WriteByte (MSG_ALL, TE_LIGHTNING3);
- WriteEntity (MSG_ALL, world);
- WriteCoord (MSG_ALL, p1_x);
- WriteCoord (MSG_ALL, p1_y);
- WriteCoord (MSG_ALL, p1_z);
- WriteCoord (MSG_ALL, p2_x);
- WriteCoord (MSG_ALL, p2_y);
- WriteCoord (MSG_ALL, p2_z);
-};
-
-void() lightning_use =
-{
- if (lightning_end >= time + 1)
- return;
-
- le1 = find( world, target, "lightning");
- le2 = find( le1, target, "lightning");
- if (!le1 || !le2)
- {
- dprint ("missing lightning targets\n");
- return;
- }
-
- if (
- (le1.state != STATE_TOP && le1.state != STATE_BOTTOM)
- || (le2.state != STATE_TOP && le2.state != STATE_BOTTOM)
- || (le1.state != le2.state) )
- {
-// dprint ("not aligned\n");
- return;
- }
-
-// don't let the electrodes go back up until the bolt is done
- le1.nextthink = -1;
- le2.nextthink = -1;
- lightning_end = time + 1;
-
- sound (self, CHAN_VOICE, "misc/power.wav", 1, ATTN_NORM);
- lightning_fire ();
-
-// advance the boss pain if down
- self = find (world, classname, "monster_boss");
- if (!self)
- return;
- self.enemy = activator;
- if (le1.state == STATE_TOP && self.health > 0)
- {
- sound_pain (self, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM);
- self.health = self.health - 1;
- if (self.health >= 2)
- boss_shocka1();
- else if (self.health == 1)
- boss_shockb1();
- else if (self.health == 0)
- boss_shockc1();
- }
-};
-
-
-/*QUAKED event_lightning (0 1 1) (-16 -16 -16) (16 16 16) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Just for boss level.
-*/
-void() event_lightning =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = lightning_use;
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/monsters/boss2.qc

diff --git a/qc-server/monsters/boss2.qc b/qc-server/monsters/boss2.qc
deleted file mode 100644
index 295e03b..0000000
--- a/qc-server/monsters/boss2.qc
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
-==============================================================================
-
-BOSS-ONE
-
-==============================================================================
-*/
-$cd id1/models/boss1
-$origin 0 0 -15
-$base base
-$skin skin
-$scale 5
-
-$frame rise1 rise2 rise3 rise4 rise5 rise6 rise7 rise8 rise9 rise10
-$frame rise11 rise12 rise13 rise14 rise15 rise16 rise17
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
-$frame walk9 walk10 walk11 walk12 walk13 walk14 walk15
-$frame walk16 walk17 walk18 walk19 walk20 walk21 walk22
-$frame walk23 walk24 walk25 walk26 walk27 walk28 walk29 walk30 walk31
-
-$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
-
-$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
-$frame attack9 attack10 attack11 attack12 attack13 attack14 attack15
-$frame attack16 attack17 attack18 attack19 attack20 attack21 attack22
-$frame attack23
-
-$frame shocka1 shocka2 shocka3 shocka4 shocka5 shocka6 shocka7 shocka8
-$frame shocka9 shocka10
-
-$frame shockb1 shockb2 shockb3 shockb4 shockb5 shockb6
-
-$frame shockc1 shockc2 shockc3 shockc4 shockc5 shockc6 shockc7 shockc8
-$frame shockc9 shockc10
-
-float NO_LAVASPLASH = 2; //supress lava splash effect when raising, lowering or gibbing - dumptruck_ds
-
-void(vector p) boss2_missile;
-
-void() boss2_face =
-{
-// go for another player if multi player
- if (self.enemy.health <= 0 || random() < 0.02)
- {
- self.enemy = find(self.enemy, classname, "player");
- if (!self.enemy)
- self.enemy = find(self.enemy, classname, "player");
- }
- ai_face();
-};
-
-void() boss2_rise1 =[ $rise1, boss2_rise2 ] {
- sound_move (self, CHAN_AUTO, "boss1/out1.wav", 1, ATTN_NORM);
-};
-void() boss2_rise2 =[ $rise2, boss2_rise3 ] {
- sound_sight (self, CHAN_AUTO, "boss1/sight1.wav", 1, ATTN_NORM);
-};
-void() boss2_rise3 =[ $rise3, boss2_rise4 ] {};
-void() boss2_rise4 =[ $rise4, boss2_rise5 ] {};
-void() boss2_rise5 =[ $rise5, boss2_rise6 ] {};
-void() boss2_rise6 =[ $rise6, boss2_rise7 ] {};
-void() boss2_rise7 =[ $rise7, boss2_rise8 ] {};
-void() boss2_rise8 =[ $rise8, boss2_rise9 ] {};
-void() boss2_rise9 =[ $rise9, boss2_rise10 ] {};
-void() boss2_rise10 =[ $rise10, boss2_rise11 ] {};
-void() boss2_rise11 =[ $rise11, boss2_rise12 ] {};
-void() boss2_rise12 =[ $rise12, boss2_rise13 ] {};
-void() boss2_rise13 =[ $rise13, boss2_rise14 ] {};
-void() boss2_rise14 =[ $rise14, boss2_rise15 ] {};
-void() boss2_rise15 =[ $rise15, boss2_rise16 ] {};
-void() boss2_rise16 =[ $rise16, boss2_rise17 ] {};
-void() boss2_rise17 =[ $rise17, boss2_missile1 ] {};
-
-void() boss2_idle1 =[ $walk1, boss2_idle2 ]
-{
-// look for other players
-};
-void() boss2_idle2 =[ $walk2, boss2_idle3 ] {boss2_face();};
-void() boss2_idle3 =[ $walk3, boss2_idle4 ] {boss2_face();};
-void() boss2_idle4 =[ $walk4, boss2_idle5 ] {boss2_face();};
-void() boss2_idle5 =[ $walk5, boss2_idle6 ] {boss2_face();};
-void() boss2_idle6 =[ $walk6, boss2_idle7 ] {boss2_face();};
-void() boss2_idle7 =[ $walk7, boss2_idle8 ] {boss2_face();};
-void() boss2_idle8 =[ $walk8, boss2_idle9 ] {boss2_face();};
-void() boss2_idle9 =[ $walk9, boss2_idle10 ] {boss2_face();};
-void() boss2_idle10 =[ $walk10, boss2_idle11 ] {boss2_face();};
-void() boss2_idle11 =[ $walk11, boss2_idle12 ] {boss2_face();};
-void() boss2_idle12 =[ $walk12, boss2_idle13 ] {boss2_face();};
-void() boss2_idle13 =[ $walk13, boss2_idle14 ] {boss2_face();};
-void() boss2_idle14 =[ $walk14, boss2_idle15 ] {boss2_face();};
-void() boss2_idle15 =[ $walk15, boss2_idle16 ] {boss2_face();};
-void() boss2_idle16 =[ $walk16, boss2_idle17 ] {boss2_face();};
-void() boss2_idle17 =[ $walk17, boss2_idle18 ] {boss2_face();};
-void() boss2_idle18 =[ $walk18, boss2_idle19 ] {boss2_face();};
-void() boss2_idle19 =[ $walk19, boss2_idle20 ] {boss2_face();};
-void() boss2_idle20 =[ $walk20, boss2_idle21 ] {boss2_face();};
-void() boss2_idle21 =[ $walk21, boss2_idle22 ] {boss2_face();};
-void() boss2_idle22 =[ $walk22, boss2_idle23 ] {boss2_face();};
-void() boss2_idle23 =[ $walk23, boss2_idle24 ] {boss2_face();};
-void() boss2_idle24 =[ $walk24, boss2_idle25 ] {boss2_face();};
-void() boss2_idle25 =[ $walk25, boss2_idle26 ] {boss2_face();};
-void() boss2_idle26 =[ $walk26, boss2_idle27 ] {boss2_face();};
-void() boss2_idle27 =[ $walk27, boss2_idle28 ] {boss2_face();};
-void() boss2_idle28 =[ $walk28, boss2_idle29 ] {boss2_face();};
-void() boss2_idle29 =[ $walk29, boss2_idle30 ] {boss2_face();};
-void() boss2_idle30 =[ $walk30, boss2_idle31 ] {boss2_face();};
-void() boss2_idle31 =[ $walk31, boss2_idle1 ] {boss2_face();};
-
-void() boss2_missile1 =[ $attack1, boss2_missile2 ] {boss2_face();};
-void() boss2_missile2 =[ $attack2, boss2_missile3 ] {boss2_face();};
-void() boss2_missile3 =[ $attack3, boss2_missile4 ] {boss2_face();};
-void() boss2_missile4 =[ $attack4, boss2_missile5 ] {boss2_face();};
-void() boss2_missile5 =[ $attack5, boss2_missile6 ] {boss2_face();};
-void() boss2_missile6 =[ $attack6, boss2_missile7 ] {boss2_face();};
-void() boss2_missile7 =[ $attack7, boss2_missile8 ] {boss2_face();};
-void() boss2_missile8 =[ $attack8, boss2_missile9 ] {boss2_face();};
-void() boss2_missile9 =[ $attack9, boss2_missile10 ] {boss2_missile('100 100 200');};
-void() boss2_missile10 =[ $attack10, boss2_missile11 ] {boss2_face();};
-void() boss2_missile11 =[ $attack11, boss2_missile12 ] {boss2_face();};
-void() boss2_missile12 =[ $attack12, boss2_missile13 ] {boss2_face();};
-void() boss2_missile13 =[ $attack13, boss2_missile14 ] {boss2_face();};
-void() boss2_missile14 =[ $attack14, boss2_missile15 ] {boss2_face();};
-void() boss2_missile15 =[ $attack15, boss2_missile16 ] {boss2_face();};
-void() boss2_missile16 =[ $attack16, boss2_missile17 ] {boss2_face();};
-void() boss2_missile17 =[ $attack17, boss2_missile18 ] {boss2_face();};
-void() boss2_missile18 =[ $attack18, boss2_missile19 ] {boss2_face();};
-void() boss2_missile19 =[ $attack19, boss2_missile20 ] {boss2_face();};
-void() boss2_missile20 =[ $attack20, boss2_missile21 ] {boss2_missile('100 -100 200');};
-void() boss2_missile21 =[ $attack21, boss2_missile22 ] {boss2_face();};
-void() boss2_missile22 =[ $attack22, boss2_missile23 ] {boss2_face();};
-void() boss2_missile23 =[ $attack23, boss2_missile1 ] {boss2_face();};
-
-void() boss2_shocka1 =[ $shocka1, boss2_shocka2 ] {};
-void() boss2_shocka2 =[ $shocka2, boss2_shocka3 ] {};
-void() boss2_shocka3 =[ $shocka3, boss2_shocka4 ] {};
-void() boss2_shocka4 =[ $shocka4, boss2_shocka5 ] {};
-void() boss2_shocka5 =[ $shocka5, boss2_shocka6 ] {};
-void() boss2_shocka6 =[ $shocka6, boss2_shocka7 ] {};
-void() boss2_shocka7 =[ $shocka7, boss2_shocka8 ] {};
-void() boss2_shocka8 =[ $shocka8, boss2_shocka9 ] {};
-void() boss2_shocka9 =[ $shocka9, boss2_shocka10 ] {};
-void() boss2_shocka10 =[ $shocka10, boss2_missile1 ] {};
-
-void() boss2_shockb1 =[ $shockb1, boss2_shockb2 ] {};
-void() boss2_shockb2 =[ $shockb2, boss2_shockb3 ] {};
-void() boss2_shockb3 =[ $shockb3, boss2_shockb4 ] {};
-void() boss2_shockb4 =[ $shockb4, boss2_shockb5 ] {};
-void() boss2_shockb5 =[ $shockb5, boss2_shockb6 ] {};
-void() boss2_shockb6 =[ $shockb6, boss2_shockb7 ] {};
-void() boss2_shockb7 =[ $shockb1, boss2_shockb8 ] {};
-void() boss2_shockb8 =[ $shockb2, boss2_shockb9 ] {};
-void() boss2_shockb9 =[ $shockb3, boss2_shockb10 ] {};
-void() boss2_shockb10 =[ $shockb4, boss2_missile1 ] {};
-
-void() boss2_shockc1 =[ $shockc1, boss2_shockc2 ] {};
-void() boss2_shockc2 =[ $shockc2, boss2_shockc3 ] {};
-void() boss2_shockc3 =[ $shockc3, boss2_shockc4 ] {};
-void() boss2_shockc4 =[ $shockc4, boss2_shockc5 ] {};
-void() boss2_shockc5 =[ $shockc5, boss2_shockc6 ] {};
-void() boss2_shockc6 =[ $shockc6, boss2_shockc7 ] {};
-void() boss2_shockc7 =[ $shockc7, boss2_shockc8 ] {};
-void() boss2_shockc8 =[ $shockc8, boss2_shockc9 ] {};
-void() boss2_shockc9 =[ $shockc9, boss2_shockc10 ] {};
-void() boss2_shockc10 =[ $shockc10, boss2_death1 ] {};
-
-void() boss2_pain1 =[ $shocka1, boss2_pain2 ] {};
-void() boss2_pain2 =[ $shocka2, boss2_pain3 ] {};
-void() boss2_pain3 =[ $shocka3, boss2_pain4 ] {};
-void() boss2_pain4 =[ $shocka4, boss2_pain5 ] {
- sound_pain (self, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM); // pain noise
-};
-void() boss2_pain5 =[ $shocka5, boss2_pain6 ] {};
-void() boss2_pain6 =[ $shocka6, bos2s_pain7 ] {};
-void() bos2s_pain7 =[ $shocka7, boss2_pain8 ] {};
-void() boss2_pain8 =[ $shocka8, boss2_pain9 ] {};
-void() boss2_pain9 =[ $shocka9, boss2_missile1 ] {}; // auto shoot a lavaball
-
-
-void() GibBoss2 =
-{
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- // throw tons of meat chunks
-
- local vector boss;
- local float x, y, z;
- local float r;
- // local entity n;
-
- boss = self.origin;
- z = 16;
- while (z <= 144)
- {
- x = -64;
- while (x <= 64)
- {
- y = -64;
- while (y <= 64)
- {
- self.origin_x = boss_x + x;
- self.origin_y = boss_y + y;
- self.origin_z = boss_z + z;
-
- r = random();
- if (r < 0.3)
- // ThrowGib ("progs/gib1.mdl", -120);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, -120);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", -120);
- }
- else if (r < 0.5)
- // ThrowGib ("progs/gib2.mdl", -120);
- if (self.mdl_gib2 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib2, -120);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", -120);
- }
- else if (r < 0.7)
- ThrowGib ("progs/lavaball.mdl", -120);
- else
- // ThrowGib ("progs/gib3.mdl", -120);
- if (self.mdl_gib3 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib3, -120);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", -120);
- }
- y = y + 32;
- }
- x = x + 32;
- }
- z = z + 96;
- }
-
- local entity head;
-
- head = spawn();
- head.origin = self.origin + '0 0 128';
- head.velocity_z = 600; + (random() * 200);
- head.velocity_x = -300 + (random() * 600);
- head.velocity_y = -200 + (random() * 600);
- head.avelocity_x = random()*120;
- head.avelocity_y = random()*120;
- head.avelocity_z = random()*120;
- head.flags = self.flags - (self.flags & FL_ONGROUND);
- head.solid = SOLID_NOT;
- head.movetype = MOVETYPE_BOUNCE;
- head.takedamage = DAMAGE_NO;
- if (self.mdl_head != "") // dumptruck_ds custom_mdls
- {
- setmodel (head, self.mdl_head);
- }
- else
- {
- setmodel (head, "progs/h_boss.mdl");
- }
-
- if (!self.skin_head) // dumptruck_ds
- {
- head.skin = self.skin_proj;
- }
- else
- {
- head.skin = 0;
- }
- setsize (head, '-67 -60 -6', '62 52 88');
- // setsize (head, '-16 -16 0', '16 16 56');
- head.touch = SUB_Null;
- head.think = SUB_Remove;
- head.nextthink = time + 120;
- if !(self.spawnflags & NO_LAVASPLASH)
- {
- // killed_monsters = killed_monsters + 1; //already done in combat.qc since this is now FL_MONSTER
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
- // WriteByte (MSG_ALL, SVC_KILLEDMONSTER); //already done in combat.qc since this is now FL_MONSTER -- dumptruck_ds
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- }
- remove (self);
-};
-
-void() boss2_die =
-{
- if (self.health < -50) // if health under -15
- {
- GibBoss2 ();
- return;
- }
- else // otherwise
- {
- boss2_death1 (); // normal death
- return;
- }
-};
-
-void() boss2_death1 = [$death1, boss2_death2] {
- sound_death (self, CHAN_VOICE, "boss1/death.wav", 1, ATTN_NORM);
-};
-void() boss2_death2 = [$death2, boss2_death3] {};
-void() boss2_death3 = [$death3, boss2_death4] {};
-void() boss2_death4 = [$death4, boss2_death5] {};
-void() boss2_death5 = [$death5, boss2_death6] {};
-void() boss2_death6 = [$death6, boss2_death7] {};
-void() boss2_death7 = [$death7, boss2_death8] {};
-void() boss2_death8 = [$death8, boss2_death9] {};
-void() boss2_death9 = [$death9, boss2_death10]
-{
- sound_move (self, CHAN_BODY, "boss1/out1.wav", 1, ATTN_NORM);
- if !(self.spawnflags & NO_LAVASPLASH)
- {
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- }
-};
-
-void(entity attacker, float damage) boss2_pain_go =
-{
- if (self.pain_finished > time)
- return;
-
- boss2_pain1();
- self.pain_finished = time + 4;
-};
-
-void() boss2_death10 = [$death9, boss2_death10]
-{
-// unlike the code for the original monster_boss, this function doesn't
-// need to increment killed_monsters or call SUB_UseTargets(); this
-// entity gets killed by regular damage and has FL_MONSTER, so the
-// Killed() function (in combat.qc) will already have taken care of
-// those things -- iw
-
- remove (self);
-};
-
-void(vector p) boss2_missile =
-{
- local vector offang;
- local vector org, vec, d;
- local float t;
-
- offang = vectoangles (self.enemy.origin - self.origin);
- makevectors (offang);
-
- org = self.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
-
-// lead the player on hard mode
- if (skill > 1)
- {
- t = vlen(self.enemy.origin - org) / 300;
- vec = self.enemy.velocity;
- vec_z = 0;
- d = self.enemy.origin + t * vec;
- }
- else
- {
- d = self.enemy.origin;
- }
-
- vec = normalize (d - org);
-
- launch_spike2 (org, vec, 300);
- // setmodel (newmis, "progs/lavaball.mdl");
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/lavaball.mdl");
- }
-
- if (!newmis.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
-
- newmis.avelocity = '200 100 300';
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- newmis.touch = T_MissileTouch; // rocket explosion
- sound_attack (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM);
-
-// check for dead enemy
- if (self.enemy.health <= 0)
- boss2_idle1 ();
-};
-
-
-void() boss2_awake =
-{
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
- self.takedamage = DAMAGE_AIM;
-
- body_model ("progs/boss.mdl");
- // setmodel (self, "progs/boss.mdl");
- setsize (self, '-128 -128 -24', '128 128 256');
-
- if (!self.health)
- {
- if (skill == 0)
- self.health = 1000;
- else
- self.health = 3000;
- }
-
-// note that self.th_run has to be set in order to avoid a "NULL
-// function" Host_Error in the case where T_Damage() calls
-// FoundTarget(), which calls HuntTarget(), which uses self.th_run as
-// the next self.think -- iw
- self.th_run = boss2_missile1;
-
- self.th_pain = boss2_pain_go;
- self.th_die = boss2_die;
-
-// give the boss a couple of seconds to finish rising before allowing it
-// to go into its pain animation -- iw
- self.pain_finished = time + 2;
-
- self.enemy = activator;
-
- if !(self.spawnflags & NO_LAVASPLASH)
- {
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- }
-
- self.yaw_speed = 20;
- boss2_rise1 ();
-};
-
-
-/*QUAKED monster_boss2 (1 0 0) (-128 -128 -24) (128 128 256)
-*/
-void() monster_boss2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
-
- if (deathmatch)
- {
- remove(self);
- return;
- } //custom sounds and models -- dumptruck_ds
- precache_body_model ("progs/boss.mdl");
- precache_head_model ("progs/h_boss.mdl");
- precache_model ("progs/lavaball.mdl");
- // precache_model ("progs/boss.mdl");
- precache_model ("progs/h_boss.mdl");
-
- precache_sound ("weapons/rocket1i.wav");
- precache_sound_move ("boss1/out1.wav");
- precache_sound_sight ("boss1/sight1.wav");
- precache_sound ("misc/power.wav");
- precache_sound_attack ("boss1/throw.wav");
- precache_sound_pain ("boss1/pain.wav");
- precache_sound_death ("boss1/death.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- total_monsters = total_monsters + 1;
- self.flags = FL_MONSTER;
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
- self.use = boss2_awake;
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/monsters/demon.qc

diff --git a/qc-server/monsters/demon.qc b/qc-server/monsters/demon.qc
deleted file mode 100644
index 4c13b4a..0000000
--- a/qc-server/monsters/demon.qc
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
-==============================================================================
-
-DEMON
-
-==============================================================================
-*/
-
-$cd id1/models/demon3
-$scale 0.8
-$origin 0 0 24
-$base base
-$skin base
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
-$frame stand10 stand11 stand12 stand13
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
-
-$frame run1 run2 run3 run4 run5 run6
-
-$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9 leap10
-$frame leap11 leap12
-
-$frame pain1 pain2 pain3 pain4 pain5 pain6
-
-$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
-
-$frame attacka1 attacka2 attacka3 attacka4 attacka5 attacka6 attacka7 attacka8
-$frame attacka9 attacka10 attacka11 attacka12 attacka13 attacka14 attacka15
-
-//============================================================================
-
-void() Demon_JumpTouch;
-
-void() demon1_stand1 =[ $stand1, demon1_stand2 ] {ai_stand();};
-void() demon1_stand2 =[ $stand2, demon1_stand3 ] {ai_stand();};
-void() demon1_stand3 =[ $stand3, demon1_stand4 ] {ai_stand();};
-void() demon1_stand4 =[ $stand4, demon1_stand5 ] {ai_stand();};
-void() demon1_stand5 =[ $stand5, demon1_stand6 ] {ai_stand();};
-void() demon1_stand6 =[ $stand6, demon1_stand7 ] {ai_stand();};
-void() demon1_stand7 =[ $stand7, demon1_stand8 ] {ai_stand();};
-void() demon1_stand8 =[ $stand8, demon1_stand9 ] {ai_stand();};
-void() demon1_stand9 =[ $stand9, demon1_stand10 ] {ai_stand();};
-void() demon1_stand10 =[ $stand10, demon1_stand11 ] {ai_stand();};
-void() demon1_stand11 =[ $stand11, demon1_stand12 ] {ai_stand();};
-void() demon1_stand12 =[ $stand12, demon1_stand13 ] {ai_stand();};
-void() demon1_stand13 =[ $stand13, demon1_stand1 ] {ai_stand();};
-
-void() demon1_walk1 =[ $walk1, demon1_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE);
-ai_walk(8);
-};
-void() demon1_walk2 =[ $walk2, demon1_walk3 ] {ai_walk(6);};
-void() demon1_walk3 =[ $walk3, demon1_walk4 ] {ai_walk(6);};
-void() demon1_walk4 =[ $walk4, demon1_walk5 ] {ai_walk(7);};
-void() demon1_walk5 =[ $walk5, demon1_walk6 ] {ai_walk(4);};
-void() demon1_walk6 =[ $walk6, demon1_walk7 ] {ai_walk(6);};
-void() demon1_walk7 =[ $walk7, demon1_walk8 ] {ai_walk(10);};
-void() demon1_walk8 =[ $walk8, demon1_walk1 ] {ai_walk(10);};
-
-void() demon1_run1 =[ $run1, demon1_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE);
-ai_run(20);};
-void() demon1_run2 =[ $run2, demon1_run3 ] {ai_run(15);};
-void() demon1_run3 =[ $run3, demon1_run4 ] {ai_run(36);};
-void() demon1_run4 =[ $run4, demon1_run5 ] {ai_run(20);};
-void() demon1_run5 =[ $run5, demon1_run6 ] {ai_run(15);};
-void() demon1_run6 =[ $run6, demon1_run1 ] {ai_run(36);};
-
-void() demon1_jump1 =[ $leap1, demon1_jump2 ] {ai_face();};
-void() demon1_jump2 =[ $leap2, demon1_jump3 ] {ai_face();};
-void() demon1_jump3 =[ $leap3, demon1_jump4 ] {ai_face();};
-void() demon1_jump4 =[ $leap4, demon1_jump5 ]
-{
- ai_face();
- self.worldtype = 0; //fix for instakill bug -- dumptruck_ds
- self.touch = Demon_JumpTouch;
- makevectors (self.angles);
- self.origin_z = self.origin_z + 1;
- self.velocity = v_forward * 600 + '0 0 250';
- if (self.flags & FL_ONGROUND)
- self.flags = self.flags - FL_ONGROUND;
-};
-void() demon1_jump5 =[ $leap5, demon1_jump6 ] {};
-void() demon1_jump6 =[ $leap6, demon1_jump7 ] {};
-void() demon1_jump7 =[ $leap7, demon1_jump8 ] {};
-void() demon1_jump8 =[ $leap8, demon1_jump9 ] {};
-void() demon1_jump9 =[ $leap9, demon1_jump10 ] {};
-void() demon1_jump10 =[ $leap10, demon1_jump1 ] {
-self.nextthink = time + 3;
-// if three seconds pass, assume demon is stuck and jump again
-};
-
-void() demon1_jump11 =[ $leap11, demon1_jump12 ] {};
-void() demon1_jump12 =[ $leap12, demon1_run1 ] {};
-
-
-void() demon1_atta1 =[ $attacka1, demon1_atta2 ] {ai_charge(4);};
-void() demon1_atta2 =[ $attacka2, demon1_atta3 ] {ai_charge(0);};
-void() demon1_atta3 =[ $attacka3, demon1_atta4 ] {ai_charge(0);};
-void() demon1_atta4 =[ $attacka4, demon1_atta5 ] {ai_charge(1);};
-void() demon1_atta5 =[ $attacka5, demon1_atta6 ] {ai_charge(2); Demon_Melee(200);};
-void() demon1_atta6 =[ $attacka6, demon1_atta7 ] {ai_charge(1);};
-void() demon1_atta7 =[ $attacka7, demon1_atta8 ] {ai_charge(6);};
-void() demon1_atta8 =[ $attacka8, demon1_atta9 ] {ai_charge(8);};
-void() demon1_atta9 =[ $attacka9, demon1_atta10] {ai_charge(4);};
-void() demon1_atta10 =[ $attacka10, demon1_atta11] {ai_charge(2);};
-void() demon1_atta11 =[ $attacka11, demon1_atta12] {Demon_Melee(-200);};
-void() demon1_atta12 =[ $attacka12, demon1_atta13] {ai_charge(5);};
-void() demon1_atta13 =[ $attacka13, demon1_atta14] {ai_charge(8);};
-void() demon1_atta14 =[ $attacka14, demon1_atta15] {ai_charge(4);};
-void() demon1_atta15 =[ $attacka15, demon1_run1] {ai_charge(4);};
-
-void() demon1_pain1 =[ $pain1, demon1_pain2 ] {};
-void() demon1_pain2 =[ $pain2, demon1_pain3 ] {};
-void() demon1_pain3 =[ $pain3, demon1_pain4 ] {};
-void() demon1_pain4 =[ $pain4, demon1_pain5 ] {};
-void() demon1_pain5 =[ $pain5, demon1_pain6 ] {};
-void() demon1_pain6 =[ $pain6, demon1_run1 ] {};
-
-void(entity attacker, float damage) demon1_pain =
-{
- if (self.touch == Demon_JumpTouch)
- return;
-
- if (self.pain_finished > time)
- return;
-
- self.pain_finished = time + 1;
- sound_pain (self, CHAN_VOICE, "demon/dpain1.wav", 1, ATTN_NORM);
-
- if (random()*200 > damage)
- return; // didn't flinch
-
- demon1_pain1 ();
-};
-
-void() demon1_die1 =[ $death1, demon1_die2 ] {
-sound_death (self, CHAN_VOICE, "demon/ddeath.wav", 1, ATTN_NORM);};
-void() demon1_die2 =[ $death2, demon1_die3 ] {};
-void() demon1_die3 =[ $death3, demon1_die4 ] {};
-void() demon1_die4 =[ $death4, demon1_die5 ] {};
-void() demon1_die5 =[ $death5, demon1_die6 ] {};
-void() demon1_die6 =[ $death6, demon1_die7 ]
-{self.solid = SOLID_NOT;};
-void() demon1_die7 =[ $death7, demon1_die8 ] {};
-void() demon1_die8 =[ $death8, demon1_die9 ] {};
-void() demon1_die9 =[ $death9, demon1_die9 ] {};
-
-void() demon_die =
-{
-// check for gib
- if (self.health < -80)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "")
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_demon.mdl", self.health);
- }
- // ThrowHead ("progs/h_demon.mdl", self.health);
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib1.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- DropStuff();
- return;
- }
-
-// regular death
- DropStuff();
- demon1_die1 ();
-};
-
-
-void() Demon_MeleeAttack =
-{
- demon1_atta1 ();
-};
-
-
-/*QUAKED monster_demon1 (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/demon.mdl");
-}
-Fiend.
-
-Default heath = 300"
-
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : ""Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound"
-snd_hit(string) : "Path to custom hit sound (DEMON SLASHING)"
-snd_idle(string) : "Path to custom idle sound"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-skin_head(float) : "Skin index of custom head model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_demon1 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- //dumptruck_ds custom_mdls
- precache_body_model ("progs/demon.mdl");
- precache_head_model ("progs/h_demon.mdl");
-
- precache_sound_death ("demon/ddeath.wav");
- precache_sound_hit ("demon/dhit2.wav");
- precache_sound_attack ("demon/djump.wav");
- precache_sound_pain ("demon/dpain1.wav");
- precache_sound_idle ("demon/idle1.wav");
- precache_sound_sight ("demon/sight2.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- // precache_gib2 ("progs/gib2.mdl");
- // precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/demon.mdl");
- // setmodel (self, "progs/demon.mdl");
-
- setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 300;
-
- self.th_stand = demon1_stand1;
- self.th_walk = demon1_walk1;
- self.th_run = demon1_run1;
- self.th_die = demon_die;
- self.th_melee = Demon_MeleeAttack; // one of two attacks
- self.th_missile = demon1_jump1; // jump attack
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = demon1_pain;
- else
- self.th_pain = SUB_NullPain;
-
- walkmonster_start();
-};
-
-
-/*
-==============================================================================
-
-DEMON
-
-==============================================================================
-*/
-
-/*
-==============
-CheckDemonMelee
-
-Returns TRUE if a melee attack would hit right now
-==============
-*/
-float() CheckDemonMelee =
-{
- if (enemy_range == RANGE_MELEE)
- { // FIXME: check canreach
- self.attack_state = AS_MELEE;
- return TRUE;
- }
- return FALSE;
-};
-
-/*
-==============
-CheckDemonJump
-
-==============
-*/
-float() CheckDemonJump =
-{
- local vector dist;
- local float d;
-
- if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z
- + 0.75 * self.enemy.size_z)
- return FALSE;
-
- if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z
- + 0.25 * self.enemy.size_z)
- return FALSE;
-
- dist = self.enemy.origin - self.origin;
- dist_z = 0;
-
- d = vlen(dist);
-
- if (d < 100)
- return FALSE;
-
- if (d > 200)
- {
- if (random() < 0.9)
- return FALSE;
- }
-
- return TRUE;
-};
-
-float() DemonCheckAttack =
-{
-
-// if close enough for slashing, go for it
- if (CheckDemonMelee ())
- {
- self.attack_state = AS_MELEE;
- return TRUE;
- }
-
- if (CheckDemonJump ())
- {
- self.attack_state = AS_MISSILE;
- sound_attack (self, CHAN_VOICE, "demon/djump.wav", 1, ATTN_NORM);
- return TRUE;
- }
-
- return FALSE;
-};
-
-
-//===========================================================================
-
-void(float side) Demon_Melee =
-{
- local float ldmg;
- local vector delta;
-
- ai_face ();
- walkmove (self.ideal_yaw, 12); // allow a little closing
-
- delta = self.enemy.origin - self.origin;
-
- if (vlen(delta) > 100)
- return;
- if (!CanDamage (self.enemy, self))
- return;
-
- sound_hit (self, CHAN_WEAPON, "demon/dhit2.wav", 1, ATTN_NORM);
- ldmg = 10 + 5*random();
- T_Damage (self.enemy, self, self, ldmg);
-
- makevectors (self.angles);
- SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
-};
-
-
-void() Demon_JumpTouch =
-{
- local float ldmg;
-
- if (self.health <= 0)
- return;
-
- if (other.takedamage)
- {
- if ( vlen(self.velocity) > 400 )
- {
- if !(self.worldtype)
- {
- ldmg = 40 + 10*random();
- T_Damage (other, self, self, ldmg);
- if (other.health > 0) // is the player still alive? Preach's instakill bug check - dumptruck_ds
- self.worldtype = 1;
- }
- }
- }
-
- if (!checkbottom(self))
- {
- if (self.flags & FL_ONGROUND)
- { // jump randomly to not get hung up
-//dprint ("popjump\n");
-// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
-// self.touch = SUB_Null;
- self.touch = monster_touch;
-// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
- self.think = demon1_jump1;
- self.nextthink = time + 0.1;
-
-// self.velocity_x = (random() - 0.5) * 600;
-// self.velocity_y = (random() - 0.5) * 600;
-// self.velocity_z = 200;
-// self.flags = self.flags - FL_ONGROUND;
- }
- return; // not on ground yet
- }
-
- // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
- // self.touch = SUB_Null;
- self.touch = monster_touch;
- // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
- self.think = demon1_jump11;
- self.nextthink = time + 0.1;
-};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_demon (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/demon.mdl","frame":53});
-}
-*/
-void() monster_dead_demon =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/demon.mdl");
- setmodel(self, "progs/demon.mdl");
- self.frame = $death9;
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-43.63 -47.26 -50.53','32.48 24.65 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/monsters/dog.qc

diff --git a/qc-server/monsters/dog.qc b/qc-server/monsters/dog.qc
deleted file mode 100644
index 6da85bb..0000000
--- a/qc-server/monsters/dog.qc
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
-==============================================================================
-
-DOG
-
-==============================================================================
-*/
-$cd id1/models/dog
-$origin 0 0 24
-$base base
-$skin skin
-
-$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
-
-$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
-
-$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
-$frame deathb9
-
-$frame pain1 pain2 pain3 pain4 pain5 pain6
-
-$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10
-$frame painb11 painb12 painb13 painb14 painb15 painb16
-
-$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12
-
-$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
-
-
-void() dog_leap1;
-void() dog_run1;
-
-/*
-================
-dog_bite
-
-================
-*/
-void() dog_bite =
-{
-local vector delta;
-local float ldmg;
-
- if (!self.enemy)
- return;
-
- ai_charge(10);
-
- if (!CanDamage (self.enemy, self))
- return;
-
- delta = self.enemy.origin - self.origin;
-
- if (vlen(delta) > 100)
- return;
-
- ldmg = (random() + random() + random()) * 8;
- T_Damage (self.enemy, self, self, ldmg);
-};
-
-void() Dog_JumpTouch =
-{
- local float ldmg;
-
- if (self.health <= 0)
- return;
-
- if (other.takedamage)
- {
- if ( vlen(self.velocity) > 300 )
- {
- if !(self.worldtype)
- {
- ldmg = 10 + 10*random();
- T_Damage (other, self, self, ldmg);
- if (other.health > 0) // is the player still alive? Preach's instakill bug check - dumptruck_ds
- self.worldtype = 1;
- }
- }
- }
-
- if (!checkbottom(self))
- {
- if (self.flags & FL_ONGROUND)
- { // jump randomly to not get hung up
-//dprint ("popjump\n");
-// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
-// self.touch = SUB_Null;
- self.touch = monster_touch;
-// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
- self.think = dog_leap1;
- self.nextthink = time + 0.1;
-
-// self.velocity_x = (random() - 0.5) * 600;
-// self.velocity_y = (random() - 0.5) * 600;
-// self.velocity_z = 200;
-// self.flags = self.flags - FL_ONGROUND;
- }
- return; // not on ground yet
- }
-
- // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
- // self.touch = SUB_Null;
- self.touch = monster_touch;
- // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
- self.think = dog_run1;
- self.nextthink = time + 0.1;
-};
-
-
-void() dog_stand1 =[ $stand1, dog_stand2 ] {ai_stand();};
-void() dog_stand2 =[ $stand2, dog_stand3 ] {ai_stand();};
-void() dog_stand3 =[ $stand3, dog_stand4 ] {ai_stand();};
-void() dog_stand4 =[ $stand4, dog_stand5 ] {ai_stand();};
-void() dog_stand5 =[ $stand5, dog_stand6 ] {ai_stand();};
-void() dog_stand6 =[ $stand6, dog_stand7 ] {ai_stand();};
-void() dog_stand7 =[ $stand7, dog_stand8 ] {ai_stand();};
-void() dog_stand8 =[ $stand8, dog_stand9 ] {ai_stand();};
-void() dog_stand9 =[ $stand9, dog_stand1 ] {ai_stand();};
-
-void() dog_walk1 =[ $walk1 , dog_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "dog/idle.wav", 1, ATTN_IDLE); //dumptruck_ds
-ai_walk(8);};
-void() dog_walk2 =[ $walk2 , dog_walk3 ] {ai_walk(8);};
-void() dog_walk3 =[ $walk3 , dog_walk4 ] {ai_walk(8);};
-void() dog_walk4 =[ $walk4 , dog_walk5 ] {ai_walk(8);};
-void() dog_walk5 =[ $walk5 , dog_walk6 ] {ai_walk(8);};
-void() dog_walk6 =[ $walk6 , dog_walk7 ] {ai_walk(8);};
-void() dog_walk7 =[ $walk7 , dog_walk8 ] {ai_walk(8);};
-void() dog_walk8 =[ $walk8 , dog_walk1 ] {ai_walk(8);};
-
-void() dog_run1 =[ $run1 , dog_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "dog/idle.wav", 1, ATTN_IDLE); //dumptruck_ds
-ai_run(16);};
-void() dog_run2 =[ $run2 , dog_run3 ] {ai_run(32);};
-void() dog_run3 =[ $run3 , dog_run4 ] {ai_run(32);};
-void() dog_run4 =[ $run4 , dog_run5 ] {ai_run(20);};
-void() dog_run5 =[ $run5 , dog_run6 ] {ai_run(64);};
-void() dog_run6 =[ $run6 , dog_run7 ] {ai_run(32);};
-void() dog_run7 =[ $run7 , dog_run8 ] {ai_run(16);};
-void() dog_run8 =[ $run8 , dog_run9 ] {ai_run(32);};
-void() dog_run9 =[ $run9 , dog_run10 ] {ai_run(32);};
-void() dog_run10 =[ $run10 , dog_run11 ] {ai_run(20);};
-void() dog_run11 =[ $run11 , dog_run12 ] {ai_run(64);};
-void() dog_run12 =[ $run12 , dog_run1 ] {ai_run(32);};
-
-void() dog_atta1 =[ $attack1, dog_atta2 ] {ai_charge(10);};
-void() dog_atta2 =[ $attack2, dog_atta3 ] {ai_charge(10);};
-void() dog_atta3 =[ $attack3, dog_atta4 ] {ai_charge(10);};
-void() dog_atta4 =[ $attack4, dog_atta5 ] {
-sound_attack (self, CHAN_VOICE, "dog/dattack1.wav", 1, ATTN_NORM); //dumptruck_ds
-dog_bite();};
-void() dog_atta5 =[ $attack5, dog_atta6 ] {ai_charge(10);};
-void() dog_atta6 =[ $attack6, dog_atta7 ] {ai_charge(10);};
-void() dog_atta7 =[ $attack7, dog_atta8 ] {ai_charge(10);};
-void() dog_atta8 =[ $attack8, dog_run1 ] {ai_charge(10);};
-
-void() dog_leap1 =[ $leap1, dog_leap2 ] {ai_face();};
-void() dog_leap2 =[ $leap2, dog_leap3 ]
-{
- ai_face();
- self.worldtype = 0; //fix for instakill bug -- dumptruck_ds
- self.touch = Dog_JumpTouch;
- makevectors (self.angles);
- self.origin_z = self.origin_z + 1;
- self.velocity = v_forward * 300 + '0 0 200';
- if (self.flags & FL_ONGROUND)
- self.flags = self.flags - FL_ONGROUND;
-};
-
-void() dog_leap3 =[ $leap3, dog_leap4 ] {};
-void() dog_leap4 =[ $leap4, dog_leap5 ] {};
-void() dog_leap5 =[ $leap5, dog_leap6 ] {};
-void() dog_leap6 =[ $leap6, dog_leap7 ] {};
-void() dog_leap7 =[ $leap7, dog_leap8 ] {};
-void() dog_leap8 =[ $leap8, dog_leap9 ] {};
-void() dog_leap9 =[ $leap9, dog_leap9 ] {};
-
-void() dog_pain1 =[ $pain1 , dog_pain2 ] {};
-void() dog_pain2 =[ $pain2 , dog_pain3 ] {};
-void() dog_pain3 =[ $pain3 , dog_pain4 ] {};
-void() dog_pain4 =[ $pain4 , dog_pain5 ] {};
-void() dog_pain5 =[ $pain5 , dog_pain6 ] {};
-void() dog_pain6 =[ $pain6 , dog_run1 ] {};
-
-void() dog_painb1 =[ $painb1 , dog_painb2 ] {};
-void() dog_painb2 =[ $painb2 , dog_painb3 ] {};
-void() dog_painb3 =[ $painb3 , dog_painb4 ] {ai_pain(4);};
-void() dog_painb4 =[ $painb4 , dog_painb5 ] {ai_pain(12);};
-void() dog_painb5 =[ $painb5 , dog_painb6 ] {ai_pain(12);};
-void() dog_painb6 =[ $painb6 , dog_painb7 ] {ai_pain(2);};
-void() dog_painb7 =[ $painb7 , dog_painb8 ] {};
-void() dog_painb8 =[ $painb8 , dog_painb9 ] {ai_pain(4);};
-void() dog_painb9 =[ $painb9 , dog_painb10 ] {};
-void() dog_painb10 =[ $painb10 , dog_painb11 ] {ai_pain(10);};
-void() dog_painb11 =[ $painb11 , dog_painb12 ] {};
-void() dog_painb12 =[ $painb12 , dog_painb13 ] {};
-void() dog_painb13 =[ $painb13 , dog_painb14 ] {};
-void() dog_painb14 =[ $painb14 , dog_painb15 ] {};
-void() dog_painb15 =[ $painb15 , dog_painb16 ] {};
-void() dog_painb16 =[ $painb16 , dog_run1 ] {};
-
-void(entity attacker, float damage) dog_pain =
-{
- sound_pain (self, CHAN_VOICE, "dog/dpain1.wav", 1, ATTN_NORM); //dumptruck_ds
-
- if (random() > 0.5)
- dog_pain1 ();
- else
- dog_painb1 ();
-};
-
-void() dog_die1 =[ $death1, dog_die2 ] {};
-void() dog_die2 =[ $death2, dog_die3 ] {};
-void() dog_die3 =[ $death3, dog_die4 ] {};
-void() dog_die4 =[ $death4, dog_die5 ] {};
-void() dog_die5 =[ $death5, dog_die6 ] {};
-void() dog_die6 =[ $death6, dog_die7 ] {};
-void() dog_die7 =[ $death7, dog_die8 ] {};
-void() dog_die8 =[ $death8, dog_die9 ] {};
-void() dog_die9 =[ $death9, dog_die9 ] {};
-
-void() dog_dieb1 =[ $deathb1, dog_dieb2 ] {};
-void() dog_dieb2 =[ $deathb2, dog_dieb3 ] {};
-void() dog_dieb3 =[ $deathb3, dog_dieb4 ] {};
-void() dog_dieb4 =[ $deathb4, dog_dieb5 ] {};
-void() dog_dieb5 =[ $deathb5, dog_dieb6 ] {};
-void() dog_dieb6 =[ $deathb6, dog_dieb7 ] {};
-void() dog_dieb7 =[ $deathb7, dog_dieb8 ] {};
-void() dog_dieb8 =[ $deathb8, dog_dieb9 ] {};
-void() dog_dieb9 =[ $deathb9, dog_dieb9 ] {};
-
-
-void() dog_die =
-{
-// check for gib
- if (self.health < -35)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
-
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_head != "")
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_dog.mdl", self.health);
- }
- DropStuff();
- return;
- }
-
-// regular death
- sound_death (self, CHAN_VOICE, "dog/ddeath.wav", 1, ATTN_NORM); //dumptruck_ds
- self.solid = SOLID_NOT;
-
- DropStuff();
-
- if (random() > 0.5)
- dog_die1 ();
- else
- dog_dieb1 ();
-};
-
-//============================================================================
-
-/*
-==============
-CheckDogMelee
-
-Returns TRUE if a melee attack would hit right now
-==============
-*/
-float() CheckDogMelee =
-{
- if (enemy_range == RANGE_MELEE)
- { // FIXME: check canreach
- self.attack_state = AS_MELEE;
- return TRUE;
- }
- return FALSE;
-};
-
-/*
-==============
-CheckDogJump
-
-==============
-*/
-float() CheckDogJump =
-{
- local vector dist;
- local float d;
-
- if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z
- + 0.75 * self.enemy.size_z)
- return FALSE;
-
- if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z
- + 0.25 * self.enemy.size_z)
- return FALSE;
-
- dist = self.enemy.origin - self.origin;
- dist_z = 0;
-
- d = vlen(dist);
-
- if (d < 80)
- return FALSE;
-
- if (d > 150)
- return FALSE;
-
- return TRUE;
-};
-
-float() DogCheckAttack =
-{
-
-// if close enough for slashing, go for it
- if (CheckDogMelee ())
- {
- self.attack_state = AS_MELEE;
- return TRUE;
- }
-
- if (CheckDogJump ())
- {
- self.attack_state = AS_MISSILE;
- return TRUE;
- }
-
- return FALSE;
-};
-
-
-//===========================================================================
-
-/*QUAKED monster_dog (1 0 0) (-32 -32 -24) (32 32 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/dog.mdl");
-}
-Rottweiler.
-
-Default health = 25
-
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound"
-snd_idle(string) : "Path to custom idle sound"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-skin_head(float) : "Skin index of custom head model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_dog =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- //dumptruck_ds -- model_custom and sounds changes
- precache_head_model ("progs/h_dog.mdl");
- precache_body_model ("progs/dog.mdl");
- precache_sound_attack ("dog/dattack1.wav");
- precache_sound_death ("dog/ddeath.wav");
- precache_sound_pain ("dog/dpain1.wav");
- precache_sound_sight ("dog/dsight.wav");
- precache_sound_idle ("dog/idle.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- // dumptruck_ds
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/dog.mdl"); //dumptruck_ds
- // setmodel (self, "progs/dog.mdl");
-
- setsize (self, '-32 -32 -24', '32 32 40');
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 25;
-
- self.th_stand = dog_stand1;
- self.th_walk = dog_walk1;
- self.th_run = dog_run1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = dog_pain;
- else
- self.th_pain = SUB_NullPain;
- self.th_die = dog_die;
- self.th_melee = dog_atta1;
- self.th_missile = dog_leap1;
-
- walkmonster_start();
-};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_dog (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/dog.mdl","frame":16});
-}
-*/
-void() monster_dead_dog =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/dog.mdl");
- setmodel(self, "progs/dog.mdl");
- self.frame = $death8;
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-24.51 -16.5 -50.37','28.2 13.81 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/monsters/enforcer.qc

diff --git a/qc-server/monsters/enforcer.qc b/qc-server/monsters/enforcer.qc
deleted file mode 100644
index 2b4b594..0000000
--- a/qc-server/monsters/enforcer.qc
+++ /dev/null
@@ -1,1044 +0,0 @@
-/*
-==============================================================================
-
-SOLDIER / PLAYER
-
-==============================================================================
-*/
-
-$cd id1/models/enforcer
-$origin 0 -6 24
-$base base
-$skin skin
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
-$frame walk11 walk12 walk13 walk14 walk15 walk16
-
-$frame run1 run2 run3 run4 run5 run6 run7 run8
-
-$frame attack1 attack2 attack3 attack4 attack5 attack6
-$frame attack7 attack8 attack9 attack10
-
-$frame death1 death2 death3 death4 death5 death6 death7 death8
-$frame death9 death10 death11 death12 death13 death14
-
-$frame fdeath1 fdeath2 fdeath3 fdeath4 fdeath5 fdeath6 fdeath7 fdeath8
-$frame fdeath9 fdeath10 fdeath11
-
-$frame paina1 paina2 paina3 paina4
-
-$frame painb1 painb2 painb3 painb4 painb5
-
-$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8
-
-$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8
-$frame paind9 paind10 paind11 paind12 paind13 paind14 paind15 paind16
-$frame paind17 paind18 paind19
-
-
-void() Laser_Touch =
-{
- local vector org;
-
- if (other == self.owner)
- return; // don't explode on owner
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
- sound_hit (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC); //dumptruck_ds
- org = self.origin - 8*normalize(self.velocity);
-
- if (other.health)
- {
- SpawnBlood (org, self.velocity*0.2, 15);
- T_Damage (other, self, self.owner, 15);
- }
- else
- {
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_GUNSHOT);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
- }
-
- remove(self);
-};
-
-void(vector org, vector vec) LaunchLaser =
-{
-
- local float projspeed = self.proj_speed_mod * 600;
-
- if (self.classname == "monster_enforcer" || self.classname == "monster_army")
- sound_attack (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
-
- vec = normalize(vec);
-
- newmis = spawn();
- newmis.snd_hit = self.snd_hit; // dumptruck_ds
- newmis.owner = self;
- newmis.movetype = MOVETYPE_FLY;
- newmis.solid = SOLID_BBOX;
- newmis.effects = EF_DIMLIGHT;
- newmis.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/laser.mdl");
- }
-
- if (!newmis.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
- // setmodel (newmis, "progs/laser.mdl");
- setsize (newmis, '0 0 0', '0 0 0');
-
- setorigin (newmis, org);
-
- SetSpeed(newmis, vec, projspeed);
- newmis.angles = vectoangles(newmis.velocity);
- if (self.homing > 0)
- {
- SetupHoming(newmis, projspeed);
- }
- else
- {
- newmis.nextthink = time + 5;
- newmis.think = SUB_Remove;
- }
- newmis.touch = Laser_Touch;
-};
-
-void(vector org, vector vec) EnfLaunchSpike =
-{
-
- local float projspeed = self.proj_speed_mod * 600;
-
- sound_attack (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
-
- vec = normalize(vec);
-
- newmis = spawn();
- newmis.owner = self;
- newmis.movetype = MOVETYPE_FLY;
- newmis.solid = SOLID_BBOX;
- // newmis.effects = EF_DIMLIGHT;
- newmis.skin = self.skin_proj; //dumptruck_ds
- // setmodel (newmis, "progs/s_spike.mdl");
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/s_spike.mdl");
- }
-
- if (!newmis.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
-// dumptruck_ds - end
- setsize (newmis, '0 0 0', '0 0 0');
-
- setorigin (newmis, org);
-
- SetSpeed(newmis, vec, projspeed);
- newmis.angles = vectoangles(newmis.velocity);
-
- if (self.homing > 0)
- {
- SetupHoming(newmis, projspeed);
- }
- else
- {
- newmis.nextthink = time + 5;
- newmis.think = SUB_Remove;
- }
- newmis.touch = superspike_touch;
-};
-
-//dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
-
-void() EnfMisTouch =
-{
- local float damg;
-
- if (other == self.owner)
- return; // don't explode on owner
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
- damg = 30 + random()*2; //dumptruck_ds
-
- if (other.health)
- {
- if (other.classname == "monster_shambler")
- damg = damg * 0.5; // mostly immune
- T_Damage (other, self, self.owner, damg );
- }
-
- // don't do radius damage to the other, because all the damage
- // was done in the impact
- T_RadiusDamage (self, self.owner, 40, other); //dumptruck_ds
-
-// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
- self.origin = self.origin - 8*normalize(self.velocity);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- BecomeExplosion ();
-};
-
-/*
-================
-EnfRocket //dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
-================
-*/
-void() EnfRocket =
-{
- local entity missile;
- local float projspeed = 900 * self.proj_speed_mod;
- // self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; dumptruck_ds
-
- sound_attack (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
-
- self.punchangle_x = -2;
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_FLYMISSILE;
- missile.solid = SOLID_BBOX;
- missile.classname = "missile";
-
-// set missile speed -- dumptruck_ds below
-
- SetSpeed(missile, normalize(self.enemy.origin - self.origin), projspeed);
- missile.angles = vectoangles(missile.velocity);
- missile.touch = EnfMisTouch;
-
- // makevectors (self.v_angle);
- // missile.velocity = aim(self, 1000);
- // missile.velocity = missile.velocity * 1000;
- // missile.angles = vectoangles(missile.velocity);
-
- // missile.touch = T_MissileTouch;
-
-// set missile duration
- if (self.homing > 0)
- {
- SetupHoming(missile, projspeed);
- }
- else
- {
- missile.nextthink = time + 5;
- missile.think = SUB_Remove;
- }
- missile.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/missile.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-// dumptruck_ds - end
- // setmodel (missile, "progs/missile.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
- setorigin (missile, self.origin + v_forward * 30 + v_right * 8.5 + '0 0 12'); //last number was 16 - dumptruck_ds
- // setorigin (missile, self.origin + v_forward*8 + '0 0 16');
-};
-//end dumptruck_ds grunt missle end
-/*
-================
-EnfFireGrenade
-================
-*/
-void() EnfFireGrenade =
-{
- local entity missile;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- sound_attack (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
-
-// set missile speed
-
- makevectors (self.angles);
-
- missile.velocity = normalize(self.enemy.origin - self.origin);
- missile.velocity = missile.velocity * 600;
- missile.velocity_z = 200;
-
- missile.avelocity = '300 300 300';
-
- missile.angles = vectoangles(missile.velocity);
-
- missile.touch = OgreGrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 2.5;
- missile.think = OgreGrenadeExplode;
- missile.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/grenade.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-// dumptruck_ds - end
-
- // setmodel (missile, "progs/grenade.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16');
- // setorigin (missile, self.origin);
-};
-
-void() EnfLightning =
-{
- local vector org, dir;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- sound_attack(self, CHAN_WEAPON, "weapons/lstart.wav", 1, ATTN_NORM);
- ai_face ();
- makevectors (self.angles);
- org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
-
- dir = self.enemy.origin - self.enemy.velocity * 0.075;
- dir = normalize (dir - org + '0 0 16');
-
- if (self.spawnflags & I_AM_TURRET)
- {
- traceline (org, self.origin + dir*900, TRUE, self);
- }
- else
- {
- traceline (org, self.origin + dir*600, TRUE, self);
- }
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
- WriteEntity (MSG_BROADCAST, self);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
- WriteCoord (MSG_BROADCAST, trace_endpos_x);
- WriteCoord (MSG_BROADCAST, trace_endpos_y);
- WriteCoord (MSG_BROADCAST, trace_endpos_z);
-
- LightningDamage (org, trace_endpos, self, 4);
-};
-
-
-// style stuff -- dumptruck_ds
-void() enforcer_fire =
-{
-
-if (self.style == 1)
-
- {
- self.effects = self.effects | EF_MUZZLEFLASH;
- ai_face();
- sound_attack (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
-
- EnfRocket();
- return;
- }
-
-else if (self.style == 2)
-
- {
- self.effects = self.effects | EF_MUZZLEFLASH;
- ai_face();
- if (self.spawnflags & I_AM_TURRET)
- {
- PreachFireGrenade(self.attack_elevation);
- }
- else
- EnfFireGrenade();
- return;
- }
-
-else if (self.style == 3 || self.style ==5)
-
- {
- local vector foo;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- makevectors (self.angles);
-
- foo = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
-
- EnfLaunchSpike(foo, self.enemy.origin - self.origin);
- return;
- }
-
-else
-
- local vector org;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- makevectors (self.angles);
-
- org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
-
- LaunchLaser(org, self.enemy.origin - self.origin);
-};
-
-//============================================================================
-
-void() enf_stand1 =[ $stand1, enf_stand2 ] {ai_stand();};
-void() enf_stand2 =[ $stand2, enf_stand3 ] {ai_stand();};
-void() enf_stand3 =[ $stand3, enf_stand4 ] {ai_stand();};
-void() enf_stand4 =[ $stand4, enf_stand5 ] {ai_stand();};
-void() enf_stand5 =[ $stand5, enf_stand6 ] {ai_stand();};
-void() enf_stand6 =[ $stand6, enf_stand7 ] {ai_stand();};
-void() enf_stand7 =[ $stand7, enf_stand1 ] {ai_stand();};
-
-void() enf_walk1 =[ $walk1 , enf_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); //dumptruck_ds
-ai_walk(2);};
-void() enf_walk2 =[ $walk2 , enf_walk3 ] {ai_walk(4);};
-void() enf_walk3 =[ $walk3 , enf_walk4 ] {ai_walk(4);};
-void() enf_walk4 =[ $walk4 , enf_walk5 ] {ai_walk(3);};
-void() enf_walk5 =[ $walk5 , enf_walk6 ] {ai_walk(1);};
-void() enf_walk6 =[ $walk6 , enf_walk7 ] {ai_walk(2);};
-void() enf_walk7 =[ $walk7 , enf_walk8 ] {ai_walk(2);};
-void() enf_walk8 =[ $walk8 , enf_walk9 ] {ai_walk(1);};
-void() enf_walk9 =[ $walk9 , enf_walk10 ] {ai_walk(2);};
-void() enf_walk10 =[ $walk10, enf_walk11 ] {ai_walk(4);};
-void() enf_walk11 =[ $walk11, enf_walk12 ] {ai_walk(4);};
-void() enf_walk12 =[ $walk12, enf_walk13 ] {ai_walk(1);};
-void() enf_walk13 =[ $walk13, enf_walk14 ] {ai_walk(2);};
-void() enf_walk14 =[ $walk14, enf_walk15 ] {ai_walk(3);};
-void() enf_walk15 =[ $walk15, enf_walk16 ] {ai_walk(4);};
-void() enf_walk16 =[ $walk16, enf_walk1 ] {ai_walk(2);};
-
-void() enf_run1 =[ $run1 , enf_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); //dumptruck_ds
-ai_run(18);};
-void() enf_run2 =[ $run2 , enf_run3 ] {ai_run(14);};
-void() enf_run3 =[ $run3 , enf_run4 ] {ai_run(7);};
-void() enf_run4 =[ $run4 , enf_run5 ] {ai_run(12);};
-void() enf_run5 =[ $run5 , enf_run6 ] {ai_run(14);};
-void() enf_run6 =[ $run6 , enf_run7 ] {ai_run(14);};
-void() enf_run7 =[ $run7 , enf_run8 ] {ai_run(7);};
-void() enf_run8 =[ $run8 , enf_run1 ] {ai_run(11);};
-
-void() enf_atk1 =[ $attack1, enf_atk2 ] {ai_face();};
-void() enf_atk2 =[ $attack2, enf_atk3 ] {ai_face();};
-void() enf_atk3 =[ $attack3, enf_atk4 ] {ai_face();};
-void() enf_atk4 =[ $attack4, enf_atk5 ] {ai_face();};
-void() enf_atk5 =[ $attack5, enf_atk6 ] {ai_face();};
-void() enf_atk6 =[ $attack6, enf_atk7 ] {enforcer_fire();};
-void() enf_atk7 =[ $attack7, enf_atk8 ] {ai_face();};
-void() enf_atk8 =[ $attack8, enf_atk9 ] {ai_face();};
-void() enf_atk9 =[ $attack5, enf_atk10 ] {ai_face();};
-void() enf_atk10 =[ $attack6, enf_atk11 ] {enforcer_fire();};
-void() enf_atk11 =[ $attack7, enf_atk12 ] {ai_face();};
-void() enf_atk12 =[ $attack8, enf_atk13 ] {ai_face();};
-void() enf_atk13 =[ $attack9, enf_atk14 ] {ai_face();};
-void() enf_atk14 =[ $attack10, enf_run1 ] {ai_face();SUB_CheckRefire (enf_atk1);
-};
-/* modified animation frames for style Enforcers */ // dumptruck_ds
-void() enf_2atk7;
-void() enf_2atk1 =[ $attack1, enf_2atk2 ] {ai_face();self.count = 0;self.t_length= 8 + floor(random()*6);};
-void() enf_2atk2 =[ $attack2, enf_2atk3 ] {ai_face();};
-void() enf_2atk3 =[ $attack3, enf_2atk4 ] {ai_face();};
-void() enf_2atk4 =[ $attack4, enf_2atk5 ] {ai_face();};
-void() enf_2atk5 =[ $attack5, enf_2atk6 ] {ai_face();};
-
-void() enf_2atk6 ={
-self.frame = $attack6;
-self.nextthink = time + .1;
-if (self.style == 5 && self.count < self.t_length)
-{
- self.count +=1;
-}
-else
-{
- self.think = enf_2atk7;
-}
-ai_face();
-enforcer_fire();};
-void() enf_2atk7 =[ $attack7, enf_2atk8 ] {ai_face();};
-void() enf_2atk8 =[ $attack8, enf_2atk9 ] {ai_face();};
-void() enf_2atk9 =[ $attack9, enf_2atk10 ] {ai_face();};
-void() enf_2atk10 =[ $attack10, enf_run1 ] {ai_face();SUB_CheckRefire (enf_2atk1);
-};
-
-void() enf_4atk1 =[ $attack1, enf_4atk2 ] {ai_face();};
-void() enf_4atk2 =[ $attack2, enf_4atk3 ] {ai_face();};
-void() enf_4atk3 =[ $attack3, enf_4atk4 ] {ai_face();};
-void() enf_4atk4 =[ $attack4, enf_4atk5 ] {ai_face();};
-void() enf_4atk5 =[ $attack5, enf_4atk6 ] {ai_face();};
-void() enf_4atk6 =[ $attack6, enf_4atk7 ] {EnfLightning();};
-void() enf_4atk7 =[ $attack6, enf_4atk8 ] {EnfLightning();};
-void() enf_4atk8 =[ $attack6, enf_4atk9 ] {EnfLightning();};
-void() enf_4atk9 =[ $attack7, enf_4atk10 ] {ai_face();};
-void() enf_4atk10 =[ $attack8, enf_4atk11 ] {ai_face();};
-void() enf_4atk11 =[ $attack9, enf_4atk12 ] {ai_face();};
-void() enf_4atk12 =[ $attack10, enf_run1 ] {ai_face();SUB_CheckRefire (enf_2atk1);
-};
-////////////////////////////
-// new frames for turret mode START
-////////////////////////////
-
-void() enf_turret_atk1 =[ $attack1, enf_turret_atk2 ] {ai_face();};
-void() enf_turret_atk2 =[ $attack2, enf_turret_atk3 ] {ai_face();};
-void() enf_turret_atk3 =[ $attack3, enf_turret_atk4 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() enf_turret_atk4 =[ $attack4, enf_turret_atk5 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() enf_turret_atk5 =[ $attack5, enf_turret_atk6 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() enf_turret_atk6 =[ $attack6, enf_turret_atk7 ] {enforcer_fire();};
-void() enf_turret_atk7 =[ $attack7, enf_turret_atk8 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() enf_turret_atk8 =[ $attack8, enf_turret_atk9 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() enf_turret_atk9 =[ $attack5, enf_turret_atk10 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() enf_turret_atk10 =[ $attack6, enf_turret_atk11 ] {enforcer_fire();};
-void() enf_turret_atk11 =[ $attack7, enf_turret_atk12 ] {ai_face();};
-void() enf_turret_atk12 =[ $attack8, enf_turret_atk13 ] {ai_face();};
-void() enf_turret_atk13 =[ $attack9, enf_turret_atk14 ] {ai_face();};
-void() enf_turret_atk14 =[ $attack10, enf_seek_stand1 ] {ai_face();SUB_CheckRefire (enf_turret_atk1);
-};
-void() enf_seek_stand1 =[ $stand1, enf_seek_stand2 ] {ai_run(0);};
-void() enf_seek_stand2 =[ $stand2, enf_seek_stand3 ] {ai_run(0);};
-void() enf_seek_stand3 =[ $stand3, enf_seek_stand4 ] {ai_run(0);};
-void() enf_seek_stand4 =[ $stand4, enf_seek_stand5 ] {ai_run(0);};
-void() enf_seek_stand5 =[ $stand5, enf_seek_stand6 ] {ai_run(0);};
-void() enf_seek_stand6 =[ $stand6, enf_seek_stand7 ] {ai_run(0);};
-void() enf_seek_stand7 =[ $stand7, enf_seek_stand1 ] {ai_run(0);};
-
-void() enf_2turret_atk7;
-void() enf_2turret_atk1 =[ $attack1, enf_2turret_atk2 ] {ai_face();self.count = 0;self.t_length= 4 + floor(random()*4);};
-void() enf_2turret_atk2 =[ $attack2, enf_2turret_atk3 ] {ai_face();};
-void() enf_2turret_atk3 =[ $attack3, enf_2turret_atk4 ] {ai_face();};
-void() enf_2turret_atk4 =[ $attack4, enf_2turret_atk5 ] {ai_face();};
-void() enf_2turret_atk5 =[ $attack5, enf_2turret_atk6 ] {ai_face();};
-
-void() enf_2turret_atk6 ={
-self.frame = $attack6;
-self.nextthink = time + .1;
-if (self.style == 5 && self.count < self.t_length)
-{
- self.count +=1;
-}
-else
-{
- self.think = enf_2turret_atk7;
-}
-ai_face();
-enforcer_fire();};
-void() enf_2turret_atk7 =[ $attack7, enf_2turret_atk8 ] {ai_face();};
-void() enf_2turret_atk8 =[ $attack8, enf_2turret_atk9 ] {ai_face();};
-void() enf_2turret_atk9 =[ $attack9, enf_2turret_atk10 ] {ai_face();};
-void() enf_2turret_atk10 =[ $attack10, enf_2stand1 ] {ai_face();SUB_CheckRefire (enf_2turret_atk1);
-};
-void() enf_4turret_atk1 =[ $attack1, enf_4turret_atk2 ] {ai_face();};
-void() enf_4turret_atk2 =[ $attack2, enf_4turret_atk3 ] {ai_face();};
-void() enf_4turret_atk3 =[ $attack3, enf_4turret_atk4 ] {ai_face();};
-void() enf_4turret_atk4 =[ $attack4, enf_4turret_atk5 ] {ai_face();};
-void() enf_4turret_atk5 =[ $attack5, enf_4turret_atk6 ] {ai_face();};
-void() enf_4turret_atk6 =[ $attack6, enf_4turret_atk7 ] {EnfLightning();};
-void() enf_4turret_atk7 =[ $attack6, enf_4turret_atk8 ] {EnfLightning();};
-void() enf_4turret_atk8 =[ $attack6, enf_4turret_atk9 ] {EnfLightning();};
-void() enf_4turret_atk9 =[ $attack7, enf_4turret_atk10 ] {ai_face();};
-void() enf_4turret_atk10 =[ $attack8, enf_4turret_atk11 ] {ai_face();};
-void() enf_4turret_atk11 =[ $attack9, enf_4turret_atk12 ] {ai_face();};
-void() enf_4turret_atk12 =[ $attack10, enf_2stand1 ] {ai_face();SUB_CheckRefire (enf_2turret_atk1);
-};
-void() enf_2stand1 =[ $stand1, enf_2stand2 ] {ai_run(0);};
-void() enf_2stand2 =[ $stand2, enf_2stand3 ] {ai_run(0);};
-void() enf_2stand3 =[ $stand3, enf_2stand4 ] {ai_run(0);};
-void() enf_2stand4 =[ $stand4, enf_2stand5 ] {ai_run(0);};
-void() enf_2stand5 =[ $stand5, enf_2stand6 ] {ai_run(0);};
-void() enf_2stand6 =[ $stand6, enf_2stand7 ] {ai_run(0);};
-void() enf_2stand7 =[ $stand7, enf_2stand1 ] {ai_run(0);};
-////////////////////////////
-// new frames for turret mode END
-////////////////////////////
-void() enf_paina1 =[ $paina1, enf_paina2 ] {};
-void() enf_paina2 =[ $paina2, enf_paina3 ] {};
-void() enf_paina3 =[ $paina3, enf_paina4 ] {};
-void() enf_paina4 =[ $paina4, enf_run1 ] {};
-
-void() enf_painb1 =[ $painb1, enf_painb2 ] {};
-void() enf_painb2 =[ $painb2, enf_painb3 ] {};
-void() enf_painb3 =[ $painb3, enf_painb4 ] {};
-void() enf_painb4 =[ $painb4, enf_painb5 ] {};
-void() enf_painb5 =[ $painb5, enf_run1 ] {};
-
-void() enf_painc1 =[ $painc1, enf_painc2 ] {};
-void() enf_painc2 =[ $painc2, enf_painc3 ] {};
-void() enf_painc3 =[ $painc3, enf_painc4 ] {};
-void() enf_painc4 =[ $painc4, enf_painc5 ] {};
-void() enf_painc5 =[ $painc5, enf_painc6 ] {};
-void() enf_painc6 =[ $painc6, enf_painc7 ] {};
-void() enf_painc7 =[ $painc7, enf_painc8 ] {};
-void() enf_painc8 =[ $painc8, enf_run1 ] {};
-
-void() enf_paind1 =[ $paind1, enf_paind2 ] {};
-void() enf_paind2 =[ $paind2, enf_paind3 ] {};
-void() enf_paind3 =[ $paind3, enf_paind4 ] {};
-void() enf_paind4 =[ $paind4, enf_paind5 ] {ai_painforward(2);};
-void() enf_paind5 =[ $paind5, enf_paind6 ] {ai_painforward(1);};
-void() enf_paind6 =[ $paind6, enf_paind7 ] {};
-void() enf_paind7 =[ $paind7, enf_paind8 ] {};
-void() enf_paind8 =[ $paind8, enf_paind9 ] {};
-void() enf_paind9 =[ $paind9, enf_paind10 ] {};
-void() enf_paind10 =[ $paind10, enf_paind11 ] {};
-void() enf_paind11 =[ $paind11, enf_paind12 ] {ai_painforward(1);};
-void() enf_paind12 =[ $paind12, enf_paind13 ] {ai_painforward(1);};
-void() enf_paind13 =[ $paind13, enf_paind14 ] {ai_painforward(1);};
-void() enf_paind14 =[ $paind14, enf_paind15 ] {};
-void() enf_paind15 =[ $paind15, enf_paind16 ] {};
-void() enf_paind16 =[ $paind16, enf_paind17 ] {ai_pain(1);};
-void() enf_paind17 =[ $paind17, enf_paind18 ] {ai_pain(1);};
-void() enf_paind18 =[ $paind18, enf_paind19 ] {};
-void() enf_paind19 =[ $paind19, enf_run1 ] {};
-
-void(entity attacker, float damage) enf_pain =
-{
- local float r;
-
- r = random ();
-
- if (self.pain_finished > time)
- return;
-
- if (r < 0.5)
- sound_pain (self, CHAN_VOICE, "enforcer/pain1.wav", 1, ATTN_NORM); //dumptruck_ds
- else
- sound_misc3 (self, CHAN_VOICE, "enforcer/pain2.wav", 1, ATTN_NORM); // dumptruck_ds
-
- if (r < 0.2)
- {
- self.pain_finished = time + 1;
- // moved these here to avoid spamming pain sounds - dumptruck_ds
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- enf_paina1 ();
- }
- else if (r < 0.4)
- {
- self.pain_finished = time + 1;
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- enf_painb1 ();
- }
- else if (r < 0.7)
- {
- self.pain_finished = time + 1;
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- enf_painc1 ();
- }
- else
- {
- self.pain_finished = time + 2;
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- enf_paind1 ();
- }
-};
-
-//============================================================================
-
-
-
-
-void() enf_die1 =[ $death1, enf_die2 ] {};
-void() enf_die2 =[ $death2, enf_die3 ] {};
-void() enf_die3 =[ $death3, enf_die4 ]
-{
- self.solid = SOLID_NOT;
-
- if (self.style == 1) // style ammotype check -- dumptruck_ds
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 2) // style ammotype check -- dumptruck_ds
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 3 || self.style == 5) // style ammotype check -- dumptruck_ds
- {
- self.ammo_nails = 5;
- }
- if (self.style == 0 || self.style == 4) // style ammotype check -- dumptruck_ds
- {
- self.ammo_cells = 5;
- }
- if(!self.keep_ammo)DropBackpack();
-};
-void() enf_die4 =[ $death4, enf_die5 ] {ai_forward(14);};
-void() enf_die5 =[ $death5, enf_die6 ] {ai_forward(2);};
-void() enf_die6 =[ $death6, enf_die7 ] {};
-void() enf_die7 =[ $death7, enf_die8 ] {};
-void() enf_die8 =[ $death8, enf_die9 ] {};
-void() enf_die9 =[ $death9, enf_die10 ] {ai_forward(3);};
-void() enf_die10 =[ $death10, enf_die11 ] {ai_forward(5);};
-void() enf_die11 =[ $death11, enf_die12 ] {ai_forward(5);};
-void() enf_die12 =[ $death12, enf_die13 ] {ai_forward(5);};
-void() enf_die13 =[ $death13, enf_die14 ] {};
-void() enf_die14 =[ $death14, enf_die14 ] {};
-
-void() enf_fdie1 =[ $fdeath1, enf_fdie2 ] {
-
-};
-void() enf_fdie2 =[ $fdeath2, enf_fdie3 ] {};
-void() enf_fdie3 =[ $fdeath3, enf_fdie4 ]
-{
- self.solid = SOLID_NOT;
-
- if (self.style == 1) // style ammotype check -- dumptruck_ds
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 2) // style ammotype check -- dumptruck_ds
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 3 || self.style == 5) // style ammotype check -- dumptruck_ds
- {
- self.ammo_nails = 5;
- }
- if (self.style == 0 || self.style == 4) // style ammotype check -- dumptruck_ds
- {
- self.ammo_cells = 5;
- }
- if(!self.keep_ammo)DropBackpack();
-};
-void() enf_fdie4 =[ $fdeath4, enf_fdie5 ] {};
-void() enf_fdie5 =[ $fdeath5, enf_fdie6 ] {};
-void() enf_fdie6 =[ $fdeath6, enf_fdie7 ] {};
-void() enf_fdie7 =[ $fdeath7, enf_fdie8 ] {};
-void() enf_fdie8 =[ $fdeath8, enf_fdie9 ] {};
-void() enf_fdie9 =[ $fdeath9, enf_fdie10 ] {};
-void() enf_fdie10 =[ $fdeath10, enf_fdie11 ] {};
-void() enf_fdie11 =[ $fdeath11, enf_fdie11 ] {};
-
-
-void() enf_die =
-{
-// check for gib
- if (self.health < -35)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_mega.mdl", self.health);
- }
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- DropStuff();
- return;
- }
-
-// regular death
- sound_death (self, CHAN_VOICE, "enforcer/death1.wav", 1, ATTN_NORM); //dumptruck_ds
- DropStuff();
- if (random() > 0.5)
- enf_die1 ();
- else
- enf_fdie1 ();
-};
-
-
-/*QUAKED monster_enforcer (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/enforcer.mdl");
-}
-Enforcer.
-
-Default health = 80
-
-keep_ammo(integer) : "1 = Don't drop backpack upon death"
-
-style(Choices) : "Attack type"
-0 : "Default (lasers)"
-1 : "rockets"
-2 : "grenades"
-3 : "nails"
-
-snd_death(string) : Path to custom death sound"
-snd_pain(string) : "Path to 1st custom pain sound"
-snd_sight(string) : "Path to custom sight sound for STOP!"
-snd_attack(string) : Path to custom attack sound e.g laser firing"
-snd_hit(string) : "Path to custom hit sound e.g. laser hits wall"
-snd_idle(string) : "Path to custom idle sound"
-snd_misc(string) : "Path to custom sight sound for FREEZE!"
-snd_misc1(string) : "Path to custom sight sound for YOU THERE!"
-snd_misc2(string) : "Path to custom sight sound for HALT!"
-snd_misc3(string) : "Path to 2nd custom pain sound"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-mdl_proj(string) : "Path to custom projectile model"
-skin_head(float) : "Skin index of custom head model"
-skin_proj(float) : "Skin index of custom projectile model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_enforcer =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- if (self.style >= 6)
- objerror("style key set too high\n");
-
- precache_body_model2 ("progs/enforcer.mdl"); // custom_mdls function -- dumptruck_ds
- precache_head_model2 ("progs/h_mega.mdl");
- precache_proj_model2 ("progs/laser.mdl");
- precache_proj_model2 ("progs/s_spike.mdl");
- precache_proj_model2 ("progs/missile.mdl");
- //dumptruck_ds
- precache_sound2_death ("enforcer/death1.wav");
- precache_sound2_attack ("enforcer/enfire.wav");
- precache_sound2_hit ("enforcer/enfstop.wav");
- precache_sound2_idle ("enforcer/idle1.wav");
- precache_sound2_pain ("enforcer/pain1.wav");
- precache_sound2_misc3 ("enforcer/pain2.wav");
- precache_sound2_sight ("enforcer/sight1.wav");
- precache_sound2_misc ("enforcer/sight2.wav"); // these will be replaced with custom noise fields eventually - dumptruck_ds
- precache_sound2_misc1 ("enforcer/sight3.wav");
- precache_sound2_misc2 ("enforcer/sight4.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/enforcer.mdl"); // SPIKE to the RESCUE!!!! - got this fixed. -- dumptruck_ds
- // // setmodel (self, "progs/enforcer.mdl"); //orginal dumptruck_ds
-
- setsize (self, '-16 -16 -24', '16 16 40');
-
- if (!self.proj_speed_mod)
- {
- self.proj_speed_mod = 1;
- }
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 80;
-
- self.th_stand = enf_stand1;
- self.th_walk = enf_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = enf_2stand1;
- }
- else
- {
- self.th_run = enf_run1;
- }
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = enf_pain;
- else
- self.th_pain = SUB_NullPain;
- self.th_die = enf_die;
- if (self.style == 1 || self.style == 2 || self.style == 5) // new animation frame check -- dumptruck_ds
- {
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_turret = enf_2turret_atk1;
- }
- self.th_missile = enf_2atk1;
- }
- else if (self.style == 0 || self.style == 3 ) // new animation frame check -- dumptruck_ds
- {
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_turret = enf_turret_atk1;
- }
- self.th_missile = enf_atk1;
- }
- else if (self.style == 4) // new animation frame check -- dumptruck_ds
- {
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_turret = enf_4turret_atk1;
- }
- self.th_missile = enf_4atk1;
- }
- walkmonster_start();
-};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_enforcer (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID FACE_UP X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/enforcer.mdl","frame":54});
-}
-*/
-void() monster_dead_enforcer =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/enforcer.mdl");
- setmodel(self, "progs/enforcer.mdl");
- if (self.spawnflags & 2)
- {
- self.frame = $fdeath11;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-41.16 -45.65 -51.95','21.45 25.49 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
- else
- {
- self.frame = $death14;
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-39.85 -29.35 -49.07','20.52 33.17 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/monsters/fish.qc

diff --git a/qc-server/monsters/fish.qc b/qc-server/monsters/fish.qc
deleted file mode 100644
index b4aead5..0000000
--- a/qc-server/monsters/fish.qc
+++ /dev/null
@@ -1,306 +0,0 @@
-$cd id1/models/fish
-$origin 0 0 24
-$base base
-$skin skin
-
-$frame attack1 attack2 attack3 attack4 attack5 attack6
-$frame attack7 attack8 attack9 attack10 attack11 attack12 attack13
-$frame attack14 attack15 attack16 attack17 attack18
-
-$frame death1 death2 death3 death4 death5 death6 death7
-$frame death8 death9 death10 death11 death12 death13 death14 death15
-$frame death16 death17 death18 death19 death20 death21
-
-$frame swim1 swim2 swim3 swim4 swim5 swim6 swim7 swim8
-$frame swim9 swim10 swim11 swim12 swim13 swim14 swim15 swim16 swim17
-$frame swim18
-
-$frame pain1 pain2 pain3 pain4 pain5 pain6 pain7 pain8
-$frame pain9
-
-void() swimmonster_start;
-
-void() f_stand1 =[ $swim1, f_stand2 ] {ai_stand();};
-void() f_stand2 =[ $swim2, f_stand3 ] {ai_stand();};
-void() f_stand3 =[ $swim3, f_stand4 ] {ai_stand();};
-void() f_stand4 =[ $swim4, f_stand5 ] {ai_stand();};
-void() f_stand5 =[ $swim5, f_stand6 ] {ai_stand();};
-void() f_stand6 =[ $swim6, f_stand7 ] {ai_stand();};
-void() f_stand7 =[ $swim7, f_stand8 ] {ai_stand();};
-void() f_stand8 =[ $swim8, f_stand9 ] {ai_stand();};
-void() f_stand9 =[ $swim9, f_stand10 ] {ai_stand();};
-void() f_stand10 =[ $swim10, f_stand11 ] {ai_stand();};
-void() f_stand11 =[ $swim11, f_stand12 ] {ai_stand();};
-void() f_stand12 =[ $swim12, f_stand13 ] {ai_stand();};
-void() f_stand13 =[ $swim13, f_stand14 ] {ai_stand();};
-void() f_stand14 =[ $swim14, f_stand15 ] {ai_stand();};
-void() f_stand15 =[ $swim15, f_stand16 ] {ai_stand();};
-void() f_stand16 =[ $swim16, f_stand17 ] {ai_stand();};
-void() f_stand17 =[ $swim17, f_stand18 ] {ai_stand();};
-void() f_stand18 =[ $swim18, f_stand1 ] {ai_stand();};
-
-void() f_walk1 =[ $swim1, f_walk2 ] {ai_walk(8);};
-void() f_walk2 =[ $swim2, f_walk3 ] {ai_walk(8);};
-void() f_walk3 =[ $swim3, f_walk4 ] {ai_walk(8);};
-void() f_walk4 =[ $swim4, f_walk5 ] {ai_walk(8);};
-void() f_walk5 =[ $swim5, f_walk6 ] {ai_walk(8);};
-void() f_walk6 =[ $swim6, f_walk7 ] {ai_walk(8);};
-void() f_walk7 =[ $swim7, f_walk8 ] {ai_walk(8);};
-void() f_walk8 =[ $swim8, f_walk9 ] {ai_walk(8);};
-void() f_walk9 =[ $swim9, f_walk10 ] {ai_walk(8);};
-void() f_walk10 =[ $swim10, f_walk11 ] {ai_walk(8);};
-void() f_walk11 =[ $swim11, f_walk12 ] {ai_walk(8);};
-void() f_walk12 =[ $swim12, f_walk13 ] {ai_walk(8);};
-void() f_walk13 =[ $swim13, f_walk14 ] {ai_walk(8);};
-void() f_walk14 =[ $swim14, f_walk15 ] {ai_walk(8);};
-void() f_walk15 =[ $swim15, f_walk16 ] {ai_walk(8);};
-void() f_walk16 =[ $swim16, f_walk17 ] {ai_walk(8);};
-void() f_walk17 =[ $swim17, f_walk18 ] {ai_walk(8);};
-void() f_walk18 =[ $swim18, f_walk1 ] {ai_walk(8);};
-
-void() f_run1 =[ $swim1, f_run2 ] {ai_run(12);
- if (random() < 0.5)
- sound_idle (self, CHAN_VOICE, "fish/idle.wav", 1, ATTN_NORM);
-};
-void() f_run2 =[ $swim3, f_run3 ] {ai_run(12);};
-void() f_run3 =[ $swim5, f_run4 ] {ai_run(12);};
-void() f_run4 =[ $swim7, f_run5 ] {ai_run(12);};
-void() f_run5 =[ $swim9, f_run6 ] {ai_run(12);};
-void() f_run6 =[ $swim11, f_run7 ] {ai_run(12);};
-void() f_run7 =[ $swim13, f_run8 ] {ai_run(12);};
-void() f_run8 =[ $swim15, f_run9 ] {ai_run(12);};
-void() f_run9 =[ $swim17, f_run1 ] {ai_run(12);};
-
-void() fish_melee =
-{
- local vector delta;
- local float ldmg;
-
- if (!self.enemy)
- return; // removed before stroke
-
- delta = self.enemy.origin - self.origin;
-
- if (vlen(delta) > 60)
- return;
-
- sound_attack (self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
- ldmg = (random() + random()) * 3;
- T_Damage (self.enemy, self, self, ldmg);
-};
-
-void() f_attack1 =[ $attack1, f_attack2 ] {ai_charge(10);};
-void() f_attack2 =[ $attack2, f_attack3 ] {ai_charge(10);};
-void() f_attack3 =[ $attack3, f_attack4 ] {fish_melee();};
-void() f_attack4 =[ $attack4, f_attack5 ] {ai_charge(10);};
-void() f_attack5 =[ $attack5, f_attack6 ] {ai_charge(10);};
-void() f_attack6 =[ $attack6, f_attack7 ] {ai_charge(10);};
-void() f_attack7 =[ $attack7, f_attack8 ] {ai_charge(10);};
-void() f_attack8 =[ $attack8, f_attack9 ] {ai_charge(10);};
-void() f_attack9 =[ $attack9, f_attack10] {fish_melee();};
-void() f_attack10 =[ $attack10, f_attack11] {ai_charge(10);};
-void() f_attack11 =[ $attack11, f_attack12] {ai_charge(10);};
-void() f_attack12 =[ $attack12, f_attack13] {ai_charge(10);};
-void() f_attack13 =[ $attack13, f_attack14] {ai_charge(10);};
-void() f_attack14 =[ $attack14, f_attack15] {ai_charge(10);};
-void() f_attack15 =[ $attack15, f_attack16] {fish_melee();};
-void() f_attack16 =[ $attack16, f_attack17] {ai_charge(10);};
-void() f_attack17 =[ $attack17, f_attack18] {ai_charge(10);};
-void() f_attack18 =[ $attack18, f_run1 ] {ai_charge(10);};
-
-void() f_death1 =[ $death1, f_death2 ]
- {
- self.solid = SOLID_NOT;
- sound_death (self, CHAN_VOICE, "fish/death.wav", 1, ATTN_NORM);
- };
-void() f_death2 =[ $death2, f_death3 ] {};
-void() f_death3 =[ $death3, f_death4 ] {};
-void() f_death4 =[ $death4, f_death5 ] {};
-void() f_death5 =[ $death5, f_death6 ] {};
-void() f_death6 =[ $death6, f_death7 ] {};
-void() f_death7 =[ $death7, f_death8 ] {};
-void() f_death8 =[ $death8, f_death9 ] {};
-void() f_death9 =[ $death9, f_death10 ] {};
-void() f_death10 =[ $death10, f_death11 ] {};
-void() f_death11 =[ $death11, f_death12 ] {};
-void() f_death12 =[ $death12, f_death13 ] {};
-void() f_death13 =[ $death13, f_death14 ] {};
-void() f_death14 =[ $death14, f_death15 ] {};
-void() f_death15 =[ $death15, f_death16 ] {};
-void() f_death16 =[ $death16, f_death17 ] {};
-void() f_death17 =[ $death17, f_death18 ] {};
-void() f_death18 =[ $death18, f_death19 ] {};
-void() f_death19 =[ $death19, f_death20 ] {};
-void() f_death20 =[ $death20, f_death21 ] {};
-void() f_death21 =[ $death21, f_death21 ] {};
-
-void() fish_die =
-{
- if (self.health < -35) //fish gibs -- dumptruck_ds
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- // ThrowGib ("progs/gib3.mdl", self.health);
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_head != "")
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_dog.mdl", self.health);
- }
- DropStuff();
- SUB_Remove();
- }
- // regular death
- else
- {
- DropStuff();
- f_death1();
- }
-};
-
-void() f_pain1 =[ $pain1, f_pain2 ] {};
-void() f_pain2 =[ $pain2, f_pain3 ] {ai_pain(6);};
-void() f_pain3 =[ $pain3, f_pain4 ] {ai_pain(6);};
-void() f_pain4 =[ $pain4, f_pain5 ] {ai_pain(6);};
-void() f_pain5 =[ $pain5, f_pain6 ] {ai_pain(6);};
-void() f_pain6 =[ $pain6, f_pain7 ] {ai_pain(6);};
-void() f_pain7 =[ $pain7, f_pain8 ] {ai_pain(6);};
-void() f_pain8 =[ $pain8, f_pain9 ] {ai_pain(6);};
-void() f_pain9 =[ $pain9, f_run1 ] {ai_pain(6);};
-
-void(entity attacker, float damage) fish_pain =
-{
-// fish always do pain frames
- f_pain1 ();
-};
-
-
-
-/*QUAKED monster_fish (1 0 0) (-16 -16 -24) (16 16 24) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/fish.mdl");
-}
-Rotfish.
-
-Default health = 25"
-
-snd_death(string) : "Path to custom death sound (BUBBLES)"
-snd_attack(string) : "Path to custom attack sound (CRUNCHY BITE)"
-snd_idle(string) : "Path to custom idle sound"
-
-mdl_body(string) : "Path to custom body model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_fish =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- precache_body_model2 ("progs/fish.mdl");
- // precache_model2 ("progs/fish.mdl");
-
- precache_sound2_death ("fish/death.wav");
- precache_sound2_attack ("fish/bite.wav");
- precache_sound2_idle ("fish/idle.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/fish.mdl");
- // setmodel (self, "progs/fish.mdl");
-
- setsize (self, '-16 -16 -24', '16 16 24');
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 25;
-
- self.th_stand = f_stand1;
- self.th_walk = f_walk1;
- self.th_run = f_run1;
- // self.th_die = f_death1;
- self.th_die = fish_die;
- if !(self.berserk) //Berserk from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = fish_pain;
- else
- self.th_pain = SUB_NullPain;
- self.th_melee = f_attack1;
-
- swimmonster_start ();
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/monsters/hknight.qc

diff --git a/qc-server/monsters/hknight.qc b/qc-server/monsters/hknight.qc
deleted file mode 100644
index 10aa2a3..0000000
--- a/qc-server/monsters/hknight.qc
+++ /dev/null
@@ -1,755 +0,0 @@
-/*
-==============================================================================
-
-KNIGHT
-
-==============================================================================
-*/
-
-$cd id1/models/knight2
-$origin 0 0 24
-$base base
-$skin skin
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9
-$frame walk10 walk11 walk12 walk13 walk14 walk15 walk16 walk17
-$frame walk18 walk19 walk20
-
-$frame run1 run2 run3 run4 run5 run6 run7 run8
-
-$frame pain1 pain2 pain3 pain4 pain5
-
-$frame death1 death2 death3 death4 death5 death6 death7 death8
-$frame death9 death10 death11 death12
-
-$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
-$frame deathb9
-
-$frame char_a1 char_a2 char_a3 char_a4 char_a5 char_a6 char_a7 char_a8
-$frame char_a9 char_a10 char_a11 char_a12 char_a13 char_a14 char_a15 char_a16
-
-$frame magica1 magica2 magica3 magica4 magica5 magica6 magica7 magica8
-$frame magica9 magica10 magica11 magica12 magica13 magica14
-
-$frame magicb1 magicb2 magicb3 magicb4 magicb5 magicb6 magicb7 magicb8
-$frame magicb9 magicb10 magicb11 magicb12 magicb13
-
-$frame char_b1 char_b2 char_b3 char_b4 char_b5 char_b6
-
-$frame slice1 slice2 slice3 slice4 slice5 slice6 slice7 slice8 slice9 slice10
-
-$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 smash8 smash9 smash10
-$frame smash11
-
-$frame w_attack1 w_attack2 w_attack3 w_attack4 w_attack5 w_attack6 w_attack7
-$frame w_attack8 w_attack9 w_attack10 w_attack11 w_attack12 w_attack13 w_attack14
-$frame w_attack15 w_attack16 w_attack17 w_attack18 w_attack19 w_attack20
-$frame w_attack21 w_attack22
-
-$frame magicc1 magicc2 magicc3 magicc4 magicc5 magicc6 magicc7 magicc8
-$frame magicc9 magicc10 magicc11
-
-
-void() hknight_char_a1;
-void() hknight_run1;
-void() hk_idle_sound;
-
-void(float offset) hknight_shot =
-{
- local vector offang;
- local vector org, vec;
- local float exploding = self.projexpl == 1 || (self.projexpl == 2 && offset % 2 == 0) || (self.projexpl == 3 && random()*2 < 1);
- offang = vectoangles (self.enemy.origin - self.origin);
- offang_y = offang_y + offset * 6;
-
- makevectors (offang);
-
- org = self.origin + self.mins + self.size*0.5 + v_forward * 20;
-
-// set missile speed
- vec = normalize (v_forward);
- vec_z = 0 - vec_z + (random() - 0.5)*0.1;
-
- launch_spike2 (org, vec, 300);
- newmis.classname = "knightspike";
- // setmodel (newmis, "progs/k_spike.mdl");
- if (exploding)
- {
- newmis.touch = T_HellKnightMisTouch;
- if (self.mdl_exproj != "") // dumptruck_ds custom_mdls
- {
- setmodel (newmis, self.mdl_exproj);
- }
- else
- {
- setmodel (newmis, "progs/k_spike2.mdl");
- }
-
- if (self.skin_exproj) // dumptruck_ds
- {
- newmis.skin = self.skin_exproj;
- }
- else
- {
- newmis.skin = 0;
- }
- }
- else
- {
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/k_spike.mdl");
- }
-
- if (self.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
- }
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- sound_attack (self, CHAN_WEAPON, "hknight/attack1.wav", 1, ATTN_NORM);
-};
-
-void() CheckForCharge =
-{
-// check for mad charge
-if (!enemy_vis)
- return;
-if (time < self.attack_finished)
- return;
-if ( fabs(self.origin_z - self.enemy.origin_z) > 20)
- return; // too much height change
-if ( vlen (self.origin - self.enemy.origin) < 80)
- return; // use regular attack
-
-// charge
- SUB_AttackFinished (2);
- hknight_char_a1 ();
-
-};
-
-void() CheckContinueCharge =
-{
- if (time > self.attack_finished)
- {
- SUB_AttackFinished (3);
- hknight_run1 ();
- return; // done charging
- }
- if (random() > 0.5)
- sound (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM);
- else
- sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
-};
-
-//===========================================================================
-
-void() hknight_stand1 =[ $stand1, hknight_stand2 ] {ai_stand();};
-void() hknight_stand2 =[ $stand2, hknight_stand3 ] {ai_stand();};
-void() hknight_stand3 =[ $stand3, hknight_stand4 ] {ai_stand();};
-void() hknight_stand4 =[ $stand4, hknight_stand5 ] {ai_stand();};
-void() hknight_stand5 =[ $stand5, hknight_stand6 ] {ai_stand();};
-void() hknight_stand6 =[ $stand6, hknight_stand7 ] {ai_stand();};
-void() hknight_stand7 =[ $stand7, hknight_stand8 ] {ai_stand();};
-void() hknight_stand8 =[ $stand8, hknight_stand9 ] {ai_stand();};
-void() hknight_stand9 =[ $stand9, hknight_stand1 ] {ai_stand();};
-
-//===========================================================================
-
-void() hknight_walk1 =[ $walk1, hknight_walk2 ] {
-hk_idle_sound();
-ai_walk(2);};
-void() hknight_walk2 =[ $walk2, hknight_walk3 ] {ai_walk(5);};
-void() hknight_walk3 =[ $walk3, hknight_walk4 ] {ai_walk(5);};
-void() hknight_walk4 =[ $walk4, hknight_walk5 ] {ai_walk(4);};
-void() hknight_walk5 =[ $walk5, hknight_walk6 ] {ai_walk(4);};
-void() hknight_walk6 =[ $walk6, hknight_walk7 ] {ai_walk(2);};
-void() hknight_walk7 =[ $walk7, hknight_walk8 ] {ai_walk(2);};
-void() hknight_walk8 =[ $walk8, hknight_walk9 ] {ai_walk(3);};
-void() hknight_walk9 =[ $walk9, hknight_walk10 ] {ai_walk(3);};
-void() hknight_walk10 =[ $walk10, hknight_walk11 ] {ai_walk(4);};
-void() hknight_walk11 =[ $walk11, hknight_walk12 ] {ai_walk(3);};
-void() hknight_walk12 =[ $walk12, hknight_walk13 ] {ai_walk(4);};
-void() hknight_walk13 =[ $walk13, hknight_walk14 ] {ai_walk(6);};
-void() hknight_walk14 =[ $walk14, hknight_walk15 ] {ai_walk(2);};
-void() hknight_walk15 =[ $walk15, hknight_walk16 ] {ai_walk(2);};
-void() hknight_walk16 =[ $walk16, hknight_walk17 ] {ai_walk(4);};
-void() hknight_walk17 =[ $walk17, hknight_walk18 ] {ai_walk(3);};
-void() hknight_walk18 =[ $walk18, hknight_walk19 ] {ai_walk(3);};
-void() hknight_walk19 =[ $walk19, hknight_walk20 ] {ai_walk(3);};
-void() hknight_walk20 =[ $walk20, hknight_walk1 ] {ai_walk(2);};
-
-//===========================================================================
-
-void() hknight_run1 =[ $run1, hknight_run2 ] {
-hk_idle_sound();
-ai_run (20); CheckForCharge (); };
-void() hknight_run2 =[ $run2, hknight_run3 ] {ai_run(25);};
-void() hknight_run3 =[ $run3, hknight_run4 ] {ai_run(18);};
-void() hknight_run4 =[ $run4, hknight_run5 ] {ai_run(16);};
-void() hknight_run5 =[ $run5, hknight_run6 ] {ai_run(14);};
-void() hknight_run6 =[ $run6, hknight_run7 ] {ai_run(25);};
-void() hknight_run7 =[ $run7, hknight_run8 ] {ai_run(21);};
-void() hknight_run8 =[ $run8, hknight_run1 ] {ai_run(13);};
-
-//============================================================================
-
-void() hknight_pain1 =[ $pain1, hknight_pain2 ] {sound_pain (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);};
-void() hknight_pain2 =[ $pain2, hknight_pain3 ] {};
-void() hknight_pain3 =[ $pain3, hknight_pain4 ] {};
-void() hknight_pain4 =[ $pain4, hknight_pain5 ] {};
-void() hknight_pain5 =[ $pain5, hknight_run1 ] {};
-
-//============================================================================
-
-void() hknight_die1 =[ $death1, hknight_die2 ] {ai_forward(10);};
-void() hknight_die2 =[ $death2, hknight_die3 ] {ai_forward(8);};
-void() hknight_die3 =[ $death3, hknight_die4 ]{self.solid = SOLID_NOT;ai_forward(7);};
-void() hknight_die4 =[ $death4, hknight_die5 ] {};
-void() hknight_die5 =[ $death5, hknight_die6 ] {};
-void() hknight_die6 =[ $death6, hknight_die7 ] {};
-void() hknight_die7 =[ $death7, hknight_die8 ] {};
-void() hknight_die8 =[ $death8, hknight_die9 ] {ai_forward(10);};
-void() hknight_die9 =[ $death9, hknight_die10 ] {ai_forward(11);};
-void() hknight_die10 =[ $death10, hknight_die11 ] {};
-void() hknight_die11 =[ $death11, hknight_die12 ] {};
-void() hknight_die12 =[ $death12, hknight_die12 ] {};
-
-void() hknight_dieb1 =[ $deathb1, hknight_dieb2 ] {};
-void() hknight_dieb2 =[ $deathb2, hknight_dieb3 ] {};
-void() hknight_dieb3 =[ $deathb3, hknight_dieb4 ] {self.solid = SOLID_NOT;};
-void() hknight_dieb4 =[ $deathb4, hknight_dieb5 ] {};
-void() hknight_dieb5 =[ $deathb5, hknight_dieb6 ] {};
-void() hknight_dieb6 =[ $deathb6, hknight_dieb7 ] {};
-void() hknight_dieb7 =[ $deathb7, hknight_dieb8 ] {};
-void() hknight_dieb8 =[ $deathb8, hknight_dieb9 ] {};
-void() hknight_dieb9 =[ $deathb9, hknight_dieb9 ] {};
-
-void() hknight_die =
-{
-// check for gib
- if (self.health < -40)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_hellkn.mdl", self.health);
- }
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- DropStuff();
- return;
- }
-
-// regular death
- sound_death (self, CHAN_VOICE, "hknight/death1.wav", 1, ATTN_NORM);
- DropStuff();
- if (random() > 0.5)
- hknight_die1 ();
- else
- hknight_dieb1 ();
-};
-
-
-//============================================================================
-
-void() hknight_magica1 =[ $magica1, hknight_magica2 ] {ai_face();};
-void() hknight_magica2 =[ $magica2, hknight_magica3 ] {ai_face();};
-void() hknight_magica3 =[ $magica3, hknight_magica4 ] {ai_face();};
-void() hknight_magica4 =[ $magica4, hknight_magica5 ] {ai_face();};
-void() hknight_magica5 =[ $magica5, hknight_magica6 ] {ai_face();};
-void() hknight_magica6 =[ $magica6, hknight_magica7 ] {ai_face();};
-void() hknight_magica7 =[ $magica7, hknight_magica8 ] {hknight_shot(-2);};
-void() hknight_magica8 =[ $magica8, hknight_magica9 ] {hknight_shot(-1);};
-void() hknight_magica9 =[ $magica9, hknight_magica10] {hknight_shot(0);};
-void() hknight_magica10 =[ $magica10, hknight_magica11] {hknight_shot(1);};
-void() hknight_magica11 =[ $magica11, hknight_magica12] {hknight_shot(2);};
-void() hknight_magica12 =[ $magica12, hknight_magica13] {hknight_shot(3);};
-void() hknight_magica13 =[ $magica13, hknight_magica14] {ai_face();};
-void() hknight_magica14 =[ $magica14, hknight_run1 ] {ai_face();};
-
-//============================================================================
-
-void() HellKnightLightning =
-{
- local vector org, dir;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- sound_attack(self, CHAN_WEAPON, "weapons/lstart.wav", 1, ATTN_NORM);
- ai_face ();
- makevectors (self.angles);
- org = self.origin + v_forward * 50 + '0 0 20';
-
- dir = self.enemy.origin - self.enemy.velocity * 0.075;
- dir = normalize (dir - org + '0 0 16');
-
- if (self.spawnflags & I_AM_TURRET)
- {
- traceline (org, self.origin + dir*900, TRUE, self);
- }
- else
- {
- traceline (org, self.origin + dir*600, TRUE, self);
- }
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
- WriteEntity (MSG_BROADCAST, self);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
- WriteCoord (MSG_BROADCAST, trace_endpos_x);
- WriteCoord (MSG_BROADCAST, trace_endpos_y);
- WriteCoord (MSG_BROADCAST, trace_endpos_z);
-
- LightningDamage (org, trace_endpos, self, 20);
-};
-void() hknight_magicb1 =[ $magicb1, hknight_magicb2 ] {ai_face();};
-void() hknight_magicb2 =[ $magicb2, hknight_magicb3 ] {ai_face();};
-void() hknight_magicb3 =[ $magicb3, hknight_magicb4 ] {ai_face();};
-void() hknight_magicb4 =[ $magicb4, hknight_magicb5 ] {ai_face();};
-void() hknight_magicb5 =[ $magicb5, hknight_magicb6 ] {ai_face();};
-void() hknight_magicb6 =[ $magicb6, hknight_magicb7 ] {ai_face();};
-void() hknight_magicb7 =[ $magicb7, hknight_magicb8 ] {ai_face();};
-void() hknight_magicb8 =[ $magicb8, hknight_magicb9 ] {ai_face();};
-void() hknight_magicb9 =[ $magicb9, hknight_magicb10] {ai_face();};
-void() hknight_magicb10 =[ $magicb10, hknight_magicb11] {ai_face();sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);HellKnightLightning();};
-void() hknight_magicb11 =[ $magicb11, hknight_magicb12] {ai_face();};
-void() hknight_magicb12 =[ $magicb12, hknight_magicb13] {ai_face();};
-void() hknight_magicb13 =[ $magicb13, hknight_run1] {ai_face();};
-
-//============================================================================
-
-void() hknight_magicc1 =[ $magicc1, hknight_magicc2 ] {ai_face();};
-void() hknight_magicc2 =[ $magicc2, hknight_magicc3 ] {ai_face();};
-void() hknight_magicc3 =[ $magicc3, hknight_magicc4 ] {ai_face();};
-void() hknight_magicc4 =[ $magicc4, hknight_magicc5 ] {ai_face();};
-void() hknight_magicc5 =[ $magicc5, hknight_magicc6 ] {ai_face();};
-void() hknight_magicc6 =[ $magicc6, hknight_magicc7 ] {hknight_shot(-2);};
-void() hknight_magicc7 =[ $magicc7, hknight_magicc8 ] {hknight_shot(-1);};
-void() hknight_magicc8 =[ $magicc8, hknight_magicc9 ] {hknight_shot(0);};
-void() hknight_magicc9 =[ $magicc9, hknight_magicc10] {hknight_shot(1);};
-void() hknight_magicc10 =[ $magicc10, hknight_magicc11] {hknight_shot(2);};
-void() hknight_magicc11 =[ $magicc11, hknight_run1] {hknight_shot(3);};
-
-//============================================================================
-///////////////////////////////////////
-////// turret frames START - revisions
-//////////////////////////////////////
-void() hknight_turret_magicc1 =[ $magicc1, hknight_turret_magicc2 ] {ai_face();};
-void() hknight_turret_magicc2 =[ $magicc2, hknight_turret_magicc3 ] {ai_face();};
-void() hknight_turret_magicc3 =[ $magicc3, hknight_turret_magicc4 ] {ai_face();};
-void() hknight_turret_magicc4 =[ $magicc4, hknight_turret_magicc5 ] {ai_face();};
-void() hknight_turret_magicc5 =[ $magicc5, hknight_turret_magicc6 ] {ai_face();};
-void() hknight_turret_magicc6 =[ $magicc6, hknight_turret_magicc7 ] {hknight_shot(-2);};
-void() hknight_turret_magicc7 =[ $magicc7, hknight_turret_magicc8 ] {hknight_shot(-1);};
-void() hknight_turret_magicc8 =[ $magicc8, hknight_turret_magicc9 ] {hknight_shot(0);};
-void() hknight_turret_magicc9 =[ $magicc9, hknight_turret_magicc10] {hknight_shot(1);};
-void() hknight_turret_magicc10 =[ $magicc10, hknight_turret_magicc11] {hknight_shot(2);};
-void() hknight_turret_magicc11 =[ $magicc11, hknight_turret_magicc12] {ai_face();};
-void() hknight_turret_magicc12 =[ $stand1, hknight_turret_magicc13 ] {ai_face();};
-void() hknight_turret_magicc13 =[ $stand2, hknight_turret_magicc14 ] {ai_face();};
-void() hknight_turret_magicc14 =[ $stand3, hknight_turret_magicc15 ] {ai_face();};
-void() hknight_turret_magicc15 =[ $stand4, hknight_seek_stand1 ] {ai_run(0);};
-void() hknight_seek_stand1 =[ $stand1, hknight_seek_stand2 ] {ai_run(0);};
-void() hknight_seek_stand2 =[ $stand2, hknight_seek_stand3 ] {ai_run(0);};
-void() hknight_seek_stand3 =[ $stand3, hknight_seek_stand4 ] {ai_run(0);};
-void() hknight_seek_stand4 =[ $stand4, hknight_seek_stand5 ] {ai_run(0);};
-void() hknight_seek_stand5 =[ $stand5, hknight_seek_stand6 ] {ai_run(0);};
-void() hknight_seek_stand6 =[ $stand6, hknight_seek_stand7 ] {ai_run(0);};
-void() hknight_seek_stand7 =[ $stand7, hknight_seek_stand8 ] {ai_run(0);};
-void() hknight_seek_stand8 =[ $stand8, hknight_seek_stand9 ] {ai_run(0);};
-void() hknight_seek_stand9 =[ $stand9, hknight_seek_stand1 ] {ai_run(0);};
-
-void() hknight_turret_magicb1 =[ $magicb1, hknight_turret_magicb2 ] {ai_face();};
-void() hknight_turret_magicb2 =[ $magicb2, hknight_turret_magicb3 ] {ai_face();};
-void() hknight_turret_magicb3 =[ $magicb3, hknight_turret_magicb4 ] {ai_face();};
-void() hknight_turret_magicb4 =[ $magicb4, hknight_turret_magicb5 ] {ai_face();};
-void() hknight_turret_magicb5 =[ $magicb5, hknight_turret_magicb6 ] {ai_face();};
-void() hknight_turret_magicb6 =[ $magicb6, hknight_turret_magicb7 ] {ai_face();};
-void() hknight_turret_magicb7 =[ $magicb7, hknight_turret_magicb8 ] {ai_face();};
-void() hknight_turret_magicb8 =[ $magicb8, hknight_turret_magicb9 ] {ai_face();};
-void() hknight_turret_magicb9 =[ $magicb9, hknight_turret_magicb10] {ai_face();};
-void() hknight_turret_magicb10 =[ $magicb10, hknight_turret_magicb11] {ai_face();sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);HellKnightLightning();};
-void() hknight_turret_magicb11 =[ $magicb11, hknight_turret_magicb12] {ai_face();};
-void() hknight_turret_magicb12 =[ $magicb12, hknight_turret_magicb13] {ai_face();};
-void() hknight_turret_magicb13 =[ $magicb13, hknight_seek_stand1] {ai_face();};
-/////////////////////////
-////// turret frames END
-/////////////////////////
-
-//===========================================================================
-
-void() hknight_char_a1 =[ $char_a1, hknight_char_a2 ] {ai_charge(20);};
-void() hknight_char_a2 =[ $char_a2, hknight_char_a3 ] {ai_charge(25);};
-void() hknight_char_a3 =[ $char_a3, hknight_char_a4 ] {ai_charge(18);};
-void() hknight_char_a4 =[ $char_a4, hknight_char_a5 ] {ai_charge(16);};
-void() hknight_char_a5 =[ $char_a5, hknight_char_a6 ] {ai_charge(14);};
-void() hknight_char_a6 =[ $char_a6, hknight_char_a7 ] {ai_charge(20); ai_melee();};
-void() hknight_char_a7 =[ $char_a7, hknight_char_a8 ] {ai_charge(21); ai_melee();};
-void() hknight_char_a8 =[ $char_a8, hknight_char_a9 ] {ai_charge(13); ai_melee();};
-void() hknight_char_a9 =[ $char_a9, hknight_char_a10 ] {ai_charge(20); ai_melee();};
-void() hknight_char_a10=[ $char_a10, hknight_char_a11 ] {ai_charge(20); ai_melee();};
-void() hknight_char_a11=[ $char_a11, hknight_char_a12 ] {ai_charge(18); ai_melee();};
-void() hknight_char_a12=[ $char_a12, hknight_char_a13 ] {ai_charge(16);};
-void() hknight_char_a13=[ $char_a13, hknight_char_a14 ] {ai_charge(14);};
-void() hknight_char_a14=[ $char_a14, hknight_char_a15 ] {ai_charge(25);};
-void() hknight_char_a15=[ $char_a15, hknight_char_a16 ] {ai_charge(21);};
-void() hknight_char_a16=[ $char_a16, hknight_run1 ] {ai_charge(13);};
-
-//===========================================================================
-
-void() hknight_char_b1 =[ $char_b1, hknight_char_b2 ]
-{CheckContinueCharge (); ai_charge(23); ai_melee();};
-void() hknight_char_b2 =[ $char_b2, hknight_char_b3 ] {ai_charge(17); ai_melee();};
-void() hknight_char_b3 =[ $char_b3, hknight_char_b4 ] {ai_charge(12); ai_melee();};
-void() hknight_char_b4 =[ $char_b4, hknight_char_b5 ] {ai_charge(22); ai_melee();};
-void() hknight_char_b5 =[ $char_b5, hknight_char_b6 ] {ai_charge(18); ai_melee();};
-void() hknight_char_b6 =[ $char_b6, hknight_char_b1 ] {ai_charge(8); ai_melee();};
-
-//===========================================================================
-
-void() hknight_slice1 =[ $slice1, hknight_slice2 ] {ai_charge(9);};
-void() hknight_slice2 =[ $slice2, hknight_slice3 ] {ai_charge(6);};
-void() hknight_slice3 =[ $slice3, hknight_slice4 ] {ai_charge(13);};
-void() hknight_slice4 =[ $slice4, hknight_slice5 ] {ai_charge(4);};
-void() hknight_slice5 =[ $slice5, hknight_slice6 ] {ai_charge(7); ai_melee();};
-void() hknight_slice6 =[ $slice6, hknight_slice7 ] {ai_charge(15); ai_melee();};
-void() hknight_slice7 =[ $slice7, hknight_slice8 ] {ai_charge(8); ai_melee();};
-void() hknight_slice8 =[ $slice8, hknight_slice9 ] {ai_charge(2); ai_melee();};
-void() hknight_slice9 =[ $slice9, hknight_slice10 ] {ai_melee();};
-void() hknight_slice10 =[ $slice10, hknight_run1 ] {ai_charge(3);};
-
-//===========================================================================
-
-void() hknight_smash1 =[ $smash1, hknight_smash2 ] {ai_charge(1);};
-void() hknight_smash2 =[ $smash2, hknight_smash3 ] {ai_charge(13);};
-void() hknight_smash3 =[ $smash3, hknight_smash4 ] {ai_charge(9);};
-void() hknight_smash4 =[ $smash4, hknight_smash5 ] {ai_charge(11);};
-void() hknight_smash5 =[ $smash5, hknight_smash6 ] {ai_charge(10); ai_melee();};
-void() hknight_smash6 =[ $smash6, hknight_smash7 ] {ai_charge(7); ai_melee();};
-void() hknight_smash7 =[ $smash7, hknight_smash8 ] {ai_charge(12); ai_melee();};
-void() hknight_smash8 =[ $smash8, hknight_smash9 ] {ai_charge(2); ai_melee();};
-void() hknight_smash9 =[ $smash9, hknight_smash10 ] {ai_charge(3); ai_melee();};
-void() hknight_smash10 =[ $smash10, hknight_smash11 ] {ai_charge(0);};
-void() hknight_smash11 =[ $smash11, hknight_run1 ] {ai_charge(0);};
-
-//============================================================================
-
-void() hknight_watk1 =[ $w_attack1, hknight_watk2 ] {ai_charge(2);};
-void() hknight_watk2 =[ $w_attack2, hknight_watk3 ] {ai_charge(0);};
-void() hknight_watk3 =[ $w_attack3, hknight_watk4 ] {ai_charge(0);};
-void() hknight_watk4 =[ $w_attack4, hknight_watk5 ] {ai_melee();};
-void() hknight_watk5 =[ $w_attack5, hknight_watk6 ] {ai_melee();};
-void() hknight_watk6 =[ $w_attack6, hknight_watk7 ] {ai_melee();};
-void() hknight_watk7 =[ $w_attack7, hknight_watk8 ] {ai_charge(1);};
-void() hknight_watk8 =[ $w_attack8, hknight_watk9 ] {ai_charge(4);};
-void() hknight_watk9 =[ $w_attack9, hknight_watk10 ] {ai_charge(5);};
-void() hknight_watk10 =[ $w_attack10, hknight_watk11 ] {ai_charge(3); ai_melee();};
-void() hknight_watk11 =[ $w_attack11, hknight_watk12 ] {ai_charge(2); ai_melee();};
-void() hknight_watk12 =[ $w_attack12, hknight_watk13 ] {ai_charge(2); ai_melee();};
-void() hknight_watk13 =[ $w_attack13, hknight_watk14 ] {ai_charge(0);};
-void() hknight_watk14 =[ $w_attack14, hknight_watk15 ] {ai_charge(0);};
-void() hknight_watk15 =[ $w_attack15, hknight_watk16 ] {ai_charge(0);};
-void() hknight_watk16 =[ $w_attack16, hknight_watk17 ] {ai_charge(1);};
-void() hknight_watk17 =[ $w_attack17, hknight_watk18 ] {ai_charge(1); ai_melee();};
-void() hknight_watk18 =[ $w_attack18, hknight_watk19 ] {ai_charge(3); ai_melee();};
-void() hknight_watk19 =[ $w_attack19, hknight_watk20 ] {ai_charge(4); ai_melee();};
-void() hknight_watk20 =[ $w_attack20, hknight_watk21 ] {ai_charge(6);};
-void() hknight_watk21 =[ $w_attack21, hknight_watk22 ] {ai_charge(7);};
-void() hknight_watk22 =[ $w_attack22, hknight_run1 ] {ai_charge(3);};
-
-//============================================================================
-
-void() hk_idle_sound =
-{
- if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "hknight/idle.wav", 1, ATTN_NORM);
-};
-
-void(entity attacker, float damage) hknight_pain =
-{
- local float r;
-
- r = random();
-
- if (self.pain_finished > time)
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- {
- if (r < 0.5)
- {
- self.pain_finished = time + 1.5;
- sound_pain (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);
- }
- return;
- }
-
- sound_pain (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);
-
- if (time - self.pain_finished > 5)
- { // always go into pain frame if it has been a while
- hknight_pain1 ();
- self.pain_finished = time + 1;
- return;
- }
-
- if ((random()*30 > damage) )
- return; // didn't flinch
-
- self.pain_finished = time + 1;
- hknight_pain1 ();
-};
-
-float hknight_type;
-
-void() hknight_melee =
-{
- hknight_type = hknight_type + 1;
-
- sound_misc (self, CHAN_WEAPON, "hknight/slash1.wav", 1, ATTN_NORM);
- if (hknight_type == 1)
- hknight_slice1 ();
- else if (hknight_type == 2)
- hknight_smash1 ();
- else if (hknight_type == 3)
- {
- hknight_watk1 ();
- hknight_type = 0;
- }
-};
-
-/*QUAKED monster_hell_knight (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/hknight.mdl");
-}
-Hellknight.
-
-Default health = 250"
-
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound (MAGIC BOING)"
-snd_idle(string) : Path to custom idle sound"
-snd_misc(string) : Path to custom SWORD SLASH sound"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-mdl_proj(string) : "Path to custom projectile model"
-mdl_exproj(string) : "Path to custom projectile model for exploding projectiles"
-skin_head(float) : "Skin index of custom head model"
-skin_proj(float) : "Skin index of custom projectile model"
-skin_exproj(float) : "Skin index of custom projectile model for exploding projectiles"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-projexpl(choices) : "Exploding projectiles"
-0 : "No explosions"
-1 : "All projectiles explode"
-2 : "Every other projectile explodes"
-3 : "Random per projectile"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_hell_knight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
-
- precache_model2 ("progs/hknight.mdl");
- precache_model2 ("progs/k_spike.mdl");
- precache_model2 ("progs/k_spike2.mdl");
- precache_model2 ("progs/h_hellkn.mdl");
- //dumptruck_ds custom_mdls
- precache_body_model2 ("progs/hknight.mdl");
- precache_head_model2 ("progs/h_hellkn.mdl");
- precache_proj_model2 ("progs/k_spike.mdl");
- precache_exproj_model2 ("progs/k_spike2.mdl"); // this needed a unique name defiined in custom_mdls.qc -- dumptruck_ds
-// dumptruck_ds
-
- precache_sound2_attack ("hknight/attack1.wav");
- precache_sound2_death ("hknight/death1.wav");
- precache_sound2_pain ("hknight/pain1.wav");
- precache_sound2_sight ("hknight/sight1.wav");
- precache_sound ("hknight/hit.wav"); // used by C code, so don't sound2
- precache_sound2_misc ("hknight/slash1.wav");
- precache_sound2_idle ("hknight/idle.wav");
- precache_sound2 ("hknight/grunt.wav"); // what??? never knew about this! -- dumptruck_ds
-
- precache_sound ("knight/sword1.wav");
- precache_sound ("knight/sword2.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/hknight.mdl"); // custom_mdls dumptruck_ds
- // setmodel (self, "progs/hknight.mdl");
-
- setsize (self, '-16 -16 -24', '16 16 40');
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 250;
-
- if (!self.proj_speed_mod)
- {
- self.proj_speed_mod = 1;
- }
-
- self.th_stand = hknight_stand1;
- self.th_walk = hknight_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = hknight_seek_stand1;
- }
- else
- {
- self.th_run = hknight_run1;
- }
- self.th_melee = hknight_melee;
- if (self.style == 1)
- {
- self.th_missile = hknight_magicb1;
- self.th_turret = hknight_turret_magicb1;
- }
- else
- {
- self.th_missile = hknight_magicc1;
- self.th_turret = hknight_turret_magicc1;
- }
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = hknight_pain;
- else
- self.th_pain = SUB_NullPain;
- self.th_die = hknight_die;
-
- walkmonster_start ();
-};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_hell_knight (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/hknight.mdl","frame":62});
-}
-*/
-void() monster_dead_hell_knight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/hknight.mdl");
- setmodel(self, "progs/hknight.mdl");
- if (self.spawnflags & 2)
- {
- self.frame = $deathb9;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-68.96 -20.43 -53.98','34.8 21.15 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
- else
- {
- self.frame = $death12;
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-42.05 -31.07 -51.56','46.34 25.02 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/monsters/knight.qc

diff --git a/qc-server/monsters/knight.qc b/qc-server/monsters/knight.qc
deleted file mode 100644
index bdfbb0e..0000000
--- a/qc-server/monsters/knight.qc
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
-==============================================================================
-
-KNIGHT
-
-==============================================================================
-*/
-
-$cd id1/models/knight
-$origin 0 0 24
-$base base
-$skin badass3
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
-
-$frame runb1 runb2 runb3 runb4 runb5 runb6 runb7 runb8
-
-//frame runc1 runc2 runc3 runc4 runc5 runc6
-
-$frame runattack1 runattack2 runattack3 runattack4 runattack5
-$frame runattack6 runattack7 runattack8 runattack9 runattack10
-$frame runattack11
-
-$frame pain1 pain2 pain3
-
-$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9
-$frame painb10 painb11
-
-//frame attack1 attack2 attack3 attack4 attack5 attack6 attack7
-//frame attack8 attack9 attack10 attack11
-
-$frame attackdummy
-$frame attackb1 attackb2 attackb3 attackb4 attackb5
-$frame attackb6 attackb7 attackb8 attackb9 attackb10
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9
-$frame walk10 walk11 walk12 walk13 walk14
-
-$frame kneel1 kneel2 kneel3 kneel4 kneel5
-
-$frame standing2 standing3 standing4 standing5
-
-$frame death1 death2 death3 death4 death5 death6 death7 death8
-$frame death9 death10
-
-$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
-$frame deathb9 deathb10 deathb11
-
-void() knight_stand1 =[ $stand1, knight_stand2 ] {ai_stand();};
-void() knight_stand2 =[ $stand2, knight_stand3 ] {ai_stand();};
-void() knight_stand3 =[ $stand3, knight_stand4 ] {ai_stand();};
-void() knight_stand4 =[ $stand4, knight_stand5 ] {ai_stand();};
-void() knight_stand5 =[ $stand5, knight_stand6 ] {ai_stand();};
-void() knight_stand6 =[ $stand6, knight_stand7 ] {ai_stand();};
-void() knight_stand7 =[ $stand7, knight_stand8 ] {ai_stand();};
-void() knight_stand8 =[ $stand8, knight_stand9 ] {ai_stand();};
-void() knight_stand9 =[ $stand9, knight_stand1 ] {ai_stand();};
-
-void() knight_walk1 =[ $walk1, knight_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE);
-ai_walk(3);};
-void() knight_walk2 =[ $walk2, knight_walk3 ] {ai_walk(2);};
-void() knight_walk3 =[ $walk3, knight_walk4 ] {ai_walk(3);};
-void() knight_walk4 =[ $walk4, knight_walk5 ] {ai_walk(4);};
-void() knight_walk5 =[ $walk5, knight_walk6 ] {ai_walk(3);};
-void() knight_walk6 =[ $walk6, knight_walk7 ] {ai_walk(3);};
-void() knight_walk7 =[ $walk7, knight_walk8 ] {ai_walk(3);};
-void() knight_walk8 =[ $walk8, knight_walk9 ] {ai_walk(4);};
-void() knight_walk9 =[ $walk9, knight_walk10 ] {ai_walk(3);};
-void() knight_walk10 =[ $walk10, knight_walk11 ] {ai_walk(3);};
-void() knight_walk11 =[ $walk11, knight_walk12 ] {ai_walk(2);};
-void() knight_walk12 =[ $walk12, knight_walk13 ] {ai_walk(3);};
-void() knight_walk13 =[ $walk13, knight_walk14 ] {ai_walk(4);};
-void() knight_walk14 =[ $walk14, knight_walk1 ] {ai_walk(3);};
-
-
-void() knight_run1 =[ $runb1, knight_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE);
-ai_run(16);};
-void() knight_run2 =[ $runb2, knight_run3 ] {ai_run(20);};
-void() knight_run3 =[ $runb3, knight_run4 ] {ai_run(13);};
-void() knight_run4 =[ $runb4, knight_run5 ] {ai_run(7);};
-void() knight_run5 =[ $runb5, knight_run6 ] {ai_run(16);};
-void() knight_run6 =[ $runb6, knight_run7 ] {ai_run(20);};
-void() knight_run7 =[ $runb7, knight_run8 ] {ai_run(14);};
-void() knight_run8 =[ $runb8, knight_run1 ] {ai_run(6);};
-
-
-void() knight_runatk1 =[ $runattack1, knight_runatk2 ]
-{
-if (random() > 0.5)
- sound_misc (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM);
-else
- sound_attack(self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
-ai_charge(20);
-};
-void() knight_runatk2 =[ $runattack2, knight_runatk3 ] {ai_charge_side();};
-void() knight_runatk3 =[ $runattack3, knight_runatk4 ] {ai_charge_side();};
-void() knight_runatk4 =[ $runattack4, knight_runatk5 ] {ai_charge_side();};
-void() knight_runatk5 =[ $runattack5, knight_runatk6 ] {ai_melee_side();};
-void() knight_runatk6 =[ $runattack6, knight_runatk7 ] {ai_melee_side();};
-void() knight_runatk7 =[ $runattack7, knight_runatk8 ] {ai_melee_side();};
-void() knight_runatk8 =[ $runattack8, knight_runatk9 ] {ai_melee_side();};
-void() knight_runatk9 =[ $runattack9, knight_runatk10 ] {ai_melee_side();};
-void() knight_runatk10 =[ $runattack10, knight_runatk11 ] {ai_charge_side();};
-void() knight_runatk11 =[ $runattack11, knight_run1 ] {ai_charge(10);};
-
-void() knight_atk1 =[ $attackb1, knight_atk2 ]
-{
-sound_attack(self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
-ai_charge(0);};
-void() knight_atk2 =[ $attackb2, knight_atk3 ] {ai_charge(7);};
-void() knight_atk3 =[ $attackb3, knight_atk4 ] {ai_charge(4);};
-void() knight_atk4 =[ $attackb4, knight_atk5 ] {ai_charge(0);};
-void() knight_atk5 =[ $attackb5, knight_atk6 ] {ai_charge(3);};
-void() knight_atk6 =[ $attackb6, knight_atk7 ] {ai_charge(4); ai_melee();};
-void() knight_atk7 =[ $attackb7, knight_atk8 ] {ai_charge(1); ai_melee();};
-void() knight_atk8 =[ $attackb8, knight_atk9 ] {ai_charge(3);
-ai_melee();};
-void() knight_atk9 =[ $attackb9, knight_atk10] {ai_charge(1);};
-void() knight_atk10=[ $attackb10, knight_run1 ] {ai_charge(5);};
-
-//void() knight_atk9 =[ $attack9, knight_atk10 ] {};
-//void() knight_atk10 =[ $attack10, knight_atk11 ] {};
-//void() knight_atk11 =[ $attack11, knight_run1 ] {};
-
-//===========================================================================
-
-void() knight_pain1 =[ $pain1, knight_pain2 ] {};
-void() knight_pain2 =[ $pain2, knight_pain3 ] {};
-void() knight_pain3 =[ $pain3, knight_run1 ] {};
-
-void() knight_painb1 =[ $painb1, knight_painb2 ] {ai_painforward(0);};
-void() knight_painb2 =[ $painb2, knight_painb3 ] {ai_painforward(3);};
-void() knight_painb3 =[ $painb3, knight_painb4 ] {};
-void() knight_painb4 =[ $painb4, knight_painb5 ] {};
-void() knight_painb5 =[ $painb5, knight_painb6 ] {ai_painforward(2);};
-void() knight_painb6 =[ $painb6, knight_painb7 ] {ai_painforward(4);};
-void() knight_painb7 =[ $painb7, knight_painb8 ] {ai_painforward(2);};
-void() knight_painb8 =[ $painb8, knight_painb9 ] {ai_painforward(5);};
-void() knight_painb9 =[ $painb9, knight_painb10 ] {ai_painforward(5);};
-void() knight_painb10 =[ $painb10, knight_painb11 ] {ai_painforward(0);};
-void() knight_painb11 =[ $painb11, knight_run1 ] {};
-
-void(entity attacker, float damage) knight_pain =
-{
- local float r;
-
- if (self.pain_finished > time)
- return;
-
- r = random();
-
- sound_pain (self, CHAN_VOICE, "knight/khurt.wav", 1, ATTN_NORM);
- if (r < 0.85)
- {
- knight_pain1 ();
- self.pain_finished = time + 1;
- }
- else
- {
- knight_painb1 ();
- self.pain_finished = time + 1;
- }
-
-};
-
-//===========================================================================
-
-void() knight_bow1 =[ $kneel1, knight_bow2 ] {ai_turn();};
-void() knight_bow2 =[ $kneel2, knight_bow3 ] {ai_turn();};
-void() knight_bow3 =[ $kneel3, knight_bow4 ] {ai_turn();};
-void() knight_bow4 =[ $kneel4, knight_bow5 ] {ai_turn();};
-
-void() knight_bow5 =[ $kneel5, knight_bow5 ] {ai_turn();};
-
-void() knight_bow6 =[ $kneel4, knight_bow7 ] {ai_turn();};
-void() knight_bow7 =[ $kneel3, knight_bow8 ] {ai_turn();};
-void() knight_bow8 =[ $kneel2, knight_bow9 ] {ai_turn();};
-void() knight_bow9 =[ $kneel1, knight_bow10 ] {ai_turn();};
-void() knight_bow10 =[ $walk1, knight_walk1 ] {ai_turn();};
-
-
-
-void() knight_die1 =[ $death1, knight_die2 ] {};
-void() knight_die2 =[ $death2, knight_die3 ] {};
-void() knight_die3 =[ $death3, knight_die4 ] {self.solid = SOLID_NOT;};
-void() knight_die4 =[ $death4, knight_die5 ] {};
-void() knight_die5 =[ $death5, knight_die6 ] {};
-void() knight_die6 =[ $death6, knight_die7 ] {};
-void() knight_die7 =[ $death7, knight_die8 ] {};
-void() knight_die8 =[ $death8, knight_die9 ] {};
-void() knight_die9 =[ $death9, knight_die10] {};
-void() knight_die10=[ $death10, knight_die10] {};
-
-
-void() knight_dieb1 =[ $deathb1, knight_dieb2 ] {};
-void() knight_dieb2 =[ $deathb2, knight_dieb3 ] {};
-void() knight_dieb3 =[ $deathb3, knight_dieb4 ] {self.solid = SOLID_NOT;};
-void() knight_dieb4 =[ $deathb4, knight_dieb5 ] {};
-void() knight_dieb5 =[ $deathb5, knight_dieb6 ] {};
-void() knight_dieb6 =[ $deathb6, knight_dieb7 ] {};
-void() knight_dieb7 =[ $deathb7, knight_dieb8 ] {};
-void() knight_dieb8 =[ $deathb8, knight_dieb9 ] {};
-void() knight_dieb9 =[ $deathb9, knight_dieb10] {};
-void() knight_dieb10 = [ $deathb10, knight_dieb11] {};
-void() knight_dieb11 = [ $deathb11, knight_dieb11] {};
-
-
-void() knight_die =
-{
-// check for gib
- if (self.health < -40)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_knight.mdl", self.health);
- }
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- DropStuff();
- return;
- }
-
-// regular death
- sound_death (self, CHAN_VOICE, "knight/kdeath.wav", 1, ATTN_NORM);
- DropStuff();
- if (random() < 0.5)
- knight_die1 ();
- else
- knight_dieb1 ();
-};
-
-
-/*QUAKED monster_knight (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/knight.mdl");
-}
-Knight.
-
-Default heath = 75"
-
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound (SWORD SLASH 1)"
-snd_idle(string) : "Path to custom idle sound"
-snd_misc(string) : "Path to custom sound (SWORD SLASH 2)"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-skin_head(float) : "Skin index of custom head model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_knight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- // dumptruck_ds custom_mdls
- precache_body_model ("progs/knight.mdl");
- precache_head_model ("progs/h_knight.mdl");
- //// dumptruck_ds
- precache_sound_death ("knight/kdeath.wav");
- precache_sound_pain ("knight/khurt.wav");
- precache_sound_sight ("knight/ksight.wav");
- precache_sound_attack ("knight/sword1.wav");
- precache_sound_misc ("knight/sword2.wav");
- precache_sound_idle ("knight/idle.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/knight.mdl"); // dumptruck_ds custom_mdls
- // setmodel (self, "progs/knight.mdl");
-
- setsize (self, '-16 -16 -24', '16 16 40');
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 75;
-
- self.th_stand = knight_stand1;
- self.th_walk = knight_walk1;
- self.th_run = knight_run1;
- self.th_melee = knight_atk1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = knight_pain;
- else
- self.th_pain = SUB_NullPain;
- self.th_die = knight_die;
-
- walkmonster_start ();
-};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_knight (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID ON_SIDE X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/knight.mdl","frame":96});
-}
-*/
-void() monster_dead_knight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/knight.mdl");
- setmodel(self, "progs/knight.mdl");
- if (self.spawnflags & 2)
- {
- self.frame = $death10;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-25.56 -14.56 -50.49','26.45 40.2 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
- else
- {
- self.frame = $deathb11;
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-30.36 -45.6 -50.18','28.29 11.59 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/monsters/ogre.qc

diff --git a/qc-server/monsters/ogre.qc b/qc-server/monsters/ogre.qc
deleted file mode 100644
index 0a1f132..0000000
--- a/qc-server/monsters/ogre.qc
+++ /dev/null
@@ -1,1571 +0,0 @@
-float MONSTER_FLAK_OGRE = 4;
-float FL_NOSELECT = 8192; //ignored by entity selector
-.float spikecount; //bdw - saves up flak hits to do a single damage next frame - currently only used for flak ogre
-
-/*
-==============================================================================
-
-OGRE
-
-==============================================================================
-*/
-
-$cd id1/models/ogre_c
-$origin 0 0 24
-$base base
-$skin base
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7
-$frame walk8 walk9 walk10 walk11 walk12 walk13 walk14 walk15 walk16
-
-$frame run1 run2 run3 run4 run5 run6 run7 run8
-
-$frame swing1 swing2 swing3 swing4 swing5 swing6 swing7
-$frame swing8 swing9 swing10 swing11 swing12 swing13 swing14
-
-$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7
-$frame smash8 smash9 smash10 smash11 smash12 smash13 smash14
-
-$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6
-
-$frame pain1 pain2 pain3 pain4 pain5
-
-$frame painb1 painb2 painb3
-
-$frame painc1 painc2 painc3 painc4 painc5 painc6
-
-$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10
-$frame paind11 paind12 paind13 paind14 paind15 paind16
-
-$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10
-$frame paine11 paine12 paine13 paine14 paine15
-
-$frame death1 death2 death3 death4 death5 death6
-$frame death7 death8 death9 death10 death11 death12
-$frame death13 death14
-
-$frame bdeath1 bdeath2 bdeath3 bdeath4 bdeath5 bdeath6
-$frame bdeath7 bdeath8 bdeath9 bdeath10
-
-$frame pull1 pull2 pull3 pull4 pull5 pull6 pull7 pull8 pull9 pull10 pull11
-
-//=============================================================================
-
-
-void() OgreGrenadeExplode =
-{
- T_RadiusDamage (self, self.owner, 40, world);
- sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- self.velocity = '0 0 0';
- self.touch = SUB_Null;
- setmodel (self, "progs/s_explod.spr");
- self.solid = SOLID_NOT;
- s_explode1 ();
-};
-
-void() OgreGrenadeTouch =
-{
- if (other == self.owner)
- return; // don't explode on owner
- if (other.takedamage == DAMAGE_AIM)
- {
- OgreGrenadeExplode();
- return;
- }
- if (self.count < time) {
- sound (self, CHAN_VOICE, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
- }
- self.count = time + .02;
- if (self.velocity == '0 0 0')
- self.avelocity = '0 0 0';
-};
-
-//BDW 31/08/00 - evil, nasty red-hot nail cluster-bomb attack... from Marcher -- dumptruck_ds
-
-void() FlakDoDamage =
-{
- self.origin = self.oldenemy.origin + self.oldorigin; //get correct gib direction
- T_Damage(self.oldenemy, self, self.owner, self.oldenemy.spikecount);
- self.oldenemy.spikecount = 0;
- remove(self);
-};
-
-void() FlakTouch =
-{
- if (other.solid == SOLID_TRIGGER)
- return;
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
-// hit something that bleeds
- if (other.takedamage)
- {
- spawn_touchblood(self.dmg);
-
- sound(self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
-
- if (other.spikecount) //not the first one
- {
- other.spikecount = other.spikecount + self.dmg;
- remove(self);
- return;
- }
-
- // the first one...
-
- other.spikecount = self.dmg;
-
- // stick around for a little while...
- self.velocity = '0 0 0';
- self.solid = SOLID_NOT;
- self.touch = SUB_Null;
- self.model = string_null;
- self.oldorigin = self.origin - other.origin; //displacement from enemy origin (its gonna move next frame)
- self.oldenemy = other;
- self.think = FlakDoDamage;
- self.nextthink = time + 0.05;
- return;
- }
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- if (self.spawnflags & MONSTER_FLAK_OGRE) //bit of a hack
- {
- remove(self);
- return;
- }
-
- self.dmg = self.dmg - 5; //gets weaker with each bounce. also stops them getting stuck in world.
- if (self.dmg <= 0)
- {
- remove(self);
- return;
- }
- self.velocity = self.velocity * 0.5; //reduce crazy ricochets
- self.movetype = MOVETYPE_BOUNCE;
-};
-
-void() BDW_OgreFireFlak =
-{
- local float flakcount;
- local vector dir, ang;
- local entity flak;
- local float projspeed = 800 * self.proj_speed_mod;
-
- flakcount = 8;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- sound(self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
-
-// make angles out of the current displacement vector...
- ang = vectoangles(self.enemy.origin - self.origin);
-// then get the required components...
- makevectors(ang);
-
- while (flakcount > 0)
- {
- //tighter spread...
- dir = v_forward*10 + crandom()*v_right + crandom()*v_up;
- dir = normalize(dir);
- // f*cking hack...is this a v_forward problem?
- dir_z = dir_z * -1;
- //dir = dir*1000;
- //dir = dir*800;
-
-
- flak = spawn();
-
- flak.owner = self;
- //flymissile is a bit too all-seeing for this gun...
- flak.movetype = MOVETYPE_FLY;
- //flak.movetype = MOVETYPE_FLYMISSILE;
- flak.solid = SOLID_BBOX;
- flak.flags = FL_NOSELECT;
- flak.touch = FlakTouch;
- flak.angles = vectoangles(dir);
- SetSpeed(flak, dir, projspeed);
- if (self.homing > 0)
- {
- SetupHoming(flak, projspeed);
- }
- else
- {
- flak.nextthink = time + 6;
- flak.think = SUB_Remove;
- }
- flak.dmg = 4;
-
- flak.spawnflags = MONSTER_FLAK_OGRE; //this is a hack to tell FlakTouch that it came from an ogre
- // setmodel(flak, "progs/spike.mdl");
- flak.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (flak, self.mdl_proj);
- }
- else
- {
- setmodel (flak, "progs/spike.mdl");
- }
-
- if (!flak.skin_proj) // dumptruck_ds
- {
- flak.skin = self.skin_proj;
- }
- else
- {
- flak.skin = 0;
- }
- // dumptruck_ds - end
-
- setsize(flak, '0 0 0', '0 0 0');
- setorigin(flak, self.origin + '0 0 16');
-
- flakcount = flakcount - 1;
- }
-};
-/////////////////////////////////////////////////////////////
-/* start Preach Ogre Marksman tutorial here -- dumptruck_ds*/
-/////////////////////////////////////////////////////////////
-
-//speed an ogre grenade is fired at
-float OGRE_G_VEL = 600;
-
-//fixme: get the correct gravity strength for the level
-float pgrav = 800;
-
-//a default angle to fire at if the enemy is too far away
-float OGRE_DEFAULT_ELEVATION = 30;
-
-//uses QuakeC builtins to calculate tan of angle
-//WARNING: uses makevectors! This overwrites the v_forward... globals
-float(float theta) tan =
-{
- local vector ang; //temporary used to calculate trig values
- ang = '0 0 0';
- ang_y = theta; //assign theta to the yaw to simplify reasoning
- makevectors(ang);
- return v_forward_y / v_forward_x;
-}
-
-//inverse tan function
-//takes two parameters, numerator and denominator
-//this copes better with denominator 0 and gets quadrant correct
-/*
-float(float y, float x) atan2 =
-{
- local vector ang; //temporary used to calculate trig values
- ang = '0 0 0';
- ang_x = x;
- ang_y = y;
- return vectoyaw(ang);
-}
-*/
-
-float(float theta, vector dest) IterateElevation =
-{
- local float a, b, c; //constants in the equation to be solved
- local vector ofs; //displacement we wish the projectile to travel
- local float y, z; //horizontal and vertical components of ofs
- local float tan_theta; //trig values of the angle theta
-
- //calculate how far we are firing
- ofs = dest - self.origin;
- z = ofs_z;
- ofs_z = 0;
- y = vlen(ofs);
-
- //find the coefficients of the quadratic in tan(theta)
- a = 0.5 * pgrav * y * y / (OGRE_G_VEL * OGRE_G_VEL);
- b = -y;
- c = a + z;
-
- //check if the destination is too far to reach
- if(b*b < 4*a*c)
- return OGRE_DEFAULT_ELEVATION;
-
- //calculate the tan value of the given theta
- tan_theta = tan(theta);
-
- //reuse ang to create the improved firing direction
- theta = atan2(a*tan_theta*tan_theta - c,
- 2*a*tan_theta + b);
-
- //constrain the values to stop anything too mad happening
- while(theta > 90)
- theta = theta - 180;
- return theta;
-}
-/*
-================
-PreachFireGrenade
-================
-*/
-void(float elevation) PreachFireGrenade =
-{
- local entity missile;
- local vector ang;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
-
-// set missile speed
- ang = self.angles;
- ang_x = -elevation;
- makevectors (ang);
-
- missile.velocity = v_forward * OGRE_G_VEL;
-
- missile.avelocity = '300 300 300';
-
- missile.angles = vectoangles(missile.velocity);
-
- missile.touch = OgreGrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 2.5;
- missile.think = OgreGrenadeExplode;
- // setmodel (missile, "progs/grenade.mdl");
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/grenade.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin);
-};
-
-// end Preach tutorial
-
-/*
-================
-PreachFireZombie
-for Z-Aware Zombies in Turret Mode only
-================
-*/
-void(float elevation) PreachFireZombie =
-{
- local entity missile;
- local vector ang;
-
- // self.effects = self.effects | EF_MUZZLEFLASH;
-
- sound_attack (self, CHAN_WEAPON, "zombie/z_shot1.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
-
-// set missile speed
- ang = self.angles;
- ang_x = -elevation;
- makevectors (ang);
-
- missile.velocity = v_forward * OGRE_G_VEL;
-
- missile.avelocity = '3000 1000 2000';
-
- missile.angles = vectoangles(missile.velocity);
-
- missile.touch = ZombieGrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 2.5;
- missile.think = SUB_Remove;
- // setmodel (missile, "progs/grenade.mdl");
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/zom_gib.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin);
-};
-
-// end Preach tutorial
-
-/*
-================
-OgreFireGrenade
-================
-*/
-void() MultiGrenadeTouch;
-void() MultiGrenadeExplode;
-
-void() OgreFireGrenade =
-{
- local entity missile;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
- missile.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/grenade.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-// dumptruck_ds - end
-// set missile speed
-
- makevectors (self.angles);
- missile.velocity = normalize(self.enemy.origin - self.origin);
- missile.velocity = missile.velocity * 600;
- missile.velocity_z = 200;
- missile.avelocity = '300 300 300';
- missile.angles = vectoangles(missile.velocity);
-
- // set missile duration
- if(self.style == 3)
- {
- missile.touch = MultiGrenadeTouch;
- missile.nextthink = time + 2.5;
- missile.think = MultiGrenadeExplode;
- setmodel (missile, "progs/mervup.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin);
- missile.classname = "MultiGrenade";
- }
- else
- {
- missile.touch = OgreGrenadeTouch;
- missile.nextthink = time + 2.5;
- missile.think = OgreGrenadeExplode;
- // setmodel (missile, "progs/grenade.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin);
- }
- };
-
- // missile.touch = OgreGrenadeTouch;
-
-// // set missile duration
-// missile.nextthink = time + 2.5;
-// missile.think = OgreGrenadeExplode;
-//
-// setmodel (missile, "progs/grenade.mdl");
-// setsize (missile, '0 0 0', '0 0 0');
-// setorigin (missile, self.origin);
-// };
-
-/*
-================
-OgreFireSpike from insideqc tutorial here: http://www.insideqc.com/qctut/lesson-33.shtml
-================
-*/
-void() OgreFireSpike =
-{
- local vector dir;
- // local entity old;
-
-
- sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
- self.attack_finished = time + .7;
- // self.attack_finished = time + 0.2;
- self.effects = self.effects | EF_MUZZLEFLASH; // -- dumptruck_ds
-
- dir = normalize (self.enemy.origin - self.origin);
-
- launch_spike (self.origin + v_right * 4 + '0 0 16', dir);
-
- newmis.touch = superduperspike_touch; //dumptruck_ds found in client.qc
- // setmodel (newmis, "progs/lspike.mdl");
- newmis.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/lspike.mdl");
- }
-
- if (!newmis.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
- // dumptruck_ds - end
-
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
-};
-//=============================================================================
-// Multi Grenade Code from doe progs MULT_WPN.QC -- dumptruck_ds
-//=============================================================================
-void() MultiGrenadeTouch;
-
-//================================
-//================================
-void() MiniGrenadeExplode =
-{
- if ( self.owner.classname == "player")
- T_RadiusDamage (self, self.owner, 90, world);
- else
- T_RadiusDamage (self, self.owner, 60, world);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION2);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- WriteByte (MSG_BROADCAST, 230);
- WriteByte (MSG_BROADCAST, 5);
-
- BecomeExplosion ();
-};
-
-//================================
-//================================
-void(float offsetAngle) MiniGrenadeLaunch =
-{
- local entity missile/*, mpuff*/;
- local float tempRand;
-
- missile = spawn ();
- missile.owner = self.owner;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
- missile.classname = "MiniGrenade";
-
-// set missile speed
- missile.v_angle = self.v_angle;
- missile.v_angle_y = missile.v_angle_y + offsetAngle;
- makevectors (missile.v_angle);
-
- missile.velocity = v_forward*100 + v_up*400;
- tempRand = (crandom()*60) - 30;
- missile.velocity = missile.velocity + tempRand * v_forward;
- tempRand = (crandom()*40) - 20;
- missile.velocity = missile.velocity + tempRand * v_right;
- tempRand = (crandom()*60) - 30;
- missile.velocity = missile.velocity + tempRand * v_up;
-
- missile.avelocity = '300 300 300';
- missile.angles = vectoangles(missile.velocity);
- missile.touch = MultiGrenadeTouch;
-
- setmodel (missile, "progs/mervup.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin);
-
-// set missile duration
- missile.nextthink = time + 1 + (crandom() * 0.5);
- missile.think = MiniGrenadeExplode;
-};
-
-//================================
-//================================
-void() MultiGrenadeExplode =
-{
- MiniGrenadeLaunch(0);
- MiniGrenadeLaunch(72);
- MiniGrenadeLaunch(144);
- MiniGrenadeLaunch(216);
- MiniGrenadeLaunch(288);
-
- remove (self);
-};
-
-//================================
-//================================
-void() MultiGrenadeTouch =
-{
- if (other == self.owner)
- return; // don't explode on owner
- if (other.takedamage == DAMAGE_AIM)
- {
- if (self.classname == "MiniGrenade")
- MiniGrenadeExplode();
- else
- {
- if (self.owner.classname == "player")
- GrenadeExplode();
- else
- MiniGrenadeExplode();
- }
- return;
- }
- // bounce sound
- sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);
- if (self.velocity == '0 0 0')
- self.avelocity = '0 0 0';
-};
-
-//================================
-//================================
-void() W_FireMultiGrenade =
-{
- local entity missile/*, mpuff*/;
-
- // self.currentammo = self.ammo_multi_rockets = self.ammo_multi_rockets - 1;
- // UpdateAmmoCounts (self);
-
- sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
-
- // self.punchangle_x = -2;
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
- missile.classname = "MultiGrenade";
-
- makevectors (self.angles);
- missile.velocity = normalize(self.enemy.origin - self.origin);
- missile.velocity = missile.velocity * 600;
- missile.velocity_z = 200;
- missile.avelocity = '300 300 300';
- missile.angles = vectoangles(missile.velocity);
-
-
-// set missile speed
- // makevectors (self.v_angle);
- // if (self.v_angle_x)
- // missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
- // else
- // {
- // missile.velocity = aim(self, 10000);
- // missile.velocity = missile.velocity * 600;
- // missile.velocity_z = 200;
- // }
- //
- // missile.avelocity = '300 300 300';
- // missile.angles = vectoangles(missile.velocity);
- missile.touch = MultiGrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 1;
- missile.think = MultiGrenadeExplode;
- setmodel (missile, "progs/mervup.mdl");
- missile.skin = self.skin_proj; //dumptruck_ds
-
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + '0 0 16');
-};
-
-//=============================================================================
-//end doe qc -- dumptruck_ds
-//=============================================================================
-/*
-================
-OgreFireLavaBall by jaycie erysdren 2021-09-14
-================
-*/
-
-void() OgreFireLavaBall =
-{
- local vector offang;
- local vector org, vec, d;
- // local float t;
-
- offang = vectoangles (self.enemy.origin - self.origin);
- makevectors (offang);
-
- org = self.origin; // + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
-
-// lead the player on hard mode
- // if (skill > 1)
- // {
- // t = vlen(self.enemy.origin - org) / 300;
- // vec = self.enemy.velocity;
- // vec_z = 0;
- // d = self.enemy.origin + t * vec;
- // }
- // else
- // {
- d = self.enemy.origin;
- // }
-
- vec = normalize (d - org);
-
- // launch_spike (org, vec);
- launch_spike2 (self.origin + v_right * 4 + '0 0 16', vec, 600);
- self.effects = self.effects | EF_MUZZLEFLASH;
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/lavaball.mdl");
- }
-
- if (!newmis.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
- newmis.avelocity = self.cust_avelocity;
- if !(newmis.avelocity)
- newmis.avelocity = '200 100 300';
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- // newmis.touch = T_MissileTouch; // rocket explosion
- newmis.touch = OgreGrenadeExplode;
- sound_attack (self, CHAN_AUTO, "boss1/throw.wav", 1, ATTN_NORM);
-
-};
-
-/*
-================
-chainsaw
-
-FIXME
-================
-*/
-void(float side) chainsaw =
-{
-local vector delta;
-local float ldmg;
-
- if (!self.enemy)
- return;
- if (!CanDamage (self.enemy, self))
- return;
-
- ai_charge(10);
-
- delta = self.enemy.origin - self.origin;
-
- if (vlen(delta) > 100)
- return;
-
- ldmg = (random() + random() + random()) * 4;
- T_Damage (self.enemy, self, self, ldmg);
-
- if (side)
- {
- makevectors (self.angles);
- if (side == 1)
- SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
- else
- SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
- }
-};
-
-void() ogre_stand1 =[ $stand1, ogre_stand2 ] {ai_stand();};
-void() ogre_stand2 =[ $stand2, ogre_stand3 ] {ai_stand();};
-void() ogre_stand3 =[ $stand3, ogre_stand4 ] {ai_stand();};
-void() ogre_stand4 =[ $stand4, ogre_stand5 ] {ai_stand();};
-void() ogre_stand5 =[ $stand5, ogre_stand6 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
-ai_stand();
-};
-void() ogre_stand6 =[ $stand6, ogre_stand7 ] {ai_stand();};
-void() ogre_stand7 =[ $stand7, ogre_stand8 ] {ai_stand();};
-void() ogre_stand8 =[ $stand8, ogre_stand9 ] {ai_stand();};
-void() ogre_stand9 =[ $stand9, ogre_stand1 ] {ai_stand();};
-
-void() ogre_walk1 =[ $walk1, ogre_walk2 ] {ai_walk(3);};
-void() ogre_walk2 =[ $walk2, ogre_walk3 ] {ai_walk(2);};
-void() ogre_walk3 =[ $walk3, ogre_walk4 ] {
-ai_walk(2);
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
-};
-void() ogre_walk4 =[ $walk4, ogre_walk5 ] {ai_walk(2);};
-void() ogre_walk5 =[ $walk5, ogre_walk6 ] {ai_walk(2);};
-void() ogre_walk6 =[ $walk6, ogre_walk7 ] {
-ai_walk(5);
-if (random() < 0.1)
- sound_misc (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);
-};
-void() ogre_walk7 =[ $walk7, ogre_walk8 ] {ai_walk(3);};
-void() ogre_walk8 =[ $walk8, ogre_walk9 ] {ai_walk(2);};
-void() ogre_walk9 =[ $walk9, ogre_walk10 ] {ai_walk(3);};
-void() ogre_walk10 =[ $walk10, ogre_walk11 ] {ai_walk(1);};
-void() ogre_walk11 =[ $walk11, ogre_walk12 ] {ai_walk(2);};
-void() ogre_walk12 =[ $walk12, ogre_walk13 ] {ai_walk(3);};
-void() ogre_walk13 =[ $walk13, ogre_walk14 ] {ai_walk(3);};
-void() ogre_walk14 =[ $walk14, ogre_walk15 ] {ai_walk(3);};
-void() ogre_walk15 =[ $walk15, ogre_walk16 ] {ai_walk(3);};
-void() ogre_walk16 =[ $walk16, ogre_walk1 ] {ai_walk(4);};
-
-void() ogre_run1 =[ $run1, ogre_run2 ] {ai_run(9);
-if (random() < 0.2)
- sound_misc1 (self, CHAN_VOICE, "ogre/ogidle2.wav", 1, ATTN_IDLE);
-};
-void() ogre_run2 =[ $run2, ogre_run3 ] {ai_run(12);};
-void() ogre_run3 =[ $run3, ogre_run4 ] {ai_run(8);};
-void() ogre_run4 =[ $run4, ogre_run5 ] {ai_run(22);};
-void() ogre_run5 =[ $run5, ogre_run6 ] {ai_run(16);};
-void() ogre_run6 =[ $run6, ogre_run7 ] {ai_run(4);};
-void() ogre_run7 =[ $run7, ogre_run8 ] {ai_run(13);};
-void() ogre_run8 =[ $run8, ogre_run1 ] {ai_run(24);};
-
-void() ogre_swing1 =[ $swing1, ogre_swing2 ] {ai_charge(11);
-sound_attack (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM);
-};
-void() ogre_swing2 =[ $swing2, ogre_swing3 ] {ai_charge(1);};
-void() ogre_swing3 =[ $swing3, ogre_swing4 ] {ai_charge(4);};
-void() ogre_swing4 =[ $swing4, ogre_swing5 ] {ai_charge(13);};
-void() ogre_swing5 =[ $swing5, ogre_swing6 ] {ai_charge(9); chainsaw(0);self.angles_y = self.angles_y + random()*25;};
-void() ogre_swing6 =[ $swing6, ogre_swing7 ] {chainsaw(200);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing7 =[ $swing7, ogre_swing8 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing8 =[ $swing8, ogre_swing9 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing9 =[ $swing9, ogre_swing10 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing10 =[ $swing10, ogre_swing11 ] {chainsaw(-200);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing11 =[ $swing11, ogre_swing12 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing12 =[ $swing12, ogre_swing13 ] {ai_charge(3);};
-void() ogre_swing13 =[ $swing13, ogre_swing14 ] {ai_charge(8);};
-void() ogre_swing14 =[ $swing14, ogre_run1 ] {ai_charge(9);};
-
-void() ogre_smash1 =[ $smash1, ogre_smash2 ] {ai_charge(6);
-sound_attack (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM);
-};
-void() ogre_smash2 =[ $smash2, ogre_smash3 ] {ai_charge(0);};
-void() ogre_smash3 =[ $smash3, ogre_smash4 ] {ai_charge(0);};
-void() ogre_smash4 =[ $smash4, ogre_smash5 ] {ai_charge(1);};
-void() ogre_smash5 =[ $smash5, ogre_smash6 ] {ai_charge(4);};
-void() ogre_smash6 =[ $smash6, ogre_smash7 ] {ai_charge(4); chainsaw(0);};
-void() ogre_smash7 =[ $smash7, ogre_smash8 ] {ai_charge(4); chainsaw(0);};
-void() ogre_smash8 =[ $smash8, ogre_smash9 ] {ai_charge(10); chainsaw(0);};
-void() ogre_smash9 =[ $smash9, ogre_smash10 ] {ai_charge(13); chainsaw(0);};
-void() ogre_smash10 =[ $smash10, ogre_smash11 ] {chainsaw(1);};
-void() ogre_smash11 =[ $smash11, ogre_smash12 ] {ai_charge(2); chainsaw(0);
-// self.nextthink = self.nextthink + random()*0.2;}; // slight variation
-self.nextthink = time + 0.1 + random()*0.2;}; // 1998-08-14 Incorrect setting of nextthink fix by Maddes/Lord Sméagol
-void() ogre_smash12 =[ $smash12, ogre_smash13 ] {ai_charge(0);};
-void() ogre_smash13 =[ $smash13, ogre_smash14 ] {ai_charge(4);};
-void() ogre_smash14 =[ $smash14, ogre_run1 ] {ai_charge(12);};
-
-// Preach tutorial alternate animation frames for monster_ogre_marksman -- dumptruck_ds
-.float attack_elevation;
-void() ogre2_nail1 =[ $shoot1, ogre2_nail2 ] {ai_face();
-self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() ogre2_nail2 =[ $shoot2, ogre2_nail3 ] {ai_face();
-self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() ogre2_nail3 =[ $shoot2, ogre2_nail4 ] {ai_face();
-self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() ogre2_nail4 =[ $shoot3, ogre_nail5 ] {ai_face();
- PreachFireGrenade(self.attack_elevation);
-};
-// Preach tutorial alternate animation frames for monster_ogre_marksman -- dumptruck_ds
-// these are for the turret version of monster_ogre_marksman
-.float attack_elevation;
-void() ogre2_turret_attack1 =[ $shoot1, ogre2_turret_attack2 ] {ai_face();
-self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() ogre2_turret_attack2 =[ $shoot2, ogre2_turret_attack3 ] {ai_face();
-self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() ogre2_turret_attack3 =[ $shoot2, ogre2_turret_attack4 ] {ai_face();
-self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() ogre2_turret_attack4 =[ $shoot3, ogre2_turret_attack5 ] {ai_face();
- PreachFireGrenade(self.attack_elevation);};
-void() ogre2_turret_attack5 =[ $shoot4, ogre2_turret_attack6 ] {ai_face();};
-void() ogre2_turret_attack6 =[ $shoot5, ogre2_turret_attack7 ] {ai_face();};
-void() ogre2_turret_attack7 =[ $shoot5, ogre2_turret_attack8 ] {ai_face();};
-void() ogre2_turret_attack8 =[ $shoot6, ogre2_turret_attack9 ] {ai_face();};
-void() ogre2_turret_attack9 =[ $shoot6, ogre2_turret_seek1 ] {ai_face();};
-void() ogre2_turret_seek1 =[ $stand1, ogre2_turret_seek2 ] {ai_run(0);};
-void() ogre2_turret_seek2 =[ $stand2, ogre2_turret_seek3 ] {ai_run(0);};
-void() ogre2_turret_seek3 =[ $stand3, ogre2_turret_seek4 ] {ai_run(0);};
-void() ogre2_turret_seek4 =[ $stand4, ogre2_turret_seek5 ] {ai_run(0);};
-void() ogre2_turret_seek5 =[ $stand5, ogre2_turret_seek6 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
- ai_run(0);
-};
-void() ogre2_turret_seek6 =[ $stand6, ogre2_turret_seek7 ] {ai_run(0);};
-void() ogre2_turret_seek7 =[ $stand7, ogre2_turret_seek8 ] {ai_run(0);};
-void() ogre2_turret_seek8 =[ $stand8, ogre2_turret_seek9 ] {ai_run(0);};
-void() ogre2_turret_seek9 =[ $stand9, ogre2_turret_seek1 ] {ai_run(0);};
-
-//end Preach -- dumptruck_ds
-void() ogre_nail1 =[ $shoot1, ogre_nail2 ] {ai_face();};
-void() ogre_nail2 =[ $shoot2, ogre_nail3 ] {ai_face();};
-void() ogre_nail3 =[ $shoot2, ogre_nail4 ] {ai_face();};
-void() ogre_nail4 =[ $shoot3, ogre_nail5 ] {ai_face();
- if (self.style == 0)
- {
- OgreFireGrenade();
- }
- if (self.style == 1)
- {
- BDW_OgreFireFlak();
- // OgreFireSpike();
- }
- else if (self.style == 2)
- {
- OgreFireSpike();
- }
- if (self.style == 3)
- {
- W_FireMultiGrenade();
- }
- if (self.style == 4) // jaycie erysdren 2021-09-14
- {
- OgreFireLavaBall();
- sound_misc2 (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM); // used for initial attack sound dumptruck_ds
- }
-};
-void() ogre_nail5 =[ $shoot4, ogre_nail6 ] {ai_face();};
-void() ogre_nail6 =[ $shoot5, ogre_nail7 ] {ai_face();};
-void() ogre_nail7 =[ $shoot6, ogre_run1 ] {ai_face();};
-//
-////////////////////////
-// turret frames START
-////////////////////////
-//
-void() ogre_turret_attack1 =[ $shoot1, ogre_turret_attack2 ] {ai_face();};
-void() ogre_turret_attack2 =[ $shoot2, ogre_turret_attack3 ] {ai_face();};
-void() ogre_turret_attack3 =[ $shoot2, ogre_turret_attack4 ] {ai_face();};
-void() ogre_turret_attack4 =[ $shoot3, ogre_turret_attack5 ] {ai_face();
- if (self.style == 0)
- {
- OgreFireGrenade();
- }
- if (self.style == 1)
- {
- BDW_OgreFireFlak();
- // OgreFireSpike();
- }
- else if (self.style == 2)
- {
- OgreFireSpike();
- }
- if (self.style == 3)
- {
- W_FireMultiGrenade();
- }
- if (self.style == 4) // jaycie erysdren 2021-09-14
- {
- OgreFireLavaBall();
- sound_misc2 (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM); // used for initial attack sound dumptruck_ds
- }
-};
-void() ogre_turret_attack5 =[ $shoot4, ogre_turret_attack6 ] {ai_face();};
-
-void() ogre_turret_attack6=[ $shoot5, ogre_turret_attack7 ] {ai_face();};
-void() ogre_turret_attack7=[ $shoot5, ogre_turret_attack8 ] {ai_face();};
-void() ogre_turret_attack8=[ $shoot6, ogre_turret_attack9 ] {ai_face();};
-void() ogre_turret_attack9=[ $shoot6, ogre_turret_seek1 ] {ai_face();};
-void() ogre_turret_seek1 =[ $stand1, ogre_turret_seek2 ] {ai_run(0);};
-void() ogre_turret_seek2 =[ $stand2, ogre_turret_seek3 ] {ai_run(0);};
-void() ogre_turret_seek3 =[ $stand3, ogre_turret_seek4 ] {ai_run(0);};
-void() ogre_turret_seek4 =[ $stand4, ogre_turret_seek5 ] {ai_run(0);};
-void() ogre_turret_seek5 =[ $stand5, ogre_turret_seek6 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
- ai_run(0);
-};
-void() ogre_turret_seek6 =[ $stand6, ogre_turret_seek7 ] {ai_run(0);};
-void() ogre_turret_seek7 =[ $stand7, ogre_turret_seek8 ] {ai_run(0);};
-void() ogre_turret_seek8 =[ $stand8, ogre_turret_seek9 ] {ai_run(0);};
-void() ogre_turret_seek9 =[ $stand9, ogre_turret_seek1 ] {ai_run(0);};
-////////////////////////
-//turret frames END
-///////////////////////
-void() ogre_pain1 =[ $pain1, ogre_pain2 ] {};
-void() ogre_pain2 =[ $pain2, ogre_pain3 ] {};
-void() ogre_pain3 =[ $pain3, ogre_pain4 ] {};
-void() ogre_pain4 =[ $pain4, ogre_pain5 ] {};
-void() ogre_pain5 =[ $pain5, ogre_run1 ] {};
-
-
-void() ogre_painb1 =[ $painb1, ogre_painb2 ] {};
-void() ogre_painb2 =[ $painb2, ogre_painb3 ] {};
-void() ogre_painb3 =[ $painb3, ogre_run1 ] {};
-
-
-void() ogre_painc1 =[ $painc1, ogre_painc2 ] {};
-void() ogre_painc2 =[ $painc2, ogre_painc3 ] {};
-void() ogre_painc3 =[ $painc3, ogre_painc4 ] {};
-void() ogre_painc4 =[ $painc4, ogre_painc5 ] {};
-void() ogre_painc5 =[ $painc5, ogre_painc6 ] {};
-void() ogre_painc6 =[ $painc6, ogre_run1 ] {};
-
-
-void() ogre_paind1 =[ $paind1, ogre_paind2 ] {};
-void() ogre_paind2 =[ $paind2, ogre_paind3 ] {ai_pain(10);};
-void() ogre_paind3 =[ $paind3, ogre_paind4 ] {ai_pain(9);};
-void() ogre_paind4 =[ $paind4, ogre_paind5 ] {ai_pain(4);};
-void() ogre_paind5 =[ $paind5, ogre_paind6 ] {};
-void() ogre_paind6 =[ $paind6, ogre_paind7 ] {};
-void() ogre_paind7 =[ $paind7, ogre_paind8 ] {};
-void() ogre_paind8 =[ $paind8, ogre_paind9 ] {};
-void() ogre_paind9 =[ $paind9, ogre_paind10 ] {};
-void() ogre_paind10=[ $paind10, ogre_paind11 ] {};
-void() ogre_paind11=[ $paind11, ogre_paind12 ] {};
-void() ogre_paind12=[ $paind12, ogre_paind13 ] {};
-void() ogre_paind13=[ $paind13, ogre_paind14 ] {};
-void() ogre_paind14=[ $paind14, ogre_paind15 ] {};
-void() ogre_paind15=[ $paind15, ogre_paind16 ] {};
-void() ogre_paind16=[ $paind16, ogre_run1 ] {};
-
-void() ogre_paine1 =[ $paine1, ogre_paine2 ] {};
-void() ogre_paine2 =[ $paine2, ogre_paine3 ] {ai_pain(10);};
-void() ogre_paine3 =[ $paine3, ogre_paine4 ] {ai_pain(9);};
-void() ogre_paine4 =[ $paine4, ogre_paine5 ] {ai_pain(4);};
-void() ogre_paine5 =[ $paine5, ogre_paine6 ] {};
-void() ogre_paine6 =[ $paine6, ogre_paine7 ] {};
-void() ogre_paine7 =[ $paine7, ogre_paine8 ] {};
-void() ogre_paine8 =[ $paine8, ogre_paine9 ] {};
-void() ogre_paine9 =[ $paine9, ogre_paine10 ] {};
-void() ogre_paine10=[ $paine10, ogre_paine11 ] {};
-void() ogre_paine11=[ $paine11, ogre_paine12 ] {};
-void() ogre_paine12=[ $paine12, ogre_paine13 ] {};
-void() ogre_paine13=[ $paine13, ogre_paine14 ] {};
-void() ogre_paine14=[ $paine14, ogre_paine15 ] {};
-void() ogre_paine15=[ $paine15, ogre_run1 ] {};
-
-
-void(entity attacker, float damage) ogre_pain =
-{
- local float r;
-
-// don't make multiple pain sounds right after each other
- if (self.pain_finished > time)
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- return;
-
- sound_pain (self, CHAN_VOICE, "ogre/ogpain1.wav", 1, ATTN_NORM);
-
- r = random();
-
- if (r < 0.25)
- {
- ogre_pain1 ();
- self.pain_finished = time + 1;
- }
- else if (r < 0.5)
- {
- ogre_painb1 ();
- self.pain_finished = time + 1;
- }
- else if (r < 0.75)
- {
- ogre_painc1 ();
- self.pain_finished = time + 1;
- }
- else if (r < 0.88)
- {
- ogre_paind1 ();
- self.pain_finished = time + 2;
- }
- else
- {
- ogre_paine1 ();
- self.pain_finished = time + 2;
- }
-};
-
-void() ogre_die1 =[ $death1, ogre_die2 ] {};
-void() ogre_die2 =[ $death2, ogre_die3 ] {};
-void() ogre_die3 =[ $death3, ogre_die4 ]
-{self.solid = SOLID_NOT;
- // style ammotype check -- dumptruck_ds
- if (self.style == 1) // flak style
- {
- self.ammo_nails = 5;
- }
- if (self.style == 2) // super nail style
- {
- self.ammo_nails = 5;
- }
- if (self.style == 3) //DOE multi-grenade
- {
- self.ammo_rockets = 2;
- }
- else if (self.style == 0) //default Ogre
- {
- self.ammo_rockets = 2;
- }
-if(!self.keep_ammo)DropBackpack();};
-void() ogre_die4 =[ $death4, ogre_die5 ] {};
-void() ogre_die5 =[ $death5, ogre_die6 ] {};
-void() ogre_die6 =[ $death6, ogre_die7 ] {};
-void() ogre_die7 =[ $death7, ogre_die8 ] {};
-void() ogre_die8 =[ $death8, ogre_die9 ] {};
-void() ogre_die9 =[ $death9, ogre_die10 ] {};
-void() ogre_die10 =[ $death10, ogre_die11 ] {};
-void() ogre_die11 =[ $death11, ogre_die12 ] {};
-void() ogre_die12 =[ $death12, ogre_die13 ] {};
-void() ogre_die13 =[ $death13, ogre_die14 ] {};
-void() ogre_die14 =[ $death14, ogre_die14 ] {};
-
-void() ogre_bdie1 =[ $bdeath1, ogre_bdie2 ] {};
-void() ogre_bdie2 =[ $bdeath2, ogre_bdie3 ] {ai_forward(5);};
-void() ogre_bdie3 =[ $bdeath3, ogre_bdie4 ]
-{self.solid = SOLID_NOT;
- // style ammotype check -- dumptruck_ds
- if (self.style == 1)
- {
- self.ammo_nails = 5;
- }
- if (self.style == 2)
- {
- self.ammo_nails = 5;
- }
- if (self.style == 3) //DOE multi-grenade
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 4) // lavaball ogre jaycie erysdren 2021-09-14
- {
- self.ammo_rockets = 2;
- }
- else if (self.style == 0)
- {
- self.ammo_rockets = 2;
- }
-if(!self.keep_ammo)DropBackpack();};
-void() ogre_bdie4 =[ $bdeath4, ogre_bdie5 ] {ai_forward(1);};
-void() ogre_bdie5 =[ $bdeath5, ogre_bdie6 ] {ai_forward(3);};
-void() ogre_bdie6 =[ $bdeath6, ogre_bdie7 ] {ai_forward(7);};
-void() ogre_bdie7 =[ $bdeath7, ogre_bdie8 ] {ai_forward(25);};
-void() ogre_bdie8 =[ $bdeath8, ogre_bdie9 ] {};
-void() ogre_bdie9 =[ $bdeath9, ogre_bdie10 ] {};
-void() ogre_bdie10 =[ $bdeath10, ogre_bdie10 ] {};
-
-void() ogre_die =
-{
-// check for gib
- if (self.health < -80)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_ogre.mdl", self.health);
- }
- // ThrowGib ("progs/gib3.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- DropStuff();
- return;
- }
-
- sound_death (self, CHAN_VOICE, "ogre/ogdth.wav", 1, ATTN_NORM);
-
- DropStuff();
- if (random() < 0.5)
- ogre_die1 ();
- else
- ogre_bdie1 ();
-};
-
-void() ogre_melee =
-{
- if (random() > 0.5)
- ogre_smash1 ();
- else
- ogre_swing1 ();
-};
-
-
-/*QUAKED monster_ogre (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/ogre.mdl");
-}
-Ogre.
-
-Default health = 200"
-
-style(Choices) : "Attack type" =
-0 : "Default (grenade)"
-1 : "Flak Ogre (Marcher, Quoth)"
-2 : "sniper (shoots single, deadly lava round)"
-3 : "multi-grenade (Mission Pack 2)"
-
-keep_ammo(integer) : "1 = Don't drop backpack upon death"
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound (CHAINSAW)"
-snd_idle(string) : "Path to custom idle sound (IDLE)"
-snd_misc(string) : "Path to custom sound (IDLE CHAINSAW DRAG)"
-snd_misc1(string) : "Path to custom sound (ATTACK GRUNT)"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-mdl_proj(string) : "Path to custom projectile model"
-skin_head(float) : "Skin index of custom head model"
-skin_proj(float) : "Skin index of custom projectile model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_ogre =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- // custom_mdls dumptruck_ds
- precache_body_model ("progs/ogre.mdl");
- precache_head_model ("progs/h_ogre.mdl");
- precache_proj_model ("progs/grenade.mdl");
-
- // custom_mdls dumptruck_ds
- precache_model ("progs/mervup.mdl"); //for style 3 Orge dumptruck_ds
- precache_model ("progs/lspike.mdl"); //for style 2 Ogre dumptruck_ds
- precache_sound_misc ("ogre/ogdrag.wav");
- precache_sound_death ("ogre/ogdth.wav");
- precache_sound_idle ("ogre/ogidle.wav");
- precache_sound_misc1 ("ogre/ogidle2.wav");
- precache_sound_pain ("ogre/ogpain1.wav");
- precache_sound_attack ("ogre/ogsawatk.wav");
- precache_sound_sight ("ogre/ogwake.wav");
- precache_sound_misc2 ("shalrath/attack2.wav");
- precache_sound ("fish/bite.wav");
- precache_sound ("boss1/throw.wav"); // jaycie erysdren 2021-09-14
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- // custom_mdls dumptruck_ds
- body_model ("progs/ogre.mdl");
- // setmodel (self, "progs/ogre.mdl");
-
- setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
- if (!self.proj_speed_mod)
- {
- self.proj_speed_mod = 1;
- }
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 200;
-
- self.th_stand = ogre_stand1;
- self.th_walk = ogre_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = ogre_turret_seek1;
- }
- else
- {
- self.th_run = ogre_run1;
- }
- self.th_die = ogre_die;
- self.th_melee = ogre_melee;
- self.th_missile = ogre_nail1;
- self.th_turret = ogre_turret_attack1; //dumptruck_ds
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = ogre_pain;
- else
- self.th_pain = SUB_NullPain;
-
- walkmonster_start();
-};
-
-/*QUAKED monster_ogre_marksman (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ({ "path" : "progs/ogre.mdl", "frame": 63 });
-}
-Ogre Marksman.
-Unlike vanilla Quake, this is a slightly more accurate Orge.
-
-keep_ammo(integer) : "1 = Don't drop backpack upon death"
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound (CHAINSAW)"
-snd_idle(string) : "Path to custom idle sound (IDLE)"
-snd_misc(string) : "Path to custom sound (IDLE CHAINSAW DRAG)"
-snd_misc1(string) : "Path to custom sound (ATTACK GRUNT)"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-mdl_proj(string) : "Path to custom projectile model"
-skin_head(float) : "Skin index of custom head model"
-skin_proj(float) : "Skin index of custom projectile model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_ogre_marksman =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- // custom_mdls dumptruck_ds
- precache_body_model ("progs/ogre.mdl");
- precache_head_model ("progs/h_ogre.mdl");
- precache_proj_model ("progs/grenade.mdl");
-
- precache_sound_misc ("ogre/ogdrag.wav");
- precache_sound_death ("ogre/ogdth.wav");
- precache_sound_idle ("ogre/ogidle.wav");
- precache_sound_misc1 ("ogre/ogidle2.wav");
- precache_sound_pain ("ogre/ogpain1.wav");
- precache_sound_attack ("ogre/ogsawatk.wav");
- precache_sound_sight ("ogre/ogwake.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- // custom_mdls dumptruck_ds
- body_model ("progs/ogre.mdl");
- // setmodel (self, "progs/ogre.mdl");
-
- setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
- if (!self.proj_speed_mod)
- {
- self.proj_speed_mod = 1;
- }
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 200;
-
- self.th_stand = ogre_stand1;
- self.th_walk = ogre_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = ogre2_turret_seek1;
- }
- else
- {
- self.th_run = ogre_run1;
- }
- self.th_die = ogre_die;
- self.th_melee = ogre_melee;
- self.th_missile = ogre2_nail1;
- self.th_turret = ogre2_turret_attack1; //dumptruck_ds
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = ogre_pain;
- else
- self.th_pain = SUB_NullPain;
-
- walkmonster_start();
-};
-
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// monster_ogre ();
-// };
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_ogre (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID ON_SIDE X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/ogre.mdl","frame":135});
-}
-*/
-void() monster_dead_ogre =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/ogre.mdl");
- setmodel(self, "progs/ogre.mdl");
- if (self.spawnflags & 2)
- {
- self.frame = $death14;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-40.64 -54.06 -54.1','29.42 54.63 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
- else
- {
- self.frame = $bdeath10;
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-45.64 -29.46 -54.52','33.87 39.18 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/monsters/oldone.qc

diff --git a/qc-server/monsters/oldone.qc b/qc-server/monsters/oldone.qc
deleted file mode 100644
index fb470bd..0000000
--- a/qc-server/monsters/oldone.qc
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
-==============================================================================
-
-OLD ONE
-
-==============================================================================
-*/
-$cd id1/models/old_one
-$origin 0 0 24
-$base base
-$skin skin
-$scale 1
-
-void() finale_1;
-void() finale_2;
-void() finale_3;
-void() finale_4;
-
-
-entity shub;
-
-$frame old1 old2 old3 old4 old5 old6 old7 old8 old9
-$frame old10 old11 old12 old13 old14 old15 old16 old17 old18 old19
-$frame old20 old21 old22 old23 old24 old25 old26 old27 old28 old29
-$frame old30 old31 old32 old33 old34 old35 old36 old37 old38 old39
-$frame old40 old41 old42 old43 old44 old45 old46
-
-$frame shake1 shake2 shake3 shake4 shake5 shake6 shake7 shake8
-$frame shake9 shake10 shake11 shake12 shake13 shake14
-$frame shake15 shake16 shake17 shake18 shake19 shake20
-
-//void() old_stand =[ $old1, old_stand ] {};
-
-void() old_idle1 =[ $old1, old_idle2 ] {};
-void() old_idle2 =[ $old2, old_idle3 ] {};
-void() old_idle3 =[ $old3, old_idle4 ] {};
-void() old_idle4 =[ $old4, old_idle5 ] {};
-void() old_idle5 =[ $old5, old_idle6 ] {};
-void() old_idle6 =[ $old6, old_idle7 ] {};
-void() old_idle7 =[ $old7, old_idle8 ] {};
-void() old_idle8 =[ $old8, old_idle9 ] {};
-void() old_idle9 =[ $old9, old_idle10 ] {};
-void() old_idle10 =[ $old10, old_idle11 ] {};
-void() old_idle11 =[ $old11, old_idle12 ] {};
-void() old_idle12 =[ $old12, old_idle13 ] {};
-void() old_idle13 =[ $old13, old_idle14 ] {};
-void() old_idle14 =[ $old14, old_idle15 ] {};
-void() old_idle15 =[ $old15, old_idle16 ] {};
-void() old_idle16 =[ $old16, old_idle17 ] {};
-void() old_idle17 =[ $old17, old_idle18 ] {};
-void() old_idle18 =[ $old18, old_idle19 ] {};
-void() old_idle19 =[ $old19, old_idle20 ] {};
-void() old_idle20 =[ $old20, old_idle21 ] {};
-void() old_idle21 =[ $old21, old_idle22 ] {};
-void() old_idle22 =[ $old22, old_idle23 ] {};
-void() old_idle23 =[ $old23, old_idle24 ] {};
-void() old_idle24 =[ $old24, old_idle25 ] {};
-void() old_idle25 =[ $old25, old_idle26 ] {};
-void() old_idle26 =[ $old26, old_idle27 ] {};
-void() old_idle27 =[ $old27, old_idle28 ] {};
-void() old_idle28 =[ $old28, old_idle29 ] {};
-void() old_idle29 =[ $old29, old_idle30 ] {};
-void() old_idle30 =[ $old30, old_idle31 ] {};
-void() old_idle31 =[ $old31, old_idle32 ] {};
-void() old_idle32 =[ $old32, old_idle33 ] {};
-void() old_idle33 =[ $old33, old_idle34 ] {};
-void() old_idle34 =[ $old34, old_idle35 ] {};
-void() old_idle35 =[ $old35, old_idle36 ] {};
-void() old_idle36 =[ $old36, old_idle37 ] {};
-void() old_idle37 =[ $old37, old_idle38 ] {};
-void() old_idle38 =[ $old38, old_idle39 ] {};
-void() old_idle39 =[ $old39, old_idle40 ] {};
-void() old_idle40 =[ $old40, old_idle41 ] {};
-void() old_idle41 =[ $old41, old_idle42 ] {};
-void() old_idle42 =[ $old42, old_idle43 ] {};
-void() old_idle43 =[ $old43, old_idle44 ] {};
-void() old_idle44 =[ $old44, old_idle45 ] {};
-void() old_idle45 =[ $old45, old_idle46 ] {};
-void() old_idle46 =[ $old46, old_idle1 ] {};
-
-
-void() old_thrash1 =[ $shake1, old_thrash2 ] {lightstyle(0, "m");};
-void() old_thrash2 =[ $shake2, old_thrash3 ] {lightstyle(0, "k");};
-void() old_thrash3 =[ $shake3, old_thrash4 ] {lightstyle(0, "k");};
-void() old_thrash4 =[ $shake4, old_thrash5 ] {lightstyle(0, "i");};
-void() old_thrash5 =[ $shake5, old_thrash6 ] {lightstyle(0, "g");};
-void() old_thrash6 =[ $shake6, old_thrash7 ] {lightstyle(0, "e");};
-void() old_thrash7 =[ $shake7, old_thrash8 ] {lightstyle(0, "c");};
-void() old_thrash8 =[ $shake8, old_thrash9 ] {lightstyle(0, "a");};
-void() old_thrash9 =[ $shake9, old_thrash10 ] {lightstyle(0, "c");};
-void() old_thrash10 =[ $shake10, old_thrash11 ] {lightstyle(0, "e");};
-void() old_thrash11 =[ $shake11, old_thrash12 ] {lightstyle(0, "g");};
-void() old_thrash12 =[ $shake12, old_thrash13 ] {lightstyle(0, "i");};
-void() old_thrash13 =[ $shake13, old_thrash14 ] {lightstyle(0, "k");};
-void() old_thrash14 =[ $shake14, old_thrash15 ] {lightstyle(0, "m");};
-void() old_thrash15 =[ $shake15, old_thrash16 ] {lightstyle(0, "m");
-self.cnt = self.cnt + 1;
-if (self.cnt != 3)
- self.think = old_thrash1;
-};
-void() old_thrash16 =[ $shake16, old_thrash17 ] {lightstyle(0, "g");};
-void() old_thrash17 =[ $shake17, old_thrash18 ] {lightstyle(0, "c");};
-void() old_thrash18 =[ $shake18, old_thrash19 ] {lightstyle(0, "b");};
-void() old_thrash19 =[ $shake19, old_thrash20 ] {lightstyle(0, "a");};
-void() old_thrash20 =[ $shake20, old_thrash20 ] {finale_4();};
-
-//============================================================================
-
-void() finale_1 =
-{
- local entity pos, pl;
- local entity timer;
-
-// 1998-07-30 Shub kill count fix by Maddes start
- killed_monsters = killed_monsters + 1;
- WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // FIXME: reliable broadcast
-// 1998-07-30 Shub kill count fix by Maddes end
-
- intermission_exittime = time + 10000000; // never allow exit
- intermission_running = 1;
-
- // find the intermission spot
- pos = find (world, classname, "info_intermission");
- if (!pos)
- error ("no info_intermission");
- pl = find (world, classname, "misc_teleporttrain");
- if (!pl)
- error ("no teleporttrain");
- remove (pl);
-
- WriteByte (MSG_ALL, SVC_FINALE);
- WriteString (MSG_ALL, "");
-
- pl = find (world, classname, "player");
- while (pl != world)
- {
- pl.view_ofs = '0 0 0';
- pl.angles = other.v_angle = pos.mangle;
- pl.fixangle = TRUE; // turn this way immediately
- pl.map = self.map;
- pl.nextthink = time + 0.5;
- pl.takedamage = DAMAGE_NO;
- pl.solid = SOLID_NOT;
- pl.movetype = MOVETYPE_NONE;
- pl.modelindex = 0;
- setorigin (pl, pos.origin);
- pl = find (pl, classname, "player");
- }
-
- // make fake versions of all players as standins, and move the real
- // players to the intermission spot
-
- // wait for 1 second
- timer = spawn();
- timer.nextthink = time + 1;
- timer.think = finale_2;
-};
-
-void() finale_2 =
-{
- local vector o;
-
- // start a teleport splash inside shub
-
- o = shub.origin - '0 100 0';
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_TELEPORT);
- WriteCoord (MSG_BROADCAST, o_x);
- WriteCoord (MSG_BROADCAST, o_y);
- WriteCoord (MSG_BROADCAST, o_z);
-
- sound (shub, CHAN_VOICE, "misc/r_tele1.wav", 1, ATTN_NORM);
-
- self.nextthink = time + 2;
- self.think = finale_3;
-};
-
-void() finale_3 =
-{
- // start shub thrashing wildly
- shub.think = old_thrash1;
- sound_death (shub, CHAN_VOICE, "boss2/death.wav", 1, ATTN_NORM);
- lightstyle(0, "abcdefghijklmlkjihgfedcb");
-};
-
-void() finale_4 =
-{
- // throw tons of meat chunks
- local vector oldo;
- local float x, y, z;
- local float r;
- local entity n;
-
- sound_misc (self, CHAN_VOICE, "boss2/pop2.wav", 1, ATTN_NORM);
-
- oldo = self.origin;
-
- z = 16;
- while (z <= 144)
- {
- x = -64;
- while (x <= 64)
- {
- y = -64;
- while (y <= 64)
- {
- self.origin_x = oldo_x + x;
- self.origin_y = oldo_y + y;
- self.origin_z = oldo_z + z;
-
- r = random();
- if (r < 0.3)
- ThrowGib ("progs/gib1.mdl", -999);
- else if (r < 0.6)
- ThrowGib ("progs/gib2.mdl", -999);
- else
- ThrowGib ("progs/gib3.mdl", -999);
- y = y + 32;
- }
- x = x + 32;
- }
- z = z + 96;
- }
- // start the end text
- WriteByte (MSG_ALL, SVC_FINALE);
- WriteString (MSG_ALL, "Congratulations and well done! You have\nbeaten the hideous Shub-Niggurath, and\nher hundreds of ugly changelings and\nmonsters. You have proven that your\nskill and your cunning are greater than\nall the powers of Quake. You are the\nmaster now. Id Software salutes you.");
-
-// put a player model down
- n = spawn();
- setmodel (n, "progs/player.mdl");
- oldo = oldo - '32 264 0';
- setorigin (n, oldo);
- n.angles = '0 290 0';
- n.frame = 1;
-
- remove (self);
-
-// switch cd track
- WriteByte (MSG_ALL, SVC_CDTRACK);
- WriteByte (MSG_ALL, 3);
- WriteByte (MSG_ALL, 3);
- lightstyle(0, "m");
-};
-
-//============================================================================
-
-void(entity attacker, float damage) nopain =
-{
- self.health = 40000;
-};
-
-//============================================================================
-
-
-/*QUAKED monster_oldone (1 0 0) (-160 -128 -24) (160 128 256)
-*/
-void() monster_oldone =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
-
- precache_body_model2 ("progs/oldone.mdl");
- // precache_model2 ("progs/oldone.mdl");
-
- precache_sound2_death ("boss2/death.wav");
-// precache_sound2_idle ("boss2/idle.wav");
- precache_sound2_sight ("boss2/sight.wav");
- precache_sound2_misc ("boss2/pop2.wav");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/oldone.mdl"); //custom_mdls dumptruck_ds
- // setmodel (self, "progs/oldone.mdl");
- setsize (self, '-160 -128 -24', '160 128 256');
-
- self.health = 40000; // kill by telefrag
- self.think = old_idle1;
- self.nextthink = time + 0.1;
- self.takedamage = DAMAGE_YES;
- self.th_pain = nopain;
- self.th_die = finale_1;
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
- shub = self;
-
- total_monsters = total_monsters + 1;
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/monsters/oldone2.qc

diff --git a/qc-server/monsters/oldone2.qc b/qc-server/monsters/oldone2.qc
deleted file mode 100644
index 0cd4047..0000000
--- a/qc-server/monsters/oldone2.qc
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
-==============================================================================
-
-OLD ONE 2 - killable variant -- dumptruck_ds
-
-==============================================================================
-*/
-$cd id1/models/old2_one
-$origin 0 0 24
-$base base
-$skin skin
-$scale 1
-
-$frame old1 old2 old3 old4 old5 old6 old7 old8 old9
-$frame old10 old11 old12 old13 old14 old15 old16 old17 old18 old19
-$frame old20 old21 old22 old23 old24 old25 old26 old27 old28 old29
-$frame old30 old31 old32 old33 old34 old35 old36 old37 old38 old39
-$frame old40 old41 old42 old43 old44 old45 old46
-
-$frame shake1 shake2 shake3 shake4 shake5 shake6 shake7 shake8
-$frame shake9 shake10 shake11 shake12 shake13 shake14
-$frame shake15 shake16 shake17 shake18 shake19 shake20
-
-void() shub_face =
-{
-// go for another player if multi player
- if (self.enemy.health <= 0 || random() < 0.02)
- {
- self.enemy = find(self.enemy, classname, "player");
- if (!self.enemy)
- self.enemy = find(self.enemy, classname, "player");
- }
- ai_face();
-};
-
-
-void() old2_stand =
-{
- FindTarget ();
-};
-
-void() old2_idle1 =[ $old1, old2_idle2 ] {old2_stand();};
-void() old2_idle2 =[ $old2, old2_idle3 ] {old2_stand();};
-void() old2_idle3 =[ $old3, old2_idle4 ] {old2_stand();};
-void() old2_idle4 =[ $old4, old2_idle5 ] {old2_stand();};
-void() old2_idle5 =[ $old5, old2_idle6 ] {old2_stand();};
-void() old2_idle6 =[ $old6, old2_idle7 ] {old2_stand();};
-void() old2_idle7 =[ $old7, old2_idle8 ] {old2_stand();};
-void() old2_idle8 =[ $old8, old2_idle9 ] {old2_stand();};
-void() old2_idle9 =[ $old9, old2_idle10 ] {old2_stand();};
-void() old2_idle10 =[ $old10, old2_idle11 ] {old2_stand();};
-void() old2_idle11 =[ $old11, old2_idle12 ] {old2_stand();};
-void() old2_idle12 =[ $old12, old2_idle13 ] {old2_stand();};
-void() old2_idle13 =[ $old13, old2_idle14 ] {old2_stand();};
-void() old2_idle14 =[ $old14, old2_idle15 ] {old2_stand();};
-void() old2_idle15 =[ $old15, old2_idle16 ] {old2_stand();};
-void() old2_idle16 =[ $old16, old2_idle17 ] {old2_stand();};
-void() old2_idle17 =[ $old17, old2_idle18 ] {old2_stand();};
-void() old2_idle18 =[ $old18, old2_idle19 ] {old2_stand();};
-void() old2_idle19 =[ $old19, old2_idle20 ] {old2_stand();};
-void() old2_idle20 =[ $old20, old2_idle21 ] {old2_stand();};
-void() old2_idle21 =[ $old21, old2_idle22 ] {old2_stand();};
-void() old2_idle22 =[ $old22, old2_idle23 ] {old2_stand();};
-void() old2_idle23 =[ $old23, old2_idle24 ] {old2_stand();};
-void() old2_idle24 =[ $old24, old2_idle25 ] {old2_stand();};
-void() old2_idle25 =[ $old25, old2_idle26 ] {old2_stand();};
-void() old2_idle26 =[ $old26, old2_idle27 ] {old2_stand();};
-void() old2_idle27 =[ $old27, old2_idle28 ] {old2_stand();};
-void() old2_idle28 =[ $old28, old2_idle29 ] {old2_stand();};
-void() old2_idle29 =[ $old29, old2_idle30 ] {old2_stand();};
-void() old2_idle30 =[ $old30, old2_idle31 ] {old2_stand();};
-void() old2_idle31 =[ $old31, old2_idle32 ] {old2_stand();};
-void() old2_idle32 =[ $old32, old2_idle33 ] {old2_stand();};
-void() old2_idle33 =[ $old33, old2_idle34 ] {old2_stand();};
-void() old2_idle34 =[ $old34, old2_idle35 ] {old2_stand();};
-void() old2_idle35 =[ $old35, old2_idle36 ] {old2_stand();};
-void() old2_idle36 =[ $old36, old2_idle37 ] {old2_stand();};
-void() old2_idle37 =[ $old37, old2_idle38 ] {old2_stand();};
-void() old2_idle38 =[ $old38, old2_idle39 ] {old2_stand();};
-void() old2_idle39 =[ $old39, old2_idle40 ] {old2_stand();};
-void() old2_idle40 =[ $old40, old2_idle41 ] {old2_stand();};
-void() old2_idle41 =[ $old41, old2_idle42 ] {old2_stand();};
-void() old2_idle42 =[ $old42, old2_idle43 ] {old2_stand();};
-void() old2_idle43 =[ $old43, old2_idle44 ] {old2_stand();};
-void() old2_idle44 =[ $old44, old2_idle45 ] {old2_stand();};
-void() old2_idle45 =[ $old45, old2_idle46 ] {old2_stand();};
-void() old2_idle46 =[ $old46, old2_idle1 ] {old2_stand();};
-
-void(vector p) shub_missile =
-{
- local vector offang;
- local vector org, vec, d;
- local float t;
-
- offang = vectoangles (self.enemy.origin - self.origin);
- makevectors (offang);
-
- org = self.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
-
-// lead the player on hard mode
- if (skill > 1)
- {
- t = vlen(self.enemy.origin - org) / 300;
- vec = self.enemy.velocity;
- vec_z = 0;
- d = self.enemy.origin + t * vec;
- }
- else
- {
- d = self.enemy.origin;
- }
-
- vec = normalize (d - org);
-
- local entity puff; // added this to motivate fireballs dumptruck_ds
-
- puff = spawn ();
-
- setmodel (puff, "progs/s_explod.spr");
- puff.origin = (org);
- puff.think = s_explode1;
- puff.nextthink = time;
-
- launch_spike2 (org, vec, 300); // lavaball in your face!
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/lavaball.mdl");
- }
-
- if (!newmis.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
-
- // setmodel (newmis, "progs/lavaball.mdl");
- newmis.avelocity = '200 100 300';
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- newmis.touch = T_MissileTouch; // rocket explosion
- sound_attack (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM);
-
-// check for dead enemy
- if (self.enemy.health <= 0)
- old2_idle1 ();
-};
-
-void() old2_attk1 =[ $old1, old2_attk2 ] {shub_face();};
-void() old2_attk2 =[ $old2, old2_attk3 ] {shub_face();};
-void() old2_attk3 =[ $old3, old2_attk4 ] {shub_face();};
-void() old2_attk4 =[ $old4, old2_attk5 ] {shub_face();};
-void() old2_attk5 =[ $old5, old2_attk6 ] {shub_face();};
-void() old2_attk6 =[ $old6, old2_attk7 ] {shub_face();};
-void() old2_attk7 =[ $old7, old2_attk8 ] {shub_face();};
-void() old2_attk8 =[ $old8, old2_attk9 ] {shub_face();};
-void() old2_attk9 =[ $old9, old2_attk10 ] {shub_missile('0 -16 416');};
-void() old2_attk10 =[ $old10, old2_attk11 ] {shub_face();};
-void() old2_attk11 =[ $old11, old2_attk12 ] {shub_face();};
-void() old2_attk12 =[ $old12, old2_attk13 ] {shub_face();};
-void() old2_attk13 =[ $old13, old2_attk14 ] {shub_face();};
-void() old2_attk14 =[ $old14, old2_attk15 ] {shub_face();};
-void() old2_attk15 =[ $old15, old2_attk16 ] {shub_face();};
-void() old2_attk16 =[ $old16, old2_attk17 ] {shub_face();};
-void() old2_attk17 =[ $old17, old2_attk18 ] {shub_face();};
-void() old2_attk18 =[ $old18, old2_attk19 ] {shub_missile('0 -16 416');};
-void() old2_attk19 =[ $old19, old2_attk20 ] {shub_face();};
-void() old2_attk20 =[ $old20, old2_attk21 ] {shub_face();};
-void() old2_attk21 =[ $old21, old2_attk22 ] {shub_face();};
-void() old2_attk22 =[ $old22, old2_attk23 ] {shub_face();};
-void() old2_attk23 =[ $old23, old2_attk24 ] {shub_face();};
-void() old2_attk24 =[ $old24, old2_attk25 ] {shub_face();};
-void() old2_attk25 =[ $old25, old2_attk26 ] {shub_face();};
-void() old2_attk26 =[ $old26, old2_attk27 ] {shub_face();};
-void() old2_attk27 =[ $old27, old2_attk28 ] {shub_missile('0 -16 416');};
-void() old2_attk28 =[ $old28, old2_attk29 ] {shub_face();};
-void() old2_attk29 =[ $old29, old2_attk30 ] {shub_face();};
-void() old2_attk30 =[ $old30, old2_attk31 ] {shub_face();};
-void() old2_attk31 =[ $old31, old2_attk32 ] {shub_face();};
-void() old2_attk32 =[ $old32, old2_attk33 ] {shub_face();};
-void() old2_attk33 =[ $old33, old2_attk34 ] {shub_face();};
-void() old2_attk34 =[ $old34, old2_attk35 ] {shub_face();};
-void() old2_attk35 =[ $old35, old2_attk36 ] {shub_face();};
-void() old2_attk36 =[ $old36, old2_attk37 ] {shub_missile('0 -16 416');};
-void() old2_attk37 =[ $old37, old2_attk38 ] {shub_face();};
-void() old2_attk38 =[ $old38, old2_attk39 ] {shub_face();};
-void() old2_attk39 =[ $old39, old2_attk40 ] {shub_face();};
-void() old2_attk40 =[ $old40, old2_attk41 ] {shub_face();};
-void() old2_attk41 =[ $old41, old2_attk42 ] {shub_face();};
-void() old2_attk42 =[ $old42, old2_attk43 ] {shub_face();};
-void() old2_attk43 =[ $old43, old2_attk44 ] {shub_face();};
-void() old2_attk44 =[ $old44, old2_attk45 ] {shub_face();};
-void() old2_attk45 =[ $old45, old2_attk46 ] {shub_missile('0 -16 416');};
-void() old2_attk46 =[ $old46, old2_attk1 ] {shub_face();};
-//death twitch --dumptruck_ds
-void() old2_twitch1 =[ $shake1, old2_twitch2 ] {sound_misc (self, CHAN_VOICE, "boss2/pop2.wav", 1, ATTN_NONE);};
-void() old2_twitch2 =[ $shake2, old2_twitch3 ] {};
-void() old2_twitch3 =[ $shake3, old2_twitch4 ] {};
-void() old2_twitch4 =[ $shake4, old2_twitch5 ] {};
-void() old2_twitch5 =[ $shake5, old2_twitch6 ] {};
-void() old2_twitch6 =[ $shake6, old2_twitch7 ] {};
-void() old2_twitch7 =[ $shake7, old2_twitch8 ] {};
-void() old2_twitch8 =[ $shake8, old2_twitch9 ] {};
-void() old2_twitch9 =[ $shake9, old2_twitch10 ] {};
-void() old2_twitch10 =[ $shake10, old2_twitch11 ] {};
-void() old2_twitch11 =[ $shake11, old2_twitch12 ] {};
-void() old2_twitch12 =[ $shake12, old2_twitch13 ] {};
-void() old2_twitch13 =[ $shake13, old2_twitch14 ] {};
-void() old2_twitch14 =[ $shake14, old2_twitch15 ] {};
-void() old2_twitch15 =[ $shake15, old2_twitch16 ] {};
-void() old2_twitch16 =[ $shake16, old2_twitch17 ] {};
-void() old2_twitch17 =[ $shake17, old2_twitch18 ] {};
-void() old2_twitch18 =[ $shake18, old2_twitch19 ] {};
-void() old2_twitch19 =[ $shake19, old2_twitch20 ] {};
-void() old2_twitch20 =[ $shake20, old2_twitch21 ] {};
-void() old2_twitch21 =[ $shake17, old2_twitch22 ] {};
-void() old2_twitch22 =[ $shake18, old2_twitch23 ] {};
-void() old2_twitch23 =[ $shake19, old2_twitch24 ] {};
-void() old2_twitch24 =[ $shake20, old2_twitch25 ] {};
-void() old2_twitch25 =[ $shake17, old2_twitch26 ] {};
-void() old2_twitch26 =[ $shake18, old2_twitch27 ] {};
-void() old2_twitch27 =[ $shake19, old2_twitch28 ] {};
-void() old2_twitch28 =[ $shake20, oldone2_die ] {};
-
-void(entity attacker, float damage) oldone2_pain =
-{
- if (self.pain_finished > time)
- return;
-
- sound_pain (self, CHAN_AUTO, "oldone2/pd_pop2.wav", 1, ATTN_NORM); //new pain sound
- old2_attk1();
- self.pain_finished = time + 4;
-};
-
-void() oldone2_die =
-{
-// 1998-07-30 Shub kill count fix by Maddes start
- //killed_monsters = killed_monsters + 1;
- //WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // Already done by FL_MONSTER
-// 1998-07-30 Shub kill count fix by Maddes end
- // throw tons of meat chunks
- local vector oldo;
- local float x, y, z;
- local float r;
-
- oldo = self.origin + '0 0 112';
-
- z = 16;
- while (z <= 144)
- {
- x = -64;
- while (x <= 64)
- {
- y = -64;
- while (y <= 64)
- {
- self.origin_x = oldo_x + x;
- self.origin_y = oldo_y + y;
- self.origin_z = oldo_z + z;
-
- r = random();
- if (r < 0.3)
- // ThrowGib ("progs/gib1.mdl", -120);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, -120);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", -120);
- }
- else if (r < 0.6)
- // ThrowGib ("progs/gib2.mdl", -120);
- if (self.mdl_gib2 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib2, -120);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", -120);
- }
- else
- // ThrowGib ("progs/gib3.mdl", -120);
- if (self.mdl_gib3 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib3, -120);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", -120);
- }
- y = y + 32;
- }
- x = x + 32;
- }
- z = z + 96;
- }
- particle (oldo, '0 0 0', 0, 255);
- particle (oldo, '128 128 128', 0, 255);
- sound_death (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
-
- remove (self);
-}
-
-/*QUAKED monster_oldone2 (1 0 0) (-160 -128 -24) (160 128 256)
-*/
-void() monster_oldone2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
-
- precache_body_model2 ("progs/oldone.mdl");
- // precache_model2 ("progs/oldone.mdl");
-
- precache_sound2_death ("boss2/death.wav");
- // precache_sound2_idle ("boss2/idle.wav");
- precache_sound2_sight ("boss2/sight.wav");
- precache_sound2_misc ("boss2/pop2.wav");
- precache_sound2_pain ("oldone2/pd_pop2.wav");
-
- precache_model ("progs/lavaball.mdl");
- precache_sound ("boss1/throw.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/oldone.mdl"); //custom_mdls dumptruck_ds
- // setmodel (self, "progs/oldone.mdl");
- setsize (self, '-160 -128 -24', '160 128 256');
-
- if (!self.health)
- {
- if (skill == 0)
- self.health = 1000;
- else
- self.health = 3000;
- }
-
- self.flags = FL_MONSTER;
- self.think = old2_idle1;
- self.nextthink = time + 0.1;
- self.takedamage = DAMAGE_AIM;
- self.th_run = old2_attk1;
- self.th_pain = oldone2_pain;
- self.th_die = old2_twitch1;
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
-
- total_monsters = total_monsters + 1;
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/monsters/shalrath.qc

diff --git a/qc-server/monsters/shalrath.qc b/qc-server/monsters/shalrath.qc
deleted file mode 100644
index f799fe4..0000000
--- a/qc-server/monsters/shalrath.qc
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
-==============================================================================
-
-SHAL-RATH
-
-==============================================================================
-*/
-$cd id1/models/shalrath
-$origin 0 0 24
-$base base
-$skin skin
-$scale 0.7
-
-$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
-$frame attack9 attack10 attack11
-
-$frame pain1 pain2 pain3 pain4 pain5
-
-$frame death1 death2 death3 death4 death5 death6 death7
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
-$frame walk11 walk12
-
-void(entity attacker, float damage) shalrath_pain;
-void() ShalMissile;
-void() shal_stand =[ $walk1, shal_stand ] {ai_stand();};
-
-void() shal_walk1 =[ $walk2, shal_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE);
-ai_walk(6);};
-void() shal_walk2 =[ $walk3, shal_walk3 ] {ai_walk(4);};
-void() shal_walk3 =[ $walk4, shal_walk4 ] {ai_walk(0);};
-void() shal_walk4 =[ $walk5, shal_walk5 ] {ai_walk(0);};
-void() shal_walk5 =[ $walk6, shal_walk6 ] {ai_walk(0);};
-void() shal_walk6 =[ $walk7, shal_walk7 ] {ai_walk(0);};
-void() shal_walk7 =[ $walk8, shal_walk8 ] {ai_walk(5);};
-void() shal_walk8 =[ $walk9, shal_walk9 ] {ai_walk(6);};
-void() shal_walk9 =[ $walk10, shal_walk10 ] {ai_walk(5);};
-void() shal_walk10 =[ $walk11, shal_walk11 ] {ai_walk(0);};
-void() shal_walk11 =[ $walk12, shal_walk12 ] {ai_walk(4);};
-void() shal_walk12 =[ $walk1, shal_walk1 ] {ai_walk(5);};
-
-void() shal_run1 =[ $walk2, shal_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE);
-ai_run(6);};
-void() shal_run2 =[ $walk3, shal_run3 ] {ai_run(4);};
-void() shal_run3 =[ $walk4, shal_run4 ] {ai_run(0);};
-void() shal_run4 =[ $walk5, shal_run5 ] {ai_run(0);};
-void() shal_run5 =[ $walk6, shal_run6 ] {ai_run(0);};
-void() shal_run6 =[ $walk7, shal_run7 ] {ai_run(0);};
-void() shal_run7 =[ $walk8, shal_run8 ] {ai_run(5);};
-void() shal_run8 =[ $walk9, shal_run9 ] {ai_run(6);};
-void() shal_run9 =[ $walk10, shal_run10 ] {ai_run(5);};
-void() shal_run10 =[ $walk11, shal_run11 ] {ai_run(0);};
-void() shal_run11 =[ $walk12, shal_run12 ] {ai_run(4);};
-void() shal_run12 =[ $walk1, shal_run1 ] {ai_run(5);};
-
-void() shal_attack1 =[ $attack1, shal_attack2 ] {
-sound_attack (self, CHAN_VOICE, "shalrath/attack.wav", 1, ATTN_NORM);
-ai_face();
-};
-void() shal_attack2 =[ $attack2, shal_attack3 ] {ai_face();};
-void() shal_attack3 =[ $attack3, shal_attack4 ] {ai_face();};
-void() shal_attack4 =[ $attack4, shal_attack5 ] {ai_face();};
-void() shal_attack5 =[ $attack5, shal_attack6 ] {ai_face();};
-void() shal_attack6 =[ $attack6, shal_attack7 ] {ai_face();};
-void() shal_attack7 =[ $attack7, shal_attack8 ] {ai_face();};
-void() shal_attack8 =[ $attack8, shal_attack9 ] {ai_face();};
-void() shal_attack9 =[ $attack9, shal_attack10 ] {ShalMissile();};
-void() shal_attack10 =[ $attack10, shal_attack11 ] {ai_face();};
-void() shal_attack11 =[ $attack11, shal_run1 ] {};
-//////////////////////////
-/// new frames for turret mode START
-//////////////////////////
-void() shal_turret_attack1 =[ $attack1, shal_turret_attack2 ] {
-sound_attack (self, CHAN_VOICE, "shalrath/attack.wav", 1, ATTN_NORM);
-ai_face();
-};
-void() shal_turret_attack2 =[ $attack2, shal_turret_attack3 ] {ai_face();};
-void() shal_turret_attack3 =[ $attack3, shal_turret_attack4 ] {ai_face();};
-void() shal_turret_attack4 =[ $attack4, shal_turret_attack5 ] {ai_face();};
-void() shal_turret_attack5 =[ $attack5, shal_turret_attack6 ] {ai_face();};
-void() shal_turret_attack6 =[ $attack6, shal_turret_attack7 ] {ai_face();};
-void() shal_turret_attack7 =[ $attack7, shal_turret_attack8 ] {ai_face();};
-void() shal_turret_attack8 =[ $attack8, shal_turret_attack9 ] {ai_face();};
-void() shal_turret_attack9 =[ $attack9, shal_turret_attack10 ] {ShalMissile();};
-void() shal_turret_attack10 =[ $attack10, shal_turret_attack11 ] {ai_face();};
-void() shal_turret_attack11 =[ $attack11, shal_turret_attack12 ] {ai_face();};
-void() shal_turret_attack12 =[ $walk1, shal_turret_attack13 ] {ai_face();};
-void() shal_turret_attack13 =[ $walk1, shal_turret_attack14 ] {ai_face();};
-void() shal_turret_attack14 =[ $walk1, shal_turret_attack15 ] {ai_face();};
-void() shal_turret_attack15 =[ $walk1, shal_seek_stand1 ] {ai_run(0);};
-void() shal_seek_stand1 =[ $walk1, shal_seek_stand2 ] {ai_run(0);};
-void() shal_seek_stand2 =[ $walk1, shal_seek_stand1 ] {ai_run(0);};
-//////////////////////////
-/// new frames for turret mode END
-//////////////////////////
-void() shal_pain1 =[ $pain1, shal_pain2 ] {};
-void() shal_pain2 =[ $pain2, shal_pain3 ] {};
-void() shal_pain3 =[ $pain3, shal_pain4 ] {};
-void() shal_pain4 =[ $pain4, shal_pain5 ] {};
-void() shal_pain5 =[ $pain5, shal_run1 ] {};
-
-void() shal_death1 =[ $death1, shal_death2 ] {};
-void() shal_death2 =[ $death2, shal_death3 ] {};
-void() shal_death3 =[ $death3, shal_death4 ] {};
-void() shal_death4 =[ $death4, shal_death5 ] {};
-void() shal_death5 =[ $death5, shal_death6 ] {};
-void() shal_death6 =[ $death6, shal_death7 ] {};
-void() shal_death7 =[ $death7, shal_death7 ] {};
-
-
-void(entity attacker, float damage) shalrath_pain =
-{
- if (self.pain_finished > time)
- return;
-
- sound_pain (self, CHAN_AUTO, "shalrath/pain.wav", 1, ATTN_NORM); //CHAN_AUTO was voice - dumptruck_ds
- self.pain_finished = time + 3;
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- shal_pain1();
-};
-
-void() shalrath_die =
-{
-// check for gib
- if (self.health < -90)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_shal.mdl", self.health);
- }
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- DropStuff();
- return;
- }
- // insert death sounds here
- sound_death (self, CHAN_VOICE, "shalrath/death.wav", 1, ATTN_NORM);
- DropStuff();
- shal_death1();
- self.solid = SOLID_NOT;
-};
-
-/*
-================
-ShalMissile
-================
-*/
-void() ShalMissileTouch;
-void() ShalMissile =
-{
- local entity missile;
- local vector dir;
- local float dist, flytime;
-
- dir = normalize((self.enemy.origin + '0 0 10') - self.origin);
- dist = vlen (self.enemy.origin - self.origin);
- flytime = dist * 0.002 * (1/self.proj_speed_mod);
- if (flytime < 0.1)
- flytime = 0.1;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- sound_misc (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
-
- missile.solid = SOLID_BBOX;
- missile.movetype = MOVETYPE_FLYMISSILE;
-
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/v_spike.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-
- // setmodel (missile, "progs/v_spike.mdl");
-
- setsize (missile, '0 0 0', '0 0 0');
-
- missile.origin = self.origin + '0 0 10';
- SetSpeed(missile, dir, 400 * self.proj_speed_mod);
- missile.avelocity = self.avelocity; // custom spin on projectile --dumptruck_ds
- if !(missile.avelocity)
- missile.avelocity = '300 300 300';
- if (self.homing > 0) // If homing is off, don't bother doing any thinking
- {
- missile.homing = self.homing;
- missile.nextthink = flytime + time;
- missile.think = MissileHome;
- }
- if (skill == 3)
- missile.proj_basespeed = 350 * self.proj_speed_mod;
- else
- missile.proj_basespeed = 250 * self.proj_speed_mod;
- missile.enemy = self.enemy;
- missile.touch = ShalMissileTouch;
-};
-
-
-// void() ShalMissileTouch = --moved to misc.qc for voreball shooter --dumptruck_ds
-// {
-// if (other == self.owner)
-// return; // don't explode on owner
-//
-// if (other.classname == "monster_zombie")
-// T_Damage (other, self, self, 110);
-// T_RadiusDamage (self, self.owner, 40, world);
-// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
-//
-// WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
-// WriteByte (MSG_BROADCAST, TE_EXPLOSION);
-// WriteCoord (MSG_BROADCAST, self.origin_x);
-// WriteCoord (MSG_BROADCAST, self.origin_y);
-// WriteCoord (MSG_BROADCAST, self.origin_z);
-//
-// self.velocity = '0 0 0';
-// self.touch = SUB_Null;
-// setmodel (self, "progs/s_explod.spr");
-// self.solid = SOLID_NOT;
-// s_explode1 ();
-// };
-
-//=================================================================
-
-/*QUAKED monster_shalrath (1 0 0) (-32 -32 -24) (32 32 48) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({ "path" : "progs/shalrath.mdl", "frame": 23 });
-}
-Vore.
-
-Default health = 400
-
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound (VORE SNARL)"
-snd_idle(string) : "Path to custom idle sound"
-snd_misc(string) : "Path to custom attack2 sound (VOREBALL FIRE)"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-mdl_proj(string) : "Path to custom projectile model"
-skin_head(float) : "Skin index of custom head model"
-skin_proj(float) : "Skin index of custom projectile model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-homing(float) : "Amount that the projectile should home in target. 1 is default, 0 is none."
-
-*/
-void() monster_shalrath =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- //dumptruck_ds custom_mdls
- precache_body_model2 ("progs/shalrath.mdl");
- precache_head_model2 ("progs/h_shal.mdl");
- precache_proj_model2 ("progs/v_spike.mdl");
-// dumptruck_ds
- precache_sound2_attack ("shalrath/attack.wav");
- precache_sound2_misc ("shalrath/attack2.wav");
- precache_sound2_death ("shalrath/death.wav");
- precache_sound2_idle ("shalrath/idle.wav");
- precache_sound2_pain ("shalrath/pain.wav");
- precache_sound2_sight ("shalrath/sight.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/shalrath.mdl");
- // setmodel (self, "progs/shalrath.mdl");
- setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 400;
-
- if (!self.proj_speed_mod)
- {
- self.proj_speed_mod = 1;
- }
-
- if (!self.homing) // default to normal
- {
- self.homing = 1;
- }
- else if (self.homing < 0) // disable with negative
- {
- self.homing = 0;
- }
-
- self.th_stand = shal_stand;
- self.th_walk = shal_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = shal_seek_stand1;
- }
- else
- {
- self.th_run = shal_run1;
- }
-
- self.th_die = shalrath_die;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = shalrath_pain;
- else
- self.th_pain = SUB_NullPain;
- self.th_missile = shal_attack1;
- self.th_turret = shal_turret_attack1;
- self.think = walkmonster_start;
- self.nextthink = time + 0.1 + random ()*0.1;
-
-};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_shalrath (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/shalrath.mdl","frame":22});
-}
-*/
-void() monster_dead_shalrath =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/shalrath.mdl");
- setmodel(self, "progs/shalrath.mdl");
- self.frame = $death7;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-41.41 -40.06 -49.38','34.52 24.32 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/monsters/shambler.qc

diff --git a/qc-server/monsters/shambler.qc b/qc-server/monsters/shambler.qc
deleted file mode 100644
index cfa6a01..0000000
--- a/qc-server/monsters/shambler.qc
+++ /dev/null
@@ -1,727 +0,0 @@
-/*
-==============================================================================
-
-SHAMBLER
-
-==============================================================================
-
-================
-ShamRocket
-================
-*/
-void() ShamRocket =
-{
- local entity missile;
- local float projspeed = 900 * self.proj_speed_mod;
-
- sound_attack (self, CHAN_AUTO, "boss1/throw.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_FLYMISSILE;
- missile.solid = SOLID_BBOX;
- missile.classname = "missile";
-
-// set missile speed -- dumptruck_ds below
-
- SetSpeed(missile, normalize(self.enemy.origin - self.origin), projspeed);
- missile.angles = vectoangles(missile.velocity);
- missile.avelocity = self.cust_avelocity; //custom spin of projectile
- if !(missile.avelocity)
- missile.avelocity = '200 100 300';
-
- missile.touch = T_MissileTouch;
-
-// set missile duration
- if (self.homing > 0)
- {
- SetupHoming(missile, projspeed);
- }
- else
- {
- missile.nextthink = time + 5;
- missile.think = SUB_Remove;
- }
- missile.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/lavaball.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
- setsize (missile, '0 0 0', '0 0 0');
- makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
- setorigin (missile, self.origin + v_forward*8 + '0 0 24');
-};
-
-
-$cd id1/models/shams
-$origin 0 0 24
-$base base
-$skin base
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
-$frame stand10 stand11 stand12 stand13 stand14 stand15 stand16 stand17
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7
-$frame walk8 walk9 walk10 walk11 walk12
-
-$frame run1 run2 run3 run4 run5 run6
-
-$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7
-$frame smash8 smash9 smash10 smash11 smash12
-
-$frame swingr1 swingr2 swingr3 swingr4 swingr5
-$frame swingr6 swingr7 swingr8 swingr9
-
-$frame swingl1 swingl2 swingl3 swingl4 swingl5
-$frame swingl6 swingl7 swingl8 swingl9
-
-$frame magic1 magic2 magic3 magic4 magic5
-$frame magic6 magic7 magic8 magic9 magic10 magic11 magic12
-
-$frame pain1 pain2 pain3 pain4 pain5 pain6
-
-$frame death1 death2 death3 death4 death5 death6
-$frame death7 death8 death9 death10 death11
-
-void() sham_stand1 =[ $stand1, sham_stand2 ] {ai_stand();};
-void() sham_stand2 =[ $stand2, sham_stand3 ] {ai_stand();};
-void() sham_stand3 =[ $stand3, sham_stand4 ] {ai_stand();};
-void() sham_stand4 =[ $stand4, sham_stand5 ] {ai_stand();};
-void() sham_stand5 =[ $stand5, sham_stand6 ] {ai_stand();};
-void() sham_stand6 =[ $stand6, sham_stand7 ] {ai_stand();};
-void() sham_stand7 =[ $stand7, sham_stand8 ] {ai_stand();};
-void() sham_stand8 =[ $stand8, sham_stand9 ] {ai_stand();};
-void() sham_stand9 =[ $stand9, sham_stand10] {ai_stand();};
-void() sham_stand10 =[ $stand10, sham_stand11] {ai_stand();};
-void() sham_stand11 =[ $stand11, sham_stand12] {ai_stand();};
-void() sham_stand12 =[ $stand12, sham_stand13] {ai_stand();};
-void() sham_stand13 =[ $stand13, sham_stand14] {ai_stand();};
-void() sham_stand14 =[ $stand14, sham_stand15] {ai_stand();};
-void() sham_stand15 =[ $stand15, sham_stand16] {ai_stand();};
-void() sham_stand16 =[ $stand16, sham_stand17] {ai_stand();};
-void() sham_stand17 =[ $stand17, sham_stand1 ] {ai_stand();};
-
-void() sham_walk1 =[ $walk1, sham_walk2 ] {ai_walk(10);};
-void() sham_walk2 =[ $walk2, sham_walk3 ] {ai_walk(9);};
-void() sham_walk3 =[ $walk3, sham_walk4 ] {ai_walk(9);};
-void() sham_walk4 =[ $walk4, sham_walk5 ] {ai_walk(5);};
-void() sham_walk5 =[ $walk5, sham_walk6 ] {ai_walk(6);};
-void() sham_walk6 =[ $walk6, sham_walk7 ] {ai_walk(12);};
-void() sham_walk7 =[ $walk7, sham_walk8 ] {ai_walk(8);};
-void() sham_walk8 =[ $walk8, sham_walk9 ] {ai_walk(3);};
-void() sham_walk9 =[ $walk9, sham_walk10] {ai_walk(13);};
-void() sham_walk10 =[ $walk10, sham_walk11] {ai_walk(9);};
-void() sham_walk11 =[ $walk11, sham_walk12] {ai_walk(7);};
-void() sham_walk12 =[ $walk12, sham_walk1 ] {ai_walk(7);
-if (random() > 0.8)
- sound_idle (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);};
-
-void() sham_run1 =[ $run1, sham_run2 ] {ai_run(20);};
-void() sham_run2 =[ $run2, sham_run3 ] {ai_run(24);};
-void() sham_run3 =[ $run3, sham_run4 ] {ai_run(20);};
-void() sham_run4 =[ $run4, sham_run5 ] {ai_run(20);};
-void() sham_run5 =[ $run5, sham_run6 ] {ai_run(24);};
-void() sham_run6 =[ $run6, sham_run1 ] {ai_run(20);
-if (random() > 0.8)
- sound_idle (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);
-};
-
-void() sham_smash1 =[ $smash1, sham_smash2 ] {
-sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM);
-ai_charge(2);};
-void() sham_smash2 =[ $smash2, sham_smash3 ] {ai_charge(6);};
-void() sham_smash3 =[ $smash3, sham_smash4 ] {ai_charge(6);};
-void() sham_smash4 =[ $smash4, sham_smash5 ] {ai_charge(5);};
-void() sham_smash5 =[ $smash5, sham_smash6 ] {ai_charge(4);};
-void() sham_smash6 =[ $smash6, sham_smash7 ] {ai_charge(1);};
-void() sham_smash7 =[ $smash7, sham_smash8 ] {ai_charge(0);};
-void() sham_smash8 =[ $smash8, sham_smash9 ] {ai_charge(0);};
-void() sham_smash9 =[ $smash9, sham_smash10 ] {ai_charge(0);};
-void() sham_smash10 =[ $smash10, sham_smash11 ] {
-local vector delta;
-local float ldmg;
-
- if (!self.enemy)
- return;
- ai_charge(0);
-
- delta = self.enemy.origin - self.origin;
-
- if (vlen(delta) > 100)
- return;
- if (!CanDamage (self.enemy, self))
- return;
-
- ldmg = (random() + random() + random()) * 40;
- T_Damage (self.enemy, self, self, ldmg);
- sound_hit (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM);
-
- SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
- SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
-};
-void() sham_smash11 =[ $smash11, sham_smash12 ] {ai_charge(5);};
-void() sham_smash12 =[ $smash12, sham_run1 ] {ai_charge(4);};
-/////////////////////////////////////
-// new frames for projectile style
-////////////////////////////////////
-void() sham_proj1 =[ $smash1, sham_proj2 ] {ai_face();};
-void() sham_proj2 =[ $smash2, sham_proj3 ] {ai_face();};
-void() sham_proj3 =[ $smash3, sham_proj4 ] {ai_face();};
-void() sham_proj4 =[ $smash4, sham_proj5 ] {ai_face();};
-void() sham_proj5 =[ $smash5, sham_proj6 ] {ai_face();};
-void() sham_proj6 =[ $smash6, sham_proj7 ] {ai_face();};
-void() sham_proj7 =[ $smash7, sham_proj8 ] {ai_face();};
-void() sham_proj8 =[ $smash8, sham_proj9 ] {ai_face();};
-void() sham_proj9 =[ $smash9, sham_proj10 ] {ai_face();};
-void() sham_proj10 =[ $smash10, sham_proj11 ]
-{
-ShamRocket();
-sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); ai_face();
-};
-void() sham_proj11 =[ $smash11, sham_proj12 ] {ai_face();};
-void() sham_proj12 =[ $smash12, sham_run1 ] {ai_face();};
-/// projectile frames for turret mode
-void() sham_turret_proj1 =[ $smash1, sham_turret_proj2 ] {ai_face();};
-void() sham_turret_proj2 =[ $smash2, sham_turret_proj3 ] {ai_face();};
-void() sham_turret_proj3 =[ $smash3, sham_turret_proj4 ] {ai_face();};
-void() sham_turret_proj4 =[ $smash4, sham_turret_proj5 ] {ai_face();};
-void() sham_turret_proj5 =[ $smash5, sham_turret_proj6 ] {ai_face();};
-void() sham_turret_proj6 =[ $smash6, sham_turret_proj7 ] {ai_face();};
-void() sham_turret_proj7 =[ $smash7, sham_turret_proj8 ] {ai_face();};
-void() sham_turret_proj8 =[ $smash8, sham_turret_proj9 ] {ai_face();};
-void() sham_turret_proj9 =[ $smash9, sham_turret_proj10 ] {ai_face();};
-void() sham_turret_proj10 =[ $smash10, sham_turret_proj11 ]
-{
-ShamRocket();
-sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); ai_face();
-};
-void() sham_turret_proj11 =[ $smash11, sham_turret_proj12 ] {ai_face();};
-void() sham_turret_proj12 =[ $smash12, sham_seek_1 ] {ai_face();};
-
-void() sham_swingr1;
-
-void(float side) ShamClaw =
-{
-local vector delta;
-local float ldmg;
-
- if (!self.enemy)
- return;
- ai_charge(10);
-
- delta = self.enemy.origin - self.origin;
-
- if (vlen(delta) > 100)
- return;
-
- ldmg = (random() + random() + random()) * 20;
- T_Damage (self.enemy, self, self, ldmg);
- sound_hit (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM);
-
- if (side)
- {
- makevectors (self.angles);
- SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
- }
-};
-
-void() sham_swingl1 =[ $swingl1, sham_swingl2 ] {
-sound_misc (self, CHAN_VOICE, "shambler/melee2.wav", 1, ATTN_NORM);
-ai_charge(5);};
-void() sham_swingl2 =[ $swingl2, sham_swingl3 ] {ai_charge(3);};
-void() sham_swingl3 =[ $swingl3, sham_swingl4 ] {ai_charge(7);};
-void() sham_swingl4 =[ $swingl4, sham_swingl5 ] {ai_charge(3);};
-void() sham_swingl5 =[ $swingl5, sham_swingl6 ] {ai_charge(7);};
-void() sham_swingl6 =[ $swingl6, sham_swingl7 ] {ai_charge(9);};
-void() sham_swingl7 =[ $swingl7, sham_swingl8 ] {ai_charge(5); ShamClaw(250);};
-void() sham_swingl8 =[ $swingl8, sham_swingl9 ] {ai_charge(4);};
-void() sham_swingl9 =[ $swingl9, sham_run1 ] {
-ai_charge(8);
-if (random()<0.5)
- self.think = sham_swingr1;
-};
-
-void() sham_swingr1 =[ $swingr1, sham_swingr2 ] {
-sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM);
-ai_charge(1);};
-void() sham_swingr2 =[ $swingr2, sham_swingr3 ] {ai_charge(8);};
-void() sham_swingr3 =[ $swingr3, sham_swingr4 ] {ai_charge(14);};
-void() sham_swingr4 =[ $swingr4, sham_swingr5 ] {ai_charge(7);};
-void() sham_swingr5 =[ $swingr5, sham_swingr6 ] {ai_charge(3);};
-void() sham_swingr6 =[ $swingr6, sham_swingr7 ] {ai_charge(6);};
-void() sham_swingr7 =[ $swingr7, sham_swingr8 ] {ai_charge(6); ShamClaw(-250);};
-void() sham_swingr8 =[ $swingr8, sham_swingr9 ] {ai_charge(3);};
-void() sham_swingr9 =[ $swingr9, sham_run1 ] {ai_charge(1);
-ai_charge(10);
-if (random()<0.5)
- self.think = sham_swingl1;
-};
-
-void() sham_melee2 =
-{
- local float chance;
-
- chance = random();
-
- if (chance > 0.6)
- sham_swingr1 ();
- else
- sham_swingl1 ();
-};
-
-void() sham_melee =
-{
- local float chance;
-
- chance = random();
-
- if (chance > 0.6 || self.health == 600) // changed to >= as you can set custom health
- sham_smash1 ();
- else if (chance > 0.3)
- sham_swingr1 ();
- else
- sham_swingl1 ();
-};
-
-
-//============================================================================
-
-
-void() sham_arc_think =
-{
- if (self.owner != world && self.owner.trigger_field == self)
- self.owner.trigger_field = world;
- remove (self);
-};
-
-
-void() CastLightning =
-{
- local vector org, dir;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- ai_face ();
-
- org = self.origin + '0 0 40';
-
- dir = self.enemy.origin + '0 0 16' - org;
- dir = normalize (dir);
-
- if (self.spawnflags & I_AM_TURRET)
- {
- traceline (org, self.origin + dir*900, TRUE, self);
- }
- else
- {
- traceline (org, self.origin + dir*600, TRUE, self);
- }
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
- WriteEntity (MSG_BROADCAST, self);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
- WriteCoord (MSG_BROADCAST, trace_endpos_x);
- WriteCoord (MSG_BROADCAST, trace_endpos_y);
- WriteCoord (MSG_BROADCAST, trace_endpos_z);
-
- LightningDamage (org, trace_endpos, self, 10);
-};
-
-void() sham_magic1 =[ $magic1, sham_magic2 ] {ai_face();
- sound_misc1 (self, CHAN_WEAPON, "shambler/sattck1.wav", 1, ATTN_NORM);
-};
-void() sham_magic2 =[ $magic2, sham_magic3 ] {ai_face();};
-void() sham_magic3 =[ $magic3, sham_magic4 ] {ai_face();self.nextthink = time + 0.2;
-local entity o;
-
-self.effects = self.effects | EF_MUZZLEFLASH;
-ai_face();
-self.trigger_field = spawn();
-o = self.trigger_field;
-setmodel (o, "progs/s_light.mdl");
-setorigin (o, self.origin);
-o.owner = self;
-o.angles = self.angles;
-o.nextthink = time + 0.7;
-o.think = sham_arc_think;
-};
-void() sham_magic4 =[ $magic4, sham_magic5 ]
-{
-self.effects = self.effects | EF_MUZZLEFLASH;
-self.trigger_field.frame = 1;
-};
-void() sham_magic5 =[ $magic5, sham_magic6 ]
-{
-self.effects = self.effects | EF_MUZZLEFLASH;
-self.trigger_field.frame = 2;
-};
-void() sham_magic6 =[ $magic6, sham_magic9 ]
-{
-remove (self.trigger_field);
-self.trigger_field = world;
-CastLightning();
-sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);
-};
-void() sham_magic9 =[ $magic9, sham_magic10 ]
-{CastLightning();};
-void() sham_magic10 =[ $magic10, sham_magic11 ]
-{CastLightning();};
-void() sham_magic11 =[ $magic11, sham_magic12 ]
-{
-if (skill == 3)
- CastLightning();
-};
-void() sham_magic12 =[ $magic12, sham_run1 ] {};
-/////////////////////////
-//// turret start
-////////////////////////
-void() sham_turret_magic1 =[ $magic1, sham_turret_magic2 ] {ai_face();
- sound_misc1 (self, CHAN_WEAPON, "shambler/sattck1.wav", 1, ATTN_NORM);
-};
-void() sham_turret_magic2 =[ $magic2, sham_turret_magic3 ] {ai_face();};
-void() sham_turret_magic3 =[ $magic3, sham_turret_magic4 ] {ai_face();self.nextthink = time + 0.2;
-local entity o;
-
-self.effects = self.effects | EF_MUZZLEFLASH;
-ai_face();
-self.trigger_field = spawn();
-o = self.trigger_field;
-setmodel (o, "progs/s_light.mdl");
-setorigin (o, self.origin);
-o.owner = self;
-o.angles = self.angles;
-o.nextthink = time + 0.7;
-o.think = sham_arc_think;
-};
-void() sham_turret_magic4 =[ $magic4, sham_turret_magic5 ]
-{
-self.effects = self.effects | EF_MUZZLEFLASH;
-self.trigger_field.frame = 1;
-};
-void() sham_turret_magic5 =[ $magic5, sham_turret_magic6 ]
-{
-self.effects = self.effects | EF_MUZZLEFLASH;
-self.trigger_field.frame = 2;
-};
-void() sham_turret_magic6 =[ $magic6, sham_turret_magic9 ]
-{
-remove (self.trigger_field);
-self.trigger_field = world;
-CastLightning();
-sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);
-};
-void() sham_turret_magic9 =[ $magic9, sham_turret_magic10 ]
-{CastLightning();};
-void() sham_turret_magic10 =[ $magic10, sham_turret_magic11 ]
-{CastLightning();};
-void() sham_turret_magic11 =[ $magic11, sham_turret_magic12 ]
-{
-if (skill == 3)
- CastLightning();
-};
-void() sham_turret_magic12 =[ $magic12, sham_turret_magic13 ] {};
-void() sham_turret_magic13 =[ $stand14, sham_turret_magic14 ] {ai_face();};
-void() sham_turret_magic14 =[ $stand15, sham_turret_magic15 ] {ai_face();};
-void() sham_turret_magic15 =[ $stand16, sham_turret_magic16 ] {ai_face();};
-void() sham_turret_magic16 =[ $stand17, sham_seek_1 ] {};
-void() sham_seek_1 =[ $stand1, sham_seek_2 ] {ai_run(0);};
-void() sham_seek_2 =[ $stand2, sham_seek_3 ] {ai_run(0);};
-void() sham_seek_3 =[ $stand3, sham_seek_4 ] {ai_run(0);};
-void() sham_seek_4 =[ $stand4, sham_seek_5 ] {ai_run(0);};
-void() sham_seek_5 =[ $stand5, sham_seek_6 ] {ai_run(0);};
-void() sham_seek_6 =[ $stand6, sham_seek_7 ] {ai_run(0);};
-void() sham_seek_7 =[ $stand7, sham_seek_8 ] {ai_run(0);};
-void() sham_seek_8 =[ $stand8, sham_seek_9 ] {ai_run(0);};
-void() sham_seek_9 =[ $stand9, sham_seek_10] {ai_run(0);};
-void() sham_seek_10 =[ $stand10, sham_seek_11] {ai_run(0);};
-void() sham_seek_11 =[ $stand11, sham_seek_12] {ai_run(0);};
-void() sham_seek_12 =[ $stand12, sham_seek_13] {ai_run(0);};
-void() sham_seek_13 =[ $stand13, sham_seek_14] {ai_run(0);};
-void() sham_seek_14 =[ $stand14, sham_seek_15] {ai_run(0);};
-void() sham_seek_15 =[ $stand15, sham_seek_16] {ai_run(0);};
-void() sham_seek_16 =[ $stand16, sham_seek_17] {ai_run(0);};
-void() sham_seek_17 =[ $stand17, sham_seek_1 ] {ai_run(0);};
-/////////////////////////
-//// turret end
-////////////////////////
-
-void() sham_pain1 =[ $pain1, sham_pain2 ] {};
-void() sham_pain2 =[ $pain2, sham_pain3 ] {};
-void() sham_pain3 =[ $pain3, sham_pain4 ] {};
-void() sham_pain4 =[ $pain4, sham_pain5 ] {};
-void() sham_pain5 =[ $pain5, sham_pain6 ] {};
-void() sham_pain6 =[ $pain6, sham_run1 ] {};
-
-void(entity attacker, float damage) sham_pain =
-{
- sound_pain (self, CHAN_VOICE, "shambler/shurt2.wav", 1, ATTN_NORM);
-
- if (self.spawnflags & I_AM_TURRET)
- return;
-
- if (self.health <= 0)
- return; // allready dying, don't go into pain frame
-
- if (random()*400 > damage)
- return; // didn't flinch
-
- if (self.pain_finished > time)
- return;
- self.pain_finished = time + 2;
-
- if (self.trigger_field != world && self.trigger_field.owner == self)
- self.trigger_field.frame = 2;
- self.trigger_field = world;
-
- sham_pain1 ();
-};
-
-
-//============================================================================
-
-void() sham_death1 =[ $death1, sham_death2 ] {};
-void() sham_death2 =[ $death2, sham_death3 ] {};
-void() sham_death3 =[ $death3, sham_death4 ] {self.solid = SOLID_NOT;};
-void() sham_death4 =[ $death4, sham_death5 ] {};
-void() sham_death5 =[ $death5, sham_death6 ] {};
-void() sham_death6 =[ $death6, sham_death7 ] {};
-void() sham_death7 =[ $death7, sham_death8 ] {};
-void() sham_death8 =[ $death8, sham_death9 ] {};
-void() sham_death9 =[ $death9, sham_death10 ] {};
-void() sham_death10 =[ $death10, sham_death11 ] {};
-void() sham_death11 =[ $death11, sham_death11 ] {};
-
-void() sham_die =
-{
-// check for gib
- if (self.health < -60)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_shams.mdl", self.health);
- }
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- DropStuff();
- return;
- }
-
-// regular death
- sound_death (self, CHAN_VOICE, "shambler/sdeath.wav", 1, ATTN_NORM);
- DropStuff();
- sham_death1 ();
-};
-
-//============================================================================
-
-
-/*QUAKED monster_shambler (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/shambler.mdl");
-}
-Shambler.
-
-Default health = 600
-
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound (GRUNT)"
-snd_hit(string) : "Path to custom hit sound (FLESH TEARING)"
-snd_idle(string) : "Path to custom idle sound"
-snd_misc(string) : "Path to custom sound (GRUNT 2)"
-snd_misc1(string) : "Path to custom sound (LIGHTNING ZAP)"
-snd_misc2(string) : "Path to custom sound (LIGHTNING BOOM)"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-skin_head(float) : "Skin index of custom head model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_shambler =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- precache_body_model ("progs/shambler.mdl"); // custom_mdls dumptruck_ds
- precache_head_model ("progs/h_shams.mdl"); // custom_mdls dumptruck_ds
- // precache_model ("progs/shambler.mdl");
- precache_model ("progs/s_light.mdl");
- // precache_model ("progs/h_shams.mdl");
- precache_model ("progs/bolt.mdl");
- precache_proj_model ("progs/lavaball.mdl");
-
- precache_sound_misc1 ("shambler/sattck1.wav");
- precache_sound_misc2 ("shambler/sboom.wav");
- precache_sound_death ("shambler/sdeath.wav");
- precache_sound_pain ("shambler/shurt2.wav");
- precache_sound_idle ("shambler/sidle.wav");
- precache_sound_sight ("shambler/ssight.wav");
- precache_sound_attack ("shambler/melee1.wav");
- precache_sound_misc ("shambler/melee2.wav");
- precache_sound_hit ("shambler/smack.wav");
- precache_sound ("boss1/throw.wav"); // jaycie erysdren 2021-09-14
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
- body_model ("progs/shambler.mdl");
- // setmodel (self, "progs/shambler.mdl");
-
- setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 600;
- if (self.proj_speed_mod <= 0)
- {
- self.proj_speed_mod = 1;
- }
-
- self.th_stand = sham_stand1;
- self.th_walk = sham_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = sham_seek_1;
- }
- else
- {
- self.th_run = sham_run1;
- }
- self.th_die = sham_die;
- if (self.style == 1)
- self.th_melee = sham_melee2;
- else
- self.th_melee = sham_melee;
- if (self.style == 1)
- self.th_missile = sham_proj1;
- else
- self.th_missile = sham_magic1;
- if (self.style == 1)
- self.th_turret = sham_turret_proj1;
- else
- self.th_turret = sham_turret_magic1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = sham_pain;
- else
- self.th_pain = SUB_NullPain;
-
- walkmonster_start();
-};
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_shambler (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/shambler.mdl","frame":93});
-}
-*/
-void() monster_dead_shambler =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/shambler.mdl");
- setmodel(self, "progs/shambler.mdl");
- self.frame = $death11;
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-77.09 -72.17 -51.52','47.44 98.15 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/monsters/soldier.qc

diff --git a/qc-server/monsters/soldier.qc b/qc-server/monsters/soldier.qc
deleted file mode 100644
index 5c22745..0000000
--- a/qc-server/monsters/soldier.qc
+++ /dev/null
@@ -1,709 +0,0 @@
-/*
-==============================================================================
-
-SOLDIER / PLAYER
-
-==============================================================================
-*/
-
-$cd id1/models/soldier3
-$origin 0 -6 24
-$base base
-$skin skin
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8
-
-$frame death1 death2 death3 death4 death5 death6 death7 death8
-$frame death9 death10
-
-$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
-$frame deathc9 deathc10 deathc11
-
-$frame load1 load2 load3 load4 load5 load6 load7 load8 load9 load10 load11
-
-$frame pain1 pain2 pain3 pain4 pain5 pain6
-
-$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10
-$frame painb11 painb12 painb13 painb14
-
-$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10
-$frame painc11 painc12 painc13
-
-$frame run1 run2 run3 run4 run5 run6 run7 run8
-
-$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6 shoot7 shoot8 shoot9
-
-$frame prowl_1 prowl_2 prowl_3 prowl_4 prowl_5 prowl_6 prowl_7 prowl_8
-$frame prowl_9 prowl_10 prowl_11 prowl_12 prowl_13 prowl_14 prowl_15 prowl_16
-$frame prowl_17 prowl_18 prowl_19 prowl_20 prowl_21 prowl_22 prowl_23 prowl_24
-
-/*
-==============================================================================
-SOLDIER CODE
-==============================================================================
-*/
-void() genforcer_fire =
-{
- local vector org;
-
- // self.effects = self.effects | EF_MUZZLEFLASH; //redundant -- dumptruck_ds
- makevectors (self.angles);
-
- org = self.origin + v_forward * 30 + v_right * 5 + '0 0 12';
-
- LaunchLaser(org, self.enemy.origin - self.origin);
-};
-/*
-================
-GruntFireGrenade
-================
-*/
-void() GruntFireGrenade =
-{
- local entity missile;
-
- // self.effects = self.effects | EF_MUZZLEFLASH; //redundant -- dumptruck_ds
-
- sound_attack (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
-
-// set missile speed
-
- makevectors (self.angles);
-
- missile.velocity = normalize(self.enemy.origin - self.origin);
- missile.velocity = missile.velocity * 600;
- missile.velocity_z = 200;
-
- missile.avelocity = '300 300 300';
-
- missile.angles = vectoangles(missile.velocity);
-
- missile.touch = OgreGrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 2.5;
- missile.think = OgreGrenadeExplode;
-
- // setmodel (missile, "progs/grenade.mdl");
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/grenade.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + v_forward * 30 + v_right * 5 + '0 0 16'); //dumptruck_ds
-};
-
-/*
-================
-MonFireSpike // used for Grunts
-================
-*/
-
-void() MonFireSpike =
-{
- local vector dir;
- // local entity old;
-
- sound_attack (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
- if (self.style == 5)
- self.attack_finished = time + 1.5;
- else
- self.attack_finished = time + 0.2;
-
- dir = normalize (self.enemy.origin - self.origin);
- makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
-
- launch_spike (self.origin + v_forward * 30 + v_right * 5 + '0 0 12', dir); //dumptruck_ds
- // launch_spike (self.origin + '0 0 16', dir);
-
- //newmis.touch = superspike_touch;
- // setmodel (newmis, "progs/s_spike.mdl");
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/s_spike.mdl");
- }
-
- if (!newmis.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
- // dumptruck_ds - end
-
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
-};
-
-void() army_fire;
-
-void() army_stand1 =[ $stand1, army_stand2 ] {ai_stand();};
-void() army_stand2 =[ $stand2, army_stand3 ] {ai_stand();};
-void() army_stand3 =[ $stand3, army_stand4 ] {ai_stand();};
-void() army_stand4 =[ $stand4, army_stand5 ] {ai_stand();};
-void() army_stand5 =[ $stand5, army_stand6 ] {ai_stand();};
-void() army_stand6 =[ $stand6, army_stand7 ] {ai_stand();};
-void() army_stand7 =[ $stand7, army_stand8 ] {ai_stand();};
-void() army_stand8 =[ $stand8, army_stand1 ] {ai_stand();};
-
-void() army_walk1 =[ $prowl_1, army_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE);
-ai_walk(1);};
-void() army_walk2 =[ $prowl_2, army_walk3 ] {ai_walk(1);};
-void() army_walk3 =[ $prowl_3, army_walk4 ] {ai_walk(1);};
-void() army_walk4 =[ $prowl_4, army_walk5 ] {ai_walk(1);};
-void() army_walk5 =[ $prowl_5, army_walk6 ] {ai_walk(2);};
-void() army_walk6 =[ $prowl_6, army_walk7 ] {ai_walk(3);};
-void() army_walk7 =[ $prowl_7, army_walk8 ] {ai_walk(4);};
-void() army_walk8 =[ $prowl_8, army_walk9 ] {ai_walk(4);};
-void() army_walk9 =[ $prowl_9, army_walk10 ] {ai_walk(2);};
-void() army_walk10 =[ $prowl_10, army_walk11 ] {ai_walk(2);};
-void() army_walk11 =[ $prowl_11, army_walk12 ] {ai_walk(2);};
-void() army_walk12 =[ $prowl_12, army_walk13 ] {ai_walk(1);};
-void() army_walk13 =[ $prowl_13, army_walk14 ] {ai_walk(0);};
-void() army_walk14 =[ $prowl_14, army_walk15 ] {ai_walk(1);};
-void() army_walk15 =[ $prowl_15, army_walk16 ] {ai_walk(1);};
-void() army_walk16 =[ $prowl_16, army_walk17 ] {ai_walk(1);};
-void() army_walk17 =[ $prowl_17, army_walk18 ] {ai_walk(3);};
-void() army_walk18 =[ $prowl_18, army_walk19 ] {ai_walk(3);};
-void() army_walk19 =[ $prowl_19, army_walk20 ] {ai_walk(3);};
-void() army_walk20 =[ $prowl_20, army_walk21 ] {ai_walk(3);};
-void() army_walk21 =[ $prowl_21, army_walk22 ] {ai_walk(2);};
-void() army_walk22 =[ $prowl_22, army_walk23 ] {ai_walk(1);};
-void() army_walk23 =[ $prowl_23, army_walk24 ] {ai_walk(1);};
-void() army_walk24 =[ $prowl_24, army_walk1 ] {ai_walk(1);};
-
-void() army_run1 =[ $run1, army_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE);
-ai_run(11);};
-void() army_run2 =[ $run2, army_run3 ] {ai_run(15);};
-void() army_run3 =[ $run3, army_run4 ] {ai_run(10);};
-void() army_run4 =[ $run4, army_run5 ] {ai_run(10);};
-void() army_run5 =[ $run5, army_run6 ] {ai_run(8);};
-void() army_run6 =[ $run6, army_run7 ] {ai_run(15);};
-void() army_run7 =[ $run7, army_run8 ] {ai_run(10);};
-void() army_run8 =[ $run8, army_run1 ] {ai_run(8);};
-
-
-void() army_atk6;
-void() army_atk1 =[ $shoot1, army_atk2 ] {ai_face();self.count = 0;self.t_length= 4 + floor(random()*4);};
-void() army_atk2 =[ $shoot2, army_atk3 ] {ai_face();};
-void() army_atk3 =[ $shoot3, army_atk4 ] {ai_face();};
-void() army_atk4 =[ $shoot4, army_atk5 ] {ai_face();};
-void() army_atk5 ={
-self.frame = $shoot5;
-self.nextthink = time + .1;
-if (self.style == 5 && self.count < self.t_length)
-{
- self.count +=1;
-}
-else
-{
- self.think = army_atk6;
-}
-ai_face();
-army_fire();
-self.effects = self.effects | EF_MUZZLEFLASH;};
-void() army_atk6 =[ $shoot6, army_atk7 ] {ai_face();};
-void() army_atk7 =[ $shoot7, army_atk8 ] {ai_face();SUB_CheckRefire (army_atk1);};
-void() army_atk8 =[ $shoot8, army_atk9 ] {ai_face();};
-void() army_atk9 =[ $shoot9, army_run1 ] {ai_face();};
-// new frames for turrets
-void() army_turret_atk6;
-void() army_turret_atk1 =[ $shoot1, army_turret_atk2 ] {ai_face();self.count = 0;self.t_length= 4 + floor(random()*4);};
-void() army_turret_atk2 =[ $shoot2, army_turret_atk3 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() army_turret_atk3 =[ $shoot3, army_turret_atk4 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() army_turret_atk4 =[ $shoot4, army_turret_atk5 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() army_turret_atk5 ={
-self.frame = $shoot5;
-self.nextthink = time + .1;
-if (self.style == 5 && self.count < self.t_length)
-{
- self.count +=1;
-}
-else
-{
- self.think = army_turret_atk6;
-}
-ai_face();
-army_fire();
-self.effects = self.effects | EF_MUZZLEFLASH;};
-void() army_turret_atk6 =[ $shoot6, army_turret_atk7 ] {ai_face();};
-void() army_turret_atk7 =[ $shoot7, army_turret_atk8 ] {ai_face();SUB_CheckRefire (army_turret_atk1);};
-void() army_turret_atk8 =[ $shoot8, army_turret_atk9 ] {ai_face();};
-void() army_turret_atk9 =[ $stand4, army_turret_atk10 ] {ai_face();};
-void() army_turret_atk10 =[ $stand5, army_seeking_stand1 ] {ai_face();};
-void() army_seeking_stand1 =[ $stand1, army_seeking_stand2 ] {ai_run(0);};
-void() army_seeking_stand2 =[ $stand2, army_seeking_stand3 ] {ai_run(0);};
-void() army_seeking_stand3 =[ $stand3, army_seeking_stand4 ] {ai_run(0);};
-void() army_seeking_stand4 =[ $stand4, army_seeking_stand5 ] {ai_run(0);};
-void() army_seeking_stand5 =[ $stand5, army_seeking_stand6 ] {ai_run(0);};
-void() army_seeking_stand6 =[ $stand6, army_seeking_stand7 ] {ai_run(0);};
-void() army_seeking_stand7 =[ $stand7, army_seeking_stand8 ] {ai_run(0);};
-void() army_seeking_stand8 =[ $stand8, army_seeking_stand1 ] {ai_run(0);};
-// new frames for turrets end
-
-void() army_pain1 =[ $pain1, army_pain2 ] {};
-void() army_pain2 =[ $pain2, army_pain3 ] {};
-void() army_pain3 =[ $pain3, army_pain4 ] {};
-void() army_pain4 =[ $pain4, army_pain5 ] {};
-void() army_pain5 =[ $pain5, army_pain6 ] {};
-void() army_pain6 =[ $pain6, army_run1 ] {ai_pain(1);};
-
-void() army_painb1 =[ $painb1, army_painb2 ] {};
-void() army_painb2 =[ $painb2, army_painb3 ] {ai_painforward(13);};
-void() army_painb3 =[ $painb3, army_painb4 ] {ai_painforward(9);};
-void() army_painb4 =[ $painb4, army_painb5 ] {};
-void() army_painb5 =[ $painb5, army_painb6 ] {};
-void() army_painb6 =[ $painb6, army_painb7 ] {};
-void() army_painb7 =[ $painb7, army_painb8 ] {};
-void() army_painb8 =[ $painb8, army_painb9 ] {};
-void() army_painb9 =[ $painb9, army_painb10] {};
-void() army_painb10=[ $painb10, army_painb11] {};
-void() army_painb11=[ $painb11, army_painb12] {};
-void() army_painb12=[ $painb12, army_painb13] {ai_pain(2);};
-void() army_painb13=[ $painb13, army_painb14] {};
-void() army_painb14=[ $painb14, army_run1 ] {};
-
-void() army_painc1 =[ $painc1, army_painc2 ] {};
-void() army_painc2 =[ $painc2, army_painc3 ] {ai_pain(1);};
-void() army_painc3 =[ $painc3, army_painc4 ] {};
-void() army_painc4 =[ $painc4, army_painc5 ] {};
-void() army_painc5 =[ $painc5, army_painc6 ] {ai_painforward(1);};
-void() army_painc6 =[ $painc6, army_painc7 ] {ai_painforward(1);};
-void() army_painc7 =[ $painc7, army_painc8 ] {};
-void() army_painc8 =[ $painc8, army_painc9 ] {ai_pain(1);};
-void() army_painc9 =[ $painc9, army_painc10] {ai_painforward(4);};
-void() army_painc10=[ $painc10, army_painc11] {ai_painforward(3);};
-void() army_painc11=[ $painc11, army_painc12] {ai_painforward(6);};
-void() army_painc12=[ $painc12, army_painc13] {ai_painforward(8);};
-void() army_painc13=[ $painc13, army_run1] {};
-
-void(entity attacker, float damage) army_pain =
-{
- local float r;
-
- if (self.pain_finished > time)
- return;
-
- r = random();
-
- if (r < 0.2)
- { // turret checks moved here to play pain sounds correctly - dumptruck_ds
- self.pain_finished = time + 0.6;
- sound_pain (self, CHAN_VOICE, "soldier/pain1.wav", 1, ATTN_NORM);
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- army_pain1 ();
- }
- else if (r < 0.6)
- {
- self.pain_finished = time + 1.1;
- sound_misc (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM);
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- army_painb1 ();
- }
- else
- {
- self.pain_finished = time + 1.1;
- sound_misc (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM);
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- army_painc1 ();
- }
-};
-
-void() army_fire =
-{ //dumptruck_ds start rocket grunt stuff
-
-if (self.style == 1)
-
- {
- ai_face();
-
- W_GruntRocket();
- }
-
-else if (self.style == 2)
-
- {
- ai_face();
- if (self.spawnflags & I_AM_TURRET)
- {
- PreachFireGrenade(self.attack_elevation);
- }
- else
- GruntFireGrenade();
- }
-
-else if (self.style == 3)
-
- {
- ai_face();
- genforcer_fire();
- }
-
-else if (self.style == 4 || self.style == 5)
-
- {
- ai_face();
- MonFireSpike();
- }
-
-else
-
- {
- local vector dir;
- local entity en;
-
- ai_face();
-
- sound_attack (self, CHAN_WEAPON, "soldier/sattck1.wav", 1, ATTN_NORM);
-
- // fire somewhat behind the player, so a dodging player is harder to hit
- en = self.enemy;
-
- dir = en.origin - en.velocity*0.2;
- dir = normalize (dir - self.origin);
-
- FireBullets (4, dir, '0.1 0.1 0');
- }
-
-};
-
-void() army_die1 =[ $death1, army_die2 ] {};
-void() army_die2 =[ $death2, army_die3 ] {};
-void() army_die3 =[ $death3, army_die4 ]
-{self.solid = SOLID_NOT;
-// style ammotype check -- dumptruck_ds
- if (self.style == 1)
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 2)
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 3)
- {
- self.ammo_cells = 5;
- }
- if (self.style == 4 || self.style == 5)
- {
- self.ammo_nails = 5;
- }
- else if (self.style == 0)
- {
- self.ammo_shells = 5;
- }
-if(!self.keep_ammo)DropBackpack();};
-void() army_die4 =[ $death4, army_die5 ] {};
-void() army_die5 =[ $death5, army_die6 ] {};
-void() army_die6 =[ $death6, army_die7 ] {};
-void() army_die7 =[ $death7, army_die8 ] {};
-void() army_die8 =[ $death8, army_die9 ] {};
-void() army_die9 =[ $death9, army_die10 ] {};
-void() army_die10 =[ $death10, army_die10 ] {};
-
-void() army_cdie1 =[ $deathc1, army_cdie2 ] {};
-void() army_cdie2 =[ $deathc2, army_cdie3 ] {ai_back(5);};
-void() army_cdie3 =[ $deathc3, army_cdie4 ]
-{self.solid = SOLID_NOT;
-// style ammotype check -- dumptruck_ds
- if (self.style == 1)
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 2)
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 3)
- {
- self.ammo_cells = 5;
- }
- if (self.style == 4 || self.style == 5)
- {
- self.ammo_nails = 5;
- }
- else if (self.style == 0)
- {
- self.ammo_shells = 5;
- }
-if(!self.keep_ammo)DropBackpack();ai_back(4);}; //dumptruck_ds
-void() army_cdie4 =[ $deathc4, army_cdie5 ] {ai_back(13);};
-void() army_cdie5 =[ $deathc5, army_cdie6 ] {ai_back(3);};
-void() army_cdie6 =[ $deathc6, army_cdie7 ] {ai_back(4);};
-void() army_cdie7 =[ $deathc7, army_cdie8 ] {};
-void() army_cdie8 =[ $deathc8, army_cdie9 ] {};
-void() army_cdie9 =[ $deathc9, army_cdie10 ] {};
-void() army_cdie10 =[ $deathc10, army_cdie11 ] {};
-void() army_cdie11 =[ $deathc11, army_cdie11 ] {};
-
-
-void() army_die =
-{
-// check for gib
- if (self.health < -35)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_guard.mdl", self.health);
- }
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- DropStuff();
- return;
- }
-
-// regular death
- sound_death (self, CHAN_VOICE, "soldier/death1.wav", 1, ATTN_NORM);
- DropStuff();
- if (random() < 0.5)
- army_die1 ();
- else
- army_cdie1 ();
-};
-
-
-/*QUAKED monster_army (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/soldier.mdl");
-}
-Grunt.
-
-Default health = 30"
-
-keep_ammo "1 = Don't drop backpack upon death"
-snd_death "Path to custom death sound"
-snd_pain "Path to custom pain sound"
-snd_sight "Path to custom sight sound"
-snd_attack "Path to custom attack sound (GUNSHOT)"
-snd_idle "Path to custom idle sound"
-snd_misc "Path to custom sound (PAIN 2)"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-skin_head(float) : "Skin index of custom head model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-style "Attack type"
-0 "Default (shotgun)"
-1 "Rockets"
-2 "Grenades"
-3 "lasers"
-4 "Nails"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_army =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- //dumptruck_ds custom_mdls
- precache_body_model ("progs/soldier.mdl");
- precache_head_model ("progs/h_guard.mdl");
- precache_proj_model ("progs/missile.mdl"); // used if style == 1
- precache_proj_model ("progs/grenade.mdl"); // used if style == 2
- precache_model2 ("progs/laser.mdl"); // used if style == 3
- //dumptruck_ds custom_mdls
- precache_model ("progs/gib1.mdl");
- precache_model ("progs/gib2.mdl");
- precache_model ("progs/gib3.mdl");
-
- precache_sound_death ("soldier/death1.wav");
- precache_sound_idle ("soldier/idle.wav");
- precache_sound_pain ("soldier/pain1.wav");
- precache_sound_misc ("soldier/pain2.wav");
- precache_sound_attack ("soldier/sattck1.wav");
- precache_sound_sight ("soldier/sight1.wav");
- precache_sound2 ("enforcer/enfire.wav"); // used if style == 3
- precache_sound2 ("enforcer/enfstop.wav"); // used if style == 3
-
- precache_sound ("player/udeath.wav"); // gib death
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- //dumptruck_ds custom_mdls
- body_model ("progs/soldier.mdl");
-
- setsize (self, '-16 -16 -24', '16 16 40');
-
- if (!self.proj_speed_mod)
- {
- self.proj_speed_mod = 1;
- }
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 30;
-
- self.th_stand = army_stand1;
- self.th_walk = army_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = army_seeking_stand1;
- }
- else
- {
- self.th_run = army_run1;
- }
- self.th_missile = army_atk1;
- self.th_turret = army_turret_atk1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = army_pain;
- else
- self.th_pain = SUB_NullPain;
- self.th_die = army_die;
-
- walkmonster_start ();
-};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_army (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID FACE_UP X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/soldier.mdl","frame":28});
-}
-*/
-void() monster_dead_army =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/soldier.mdl");
- setmodel(self, "progs/soldier.mdl");
- if (self.spawnflags & 2)
- {
- self.frame = $death10;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-38.27 -30.47 -50.3','22.1 25.35 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
- else
- {
- self.frame = $deathc11;
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-39.85 -29.35 -49.07','20.52 33.17 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/monsters/wizard.qc

diff --git a/qc-server/monsters/wizard.qc b/qc-server/monsters/wizard.qc
deleted file mode 100644
index dfde2b0..0000000
--- a/qc-server/monsters/wizard.qc
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
-==============================================================================
-
-WIZARD
-
-==============================================================================
-*/
-
-$cd id1/models/a_wizard
-$origin 0 0 24
-$base wizbase
-$skin wizbase
-
-$frame hover1 hover2 hover3 hover4 hover5 hover6 hover7 hover8
-$frame hover9 hover10 hover11 hover12 hover13 hover14 hover15
-
-$frame fly1 fly2 fly3 fly4 fly5 fly6 fly7 fly8 fly9 fly10
-$frame fly11 fly12 fly13 fly14
-
-$frame magatt1 magatt2 magatt3 magatt4 magatt5 magatt6 magatt7
-$frame magatt8 magatt9 magatt10 magatt11 magatt12 magatt13
-
-$frame pain1 pain2 pain3 pain4
-
-$frame death1 death2 death3 death4 death5 death6 death7 death8
-
-/*
-==============================================================================
-
-WIZARD
-
-If the player moves behind cover before the missile is launched, launch it
-at the last visible spot with no velocity leading, in hopes that the player
-will duck back out and catch it.
-==============================================================================
-*/
-
-/*
-=============
-LaunchMissile
-
-Sets the given entities velocity and angles so that it will hit self.enemy
-if self.enemy maintains it's current velocity
-0.1 is moderately accurate, 0.0 is totally accurate
-=============
-*/
-void(entity missile, float mspeed, float accuracy) LaunchMissile =
-{
- local vector vec, move;
- local float fly;
-
- makevectors (self.angles);
-
-// set missile speed
- vec = self.enemy.origin + self.enemy.mins + self.enemy.size * 0.7 - missile.origin;
-
-// calc aproximate time for missile to reach vec
- fly = vlen (vec) / mspeed;
-
-// get the entities xy velocity
- move = self.enemy.velocity;
- move_z = 0;
-
-// project the target forward in time
- vec = vec + move * fly;
-
- vec = normalize(vec);
- vec = vec + accuracy*v_up*(random()- 0.5) + accuracy*v_right*(random()- 0.5);
-
- missile.velocity = vec * mspeed;
-
- missile.angles = '0 0 0';
- missile.angles_y = vectoyaw(missile.velocity);
-
- if (self.projexpl)
- {
- missile.touch = T_WizardMisTouch;
- }
-
-// set missile duration
- missile.nextthink = time + 5;
- missile.think = SUB_Remove;
-};
-
-
-void() wiz_run1;
-void() wiz_side1;
-
-/*
-=================
-WizardCheckAttack
-=================
-*/
-float() WizardCheckAttack =
-{
- local vector spot1, spot2;
- local entity targ;
- local float chance;
-
- if (time < self.attack_finished)
- return FALSE;
- if (!enemy_vis)
- return FALSE;
-
- if (enemy_range == RANGE_FAR)
- {
- if (self.attack_state != AS_STRAIGHT)
- {
- self.attack_state = AS_STRAIGHT;
- wiz_run1 ();
- }
- return FALSE;
- }
-
- targ = self.enemy;
-
-// see if any entities are in the way of the shot
- spot1 = self.origin + self.view_ofs;
- spot2 = targ.origin + targ.view_ofs;
-
- traceline (spot1, spot2, FALSE, self);
-
- if (trace_ent != targ)
- { // don't have a clear shot, so move to a side
- if (self.attack_state != AS_STRAIGHT)
- {
- self.attack_state = AS_STRAIGHT;
- wiz_run1 ();
- }
- return FALSE;
- }
-
- if (enemy_range == RANGE_MELEE)
- chance = 0.9;
- else if (enemy_range == RANGE_NEAR)
- chance = 0.6;
- else if (enemy_range == RANGE_MID)
- chance = 0.2;
- else
- chance = 0;
-
- if (random () < chance)
- {
- self.attack_state = AS_MISSILE;
- return TRUE;
- }
-
- if (enemy_range == RANGE_MID)
- {
- if (self.attack_state != AS_STRAIGHT)
- {
- self.attack_state = AS_STRAIGHT;
- wiz_run1 ();
- }
- }
- else
- {
- if (self.attack_state != AS_SLIDING)
- {
- self.attack_state = AS_SLIDING;
- wiz_side1 ();
- }
- }
-
- return FALSE;
-};
-
-/*
-=================
-WizardAttackFinished
-=================
-*/
-void() WizardAttackFinished =
-{
- if (enemy_range >= RANGE_MID || !enemy_vis)
- {
- self.attack_state = AS_STRAIGHT;
- self.think = wiz_run1;
- }
- else
- {
- self.attack_state = AS_SLIDING;
- self.think = wiz_side1;
- }
-};
-
-/*
-==============================================================================
-
-FAST ATTACKS
-
-==============================================================================
-*/
-void() Wiz_AttackSound = // this is a hack to fix Wizard custom attack sounds
-{
- sound_attack (self, CHAN_AUTO, "wizard/wattack.wav", 1, ATTN_NORM);
-};
-
-void() Wiz_FastFire =
-{
- local vector vec;
- local vector dst;
- local entity oldself;
- local float projspeed = self.owner.proj_speed_mod * 600;
-
- if (self.owner.health > 0)
- {
- self.owner.effects = self.owner.effects | EF_MUZZLEFLASH;
-
- makevectors (self.enemy.angles);
- dst = self.enemy.origin - 13*self.movedir;
-
- vec = normalize(dst - self.origin);
- // sound_attack (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM);
- launch_spike (self.origin, vec);
- SetSpeed(newmis, vec, projspeed);
- newmis.owner = self.owner;
- newmis.classname = "wizspike";
- if (self.owner.projexpl)
- {
- // dprint("spawning exploding wizard proj from fastfire\n");
- newmis.touch = T_WizardMisTouch;
- }
- if (self.owner.homing)
- {
- oldself = self;
- self = self.owner;
- SetupHoming(newmis, projspeed);
- self = oldself;
- }
- setmodel(newmis, self.owner.mdl_proj);
- newmis.skin = self.owner.skin_proj;
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
-
- }
-
- remove (self);
-};
-
-
-void() Wiz_StartFast =
-{
- local entity missile;
-
- // sound_attack (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM);
- self.v_angle = self.angles;
- makevectors (self.angles);
-
- missile = spawn ();
- missile.owner = self;
- missile.nextthink = time + 0.6;
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right*14);
- missile.enemy = self.enemy;
- missile.nextthink = time + 0.8;
- missile.think = Wiz_FastFire;
- missile.movedir = v_right;
-
- missile = spawn ();
- missile.owner = self;
- missile.nextthink = time + 1;
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right* -14);
- missile.enemy = self.enemy;
- missile.nextthink = time + 0.3;
- missile.think = Wiz_FastFire;
- missile.movedir = VEC_ORIGIN - v_right;
-};
-
-void() Wiz_idlesound =
-{
-local float wr;
- wr = random() * 5;
-
- if (self.fly_sound < time)
- {
- self.fly_sound = time + 2;
- if (wr > 4.5)
- sound_idle (self, CHAN_VOICE, "wizard/widle1.wav", 1, ATTN_IDLE);
- if (wr < 1.5)
- sound_misc (self, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_IDLE);
- }
- return;
-};
-
-void() wiz_stand1 =[ $hover1, wiz_stand2 ] {ai_stand();};
-void() wiz_stand2 =[ $hover2, wiz_stand3 ] {ai_stand();};
-void() wiz_stand3 =[ $hover3, wiz_stand4 ] {ai_stand();};
-void() wiz_stand4 =[ $hover4, wiz_stand5 ] {ai_stand();};
-void() wiz_stand5 =[ $hover5, wiz_stand6 ] {ai_stand();};
-void() wiz_stand6 =[ $hover6, wiz_stand7 ] {ai_stand();};
-void() wiz_stand7 =[ $hover7, wiz_stand8 ] {ai_stand();};
-void() wiz_stand8 =[ $hover8, wiz_stand1 ] {ai_stand();};
-
-void() wiz_walk1 =[ $hover1, wiz_walk2 ] {ai_walk(8);
-Wiz_idlesound();};
-void() wiz_walk2 =[ $hover2, wiz_walk3 ] {ai_walk(8);};
-void() wiz_walk3 =[ $hover3, wiz_walk4 ] {ai_walk(8);};
-void() wiz_walk4 =[ $hover4, wiz_walk5 ] {ai_walk(8);};
-void() wiz_walk5 =[ $hover5, wiz_walk6 ] {ai_walk(8);};
-void() wiz_walk6 =[ $hover6, wiz_walk7 ] {ai_walk(8);};
-void() wiz_walk7 =[ $hover7, wiz_walk8 ] {ai_walk(8);};
-void() wiz_walk8 =[ $hover8, wiz_walk1 ] {ai_walk(8);};
-
-void() wiz_side1 =[ $hover1, wiz_side2 ] {ai_run(8);
-Wiz_idlesound();};
-void() wiz_side2 =[ $hover2, wiz_side3 ] {ai_run(8);};
-void() wiz_side3 =[ $hover3, wiz_side4 ] {ai_run(8);};
-void() wiz_side4 =[ $hover4, wiz_side5 ] {ai_run(8);};
-void() wiz_side5 =[ $hover5, wiz_side6 ] {ai_run(8);};
-void() wiz_side6 =[ $hover6, wiz_side7 ] {ai_run(8);};
-void() wiz_side7 =[ $hover7, wiz_side8 ] {ai_run(8);};
-void() wiz_side8 =[ $hover8, wiz_side1 ] {ai_run(8);};
-
-void() wiz_run1 =[ $fly1, wiz_run2 ] {ai_run(16);
-Wiz_idlesound();
-};
-void() wiz_run2 =[ $fly2, wiz_run3 ] {ai_run(16);};
-void() wiz_run3 =[ $fly3, wiz_run4 ] {ai_run(16);};
-void() wiz_run4 =[ $fly4, wiz_run5 ] {ai_run(16);};
-void() wiz_run5 =[ $fly5, wiz_run6 ] {ai_run(16);};
-void() wiz_run6 =[ $fly6, wiz_run7 ] {ai_run(16);};
-void() wiz_run7 =[ $fly7, wiz_run8 ] {ai_run(16);};
-void() wiz_run8 =[ $fly8, wiz_run9 ] {ai_run(16);};
-void() wiz_run9 =[ $fly9, wiz_run10 ] {ai_run(16);};
-void() wiz_run10 =[ $fly10, wiz_run11 ] {ai_run(16);};
-void() wiz_run11 =[ $fly11, wiz_run12 ] {ai_run(16);};
-void() wiz_run12 =[ $fly12, wiz_run13 ] {ai_run(16);};
-void() wiz_run13 =[ $fly13, wiz_run14 ] {ai_run(16);};
-void() wiz_run14 =[ $fly14, wiz_run1 ] {ai_run(16);};
-
-void() wiz_fast1 =[ $magatt1, wiz_fast2 ] {ai_face();Wiz_StartFast();Wiz_AttackSound();};
-void() wiz_fast2 =[ $magatt2, wiz_fast3 ] {ai_face();};
-void() wiz_fast3 =[ $magatt3, wiz_fast4 ] {ai_face();};
-void() wiz_fast4 =[ $magatt4, wiz_fast5 ] {ai_face();};
-void() wiz_fast5 =[ $magatt5, wiz_fast6 ] {ai_face();};
-void() wiz_fast6 =[ $magatt6, wiz_fast7 ] {ai_face();};
-void() wiz_fast7 =[ $magatt5, wiz_fast8 ] {ai_face();Wiz_AttackSound();};
-void() wiz_fast8 =[ $magatt4, wiz_fast9 ] {ai_face();};
-void() wiz_fast9 =[ $magatt3, wiz_fast10 ] {ai_face();};
-void() wiz_fast10 =[ $magatt2, wiz_run1 ] {ai_face();SUB_AttackFinished(2);WizardAttackFinished ();};
-
-void() wiz_pain1 =[ $pain1, wiz_pain2 ] {};
-void() wiz_pain2 =[ $pain2, wiz_pain3 ] {};
-void() wiz_pain3 =[ $pain3, wiz_pain4 ] {};
-void() wiz_pain4 =[ $pain4, wiz_run1 ] {};
-
-void() wiz_death1 =[ $death1, wiz_death2 ] {
-
-self.velocity_x = -200 + 400*random();
-self.velocity_y = -200 + 400*random();
-self.velocity_z = 100 + 100*random();
-self.flags = self.flags - (self.flags & FL_ONGROUND);
-sound_death (self, CHAN_VOICE, "wizard/wdeath.wav", 1, ATTN_NORM);
-};
-void() wiz_death2 =[ $death2, wiz_death3 ] {};
-void() wiz_death3 =[ $death3, wiz_death4 ]{self.solid = SOLID_NOT;};
-void() wiz_death4 =[ $death4, wiz_death5 ] {};
-void() wiz_death5 =[ $death5, wiz_death6 ] {};
-void() wiz_death6 =[ $death6, wiz_death7 ] {};
-void() wiz_death7 =[ $death7, wiz_death8 ] {};
-void() wiz_death8 =[ $death8, wiz_death8 ] {};
-
-void() wiz_die =
-{
-// check for gib
- if (self.health < -40)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_wizard.mdl", self.health);
- }
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- DropStuff();
- return;
- }
- DropStuff();
- wiz_death1 ();
-};
-
-void(entity attacker, float damage) Wiz_Pain =
-{
- sound_pain (self, CHAN_VOICE, "wizard/wpain.wav", 1, ATTN_NORM);
- if (random()*70 > damage)
- return; // didn't flinch
-
- wiz_pain1 ();
-};
-
-
-void() Wiz_Missile =
-{
- wiz_fast1();
-};
-
-/*QUAKED monster_wizard (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/wizard.mdl");
-}
-Wizard a.k.a. Scrag.
-
-Default health = 80
-
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound"
-snd_idle(string) : "Path to custom idle sound"
-snd_misc(string) : "Path to custom sound (IDLE 2)"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-skin_head(float) : "Skin index of custom head model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-projexpl(choices) : "Exploding projectiles"
-0 : "No explosions"
-1 : "All projectiles explode"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_wizard =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
-
- if (!self.mdl_proj)
- {
- self.mdl_proj = "progs/w_spike.mdl";
- }
-
- // dumptruck_ds custom_mdls
- precache_body_model ("progs/wizard.mdl");
- precache_head_model ("progs/h_wizard.mdl");
- precache_proj_model ("progs/w_spike.mdl");
- ////dumptruck_ds
- precache_sound_hit ("wizard/hit.wav"); // used by c code
- precache_sound_attack ("wizard/wattack.wav");
- precache_sound_death ("wizard/wdeath.wav");
- precache_sound_idle ("wizard/widle1.wav");
- precache_sound_misc ("wizard/widle2.wav");
- precache_sound_pain ("wizard/wpain.wav");
- precache_sound_sight ("wizard/wsight.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/wizard.mdl");
- // setmodel (self, "progs/wizard.mdl"); //dumptruck_ds
-
- setsize (self, '-16 -16 -24', '16 16 40');
-
- if (!self.proj_speed_mod)
- {
- self.proj_speed_mod = 1;
- }
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 80;
-
- self.th_stand = wiz_stand1;
- self.th_walk = wiz_walk1;
- self.th_run = wiz_run1;
- self.th_missile = Wiz_Missile;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = Wiz_Pain;
- else
- self.th_pain = SUB_NullPain;
- self.th_die = wiz_die;
-
- flymonster_start ();
-};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_wizard (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/wizard.mdl","frame":53});
-}
-*/
-void() monster_dead_wizard =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/wizard.mdl");
- setmodel(self, "progs/wizard.mdl");
- self.frame = $death8;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-50.75 -27.46 -55.19','31.81 33.61 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/monsters/zombie.qc

diff --git a/qc-server/monsters/zombie.qc b/qc-server/monsters/zombie.qc
deleted file mode 100644
index 3230c93..0000000
--- a/qc-server/monsters/zombie.qc
+++ /dev/null
@@ -1,865 +0,0 @@
-/*
-==============================================================================
-
-ZOMBIES!.qc - Version 1.1
-by Ace_Dave
-http://www.trenton.edu/~weiden/quake
-Weiden@Trenton.EDU
-
-==============================================================================
-*/
-$cd /raid/quake/id1/models/zombie
-
-$origin 0 0 24
-
-$base base
-$skin skin
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8
-$frame stand9 stand10 stand11 stand12 stand13 stand14 stand15
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 walk11
-$frame walk12 walk13 walk14 walk15 walk16 walk17 walk18 walk19
-
-$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12
-$frame run13 run14 run15 run16 run17 run18
-
-$frame atta1 atta2 atta3 atta4 atta5 atta6 atta7 atta8 atta9 atta10 atta11
-$frame atta12 atta13
-
-$frame attb1 attb2 attb3 attb4 attb5 attb6 attb7 attb8 attb9 attb10 attb11
-$frame attb12 attb13 attb14
-
-$frame attc1 attc2 attc3 attc4 attc5 attc6 attc7 attc8 attc9 attc10 attc11
-$frame attc12
-
-$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10
-$frame paina11 paina12
-
-$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10
-$frame painb11 painb12 painb13 painb14 painb15 painb16 painb17 painb18 painb19
-$frame painb20 painb21 painb22 painb23 painb24 painb25 painb26 painb27 painb28
-
-$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10
-$frame painc11 painc12 painc13 painc14 painc15 painc16 painc17 painc18
-
-$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10
-$frame paind11 paind12 paind13
-
-$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10
-$frame paine11 paine12 paine13 paine14 paine15 paine16 paine17 paine18 paine19
-$frame paine20 paine21 paine22 paine23 paine24 paine25 paine26 paine27 paine28
-$frame paine29 paine30
-
-$frame cruc_1 cruc_2 cruc_3 cruc_4 cruc_5 cruc_6
-
-float SPAWN_CRUCIFIED = 1;
-float SPAWN_DEAD_CRUCIFIED = 4;
-float SPAWN_SLEEPING = 16; //changed from 2 which was Zer default
-// float SPAWN_DEAD = 4; -- not used in progs_dump -- dumptruck_ds -- this is from Zer src for my reference
-// float SPAWN_DEAD_CRUCIFIED = 8; -- not used in progs_dump -- dumptruck_ds -- this is from Zer src for my reference
-
-//=============================================================================
-.float inpain;
-
-// motionless crucified zombie
-void() zombie_dead_cruc1 = [$cruc_1, zombie_dead_cruc1] {self.nextthink = time + 1;};
-
-// new "stand" - for sleeping zombies
-void() zombie_stand1 =[ $paine11, zombie_stand2 ]
-{
- self.solid = SOLID_NOT;
- if (self.count == 0) //dumptruck_ds -- count value > 0 to leave the zombie sleeping until triggered!
- ai_stand();
-};
-void() zombie_stand2 =[ $paine11, zombie_stand1 ]
-{
- if (self.count == 0)
- ai_stand();
-};
-
-// old "stand" - called when standing only
-void() alt_zombie_stand1 =[ $stand1, alt_zombie_stand2 ] {self.health = 60; ai_stand();};
-void() alt_zombie_stand2 =[ $stand2, zombie_stand3 ] {ai_stand();};
-void() zombie_stand3 =[ $stand3, zombie_stand4 ] {ai_stand();};
-void() zombie_stand4 =[ $stand4, zombie_stand5 ] {ai_stand();};
-void() zombie_stand5 =[ $stand5, zombie_stand6 ] {ai_stand();};
-void() zombie_stand6 =[ $stand6, zombie_stand7 ] {ai_stand();};
-void() zombie_stand7 =[ $stand7, zombie_stand8 ] {ai_stand();};
-void() zombie_stand8 =[ $stand8, zombie_stand9 ] {ai_stand();};
-void() zombie_stand9 =[ $stand9, zombie_stand10 ] {ai_stand();};
-void() zombie_stand10 =[ $stand10, zombie_stand11 ] {ai_stand();};
-void() zombie_stand11 =[ $stand11, zombie_stand12 ] {ai_stand();};
-void() zombie_stand12 =[ $stand12, zombie_stand13 ] {ai_stand();};
-void() zombie_stand13 =[ $stand13, zombie_stand14 ] {ai_stand();};
-void() zombie_stand14 =[ $stand14, zombie_stand15 ] {ai_stand();};
-void() zombie_stand15 =[ $stand15, alt_zombie_stand1 ] {ai_stand();};
-
-void() zombie_cruc1 = [ $cruc_1, zombie_cruc2 ] {
-if (random() < 0.1)
- sound_idle (self, CHAN_VOICE, "zombie/idle_w2.wav", 1, ATTN_STATIC);};
-void() zombie_cruc2 = [ $cruc_2, zombie_cruc3 ] {self.nextthink = time + 0.1 + random()*0.1;};
-void() zombie_cruc3 = [ $cruc_3, zombie_cruc4 ] {self.nextthink = time + 0.1 + random()*0.1;};
-void() zombie_cruc4 = [ $cruc_4, zombie_cruc5 ] {self.nextthink = time + 0.1 + random()*0.1;};
-void() zombie_cruc5 = [ $cruc_5, zombie_cruc6 ] {self.nextthink = time + 0.1 + random()*0.1;};
-void() zombie_cruc6 = [ $cruc_6, zombie_cruc1 ] {self.nextthink = time + 0.1 + random()*0.1;};
-
-void() zombie_walk1 =[ $walk1, zombie_walk2 ] {
- self.solid = SOLID_SLIDEBOX;
- self.health = 60; //so he doesn't fall
- ai_walk(0);};
-void() zombie_walk2 =[ $walk2, zombie_walk3 ] {ai_walk(2);};
-void() zombie_walk3 =[ $walk3, zombie_walk4 ] {ai_walk(3);};
-void() zombie_walk4 =[ $walk4, zombie_walk5 ] {ai_walk(2);};
-void() zombie_walk5 =[ $walk5, zombie_walk6 ] {ai_walk(1);};
-void() zombie_walk6 =[ $walk6, zombie_walk7 ] {ai_walk(0);};
-void() zombie_walk7 =[ $walk7, zombie_walk8 ] {ai_walk(0);};
-void() zombie_walk8 =[ $walk8, zombie_walk9 ] {ai_walk(0);};
-void() zombie_walk9 =[ $walk9, zombie_walk10 ] {ai_walk(0);};
-void() zombie_walk10 =[ $walk10, zombie_walk11 ] {ai_walk(0);};
-void() zombie_walk11 =[ $walk11, zombie_walk12 ] {ai_walk(2);};
-void() zombie_walk12 =[ $walk12, zombie_walk13 ] {ai_walk(2);};
-void() zombie_walk13 =[ $walk13, zombie_walk14 ] {ai_walk(1);};
-void() zombie_walk14 =[ $walk14, zombie_walk15 ] {ai_walk(0);};
-void() zombie_walk15 =[ $walk15, zombie_walk16 ] {ai_walk(0);};
-void() zombie_walk16 =[ $walk16, zombie_walk17 ] {ai_walk(0);};
-void() zombie_walk17 =[ $walk17, zombie_walk18 ] {ai_walk(0);};
-void() zombie_walk18 =[ $walk18, zombie_walk19 ] {ai_walk(0);};
-void() zombie_walk19 =[ $walk19, zombie_walk1 ] {
-ai_walk(0);
-if (random() < 0.2)
- sound_misc (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);};
-
-void() zombie_run1 =[ $run1, zombie_run2 ] {
- if (self.spawnflags & SPAWN_SLEEPING)
- { // sloppy hack, but it fixes the illusionary zombie bug
- body_model ("progs/zombie.mdl"); //custom_mdls dumptruck_ds
- // setmodel (self, "progs/zombie.mdl");
- setsize (self, '-16 -16 -24', '16 16 40');
- }
- ai_run(1);
- self.inpain = 0;};
-void() zombie_run2 =[ $run2, zombie_run3 ] {ai_run(1);};
-void() zombie_run3 =[ $run3, zombie_run4 ] {ai_run(0);};
-void() zombie_run4 =[ $run4, zombie_run5 ] {ai_run(1);};
-void() zombie_run5 =[ $run5, zombie_run6 ] {ai_run(2);};
-void() zombie_run6 =[ $run6, zombie_run7 ] {ai_run(3);};
-void() zombie_run7 =[ $run7, zombie_run8 ] {ai_run(4);};
-void() zombie_run8 =[ $run8, zombie_run9 ] {ai_run(4);};
-void() zombie_run9 =[ $run9, zombie_run10 ] {ai_run(2);};
-void() zombie_run10 =[ $run10, zombie_run11 ] {ai_run(0);};
-void() zombie_run11 =[ $run11, zombie_run12 ] {ai_run(0);};
-void() zombie_run12 =[ $run12, zombie_run13 ] {ai_run(0);};
-void() zombie_run13 =[ $run13, zombie_run14 ] {ai_run(2);};
-void() zombie_run14 =[ $run14, zombie_run15 ] {ai_run(4);};
-void() zombie_run15 =[ $run15, zombie_run16 ] {ai_run(6);};
-void() zombie_run16 =[ $run16, zombie_run17 ] {ai_run(7);};
-void() zombie_run17 =[ $run17, zombie_run18 ] {ai_run(3);};
-void() zombie_run18 =[ $run18, zombie_run1 ] {
-ai_run(8);
-if (random() < 0.2)
- sound_misc (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
-if (random() > 0.8)
- sound_sight (self, CHAN_VOICE, "zombie/z_idle1.wav", 1, ATTN_IDLE);
-};
-
-/*
-=============================================================================
-
-ATTACKS
-
-=============================================================================
-*/
-// void() Z_hit =
-// {
-// sound_hit (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM);
-// };
-//
-// void() Z_land =
-// {
-// sound_land (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
-// };
-
-// void() ZombieGrenadeTouch2 =
-// {
-// if (other == self.owner)
-// return; // don't explode on owner
-// if (other.takedamage)
-// {
-// // Z_hit();
-// T_Damage (other, self, self.owner, 10 );
-// sound_hit (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM);
-// remove (self);
-// return;
-// }
-// // Z_land();
-// sound_land (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
-// self.velocity = '0 0 0';
-// self.avelocity = '0 0 0';
-// self.touch = SUB_Remove;
-// };
-
-/*
-================
-ZombieFireGrenade
-================
-*/
-void(vector st) ZombieFireGrenade =
-{
- local entity missile;
- local vector org;
-
- sound_attack (self, CHAN_WEAPON, "zombie/z_shot1.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
-
-// calc org
- org = self.origin + st_x * v_forward + st_y * v_right + (st_z - 24) * v_up;
-
-// set missile speed
-
- makevectors (self.angles);
-
- missile.velocity = normalize(self.enemy.origin - org);
- missile.velocity = missile.velocity * 600;
- missile.velocity_z = 200;
-
- missile.avelocity = '3000 1000 2000';
-
- missile.touch = ZombieGrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 2.5;
- missile.think = SUB_Remove;
- // setmodel (missile, "progs/zom_gib.mdl");
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/zom_gib.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, org);
-};
-
-
-void() zombie_atta1 =[ $atta1, zombie_atta2 ] {ai_face();};
-void() zombie_atta2 =[ $atta2, zombie_atta3 ] {ai_face();};
-void() zombie_atta3 =[ $atta3, zombie_atta4 ] {ai_face();};
-void() zombie_atta4 =[ $atta4, zombie_atta5 ] {ai_face();};
-void() zombie_atta5 =[ $atta5, zombie_atta6 ] {ai_face();};
-void() zombie_atta6 =[ $atta6, zombie_atta7 ] {ai_face();};
-void() zombie_atta7 =[ $atta7, zombie_atta8 ] {ai_face();};
-void() zombie_atta8 =[ $atta8, zombie_atta9 ] {ai_face();};
-void() zombie_atta9 =[ $atta9, zombie_atta10 ] {ai_face();};
-void() zombie_atta10 =[ $atta10, zombie_atta11 ] {ai_face();};
-void() zombie_atta11 =[ $atta11, zombie_atta12 ] {ai_face();};
-void() zombie_atta12 =[ $atta12, zombie_atta13 ] {ai_face();};
-void() zombie_atta13 =[ $atta13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -22 30');};
-
-void() zombie_attb1 =[ $attb1, zombie_attb2 ] {ai_face();};
-void() zombie_attb2 =[ $attb2, zombie_attb3 ] {ai_face();};
-void() zombie_attb3 =[ $attb3, zombie_attb4 ] {ai_face();};
-void() zombie_attb4 =[ $attb4, zombie_attb5 ] {ai_face();};
-void() zombie_attb5 =[ $attb5, zombie_attb6 ] {ai_face();};
-void() zombie_attb6 =[ $attb6, zombie_attb7 ] {ai_face();};
-void() zombie_attb7 =[ $attb7, zombie_attb8 ] {ai_face();};
-void() zombie_attb8 =[ $attb8, zombie_attb9 ] {ai_face();};
-void() zombie_attb9 =[ $attb9, zombie_attb10 ] {ai_face();};
-void() zombie_attb10 =[ $attb10, zombie_attb11 ] {ai_face();};
-void() zombie_attb11 =[ $attb11, zombie_attb12 ] {ai_face();};
-void() zombie_attb12 =[ $attb12, zombie_attb13 ] {ai_face();};
-void() zombie_attb13 =[ $attb13, zombie_attb14 ] {ai_face();};
-void() zombie_attb14 =[ $attb13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -24 29');};
-
-void() zombie_attc1 =[ $attc1, zombie_attc2 ] {ai_face();};
-void() zombie_attc2 =[ $attc2, zombie_attc3 ] {ai_face();};
-void() zombie_attc3 =[ $attc3, zombie_attc4 ] {ai_face();};
-void() zombie_attc4 =[ $attc4, zombie_attc5 ] {ai_face();};
-void() zombie_attc5 =[ $attc5, zombie_attc6 ] {ai_face();};
-void() zombie_attc6 =[ $attc6, zombie_attc7 ] {ai_face();};
-void() zombie_attc7 =[ $attc7, zombie_attc8 ] {ai_face();};
-void() zombie_attc8 =[ $attc8, zombie_attc9 ] {ai_face();};
-void() zombie_attc9 =[ $attc9, zombie_attc10 ] {ai_face();};
-void() zombie_attc10 =[ $attc10, zombie_attc11 ] {ai_face();};
-void() zombie_attc11 =[ $attc11, zombie_attc12 ] {ai_face();};
-void() zombie_attc12 =[ $attc12, zombie_run1 ] {ai_face();ZombieFireGrenade('-12 -19 29');};
-
-void() zombie_missile =
-{
- local float r;
-
- r = random();
-
- if (r < 0.3)
- zombie_atta1 ();
- else if (r < 0.6)
- zombie_attb1 ();
- else
- zombie_attc1 ();
-};
-//////////////////////////
-/// turret frames START
-/////////////////////////
-void() zombie_turret_atta1 =[ $atta1, zombie_turret_atta2 ] {self.health = 60;ai_face();};
-void() zombie_turret_atta2 =[ $atta2, zombie_turret_atta3 ] {ai_face();};
-void() zombie_turret_atta3 =[ $atta3, zombie_turret_atta4 ] {ai_face();};
-void() zombie_turret_atta4 =[ $atta4, zombie_turret_atta5 ] {ai_face();};
-void() zombie_turret_atta5 =[ $atta5, zombie_turret_atta6 ] {ai_face();};
-void() zombie_turret_atta6 =[ $atta6, zombie_turret_atta7 ] {ai_face();};
-void() zombie_turret_atta7 =[ $atta7, zombie_turret_atta8 ] {ai_face();};
-void() zombie_turret_atta8 =[ $atta8, zombie_turret_atta9 ] {ai_face();};
-void() zombie_turret_atta9 =[ $atta9, zombie_turret_atta10 ] {ai_face();};
-void() zombie_turret_atta10 =[ $atta10, zombie_turret_atta11 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() zombie_turret_atta11 =[ $atta11, zombie_turret_atta12 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_atta12 =[ $atta12, zombie_turret_atta13 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_atta13 =[ $atta13, alt_zombie_seek_stand1 ] {ai_run(0);PreachFireZombie(self.attack_elevation);};
-
-void() zombie_turret_attb1 =[ $attb1, zombie_turret_attb2 ] {self.health = 60;ai_face();};
-void() zombie_turret_attb2 =[ $attb2, zombie_turret_attb3 ] {ai_face();};
-void() zombie_turret_attb3 =[ $attb3, zombie_turret_attb4 ] {ai_face();};
-void() zombie_turret_attb4 =[ $attb4, zombie_turret_attb5 ] {ai_face();};
-void() zombie_turret_attb5 =[ $attb5, zombie_turret_attb6 ] {ai_face();};
-void() zombie_turret_attb6 =[ $attb6, zombie_turret_attb7 ] {ai_face();};
-void() zombie_turret_attb7 =[ $attb7, zombie_turret_attb8 ] {ai_face();};
-void() zombie_turret_attb8 =[ $attb8, zombie_turret_attb9 ] {ai_face();};
-void() zombie_turret_attb9 =[ $attb9, zombie_turret_attb10 ] {ai_face();};
-void() zombie_turret_attb10 =[ $attb10, zombie_turret_attb11 ] {ai_face();};
-void() zombie_turret_attb11 =[ $attb11, zombie_turret_attb12 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() zombie_turret_attb12 =[ $attb12, zombie_turret_attb13 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_attb13 =[ $attb13, zombie_turret_attb14 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_attb14 =[ $attb13, alt_zombie_seek_stand1 ] {ai_run(0);PreachFireZombie(self.attack_elevation);};
-
-void() zombie_turret_attc1 =[ $attc1, zombie_turret_attc2 ] {self.health = 60;ai_face();};
-void() zombie_turret_attc2 =[ $attc2, zombie_turret_attc3 ] {ai_face();};
-void() zombie_turret_attc3 =[ $attc3, zombie_turret_attc4 ] {ai_face();};
-void() zombie_turret_attc4 =[ $attc4, zombie_turret_attc5 ] {ai_face();};
-void() zombie_turret_attc5 =[ $attc5, zombie_turret_attc6 ] {ai_face();};
-void() zombie_turret_attc6 =[ $attc6, zombie_turret_attc7 ] {ai_face();};
-void() zombie_turret_attc7 =[ $attc7, zombie_turret_attc8 ] {ai_face();};
-void() zombie_turret_attc8 =[ $attc8, zombie_turret_attc9 ] {ai_face();};
-void() zombie_turret_attc9 =[ $attc9, zombie_turret_attc10 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() zombie_turret_attc10 =[ $attc10, zombie_turret_attc11 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_attc11 =[ $attc11, zombie_turret_attc12 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_attc12 =[ $attc12, alt_zombie_seek_stand1 ] {ai_run(0);PreachFireZombie(self.attack_elevation);};
-void() alt_zombie_seek_stand1 =[ $stand1, alt_zombie_seek_stand2 ] {self.health = 60; ai_run(0);};
-void() alt_zombie_seek_stand2 =[ $stand2, zombie_seek_stand3 ] {ai_run(0);};
-void() zombie_seek_stand3 =[ $stand3, zombie_seek_stand4 ] {ai_run(0);};
-void() zombie_seek_stand4 =[ $stand4, zombie_seek_stand5 ] {ai_run(0);};
-void() zombie_seek_stand5 =[ $stand5, zombie_seek_stand6 ] {ai_run(0);};
-void() zombie_seek_stand6 =[ $stand6, zombie_seek_stand7 ] {ai_run(0);};
-void() zombie_seek_stand7 =[ $stand7, zombie_seek_stand8 ] {ai_run(0);};
-void() zombie_seek_stand8 =[ $stand8, zombie_seek_stand9 ] {ai_run(0);};
-void() zombie_seek_stand9 =[ $stand9, zombie_seek_stand10 ] {ai_run(0);};
-void() zombie_seek_stand10 =[ $stand10, zombie_seek_stand11 ] {ai_run(0);};
-void() zombie_seek_stand11 =[ $stand11, zombie_seek_stand12 ] {ai_run(0);};
-void() zombie_seek_stand12 =[ $stand12, zombie_seek_stand13 ] {ai_run(0);};
-void() zombie_seek_stand13 =[ $stand13, zombie_seek_stand14 ] {ai_run(0);};
-void() zombie_seek_stand14 =[ $stand14, zombie_seek_stand15 ] {ai_run(0);};
-void() zombie_seek_stand15 =[ $stand15, alt_zombie_seek_stand1 ] {ai_run(0);};
-
-void() zombie_turret_missile =
-{
- local float r;
-
- r = random();
-
- if (r < 0.3)
- zombie_turret_attb1 ();
- else if (r < 0.6)
- zombie_turret_atta1 ();
- else
- zombie_turret_attc1 ();
-};
-//////////////////////////
-/// turret frames END
-/////////////////////////
-
-/*
-=============================================================================
-
-PAIN
-
-=============================================================================
-*/
-
-void() zombie_paina1 =[ $paina1, zombie_paina2 ] {sound_pain (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);};
-void() zombie_paina2 =[ $paina2, zombie_paina3 ] {ai_painforward(3);};
-void() zombie_paina3 =[ $paina3, zombie_paina4 ] {ai_painforward(1);};
-void() zombie_paina4 =[ $paina4, zombie_paina5 ] {ai_pain(1);};
-void() zombie_paina5 =[ $paina5, zombie_paina6 ] {ai_pain(3);};
-void() zombie_paina6 =[ $paina6, zombie_paina7 ] {ai_pain(1);};
-void() zombie_paina7 =[ $paina7, zombie_paina8 ] {};
-void() zombie_paina8 =[ $paina8, zombie_paina9 ] {};
-void() zombie_paina9 =[ $paina9, zombie_paina10 ] {};
-void() zombie_paina10 =[ $paina10, zombie_paina11 ] {};
-void() zombie_paina11 =[ $paina11, zombie_paina12 ] {};
-void() zombie_paina12 =[ $paina12, zombie_run1 ] {};
-
-void() zombie_painb1 =[ $painb1, zombie_painb2 ] {sound_misc2 (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);};
-void() zombie_painb2 =[ $painb2, zombie_painb3 ] {ai_pain(2);};
-void() zombie_painb3 =[ $painb3, zombie_painb4 ] {ai_pain(8);};
-void() zombie_painb4 =[ $painb4, zombie_painb5 ] {ai_pain(6);};
-void() zombie_painb5 =[ $painb5, zombie_painb6 ] {ai_pain(2);};
-void() zombie_painb6 =[ $painb6, zombie_painb7 ] {};
-void() zombie_painb7 =[ $painb7, zombie_painb8 ] {};
-void() zombie_painb8 =[ $painb8, zombie_painb9 ] {};
-void() zombie_painb9 =[ $painb9, zombie_painb10 ] {sound_misc3 (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);};
-void() zombie_painb10 =[ $painb10, zombie_painb11 ] {};
-void() zombie_painb11 =[ $painb11, zombie_painb12 ] {};
-void() zombie_painb12 =[ $painb12, zombie_painb13 ] {};
-void() zombie_painb13 =[ $painb13, zombie_painb14 ] {};
-void() zombie_painb14 =[ $painb14, zombie_painb15 ] {};
-void() zombie_painb15 =[ $painb15, zombie_painb16 ] {};
-void() zombie_painb16 =[ $painb16, zombie_painb17 ] {};
-void() zombie_painb17 =[ $painb17, zombie_painb18 ] {};
-void() zombie_painb18 =[ $painb18, zombie_painb19 ] {};
-void() zombie_painb19 =[ $painb19, zombie_painb20 ] {};
-void() zombie_painb20 =[ $painb20, zombie_painb21 ] {};
-void() zombie_painb21 =[ $painb21, zombie_painb22 ] {};
-void() zombie_painb22 =[ $painb22, zombie_painb23 ] {};
-void() zombie_painb23 =[ $painb23, zombie_painb24 ] {};
-void() zombie_painb24 =[ $painb24, zombie_painb25 ] {};
-void() zombie_painb25 =[ $painb25, zombie_painb26 ] {ai_painforward(1);};
-void() zombie_painb26 =[ $painb26, zombie_painb27 ] {};
-void() zombie_painb27 =[ $painb27, zombie_painb28 ] {};
-void() zombie_painb28 =[ $painb28, zombie_run1 ] {};
-
-void() zombie_painc1 =[ $painc1, zombie_painc2 ] {sound_misc2 (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);};
-void() zombie_painc2 =[ $painc2, zombie_painc3 ] {};
-void() zombie_painc3 =[ $painc3, zombie_painc4 ] {ai_pain(3);};
-void() zombie_painc4 =[ $painc4, zombie_painc5 ] {ai_pain(1);};
-void() zombie_painc5 =[ $painc5, zombie_painc6 ] {};
-void() zombie_painc6 =[ $painc6, zombie_painc7 ] {};
-void() zombie_painc7 =[ $painc7, zombie_painc8 ] {};
-void() zombie_painc8 =[ $painc8, zombie_painc9 ] {};
-void() zombie_painc9 =[ $painc9, zombie_painc10 ] {};
-void() zombie_painc10 =[ $painc10, zombie_painc11 ] {};
-void() zombie_painc11 =[ $painc11, zombie_painc12 ] {ai_painforward(1);};
-void() zombie_painc12 =[ $painc12, zombie_painc13 ] {ai_painforward(1);};
-void() zombie_painc13 =[ $painc13, zombie_painc14 ] {};
-void() zombie_painc14 =[ $painc14, zombie_painc15 ] {};
-void() zombie_painc15 =[ $painc15, zombie_painc16 ] {};
-void() zombie_painc16 =[ $painc16, zombie_painc17 ] {};
-void() zombie_painc17 =[ $painc17, zombie_painc18 ] {};
-void() zombie_painc18 =[ $painc18, zombie_run1 ] {};
-
-void() zombie_paind1 =[ $paind1, zombie_paind2 ] {sound_pain (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);};
-void() zombie_paind2 =[ $paind2, zombie_paind3 ] {};
-void() zombie_paind3 =[ $paind3, zombie_paind4 ] {};
-void() zombie_paind4 =[ $paind4, zombie_paind5 ] {};
-void() zombie_paind5 =[ $paind5, zombie_paind6 ] {};
-void() zombie_paind6 =[ $paind6, zombie_paind7 ] {};
-void() zombie_paind7 =[ $paind7, zombie_paind8 ] {};
-void() zombie_paind8 =[ $paind8, zombie_paind9 ] {};
-void() zombie_paind9 =[ $paind9, zombie_paind10 ] {ai_pain(1);};
-void() zombie_paind10 =[ $paind10, zombie_paind11 ] {};
-void() zombie_paind11 =[ $paind11, zombie_paind12 ] {};
-void() zombie_paind12 =[ $paind12, zombie_paind13 ] {};
-void() zombie_paind13 =[ $paind13, zombie_run1 ] {};
-
-void() zombie_paine1 =[ $paine1, zombie_paine2 ] {
-if (self.axhitme == 2) // Chainsaw will gib zombie
-{
- T_Damage(self, world, world, 80);
- return;
-}
-sound_pain (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);
-self.health = 60;
-};
-void() zombie_paine2 =[ $paine2, zombie_paine3 ] {ai_pain(8);};
-void() zombie_paine3 =[ $paine3, zombie_paine4 ] {ai_pain(5);};
-void() zombie_paine4 =[ $paine4, zombie_paine5 ] {ai_pain(3);};
-void() zombie_paine5 =[ $paine5, zombie_paine6 ] {ai_pain(1);};
-void() zombie_paine6 =[ $paine6, zombie_paine7 ] {ai_pain(2);};
-void() zombie_paine7 =[ $paine7, zombie_paine8 ] {ai_pain(1);};
-void() zombie_paine8 =[ $paine8, zombie_paine9 ] {ai_pain(1);};
-void() zombie_paine9 =[ $paine9, zombie_paine10 ] {ai_pain(2);};
-void() zombie_paine10 =[ $paine10, zombie_paine11 ] {
-sound_misc3 (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);
-self.solid = SOLID_NOT;
-};
-void() zombie_paine11 =[ $paine11, zombie_paine12 ] {self.nextthink = self.nextthink + 5;self.health = 60;};
-void() zombie_paine12 =[ $paine12, zombie_paine13 ]{
-// see if ok to stand up
-self.health = 60;
-sound_misc (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
-self.solid = SOLID_SLIDEBOX;
-if (!walkmove (0, 0))
-{
- self.think = zombie_paine11;
- self.solid = SOLID_NOT;
- return;
-}
-};
-void() zombie_paine13 =[ $paine13, zombie_paine14 ] {};
-void() zombie_paine14 =[ $paine14, zombie_paine15 ] {};
-void() zombie_paine15 =[ $paine15, zombie_paine16 ] {};
-void() zombie_paine16 =[ $paine16, zombie_paine17 ] {};
-void() zombie_paine17 =[ $paine17, zombie_paine18 ] {};
-void() zombie_paine18 =[ $paine18, zombie_paine19 ] {};
-void() zombie_paine19 =[ $paine19, zombie_paine20 ] {};
-void() zombie_paine20 =[ $paine20, zombie_paine21 ] {};
-void() zombie_paine21 =[ $paine21, zombie_paine22 ] {};
-void() zombie_paine22 =[ $paine22, zombie_paine23 ] {};
-void() zombie_paine23 =[ $paine23, zombie_paine24 ] {};
-void() zombie_paine24 =[ $paine24, zombie_paine25 ] {};
-void() zombie_paine25 =[ $paine25, zombie_paine26 ] {ai_painforward(5);};
-void() zombie_paine26 =[ $paine26, zombie_paine27 ] {ai_painforward(3);};
-void() zombie_paine27 =[ $paine27, zombie_paine28 ] {ai_painforward(1);};
-void() zombie_paine28 =[ $paine28, zombie_paine29 ] {ai_pain(1);};
-void() zombie_paine29 =[ $paine29, zombie_paine30 ] {};
-void() zombie_paine30 =[ $paine30, zombie_run1 ] {};
-
-void() zombie_die =
-{
- sound_death (self, CHAN_VOICE, "zombie/z_gib.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_zombie.mdl", self.health/*, self.dest*/); //commented out dest -- dumptruck_ds
- }
- // ThrowGib ("progs/gib1.mdl", self.health/*, self.dest*/);
- // ThrowGib ("progs/gib2.mdl", self.health/*, self.dest*/);
- // ThrowGib ("progs/gib3.mdl", self.health/*, self.dest*/);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- DropStuff();
-};
-
-/*
-=================
-zombie_pain
-
-Zombies can only be killed (gibbed) by doing 60 hit points of damage
-in a single frame (rockets, grenades, quad shotgun, quad nailgun).
-
-A hit of 25 points or more (super shotgun, quad nailgun) will always put it
-down to the ground.
-
-A hit of from 10 to 40 points in one frame will cause it to go down if it
-has been twice in two seconds, otherwise it goes into one of the four
-fast pain frames.
-
-A hit of less than 10 points of damage (winged by a shotgun) will be ignored.
-
-FIXME: don't use pain_finished because of nightmare hack
-=================
-*/
-void(entity attacker, float take) zombie_pain =
-{
- if (self.spawnflags & I_AM_TURRET)
- {
- self.health = 60; // always reset health
-
- if (take >= 60)
- {
- zombie_die();
- }
- else
- return;
- }
-
- local float r;
-
- self.health = 60; // always reset health
-
- if (take < 9)
- return; // totally ignore
-
- if (self.inpain == 2)
- return; // down on ground, so don't reset any counters
-
-// go down immediately if a big enough hit
- if ((take >= 25) || (self.axhitme == 2))
- {
- self.inpain = 2;
- zombie_paine1 ();
- return;
- }
-
- if (self.inpain)
- {
-// if hit again in next gre seconds while not in pain frames, definately drop
- self.pain_finished = time + 3;
- return; // currently going through an animation, don't change
- }
-
- if (self.pain_finished > time)
- {
-// hit again, so drop down
- self.inpain = 2;
- zombie_paine1 ();
- return;
- }
-
-// gp into one of the fast pain animations
- self.inpain = 1;
-
- r = random();
- if (r < 0.25)
- zombie_paina1 ();
- else if (r < 0.5)
- zombie_painb1 ();
- else if (r < 0.75)
- zombie_painc1 ();
- else
- zombie_paind1 ();
-};
-
-void() zombie_decide = // stand up if orig. lying down, else just start running
-{
- if (self.health==61)
- zombie_paine12();
- else
- zombie_run1();
-
- self.th_run = zombie_run1;
-};
-
-void() zombie_use = // wake up a sleeping zombie!
-
-{
- self.count = 0;
- //attacker = other;
- monster_use();
-};
-
-void() zombie_start = // determine if zombie is to be lying down, or standing
-{
- self.count = 1; //dumptruck_ds -- Don't start zombie_stand1 yet!
- self.use = zombie_use; //dumptruck_ds -- makes self.count = 0 so zombie_stand1 is called
-
- if (self.spawnflags & SPAWN_SLEEPING)
- {
- if (!SUB_IsTargeted ())
- {
- dprint ("WARNING: removed untargeted sleeping zombie at ");
- dprint (vtos (self.origin));
- dprint ("\n");
-
- monster_update_total (-1);
- remove (self);
- return;
- }
- self.inpain = 2;
- zombie_stand1 ();
- }
- else
- {
- alt_zombie_stand1 ();
- }
-
- self.th_stand = alt_zombie_stand1;
-};
-
-// void() zombie_start2 = //unused in progs_dump -- dumptruck_ds
-// {
-// local vector org;
-// local entity teldeath;
-//
-// if (self.style)
-// {
-// makevectors (self.angles);
-// org = self.origin + 16 * v_forward;
-// spawn_tfog (org);
-// teldeath = spawn();
-// teldeath.origin = org;
-// teldeath.owner = self;
-// // teldeath.think = sf64_teledeath; -- not used in progs_dump -- dumptruck_ds
-// teldeath.nextthink = time + 0.1;
-// }
-//
-// self.solid = SOLID_SLIDEBOX;
-// self.movetype = MOVETYPE_STEP;
-//
-// setmodel (self, "progs/zombie.mdl");
-//
-// setsize (self, '-16 -16 -24', '16 16 40');
-// self.health = 61;
-//
-// walkmonster_start();
-// };
-
-//============================================================================
-
-/*QUAKED monster_zombie (1 0 0) (-16 -16 -24) (16 16 32) CRUCIFIED AMBUSH CRUCIFIED_MOTIONLESS TRIGGER_SPAWNED SPAWN_SLEEPING X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ( {{ spawnflags & 1 -> { "path" : "progs/zombie.mdl", "frame" : 192 }, "progs/zombie.mdl" }} );
-}
-If crucified, stick the bounding box 12 pixels back into a wall to look right.
-
-Default health = 60
-
-If SPAWN_SLEEPING is used there must be a targetname set. The zombie will stand up when targeted. Crucified motionless zombies are silent and do not animate." //dumptruck_ds
-
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_attack(string) : "Path to custom attack sound (WHOOSH)"
-snd_idle(string) : "Path to custom idle sound (CRUCIFIED ONLY)"
-snd_misc(string) : "Path to custom (IDLE 2) sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_misc2(string) : "Path to custom (PAIN 2) sound"
-snd_misc3(string) : "Path to custom (FALLING) sound"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-mdl_proj(string) : "Path to custom projectile model"
-skin_head(float) : "Skin index of custom head model"
-skin_proj(float) : "Skin index of custom projectile model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-spawnflags(Flags) =
-1 : "Crucified"
-2 : "Ambush"
-4 : "Crucified motionless"
-16 : "Spawn Sleeping"
-*/
-void() monster_zombie =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch /*&& (!(self.spawnflags & SPAWN_DEAD_CRUCIFIED))*/)
- {
- remove(self);
- return;
- }
-
- precache_body_model ("progs/zombie.mdl"); //custom_mdls dumptruck_ds
- precache_head_model ("progs/h_zombie.mdl");
- precache_proj_model ("progs/zom_gib.mdl");
- // precache_model ("progs/zombie.mdl");
- // precache_model ("progs/h_zombie.mdl");
- // precache_model ("progs/zom_gib.mdl");
-
- precache_sound_misc ("zombie/z_idle.wav");
- precache_sound_sight ("zombie/z_idle1.wav");
- precache_sound_attack ("zombie/z_shot1.wav");
- precache_sound_death ("zombie/z_gib.wav");
- precache_sound_pain ("zombie/z_pain.wav");
- precache_sound_misc2 ("zombie/z_pain1.wav");
- precache_sound_misc3 ("zombie/z_fall.wav");
- precache_sound ("zombie/z_miss.wav");
- precache_sound ("zombie/z_hit.wav");
-
- precache_sound_idle ("zombie/idle_w2.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.th_stand = zombie_start;
- self.th_walk = zombie_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = alt_zombie_seek_stand1;
- }
- else
- {
- self.th_run = zombie_decide;
- }
-
- self.th_pain = zombie_pain;
- self.th_die = zombie_die;
- self.th_turret = zombie_turret_missile;
- self.th_missile = zombie_missile;
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/zombie.mdl"); //custom_mdls dumptruck_ds
- // setmodel (self, "progs/zombie.mdl");
-
- setsize (self, '-16 -16 -24', '16 16 40');
- self.health = 61;
-
- if (self.spawnflags & SPAWN_CRUCIFIED)
- {
- self.movetype = MOVETYPE_NONE;
- zombie_cruc1 ();
- }
- else if (self.spawnflags & SPAWN_DEAD_CRUCIFIED)
- {
- self.movetype = MOVETYPE_NONE;
- zombie_dead_cruc1 ();
- }
- else
- walkmonster_start();
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/newflags.qc

diff --git a/qc-server/newflags.qc b/qc-server/newflags.qc
deleted file mode 100644
index 07d8ff5..0000000
--- a/qc-server/newflags.qc
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
-========================================================================
-
-NEW SPAWNFLAGS FOR ALL ENTITIES
-
-========================================================================
-
-
-This file was created for progs_dump by Ian "iw" Walshaw, August 2019.
-
-It defines functions which can be called to implement the following new
-spawnflags:
-
- 4096 Not in Coop
- 8192 Not in Single Player
- 32768 Not on Hard Only
- 65536 Not on Nightmare Only
-
-(Spawnflag 16384 is not used here because it's already used for
-something else in progs_dump.)
-
-The new spawnflags complement and complete the set of built-in
-spawnflags provided by the engine, which of course are:
-
- 256 Not on Easy
- 512 Not on Normal
- 1024 Not on Hard or Nightmare
- 2048 Not in Deathmatch
-
-In conjunction with the old spawnflags, the new spawnflags make it
-possible to exclude any entity from any combination of game modes and/or
-skill levels.
-
-
-"Not in Coop" and "Not in Single Player"
-----------------------------------------
-
-These spawnflags were inspired by Quoth 2 (Kell and Necros, 2008), which
-included two additional spawnflags for all entities: "Not in Coop" and
-"Coop Only". In contrast to Quoth 2, the spawnflags implemented here
-are "Not in Coop" and "Not in Single Player", for symmetry with the
-built-in "Not in Deathmatch" spawnflag.
-
-
-"Not on Hard Only" and "Not on Nightmare Only"
-----------------------------------------------
-
-The set of built-in spawnflags doesn't allow a mapper to treat the Hard
-and Nightmare skill levels differently, because it only includes one
-spawnflag, 1024, which excludes an entity from both Hard and Nightmare.
-The new "Not on Hard Only" and "Not on Nightmare Only" spawnflags allow
-the mapper to exclude an entity from one of these skill levels without
-affecting the other.
-
-
-========================================================================
-*/
-
-
-// The new spawnflags. (16384 is already used elsewhere.)
-float SPAWNFLAG_NOT_IN_COOP = 4096; // Not in Coop
-float SPAWNFLAG_NOT_IN_SP = 8192; // Not in Single Player
-float SPAWNFLAG_NOT_ON_SKILL2 = 32768; // Not on Hard Only
-float SPAWNFLAG_NOT_ON_SKILL3 = 65536; // Not on Nightmare Only
-
-// The number of entities inhibited by each of the new spawnflags.
-float total_not_in_coop;
-float total_not_in_sp;
-float total_not_on_skill2;
-float total_not_on_skill3;
-
-// TRUE if the developer summary has been printed.
-float done_inhibition_summary;
-
-
-/*
-================
-InitNewSpawnflags
-
-This function is intended to be called from the top of the worldspawn
-function (in world.qc). -- iw
-================
-*/
-void() InitNewSpawnflags =
-{
- // Initialize the global variables.
- total_not_in_coop = 0;
- total_not_in_sp = 0;
- total_not_on_skill2 = 0;
- total_not_on_skill3 = 0;
- done_inhibition_summary = FALSE;
-
- // In the original code, the value of the skill cvar was not copied
- // into the skill global until the first call to StartFrame.
- // However, the new SUB_Inhibit function will need to check what the
- // skill is before then, so, the value is copied here. -- iw
- skill = cvar ("skill");
-};
-
-
-/*
-================
-SUB_Inhibit
-
-This function is intended to be called from the top of every spawn
-function, like this:
-
- if (SUB_Inhibit ())
- return;
-
-If the entity's spawnflags mean that it should be inhibited in the
-current game mode or on the current skill level, this function will
-remove the entity and return TRUE, otherwise this function will take no
-action and return FALSE. -- iw
-================
-*/
-float() SUB_Inhibit =
-{
- if (coop && (self.spawnflags & SPAWNFLAG_NOT_IN_COOP))
- {
- total_not_in_coop = total_not_in_coop + 1;
- remove (self);
- return TRUE;
- }
-
- if (!coop && !deathmatch && (self.spawnflags & SPAWNFLAG_NOT_IN_SP))
- {
- total_not_in_sp = total_not_in_sp + 1;
- remove (self);
- return TRUE;
- }
-
- // The built-in skill level spawnflags are ignored in Deathmatch, so
- // we ignore the new ones in Deathmatch, too. -- iw
- if (!deathmatch)
- {
- if (skill == 2 && (self.spawnflags & SPAWNFLAG_NOT_ON_SKILL2))
- {
- total_not_on_skill2 = total_not_on_skill2 + 1;
- remove (self);
- return TRUE;
- }
-
- if (skill == 3 && (self.spawnflags & SPAWNFLAG_NOT_ON_SKILL3))
- {
- total_not_on_skill3 = total_not_on_skill3 + 1;
- remove (self);
- return TRUE;
- }
- }
-
- return FALSE;
-};
-
-
-/*
-================
-PrintInhibitionTotal
-
-This just dprints the summary line about the total number of entities
-inhibited by one of the new spawnflags (see PrintInhibitionSummary
-below). -- iw
-================
-*/
-void(float total, string spawnflag_name) PrintInhibitionTotal =
-{
- if (total == 0)
- return;
-
- dprint ("... ");
- dprint (ftos (total));
- dprint (" with '");
- dprint (spawnflag_name);
- dprint ("' spawnflag\n");
-};
-
-
-/*
-================
-PrintInhibitionSummary
-
-This function is intended to be called from the top of the StartFrame
-function (in world.qc), like this:
-
- if (!done_inhibition_summary)
- PrintInhibitionSummary ();
-
-The engine already logs a developer message about the number of entities
-inhibited by the built-in spawnflags; this function logs a message about
-the number of entities inhibited by the new spawnflags. -- iw
-================
-*/
-void() PrintInhibitionSummary =
-{
- dprint (ftos (total_not_in_coop + total_not_in_sp +
- total_not_on_skill2 + total_not_on_skill3));
- dprint (" additional entities inhibited by the progs.dat\n");
-
- PrintInhibitionTotal (total_not_in_coop, "Not in Coop");
- PrintInhibitionTotal (total_not_in_sp, "Not in Single Player");
- PrintInhibitionTotal (total_not_on_skill2, "Not on Hard Only");
- PrintInhibitionTotal (total_not_on_skill3, "Not on Nightmare Only");
-
- done_inhibition_summary = TRUE;
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/plats.qc

diff --git a/qc-server/plats.qc b/qc-server/plats.qc
deleted file mode 100644
index f6c5166..0000000
--- a/qc-server/plats.qc
+++ /dev/null
@@ -1,786 +0,0 @@
-
-
-void() plat_center_touch;
-void() plat_outside_touch;
-void() plat_trigger_use;
-void() plat_go_up;
-void() plat_go_down;
-void() plat_crush;
-float PLAT_LOW_TRIGGER = 1;
-
-void() plat_spawn_inside_trigger =
-{
- local entity trigger;
- local vector tmin, tmax;
-
-//
-// middle trigger
-//
- trigger = spawn();
- trigger.touch = plat_center_touch;
- trigger.movetype = MOVETYPE_NONE;
- trigger.solid = SOLID_TRIGGER;
- trigger.enemy = self;
-
- tmin = self.mins + '25 25 0';
- tmax = self.maxs - '25 25 -8';
- tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8);
- if (self.spawnflags & PLAT_LOW_TRIGGER)
- tmax_z = tmin_z + 8;
-
- if (self.size_x <= 50)
- {
- tmin_x = (self.mins_x + self.maxs_x) / 2;
- tmax_x = tmin_x + 1;
- }
- if (self.size_y <= 50)
- {
- tmin_y = (self.mins_y + self.maxs_y) / 2;
- tmax_y = tmin_y + 1;
- }
-
- setsize (trigger, tmin, tmax);
-};
-
-void() plat_hit_top =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_TOP;
- self.think = plat_go_down;
- self.nextthink = self.ltime + 3;
-};
-
-void() plat_hit_bottom =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_BOTTOM;
-};
-
-void() plat_go_down =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos2, self.speed, plat_hit_bottom);
-};
-
-void() plat_go_up =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_UP;
- SUB_CalcMove (self.pos1, self.speed, plat_hit_top);
-};
-
-void() plat_center_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- self = self.enemy;
- if (self.state == STATE_BOTTOM)
- plat_go_up ();
- else if (self.state == STATE_TOP)
- self.nextthink = self.ltime + 1; // delay going down
-};
-
-void() plat_outside_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
-//dprint ("plat_outside_touch\n");
- self = self.enemy;
- if (self.state == STATE_TOP)
- plat_go_down ();
-};
-
-void() plat_trigger_use =
-{
- if (self.think)
- return; // allready activated
- plat_go_down();
-};
-
-
-void() plat_crush =
-{
-//dprint ("plat_crush\n");
-
- T_Damage (other, self, self, 1);
-
- if (self.state == STATE_UP)
- plat_go_down ();
- else if (self.state == STATE_DOWN)
- plat_go_up ();
- else
- objerror ("plat_crush: bad self.state\n");
-};
-
-void() plat_use =
-{
- self.use = SUB_Null;
- if (self.state != STATE_UP)
- objerror ("plat_use: not in up state");
- plat_go_down();
-};
-
-
-/*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-speed default 150
-
-Plats are always drawn in the extended position, so they will light correctly.
-
-If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat.
-
-If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determined by the model's height.
-Set "sounds" to one of the following:
-1) base fast
-2) chain slow
-*/
-
-
-void() func_plat =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.t_length)
- self.t_length = 80;
- if (!self.t_width)
- self.t_width = 10;
-
- if (self.sounds == 0)
- self.sounds = 2;
-// FIX THIS TO LOAD A GENERIC PLAT SOUND
-
- if (self.sounds == 1)
- {
- precache_sound ("plats/plat1.wav");
- precache_sound ("plats/plat2.wav");
- self.noise = "plats/plat1.wav";
- self.noise1 = "plats/plat2.wav";
- }
-
- if (self.sounds == 2)
- {
- precache_sound ("plats/medplat1.wav");
- precache_sound ("plats/medplat2.wav");
- self.noise = "plats/medplat1.wav";
- self.noise1 = "plats/medplat2.wav";
- }
-
-
- self.mangle = self.angles;
- self.angles = '0 0 0';
-
- self.classname = "plat";
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- setorigin (self, self.origin);
- setmodel (self, self.model);
- setsize (self, self.mins , self.maxs);
-
- self.blocked = plat_crush;
- if (!self.speed)
- self.speed = 150;
-
-// pos1 is the top position, pos2 is the bottom
- self.pos1 = self.origin;
- self.pos2 = self.origin;
- if (self.height)
- self.pos2_z = self.origin_z - self.height;
- else
- self.pos2_z = self.origin_z - self.size_z + 8;
-
- self.use = plat_trigger_use;
-
- plat_spawn_inside_trigger (); // the "start moving" trigger
-
- if (self.targetname != "")
- {
- self.state = STATE_UP;
- self.use = plat_use;
- }
- else
- {
- setorigin (self, self.pos2);
- self.state = STATE_BOTTOM;
- }
-};
-
-//============================================================================
-// TRAINS
-//============================================================================
-void() train_next;
-void() func_train_find;
-
-float TRAIN_RETRIGGER = 1;
-float TRAIN_MOVEONTRIGGER = 2;
-float TRAIN_STOPONTRIGGER = 4;
-float TRAIN_NONSOLID = 8;
-float TRAIN_NOROTATE = 16;
-float TRAIN_ROTATEY = 32;
-float TRAIN_CUSTOMALIGN = 64;
-
-float TRAIN_NEXT_WAIT = 0; //normal movement
-float TRAIN_NEXT_STOP = 1; // force a stop on the next path_corner
-float TRAIN_NEXT_CONTINUE = 2; // force continue on the next path_corner (ignores wait time)
-
-float TRAIN_STYLE_SINGLEANIM = 1;
-
-float TRAIN_ANIMTYPE_FORWARD = 1;
-float TRAIN_ANIMTYPE_BACKFORTH = 2;
-
-void() train_blocked = {
- if (time < self.attack_finished) return;
-
- self.attack_finished = time + 0.5;
- T_Damage (other, self, self, self.dmg);
-};
-
-
-// Use function for when the train is stopped.
-// Makes the train continue on path_corners with wait -1,
-// or forces a continue if the "move on trigger" spawnflag is set.
-void() train_use = {
-
- if (self.spawnflags & TRAIN_MOVEONTRIGGER || self.wait < 0) {
- train_next();
- return;
- }
-
- // Train has already moved after startup, and has no "stop on trigger" flag,
- // so ignore activation.
- if (self.think != func_train_find && self.cnt != TRAIN_NEXT_STOP)
- return;
-
- train_next();
-};
-
-// Use function for when the train is moving.
-// Forces a stop or an instant continue on the next path_corner depending on the spawnflag set
-void() train_moving_use = {
- if (self.spawnflags & TRAIN_MOVEONTRIGGER || self.wait < 0)
- self.cnt = TRAIN_NEXT_CONTINUE;
- else if (self.spawnflags & TRAIN_STOPONTRIGGER)
- self.cnt = TRAIN_NEXT_STOP;
-}
-
-// path_corner has been reached, so decide what to do next
-void() train_wait = {
- float localtime;
- if (self.movetype == MOVETYPE_PUSH) localtime = self.ltime;
- else localtime = time;
-
- self.use = train_use; //ready to be re-triggered
-
- // from Copper
- // Trains now fire their path_corners' targets on arrival.
- // If a player is riding the train, treat them as activator.
- activator = nextent(world);
- while (!EntitiesTouching(self,activator) && activator.classname == "player")
- activator = nextent(activator);
- if (activator.classname != "player")
- activator = nextent(world); // default to player1 wherever they are
- SUB_UseEntTargets(self.enemy);
-
- if (self.enemy.speed) self.speed2 = self.enemy.speed; // sets the speed from the current path_corner
-
- // copies the modeltrain animation parameters set in the path_corner, if any
- if (self.classname == "misc_modeltrain") {
- if (self.enemy.first_frame) self.first_frame = self.enemy.first_frame;
- if (self.enemy.last_frame) self.last_frame = self.enemy.last_frame;
- if (self.enemy.first_frame2) self.first_frame2 = self.enemy.first_frame2;
- if (self.enemy.last_frame2) self.last_frame2 = self.enemy.last_frame2;
- if (self.enemy.frtime) self.frtime = self.enemy.frtime;
- if (self.enemy.frtime2) self.frtime2 = self.enemy.frtime2;
- if (self.enemy.animtype) self.animtype = self.enemy.animtype;
- if (self.enemy.animtype2) self.animtype2 = self.enemy.animtype2;
- if (self.enemy.multiplier) self.multiplier = self.enemy.multiplier;
- }
-
- self.think = train_next;
-
- // train is moving normally and path_corner has a wait set, so pause for that time.
- if (self.wait > 0 && self.cnt == TRAIN_NEXT_WAIT && !(self.spawnflags & TRAIN_RETRIGGER)) {
- // state: stopped
- self.state = 0;
- if (self.classname == "misc_modeltrain") SUB_CallAsSelf(self.animcontroller.think, self.animcontroller);
- self.nextthink = localtime + self.wait;
-
- //play stopping sound. If path_corner has a custom sound, play that instead
- if (self.enemy.noise != "") sound(self, CHAN_WEAPON, self.enemy.noise, 1, ATTN_NORM);
- else sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- }
- // train is moving normally and path_corner has no wait time,
- // or has been forced to move instantly through a triggering.
- else if (self.cnt != TRAIN_NEXT_STOP && !self.wait && !(self.spawnflags & TRAIN_RETRIGGER)) {
-
- //play "passing by" sound, if any. If path_corner has a custom one, play that instead
- if (self.enemy.noise2 != "") sound(self, CHAN_WEAPON, self.enemy.noise2, 1, ATTN_NORM);
- else if (self.noise2 != "") sound(self, CHAN_WEAPON, self.noise2, 1, ATTN_NORM);
-
- self.nextthink = -1; // move instantly
- train_next();
- }
- // path_corner has wait -1, or train has been forced to stop through a triggering.
- // Also catches the backwards compatible case for the original rubicon2 "retrigger" flag.
- else {
- //play stopping sound. If path_corner has a custom sound, play that instead
- if (self.enemy.noise != "") sound(self, CHAN_WEAPON, self.enemy.noise, 1, ATTN_NORM);
- else sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
-
- // state: stopped
- self.state = 0;
-
- if (self.classname == "misc_modeltrain") SUB_CallAsSelf(self.animcontroller.think, self.animcontroller);
- self.nextthink = -1;
- }
-
-
-};
-
-// searches for the next path_corner and sends the train on its way
-void() train_next = {
- local entity targ;
- vector destang, displ;
-
- targ = find(world, targetname, self.target);
-
- if (!targ || self.target == "")
- objerror("train_next: no next target");
-
- self.target = targ.target;
-
- // gets the wait time from the upcoming path_corner if set
- if (targ.wait){
- // wait -2 on the path_corner forces it to continue moving (no wait),
- // even if the train has a default wait time
- if (targ.wait == -2) self.wait = 0;
- else self.wait = targ.wait;
- }
- // uses train's current wait time otherwise
- else
- self.wait = self.pausetime;
-
- self.enemy = targ;
-
- sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
-
- if(!(!self.wait && self.cnt == TRAIN_NEXT_CONTINUE)) self.cnt = TRAIN_NEXT_WAIT;
-
- //store up any premature triggerings until current movement is finished
- self.use = train_moving_use;
-
- if (self.classname == "misc_modeltrain") {
- if (!(self.spawnflags & TRAIN_NOROTATE)) {
- destang = vectoangles(targ.origin - self.origin);
- if (self.spawnflags & TRAIN_ROTATEY) {
- destang_x = self.angles_x;
- destang_z = self.angles_z;
- }
- if (self.multiplier > 0) SUB_CalcAngleMoveController(destang, self.speed2*self.multiplier, SUB_Null, self.rotatecontroller);
- else self.angles = destang;
- }
- }
-
- if (!self.state) {
- self.state = 1;
- if (self.classname == "misc_modeltrain" && self.style != TRAIN_STYLE_SINGLEANIM)
- SUB_CallAsSelf(self.animcontroller.think, self.animcontroller);
- }
- // if the TRAIN_CUSTOMALIGN flag is checked then the train should align
- // with its path_corners based on the location of an "origin" brush added
- // to the train by the mapper instead of the mins corner
- // -therektafire
- float doDisplace;
- if (self.spawnflags & TRAIN_CUSTOMALIGN) doDisplace = 0.0;
- else doDisplace = 1.0;
-
- if (self.classname != "misc_modeltrain") displ = self.mins;
-
- SUB_CalcMove(targ.origin - (displ * doDisplace), self.speed2, train_wait);
-};
-
-// searches for the first path_corner after the train entity is initialized
-void() func_train_find = {
- local entity targ;
- float localtime;
- vector displ;
-
- if (self.movetype == MOVETYPE_PUSH) localtime = self.ltime;
- else localtime = time;
-
- targ = find(world, targetname, self.target);
- self.target = targ.target;
-
- float doDisplace;
- if (self.spawnflags & TRAIN_CUSTOMALIGN) doDisplace = 0.0;
- else doDisplace = 1.0;
-
- if (self.classname != "misc_modeltrain") displ = self.mins;
- self.enemy = targ;
- setorigin(self, targ.origin - (displ * doDisplace));
- if (targ.speed) self.speed2 = targ.speed; // uses speed from the 1st path corner if set
-
- if (!self.targetname)
- { // not triggered, so start immediately
- self.nextthink = localtime + 0.1;
- self.think = train_next;
- }
-};
-
-/*QUAKED func_train (0 .5 .8) ? RETRIGGER
-Trains are moving platforms that players can ride.
-The targets origin specifies the min point of the train at each corner.
-The train spawns at the first target it is pointing at.
-If the train is the target of a button or trigger, it will not begin moving until activated.
-
-RETRIGGER: stop at each path_corner and don't resume until triggered again (ignores wait time)
-
-speed default 100
-dmg default 2
-sounds
-1) ratchet metal
-2) base
-
-*/
-void() func_train =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.speed)
- self.speed = 100;
- if (!self.target)
- objerror ("func_train without a target");
- if (!self.dmg)
- self.dmg = 2;
-
- if(self.spawnflags & TRAIN_STOPONTRIGGER && self.spawnflags & TRAIN_MOVEONTRIGGER)
- objerror("func_train: Stop and move on trigger set at the same time");
-
-
-
- if (self.sounds == 1) {
- if (self.noise == "") self.noise = ("plats/train2.wav");
- if (self.noise1 == "") self.noise1 = ("plats/train1.wav");
- }
- else if (self.sounds == 2) { // base door sound
- if (self.noise == "") self.noise = "doors/hydro2.wav";
- if (self.noise1 == "") self.noise1 = "doors/hydro1.wav";
- }
- else {
- if (self.noise == "") self.noise = ("misc/null.wav");
- if (self.noise1 == "") self.noise1 = ("misc/null.wav");
- }
-
- // backwards compatibility with previous version
- if (self.noise3 != "") self.noise = self.noise3;
- if (self.noise4 != "") self.noise1 = self.noise4;
-
- precache_sound(self.noise);
- precache_sound(self.noise1);
- if (self.noise2 != "") precache_sound(self.noise2);
-
-
- self.cnt = TRAIN_NEXT_WAIT;
-
- if (self.spawnflags & TRAIN_NONSOLID) {
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_NOCLIP;
- }
- else {
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- }
-
- self.blocked = train_blocked;
- self.use = train_use;
- //self.classname = "train";
-
- setmodel (self, self.model);
- setsize (self, self.mins , self.maxs);
- setorigin (self, self.origin);
-
- // start trains on the second frame, to make sure their targets have had
- // a chance to spawn
-
- if (self.movetype == MOVETYPE_PUSH) self.nextthink = self.ltime + 0.1;
- else self.nextthink = time + 0.1;
-
- self.think = func_train_find;
-
- self.speed2 = self.speed;
-};
-
-
-//===================================================
-
-
-void() animcontroller_think = {
- entity tr;
- tr = self.owner;
-
- float first, last, step, atype, dir, nextframe;
-
- // train just went from stopped to moving or vice-versa,
- // and have both animations set
- if (self.state != tr.state && tr.style != TRAIN_STYLE_SINGLEANIM) {
- if (tr.state) { // just started moving
- tr.frame = zeroconvert(tr.first_frame2);
- }
- else { // just stopped
- tr.frame = zeroconvert(tr.first_frame);
- }
- tr.distance = 1; // reset back/forth status
- self.state = tr.state;
- }
-
- else {
- if (self.state && tr.style != TRAIN_STYLE_SINGLEANIM) { // moving train animation, if set
- first = zeroconvert(tr.first_frame2);
- last = zeroconvert(tr.last_frame2);
- atype = tr.animtype2;
- }
- else { // stopped/default train animation
- first = zeroconvert(tr.first_frame);
- last = zeroconvert(tr.last_frame);
- atype = tr.animtype;
- }
-
- if (first > last) step = dir = -1; // reverse direction
- else step = dir = 1;
-
- // back-and-forth is going the other way, so invert the step's signal
- if (tr.distance < 0) step = step * (-1);
-
- nextframe = tr.frame + step;
-
- if (atype == TRAIN_ANIMTYPE_BACKFORTH){
- if (dir > 0 && (nextframe > last || nextframe < first) ||
- dir < 0 && (nextframe > first || nextframe < last)
- ) {
- nextframe = tr.frame - step;
- tr.distance = tr.distance * (-1);
- }
- }
-
- if (dir > 0) nextframe = wrap(nextframe, first, last);
- else nextframe = wrap(nextframe, last, first);
-
- tr.frame = nextframe;
-
- }
-
- self.think = animcontroller_think;
- if (self.state || tr.style == TRAIN_STYLE_SINGLEANIM) self.nextthink = time + tr.frtime;
- else self.nextthink = time + tr.frtime2;
-};
-
-void() misc_modeltrain = {
-
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model(self.mdl);
-
- func_train();
-
- if (self.spawnflags & TRAIN_NONSOLID)
- self.solid = SOLID_NOT;
- else {
- self.solid = SOLID_BBOX;
- if (self.cmins == VEC_ORIGIN) self.cmins = '-8 -8 -8';
- if (self.cmaxs == VEC_ORIGIN) self.cmaxs = '8 8 8';
- }
-
- self.movetype = MOVETYPE_NOCLIP;
- setmodel (self, self.mdl);
- setsize (self, self.cmins , self.cmaxs);
- setorigin (self, self.origin);
-
- entity rot, anim;
-
- rot = spawn();
- self.rotatecontroller = rot;
- rot.classname = "rotatecontroller";
- rot.owner = self;
-
- anim = spawn();
- self.animcontroller = anim;
- anim.classname = "animcontroller";
- anim.owner = self;
-
- anim.think = animcontroller_think;
- anim.nextthink = time + 0.2;
-
- self.distance = 1;
-
- if (!self.frtime) self.frtime = 0.1;
- if (!self.frtime2) self.frtime2 = self.frtime;
- if (!self.multiplier) self.multiplier = 1;
-
-
- // make sure all first and last frame fields are filled
- if (self.first_frame && !self.last_frame) self.last_frame = self.first_frame;
- else if (!self.first_frame && self.last_frame) self.first_frame = self.last_frame;
-
- if (self.first_frame2 && !self.last_frame2) self.last_frame2 = self.first_frame2;
- else if (!self.first_frame2 && self.last_frame2) self.first_frame2 = self.last_frame2;
-
- if (!self.first_frame2) self.style = TRAIN_STYLE_SINGLEANIM;
-
- if (!self.animtype) self.animtype = TRAIN_ANIMTYPE_FORWARD;
- if (!self.animtype2) self.animtype2 = self.animtype;
-
- self.frame = self.first_frame;
-
-};
-
-
-//===================================================
-
-
-//Code for the fixed teleporttrain written by c0burn and modified by ZungryWare
-void() teleporttrain_calcmove;
-void() teleporttrain_next =
-{
- local vector dir;
- setorigin(self, self.enemy.origin + '16 16 16');
-
- if (!self.target)
- {
- self.enemy = world;
- return;
- }
- self.enemy = find(world, targetname, self.target);
- if (self.enemy.classname == "path_corner")
- {
- dir = normalize((self.enemy.origin + '16 16 16') - self.origin);
- self.velocity = dir * self.speed;
- self.target = self.enemy.target;
- }
- else
- {
- objerror("unable to find target\n");
- remove(self);
- }
- teleporttrain_calcmove();
-};
-void() teleporttrain_wait =
-{
- local float wait_time;
- if (self.enemy.wait > 0)
- wait_time = self.enemy.wait;
- else
- wait_time = .1;
- self.velocity = '0 0 0';
- self.nextthink = time + wait_time;
- self.think = teleporttrain_next;
-
-}
-void() teleporttrain_calcmove =
-{
- local float len;
- local vector delta;
- local float spd;
-
- delta = (self.enemy.origin + '16 16 16') - self.origin;
- len = vlen(delta);
- spd = vlen(self.velocity);
- self.nextthink = time + (len / spd);
- self.think = teleporttrain_wait;
-};
-void() teleporttrain_use =
-{
- if (self.velocity == '0 0 0')
- {
- teleporttrain_next();
- }
-};
-void() teleporttrain_find =
-{
- // always start positioned on the first path_corner
- self.enemy = find(world, targetname, self.target);
- if (self.enemy.classname == "path_corner")
- {
- setorigin (self, self.enemy.origin + '16 16 16');
- self.target = self.enemy.target;
- }
- else
- {
- objerror("unable to find target\n");
- remove(self);
- return;
- }
-
- if (self.spawnflags & 4) // start immediately even with a targetname
- {
- teleporttrain_next();
- }
- // not triggered, so start immediately
- else if (!self.targetname)
- {
- teleporttrain_next();
- }
- else
- {
- self.use = teleporttrain_use;
- }
-};
-/*QUAKED misc_teleporttrain (.5 .5 .5) (-16 -16 -16) (16 16 16) X DONT_ROTATE START_ON_WITH_TARGETNAME INVISIBLE X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/teleport.mdl"); }
-This was used for the final boss level in the original game. In progs_dump you can use this as a moving decoration or even target it as a spawn point for a func_monster_spawner. Make sure and select the Don't Rotate spawnflag though or you'll experience a pretty hilarious effect!
-
-You set this up like a func_train using path_corners. By default, it will move automatically between path corners upon map load. However, you can have it wait to move by giving it a targetname. If you need to target it as a spawner and want it to move on map load, use the Start On spawnflag.
-
-You can add effects, use a custom model using the mdl_body keyvalue and even make it invisible with spawnflag 8.
-
-Effects
-0: "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-
-Teleporter target for final boss level. Must target a series of 'path_corner' entities.
-It will position itself on its first target at map load.
-If a targetname is set, it must be triggered to start moving, otherwise it will start automatically.
-*/
-void() misc_teleporttrain =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.target)
- {
- objerror ("misc_teleporttrain has no target");
- remove(self);
- return;
- }
- if (self.speed <= 0)
- {
- self.speed = 100;
- }
-
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_FLY;
- precache_body_model ("progs/teleport.mdl"); // custom custom_mdls -- dumptruck_ds
- precache_model ("progs/s_null.spr"); // invisble -- dumptruck_ds
- if (self.spawnflags & 8)
- // setmodel (self, "progs/s_null.spr");
- body_model ("progs/s_null.spr");
- else
- body_model ("progs/teleport.mdl");
- // precache_model ("progs/teleport.mdl");
- setsize (self, '-16 -16 -16', '16 16 16');
-
- //Causes the ball to spin around like it was originally intended to.
- if (!(self.spawnflags & 2)) //don't spin - helpful for invisible spawner -- dumptruck_ds
- self.avelocity = '40 80 120';
- // self.avelocity = '100 200 300';
-
- self.think = teleporttrain_find;
- self.nextthink = time + 0.1;
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/player.qc

diff --git a/qc-server/player.qc b/qc-server/player.qc
deleted file mode 100644
index ec61c1c..0000000
--- a/qc-server/player.qc
+++ /dev/null
@@ -1,762 +0,0 @@
-
-void() bubble_bob;
-
-/*
-==============================================================================
-
-PLAYER
-
-==============================================================================
-*/
-
-$cd id1/models/player_4
-$origin 0 -6 24
-$base base
-$skin skin
-
-//
-// running
-//
-$frame axrun1 axrun2 axrun3 axrun4 axrun5 axrun6
-
-$frame rockrun1 rockrun2 rockrun3 rockrun4 rockrun5 rockrun6
-
-//
-// standing
-//
-$frame stand1 stand2 stand3 stand4 stand5
-
-$frame axstnd1 axstnd2 axstnd3 axstnd4 axstnd5 axstnd6
-$frame axstnd7 axstnd8 axstnd9 axstnd10 axstnd11 axstnd12
-
-
-//
-// pain
-//
-$frame axpain1 axpain2 axpain3 axpain4 axpain5 axpain6
-
-$frame pain1 pain2 pain3 pain4 pain5 pain6
-
-
-//
-// death
-//
-
-$frame axdeth1 axdeth2 axdeth3 axdeth4 axdeth5 axdeth6
-$frame axdeth7 axdeth8 axdeth9
-
-$frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8
-$frame deatha9 deatha10 deatha11
-
-$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
-$frame deathb9
-
-$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
-$frame deathc9 deathc10 deathc11 deathc12 deathc13 deathc14 deathc15
-
-$frame deathd1 deathd2 deathd3 deathd4 deathd5 deathd6 deathd7
-$frame deathd8 deathd9
-
-$frame deathe1 deathe2 deathe3 deathe4 deathe5 deathe6 deathe7
-$frame deathe8 deathe9
-
-//
-// attacks
-//
-$frame nailatt1 nailatt2
-
-$frame light1 light2
-
-$frame rockatt1 rockatt2 rockatt3 rockatt4 rockatt5 rockatt6
-
-$frame shotatt1 shotatt2 shotatt3 shotatt4 shotatt5 shotatt6
-
-$frame axatt1 axatt2 axatt3 axatt4 axatt5 axatt6
-
-$frame axattb1 axattb2 axattb3 axattb4 axattb5 axattb6
-
-$frame axattc1 axattc2 axattc3 axattc4 axattc5 axattc6
-
-$frame axattd1 axattd2 axattd3 axattd4 axattd5 axattd6
-
-
-/*
-==============================================================================
-PLAYER
-==============================================================================
-*/
-
-void() player_run;
-
-void() player_stand1 =[ $axstnd1, player_stand1 ]
-{
- self.weaponframe=0;
- if (self.velocity_x || self.velocity_y)
- {
- self.walkframe=0;
- player_run();
- return;
- }
-
- if (self.weapon == IT_AXE)
- {
- if (self.walkframe >= 12)
- self.walkframe = 0;
- self.frame = $axstnd1 + self.walkframe;
- }
- else
- {
- if (self.walkframe >= 5)
- self.walkframe = 0;
- self.frame = $stand1 + self.walkframe;
- }
- self.walkframe = self.walkframe + 1;
-};
-
-void() player_run =[ $rockrun1, player_run ]
-{
- self.weaponframe=0;
- if (!self.velocity_x && !self.velocity_y)
- {
- self.walkframe=0;
- player_stand1();
- return;
- }
-
- if (self.weapon == IT_AXE)
- {
- if (self.walkframe == 6)
- self.walkframe = 0;
- self.frame = $axrun1 + self.walkframe;
- }
- else
- {
- if (self.walkframe == 6)
- self.walkframe = 0;
- self.frame = self.frame + self.walkframe;
- }
- self.walkframe = self.walkframe + 1;
-};
-
-
-void() player_shot1 = [$shotatt1, player_shot2 ] {self.weaponframe=1;
-self.effects = self.effects | EF_MUZZLEFLASH;};
-void() player_shot2 = [$shotatt2, player_shot3 ] {self.weaponframe=2;};
-void() player_shot3 = [$shotatt3, player_shot4 ] {self.weaponframe=3;};
-void() player_shot4 = [$shotatt4, player_shot5 ] {self.weaponframe=4;};
-void() player_shot5 = [$shotatt5, player_shot6 ] {self.weaponframe=5;};
-void() player_shot6 = [$shotatt6, player_run ] {self.weaponframe=6;};
-
-void() player_axe1 = [$axatt1, player_axe2 ] {self.weaponframe=1;};
-void() player_axe2 = [$axatt2, player_axe3 ] {self.weaponframe=2;};
-void() player_axe3 = [$axatt3, player_axe4 ] {self.weaponframe=3;W_FireAxe();};
-void() player_axe4 = [$axatt4, player_run ] {self.weaponframe=4;};
-
-void() player_axeb1 = [$axattb1, player_axeb2 ] {self.weaponframe=5;};
-void() player_axeb2 = [$axattb2, player_axeb3 ] {self.weaponframe=6;};
-void() player_axeb3 = [$axattb3, player_axeb4 ] {self.weaponframe=7;W_FireAxe();};
-void() player_axeb4 = [$axattb4, player_run ] {self.weaponframe=8;};
-
-void() player_axec1 = [$axattc1, player_axec2 ] {self.weaponframe=1;};
-void() player_axec2 = [$axattc2, player_axec3 ] {self.weaponframe=2;};
-void() player_axec3 = [$axattc3, player_axec4 ] {self.weaponframe=3;W_FireAxe();};
-void() player_axec4 = [$axattc4, player_run ] {self.weaponframe=4;};
-
-void() player_axed1 = [$axattd1, player_axed2 ] {self.weaponframe=5;};
-void() player_axed2 = [$axattd2, player_axed3 ] {self.weaponframe=6;};
-void() player_axed3 = [$axattd3, player_axed4 ] {self.weaponframe=7;W_FireAxe();};
-void() player_axed4 = [$axattd4, player_run ] {self.weaponframe=8;};
-
-
-//============================================================================
-
-void() player_nail1 =[$nailatt1, player_nail2 ]
-{
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- if (!self.button0)
- {player_run ();return;}
- self.weaponframe = self.weaponframe + 1;
- if (self.weaponframe == 9)
- self.weaponframe = 1;
- SuperDamageSound();
- W_FireSpikes (4);
- self.attack_finished = time + 0.2;
-};
-void() player_nail2 =[$nailatt2, player_nail1 ]
-{
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- if (!self.button0)
- {player_run ();return;}
- self.weaponframe = self.weaponframe + 1;
- if (self.weaponframe == 9)
- self.weaponframe = 1;
- SuperDamageSound();
- W_FireSpikes (-4);
- self.attack_finished = time + 0.2;
-};
-
-//============================================================================
-
-void() player_light1 =[$light1, player_light2 ]
-{
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- if (!self.button0)
- {player_run ();return;}
- self.weaponframe = self.weaponframe + 1;
- if (self.weaponframe == 5)
- self.weaponframe = 1;
- SuperDamageSound();
- W_FireLightning();
- self.attack_finished = time + 0.2;
-};
-void() player_light2 =[$light2, player_light1 ]
-{
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- if (!self.button0)
- {player_run ();return;}
- self.weaponframe = self.weaponframe + 1;
- if (self.weaponframe == 5)
- self.weaponframe = 1;
- SuperDamageSound();
- W_FireLightning();
- self.attack_finished = time + 0.2;
-};
-
-//============================================================================
-
-
-void() player_rocket1 =[$rockatt1, player_rocket2 ] {self.weaponframe=1;
-self.effects = self.effects | EF_MUZZLEFLASH;};
-void() player_rocket2 =[$rockatt2, player_rocket3 ] {self.weaponframe=2;};
-void() player_rocket3 =[$rockatt3, player_rocket4 ] {self.weaponframe=3;};
-void() player_rocket4 =[$rockatt4, player_rocket5 ] {self.weaponframe=4;};
-void() player_rocket5 =[$rockatt5, player_rocket6 ] {self.weaponframe=5;};
-void() player_rocket6 =[$rockatt6, player_run ] {self.weaponframe=6;};
-void(float num_bubbles) DeathBubbles;
-
-void() PainSound =
-{
-local float rs;
-
- if (self.health < 0)
- return;
-
- if (damage_attacker.classname == "teledeath")
- {
- sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
- return;
- }
-
-// water pain sounds
- if (self.watertype == CONTENT_WATER && self.waterlevel == 3)
- {
- DeathBubbles(1);
- if (random() > 0.5)
- sound (self, CHAN_VOICE, "player/drown1.wav", 1, ATTN_NORM);
- else
- sound (self, CHAN_VOICE, "player/drown2.wav", 1, ATTN_NORM);
- return;
- }
-
-// slime pain sounds
- if (self.watertype == CONTENT_SLIME)
- {
-// FIX ME put in some steam here
-// 1998-08-10 Player gulps bubbles when hurt in slime by Maddes start
- if (self.waterlevel == 3)
- DeathBubbles(1);
-// 1998-08-10 Player gulps bubbles when hurt in slime by Maddes end
- if (random() > 0.5)
- sound (self, CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM);
- else
- sound (self, CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM);
- return;
- }
-
- if (self.watertype == CONTENT_LAVA)
- {
- if (random() > 0.5)
- sound (self, CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM);
- else
- sound (self, CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM);
- return;
- }
-
- if (self.pain_finished > time)
- {
- self.axhitme = 0;
- return;
- }
- self.pain_finished = time + 0.5;
-
-// don't make multiple pain sounds right after each other
-
-// ax pain sound
- if (self.axhitme == 1)
- {
- self.axhitme = 0;
- sound (self, CHAN_VOICE, "player/axhit1.wav", 1, ATTN_NORM);
- return;
- }
-
-
- rs = rint((random() * 5) + 1);
-
- self.noise = "";
- if (rs == 1)
- self.noise = "player/pain1.wav";
- else if (rs == 2)
- self.noise = "player/pain2.wav";
- else if (rs == 3)
- self.noise = "player/pain3.wav";
- else if (rs == 4)
- self.noise = "player/pain4.wav";
- else if (rs == 5)
- self.noise = "player/pain5.wav";
- else
- self.noise = "player/pain6.wav";
-
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- return;
-};
-
-void() player_pain1 = [ $pain1, player_pain2 ] {PainSound();self.weaponframe=0;};
-void() player_pain2 = [ $pain2, player_pain3 ] {};
-void() player_pain3 = [ $pain3, player_pain4 ] {};
-void() player_pain4 = [ $pain4, player_pain5 ] {};
-void() player_pain5 = [ $pain5, player_pain6 ] {};
-void() player_pain6 = [ $pain6, player_run ] {};
-
-void() player_axpain1 = [ $axpain1, player_axpain2 ] {PainSound();self.weaponframe=0;};
-void() player_axpain2 = [ $axpain2, player_axpain3 ] {};
-void() player_axpain3 = [ $axpain3, player_axpain4 ] {};
-void() player_axpain4 = [ $axpain4, player_axpain5 ] {};
-void() player_axpain5 = [ $axpain5, player_axpain6 ] {};
-void() player_axpain6 = [ $axpain6, player_run ] {};
-
-void(entity attacker, float damage) player_pain =
-{
- if (self.weaponframe)
- return;
-
- if (self.invisible_finished > time)
- return; // eyes don't have pain frames
-
- if (self.weapon == IT_AXE)
- player_axpain1 ();
- else
- player_pain1 ();
-};
-
-void() player_diea1;
-void() player_dieb1;
-void() player_diec1;
-void() player_died1;
-void() player_diee1;
-void() player_die_ax1;
-
-void() DeathBubblesSpawn =
-{
-local entity bubble;
- if ((self.owner.waterlevel != 3) && (self.owner.health > 0)) // 1998-08-14 Improved bubble spawn by Maddes
-// 1998-08-14 Bubblespawner remove fix by Perged start
-{
- remove(self); // remove bubble spawner
-// 1998-08-14 Bubblespawner remove fix by Perged end
- return;
-} // 1998-08-14 Bubblespawner remove fix by Perged return;
- bubble = spawn();
- setmodel (bubble, "progs/s_bubble.spr");
- setorigin (bubble, self.owner.origin + '0 0 24');
- bubble.movetype = MOVETYPE_NOCLIP;
- bubble.solid = SOLID_NOT;
- bubble.velocity = '0 0 15';
- bubble.nextthink = time + 0.5;
- bubble.think = bubble_bob;
- bubble.classname = "bubble";
- bubble.frame = 0;
- bubble.cnt = 0;
- setsize (bubble, '-8 -8 -8', '8 8 8');
-// 1998-08-14 Improved bubble spawn by Maddes start
-// self.nextthink = time + 0.1;
- self.nextthink = time + 0.01;
-// 1998-08-14 Improved bubble spawn by Maddes end
- self.think = DeathBubblesSpawn;
- self.air_finished = self.air_finished + 1;
- if (self.air_finished >= self.bubble_count)
- remove(self);
-};
-
-void(float num_bubbles) DeathBubbles =
-{
-local entity bubble_spawner;
-
- bubble_spawner = spawn();
- setorigin (bubble_spawner, self.origin);
- bubble_spawner.movetype = MOVETYPE_NONE;
- bubble_spawner.solid = SOLID_NOT;
-// 1998-08-14 Improved bubble spawn by Maddes start
-// bubble_spawner.nextthink = time + 0.1;
- bubble_spawner.nextthink = time + 0.01;
-// 1998-08-14 Improved bubble spawn by Maddes end
- bubble_spawner.think = DeathBubblesSpawn;
- bubble_spawner.air_finished = 0;
- bubble_spawner.owner = self;
- bubble_spawner.bubble_count = num_bubbles;
-// return; // 1998-08-14 unnecessary by Maddes
-};
-
-
-void() DeathSound =
-{
-local float rs;
-
- // water death sounds
- if (self.waterlevel == 3)
- {
- DeathBubbles(20);
- sound (self, CHAN_VOICE, "player/h2odeath.wav", 1, ATTN_NONE);
- return;
- }
-
- rs = rint ((random() * 4) + 1);
- if (rs == 1)
- self.noise = "player/death1.wav";
- if (rs == 2)
- self.noise = "player/death2.wav";
- if (rs == 3)
- self.noise = "player/death3.wav";
- if (rs == 4)
- self.noise = "player/death4.wav";
- if (rs == 5)
- self.noise = "player/death5.wav";
-
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NONE);
- return;
-};
-
-
-void() PlayerDead =
-{
- self.nextthink = -1;
-// allow respawn after a certain time
- self.deadflag = DEAD_DEAD;
-};
-
-vector(float dm) VelocityForDamage =
-{
- local vector v;
-
- v_x = 100 * crandom();
- v_y = 100 * crandom();
- v_z = 200 + 100 * random();
-
- if (dm > -50)
- {
-// dprint ("level 1\n");
- v = v * 0.7;
- }
- else if (dm > -200)
- {
-// dprint ("level 3\n");
- v = v * 2;
- }
- else
- v = v * 10;
-
- return v;
-};
-
-void(string gibname, float dm) ThrowGib =
-{
- local entity new;
-
- new = spawn();
- new.origin = self.origin;
- setmodel (new, gibname);
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (dm);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random()*600;
- new.avelocity_y = random()*600;
- new.avelocity_z = random()*600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random()*10;
- new.frame = 0;
- new.flags = 0;
-};
-
-void(string gibname, float dm) ThrowHead =
-{
- setmodel (self, gibname);
- self.skin = self.skin_head; // dumptruck_ds custom_mdl changes
- if !(self.skin_head)
- self.skin_head = 0;
- // end dumptruck_ds
- self.frame = 0;
- self.nextthink = -1;
- self.movetype = MOVETYPE_BOUNCE;
- self.takedamage = DAMAGE_NO;
- self.solid = SOLID_NOT;
- self.view_ofs = '0 0 8';
- setsize (self, '-16 -16 0', '16 16 56');
- self.velocity = VelocityForDamage (dm);
- self.origin_z = self.origin_z - 24;
- self.flags = self.flags - (self.flags & FL_ONGROUND);
- self.avelocity = crandom() * '0 600 0';
-};
-
-
-void() GibPlayer =
-{
- ThrowHead ("progs/h_player.mdl", self.health);
- ThrowGib ("progs/gib1.mdl", self.health);
- ThrowGib ("progs/gib2.mdl", self.health);
- ThrowGib ("progs/gib3.mdl", self.health);
-
- self.deadflag = DEAD_DEAD;
-
- if (damage_attacker.classname == "teledeath")
- {
- sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
- return;
- }
-
- if (damage_attacker.classname == "teledeath2")
- {
- sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
- return;
- }
-
- if (random() < 0.5)
- sound (self, CHAN_VOICE, "player/gib.wav", 1, ATTN_NONE);
- else
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NONE);
-};
-
-void() PlayerDie =
-{
- local float i;
-
-// 1998-07-23 Palette shift when player dies with quad/pentagram fix by Maddes start
-// self.items = self.items - (self.items & IT_INVISIBILITY);
- self.items = self.items - (self.items & (IT_INVISIBILITY | IT_INVULNERABILITY | IT_SUIT | IT_QUAD) );
-// 1998-07-23 Palette shift when player dies with quad/pentagram fix by Maddes end self.invisible_finished = 0; // don't die as eyes
- self.invincible_finished = 0;
- self.super_damage_finished = 0;
- self.radsuit_finished = 0;
- self.effects = 0; // 1998-07-23 Glowing corpse of players which had quad/pentagram until respawn fix by Maddes
- self.modelindex = modelindex_player; // don't use eyes
-
- if (deathmatch || coop)
- DropBackpack();
-
- self.weaponmodel="";
- self.view_ofs = '0 0 -8';
- self.deadflag = DEAD_DYING;
- self.solid = SOLID_NOT;
- self.flags = self.flags - (self.flags & FL_ONGROUND);
- self.movetype = MOVETYPE_TOSS;
- if (self.velocity_z < 10)
- self.velocity_z = self.velocity_z + random()*300;
-
- if (self.health < -40)
- {
- GibPlayer ();
- return;
- }
-
- DeathSound();
-
- self.angles_x = 0;
- self.angles_z = 0;
-
- if (self.weapon == IT_AXE)
- {
- player_die_ax1 ();
- return;
- }
-
- i = cvar("temp1");
- if (!i)
- i = 1 + floor(random()*6);
-
- if (i == 1)
- player_diea1();
- else if (i == 2)
- player_dieb1();
- else if (i == 3)
- player_diec1();
- else if (i == 4)
- player_died1();
- else
- player_diee1();
-
-};
-
-void() set_suicide_frame =
-{ // used by klill command and diconnect command
- if (self.model != "progs/player.mdl")
- return; // allready gibbed
- self.frame = $deatha11;
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_TOSS;
- self.deadflag = DEAD_DEAD;
- self.nextthink = -1;
-};
-
-
-void() player_diea1 = [ $deatha1, player_diea2 ] {};
-void() player_diea2 = [ $deatha2, player_diea3 ] {};
-void() player_diea3 = [ $deatha3, player_diea4 ] {};
-void() player_diea4 = [ $deatha4, player_diea5 ] {};
-void() player_diea5 = [ $deatha5, player_diea6 ] {};
-void() player_diea6 = [ $deatha6, player_diea7 ] {};
-void() player_diea7 = [ $deatha7, player_diea8 ] {};
-void() player_diea8 = [ $deatha8, player_diea9 ] {};
-void() player_diea9 = [ $deatha9, player_diea10 ] {};
-void() player_diea10 = [ $deatha10, player_diea11 ] {};
-void() player_diea11 = [ $deatha11, player_diea11 ] {PlayerDead();};
-
-void() player_dieb1 = [ $deathb1, player_dieb2 ] {};
-void() player_dieb2 = [ $deathb2, player_dieb3 ] {};
-void() player_dieb3 = [ $deathb3, player_dieb4 ] {};
-void() player_dieb4 = [ $deathb4, player_dieb5 ] {};
-void() player_dieb5 = [ $deathb5, player_dieb6 ] {};
-void() player_dieb6 = [ $deathb6, player_dieb7 ] {};
-void() player_dieb7 = [ $deathb7, player_dieb8 ] {};
-void() player_dieb8 = [ $deathb8, player_dieb9 ] {};
-void() player_dieb9 = [ $deathb9, player_dieb9 ] {PlayerDead();};
-
-void() player_diec1 = [ $deathc1, player_diec2 ] {};
-void() player_diec2 = [ $deathc2, player_diec3 ] {};
-void() player_diec3 = [ $deathc3, player_diec4 ] {};
-void() player_diec4 = [ $deathc4, player_diec5 ] {};
-void() player_diec5 = [ $deathc5, player_diec6 ] {};
-void() player_diec6 = [ $deathc6, player_diec7 ] {};
-void() player_diec7 = [ $deathc7, player_diec8 ] {};
-void() player_diec8 = [ $deathc8, player_diec9 ] {};
-void() player_diec9 = [ $deathc9, player_diec10 ] {};
-void() player_diec10 = [ $deathc10, player_diec11 ] {};
-void() player_diec11 = [ $deathc11, player_diec12 ] {};
-void() player_diec12 = [ $deathc12, player_diec13 ] {};
-void() player_diec13 = [ $deathc13, player_diec14 ] {};
-void() player_diec14 = [ $deathc14, player_diec15 ] {};
-void() player_diec15 = [ $deathc15, player_diec15 ] {PlayerDead();};
-
-void() player_died1 = [ $deathd1, player_died2 ] {};
-void() player_died2 = [ $deathd2, player_died3 ] {};
-void() player_died3 = [ $deathd3, player_died4 ] {};
-void() player_died4 = [ $deathd4, player_died5 ] {};
-void() player_died5 = [ $deathd5, player_died6 ] {};
-void() player_died6 = [ $deathd6, player_died7 ] {};
-void() player_died7 = [ $deathd7, player_died8 ] {};
-void() player_died8 = [ $deathd8, player_died9 ] {};
-void() player_died9 = [ $deathd9, player_died9 ] {PlayerDead();};
-
-void() player_diee1 = [ $deathe1, player_diee2 ] {};
-void() player_diee2 = [ $deathe2, player_diee3 ] {};
-void() player_diee3 = [ $deathe3, player_diee4 ] {};
-void() player_diee4 = [ $deathe4, player_diee5 ] {};
-void() player_diee5 = [ $deathe5, player_diee6 ] {};
-void() player_diee6 = [ $deathe6, player_diee7 ] {};
-void() player_diee7 = [ $deathe7, player_diee8 ] {};
-void() player_diee8 = [ $deathe8, player_diee9 ] {};
-void() player_diee9 = [ $deathe9, player_diee9 ] {PlayerDead();};
-
-void() player_die_ax1 = [ $axdeth1, player_die_ax2 ] {};
-void() player_die_ax2 = [ $axdeth2, player_die_ax3 ] {};
-void() player_die_ax3 = [ $axdeth3, player_die_ax4 ] {};
-void() player_die_ax4 = [ $axdeth4, player_die_ax5 ] {};
-void() player_die_ax5 = [ $axdeth5, player_die_ax6 ] {};
-void() player_die_ax6 = [ $axdeth6, player_die_ax7 ] {};
-void() player_die_ax7 = [ $axdeth7, player_die_ax8 ] {};
-void() player_die_ax8 = [ $axdeth8, player_die_ax9 ] {};
-void() player_die_ax9 = [ $axdeth9, player_die_ax9 ] {PlayerDead();};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED player_dead_axe (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/player.mdl","frame":49});
-}
-*/
-void() player_dead_axe =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/player.mdl");
- setmodel(self, "progs/player.mdl");
- self.frame = $axdeth9;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-38.72 -5.83 -50.45','28.73 33.85 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-
-};
-
-/*QUAKED player_dead_face_down (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/player.mdl","frame":84});
-}
-*/
-void() player_dead_face_down =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/player.mdl");
- setmodel(self, "progs/player.mdl");
- self.frame = $deathc14;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-50.28 -23.55 -49.85','30.66 14.49 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-
-};
-
-/*QUAKED player_dead_on_side (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/player.mdl","frame":102});
-}
-*/
-void() player_dead_on_side =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/player.mdl");
- setmodel(self, "progs/player.mdl");
- self.frame = $deathe9;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-38.72 -5.83 -50.45','28.73 33.85 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-
-};
-/* END Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */

Return to the top of this page or return to the overview of this repo.

Diff qc-server/progs.src

diff --git a/qc-server/progs.src b/qc-server/progs.src
deleted file mode 100644
index 381f092..0000000
--- a/qc-server/progs.src
+++ /dev/null
@@ -1,76 +0,0 @@
-../progs.dat
-#pragma autoproto
-
-fteopts.qc
-defs_globalvars.qc // globalvars_t
-defs_entvars.qc // entvars_t
-defs_builtins.qc // builtin functions (& overrides)
-defs_misc.qc // additional
-newflags.qc // new spawnflags for all entities
-math.qc // Code by Joshua Skelton
-utility.qc
-
-subs.qc // modified targets, triggers and killtargets
-
-fight.qc
-custom_snd.qc // mapper-settable sound FX for monsters - iw
-custom_mdls.qc // mapper-settable models for monsters - iw
-ai.qc
-combat.qc
-keydata.qc // functions which deal with key item bitflags + names
-items.qc
-weapons.qc
-world.qc
-intermission.qc
-client.qc
-cutscene.qc // Drake version -- dumptruck_ds
-player.qc
-keylock.qc // common code for entities unlockable with keys
-doors.qc
-buttons.qc
-triggers.qc // added trigger_push_custom based on Hipnotic
-plats.qc
-misc.qc
-lights.qc // c0burn's excellent switchable lights
-fog.qc // fog triggers
-cshift.qc // background color shift controller
-
-// monsters
-monsters.qc // modified by dumptruck_ds from Preach's
- // spawning tutorial | fish count fixed
-monsters/boss.qc
-monsters/boss2.qc // killable Chthon
-monsters/dog.qc
-monsters/demon.qc
-monsters/knight.qc
-monsters/ogre.qc
-monsters/shambler.qc
-monsters/soldier.qc
-monsters/wizard.qc
-monsters/zombie.qc // modified ver. of Ace_Dave's zombies from Rubicon2
-monsters/enforcer.qc // registered
-monsters/fish.qc // registered
-monsters/hknight.qc // registered
-monsters/oldone.qc // registered
-monsters/oldone2.qc // killable Shub
-monsters/shalrath.qc // registered
-
-dtmisc.qc // sound code from Hipnotic & Rubicon Rumble
- // and misc visual effects
-
-misc_model.qc // Code by Joshua Skelton
-
-hip_count.qc // Hipnotic counter
-hip_part.qc // Hipnotic particlefield and func_togglewall
-hip_rotate.qc // from Hipnotic thanks RennyC
-hip_trig.qc // Hipnotic triggers qc
-doe_elbutton.qc // Rogue elevator code
-doe_ltrail.qc // from DOE lightnin.qc
-doe_plats.qc // Rogue MP newplats.qc
-
-rubicon2.qc // selections from Rubicon2 QC
-dtquake.qc // triggerable earthquake from Zer cutscenes
-func_bob.qc // RennyC's stand alone version based on AD
-func_fall2.qc // Renny's improved version.
-mobot.qc // Using "bot" creation code for func_monster_spawner
-

Return to the top of this page or return to the overview of this repo.

Diff qc-server/rubicon2.qc

diff --git a/qc-server/rubicon2.qc b/qc-server/rubicon2.qc
deleted file mode 100644
index 0e9280f..0000000
--- a/qc-server/rubicon2.qc
+++ /dev/null
@@ -1,1010 +0,0 @@
-//selections from Rubicon 2 qc by john fitzgibbons
-//and AD breakable code modified by Qmaster,iw and dumptruck_ds
-float BREAKABLE_NO_MONSTERS = 1;
-float BREAK_EXPLODE = 2;
-float BREAK_CUSTOM = 4;
-float START_OFF = 1;
-float SPARKS_BLUE = 2;
-float SPARKS_PALE = 4;
-
-void() make_breakable_debris;
-
-/*
-===============================================================================
-func_explobox
-===============================================================================
-*/
-
-void () func_explobox_explode_silent =
-{
- self.takedamage = DAMAGE_NO;
- self.origin = ((self.absmin + self.absmax) * 0.5);
- self.classname = "explo_box";
- T_RadiusDamage (self, self, self.dmg, world);
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- BecomeExplosion ();
-
-};
-
-void () func_explobox_explode = {
- // sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
- func_explobox_explode_silent();
-};
-
-void () func_explobox_die =
-{
- self.nextthink = 0.2; //for some reason, time + 0.2 doesn't work
- self.think = func_explobox_explode;
-};
-
-/*QUAKED func_explobox (0 .5 .8) ? START_OFF X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-An exploding brush entity. Works just like misc_explobox.
-
-Keys:
-
-"health" Default 20
-
-"dmg" default 100
-
-*/
-void () func_explobox =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- setmodel (self, self.model);
- precache_sound ("weapons/r_exp3.wav");
- if (!self.health)
- {
- self.health = 20;
- }
- if (!self.dmg)
- {
- self.dmg = 100;
- }
- self.th_die = func_explobox_die;
- self.takedamage = DAMAGE_AIM;
-};
-
-
-/*
-===============================================================================
-func_breakable
-===============================================================================
-*/
-
-.string break_template1;
-.string break_template2;
-.string break_template3;
-.string break_template4;
-.string break_template5;
-.float brk_obj_count1;
-.float brk_obj_count2;
-.float brk_obj_count3;
-.float brk_obj_count4;
-.float brk_obj_count5;
-
-
-// template system from Qmaster -- dumptruck_ds
-void() make_breakable_templates_debris = {
- local float i;
- local entity new;
-
- i = 0;
- if (self.break_template1 != "") {
- while (i < self.brk_obj_count1) {
- new = spawn();
- new.model = self.break_template1;
- new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
- setmodel (new, new.model); //dumptruck_ds
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health*2);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random()*600;
- new.avelocity_y = random()*600;
- new.avelocity_z = random()*600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random()*10;
- new.flags = 0;
- i++;
- }
- }
-
- i = 0;
- if (self.break_template2 != "") {
- while (i < self.brk_obj_count2) {
- new = spawn();
- new.model = self.break_template2;
- new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
- setmodel (new, new.model); //dumptruck_ds
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health*2);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random()*600;
- new.avelocity_y = random()*600;
- new.avelocity_z = random()*600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random()*10;
- new.flags = 0;
- i++;
- }
- }
-
- i = 0;
- if (self.break_template3 != "") {
- while (i < self.brk_obj_count3) {
- new = spawn();
- new.model = self.break_template3;
- new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
- setmodel (new, new.model); //dumptruck_ds
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health*2);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random()*600;
- new.avelocity_y = random()*600;
- new.avelocity_z = random()*600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random()*10;
- new.flags = 0;
- i++;
- }
- }
-
- i = 0;
- if (self.break_template4 != "") {
- while (i < self.brk_obj_count4) {
- new = spawn();
- new.model = self.break_template4;
- new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
- setmodel (new, new.model); //dumptruck_ds
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health*2);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random()*600;
- new.avelocity_y = random()*600;
- new.avelocity_z = random()*600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random()*10;
- new.flags = 0;
- i++;
- }
- }
-
- i = 0;
- if (self.break_template5 != "") {
- while (i < self.brk_obj_count5) {
- new = spawn();
- new.model = self.break_template5;
- new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
- setmodel (new, new.model); //dumptruck_ds
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health*2);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random()*600;
- new.avelocity_y = random()*600;
- new.avelocity_z = random()*600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random()*10;
- new.flags = 0;
- i++;
- }
- }
-};
-
-
-//Below this is from Rubicon2 -- dumptruck_ds
-
-void() make_breakable_debris = {
- local float i;
- i = 0;
- while (i < self.cnt)
- {
- local entity new;
-
- new = spawn();
- new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
- // setmodel (new, "progs/debris.mdl"); this was originally just an mdl from Rubicon2, now you set custom model via spawnflag or use the builtin from Rubicon2 -- dumptruck_ds
- setmodel (new, self.mdl_debris); //dumptruck_ds
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health*2);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random()*600;
- new.avelocity_y = random()*600;
- new.avelocity_z = random()*600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random()*10;
- new.flags = 0;
-
- // randomly choose size
- if (random() > 0.333)
- new.frame = 1; //larger
- else
- new.frame = 2; //smaller
-
- // choose skin based on "style" key
- if (self.style == 1)
- new.skin = 1;
- if (self.style == 2)
- new.skin = 2;
- if (self.style == 3) // new debris skins start here - dumptruck_ds
- new.skin = 3;
- if (self.style == 4)
- new.skin = 4;
- if (self.style == 5)
- new.skin = 5;
- if (self.style == 6)
- new.skin = 6;
- if (self.style == 7)
- new.skin = 7;
- if (self.style == 8)
- new.skin = 8;
- if (self.style == 9)
- new.skin = 9;
- if (self.style == 10)
- new.skin = 10;
- if (self.style == 11)
- new.skin = 11;
- if (self.style == 12)
- new.skin = 12;
- if (self.style == 13)
- new.skin = 13;
- if (self.style == 14)
- new.skin = 14;
- if (self.style == 15)
- new.skin = 15;
- if (self.style == 16)
- new.skin = 16;
- if (self.style == 17)
- new.skin = 17;
- if (self.style == 18)
- new.skin = 18;
- if (self.style == 19)
- new.skin = 19;
- if (self.style == 20)
- new.skin = 20;
- if (self.style == 21)
- new.skin = 21;
- if (self.style == 22)
- new.skin = 22;
- if (self.style == 23)
- new.skin = 23;
- if (self.style == 24)
- new.skin = 24;
- if (self.style == 25)
- new.skin = 25;
- if (self.style == 26)
- new.skin = 26;
- if (self.style == 27)
- new.skin = 27;
- if (self.style == 28)
- new.skin = 28;
- if (self.style == 29)
- new.skin = 29;
- if (self.style == 30)
- new.skin = 30;
- if (self.style == 31)// new debris skins end here - dumptruck_ds
- new.skin = 31;
-
- i = i + 1;
- }
-};
-
-void () func_breakable_die = {
- //dumptruck_ds -- set the spawnflag for cosmetic explosion effect; use "dmg" value to hurt the player
- {
- local entity ent; //thanks to Qmaster!!! He helped me sort out noise1 playing from 0 0 0 with this temp entity - dumptruck_ds
-
- ent = spawn();
- ent.origin = ((self.absmin + self.absmax) * 0.5);
- setsize (ent, '0 0 0', '0 0 0');
- ent.solid = SOLID_NOT;
- ent.think = SUB_Remove;
- // ent.ltime = time;
- ent.nextthink = time + 60;
-
- sound(ent, CHAN_AUTO, self.noise1, 1, ATTN_NORM);
- // remove (self);
- }
-
- // this is to ensure that any debris from another func_breakable
- // which is resting on top of this func_breakable is not left
- // floating in mid-air after this entity is removed -- iw
- SUB_DislodgeRestingEntities ();
-
- if (self.spawnflags & BREAK_EXPLODE) {
- if (self.spawnflags & BREAK_CUSTOM) {
- make_breakable_templates_debris ();
- } else {
- make_breakable_debris ();
- }
- func_explobox_explode_silent(); // to let us use noise2
- // sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); this is broken as of 1.1.0 no custom explosion sound for now -- dumptruck_ds
- remove (self);
- } else {
- self.origin = ((self.absmin + self.absmax) * 0.5);
- setorigin (self, self.origin);
- DropStuff();
- if (self.spawnflags & BREAK_CUSTOM) {
- if (self.switchshadstyle) lightstyle(self.switchshadstyle, "m");
- make_breakable_templates_debris ();
- remove (self);
- } else {
- if (self.switchshadstyle) lightstyle(self.switchshadstyle, "m");
- make_breakable_debris ();
- remove (self);
- }
- }
-};
-
-void () func_breakable_killed =
-{
- activator = damage_attacker;
- SUB_UseTargets ();
- func_breakable_die ();
-};
-
-void () func_breakable_use =
-{
- activator = other;
- SUB_UseTargets ();
- func_breakable_die ();
-};
-
-/*QUAKED func_breakable (0 .5 .8) ? NO_MONSTERS X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-"Breakable - See manual for full details
-
-Defaults to built-in .mdl file with 32 styles, cnt is number of pieces of debris to spawn (built-in only)
-Or use spawnflag 4 and break_template1-4 to set path of custom .mdl or .bsp models.
-brk_object_count1-4 sets the number of pieces of each break_template when using custom .mdl or bsp models.
-If noise1 is not set it will default to various sounds in sounds/break folder
-Use spawnflag 2 for an explosion, dmg is amount of damage inflicted"
-
-spawnflags(flags)
-1 : "No Monster Damage" : 0 : "Only the player can break"
-2 : "Explosion" : 0 : "Produces explosion effect and sound"
-4 : "Use custom mdls or bsp models" : 0 : "Uses models specified in break_template1, 2, etc"
-
-style(choices) : "Built-in debris style" : 0
-0 : "Green Metal (default)"
-1 : "Red Metal"
-2 : "Concrete"
-3 : "Pine wood"
-4 : "Brown wood"
-5 : "Red wood"
-6 : "Stained Glass Yellow Flames"
-7 : "Stained Glass Red Rays"
-8 : "Stained Glass Yellow Dragon"
-9 : "Stained Glass Blue Dragon"
-10 : "Stained Glass Red Dragon"
-11 : "Light Copper"
-12 : "Dark Copper"
-13 : "Tan Bricks Large"
-14 : "Brown Bricks Large"
-15 : "Green Bricks Large"
-16 : "Generic Light Brown"
-17 : "Red Brown Computer"
-18 : "Grey Black Computer"
-19 : "Blue Green Metal"
-20 : "Blue Green Runic Wall"
-21 : "Brown Metal"
-22 : "Dark Brown Metal"
-23 : "Medium Brown Metal"
-24 : "Blue Metal"
-25 : "Green Stonework"
-26 : "Blue Stonework"
-27 : "Brown Bricks"
-28 : "Tan Blue Bricks"
-29 : "Red Bricks"
-30 : "Blue Bricks"
-31 : "Metal Rivets"
-
-noise1(string) : "Break noise (overrides default sounds)"
-cnt(integer) : "Number of pieces of debris to spawn" : 5
-health(integer) : "Health of breakable" : 20
-dmg(integer) : "Amount of Explosive Damage" : 20
-break_template1(string) : "Template 1 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
-break_template2(string) : "Template 2 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
-break_template3(string) : "Template 3 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
-break_template4(string) : "Template 4 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
-break_template5(string) : "Template 5 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
-brk_obj_count1(integer) : "Template 1 spawn count"
-brk_obj_count2(integer) : "Template 2 spawn count"
-brk_obj_count3(integer) : "Template 3 spawn count"
-brk_obj_count4(integer) : "Template 4 spawn count"
-brk_obj_count5(integer) : "Template 5 spawn count"
-*/
-
-void() break_template_setup = {
- if (self.break_template1 != "") precache_model(self.break_template1);
- if (self.break_template2 != "") precache_model(self.break_template2);
- if (self.break_template3 != "") precache_model(self.break_template3);
- if (self.break_template4 != "") precache_model(self.break_template4);
- if (self.break_template5 != "") precache_model(self.break_template5);
-};
-
-void () func_breakable = {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- break_template_setup();
-
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- setmodel (self, self.model);
- self.mdl_debris = "progs/debris.mdl";
- precache_model (self.mdl_debris);
- precache_sound ("blob/hit1.wav");
-
- if (self.noise1 != "") precache_sound(self.noise1);
-// adding new default sounds for "simple" breakables in 1.2.0 -- dumptruck_ds
-// here's genreic metal breaking
- if (self.style == 0 || self.style == 11 || self.style == 12 || self.style == 17 || self.style == 18 || self.style == 19
- || self.style == 24 || self.style == 31)
- if !(self.noise1)
- {
- precache_sound("break/metal2.wav");
- self.noise1 = "break/metal2.wav";
- }
- if (self.style == 3 || self.style == 4 || self.style == 5)
- if !(self.noise1)
- {
- precache_sound("break/wood1.wav");
- precache_sound("break/wood2.wav");
- if (random() > 0.6) // wood only randomized
- self.noise1 = "break/wood1.wav";
- else
- self.noise1 = "break/wood2.wav";
- }
- // glass sounds -- this is more of a shattering sound anyway
- if (self.style == 6 || self.style == 7 || self.style == 8 || self.style == 9 || self.style == 10)
- if !(self.noise1)
- {
- precache_sound("break/metal1.wav");
- self.noise1 = "break/metal1.wav";
- }
- if (self.style == 1 || self.style == 2 || self.style == 13 || self.style == 14
- || self.style == 15 || self.style == 16 || self.style == 20 || self.style == 21
- || self.style == 22 || self.style == 23)
- if !(self.noise1)
- {
- precache_sound("break/stones1.wav");
- precache_sound("break/bricks1.wav");
- if (random() > 0.6) // wood only randomized
- self.noise1 = "break/bricks1.wav";
- else
- self.noise1 = "break/stones1.wav";
- }
- if (self.style == 25 || self.style == 26 || self.style == 27 || self.style == 28 || self.style == 29 || self.style == 30)
- if !(self.noise1)
- {
- precache_sound("break/stones1.wav");
- precache_sound("break/bricks1.wav");
- if (random() > 0.6) // wood only randomized
- self.noise1 = "break/stones1.wav";
- else
- self.noise1 = "break/bricks1.wav";
- }
- // else
- // (self.noise1 = "blob/hit1.wav");
-
- if (!self.health)
- self.health = 20;
- if (!self.cnt)
- self.cnt = 5; // was 6 dumptruck_ds
-
- if (self.targetname != "")
- {
- self.use = func_breakable_use;
- }
- else
- {
- self.takedamage = DAMAGE_YES;
- self.th_die = func_breakable_killed;
- }
-
- if (self.switchshadstyle) lightstyle(self.switchshadstyle, "a");
-};
-
-/*
-===============================================================================
-trigger_ladder
-===============================================================================
-*/
-
-void() ladder_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- // prevent the player "sticking" to a ladder if they are standing on
- // the platform at the top of the ladder with the bottom of their
- // bounding box flush with the top of the trigger -- iw
- if (other.absmin_z + 1 >= self.absmax_z - 1)
- return;
-
- // if the trigger has an angles field, check player's facing direction
- if (self.movedir != '0 0 0')
- {
- makevectors (other.angles);
- if (v_forward * self.movedir < 0)
- return; // not facing the right way
- }
- other.onladder = 1;
-}
-
-/*QUAKED trigger_ladder (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-invisible ladder entity. when player is touching this entity, he can climb by pushing 'jump'
-
-Keys:
-
-"angle" the direction player must be facing to climb ladder
-*/
-void() trigger_ladder =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- // ignore an "up" or "down" angle (doesn't make sense for a ladder)
- if (self.angles_y == -1 || self.angles_y == -2)
- {
- dprint ("WARNING: trigger_ladder ignored bad 'angle' value: ");
- dprint (ftos (self.angles_y));
- dprint ("\n");
-
- self.angles_y = 0;
- }
-
- InitTrigger ();
- self.touch = ladder_touch;
-
- SUB_CheckWaiting();
-};
-/*
-===============================================================================
-func_laser
-===============================================================================
-*/
-float LASER_SOLID = 2;
-.string message2;
-.float alpha;
-
-
-void() laser_helper_think =
-{
- if (!self.owner || self.owner.classname != "func_laser")
- {
- remove(self);
- return;
- }
-
-
- if (!(self.owner.spawnflags & START_OFF))
- self.owner.alpha = self.alpha * 0.8 + self.alpha * random() * 0.4;
-
- self.nextthink = time + 0.05;
-};
-
-void() func_laser_touch =
-{
- // from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
- return;
-
- if (other.takedamage && self.attack_finished < time)
- {
- T_Damage (other, self, self, self.dmg);
- self.attack_finished = time + 0.1;
- }
-
-};
-
-void () func_laser_use =
-{
- if (self.spawnflags & START_OFF)
- {
- setorigin(self, '0 0 0');
- self.spawnflags = self.spawnflags - START_OFF;
-
- // changed for progs_dump: the laser sound is now emitted from
- // the func_laser itself instead of from the activator -- iw
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
-
- if (activator.classname == "player" && self.message != "")
- {
- centerprint (activator, self.message);
- }
- }
- else
- {
- // changed for progs_dump: the laser sound is now emitted from
- // the func_laser itself instead of from the activator -- iw
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
-
- setorigin(self, '0 0 9000');
- self.spawnflags = self.spawnflags + START_OFF;
-
- if (activator.classname == "player" && self.message2 != "")
- {
- centerprint (activator, self.message2);
- }
- }
-};
-
-/*QUAKED func_laser (0 .5 .8) ? START_OFF LASER_SOLID X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-A toggleable laser, hurts to touch, can be used to block players
-
-START_OFF: Laser starts off.
-
-LASER_SOLID: Laser blocks movement while turned on.
-
-Keys:
-
-"dmg" damage to do on touch. default 1
-
-"alpha" approximate alpha you want the laser drawn at. default 0.5. alpha will vary by 20% of this value.
-
-"message" message to display when activated
-
-"message2" message to display when deactivated
-
-*/
-void () func_laser =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- local entity helper;
-
- setmodel (self, self.model);
-
- precache_sound ("buttons/switch02.wav");
- precache_sound ("buttons/switch04.wav");
-
- if (self.spawnflags & LASER_SOLID)
- {
- self.solid = SOLID_BSP; //so you can shoot between lasers in a single bmodel
- self.movetype = MOVETYPE_PUSH; //required becuase of SOLID_BSP
- }
- else
- {
- self.solid = SOLID_TRIGGER;
- self.movetype = MOVETYPE_NONE;
- }
-
- if (!self.alpha)
- self.alpha = 0.5;
-
- if (!self.dmg)
- self.dmg = 1;
-
- self.use = func_laser_use;
- self.touch = func_laser_touch;
-
- if (self.spawnflags & START_OFF)
- setorigin(self, '0 0 9000');
- {
- if (self.noise != "") precache_sound(self.noise);
-
- else
- (self.noise = "buttons/switch02.wav");
- }
- {
- if (self.noise1 != "") precache_sound(self.noise1);
-
- else
- (self.noise1 = "buttons/switch04.wav");
- }
-
-
-
-
- //spawn a second entity to handle alpha changes, since MOVETYPE_PUSH doesn't support think functions
- helper = spawn();
- helper.alpha = self.alpha;
- helper.owner = self;
- helper.nextthink = 0.05;
- helper.think = laser_helper_think;
-};
-
-/*
-===============================================================================
-misc_sparks
-===============================================================================
-*/
-
-void() sparks_fade1 = [0, sparks_fade2] {self.alpha = 0.8; self.nextthink = time + 0.05;};
-void() sparks_fade2 = [0, sparks_fade3] {self.alpha = 0.6; self.nextthink = time + 0.05;};
-void() sparks_fade3 = [0, sparks_fade4] {self.alpha = 0.4; self.nextthink = time + 0.05;};
-void() sparks_fade4 = [0, SUB_Remove] {self.alpha = 0.2; self.nextthink = time + 0.05;};
-
-void() sparks_use =
-{
- if (self.spawnflags & START_OFF)
- self.spawnflags = self.spawnflags - START_OFF;
- else
- self.spawnflags = self.spawnflags + START_OFF;
-};
-
-void() make_sparks;
-
-void() spark_turnofflight =
-{
- SUB_UseTargets();
- self.think = make_sparks;
- self.nextthink = time + (random() + 0.5)*self.wait - 0.15;
-}
-
-void() make_sparks =
-{
-
- if (self.spawnflags & START_OFF)
- {
- self.nextthink = time + 0.1;
- self.think = make_sparks;
- }
- else
- {
- local float i;
- i = -0.25*self.cnt + random()*0.5*self.cnt;
- while (i < self.cnt)
- {
-
- local entity spark;
- spark = spawn();
- spark.owner = self;
- setmodel (spark, "progs/spark.mdl");
- setorigin (spark, self.origin);
- spark.movetype = MOVETYPE_BOUNCE;
- spark.solid = SOLID_TRIGGER;
- spark.gravity = 0.3;
- spark.velocity_x = -40 + random() * 80;
- spark.velocity_y = -40 + random() * 80;
- spark.velocity_z = -40 + random() * 80;
- spark.avelocity = '3000 3000 3000';
- spark.nextthink = time + 0.5 + 1.5*random();
- spark.think = sparks_fade1;
- spark.classname = "spark";
-
- if (random() < 0.33)
- spark.skin = 0;
- else if (random() < 0.5)
- spark.skin = 1;
- else
- spark.skin = 2;
-
- if (self.spawnflags & SPARKS_PALE)
- spark.skin = spark.skin + 6;
- else if (self.spawnflags & SPARKS_BLUE)
- spark.skin = spark.skin + 3;
-
- setsize (spark, '0 0 0', '0 0 0');
- i = i + 1;
- }
- if (self.sounds == 1)
- {
- if (self.noise != "")
- {
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_STATIC);
- }
- else
- sound (self, CHAN_AUTO, "enforcer/enfstop.wav", 1, ATTN_STATIC);
- }
- SUB_UseTargets();
- self.nextthink = time + 0.1 + random() * 0.1;
- self.think = spark_turnofflight;
-
- }
-
-};
-
-/*QUAKED misc_sparks (0 .5 .8) (-8 -8 -8) (8 8 8) START_OFF SPARKS_BLUE SPARKS_PALE X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Produces a burst of yellow sparks at random intervals. If targeted, it will toggle between on or off. If it targets a light, that light will flash allong with each burst of sparks. Note: targeted lights should be set to START_OFF.
-
-SPARKS_BLUE: sparks are blue in color
-
-SPARKS_PALE: sparks are pale yellow in color
-
-Keys:
-
-"wait" is the average delay between bursts (variance is 1/2 wait). Default is 2.
-
-"cnt" is the average number of sparks in a burst (variance is 1/4 cnt). Default is 15.
-
-"sounds"
-0) no sound
-1) sparks
-*/
-void() misc_sparks =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/spark.mdl");
- if (!self.noise)
- precache_sound ("dump/spark.wav");
- else
- precache_sound (self.noise);
-
- if (!self.movedir)
- self.movedir = '0 0 -30';
- if (!self.wait)
- self.wait = 2;
- if (!self.cnt)
- self.cnt = 15;
-
- self.use = sparks_use;
- self.nextthink = time + random()*0.1;
- self.think = make_sparks;
-};
-
-/*
-===============================================================================
-misc_particles a.k.a. misc_splash
-===============================================================================
-*/
-void() splash_use =
-{
- if (self.spawnflags & START_OFF)
- self.spawnflags = self.spawnflags - START_OFF;
- else
- self.spawnflags = self.spawnflags + START_OFF;
-};
-
-void() splash_think =
-{
- if (self.spawnflags & START_OFF)
- {
- self.nextthink = time + 0.1;
- self.think = splash_think;
- }
- else
- {
- local vector vec;
- local float variance;
- variance = vlen(self.movedir) / 2;
- vec_x = self.movedir_x - variance + random() * variance * 2;
- vec_y = self.movedir_y - variance + random() * variance * 2;
- vec_z = self.movedir_z - variance + random() * variance * 2;
- particle (self.origin, vec, self.color, self.volume);
- self.nextthink = time + self.wait;
- }
-};
-
-//
-//misc_particles
-//
-// renamed from misc_splash (Rubcion 2) --dumptruck_ds
-//
-
-/*QUAKED misc_particles (0 .5 .8) (-8 -8 -8) (8 8 8) START_OFF X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Produces a continuous particle splash for waterfalls and other effects
-
-"color" color of particles. 0 through 15, corresponds to a row of the quake palette. (default 0)
-
-"movedir" average movement vector of particles (default 0 0 4)
-
-"wait" time between particle generation cycles. (default 0.1)
-
-"volume" density of particles. (default 10)
-
-
-*/
-void() misc_particles =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.wait)
- self.wait = 0.1;
- if (!self.movedir)
- self.movedir = '0 0 4';
- if (!self.volume)
- self.volume = 10;
- self.color = self.color * 16;
-
- self.use = splash_use;
- self.nextthink = time + self.wait;
- self.think = splash_think;
-};
-
-//##########################################
-//#### Particle Sprayer ####
-//##########################################
-
-//this is from Custents not Rubicon2 -- dumptruck_ds
-//renamed from func to misc
-
-/*QUAKED misc_particlespray (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Shoots particles either when triggered, or contiuously when not triggered by anything.
-"color" is the palette color of the particles
-
-"count" is the number of particles to make each time
-
-"delay" is the delay between each triggering
-
-"noise" is the name of the wav file to play when triggered
-
-"movedir" is the vector distance that the particles will travel before disappearing. (in x y z)
-
-"duration" is the amount of time that the it will continue to release particles so that it can release a long stream of particles with only one triggering.
-*/
-
-.float endtime;
-.float duration;
-
-void() partspray_think =
-{
- particle (self.origin, self.movedir, self.color, self.count);
-
- if(!self.targetname || self.endtime > time)
- self.nextthink = time + self.delay;
-
- if(self.noise != "")
- sound(self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- else
- sound(self, CHAN_AUTO, "misc/null.wav", 1, ATTN_NORM);
-
-};
-
-void() partspray_use =
-{
- self.endtime = time + self.duration;
- partspray_think();
-};
-
-void() misc_particlespray =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if ( !self.color )
- self.color = 47;
- if ( self.count <= 0 )
- self.count = 15;
- if(self.delay <= 0)
- self.delay = 0.1;
- self.classname = "particlespray";
- if (self.noise != "")
- precache_sound(self.noise);
- precache_sound ("misc/null.wav");
- self.think = partspray_think;
- if(!self.targetname)
- self.nextthink = time + 0.1 + self.delay;
- else
- self.use = partspray_use;
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/subs.qc

diff --git a/qc-server/subs.qc b/qc-server/subs.qc
deleted file mode 100644
index 71c715a..0000000
--- a/qc-server/subs.qc
+++ /dev/null
@@ -1,741 +0,0 @@
-
-
-void() SUB_Null = {};
-
-void(entity attacker, float damage) SUB_NullPain = {};
-
-void() SUB_Remove = {remove(self);};
-
-
-/*
-QuakeEd only writes a single float for angles (bad idea), so up and down are
-just constant angles.
-*/
-void() SetMovedir =
-{
- if (self.angles == '0 -1 0')
- self.movedir = '0 0 1';
- else if (self.angles == '0 -2 0')
- self.movedir = '0 0 -1';
- else
- {
- makevectors (self.angles);
- self.movedir = v_forward;
- }
-
- self.angles = '0 0 0';
-};
-
-
-/*
-=============
-SUB_CallAsSelf
-
-wrap the self/oself shuffle for code cleanliness elsewhere
-===============
-*/
-void(void() fun, entity newself) SUB_CallAsSelf =
-{
- local entity oself;
-
- oself = self;
- self = newself;
- fun();
- self = oself;
-}
-
-/*
-================
-InitTrigger
-================
-*/
-void() InitTrigger =
-{
-// trigger angles are used for one-way touches. An angle of 0 is assumed
-// to mean no restrictions, so use a yaw of 360 instead.
- if (self.angles != '0 0 0')
- SetMovedir ();
- self.solid = SOLID_TRIGGER;
- setmodel (self, self.model); // set size and link into world
- self.movetype = MOVETYPE_NONE;
- self.modelindex = 0;
- self.model = "";
-};
-
-// Drake -- dumptruck_ds
-// PM: The point trigger version of InitTrigger.
-void() InitPointTrigger =
-{
- local vector v1, v2;
-
- v1 = self.origin;
- v2 = v1 + self.mangle;
- self.model = "";
- setorigin (self, '0 0 0');
- InitTrigger (); // Calls 'setmodel', so do first.
- setsize (self, v1, v2); // Calling 'setmodel' resets entity size.
-};
-
-/*
-=============
-SUB_CalcMove
-
-calculate self.velocity and self.nextthink to reach dest from
-self.origin traveling at speed
-===============
-*/
-void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt =
-{
- local entity stemp;
- stemp = self;
- self = ent;
-
- SUB_CalcMove (tdest, tspeed, func);
- self = stemp;
-};
-
-void(vector tdest, float tspeed, void() func) SUB_CalcMove =
-{
- local vector vdestdelta;
- local float len, traveltime, localtime;
-
- if (!tspeed)
- objerror("No speed is defined!");
-
- if (self.movetype == MOVETYPE_PUSH) localtime = self.ltime;
- else localtime = time;
-
- self.think1 = func;
- self.finaldest = tdest;
- self.think = SUB_CalcMoveDone;
-
- if (tdest == self.origin)
- {
- self.velocity = '0 0 0';
- self.nextthink = localtime + 0.1;
- return;
- }
-
-// set destdelta to the vector needed to move
- vdestdelta = tdest - self.origin;
-
-// calculate length of vector
- len = vlen (vdestdelta);
-
-// divide by speed to get time to reach dest
- traveltime = len / tspeed;
-
- if (traveltime < 0.1)
- {
- self.velocity = '0 0 0';
- self.nextthink = localtime + 0.1;
- return;
- }
-
-// set nextthink to trigger a think when dest is reached
- self.nextthink = localtime + traveltime;
-
-// scale the destdelta vector by the time spent traveling to get velocity
- self.velocity = vdestdelta * (1/traveltime); // qcc won't take vec/float
-};
-
-/*
-============
-After moving, set origin to exact final destination
-============
-*/
-void() SUB_CalcMoveDone =
-{
- setorigin(self, self.finaldest);
- self.velocity = '0 0 0';
- self.nextthink = -1;
- if (self.think1)
- self.think1();
-};
-
-/*
-=============
-SUB_CalcAngleMove
-
-calculate self.avelocity and self.nextthink to reach destangle from
-self.angles rotating
-
-The calling function should make sure self.think is valid
-===============
-*/
-void(entity ent, vector destangle, float tspeed, void() func) SUB_CalcAngleMoveEnt =
-{
-local entity stemp;
- stemp = self;
- self = ent;
- SUB_CalcAngleMove (destangle, tspeed, func);
- self = stemp;
-};
-
-void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove =
-{
-local vector destdelta;
-local float len, traveltime;
-
- if (!tspeed)
- objerror("No speed is defined!");
-
-// set destdelta to the vector needed to move
- destdelta = destangle - self.angles;
-
-// calculate length of vector
- len = vlen (destdelta);
-
-// divide by speed to get time to reach dest
- traveltime = len / tspeed;
-
-// set nextthink to trigger a think when dest is reached
- self.nextthink = self.ltime + traveltime;
-
-// scale the destdelta vector by the time spent traveling to get velocity
- self.avelocity = destdelta * (1 / traveltime);
-
- self.think1 = func;
- self.finalangle = destangle;
- self.think = SUB_CalcAngleMoveDone;
-};
-
-/*
-============
-After rotating, set angle to exact final angle
-============
-*/
-void() SUB_CalcAngleMoveDone =
-{
- self.angles = self.finalangle;
- self.avelocity = '0 0 0';
- self.nextthink = -1;
- if (self.think1)
- self.think1();
-};
-
-/*
-=============
-SUB_CalcAngleMoveController
-
-Same as SUB_CalcAngleMove, but using a separate controller entity
-to not lose track of current think functions.
-
-===============
-*/
-void() SUB_CalcAngleMoveDoneController;
-
-void(vector destangle, float tspeed, void() func, entity controller) SUB_CalcAngleMoveController =
-{
- local vector destdelta;
- local float len, traveltime;
-
- if (!tspeed)
- objerror("No speed is defined!");
-
- // set destdelta to the vector needed to move
-
- destdelta = normalizeAngles180(destangle - self.angles);
- /*dprint3("destangle: ", vtos(destangle), "\n");
- dprint3("self.angles: ", vtos( self.angles), "\n");
- dprint3("destdelta: ", vtos(destdelta), "\n");
- */
-
- // calculate length of vector
- len = vlen (destdelta);
-
- // divide by speed to get time to reach dest
- traveltime = len / tspeed;
-
- // set nextthink to trigger a think when dest is reached
- controller.nextthink = time + traveltime;
-
- // scale the destdelta vector by the time spent traveling to get velocity
- self.avelocity = destdelta * (1 / traveltime);
-
- // Makes sure controller.owner points to self so it can be referenced later in the think function
- controller.owner = self;
- controller.think1 = func;
- controller.finalangle = destangle;
- controller.think = SUB_CalcAngleMoveDoneController;
-};
-
-/*
-============
-After rotating, set angle to exact final angle
-============
-*/
-void() SUB_CalcAngleMoveDoneController =
-{
- self.owner.angles = self.finalangle;
- self.owner.avelocity = '0 0 0';
- self.nextthink = -1;
- if (self.think1)
- SUB_CallAsSelf(self.think1, self.owner);
-};
-
-
-//=============================================================================
-
-void() DelayThink =
-{
- activator = self.enemy;
- SUB_UseTargets ();
- remove(self);
-};
-
-/* ### (added targets, killtargets, and targetnames)
-==============================
-SUB_UseTargets
-
-the global "activator" should be set to the entity that initiated the firing.
-
-If self.delay is set, a DelayedUse entity will be created that will actually
-do the SUB_UseTargets after that many seconds have passed.
-
-Centerprints any self.message to the activator.
-
-Removes all entities with a targetname that match self.killtarget,
-or killtarget2, so some events can remove other triggers.
-
-Search for (string)targetname, targetname2, targetname3, and targetname 4
-in all entities that match (string)self.target, self.target2, self.target3,
-or self.target4 and use their .use function.
-==============================
-*/
-void(string matchstring, .string matchfield) SUB_UseSpecificTarget =
-{
- local entity t, stemp, otemp, act;
-
- act = activator;
- t = find (world, matchfield, matchstring);
- while ( t != world )
- {
- stemp = self;
- otemp = other;
- self = t;
- other = stemp;
- if (self.use != SUB_Null)
- {
- if (self.use)
- {
- lastnameused = matchstring;
- self.use ();
- }
- }
- self = stemp;
- other = otemp;
- activator = act;
- t = find (t, matchfield, matchstring);
- }
-};
-
-void() SUB_UseTargets =
-{
-// local entity t, stemp, otemp, act;
- local entity t;
-
- if (self.estate != STATE_ACTIVE) return;
-//
-// check for a delay
-//
- if (self.delay)
- {
- // create a temp object to fire at a later time
- t = spawn();
- t.classname = "DelayedUse";
- t.nextthink = time + self.delay;
- t.think = DelayThink;
- t.enemy = activator;
- t.message = self.message;
- t.killtarget = self.killtarget;
- t.killtarget2 = self.killtarget2;
- t.target = self.target;
- t.target2 = self.target2;
- t.target3 = self.target3;
- t.target4 = self.target4;
- return;
- }
-
-
-//
-// print the message
-//
- if (self.message != "" && !(self.flags & FL_NOCENTERPRINT)) {
- if (self.spawnflags & TRIGGER_CENTERPRINTALL) {
- t = find(world, classname, "player");
- while (t) {
- centerprint (t, self.message);
- if (!self.noise)
- sound (t, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
- t = find(t, classname, "player");
- }
- }
-
- else if (activator.classname == "player") {
- centerprint (activator, self.message);
- if (!self.noise)
- sound (activator, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
- }
- }
-
-//
-// kill the killtarget entities
-//
- if (self.killtarget != "")
- {
- t = find(world, targetname, self.killtarget);
- while(t != world)
- {
- if(t.switchshadstyle) lightstyle(t.switchshadstyle, "m");
- remove(t);
- t = find(t, targetname, self.killtarget);
- }
- t = find(world, targetname2, self.killtarget);
- while(t != world)
- {
- if(t.switchshadstyle) lightstyle(t.switchshadstyle, "m");
- remove(t);
- t = find(t, targetname2, self.killtarget);
- }
- t = find(world, targetname3, self.killtarget);
- while(t != world)
- {
- if(t.switchshadstyle) lightstyle(t.switchshadstyle, "m");
- remove(t);
- t = find(t, targetname3, self.killtarget);
- }
- t = find(world, targetname4, self.killtarget);
- while(t != world)
- {
- if(t.switchshadstyle) lightstyle(t.switchshadstyle, "m");
- remove(t);
- t = find(t, targetname4, self.killtarget);
- }
- }
-
-//
-// kill the killtaget2 entities
-//
- if (self.killtarget2 != "")
- {
- t = find(world, targetname, self.killtarget2);
- while(t != world)
- {
- if(t.switchshadstyle) lightstyle(t.switchshadstyle, "m");
- remove(t);
- t = find(t, targetname, self.killtarget2);
- }
- t = find(world, targetname2, self.killtarget2);
- while(t != world)
- {
- if(t.switchshadstyle) lightstyle(t.switchshadstyle, "m");
- remove(t);
- t = find(t, targetname2, self.killtarget2);
- }
- t = find(world, targetname3, self.killtarget2);
- while(t != world)
- {
- if(t.switchshadstyle) lightstyle(t.switchshadstyle, "m");
- remove(t);
- t = find(t, targetname3, self.killtarget2);
- }
- t = find(world, targetname4, self.killtarget2);
- while(t != world)
- {
- if(t.switchshadstyle) lightstyle(t.switchshadstyle, "m");
- remove(t);
- t = find(t, targetname4, self.killtarget2);
- }
- }
-
-//
-// fire targets
-//
-
-// target 1
- if (self.target != "")
- {
- SUB_UseSpecificTarget(self.target, targetname);
- SUB_UseSpecificTarget(self.target, targetname2);
- SUB_UseSpecificTarget(self.target, targetname3);
- SUB_UseSpecificTarget(self.target, targetname4);
- }
-
-// target 2
- if (self.target2 != "")
- {
- SUB_UseSpecificTarget(self.target2, targetname);
- SUB_UseSpecificTarget(self.target2, targetname2);
- SUB_UseSpecificTarget(self.target2, targetname3);
- SUB_UseSpecificTarget(self.target2, targetname4);
- }
-
-// target 3
- if (self.target3 != "")
- {
- SUB_UseSpecificTarget(self.target3, targetname);
- SUB_UseSpecificTarget(self.target3, targetname2);
- SUB_UseSpecificTarget(self.target3, targetname3);
- SUB_UseSpecificTarget(self.target3, targetname4);
- }
-
-// target 4
- if (self.target4 != "")
- {
- SUB_UseSpecificTarget(self.target4, targetname);
- SUB_UseSpecificTarget(self.target4, targetname2);
- SUB_UseSpecificTarget(self.target4, targetname3);
- SUB_UseSpecificTarget(self.target4, targetname4);
- }
-};
-
-void(string matchstring) SUB_UseName =
-{
- SUB_UseSpecificTarget(matchstring, targetname);
- SUB_UseSpecificTarget(matchstring, targetname2);
- SUB_UseSpecificTarget(matchstring, targetname3);
- SUB_UseSpecificTarget(matchstring, targetname4);
-};
-// ### end of Custents triggering code
-
-/*
-=============
-SUB_UseEntTargets
-===============
-*/
-void(entity t) SUB_UseEntTargets =
-{
- if (t == world) return;
- activator = self;
- entity oself = self;
- self = t;
- SUB_UseTargets();
- self = oself;
-}
-
-/*
-================
-SUB_UseAndForgetTargets
-
-This calls SUB_UseTargets, then clears all of self's fields that cause
-SUB_UseTargets to do things. The intention is that if SUB_UseTargets
-gets called again in the future, it won't do anything. Call this
-function if you want an entity to fire its targets just this once, and
-never again.
-
-Note that this function relies on the fact that SUB_UseTargets has
-already been modified to work around the engine bug involving tests of
-the form 'if (string)', i.e. that the tests in SUB_UseTargets are now of
-the form 'if (string != "")'. -- iw
-================
-*/
-void() SUB_UseAndForgetTargets =
-{
- SUB_UseTargets ();
-
- self.delay = 0;
- self.killtarget = "";
- self.killtarget2 = "";
- self.message = "";
- self.target = "";
- self.target2 = "";
- self.target3 = "";
- self.target4 = "";
-};
-
-/*
-================
-SUB_FieldIsTargeted
-
-Return TRUE if the "fld" field of this entity is non-empty and matches
-the target (or target2/3/4 or pain_target) field of any other entity,
-otherwise return FALSE. -- iw
-================
-*/
-float(.string fld) SUB_FieldIsTargeted =
-{
- if (self.fld == "")
- return FALSE;
-
- // the following function calls are staggered to avoid the silly
- // "return value conflict" problem with traditional compilers -- iw
-
- if (find (world, target, self.fld) != world)
- return TRUE;
-
- if (find (world, target2, self.fld) != world)
- return TRUE;
-
- if (find (world, target3, self.fld) != world)
- return TRUE;
-
- if (find (world, target4, self.fld) != world)
- return TRUE;
-
- if (find (world, pain_target, self.fld) != world)
- return TRUE;
-
- return FALSE;
-};
-
-/*
-================
-SUB_IsTargeted
-
-Return TRUE if the targetname (or targetname2/3/4) field of this entity
-is non-empty and matches the target (or target2/3/4 or pain_target)
-field of any other entity, otherwise return FALSE. -- iw
-================
-*/
-float() SUB_IsTargeted =
-{
- // the following function calls are staggered to avoid the silly
- // "return value conflict" problem with traditional compilers -- iw
-
- if (SUB_FieldIsTargeted (targetname))
- return TRUE;
-
- if (SUB_FieldIsTargeted (targetname2))
- return TRUE;
-
- if (SUB_FieldIsTargeted (targetname3))
- return TRUE;
-
- if (SUB_FieldIsTargeted (targetname4))
- return TRUE;
-
- return FALSE;
-};
-
-//
-// pain_target //dumptruck_ds
-//
-void() SUB_UsePain =
-{
- if (self.pain_target != "")
- {
- SUB_UseSpecificTarget (self.pain_target, targetname);
- SUB_UseSpecificTarget (self.pain_target, targetname2);
- SUB_UseSpecificTarget (self.pain_target, targetname3);
- SUB_UseSpecificTarget (self.pain_target, targetname4);
- }
- self.pain_target = ""; //dumptruck_ds via Discord - thanks Spike, Snaut and QueenJazz
-};
-
-/*
-
-in nightmare mode, all attack_finished times become 0
-some monsters refire twice automatically
-
-*/
-
-void(float normal) SUB_AttackFinished =
-{
- self.cnt = 0; // refire count for nightmare
- if (skill != 3)
- self.attack_finished = time + normal;
-};
-
-float (entity targ) visible;
-
-void (void() thinkst) SUB_CheckRefire =
-{
- if (skill != 3)
- return;
- if (self.cnt == 1)
- return;
- if (!visible (self.enemy))
- return;
- self.cnt = 1;
- self.think = thinkst;
-};
-
-/*
-================
-SUB_DislodgeRestingEntities
-
-This clears the FL_ONGROUND flag from any entities that are on top of
-self.
-
-The engine does not update the FL_ONGROUND flag automatically in some
-cases, with the result that certain types of entities can be left
-floating in mid-air if the entity they are resting on is removed from
-under them. This function is intended to be called in the case where
-self is going to be removed, to ensure that other entities are not left
-floating. -- iw
-================
-*/
-void() SUB_DislodgeRestingEntities =
-{
- local entity e;
-
- e = nextent (world);
- while (e != world)
- {
- if ((e.flags & FL_ONGROUND) && e.groundentity == self)
- e.flags = e.flags - (e.flags & FL_ONGROUND);
- e = nextent (e);
- }
-};
-//------------------------------------------------------------------------//
-// Drake -- This makes an entity do a think function right now.
-//------------------------------------------------------------------------//
-void(entity ent, void() thinkst) SUB_Think =
-{
- local entity swap;
-
- swap = self;
- self = ent;
- thinkst ();
- self = swap;
-};
-
-/// from Copper -- dumptruck_ds (orginally found in triggers.qc)
-/*
-================================
-CheckValidTouch
-health and playerhood checks were duplicated everywhere
-added noclip check because Quake's default still-touch-everything noclip is awful
-================================
-*/
-float() CheckValidTouch =
-{
- if (other.classname != "player")
- return FALSE;
- if (other.health <= 0)
- return FALSE;
- if (other.movetype == MOVETYPE_NOCLIP)
- return FALSE;
- if (self.estate != STATE_ACTIVE)
- return FALSE;
- return TRUE;
-}
-float(float a, float b) not = { return a - (a & b); } // fix not issue in client.qc - Copper -- dumptruck_ds
-
-void() SUB_EndWaiting = {
- self.is_waiting = 0;
- self.estate = STATE_ACTIVE;
- if (self.use == SUB_EndWaiting) self.use = self.dormant_use;
-
- // special case for teleports, makes it ignore the fact that it has a targetname when touched
- if (self.classname == "trigger_teleport") {
- self.is_waiting = -1;
- }
-};
-
-void() SUB_CheckWaiting = {
- if (self.is_waiting > 0) {
- self.dormant_use = self.use;
- self.use = SUB_EndWaiting;
- self.estate = STATE_INACTIVE;
-
- dprint("Spawned a waiting ");
- dprint(self.classname);
- dprint(" with targetname ");
- dprint(self.targetname);
- dprint(" and target ");
- dprint(self.target);
- dprint("\n");
- }
-};
\ No newline at end of file

Return to the top of this page or return to the overview of this repo.

Diff qc-server/triggers.qc

diff --git a/qc-server/triggers.qc b/qc-server/triggers.qc
deleted file mode 100644
index cda0c06..0000000
--- a/qc-server/triggers.qc
+++ /dev/null
@@ -1,1781 +0,0 @@
-
-// entity s;
-
-
-void() trigger_reactivate =
-{
- self.solid = SOLID_TRIGGER;
-};
-
-//=============================================================================
-
-float SPAWNFLAG_NOMESSAGE = 1;
-float SPAWNFLAG_NOTOUCH = 1;
-float SPAWNFLAG_TURNS_OFF = 2; //used for Wait for retrigger spawnflag
-
-// the wait time has passed, so set back up for another activation
-void() multi_wait =
-{
- if (self.max_health)
- {
- self.health = self.max_health;
- self.takedamage = DAMAGE_YES;
- self.solid = SOLID_BBOX;
- }
-};
-
-
-// the trigger was just touched/killed/used
-// self.enemy should be set to the activator so it can be held through a delay
-// so wait for the delay time before firing
-void() multi_trigger =
-{
- if (self.nextthink > time)
- {
- return; // allready been triggered
- }
-
- if (self.classname == "trigger_secret")
- {
- if (self.enemy.classname != "player")
- return;
- if (cutscene)
- return; // Don't activate in cutscene mode
- found_secrets = found_secrets + 1;
- WriteByte (MSG_ALL, SVC_FOUNDSECRET);
- }
-
- if (self.noise != "")
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
-
-// don't trigger again until reset
- self.takedamage = DAMAGE_NO;
-
- activator = self.enemy;
-
- SUB_UseTargets();
-
- if (self.wait > 0)
- {
- self.think = multi_wait;
- self.nextthink = time + self.wait;
- if (self.spawnflags & SPAWNFLAG_TURNS_OFF)
- {
- self.is_waiting = 1;
- SUB_CheckWaiting();
- }
- }
- else
- { // we can't just remove (self) here, because this is a touch function
- // called wheil C code is looping through area links...
- self.touch = SUB_Null;
- self.nextthink = time + 0.1;
- self.think = SUB_Remove;
- }
-};
-
-void() multi_killed = //dumptruck_ds
-{
- if (self.estate != STATE_ACTIVE) // Supa, restore health and do nothing if we're still waiting to be activated
- {
- self.health = self.max_health; // nyah nyah~!
- self.takedamage = DAMAGE_YES;
- self.solid = SOLID_BBOX;
-
- return;
- }
-
- self.enemy = damage_attacker;
- multi_trigger();
-};
-
-void() multi_use = //dumptruck_ds
-{
- self.enemy = activator;
- multi_trigger();
-};
-
-void() multi_touch = //dumptruck_ds
-{
-
- if (other.classname != "player")
- return;
-
- // from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
- return;
-
- if (self.estate != STATE_ACTIVE)
- return;
-
-// if the trigger has an angles field, check player's facing direction
- if (self.movedir != '0 0 0')
- {
- makevectors (other.angles);
- if (v_forward * self.movedir < 0)
- return; // not facing the right way
- }
-
- self.enemy = other;
- multi_trigger ();
-};
-
-/*QUAKED trigger_multiple (.5 .5 .5) ? notouch WAIT_FOR_RETRIGGER X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Variable sized repeatable trigger. Must be targeted at one or more entities. If "health" is set, the trigger must be killed to activate each time.
-If "WAIT_FOR_RETRIGGER" is set, it must be triggered by another entity before it can trigger again.
-If "delay" is set, the trigger waits some time after activating before firing.
-"wait" : Seconds between triggerings. (.2 default)
-If notouch is set, the trigger is only fired by other entities, not by touching.
-NOTOUCH has been obsoleted by trigger_relay!
-sounds
-1) secret
-2) beep beep
-3) large switch
-set "message" to text string
-"is_waiting" : If set to 1, this trigger will do nothing until another trigger activates it
-*/
-void() trigger_multiple =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.sounds == 1)
- {
- precache_sound ("misc/secret.wav");
- self.noise = "misc/secret.wav";
- }
- else if (self.sounds == 2)
- {
- precache_sound ("misc/talk.wav");
- self.noise = "misc/talk.wav";
- }
- else if (self.sounds == 3)
- {
- precache_sound ("misc/trigger1.wav");
- self.noise = "misc/trigger1.wav";
- }
-
- if (!self.wait)
- {
- self.wait = 0.2;
- }
- else if (self.wait < 0 && (self.spawnflags & SPAWNFLAG_TURNS_OFF))
- {
- objerror("Wait for retrigger and negative wait don't make sense");
- }
- self.use = multi_use;
-
- InitTrigger ();
-
- if (self.health)
- {
- if (self.spawnflags & SPAWNFLAG_NOTOUCH)
- objerror ("health and notouch don't make sense\n");
- self.max_health = self.health;
- self.th_die = multi_killed;
- self.takedamage = DAMAGE_YES;
- self.solid = SOLID_BBOX;
- setorigin (self, self.origin); // make sure it links into the world
- }
- else
- {
- if ( !(self.spawnflags & SPAWNFLAG_NOTOUCH) )
- {
- self.touch = multi_touch;
- }
- }
-
- SUB_CheckWaiting();
-};
-
-
-/*QUAKED trigger_once (.5 .5 .5) ? notouch X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Variable sized trigger. Triggers once, then removes itself. You must set the key "target" to the name of another object in the level that has a matching
-"targetname". If "health" is set, the trigger must be killed to activate.
-If notouch is set, the trigger is only fired by other entities, not by touching.
-if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired.
-if "angle" is set, the trigger will only fire when someone is facing the direction of the angle. Use "360" for an angle of 0.
-sounds
-1) secret
-2) beep beep
-3) large switch
-set "message" to text string
-*/
-void() trigger_once =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.wait = -1;
- trigger_multiple();
-};
-
-//=============================================================================
-
-/*QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-This fixed size trigger cannot be touched, it can only be fired by other events. It can contain killtargets, targets, delays, and messages.
-*/
-void() trigger_relay =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = SUB_UseTargets;
-};
-
-
-//=============================================================================
-
-/*QUAKED trigger_secret (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-secret counter trigger
-sounds
-1) secret
-2) beep beep
-set "message" to text string
-*/
-void() trigger_secret =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- total_secrets = total_secrets + 1;
- self.wait = -1;
- if (!self.message)
- self.message = "You found a secret area!";
- if (!self.sounds)
- self.sounds = 1;
-
- if (self.sounds == 1)
- {
- precache_sound ("misc/secret.wav");
- self.noise = "misc/secret.wav";
- }
- else if (self.sounds == 2)
- {
- precache_sound ("misc/talk.wav");
- self.noise = "misc/talk.wav";
- }
-
- trigger_multiple ();
-};
-
-//=============================================================================
-
-
-void() counter_use =
-{
- if (self.estate != STATE_ACTIVE) return;
-
- self.count = self.count - 1;
- if (self.count < 0)
- return;
-
- if (self.count != 0)
- {
- if (activator.classname == "player"
- && (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
- {
- if (self.count >= 4)
- centerprint (activator, "There are more to go...");
- else if (self.count == 3)
- centerprint (activator, "Only 3 more to go...");
- else if (self.count == 2)
- centerprint (activator, "Only 2 more to go...");
- else
- centerprint (activator, "Only 1 more to go...");
- }
- return;
- }
-
- if (activator.classname == "player"
- && (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
- centerprint(activator, "Sequence completed!");
- self.enemy = activator;
- multi_trigger ();
-};
-
-/*QUAKED trigger_counter (.5 .5 .5) ? nomessage X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Acts as an intermediary for an action that takes multiple inputs.
-
-If nomessage is not set, t will print "1 more.. " etc when triggered and "sequence complete" when finished.
-
-After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself.
-*/
-void() trigger_counter =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.wait = -1;
- if (!self.count)
- self.count = 2;
-
- self.use = counter_use;
-};
-
-/*
-==============================================================================
-
-TELEPORT TRIGGERS with added functions from Zerstrorer and Qmaster
--- dumptruck_ds
-
-==============================================================================
-*/
-
-float PLAYER_ONLY = 1;
-float SILENT = 2;
-float RANDOM = 4;
-float TELE_STEALTH = 8;
-float MONSTER_ONLY = 16;
-float TELE_DD = 32;
-
-void() play_teleport =
-{
- local float v;
- local string tmpstr;
-
- v = random() * 5;
- if (v < 1)
- tmpstr = "misc/r_tele1.wav";
- else if (v < 2)
- tmpstr = "misc/r_tele2.wav";
- else if (v < 3)
- tmpstr = "misc/r_tele3.wav";
- else if (v < 4)
- tmpstr = "misc/r_tele4.wav";
- else
- tmpstr = "misc/r_tele5.wav";
-
- sound (self, CHAN_VOICE, tmpstr, 1, ATTN_NORM);
- remove (self);
-};
-
-void(vector org) spawn_tfog =
-{
- local entity s;
-
- s = spawn ();
- s.origin = org;
- s.spawnflags = self.spawnflags; //dumptruck_ds
- s.nextthink = time + 0.2;
- s.think = play_teleport;
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_TELEPORT);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
-};
-
-
-void() tdeath_touch =
-{
- if (other == self.owner)
- return;
-
-// frag anyone who teleports in on top of an invincible player
- if (other.classname == "player")
- {
-// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes start
- if (self.owner.classname != "player")
- { // other monsters explode themselves
- T_Damage (self.owner, self, self, 50000);
- return;
- }
-// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes end
- if (other.invincible_finished > time)
-// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes start
- { //player on spot has active pentagram
- if (self.owner.invincible_finished > time)
- { // teleported player has active pentagram too
- // can happen often in deathmatch 4
- // and levels with more than one pentagram
- self.classname = "teledeath3";
- other.invincible_finished = 0;
- T_Damage (other, self, self, 50000); // kill player on spot
-/* 1998-07-26 only telefrag player on spot by Maddes
- local entity other2;
- other2 = self.owner;
- self.owner = other;
- other2.invincible_finished = 0;
- T_Damage (other2, self, self, 50000); // kill teleported player
-*/
- }
- else // 1998-07-26 only telefrag player on spot by Maddes
- { // 1998-07-26 only telefrag player on spot by Maddes
-// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes end
- self.classname = "teledeath2";
-// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes start
- T_Damage (self.owner, self, self, 50000);
- } // 1998-07-26 only telefrag player on spot by Maddes
- return;
- }
-
-/*
- if (self.owner.classname != "player")
- { // other monsters explode themselves
- T_Damage (self.owner, self, self, 50000);
- return;
- }
-*/
-// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes end
-
- }
-
- if (other.health)
- {
- T_Damage (other, self, self, 50000);
- }
-};
-
-
-void(vector org, entity death_owner) spawn_tdeath =
-{
-local entity death;
-
- death = spawn();
- death.classname = "teledeath";
- death.movetype = MOVETYPE_NONE;
- death.solid = SOLID_TRIGGER;
- death.angles = '0 0 0';
- setsize (death, death_owner.mins - '1 1 1', death_owner.maxs + '1 1 1');
- setorigin (death, org);
- death.touch = tdeath_touch;
- death.nextthink = time + 0.2;
- death.think = SUB_Remove;
- death.owner = death_owner;
-
- force_retouch = 2; // make sure even still objects get hit
-};
-
-/*-----------------------------------------------*/
-/*| more Zerstrorer-- dumptruck_ds |*/
-/*| teleport_randomspot - returns a random spot |*/
-/*| to teleport to among all of the |*/
-/*| "info_teleport_random" entities in the |*/
-/*| level. self.count is number of spots |*/
-/*-----------------------------------------------*/
-entity() teleport_randomspot =
-{
-local float rndm;
-// local float rndm, num1;
-local entity spot,first;
-
- rndm = rint(random() * (self.count - 1));
- spot = find(world, classname, "info_teleport_random");
- if(!spot)
- dprint("No random teleport points found!\n");
- first = spot;
-
- while (rndm > 0)
- {
- rndm = rndm - 1;
- spot = find(spot, classname, "info_teleport_random");
- }
-
- if (spot == world)
- {
- dprint("Random spot found world!!\n");
- spot = first;
- }
-
- return spot;
-};
-// end dumptruck_ds
-void() teleport_touch =
-{
-local entity t;
-local vector org;
-
- if (self.estate != STATE_ACTIVE) return;
-
- if (self.targetname != "")
- {
- if (self.nextthink < time)
- {
- return; // not fired yet
- }
- }
-
- if (self.spawnflags & PLAYER_ONLY)
- {
- if (other.classname != "player")
- return;
- }
-
- if (self.spawnflags & MONSTER_ONLY) // is this going to work? dumptruck_ds
- {
- if (other.classname == "player")
- return;
- }
-
- if (other.movetype == MOVETYPE_NOCLIP) // from Copper -- dumptruck_ds
- return;
-
- if (self.is_waiting == TRUE) // Supa, is this trigger waiting to be activated?
- return;
-
- if (self.is_waiting != -1) // Special case
- if (self.targetname != "")
- {
- if (self.nextthink < time)
- {
- return; // not fired yet
- }
- }
-
-// only teleport living creatures
- if (other.health <= 0 || other.solid != SOLID_SLIDEBOX)
- return;
-
- SUB_UseTargets ();
-
- // put a tfog where the player was
- // ### dhm - if stealth, don't spawn a fog
- if (!(self.spawnflags & TELE_STEALTH))
- spawn_tfog (other.origin);
-
- //dhm - if this is a random teleporter, pick a random spot!
- if (self.spawnflags & RANDOM)
- t = teleport_randomspot();
- else if ((self.spawnflags & TELE_DD) && other.classname == "player")
- t = find (world, targetname, self.noise);
- else
- t = find (world, targetname, self.target);
-
- if (!t)
- objerror ("couldn't find target");
-
-// // put a tfog where the player was
-// spawn_tfog (other.origin);
-//
-// t = find (world, targetname, self.target);
-// if (!t)
-// objerror ("couldn't find target");
-
-// spawn a tfog flash in front of the destination
- makevectors (t.mangle);
- org = t.origin + 32 * v_forward;
-
-// ### dhm - if stealth, don't spawn a fog
-if (!(self.spawnflags & TELE_STEALTH))
- spawn_tfog (org);
-
- spawn_tdeath(t.origin, other);
-
-// move the player and lock him down for a little while
- if (!other.health)
- {
- other.origin = t.origin;
- other.velocity = (v_forward * other.velocity_x) + (v_forward * other.velocity_y);
- return;
- }
-
- setorigin (other, t.origin);
- other.angles = t.mangle;
- if (other.classname == "player")
- {
- fog_setFromEnt(other, t); // retrieves fog values from teleport destination, if any
-
- other.fixangle = 1; // turn this way immediately
- other.teleport_time = time + 0.7;
- if (other.flags & FL_ONGROUND)
- other.flags = other.flags - FL_ONGROUND;
- other.velocity = v_forward * 300;
- }
- other.flags = other.flags - other.flags & FL_ONGROUND;
-
- if ((self.spawnflags & MONSTER_ONLY) && other.classname != "player")
- {
- other.fixangle = 1; // turn this way immediately
- other.teleport_time = time + 0.7;
- if (other.flags & FL_ONGROUND)
- other.flags = other.flags - FL_ONGROUND;
- other.velocity = v_forward * 300;
- }
- other.flags = other.flags - other.flags & FL_ONGROUND;
-};
-// this is from Qmaster:
-
-// "I created an info_teleport_changedest
-// target = targetname of trigger_teleport to affect
-// message = targetname of new info_teleport_destination (or whatever entity
-// really) to now teleport to
-
-// So that I can automatically update the teleporter under my coagula map as you
-// progress rather than have a bunch of triggers that I need to killtarget.
-// Falling is not fatal then, but it does put you back some. Works as a sorta
-// checkpoint system but also builds on my older idea for saving time in coop
-// implemented in my Terracity map eons ago.
-
-// looking at vanilla, you would only need to change trig.target to match
-// self.message if you were to add this.""
-
-void() teleport_destchange =
-{
- local entity trig;
-
- trig = find(world,targetname,self.target);
- if (!trig || trig.classname != "trigger_teleport") {
- dprint("\b[TELEPORT_DESTCHANGE]\b Cannot find trigger_teleport\n");
- return;
- }
-
- trig.goalentity = find (world, targetname, self.message);
- if (!trig.goalentity) {
- dprint("\b[TELEPORT_DESTCHANGE]\b Cannot find teleport destination\n");
- return;
- }
-
- makevectors (trig.goalentity.mangle);
- trig.goalentity.movedir = v_forward;
- trig.goalentity.pos1 = trig.goalentity.origin + 32 * trig.goalentity.movedir;
-
- trig.target = self.message; //dumptruck_ds see comment above
-};
-
-/*QUAKED info_teleport_changedest (0 0.5 0) (-4 -4 -4) (4 4 4) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Allows a mapper to change the target of a teleport_trigger. Useful in maps where
-the player may fall into a void and the mapper wants to update where they "respawn"
-as they progress through the level. Could also be used for teleport puzzles and more.
-target = trigger_teleport to change
-message = new info_teleport_destination's targetname to switch to
-targetname = name of this entity so we can use it
-*/
-void() info_teleport_changedest =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = teleport_destchange;
- if (self.targetname == "") {
- dprint("\b[ERROR]\b info_teleport_changedest with no targetname");
- remove(self);
- }
-
- if (self.target == "") {
- dprint("\b[ERROR]\b info_teleport_changedest with no target");
- remove(self);
- }
-
- if (self.message == "") {
- dprint("\b[ERROR]\b info_teleport_changedest with no message set for new destination");
- remove(self);
- }
-};
-
-/*QUAKED info_teleport_destination (.5 .5 .5) (-8 -8 -8) (8 8 32) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/player.mdl");
-}
-This is the destination marker for a teleporter. It should have a "targetname" field with the same value as a teleporter's "target" field.
-*/
-void() info_teleport_destination =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
-// this does nothing, just serves as a target spot
- self.mangle = self.angles;
- self.angles = '0 0 0';
- self.model = "";
- self.origin = self.origin + '0 0 27';
- if (!self.targetname)
- objerror ("no targetname");
-};
-
-/*QUAKED info_teleport_random (.5 .5 .5) (-8 -8 -8) (8 8 32) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/player.mdl");
-}
-This is a random destination marker for a teleporter.
-*/
-void() info_teleport_random =
-{
-// this does nothing, just serves as a target spot
- self.mangle = self.angles;
- self.angles = '0 0 0';
- self.model = "";
- self.origin = self.origin + '0 0 27';
-};
-
-void() teleport_use =
-{
- self.nextthink = time + 0.2;
- force_retouch = 2; // make sure even still objects get hit
- self.think = SUB_Null;
-};
-
-// -------------------------
-/*QUAKED trigger_teleport (.5 .5 .5) ? PLAYER_ONLY SILENT RANDOM STEALTH X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Any object touching this will be transported to the corresponding
-info_teleport_destination entity. You must set the "target" field,
-and create an object with a "targetname" field that matches.
-
-If the trigger_teleport has a targetname, it will only teleport entities
-when it has been fired.
-
-SILENT(2) eliminates the teleporter ambient noise (good for hidden monster teleporters.
-RANDOM(4) causes the teleporter to send the player to a random destination
- among the info_teleport_random markers in the level. You MUST place a
- "count" field that is the number of info_teleport_random entities you
- placed.
-STEALTH(8) eliminates the particle flash and noise when an entity is teleported.
-MONSTER_ONLY(16) will only teleport monsters
-*/void() trigger_teleport =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- local vector o;
-
- InitTrigger ();
- self.touch = teleport_touch;
- // find the destination
- if (!self.target)
- objerror ("no target");
- self.use = teleport_use;
-
- if (!(self.spawnflags & SILENT))
- {
- precache_sound ("ambience/hum1.wav");
- o = (self.mins + self.maxs)*0.5;
- ambientsound (o, "ambience/hum1.wav",0.5 , ATTN_STATIC);
- }
-
- SUB_CheckWaiting();
-};
-
-/*
-==============================================================================
-
-trigger_setskill
-
-==============================================================================
-*/
-
-void() trigger_skill_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- cvar_set ("skill", self.message);
-};
-
-/*QUAKED trigger_setskill (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-sets skill level to the value of "message".
-Only used on start map.
-*/
-void() trigger_setskill =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- InitTrigger ();
- self.touch = trigger_skill_touch;
-
- SUB_CheckWaiting();
-};
-
-
-/*
-==============================================================================
-
-ONLY REGISTERED TRIGGERS
-
-==============================================================================
-*/
-
-void() trigger_onlyregistered_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
- if (self.attack_finished > time)
- return;
-
- self.attack_finished = time + 2;
- if (cvar("registered"))
- {
- self.message = "";
- SUB_UseTargets ();
- remove (self);
- }
- else
- {
- if (self.message != "")
- {
- centerprint (other, self.message);
- sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
- }
- }
-};
-
-/*QUAKED trigger_onlyregistered (.5 .5 .5) ?
-Only fires if playing the registered version, otherwise prints the message
-*/
-void() trigger_onlyregistered =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("misc/talk.wav");
- InitTrigger ();
- self.touch = trigger_onlyregistered_touch;
-
- SUB_CheckWaiting();
-};
-
-//============================================================================
-
-// 1998-07-03 hurt_touch fix by Robert Field start
-/*
-void() hurt_on =
-{
- self.solid = SOLID_TRIGGER;
- self.nextthink = -1;
-};
-*/
-// 1998-07-03 hurt_touch fix by Robert Field end
-
-void() hurt_touch =
-{
-
- if (self.estate != STATE_ACTIVE) return;
-
- // from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
- return;
-
- if (other.takedamage && self.nextthink < time)
- {
-// 1998-07-03 hurt_touch fix by Robert Field start
-// self.solid = SOLID_NOT;
- if (time != self.hurt_together_time)
- if (time < self.hurt_nextthink)
- return;
-// 1998-07-03 hurt_touch fix by Robert Field end
- T_Damage (other, self, self, self.dmg);
-// 1998-07-03 hurt_touch fix by Robert Field start
-// self.think = hurt_on;
-// self.nextthink = time + 1;
- self.hurt_together_time = time;
- self.hurt_nextthink = time + 1;
-// 1998-07-03 hurt_touch fix by Robert Field end
- }
- return;
-};
-
-/*QUAKED trigger_hurt (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Any object touching this will be hurt
-set dmg to damage amount
-defalt dmg = 5
-*/
-void() trigger_hurt =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- InitTrigger ();
- self.touch = hurt_touch;
- if (!self.dmg)
- self.dmg = 5;
-
- SUB_CheckWaiting();
-};
-
-//============================================================================
-
-//////////////////////////////////////////////////////////////////////////////
-// start dumptruck_ds additions //////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-float PUSH_ONCE = 1;
-float DT_STARTOFF = 8; // trigger will start off
-float DT_SILENT = 16; // push silently
-float DT_NOISE = 32; // use custom sound using noise key/value
-
-void() trigger_push_touch =
-{
- if (self.estate != STATE_ACTIVE) return;
-
- // from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
- return;
- if (other.classname == "grenade")
- other.velocity = self.speed * self.movedir * 10;
- else if (other.health > 0)
- {
- other.velocity = self.speed * self.movedir * 10;
- if (other.classname == "player")
- if (!(self.spawnflags & DT_SILENT))
- {
- if (other.fly_sound < time)
- if (!(self.spawnflags & DT_NOISE))
- {
- other.fly_sound = time + 1.5;
- sound (other, CHAN_AUTO, "ambience/windfly.wav", 1, ATTN_NORM);
- }
- else
- {
- other.fly_sound = time + 1.5;
- sound (other, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
- }
- }
- if (self.spawnflags & PUSH_ONCE)
- remove(self);
-};
-
-// void() trigger_push_use = //dumptruck_ds
-// {
-// self.is_waiting = !self.is_waiting;
-// }
-
-/*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Pushes the player
-*/
-void() trigger_push = //dumptruck_ds
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- InitTrigger ();
- precache_sound ("ambience/windfly.wav");
- self.touch = trigger_push_touch;
-
- if (!self.speed)
- self.speed = 1000;
-
- SUB_CheckWaiting();
-};
-
-void() push_toggle = //dumptruck_ds was based on hipnotic blocker_use now Alklaine estate
-
-{
- if (self.estate != STATE_ACTIVE)
- self.estate = STATE_ACTIVE;
- else
- self.estate = STATE_INACTIVE;
-};
-
-/*QUAKED trigger_push_custom (.5 .5 .5) ? PUSH_ONCE DT_STARTOFF DT_SILENT X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-
-dumptruck_ds
-
-trigger_push_custom is a new entity. This can be used to create traps,
-jumppads, currents in water and more.
-
-If DT_STARTOFF flag is set, this disables the trigger. This can be targeted and
-toggled off and on. If the DT_SILENT flag is set it won't make the windfly
-sound. Use DT_CUSTOM spawnflag and the noise key/value to use a custom push
-sound. Custom sounds should be "one off" sounds NOT be looping.
-
-Adapted from Hipnotic's func_togglewall */
-
-void() trigger_push_custom =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- InitTrigger();
- precache_sound ("ambience/windfly.wav");
- self.use = push_toggle;
- self.touch = trigger_push_touch;
-
- if ( self.spawnflags & DT_STARTOFF )
- {
- self.estate = STATE_INACTIVE;
- }
-
- if ( self.noise != "" )
- {
- precache_sound(self.noise);
- }
-
- if (!self.speed)
- self.speed = 1000;
-
- SUB_CheckWaiting();
-};
-
-
-//============================================================================
-
-void() trigger_monsterjump_touch =
-{
- if (self.estate != STATE_ACTIVE) return;
-
- if ( other.flags & (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER )
- return;
-
-// set XY even if not on ground, so the jump will clear lips
- other.velocity_x = self.movedir_x * self.speed;
- other.velocity_y = self.movedir_y * self.speed;
-
- if ( !(other.flags & FL_ONGROUND) )
- return;
-
- other.flags = other.flags - FL_ONGROUND;
-
- other.velocity_z = self.height;
-};
-
-/*QUAKED trigger_monsterjump (.5 .5 .5) ? X X X DT_STARTOFF X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Walking monsters that touch this will jump in the direction of the trigger's angle
-"speed" default to 200, the speed thrown forward
-"height" default to 200, the speed thrown upwards
-
-If DT_STARTOFF flag is set, this makes the trigger
-inactive. This can be targeted and toggled off and on.
-*/
-void() trigger_monsterjump =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = push_toggle;
- if ( self.spawnflags & DT_STARTOFF ) // dumptruck_ds
- {
- self.estate = STATE_INACTIVE;
- }
- if (!self.speed)
- self.speed = 200;
- if (!self.height)
- self.height = 200;
- if (self.angles == '0 0 0')
- self.angles = '0 360 0';
- InitTrigger ();
- self.touch = trigger_monsterjump_touch;
-
- SUB_CheckWaiting();
-};
-//////////////////////////////////////////////////////////////////////////////
-// end dumptruck_ds additions //////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-//This is necros' trigger_void from Lost Chapters pack, modified by dumptruck_ds
-
-float MONSTER_SAFE = 1;
-float PLAYER_SAFE = 2;
-
-void() trigger_void_touch =
-{
- if (self.estate != STATE_ACTIVE) return;
-
- if (other.movetype == MOVETYPE_NOCLIP) // from Copper -- dumptruck_ds
- return FALSE;
-
- if (self.spawnflags & MONSTER_SAFE && other.flags & FL_MONSTER) return; //ignore monsters
- if (self.spawnflags & PLAYER_SAFE && other.flags & FL_CLIENT) return; // ignore players
-
- if (other.takedamage)
- {
- other.invincible_finished = 0; // kills even with Pentagram, this took forever to figure out!! -- dumptruck_ds
- T_Damage (other, self, self, other.health + 1000 /*, DTH_TRIGGER_VOID, 1, 1*/);
-
- if (other.flags & FL_MONSTER)
- remove(other);
- }
-
- if (other.classname == "gib" ||
- other.classname == "grenade" ||
- other.classname == "spike" ||
- other.classname == "missile")
- remove(other);
-
- if (other.flags & FL_ITEM)
- remove(other);
-
- force_retouch = 2;
-};
-
-/*QUAKED trigger_void (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Use this for a 'void' area. removes monsters, gibs, ammo, etc... also kills player.
-*/
-void() trigger_void =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- InitTrigger ();
- self.touch = trigger_void_touch;
-
- SUB_CheckWaiting();
-};
-
-/*==============================================================================
-GIVE AND TAKE STUFF (WIP)
-
-This is Axe only at the moment. Need to research removing all weapons.
-==============================================================================*/
-
-void() take_weapon_use = //thanks to ShanJaq and Spike for their help on this.
-
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- if (!(other.flags & FL_CLIENT))
- return;
-
- {
- multi_trigger();
- other.items &= ~IT_SHOTGUN;
- other.currentammo = !other.ammo_shells;
- other.ammo_shells = !other.ammo_shells;
- other.items = other.items - ( other.items & IT_SHELLS);
- W_SetCurrentAmmo();
- W_BestWeapon();
- }
-};
-/*QUAKED trigger_take_weapon (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Removes shotgun upon touch. You can also set "reset_items" in the worldspawn entity to accomplish an axe only start.
-*/
-void() trigger_take_weapon =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.wait = -1;
- trigger_multiple();
- self.touch = take_weapon_use;
-
- SUB_CheckWaiting();
-};
-
-void(float newtrack) changemusic =
-{
- *world_sounds = newtrack; //changing the field via a pointer
- //world.sounds has now been changed via our pointer, newly connecting players (like those connecting after the game is loaded) will get sent the new cd track's number.
-
- //let everyone currently on the server know.
- WriteByte(MSG_ALL, SVC_CDTRACK);
- WriteByte(MSG_ALL, newtrack); //initial track
- WriteByte(MSG_ALL, newtrack); //looped track... should generally be set the same as the initial track as most engines ignore it entirely so it might as well be sane for those that care.
-};
-
-//thanks to jleww via changemusic.rar --dumptruck_ds
-
-void() trigger_changemusic_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- if (!(other.flags & FL_CLIENT))
- {
- return;
- }
- changemusic(self.sounds);
- self.touch = SUB_Null;
- self.nextthink = (time + 0.1);
- self.think = SUB_Remove;
-};
-/*QUAKED trigger_changemusic (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-A trigger brush that changes the currently playing music track. The number of the track to play goes in the sounds key (just like worldspawn). */
-void() trigger_changemusic =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
- if (!self.sounds)
- {
- objerror("ERROR: trigger_changemusic needs valid track number in sounds field");
- return;
- }
- InitTrigger();
- self.touch = trigger_changemusic_touch;
-
- SUB_CheckWaiting();
-};
-
-void() trigger_cdtrack_use = //point entity version uses count for music track number for backwards compatibly in Adoria mod -- dumptruck_ds
-{
- changemusic(self.count);
-};
-/*QUAKED trigger_cdtrack (.7 .7 .7) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-A point entity that changes the currently playing music track when triggered. The number of the track to play goes in the count key. e.g. 32 for track32.ogg See manual trigger_changemusic for more information on formats and more.
-
-NOTE: the track number uses the count key here but trigger_changemusic uses the sound key for the same info.
-*/
-void() trigger_cdtrack =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
- if (!self.count)
- {
- objerror("ERROR: trigger_cdtrack needs valid track number in count field");
- return;
- }
- InitTrigger();
- self.use = trigger_cdtrack_use;
-};
-///////////////////////////////////////////////////////////////
-//trigger_look (a.k.a. trigger_onlookat from NullPointPaladin!)
-///////////////////////////////////////////////////////////////
-void() onlookat_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- if (self.nextthink > time)
- {
- return; // allready been triggered
- }
-
- //added player view offset to make this more accurate to the player crosshairs
- local vector player_offset;
- player_offset = other.origin + other.view_ofs;
-
- makevectors(other.v_angle);
-
- //using speed to determine the reach of the trace
- if(!self.speed)
- self.speed = 500;
- traceline(player_offset, (player_offset + (v_forward * self.speed)), FALSE, other);
-
- if ((trace_ent.targetname == self.target))
- {
- // Play message if available
- if (self.message != "")
- {
- centerprint (other, self.message);
- }
- self.use = multi_trigger;
- SUB_UseTargets();
-
- if (self.noise != "")
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- else
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
-
- // added wait
- if (self.wait > 0)
- {
- self.think = multi_wait;
- self.nextthink = time + self.wait;
- }
- else
- { // we can't just remove (self) here, because this is a touch function
- // called wheil C code is looping through area links...
- self.touch = SUB_Null;
- self.nextthink = time + 0.1;
- self.think = SUB_Remove;
- }
- }
-};
-/*QUAKED trigger_look (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-This will trigger when a player is within the brush trigger and looks directly at a target entity.
-Use the first target key for the "looked at entity" and use the subsequent targets (2-4) to trigger other events.
-
-speed = Distance from player to search for trigger, adjust if the target is too far from the trigger (default 500 units)
-wait = Time between re-triggering (default 0)
-sounds = 0-3 are standard Quake trigger choices, 4 allows a custom sound, requires a path set in noise1 key
-noise1 = Path to custom sound. Use with sounds key set to 4 (e.g. fish/bite.wav)
-
-See manual for complete details. See pd_cutscenes sample map for example
-*/
-void() trigger_look =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- //play all the sounds available for a normal trigger
- if (self.sounds == 0)
- {
- precache_sound ("misc/null.wav");
- self.noise = "misc/null.wav";
- }
- else if (self.sounds == 1)
- {
- precache_sound ("misc/secret.wav");
- self.noise = "misc/secret.wav";
- }
- else if (self.sounds == 2)
- {
- precache_sound ("misc/talk.wav");
- self.noise = "misc/talk.wav";
- }
- else if (self.sounds == 3)
- {
- precache_sound ("misc/trigger1.wav");
- self.noise = "misc/trigger1.wav";
- }
- else if (self.sounds == 4)
- {
- if (!self.noise1) //dumptruck_ds
- {
- objerror ("no soundfile set in noise1!\n");
- remove(self);
- return;
- }
- else
- precache_sound (self.noise1);
- self.noise = self.noise1;
- }
-
- InitTrigger();
- self.touch = onlookat_touch;
-
- SUB_CheckWaiting();
-};
-
-void() trigger_target_change_use =
-{
- if (self.estate != STATE_ACTIVE) return;
-
- for (entity e = world; (e = find(e, targetname, self.target)); )
- {
- if (!self.cnt || self.cnt == 1)
- {
- e.target = self.message;
- }
- else if (self.cnt == 2)
- {
- e.target2 = self.message;
- }
- else if (self.cnt == 3)
- {
- e.target3 = self.message;
- }
- else if (self.cnt == 4)
- {
- e.target4 = self.message;
- }
- }
-};
-
-
-/*QUAKED trigger_changetarget (.5 .5 .5) ?
-Changes an entity's target field
-
-target = entity to change
-message = new value for target field
-cnt = target field to change, null defaults to target
-
-*/
-void() trigger_changetarget =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = trigger_target_change_use;
-};
-
-
-
-
-/*
-=============================================================
-
-target_setstate
-
-=============================================================
-*/
-float SETSTATE_STARTOFF = 1;
-float SETSTATE_CLOSEALLDOORS = 2;
-float SETSTATE_DONTRESETBUTTON = 4;
-
-float(entity e) entity_get_state = {
- if(e.classname == "func_door") return e.owner.estate;
- else return e.estate;
-};
-
-void(entity e, float state, float flags) entity_set_state = {
- float closealldoors;
-
- if(e.classname == "func_button") {
- if (state == STATE_ACTIVE) button_unlock(e, flags & SETSTATE_DONTRESETBUTTON);
- else button_lock(e);
- }
- else if(e.classname == "func_door") {
- if (flags & SETSTATE_CLOSEALLDOORS) closealldoors = 1;
-
- if (state == STATE_ACTIVE) door_estate_unlock(e, closealldoors);
- else door_estate_lock(e, closealldoors);
- }
- else e.estate = state;
-
- if (e.is_waiting > 0 && state == STATE_ACTIVE) {
- SUB_CallAsSelf(SUB_EndWaiting, e);
- }
-
- //if (e.touch && e.touch != SUB_Null) {
- // force_retouch = 2;
- //}
-};
-
-void(string matchstring, .string matchfield, float state, float flags) target_setstate_set_target = {
- local entity t;
-
- t = find (world, matchfield, matchstring);
- while (t != world) {
- if(state == -1){
- if(entity_get_state(t) == STATE_ACTIVE) entity_set_state(t, STATE_INACTIVE, flags);
- else entity_set_state(t, STATE_ACTIVE, flags);
- }
- else entity_set_state(t, state, flags);
-
- t = find (t, matchfield, matchstring);
- }
-};
-
-void(float state) target_setstate_set_alltargets = {
- if (self.target && self.target != "") {
- target_setstate_set_target(self.target, targetname, state, self.spawnflags);
- target_setstate_set_target(self.target, targetname2, state, self.spawnflags);
- target_setstate_set_target(self.target, targetname3, state, self.spawnflags);
- target_setstate_set_target(self.target, targetname4, state, self.spawnflags);
- }
- if (self.target2 && self.target2 != "") {
- target_setstate_set_target(self.target2, targetname, state, self.spawnflags);
- target_setstate_set_target(self.target2, targetname2, state, self.spawnflags);
- target_setstate_set_target(self.target2, targetname3, state, self.spawnflags);
- target_setstate_set_target(self.target2, targetname4, state, self.spawnflags);
- }
- if (self.target3 && self.target3 != "") {
- target_setstate_set_target(self.target3, targetname, state, self.spawnflags);
- target_setstate_set_target(self.target3, targetname2, state, self.spawnflags);
- target_setstate_set_target(self.target3, targetname3, state, self.spawnflags);
- target_setstate_set_target(self.target3, targetname4, state, self.spawnflags);
- }
- if (self.target4 && self.target4 != "") {
- target_setstate_set_target(self.target4, targetname, state, self.spawnflags);
- target_setstate_set_target(self.target4, targetname2, state, self.spawnflags);
- target_setstate_set_target(self.target4, targetname3, state, self.spawnflags);
- target_setstate_set_target(self.target4, targetname4, state, self.spawnflags);
- }
-};
-
-void() target_setstate_use = {
- local float state;
-
- if (self.style == 1) state = STATE_ACTIVE;
- else if (self.style == 2) state = STATE_INACTIVE;
- else state = -1;
-
- target_setstate_set_alltargets(state);
-
-};
-
-void() target_setstate_startoff_think = {
- target_setstate_set_alltargets(STATE_INACTIVE);
-};
-
-void() target_setstate = {
- self.use = target_setstate_use;
-
- if(self.spawnflags & SETSTATE_STARTOFF) {
- // wait a bit while doors finish being set up
- self.think = target_setstate_startoff_think;
- self.nextthink = time + 0.2;
- }
-};
-
-
-
-
-/*
-=============================================================
-
-trigger_filter
-
-=============================================================
-*/
-
-
-float FILTER_FIELD_STATE = 0;
-float FILTER_FIELD_HEALTH = 1;
-float FILTER_FIELD_WEAPON = 2;
-float FILTER_FIELD_FLAGS = 3;
-float FILTER_FIELD_SPAWNFLAGS = 4;
-float FILTER_FIELD_CLASSNAME = 5;
-float FILTER_FIELD_ESTATE = 6;
-float FILTER_FIELD_TARGETNAME = 8;
-float FILTER_FIELD_ITEMS = 10;
-float FILTER_FIELD_COUNT = 11;
-float FILTER_FIELD_CNT = 12;
-float FILTER_FIELD_TYPE = 13;
-
-
-float FILTER_FIELDTYPE_FLOAT = 0;
-float FILTER_FIELDTYPE_STRING = 1;
-float FILTER_FIELDTYPE_FLAG = 2;
-
-float FILTER_OP_EQUALS = 0;
-float FILTER_OP_LT = 1;
-float FILTER_OP_LTE = 2;
-float FILTER_OP_GT = 3;
-float FILTER_OP_GTE = 4;
-float FILTER_OP_BITMASK_AND = 5;
-float FILTER_OP_BITMASK_OR = 6;
-
-void() trigger_filter_use = {
- self.state = 0;
-
- if (self.estate != STATE_ACTIVE) return;
-
- entity targ;
- float targfloat;
- string targstring;
-
- float fieldtype, op, result;
-
- if (self.include != "") {
- targ = find(world, targetname, self.include);
- if (!targ) targ = find(world, targetname2, self.include);
- if (!targ) return;
- }
- else
- targ = activator;
-
- op = self.weapon;
-
- switch (self.style) {
- case FILTER_FIELD_STATE:
- fieldtype = FILTER_FIELDTYPE_FLOAT;
- targfloat = targ.state;
- break;
-
- case FILTER_FIELD_ESTATE:
- fieldtype = FILTER_FIELDTYPE_FLOAT;
- targfloat = targ.estate;
- break;
-
- case FILTER_FIELD_HEALTH:
- fieldtype = FILTER_FIELDTYPE_FLOAT;
- targfloat = targ.health;
- break;
-
- case FILTER_FIELD_COUNT:
- fieldtype = FILTER_FIELDTYPE_FLOAT;
- targfloat = targ.count;
- break;
-
- case FILTER_FIELD_CNT:
- fieldtype = FILTER_FIELDTYPE_FLOAT;
- targfloat = targ.cnt;
- break;
-
- case FILTER_FIELD_WEAPON:
- fieldtype = FILTER_FIELDTYPE_FLOAT;
- targfloat = targ.weapon;
- break;
-
- case FILTER_FIELD_FLAGS:
- fieldtype = FILTER_FIELDTYPE_FLAG;
- targfloat = targ.flags;
- break;
-
- case FILTER_FIELD_SPAWNFLAGS:
- fieldtype = FILTER_FIELDTYPE_FLAG;
- targfloat = targ.spawnflags;
- break;
-
- case FILTER_FIELD_ITEMS:
- fieldtype = FILTER_FIELDTYPE_FLAG;
- targfloat = targ.items;
- break;
-
- case FILTER_FIELD_CLASSNAME:
- fieldtype = FILTER_FIELDTYPE_STRING;
- targstring = targ.classname;
- break;
-
- case FILTER_FIELD_TARGETNAME:
- fieldtype = FILTER_FIELDTYPE_STRING;
- targstring = targ.targetname;
- break;
-
- case FILTER_FIELD_TYPE:
- fieldtype = FILTER_FIELDTYPE_STRING;
- targstring = targ.type;
- break;
- }
-
- if (fieldtype == FILTER_FIELDTYPE_FLOAT) {
- if (op == FILTER_OP_EQUALS) {if (targfloat == self.count) result = 1;}
- else if (op == FILTER_OP_LT) {if (targfloat < self.count) result = 1;}
- else if (op == FILTER_OP_LTE) {if (targfloat <= self.count) result = 1;}
- else if (op == FILTER_OP_GT) {if (targfloat > self.count) result = 1;}
- else if (op == FILTER_OP_GTE) {if (targfloat >= self.count) result = 1;}
- else if (op == FILTER_OP_BITMASK_AND) {if (targfloat & self.count) result = 1;}
- else if (op == FILTER_OP_BITMASK_OR) {if (targfloat | self.count) result = 1;}
- else {if (targfloat == self.count) result = 1;}
- }
- else if (fieldtype == FILTER_FIELDTYPE_FLAG) {
- if (op == FILTER_OP_EQUALS) {if (targfloat == self.aflag) result = 1;}
- else if (op == FILTER_OP_BITMASK_AND) {if (targfloat & self.aflag) result = 1;}
- else if (op == FILTER_OP_BITMASK_OR) {if (targfloat | self.aflag) result = 1;}
- else {if (targfloat == self.aflag) result = 1;}
- }
- else if (fieldtype == FILTER_FIELDTYPE_STRING) {
-
- if (targstring == self.type) result = 1;
- }
- else {
- objerror ("invalid fieldtype");
- return;
- }
-
- if (self.spawnflags & 1) result = 1 - result; // negate
-
- if (result) {
- self.state = 1;
-
- if (self.spawnflags & 2 && activator.owner) activator = activator.owner; // relay activator as owner
-
- SUB_UseTargets();
- if (other.classname == "trigger_everything" && other.spawnflags & 1) {
- if (other.wait) other.attack_finished = time + other.wait;
- }
-
- }
-};
-
-void() trigger_filter = {
- self.use = trigger_filter_use;
-
-};
-
-
-/*
-=============================================================
-
-trigger_everything
-
-=============================================================
-*/
-
-void() trigger_everything_touch = {
- if (self.estate != STATE_ACTIVE) return;
-
- if (time < self.attack_finished) return;
-
- activator = other;
-
- SUB_UseSpecificTarget(self.target, targetname);
-
- if (self.wait)
- if (!(self.spawnflags & 1)) self.attack_finished = time + self.wait;
-
-};
-
-void() trigger_everything = {
- InitTrigger();
-
- self.touch = trigger_everything_touch;
- SUB_CheckWaiting();
-};
-
-
-/*
-=============================================================
-
-target_setcount
-
-=============================================================
-*/
-
-void(string name, .string fld) target_setcount_set = {
- local entity t;
-
- t = find(world, fld, name);
-
- while (t) {
- if (self.style == 1)
- t.count += self.count;
- else
- t.count = self.count;
-
- t = find(t, fld, name);
- }
-};
-
-void() target_setcount_use = {
- if (self.target && self.target != "") {
- target_setcount_set(self.target, targetname);
- target_setcount_set(self.target, targetname2);
- target_setcount_set(self.target, targetname3);
- target_setcount_set(self.target, targetname4);
- }
- if (self.target2 && self.target2 != "") {
- target_setcount_set(self.target2, targetname);
- target_setcount_set(self.target2, targetname2);
- target_setcount_set(self.target2, targetname3);
- target_setcount_set(self.target2, targetname4);
- }
- if (self.target3 && self.target3 != "") {
- target_setcount_set(self.target3, targetname);
- target_setcount_set(self.target3, targetname2);
- target_setcount_set(self.target3, targetname3);
- target_setcount_set(self.target3, targetname4);
- }
- if (self.target4 && self.target4 != "") {
- target_setcount_set(self.target4, targetname);
- target_setcount_set(self.target4, targetname2);
- target_setcount_set(self.target4, targetname3);
- target_setcount_set(self.target4, targetname4);
- }
-
- if (self.spawnflags & 1) {
- if (self.style == 1)
- activator.count += activator.count;
- else
- activator.count = activator.count;
- }
-};
-
-void() target_setcount = {
- self.use = target_setcount_use;
-
-};
-
-void() trigger_monsterface_touch =
-{
- // only affect ground monsters
- if ( other.flags & (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER )
- return;
-
- if (!visibleToOther(other.enemy)) { // enemy is hidden
- other.t_length = time + self.wait + 0.2; // don't dodge around, just go straight
- other.ideal_yaw = self.angles_y; // face where I want
- }
-}
-
-void() trigger_monsterface_init =
-{
- self.solid = SOLID_TRIGGER;
- setmodel (self, self.model); // set size and link into world
- self.movetype = MOVETYPE_NONE;
- self.modelindex = 0;
- self.model = "";
-
- if (self.angles == '0 0 0')
- self.angles = '0 360 0';
-
- self.touch = trigger_monsterface_touch;
-}
-
-/*QUAKED trigger_monsterface (.5 .0 .5)
-Running monsters that do not see their target and touch this will face in the direction of the trigger's angle instead of the unseen target.
-Use this trigger to make monsters leave their sniping spot and execute complex maneuvers.
-
-Keys:
-"angle" absolute angle in which the monster should face
-"targetname" entity name
-"wait" time to wait between retriggers
-*/
-void() trigger_monsterface =
-{
- if (SUB_Inhibit())
- return;
-
- trigger_monsterface_init();
- // InitTrigger();
-}

Return to the top of this page or return to the overview of this repo.

Diff qc-server/utility.qc

diff --git a/qc-server/utility.qc b/qc-server/utility.qc
deleted file mode 100644
index 7e98b90..0000000
--- a/qc-server/utility.qc
+++ /dev/null
@@ -1,218 +0,0 @@
-void(string s, string ss) dprint2 =
- { dprint(s); dprint(ss); }
-void(string s, string ss, string sss) dprint3 =
- { dprint(s); dprint(ss); dprint(sss); }
-void(string s, string ss, string sss, string ssss) dprint4 =
- { dprint(s); dprint(ss); dprint(sss); dprint(ssss); }
-void(string s, string ss, string sss, string ssss, string sssss) dprint5 =
- { dprint(s); dprint(ss); dprint(sss); dprint(ssss); dprint(sssss); }
-void(string s, string ss, string sss, string ssss, string sssss, string ssssss) dprint6 =
- { dprint(s); dprint(ss); dprint(sss); dprint(ssss); dprint(sssss); dprint(ssssss);}
-void(string s, string ss, string sss, string ssss, string sssss, string ssssss, string sssssss) dprint7 =
- { dprint(s); dprint(ss); dprint(sss); dprint(ssss); dprint(sssss); dprint(ssssss); dprint(sssssss);}
-void(string s, string ss, string sss, string ssss, string sssss, string ssssss, string sssssss, string ssssssss) dprint8 =
- { dprint(s); dprint(ss); dprint(sss); dprint(ssss); dprint(sssss); dprint(ssssss); dprint(sssssss); dprint(ssssssss); }
-void(string s, string ss, string sss, string ssss, string sssss, string ssssss, string sssssss, string ssssssss, string sssssssss) dprint9 =
- { dprint(s); dprint(ss); dprint(sss); dprint(ssss); dprint(sssss); dprint(ssssss); dprint(sssssss); dprint(ssssssss); dprint(sssssssss); }
-
-/**********************************
- Sourced from utility.qc from smej2
- **********************************/
-
-
-float(float in) bprint_int =
-{
- in = floor(in);
- if (in <= 0) return 0;
-
- float digit;
- digit = in - bprint_int(in / 10);
-
- switch(digit) {
- case 9:
- bprint("9"); break;
- case 8:
- bprint("8"); break;
- case 7:
- bprint("7"); break;
- case 6:
- bprint("6"); break;
- case 5:
- bprint("5"); break;
- case 4:
- bprint("4"); break;
- case 3:
- bprint("3"); break;
- case 2:
- bprint("2"); break;
- case 1:
- bprint("1"); break;
- case 0:
- bprint("0"); break;
- }
-
- return in * 10;
-}
-
-
-float(float in, float def) defaultFl = {
- if (in) return in;
- else return def;
-}
-
-
-// shorthand for turning -1 to 0 for keyvalues for which 0 is a valid non-default selection
-float(float in) zeroconvert =
-{
- if (in == -1) return 0;
- return in;
-}
-float(float in, float def) zeroconvertdefault =
-{
- if (in == -1) return 0;
- if (in == 0) return def;
- return in;
-}
-
-
-
-
-// for measuring how large an entity is along an arbitrary vector
-// FIXME: this is trash and it returns trash
-float(vector v, vector s) BoundsAngleSize =
-{
- v_x = fabs(v_x);
- v_y = fabs(v_y);
- v_z = fabs(v_z);
-
- // size is always + + + but this is in case I switch the parameters somewhere
- s_x = fabs(s_x);
- s_y = fabs(s_y);
- s_z = fabs(s_z);
-
- return v * s;
-}
-
-//count -4 = numclients in coop
-/*void(.float fld) playercount_convert =
-{
- if (self.fld != -4) return;
- if (!coop)
- self.fld = 1;
- else
- self.fld = clients;
-}
-*/
-
-
-// wonderful stuffcmd code from Honey by czg
-
-/*
-=============
-stuffcmd_float
-
-This is a horrible hack that I am ashamed of!
-===============
-*/
-void stuffcmd_digit( entity client, float f) =
-{
- float d;
- d = floor(f);
- d = mod(d, 10);
-
- //CLOSE YOUR EYES, HONEY! DON'T LOOK!
- if(d == 0)
- stuffcmd(client, "0");
- else if(d == 1)
- stuffcmd(client, "1");
- else if(d == 2)
- stuffcmd(client, "2");
- else if(d == 3)
- stuffcmd(client, "3");
- else if(d == 4)
- stuffcmd(client, "4");
- else if(d == 5)
- stuffcmd(client, "5");
- else if(d == 6)
- stuffcmd(client, "6");
- else if(d == 7)
- stuffcmd(client, "7");
- else if(d == 8)
- stuffcmd(client, "8");
- else if(d == 9)
- stuffcmd(client, "9");
-}
-
-void stuffcmd_int( entity client, float f, float numdigits) =
-{
-
- float tmp;
-
-
- if(f == 0)
- {
- stuffcmd( client, "0");
- return;
- }
-
- if(f < 0)
- {
- // Yeah sure.
- stuffcmd( client, "-");
- f = fabs(f);
- }
-
- if(numdigits <= 0)
- {
- tmp = f;
- numdigits = 1;
- while(tmp >= 1){
- tmp = tmp / 10;
- numdigits = numdigits * 10;
- }
- }
-
- //I don't know what I'm thinking here...
- //I need to do this to get zero-padding to work.
-
- while( numdigits > 1 )
- {
- numdigits = numdigits / 10;
- tmp = f / numdigits;
- stuffcmd_digit( client, tmp);
- }
-}
-
-void stuffcmd_float( entity client, float f) =
-{
- float intpart, decpart, isNegative;
-
- isNegative = FALSE;
-
- if(f == 0)
- {
- stuffcmd( client, "0");
- return;
- }
-
- if(f < 0)
- {
- // easier this way
- isNegative = TRUE;
- f = fabs(f);
- }
-
- // 1: stuff the integer part.
- intpart = floor(f);
- if(isNegative)
- stuffcmd( client, "-");
- stuffcmd_int( client, intpart, 0);
-
- // 2: stuff the decimal point.
- stuffcmd( client, ".");
-
- // 3: stuff the decimal part.
- decpart = mod( f, 1);
- decpart = decpart * 10000;
- stuffcmd_int( client, decpart, 10000);
-}

Return to the top of this page or return to the overview of this repo.

Diff qc-server/weapons.qc

diff --git a/qc-server/weapons.qc b/qc-server/weapons.qc
deleted file mode 100644
index 8dacf7b..0000000
--- a/qc-server/weapons.qc
+++ /dev/null
@@ -1,1807 +0,0 @@
-/*
-*/
-void (entity targ, entity inflictor, entity attacker, float damage) T_Damage;
-void () player_run;
-void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
-void(vector org, vector vel, float damage) SpawnBlood;
-void() SuperDamageSound;
-void() create_mobot; //dumptruck_ds mobot.qc
-void(entity mis, float speed) SetupHoming;
-
-void(entity mis, vector dir, float speed) SetSpeed =
-{
- if (cvar("sv_maxvelocity") > speed)
- {
- mis.velocity = dir * speed;
- }
- else {
- mis.velocity = dir * cvar("sv_maxvelocity");
- }
-};
-
-// called by worldspawn
-void() W_Precache =
-{
- precache_sound ("weapons/r_exp3.wav"); // new rocket explosion
- precache_sound ("weapons/rocket1i.wav"); // spike gun
- precache_sound ("weapons/sgun1.wav");
- precache_sound ("weapons/guncock.wav"); // player shotgun
- precache_sound ("weapons/ric1.wav"); // ricochet (used in c code)
- precache_sound ("weapons/ric2.wav"); // ricochet (used in c code)
- precache_sound ("weapons/ric3.wav"); // ricochet (used in c code)
- precache_sound ("weapons/spike2.wav"); // super spikes
- precache_sound ("weapons/tink1.wav"); // spikes tink (used in c code)
- precache_sound ("weapons/grenade.wav"); // grenade launcher
- precache_sound ("weapons/bounce.wav"); // grenade bounce
- precache_sound ("weapons/shotgn2.wav"); // super shotgun
-
-// dumptruck_ds mobot.qc precaches START
-
- precache_model ("progs/ogre.mdl");
- precache_model ("progs/h_ogre.mdl");
- precache_model ("progs/grenade.mdl");
- precache_sound ("ogre/ogdrag.wav");
- precache_sound ("ogre/ogdth.wav");
- precache_sound ("ogre/ogidle.wav");
- precache_sound ("ogre/ogidle2.wav");
- precache_sound ("ogre/ogpain1.wav");
- precache_sound ("ogre/ogsawatk.wav");
- precache_sound ("ogre/ogwake.wav");
-
- precache_model ("progs/demon.mdl");
- precache_model ("progs/h_demon.mdl");
-
- precache_sound ("demon/ddeath.wav");
- precache_sound ("demon/dhit2.wav");
- precache_sound ("demon/djump.wav");
- precache_sound ("demon/dpain1.wav");
- precache_sound ("demon/idle1.wav");
- precache_sound ("demon/sight2.wav");
-
- precache_model2 ("progs/enforcer.mdl");
- precache_model2 ("progs/h_mega.mdl");
- precache_model2 ("progs/laser.mdl");
- precache_model2 ("progs/s_spike.mdl");
-
- precache_sound2 ("enforcer/death1.wav");
- precache_sound2 ("enforcer/enfire.wav");
- precache_sound2 ("enforcer/enfstop.wav");
- precache_sound2("enforcer/idle1.wav");
- precache_sound2 ("enforcer/pain1.wav");
- precache_sound2 ("enforcer/pain2.wav");
- precache_sound2 ("enforcer/sight1.wav");
- precache_sound2 ("enforcer/sight2.wav");
- precache_sound2 ("enforcer/sight3.wav");
- precache_sound2("enforcer/sight4.wav");
-
- precache_model ("progs/soldier.mdl");
- precache_model ("progs/h_guard.mdl");
-
- precache_model ("progs/gib1.mdl");
- precache_model ("progs/gib2.mdl");
- precache_model ("progs/gib3.mdl");
-
- precache_sound ("soldier/death1.wav");
- precache_sound ("soldier/idle.wav");
- precache_sound ("soldier/pain1.wav");
- precache_sound ("soldier/pain2.wav");
- precache_sound ("soldier/sattck1.wav");
- precache_sound ("soldier/sight1.wav");
- precache_sound ("player/udeath.wav"); // gib death
-
- precache_model ("progs/h_dog.mdl");
- precache_model ("progs/dog.mdl");
- precache_sound ("dog/dattack1.wav");
- precache_sound("dog/ddeath.wav");
- precache_sound ("dog/dpain1.wav");
- precache_sound ("dog/dsight.wav");
- precache_sound ("dog/idle.wav");
-
- precache_model ("progs/wizard.mdl");
- precache_model ("progs/h_wizard.mdl");
- precache_model ("progs/w_spike.mdl");
-
- precache_sound ("wizard/hit.wav"); // used by c code
- precache_sound ("wizard/wattack.wav");
- precache_sound ("wizard/wdeath.wav");
- precache_sound ("wizard/widle1.wav");
- precache_sound ("wizard/widle2.wav");
- precache_sound ("wizard/wpain.wav");
- precache_sound ("wizard/wsight.wav");
-
- precache_model2 ("progs/shalrath.mdl");
- precache_model2 ("progs/h_shal.mdl");
- precache_model2 ("progs/v_spike.mdl");
-
- precache_sound2 ("shalrath/attack.wav");
- precache_sound2 ("shalrath/attack2.wav");
- precache_sound2 ("shalrath/death.wav");
- precache_sound2 ("shalrath/idle.wav");
- precache_sound2 ("shalrath/pain.wav");
- precache_sound2 ("shalrath/sight.wav");
-
- precache_model ("progs/knight.mdl");
- precache_model ("progs/h_knight.mdl");
-
- precache_sound ("knight/kdeath.wav");
- precache_sound ("knight/khurt.wav");
- precache_sound ("knight/ksight.wav");
- precache_sound ("knight/sword1.wav");
- precache_sound ("knight/sword2.wav");
- precache_sound ("knight/idle.wav");
-
- precache_model2 ("progs/hknight.mdl");
- precache_model2 ("progs/k_spike.mdl");
- precache_model2 ("progs/k_spike2.mdl");
- precache_model2 ("progs/h_hellkn.mdl");
- precache_model2 ("progs/hknight.mdl");
- precache_model2 ("progs/h_hellkn.mdl");
- precache_model2 ("progs/k_spike.mdl");
-
- precache_sound2 ("hknight/attack1.wav");
- precache_sound2 ("hknight/death1.wav");
- precache_sound2 ("hknight/pain1.wav");
- precache_sound2 ("hknight/sight1.wav");
- precache_sound ("hknight/hit.wav"); // used by C code, so don't sound2
- precache_sound2 ("hknight/slash1.wav");
- precache_sound2 ("hknight/idle.wav");
- precache_sound2 ("hknight/grunt.wav");
- precache_sound ("knight/sword1.wav");
- precache_sound ("knight/sword2.wav");
-
- precache_sound2 ("blob/death1.wav");
- precache_sound2 ("blob/hit1.wav");
- precache_sound2 ("blob/land1.wav");
- precache_sound2 ("blob/sight1.wav");
-
- precache_model ("progs/zombie.mdl");
- precache_model ("progs/h_zombie.mdl");
- precache_model ("progs/zom_gib.mdl");
-
- precache_sound ("zombie/z_idle.wav");
- precache_sound ("zombie/z_idle1.wav");
- precache_sound ("zombie/z_shot1.wav");
- precache_sound ("zombie/z_gib.wav");
- precache_sound ("zombie/z_pain.wav");
- precache_sound ("zombie/z_pain1.wav");
- precache_sound ("zombie/z_fall.wav");
- precache_sound ("zombie/z_miss.wav");
- precache_sound ("zombie/z_hit.wav");
- precache_sound ("zombie/idle_w2.wav");
-
- precache_model ("progs/shambler.mdl");
- precache_model ("progs/s_light.mdl");
- precache_model ("progs/h_shams.mdl");
- precache_model ("progs/bolt.mdl");
-
- precache_sound ("shambler/sattck1.wav");
- precache_sound ("shambler/sboom.wav");
- precache_sound ("shambler/sdeath.wav");
- precache_sound ("shambler/shurt2.wav");
- precache_sound ("shambler/sidle.wav");
- precache_sound ("shambler/ssight.wav");
- precache_sound ("shambler/melee1.wav");
- precache_sound ("shambler/melee2.wav");
- precache_sound ("shambler/smack.wav");
-
- // dumptruck_ds mobot.qc END
-};
-
-float() crandom =
-{
- return 2*(random() - 0.5);
-};
-
-/*
-================
-W_FireAxe
-================
-*/
-void() W_FireAxe =
-{
- local vector source;
- local vector org;
-
- makevectors (self.v_angle);
- source = self.origin + '0 0 16';
- traceline (source, source + v_forward*64, FALSE, self);
- if (trace_fraction == 1.0)
- return;
- org = trace_endpos - v_forward*4;
-
- if (trace_ent.takedamage)
- {
- trace_ent.axhitme = 1;
- SpawnBlood (org, '0 0 0', 20);
- T_Damage (trace_ent, self, self, 20);
- }
- else
- { // hit wall
- sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_GUNSHOT);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
- }
-};
-
-
-//============================================================================
-
-
-vector() wall_velocity =
-{
- local vector vel;
-
- vel = normalize (self.velocity);
- vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
- vel = vel + 2*trace_plane_normal;
- vel = vel * 200;
-
- return vel;
-};
-
-
-/*
-================
-SpawnMeatSpray
-================
-*/
-void(vector org, vector vel) SpawnMeatSpray =
-{
- local entity missile;
-
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_NOT;
-
- makevectors (self.angles);
-
- missile.velocity = vel;
- missile.velocity_z = missile.velocity_z + 250 + 50*random();
-
- missile.avelocity = '3000 1000 2000';
-
-// set missile duration
- missile.nextthink = time + 1;
- missile.think = SUB_Remove;
-
- setmodel (missile, "progs/zom_gib.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, org);
-};
-
-/*
-================
-SpawnBlood
-================
-*/
-void(vector org, vector vel, float damage) SpawnBlood =
-{
- particle (org, vel*0.1, 73, damage*2);
-};
-
-/*
-================
-spawn_touchblood
-================
-*/
-void(float damage) spawn_touchblood =
-{
- local vector vel;
-
- vel = wall_velocity () * 0.2;
- SpawnBlood (self.origin + vel*0.01, vel, damage);
-};
-
-
-/*
-================
-SpawnChunk
-================
-*/
-void(vector org, vector vel) SpawnChunk =
-{
- particle (org, vel*0.02, 0, 10);
-};
-
-/*
-==============================================================================
-
-MULTI-DAMAGE
-
-Collects multiple small damages into a single damage
-
-==============================================================================
-*/
-
-entity multi_ent;
-float multi_damage;
-
-void() ClearMultiDamage =
-{
- multi_ent = world;
- multi_damage = 0;
-};
-
-void() ApplyMultiDamage =
-{
- if (!multi_ent)
- return;
- T_Damage (multi_ent, self, self, multi_damage);
-};
-
-void(entity hit, float damage) AddMultiDamage =
-{
- if (!hit)
- return;
-
- if (hit != multi_ent)
- {
- ApplyMultiDamage ();
- multi_damage = damage;
- multi_ent = hit;
- }
- else
- multi_damage = multi_damage + damage;
-};
-
-/*
-==============================================================================
-
-BULLETS
-
-==============================================================================
-*/
-
-/*
-================
-TraceAttack
-================
-*/
-void(float damage, vector dir) TraceAttack =
-{
- local vector vel, org;
-
- vel = normalize(dir + v_up*crandom() + v_right*crandom());
- vel = vel + 2*trace_plane_normal;
- vel = vel * 200;
-
- org = trace_endpos - dir*4;
-
- if (trace_ent.takedamage)
- {
- SpawnBlood (org, vel*0.2, damage);
- AddMultiDamage (trace_ent, damage);
- }
- else
- {
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_GUNSHOT);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
- }
-};
-
-/*
-================
-FireBullets
-
-Used by shotgun, super shotgun, and enemy soldier firing
-Go to the trouble of combining multiple pellets into a single damage call.
-================
-*/
-void(float shotcount, vector dir, vector spread) FireBullets =
-{
- local vector direction;
- local vector src;
-
- makevectors(self.v_angle);
-
- src = self.origin + v_forward*10;
- src_z = self.absmin_z + self.size_z * 0.7;
-
- ClearMultiDamage ();
- while (shotcount > 0)
- {
- direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up;
-
- traceline (src, src + direction*2048, FALSE, self);
- if (trace_fraction != 1.0)
- TraceAttack (4, direction);
-
- shotcount = shotcount - 1;
- }
- ApplyMultiDamage ();
-};
-
-/*
-================
-W_FireShotgun
-================
-*/
-void() W_FireShotgun =
-{
- local vector dir;
-
- sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);
-
- self.punchangle_x = -2;
-
- self.currentammo = self.ammo_shells = self.ammo_shells - 1;
- dir = aim (self, 100000);
- FireBullets (6, dir, '0.04 0.04 0');
-};
-
-
-/*
-================
-W_FireSuperShotgun
-================
-*/
-void() W_FireSuperShotgun =
-{
- local vector dir;
-
- if (self.currentammo == 1)
- {
- W_FireShotgun ();
- return;
- }
-
- sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);
-
- self.punchangle_x = -4;
-
- self.currentammo = self.ammo_shells = self.ammo_shells - 2;
- dir = aim (self, 100000);
- FireBullets (14, dir, '0.14 0.08 0');
-};
-
-
-/*
-==============================================================================
-
-ROCKETS
-
-==============================================================================
-*/
-
-void() s_explode1 = [0, s_explode2] {};
-void() s_explode2 = [1, s_explode3] {};
-void() s_explode3 = [2, s_explode4] {};
-void() s_explode4 = [3, s_explode5] {};
-void() s_explode5 = [4, s_explode6] {};
-void() s_explode6 = [5, SUB_Remove] {};
-
-void() BecomeExplosion =
-{
- self.movetype = MOVETYPE_NONE;
- self.velocity = '0 0 0';
- self.touch = SUB_Null;
- setmodel (self, "progs/s_explod.spr");
- self.solid = SOLID_NOT;
- s_explode1 ();
-};
-
-void() T_MissileTouch =
-{
- local float damg;
-
- if (other == self.owner)
- return; // don't explode on owner
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
- damg = 100 + random()*20;
-
- if (other.health)
- {
- if (other.classname == "monster_shambler")
- damg = damg * 0.5; // mostly immune
- T_Damage (other, self, self.owner, damg );
- }
-
- // don't do radius damage to the other, because all the damage
- // was done in the impact
- T_RadiusDamage (self, self.owner, 120, other);
-
-// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
- self.origin = self.origin - 8*normalize(self.velocity);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- BecomeExplosion ();
-
-};
-//dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
-
-void(float direct, float splash) T_MonsterMisTouch =
-{
- local float damg;
-
- if (other == self.owner)
- return; // don't explode on owner
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
- damg = direct + random()*2; //dumptruck_ds
-
- if (other.health)
- {
- if (other.classname == "monster_shambler")
- damg = damg * 0.5; // mostly immune
- T_Damage (other, self, self.owner, damg );
- }
-
- // don't do radius damage to the other, because all the damage
- // was done in the impact
- T_RadiusDamage (self, self.owner, splash, other); //dumptruck_ds
-
-// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
- self.origin = self.origin - 8*normalize(self.velocity);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- BecomeExplosion ();
-};
-
-void() T_GruntMisTouch =
-{
- T_MonsterMisTouch(30, 40);
-};
-
- // less direct damage, more splash than grunt
- // TODO: add damage modifier
-void() T_HellKnightMisTouch =
-{
- T_MonsterMisTouch(20, 50);
-};
-
-// big damage. explody scrag should be beefy.
-// TODO: add damage modifier
-void() T_WizardMisTouch =
-{
- T_MonsterMisTouch(50, 50);
-};
-//dumptruck_ds end
-
-/*
-================
-W_FireRocket
-================
-*/
-void() W_FireRocket =
-{
- local entity missile;
-
- self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
-
- sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
-
- self.punchangle_x = -2;
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_FLYMISSILE;
- missile.solid = SOLID_BBOX;
- missile.classname = "missile";
-
-// set missile speed
-
- makevectors (self.v_angle);
- missile.velocity = aim(self, 1000);
- missile.velocity = missile.velocity * 1000;
- missile.angles = vectoangles(missile.velocity);
-
- missile.touch = T_MissileTouch;
-
-// set missile duration
- missile.nextthink = time + 5;
- missile.think = SUB_Remove;
-
- setmodel (missile, "progs/missile.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + v_forward*8 + '0 0 16');
-};
-/*
-================
-W_GruntRocket //dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
-================
-*/
-void() W_GruntRocket =
-{
- local entity missile;
-
- // self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; dumptruck_ds
-
- sound_attack (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
-
- self.punchangle_x = -2;
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_FLYMISSILE;
- missile.solid = SOLID_BBOX;
- missile.classname = "missile";
-
-// set missile speed -- dumptruck_ds below
-
- missile.velocity = normalize(self.enemy.origin - self.origin);
- SetSpeed(missile, missile.velocity, 900*self.proj_speed_mod);
- missile.angles = vectoangles(missile.velocity);
- missile.touch = T_GruntMisTouch;
-
- // makevectors (self.v_angle);
- // missile.velocity = aim(self, 1000);
- // missile.velocity = missile.velocity * 1000;
- // missile.angles = vectoangles(missile.velocity);
-
- // missile.touch = T_MissileTouch;
-
-// set missile duration
- if (self.homing > 0)
- {
- SetupHoming(missile, 900 * self.proj_speed_mod);
- }
- else {
- missile.nextthink = time + 5;
- missile.think = SUB_Remove;
- }
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/missile.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-// dumptruck_ds - end
-
- // setmodel (missile, "progs/missile.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
- setorigin (missile, self.origin + v_forward * 30 + v_right * 5 + '0 0 12');
- // setorigin (missile, self.origin + v_forward*8 + '0 0 16');
-};
-
-//end dumptruck_ds grunt missle end
-
-/*
-===============================================================================
-
-LIGHTNING
-
-===============================================================================
-*/
-
-/*
-=================
-LightningDamage
-=================
-*/
-void(vector p1, vector p2, entity from, float damage) LightningDamage =
-{
- local entity e1, e2;
- local vector f;
-
- f = p2 - p1;
- normalize (f);
- f_x = 0 - f_y;
- f_y = f_x;
- f_z = 0;
- f = f*16;
-
- e1 = e2 = world;
-
- traceline (p1, p2, FALSE, self);
- if (trace_ent.takedamage)
- {
- particle (trace_endpos, '0 0 100', 225, damage*4);
- T_Damage (trace_ent, from, from, damage);
- if (self.classname == "player")
- {
- if (other.classname == "player")
- trace_ent.velocity_z = trace_ent.velocity_z + 400;
- }
- }
- e1 = trace_ent;
-
- traceline (p1 + f, p2 + f, FALSE, self);
- if (trace_ent != e1 && trace_ent.takedamage)
- {
- particle (trace_endpos, '0 0 100', 225, damage*4);
- T_Damage (trace_ent, from, from, damage);
- }
- e2 = trace_ent;
-
- traceline (p1 - f, p2 - f, FALSE, self);
- if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
- {
- particle (trace_endpos, '0 0 100', 225, damage*4);
- T_Damage (trace_ent, from, from, damage);
- }
-};
-
-
-void() W_FireLightning =
-{
- local vector org;
- local float cells;
-
- if (self.ammo_cells < 1)
- {
- self.weapon = W_BestWeapon ();
- W_SetCurrentAmmo ();
- return;
- }
-
-// explode if under water
- if (self.waterlevel > 1)
- {
- cells = self.ammo_cells;
- self.ammo_cells = 0;
- W_SetCurrentAmmo ();
- T_RadiusDamage (self, self, 35*cells, world);
- return;
- }
-
- if (self.t_width < time)
- {
- sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
- self.t_width = time + 0.6;
- }
- self.punchangle_x = -2;
-
- self.currentammo = self.ammo_cells = self.ammo_cells - 1;
-
- org = self.origin + '0 0 16';
-
- traceline (org, org + v_forward*600, TRUE, self);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
- WriteEntity (MSG_BROADCAST, self);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
- WriteCoord (MSG_BROADCAST, trace_endpos_x);
- WriteCoord (MSG_BROADCAST, trace_endpos_y);
- WriteCoord (MSG_BROADCAST, trace_endpos_z);
-
- LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30);
-};
-
-
-//=============================================================================
-
-
-/*
-================
-GrenadeExplode2
-
-This is the same as the original GrenadeExplode function except that it
-will ignore the entity specified by the "ignore" parameter when dealing
-damage. -- iw
-================
-*/
-void(entity ignore) GrenadeExplode2 =
-{
- T_RadiusDamage (self, self.owner, 120, ignore);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- BecomeExplosion ();
-};
-
-
-/*
-================
-GrenadeExplode
-
-Refactored. -- iw
-================
-*/
-void() GrenadeExplode =
-{
- GrenadeExplode2 (world);
-};
-
-
-/*
-================
-GrenadeTouch
-
-This has been modified to fix a bug in the original code, which is that
-an entity with a very large bounding box (e.g. the size of monster_boss
-or monster_oldone) would receive little or no damage from a grenade
-impact. (In the original game, this bug didn't really matter because
-the largest DAMAGE_AIM entities were Shambler-sized.)
-
-In the original code, this function simply called GrenadeExplode, which
-called T_RadiusDamage, which deals an amount of damage based on the
-distance to the center of the victim's bounding box. Therefore, the
-larger the victim's bounding box, the lower the amount of damage that
-a grenade impact could deal.
-
-This modified version of GrenadeTouch adds a hack so that an entity
-which is larger than Shambler-size is treated differently: damage will
-be dealt to it using the same logic as a rocket impact, i.e. T_Damage
-will be called to deal damage to the impacted entity, and then radius
-damage will be dealt to any other entities in the vicinity. Grenades
-and rockets have always dealt the same amount of radius damage, so
-making the impact damage the same seemed a reasonable solution.
-
-The reason this logic is only used for very large entities is because
-I didn't want to affect the amount of damage that grenades deal to any
-of the original monsters under any circumstances. -- iw
-================
-*/
-void() GrenadeTouch =
-{
- local float damg;
-
- if (other == self.owner)
- return; // don't explode on owner
- if (other.takedamage == DAMAGE_AIM)
- {
- // see the explanation above -- iw
- if (other.size_x > VEC_HULL2_SIZE_x ||
- other.size_y > VEC_HULL2_SIZE_y ||
- other.size_z > VEC_HULL2_SIZE_z)
- {
- // note that the logic for monster_shambler's partial immunity
- // to explosions is not required because this is only for
- // entities which are larger than monster_shambler -- iw
- damg = 100 + random () * 20;
- T_Damage (other, self, self.owner, damg);
- GrenadeExplode2 (other);
- return;
- }
- GrenadeExplode ();
- return;
- }
- if (self.count < time) {
- sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
- }
- self.count = time + .02;
- if (self.velocity == '0 0 0')
- self.avelocity = '0 0 0';
-};
-
-
-/*
-================
-W_FireGrenade
-================
-*/
-void() W_FireGrenade =
-{
- local entity missile;
-
- self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
-
- sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
-
- self.punchangle_x = -2;
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
- missile.classname = "grenade";
-
-// set missile speed
-
- makevectors (self.v_angle);
-
- if (self.v_angle_x)
- missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
- else
- {
- missile.velocity = aim(self, 10000);
- missile.velocity = missile.velocity * 600;
- missile.velocity_z = 200;
- }
-
- missile.avelocity = '300 300 300';
-
- missile.angles = vectoangles(missile.velocity);
-
- missile.touch = GrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 2.5;
- missile.think = GrenadeExplode;
-
- setmodel (missile, "progs/grenade.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin);
-};
-
-
-//=============================================================================
-
-void() spike_touch;
-void() superspike_touch;
-
-
-/*
-===============
-launch_spike
-
-Used for both the player and the ogre
-===============
-*/
-
-void(vector org, vector dir, float speed) launch_spike2 = {
- newmis = spawn ();
- newmis.owner = self;
- newmis.movetype = MOVETYPE_FLYMISSILE;
- newmis.solid = SOLID_BBOX;
-
- newmis.angles = vectoangles(dir);
-
- newmis.touch = spike_touch;
- newmis.classname = "spike";
- if (self.homing > 0)
- {
- SetupHoming(newmis, speed);
- }
- else
- {
- newmis.think = SUB_Remove;
- newmis.nextthink = time + 6;
- }
- setmodel (newmis, "progs/spike.mdl");
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- setorigin (newmis, org);
-
- SetSpeed(newmis, dir, speed * (self.proj_speed_mod ? self.proj_speed_mod : 1));
-};
-void(vector org, vector dir) launch_spike = {
- launch_spike2(org,dir,1000);
-};
-
-void() W_FireSuperSpikes =
-{
- local vector dir;
-
- sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
- self.attack_finished = time + 0.2;
- self.currentammo = self.ammo_nails = self.ammo_nails - 2;
- dir = aim (self, 1000);
- launch_spike (self.origin + '0 0 16', dir);
- newmis.touch = superspike_touch;
- setmodel (newmis, "progs/s_spike.mdl");
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- self.punchangle_x = -2;
-};
-
-void(float ox) W_FireSpikes =
-{
- local vector dir;
-
- makevectors (self.v_angle);
-
- if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
- {
- W_FireSuperSpikes ();
- return;
- }
-
- if (self.ammo_nails < 1)
- {
- self.weapon = W_BestWeapon ();
- W_SetCurrentAmmo ();
- return;
- }
-
- sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
- self.attack_finished = time + 0.2;
- self.currentammo = self.ammo_nails = self.ammo_nails - 1;
- dir = aim (self, 1000);
- // launch_spike (self.origin + '0 0 16' + v_right*ox, dir);
- launch_spike (self.origin + self.view_ofs + v_up * -8 + v_right*ox, dir); //seven Nailgun position fix - thanks to Greenwood -- dumptruck_ds
-
- self.punchangle_x = -2;
-
- };
-
-
-
-void() spike_touch =
-{
- if (other == self.owner)
- return;
-
- if (other.solid == SOLID_TRIGGER)
- return; // trigger field, do nothing
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
-// hit something that bleeds
- if (other.takedamage)
- {
- spawn_touchblood (9);
- T_Damage (other, self, self.owner, 9);
- }
- else
- {
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- if (self.owner.snd_hit)
- {
- sound (self, CHAN_WEAPON, self.owner.snd_hit, 1, ATTN_STATIC); //dumptruck_ds
- WriteByte(MSG_BROADCAST, TE_GUNSHOT);
- }
-
- else if (self.classname == "wizspike")
- WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
- else if (self.classname == "knightspike")
- WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
- else
- WriteByte (MSG_BROADCAST, TE_SPIKE);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- }
-
- remove(self);
-
-};
-
-void() superspike_touch =
-{
- if (other == self.owner)
- return;
-
- if (other.solid == SOLID_TRIGGER)
- return; // trigger field, do nothing
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
-// hit something that bleeds
- if (other.takedamage)
- {
- spawn_touchblood (18);
- T_Damage (other, self, self.owner, 18);
- }
- else
- {
- if (self.owner.snd_hit)
- {
- sound (self, CHAN_WEAPON, self.owner.snd_hit, 1, ATTN_STATIC); //dumptruck_ds
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte(MSG_BROADCAST, TE_GUNSHOT);
- }
- else
- {
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
- }
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- }
-
- remove(self);
-
-};
-void() superduperspike_touch = //dumptruck_ds for Style 2 Ogre see ogre.qc
-{
- if (other == self.owner)
- return;
-
- if (other.solid == SOLID_TRIGGER)
- return; // trigger field, do nothing
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
-// hit something that bleeds
- if (other.takedamage)
- {
- spawn_touchblood (36);
- T_Damage (other, self, self.owner, 36);
- sound(self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
- }
- else
- {
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- }
-
- remove(self);
-};
-
-/*
-===============================================================================
-
-PLAYER WEAPON USE
-
-===============================================================================
-*/
-
-void() W_SetCurrentAmmo =
-{
- player_run (); // get out of any weapon firing states
-
- self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) );
-
- if (self.weapon == IT_AXE)
- {
- self.currentammo = 0;
- self.weaponmodel = "progs/v_axe.mdl";
- self.weaponframe = 0;
- }
- else if (self.weapon == IT_SHOTGUN)
- {
- self.currentammo = self.ammo_shells;
- self.weaponmodel = "progs/v_shot.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_SHELLS;
- }
- else if (self.weapon == IT_SUPER_SHOTGUN)
- {
- self.currentammo = self.ammo_shells;
- self.weaponmodel = "progs/v_shot2.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_SHELLS;
- }
- else if (self.weapon == IT_NAILGUN)
- {
- self.currentammo = self.ammo_nails;
- self.weaponmodel = "progs/v_nail.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_NAILS;
- }
- else if (self.weapon == IT_SUPER_NAILGUN)
- {
- self.currentammo = self.ammo_nails;
- self.weaponmodel = "progs/v_nail2.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_NAILS;
- }
- else if (self.weapon == IT_GRENADE_LAUNCHER)
- {
- self.currentammo = self.ammo_rockets;
- self.weaponmodel = "progs/v_rock.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_ROCKETS;
- }
- else if (self.weapon == IT_ROCKET_LAUNCHER)
- {
- self.currentammo = self.ammo_rockets;
- self.weaponmodel = "progs/v_rock2.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_ROCKETS;
- }
- else if (self.weapon == IT_LIGHTNING)
- {
- self.currentammo = self.ammo_cells;
- self.weaponmodel = "progs/v_light.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_CELLS;
- }
- else
- {
- self.currentammo = 0;
- self.weaponmodel = "";
- self.weaponframe = 0;
- }
-};
-
-float() W_BestWeapon =
-{
- local float it;
-
- it = self.items;
-
- if (self.waterlevel <= 1 && self.ammo_cells >= 1 && (it & IT_LIGHTNING) )
- return IT_LIGHTNING;
- if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
- return IT_SUPER_NAILGUN;
- if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
- return IT_SUPER_SHOTGUN;
- if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
- return IT_NAILGUN;
- if(self.ammo_shells >= 1 && (it & IT_SHOTGUN) )
- return IT_SHOTGUN;
- return IT_AXE;
-};
-
-float() W_CheckNoAmmo =
-{
- if (self.currentammo > 0)
- return TRUE;
-
- if (self.weapon == IT_AXE)
- return TRUE;
-
- self.weapon = W_BestWeapon ();
-
- W_SetCurrentAmmo ();
-
-// drop the weapon down
- return FALSE;
-};
-
-/*
-============
-W_Attack
-
-An attack impulse can be triggered now
-============
-*/
-void() player_axe1;
-void() player_axeb1;
-void() player_axec1;
-void() player_axed1;
-void() player_shot1;
-void() player_nail1;
-void() player_light1;
-void() player_rocket1;
-
-void() W_Attack =
-{
- local float r;
-
- if (!W_CheckNoAmmo ())
- return;
-
- makevectors (self.v_angle); // calculate forward angle for velocity
- self.show_hostile = time + 1; // wake monsters up
-
- if (self.weapon == IT_AXE)
- {
- sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
- r = random();
- if (r < 0.25)
- player_axe1 ();
- else if (r<0.5)
- player_axeb1 ();
- else if (r<0.75)
- player_axec1 ();
- else
- player_axed1 ();
- self.attack_finished = time + 0.5;
- }
- else if (self.weapon == IT_SHOTGUN)
- {
- player_shot1 ();
- W_FireShotgun ();
- self.attack_finished = time + 0.5;
- }
- else if (self.weapon == IT_SUPER_SHOTGUN)
- {
- player_shot1 ();
- W_FireSuperShotgun ();
- self.attack_finished = time + 0.7;
- }
- else if (self.weapon == IT_NAILGUN)
- {
- player_nail1 ();
- }
- else if (self.weapon == IT_SUPER_NAILGUN)
- {
- player_nail1 ();
- }
- else if (self.weapon == IT_GRENADE_LAUNCHER)
- {
- player_rocket1();
- W_FireGrenade();
- self.attack_finished = time + 0.6;
- }
- else if (self.weapon == IT_ROCKET_LAUNCHER)
- {
- player_rocket1();
- W_FireRocket();
- self.attack_finished = time + 0.8;
- }
- else if (self.weapon == IT_LIGHTNING)
- {
- player_light1();
- self.attack_finished = time + 0.1;
- sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
- }
-};
-
-/*
-============
-W_ChangeWeapon
-
-============
-*/
-void() W_ChangeWeapon =
-{
- local float it, am, fl;
-
- it = self.items;
- am = 0;
-
- if (self.impulse == 1)
- {
- fl = IT_AXE;
- }
- else if (self.impulse == 2)
- {
- fl = IT_SHOTGUN;
- if (self.ammo_shells < 1)
- am = 1;
- }
- else if (self.impulse == 3)
- {
- fl = IT_SUPER_SHOTGUN;
- if (self.ammo_shells < 2)
- am = 1;
- }
- else if (self.impulse == 4)
- {
- fl = IT_NAILGUN;
- if (self.ammo_nails < 1)
- am = 1;
- }
- else if (self.impulse == 5)
- {
- fl = IT_SUPER_NAILGUN;
- if (self.ammo_nails < 2)
- am = 1;
- }
- else if (self.impulse == 6)
- {
- fl = IT_GRENADE_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.impulse == 7)
- {
- fl = IT_ROCKET_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.impulse == 8)
- {
- fl = IT_LIGHTNING;
- if (self.ammo_cells < 1)
- am = 1;
- }
- else
- {
- dprint ("WARNING: W_ChangeWeapon: bad impulse: ");
- dprint (ftos (self.impulse));
- dprint ("\n");
- return;
- }
-
- self.impulse = 0;
-
- if (!(self.items & fl))
- { // don't have the weapon or the ammo
- sprint (self, "no weapon.\n");
- return;
- }
-
- if (am)
- { // don't have the ammo
- sprint (self, "not enough ammo.\n");
- return;
- }
-
-//
-// set weapon, set ammo
-//
- self.weapon = fl;
- W_SetCurrentAmmo ();
-};
-
-/*
-============
-CheatCommand
-============
-*/
-void() CheatCommand =
-{
-// 1998-07-29 Cheats coop fix by Maddes start
-// if (deathmatch || coop)
- if (deathmatch)
-// 1998-07-29 Cheats coop fix by Maddes end
- return;
-
- self.ammo_rockets = 100;
- self.ammo_nails = 200;
- self.ammo_shells = 100;
- self.items = self.items |
- IT_AXE |
- IT_SHOTGUN |
- IT_SUPER_SHOTGUN |
- IT_NAILGUN |
- IT_SUPER_NAILGUN |
- IT_GRENADE_LAUNCHER |
- IT_ROCKET_LAUNCHER;
- GiveAllKeys (self); // support for item_key_custom -- iw
-
- self.ammo_cells = 200;
- self.items = self.items | IT_LIGHTNING;
-
- self.weapon = IT_ROCKET_LAUNCHER;
- self.impulse = 0;
- W_SetCurrentAmmo ();
-};
-
-/*
-============
-CycleWeaponCommand
-
-Go to the next weapon with ammo
-============
-*/
-void() CycleWeaponCommand =
-{
- local float it, am;
-
- it = self.items;
- self.impulse = 0;
-
- while (1)
- {
- am = 0;
-
- if (self.weapon == IT_LIGHTNING)
- {
- self.weapon = IT_AXE;
- }
- else if (self.weapon == IT_AXE)
- {
- self.weapon = IT_SHOTGUN;
- if (self.ammo_shells < 1)
- am = 1;
- }
- else if (self.weapon == IT_SHOTGUN)
- {
- self.weapon = IT_SUPER_SHOTGUN;
- if (self.ammo_shells < 2)
- am = 1;
- }
- else if (self.weapon == IT_SUPER_SHOTGUN)
- {
- self.weapon = IT_NAILGUN;
- if (self.ammo_nails < 1)
- am = 1;
- }
- else if (self.weapon == IT_NAILGUN)
- {
- self.weapon = IT_SUPER_NAILGUN;
- if (self.ammo_nails < 2)
- am = 1;
- }
- else if (self.weapon == IT_SUPER_NAILGUN)
- {
- self.weapon = IT_GRENADE_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.weapon == IT_GRENADE_LAUNCHER)
- {
- self.weapon = IT_ROCKET_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.weapon == IT_ROCKET_LAUNCHER)
- {
- self.weapon = IT_LIGHTNING;
- if (self.ammo_cells < 1)
- am = 1;
- }
-
- if ( (it & self.weapon) && am == 0)
- {
- W_SetCurrentAmmo ();
- return;
- }
- }
-
-};
-
-/*
-============
-CycleWeaponReverseCommand
-
-Go to the prev weapon with ammo
-============
-*/
-void() CycleWeaponReverseCommand =
-{
- local float it, am;
-
- it = self.items;
- self.impulse = 0;
-
- while (1)
- {
- am = 0;
-
- if (self.weapon == IT_LIGHTNING)
- {
- self.weapon = IT_ROCKET_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.weapon == IT_ROCKET_LAUNCHER)
- {
- self.weapon = IT_GRENADE_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.weapon == IT_GRENADE_LAUNCHER)
- {
- self.weapon = IT_SUPER_NAILGUN;
- if (self.ammo_nails < 2)
- am = 1;
- }
- else if (self.weapon == IT_SUPER_NAILGUN)
- {
- self.weapon = IT_NAILGUN;
- if (self.ammo_nails < 1)
- am = 1;
- }
- else if (self.weapon == IT_NAILGUN)
- {
- self.weapon = IT_SUPER_SHOTGUN;
- if (self.ammo_shells < 2)
- am = 1;
- }
- else if (self.weapon == IT_SUPER_SHOTGUN)
- {
- self.weapon = IT_SHOTGUN;
- if (self.ammo_shells < 1)
- am = 1;
- }
- else if (self.weapon == IT_SHOTGUN)
- {
- self.weapon = IT_AXE;
- }
- else if (self.weapon == IT_AXE)
- {
- self.weapon = IT_LIGHTNING;
- if (self.ammo_cells < 1)
- am = 1;
- }
-
- if ( (it & self.weapon) && am == 0)
- {
- W_SetCurrentAmmo ();
- return;
- }
- }
-
-};
-
-/*
-============
-ServerflagsCommand
-
-Just for development
-============
-*/
-void() ServerflagsCommand =
-{
-// 1998-07-29 Cheats coop fix by Maddes start
- if (deathmatch)
- return;
-// 1998-07-29 Cheats coop fix by Maddes end
- serverflags = serverflags * 2 + 1;
-};
-
-void() QuadCheat =
-{
-// 1998-07-29 Cheats coop fix by Maddes start
-// if (deathmatch || coop)
- if (deathmatch)
-// 1998-07-29 Cheats coop fix by Maddes end
- return;
- self.super_time = 1;
- self.super_damage_finished = time + 30;
- self.items = self.items | IT_QUAD;
- dprint ("quad cheat\n");
-};
-
-/*
-============
-ImpulseCommands
-
-============
-*/
-void() ImpulseCommands =
-{
- if (self.impulse >= 1 && self.impulse <= 8)
- W_ChangeWeapon ();
-
- if (self.impulse == 9)
- CheatCommand ();
- if (self.impulse == 10)
- CycleWeaponCommand ();
- if (self.impulse == 11)
- ServerflagsCommand ();
- if (self.impulse == 12)
- CycleWeaponReverseCommand ();
-
- if (self.impulse == 255)
- QuadCheat ();
-// dumptruck_ds version inspired by Copper
- if (self.impulse == 100)
- sprint(self, version);
-
- // if (self.impulse == 101) // debugging armor shards -- dumptruck_ds
- // dprint ("Armortype is");
- // dprint (ftos(self.armortype));
- // dprint ("\n");
-
- self.impulse = 0;
-};
-
-/*
-============
-W_WeaponFrame
-
-Called every frame so impulse events can be handled as well as possible
-============
-*/
-void() W_WeaponFrame =
-{
- if (time < self.attack_finished)
- return;
-
-if (self.impulse) // 1998-08-14 Constantly checking all impulses fix by Perged
- ImpulseCommands ();
-
-// check for attack
- if (self.button0)
- {
- SuperDamageSound ();
- W_Attack ();
- }
-};
-
-/*
-========
-SuperDamageSound
-
-Plays sound if needed
-========
-*/
-void() SuperDamageSound =
-{
- if (self.super_damage_finished > time)
- {
- if (self.super_sound < time)
- {
- self.super_sound = time + 1;
- sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
- }
- }
- return;
-};
-
-void() MissileHome =
-{
- local vector dir, vtemp;
- vtemp = self.enemy.origin + '0 0 10';
-
- if (self.enemy.health < 1)
- {
- remove(self);
- return;
- }
- dir = normalize(vtemp - self.origin);
- if (self.homing < 1 && self.homing > 0) // can't do better than 100% homing
- {
- /*
- This finds a vector somewhere between the vector the projectile is currently
- travelling on and the vector that it would normally snap to for homing
-
- homing = .25 means it will go 25% to the new direction, but keep 75% of the
- original vector, resulting in a wider turning range.
- */
- dir = normalize((dir * self.homing) + normalize(self.velocity * (1 - self.homing)));
- }
- if (!self.avelocity)
- self.angles = vectoangles(dir);
- SetSpeed(self, dir, self.proj_basespeed);
-
- if (self.homing > 0)
- {
- if (self.homing < 1 && self.attack_finished && self.attack_finished < time )
- {
- //dprint("incrementing homing | ");
- //dprint("old: ");
- //dprint(ftos(self.homing));
- //dprint(" | new: ");
- self.homing = self.homing + 0.005;
- //dprint(ftos(self.homing));
- //dprint("\n");
- }
- self.nextthink = time + 0.2;
- self.think = MissileHome;
- }
-};
-
-void(entity mis, float speed) SetupHoming =
-{
- local vector dir;
- local float dist, flytime, speedmod;
- if (self.proj_speed_mod > 1)
- {
- speedmod = 1/self.proj_speed_mod;
- }
- else if (speed > 250)
- {
- speedmod = 1 / (speed / 250);
- }
- else
- {
- speedmod = 1;
- }
- dir = normalize((self.enemy.origin + '0 0 10') - self.origin);
- dist = vlen (self.enemy.origin - self.origin);
- flytime = dist * 0.002 * speedmod;
- if (flytime < 0.1)
- flytime = 0.1;
-
- mis.enemy = self.enemy;
- mis.proj_basespeed = speed;
- mis.homing = self.homing;
- mis.nextthink = flytime + time;
- mis.think = MissileHome;
- if (self.waitmin > 0)
- {
- mis.attack_finished = time + self.waitmin; // store time to start increasing
- }
-};

Return to the top of this page or return to the overview of this repo.

Diff qc-server/world.qc

diff --git a/qc-server/world.qc b/qc-server/world.qc
deleted file mode 100644
index 84555aa..0000000
--- a/qc-server/world.qc
+++ /dev/null
@@ -1,621 +0,0 @@
-
-void() InitBodyQue;
-
-
-void() main =
-{
- dprint ("main function\n");
-
-// these are just commands the the prog compiler to copy these files
-
- precache_file ("progs.dat");
- precache_file ("gfx.wad");
- precache_file ("quake.rc");
- precache_file ("default.cfg");
-
- precache_file ("end1.bin");
- precache_file2 ("end2.bin");
-
- precache_file ("demo1.dem");
- precache_file ("demo2.dem");
- precache_file ("demo3.dem");
-
-//
-// these are all of the lumps from the cached.ls files
-//
- precache_file ("gfx/palette.lmp");
- precache_file ("gfx/colormap.lmp");
-
- precache_file2 ("gfx/pop.lmp");
-
- precache_file ("gfx/complete.lmp");
- precache_file ("gfx/inter.lmp");
-
- precache_file ("gfx/ranking.lmp");
- precache_file ("gfx/vidmodes.lmp");
- precache_file ("gfx/finale.lmp");
- precache_file ("gfx/conback.lmp");
- precache_file ("gfx/qplaque.lmp");
-
- precache_file ("gfx/menudot1.lmp");
- precache_file ("gfx/menudot2.lmp");
- precache_file ("gfx/menudot3.lmp");
- precache_file ("gfx/menudot4.lmp");
- precache_file ("gfx/menudot5.lmp");
- precache_file ("gfx/menudot6.lmp");
-
- precache_file ("gfx/menuplyr.lmp");
- precache_file ("gfx/bigbox.lmp");
- precache_file ("gfx/dim_modm.lmp");
- precache_file ("gfx/dim_drct.lmp");
- precache_file ("gfx/dim_ipx.lmp");
- precache_file ("gfx/dim_tcp.lmp");
- precache_file ("gfx/dim_mult.lmp");
- precache_file ("gfx/mainmenu.lmp");
-
- precache_file ("gfx/box_tl.lmp");
- precache_file ("gfx/box_tm.lmp");
- precache_file ("gfx/box_tr.lmp");
-
- precache_file ("gfx/box_ml.lmp");
- precache_file ("gfx/box_mm.lmp");
- precache_file ("gfx/box_mm2.lmp");
- precache_file ("gfx/box_mr.lmp");
-
- precache_file ("gfx/box_bl.lmp");
- precache_file ("gfx/box_bm.lmp");
- precache_file ("gfx/box_br.lmp");
-
- precache_file ("gfx/sp_menu.lmp");
- precache_file ("gfx/ttl_sgl.lmp");
- precache_file ("gfx/ttl_main.lmp");
- precache_file ("gfx/ttl_cstm.lmp");
-
- precache_file ("gfx/mp_menu.lmp");
-
- precache_file ("gfx/netmen1.lmp");
- precache_file ("gfx/netmen2.lmp");
- precache_file ("gfx/netmen3.lmp");
- precache_file ("gfx/netmen4.lmp");
- precache_file ("gfx/netmen5.lmp");
-
- precache_file ("gfx/sell.lmp");
-
- precache_file ("gfx/help0.lmp");
- precache_file ("gfx/help1.lmp");
- precache_file ("gfx/help2.lmp");
- precache_file ("gfx/help3.lmp");
- precache_file ("gfx/help4.lmp");
- precache_file ("gfx/help5.lmp");
-
- precache_file ("gfx/pause.lmp");
- precache_file ("gfx/loading.lmp");
-
- precache_file ("gfx/p_option.lmp");
- precache_file ("gfx/p_load.lmp");
- precache_file ("gfx/p_save.lmp");
- precache_file ("gfx/p_multi.lmp");
-
-// sounds loaded by C code
- precache_sound ("misc/menu1.wav");
- precache_sound ("misc/menu2.wav");
- precache_sound ("misc/menu3.wav");
-
- precache_sound ("ambience/water1.wav");
- precache_sound ("ambience/wind2.wav");
-
-// shareware
- precache_file ("maps/start.bsp");
-
- precache_file ("maps/e1m1.bsp");
- precache_file ("maps/e1m2.bsp");
- precache_file ("maps/e1m3.bsp");
- precache_file ("maps/e1m4.bsp");
- precache_file ("maps/e1m5.bsp");
- precache_file ("maps/e1m6.bsp");
- precache_file ("maps/e1m7.bsp");
- precache_file ("maps/e1m8.bsp");
-
-// registered
- precache_file2 ("gfx/pop.lmp");
-
- precache_file2 ("maps/e2m1.bsp");
- precache_file2 ("maps/e2m2.bsp");
- precache_file2 ("maps/e2m3.bsp");
- precache_file2 ("maps/e2m4.bsp");
- precache_file2 ("maps/e2m5.bsp");
- precache_file2 ("maps/e2m6.bsp");
- precache_file2 ("maps/e2m7.bsp");
-
- precache_file2 ("maps/e3m1.bsp");
- precache_file2 ("maps/e3m2.bsp");
- precache_file2 ("maps/e3m3.bsp");
- precache_file2 ("maps/e3m4.bsp");
- precache_file2 ("maps/e3m5.bsp");
- precache_file2 ("maps/e3m6.bsp");
- precache_file2 ("maps/e3m7.bsp");
-
- precache_file2 ("maps/e4m1.bsp");
- precache_file2 ("maps/e4m2.bsp");
- precache_file2 ("maps/e4m3.bsp");
- precache_file2 ("maps/e4m4.bsp");
- precache_file2 ("maps/e4m5.bsp");
- precache_file2 ("maps/e4m6.bsp");
- precache_file2 ("maps/e4m7.bsp");
- precache_file2 ("maps/e4m8.bsp");
-
- precache_file2 ("maps/end.bsp");
-
- precache_file2 ("maps/dm1.bsp");
- precache_file2 ("maps/dm2.bsp");
- precache_file2 ("maps/dm3.bsp");
- precache_file2 ("maps/dm4.bsp");
- precache_file2 ("maps/dm5.bsp");
- precache_file2 ("maps/dm6.bsp");
-};
-
-
-/*
-================
-DetectKnownRelease
-
-This detects whether the current map is from a known release for which
-a backwards-compatibility hack should be applied, and sets the
-known_release global accordingly. -- iw
-================
-*/
-void() DetectKnownRelease =
-{
- local string release_name;
-
- known_release = KNOWN_RELEASE_NOT;
- release_name = "";
-
- if (mapname == "dm1" ||
- mapname == "dm2" ||
- mapname == "dm3" ||
- mapname == "dm4" ||
- mapname == "dm5" ||
- mapname == "dm6" ||
- mapname == "e1m1" ||
- mapname == "e1m2" ||
- mapname == "e1m3" ||
- mapname == "e1m4" ||
- mapname == "e1m5" ||
- mapname == "e1m6" ||
- mapname == "e1m7" ||
- mapname == "e1m8" ||
- mapname == "e2m1" ||
- mapname == "e2m2" ||
- mapname == "e2m3" ||
- mapname == "e2m4" ||
- mapname == "e2m5" ||
- mapname == "e2m6" ||
- mapname == "e2m7" ||
- mapname == "e3m1" ||
- mapname == "e3m2" ||
- mapname == "e3m3" ||
- mapname == "e3m4" ||
- mapname == "e3m5" ||
- mapname == "e3m6" ||
- mapname == "e3m7" ||
- mapname == "e4m1" ||
- mapname == "e4m2" ||
- mapname == "e4m3" ||
- mapname == "e4m4" ||
- mapname == "e4m5" ||
- mapname == "e4m6" ||
- mapname == "e4m7" ||
- mapname == "e4m8" ||
- mapname == "end" ||
- (mapname == "start" && world.message == "Introduction"))
- {
- known_release = KNOWN_RELEASE_ID1;
- release_name = "id1";
- }
-
- if (mapname == "jamx_artistical" ||
- mapname == "jamx_bloodshot" ||
- mapname == "jamx_fw" ||
- mapname == "jamx_hcm" ||
- mapname == "jamx_ionous" ||
- mapname == "jamx_jcr" ||
- mapname == "jamx_kalebclark" ||
- mapname == "jamx_mafon" ||
- //mapname == "jamx_mugwump" || // dummy map
- mapname == "jamx_naitelveni" ||
- mapname == "jamx_newhouse" ||
- mapname == "jamx_pinchy" ||
- mapname == "jamx_strwrk" ||
- mapname == "jamx_ukko" ||
- mapname == "jamx_yoder" ||
- (mapname == "start" && world.message == "An Unending Dusk"))
- {
- known_release = KNOWN_RELEASE_FUNC_MAPJAMX;
- release_name = "func_mapjamx";
- }
-
- if (release_name != "")
- {
- dprint ("WARNING: progs.dat detected a map from ");
- dprint (release_name);
- dprint (", attempting to behave compatibly\n");
- }
-};
-
-
-entity lastspawn;
-
-//=======================
-/*QUAKED worldspawn (0 0 0) ?
-Only used for the world entity.
-
-Optionally set reset_items to one of the following values:
-0: don't reset the player's inventory
-1: reset to shotgun, axe, and 25 shells
-2: reset to axe only
-
-message(string) : "Level name"
-
-worldtype(choices) : "Ambience" : 0 =
-0 : "Medieval"
-1 : "Runic (metal)"
-2 : "Present (base)"
-
-sounds(integer) : "CD track to play" : 0
-
-light(integer) : "Ambient light" : 0 : "Set a global minimum light level of 'n' across the whole map. This is an easy way to eliminate completely dark areas of the level, however you may lose some contrast as a result, so use with care. Default 0"
-
-reset_items(choices) : "Reset the player's inventory on spawn" : 0 =
-0 "Don't reset the player's inventory"
-1 "Reset to shotgun, axe, and 25 shells"
-2 "Reset to axe only"
-
-_sunlight(integer) : "Sunlight" : 0 : "Set the brightness of the sunlight coming from an unseen sun in the sky. Sky brushes (or more accurately bsp leafs with sky contents) will emit sunlight at an angle specified by the _sun_mangle key. Default 0"
-
-_sun_mangle(string) : "Sun mangle (Yaw pitch roll)" : "0 -90 0" : "Specifies the direction of sunlight using yaw(x), pitch(y) and roll(z) in degrees. Yaw specifies the angle around the Z-axis from 0 to 359 degrees and pitch specifies the angle from 90 (straight up) to -90 (straight down). Roll has no effect, so use any value (e.g. 0). Default is straight down (0 -90 0)"
-
-_sunlight_penumbra(integer) : "Sunlight penumbra in degrees" : 0 : "Specifies the penumbra width, in degrees, of sunlight. Useful values are 3-4 for a gentle soft edge, or 10-20+ for more diffuse sunlight. Default is 0"
-
-_sunlight_color(color255) : "Sunlight color R G B" : "255 255 255" : "Specify red(r), green(g) and blue(b) components for the colour of the sunlight. RGB component values are between 0 and 255 (between 0 and 1 is also accepted). Default is white light (255 255 255)"
-
-_sunlight2(integer) : "Sunlight 2 brightness" : 0 : "Set the brightness of a large dome of lights positioned around the map (16K unit radius). Useful for simulating higly diffused light (e.g. cloudy skies) in outdoor areas. Default 0"
-
-_sunlight2_color(color255) : "Sunlight 2 color R G B" : "255 255 255" : "Specifies the colour of _sunlight2, same format as _sunlight_color. Default is white light (255 255 255)"
-
-_sunlight3(integer) : "Sunlight 3 brightness" : 0 : "Same as _sunlight2 but creates lights on the bottom hemisphere. Default 0"
-
-_sunlight3_color(color255) : "Sunlight 3 color R G B" : "255 255 255" : "Specifies the colour of _sunlight3, same format as _sunlight_color. Default is white light (255 255 255)"
-
-_dist(integer) : "Global light scale" : 1 : "Scales the fade distance of all lights by a factor of n. If n is more than 1 lights fade more quickly with distance and if n is less than 1, lights fade more slowly with distance and light reaches further"
-
-_range(float) : "Global light range" : "0.5" : "Scales the brightness range of all lights without affecting their fade discance. Values of n more than 0.5 makes lights brighter and n less than 0.5 makes lights less bright. The same effect can be achieved on individual lights by adjusting both the 'light' and 'wait' attributes"
-
-_anglescale(float) : "Light angle scale" : "0.5" : "Sets a scaling factor for how much influence the angle of incidence of sunlight on a surface has on the brightness of the surface. n must be between 0.0 and 1.0. Smaller values mean less attenuation, with zero meaning that angle of incidence has no effect at all on the brightness. Default 0.5"
-
-_dirt(integer) : "Dirt mapping (AO)" : -1 : "1 enables dirtmapping (ambient occlusion) on all lights, borrowed from q3map2. This adds shadows to corners and crevices. You can override the global setting for specific lights with the _dirt light entity key or _sunlight_dirt, _sunlight2_dirt, and _minlight_dirt worldspawn keys. Default is no dirtmapping (-1)"
-
-_sunlight_dirt(integer) : "Sunlight dirt" : -1 : "1 enables dirtmapping (ambient occlusion) on sunlight, -1 to disable (making it illuminate the dirtmapping shadows). Default is to use the value of '_dirt'"
-
-_sunlight2_dirt(integer) : "Sublight 2 dirt" : -1 : "1 enables dirtmapping (ambient occlusion) on sunlight2, -1 to disable. Default is to use the value of '_dirt'"
-
-_minlight_dirt(integer) : "Minlight dirt" : -1 : "1 enables dirtmapping (ambient occlusion) on minlight, -1 to disable. Default is to use the value of '_dirt'"
-
-_dirtmode(integer) : "Dirt mode" : 0 : "Choose between ordered (0, default) and randomized (1) dirtmapping."
-
-_dirtdepth(integer) : "Dirt depth" : 128 : "Maximum depth of occlusion checking for dirtmapping, default 128."
-
-_dirtscale(integer) : "Dirt scale" : 1 : "Scale factor used in dirt calculations, default 1. Lower values (e.g. 0.5) make the dirt fainter, 2.0 would create much darker shadows"
-
-_dirtgain(integer) : "Dirt gain" : 1 : "Exponent used in dirt calculation, default 1. Lower values (e.g. 0.5) make the shadows darker and stretch further away from corners"
-
-_gamma(integer) : "Lightmap gamma" : 1 : "Adjust brightness of final lightmap. Default 1, >1 is brighter, <1 is darker"
-
-fog(string) : "Fog Command" : : "ENGINE only 'console command' for setting fog parameters, Density/R/G/B example = (0.05 0.3 0.3 0.3)."
-
-fog_density(string) : "Fog Density example = (0.05)"
-
-fog_color(string) : "Fog Color R/G/B example = (0.3 0.3 0.3)"
-
-sky(string) : "Sky Texture" : : "Must have compatible skybox textures in gfx/env folder."
-*/
-//=======================
-void() worldspawn =
-{
- DetectKnownRelease ();
-
- InitNewSpawnflags (); // new spawnflags for all entities -- iw
-
- lastspawn = world;
-
- if (cvar("pr_checkextension"))
- {
- clientstat (CLIENT_VELOCITY_X, EV_FLOAT, velocity_x);
- clientstat (CLIENT_VELOCITY_Y, EV_FLOAT, velocity_y);
- }
-
- InitBodyQue ();
-
-// custom map attributes
- if (self.model == "maps/e1m8.bsp" && self.skip_id1_overrides == 0)
- cvar_set ("sv_gravity", "100");
- else
- cvar_set ("sv_gravity", "800");
-
- cutscene = 0; // No cutscene is active during worldspawn. Drake -- dumptruck_ds
-
- world_sounds = &world.sounds; //Spike via dumptruck_ds || not read-only yet...
-
-// the area based ambient sounds MUST be the first precache_sounds
-
-// player precaches
- W_Precache (); // get weapon precaches
-
-// sounds used from C physics code
- precache_sound_land ("demon/dland2.wav"); // landing thud
- precache_sound ("misc/h2ohit1.wav"); // landing splash
-
-// setup precaches always needed
- precache_sound ("items/itembk2.wav"); // item respawn sound
- precache_sound ("player/plyrjmp8.wav"); // player jump
- precache_sound ("player/land.wav"); // player landing
- precache_sound ("player/land2.wav"); // player hurt landing
- precache_sound ("player/drown1.wav"); // drowning pain
- precache_sound ("player/drown2.wav"); // drowning pain
- precache_sound ("player/gasp1.wav"); // gasping for air
- precache_sound ("player/gasp2.wav"); // taking breath
- precache_sound ("player/h2odeath.wav"); // drowning death
-
- precache_sound ("misc/talk.wav"); // talk
- precache_sound ("player/teledth1.wav"); // telefrag
- precache_sound ("misc/r_tele1.wav"); // teleport sounds
- precache_sound ("misc/r_tele2.wav");
- precache_sound ("misc/r_tele3.wav");
- precache_sound ("misc/r_tele4.wav");
- precache_sound ("misc/r_tele5.wav");
- precache_sound ("weapons/lock4.wav"); // ammo pick up
- precache_sound ("weapons/pkup.wav"); // weapon up
- precache_sound ("items/armor1.wav"); // armor up
- precache_sound ("weapons/lhit.wav"); //lightning
- precache_sound ("weapons/lstart.wav"); //lightning start
-
- // iw -- fix powerup cheat sounds // noticed this in Copper so why not? --ds
- // sounds used by cheats
- precache_sound ("items/suit2.wav"); // suit (finish)
- precache_sound ("items/protect2.wav"); // pent (finish)
- precache_sound ("items/protect3.wav"); // pent (protect)
- precache_sound ("items/inv2.wav"); // ring (finish)
- precache_sound ("items/inv3.wav"); // ring (idle)
- precache_sound ("items/damage2.wav"); // quad (finish)
- precache_sound ("items/damage3.wav"); // quad (attack)
- // iw -- END
-
- precache_sound ("misc/power.wav"); //lightning for boss
-
-// player gib sounds
- precache_sound ("player/gib.wav"); // player gib sound
- precache_sound ("player/udeath.wav"); // player gib sound
- precache_sound ("player/tornoff2.wav"); // gib sound
-
-// player pain sounds
-
- precache_sound ("player/pain1.wav");
- precache_sound ("player/pain2.wav");
- precache_sound ("player/pain3.wav");
- precache_sound ("player/pain4.wav");
- precache_sound ("player/pain5.wav");
- precache_sound ("player/pain6.wav");
-
-// player death sounds
- precache_sound ("player/death1.wav");
- precache_sound ("player/death2.wav");
- precache_sound ("player/death3.wav");
- precache_sound ("player/death4.wav");
- precache_sound ("player/death5.wav");
-
-// ax sounds
- precache_sound ("weapons/ax1.wav"); // ax swoosh
- precache_sound ("player/axhit1.wav"); // ax hit meat
- precache_sound ("player/axhit2.wav"); // ax hit world
-
- precache_sound ("player/h2ojump.wav"); // player jumping into water
- precache_sound ("player/slimbrn2.wav"); // player enter slime
- precache_sound ("player/inh2o.wav"); // player enter water
- precache_sound ("player/inlava.wav"); // player enter lava
- precache_sound ("misc/outwater.wav"); // leaving water sound
-
- precache_sound ("player/lburn1.wav"); // lava burn
- precache_sound ("player/lburn2.wav"); // lava burn
-
- precache_sound ("misc/water1.wav"); // swimming
- precache_sound ("misc/water2.wav"); // swimming
-
- precache_model ("progs/player.mdl");
- precache_model ("progs/s_null.spr"); // Invisible -- Drake -- dumptruck_ds
- // precache_model ("progs/null_256.spr"); // Invisible -- Drake -- dumptruck_ds
- precache_model ("progs/eyes.mdl");
- precache_model ("progs/h_player.mdl");
- precache_model ("progs/gib1.mdl");
- precache_model ("progs/gib2.mdl");
- precache_model ("progs/gib3.mdl");
-
- precache_model ("progs/s_bubble.spr"); // drowning bubbles
- precache_model ("progs/s_explod.spr"); // sprite explosion
-
- precache_model ("progs/v_axe.mdl");
- precache_model ("progs/v_shot.mdl");
- precache_model ("progs/v_nail.mdl");
- precache_model ("progs/v_rock.mdl");
- precache_model ("progs/v_shot2.mdl");
- precache_model ("progs/v_nail2.mdl");
- precache_model ("progs/v_rock2.mdl");
-
- precache_model ("progs/bolt.mdl"); // for lightning gun
- precache_model ("progs/bolt2.mdl"); // for lightning gun
- precache_model ("progs/bolt3.mdl"); // for boss shock
- precache_model ("progs/lavaball.mdl"); // for testing
-
- precache_model ("progs/missile.mdl");
- precache_model ("progs/grenade.mdl");
- precache_model ("progs/spike.mdl");
- // dumptruck_ds added w_spike due to errors
- // with custom_mdls in precache_proj_model in wizard.qc
- // precache_model ("progs/w_spike.mdl");
- // this is on hold for now head and body are working
- precache_model ("progs/s_spike.mdl");
-
- precache_model ("progs/backpack.mdl");
-
- precache_model ("progs/zom_gib.mdl");
-
- precache_model ("progs/v_light.mdl");
-
- precache_model ("progs/w_s_key.mdl"); // dumptruck_ds needed for DropStuff
- precache_model ("progs/w_g_key.mdl"); //
- precache_sound ("misc/medkey.wav");
- precache_sound ("misc/runekey.wav");
- precache_model ("progs/m_s_key.mdl");
- precache_model ("progs/m_g_key.mdl");
- precache_sound2 ("misc/basekey.wav");
- precache_model2 ("progs/b_s_key.mdl");
- precache_model2 ("progs/b_g_key.mdl");
- precache_model ("progs/h_mdls/pd_vial.mdl"); // DropVial -- dumptruck_ds
- precache_sound ("items/r_item1.wav");
- precache_sound ("dump/armsh1.wav"); // DropShard -- dumptruck_ds
- precache_model ("progs/armshr.mdl");
-
-//
-// Setup light animation tables. 'a' is total darkness, 'z' is maxbright.
-//
-
- // 0 normal
- lightstyle(0, "m");
-
- // 1 FLICKER (first variety)
- lightstyle(1, "mmnmmommommnonmmonqnmmo");
-
- // 2 SLOW STRONG PULSE
- lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
-
- // 3 CANDLE (first variety)
- lightstyle(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");
-
- // 4 FAST STROBE
- lightstyle(4, "mamamamamama");
-
- // 5 GENTLE PULSE 1
- lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");
-
- // 6 FLICKER (second variety)
- lightstyle(6, "nmonqnmomnmomomno");
-
- // 7 CANDLE (second variety)
- lightstyle(7, "mmmaaaabcdefgmmmmaaaammmaamm");
-
- // 8 CANDLE (third variety)
- lightstyle(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");
-
- // 9 SLOW STROBE (fourth variety)
- lightstyle(9, "aaaaaaaazzzzzzzz");
-
- // 10 FLUORESCENT FLICKER
- lightstyle(10, "mmamammmmammamamaaamammma");
-
- // 11 SLOW PULSE NOT FADE TO BLACK
- lightstyle(11, "abcdefghijklmnopqrrqponmlkjihgfedcba");
-
- // styles 32-62 are assigned by the light program for switchable lights
-
- // 63 testing
- lightstyle(63, "a");
-};
-
-void() RestartLoopSounds_think = {
- sound(self, self.impulse, self.noise, self.volume, self.speed);
-};
-
-void() RestartLoopSounds = {
- entity e;
- e = find(world, classname, "play_sound_triggered");
- while (e) {
-
- if (e.spawnflags & 3 == 3) { // both "toggle" and "looped" need to be set
- if (e.state == 1) {
- e.nextthink = time + 0.1;
- e.think = RestartLoopSounds_think;
- }
- }
-
- e = find(e, classname, "play_sound_triggered");
- }
-};
-
-
-void() StartFrame =
-{
- if (!done_inhibition_summary) // new spawnflags for all entities -- iw
- PrintInhibitionSummary ();
-
- teamplay = cvar("teamplay");
- skill = cvar("skill");
- framecount = framecount + 1;
-
- if (cleanUpClientStuff) {
- cleanUpClientStuff -= 1;
-
- RestartLoopSounds();
- }
- else if (!gamestarted && framecount > 2)
- {
- if (framecount != 3)
- cleanUpClientStuff += 2;
-
- gamestarted = TRUE;
- }
-};
-
-/*
-==============================================================================
-
-BODY QUE
-
-==============================================================================
-*/
-
-entity bodyque_head;
-
-void() bodyque =
-{ // just here so spawn functions don't complain after the world
- // creates bodyques
-};
-
-void() InitBodyQue =
-{
- bodyque_head = spawn();
- bodyque_head.classname = "bodyque";
- bodyque_head.owner = spawn();
- bodyque_head.owner.classname = "bodyque";
- bodyque_head.owner.owner = spawn();
- bodyque_head.owner.owner.classname = "bodyque";
- bodyque_head.owner.owner.owner = spawn();
- bodyque_head.owner.owner.owner.classname = "bodyque";
- bodyque_head.owner.owner.owner.owner = bodyque_head;
-};
-
-
-// make a body que entry for the given ent so the ent can be
-// respawned elsewhere
-void(entity ent) CopyToBodyQue =
-{
- bodyque_head.angles = ent.angles;
- bodyque_head.model = ent.model;
- bodyque_head.modelindex = ent.modelindex;
- bodyque_head.frame = ent.frame;
- bodyque_head.colormap = ent.colormap;
- bodyque_head.movetype = ent.movetype;
- bodyque_head.velocity = ent.velocity;
- bodyque_head.flags = 0;
- setorigin (bodyque_head, ent.origin);
- setsize (bodyque_head, ent.mins, ent.maxs);
- bodyque_head = bodyque_head.owner;
-};

Return to the top of this page or return to the overview of this repo.

Diff qc/ai.qc

diff --git a/qc/ai.qc b/qc/ai.qc
new file mode 100644
index 0000000..0d8f18a
--- /dev/null
+++ b/qc/ai.qc
@@ -0,0 +1,858 @@
+void() movetarget_f;
+void() t_movetarget;
+void() knight_walk1;
+void() knight_bow6;
+void() knight_bow1;
+void(entity etemp, entity stemp, entity stemp, float dmg) T_Damage;
+float NO_SIGHT_SOUND = 32;
+float PASSIVE_UNTIL_ATTACKED = 64;
+float PASSIVE_ALWAYS = 128;
+/*
+
+.enemy
+Will be world if not currently angry at anyone.
+
+.movetarget
+The next path spot to walk toward. If .enemy, ignore .movetarget.
+When an enemy is killed, the monster will try to return to it's path.
+
+.huntt_ime
+Set to time + something when the player is in sight, but movement straight for
+him is blocked. This causes the monster to use wall following code for
+movement direction instead of sighting on the player.
+
+.ideal_yaw
+A yaw angle of the intended direction, which will be turned towards at up
+to 45 deg / state. If the enemy is in view and hunt_time is not active,
+this will be the exact line towards the enemy.
+
+.pausetime
+A monster will leave it's stand state and head towards it's .movetarget when
+time > .pausetime.
+
+walkmove(angle, speed) primitive is all or nothing
+*/
+
+
+//
+// globals
+//
+
+//
+// when a monster becomes angry at a player, that monster will be used
+// as the sight target the next frame so that monsters near that one
+// will wake up even if they wouldn't have noticed the player
+//
+entity sight_entity;
+float sight_entity_time;
+
+float(float v) anglemod =
+{
+ while (v >= 360)
+ v = v - 360;
+ while (v < 0)
+ v = v + 360;
+ return v;
+};
+
+/*
+==============================================================================
+
+MOVETARGET CODE
+
+The angle of the movetarget effects standing and bowing direction, but has no effect on movement, which always heads to the next target.
+
+targetname
+must be present. The name of this movetarget.
+
+target
+the next spot to move to. If not present, stop here for good.
+
+pausetime
+The number of seconds to spend standing or bowing for path_stand or path_bow
+
+==============================================================================
+*/
+
+
+void() movetarget_f =
+{
+ if (!self.targetname)
+ objerror ("monster_movetarget: no targetname");
+
+ self.solid = SOLID_TRIGGER;
+ self.touch = t_movetarget;
+ setsize (self, '-8 -8 -8', '8 8 8');
+
+};
+
+/*QUAKED path_corner (0.5 0.3 0) (-8 -8 -8) (8 8 8)
+Monsters will continue walking towards the next target corner.
+*/
+void() path_corner =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.noise) precache_sound(self.noise);
+ if (self.noise2) precache_sound(self.noise2);
+
+ movetarget_f ();
+};
+
+
+/*
+=============
+t_movetarget
+
+Something has bumped into a movetarget. If it is a monster
+moving towards it, change the next destination and continue.
+==============
+*/
+void() t_movetarget =
+{
+local entity temp;
+
+ if (other.movetarget != self)
+ return;
+
+ if (other.enemy)
+ return; // fighting, not following a path
+
+ temp = self;
+ self = other;
+ other = temp;
+
+ if (self.classname == "monster_ogre")
+ sound_misc (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);// play chainsaw drag sound -- sound_custom -- dumptruck_ds
+
+//dprint ("t_movetarget\n");
+ self.goalentity = self.movetarget = find (world, targetname, other.target);
+ self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
+ if (!self.movetarget)
+ {
+ self.pausetime = time + 999999;
+ self.th_stand ();
+ return;
+ }
+};
+
+
+
+//============================================================================
+
+/*
+=============
+range
+
+returns the range catagorization of an entity reletive to self
+0 melee range, will become hostile even if back is turned
+1 visibility and infront, or visibility and show hostile
+2 infront and show hostile
+3 only triggered by damage
+=============
+*/
+float(entity targ) range =
+{
+local vector spot1, spot2;
+local float r;
+ spot1 = self.origin + self.view_ofs;
+ spot2 = targ.origin + targ.view_ofs;
+
+ r = vlen (spot1 - spot2);
+ if (r < 120)
+ return RANGE_MELEE;
+ if (r < 500)
+ return RANGE_NEAR;
+ if (r < 1000)
+ return RANGE_MID;
+ return RANGE_FAR;
+};
+
+/*
+=============
+visible
+
+returns 1 if the entity is visible to self, even if not infront ()
+=============
+*/
+float (entity targ) visible =
+{
+ local vector spot1, spot2;
+
+ spot1 = self.origin + self.view_ofs;
+ spot2 = targ.origin + targ.view_ofs;
+ traceline (spot1, spot2, TRUE, self); // see through other monsters
+
+ if (trace_inopen && trace_inwater)
+ return FALSE; // sight line crossed contents
+
+ if (trace_fraction == 1)
+ return TRUE;
+ return FALSE;
+};
+
+
+/*
+=============
+infront
+
+returns 1 if the entity is in front (in sight) of self
+=============
+*/
+float(entity targ) infront =
+{
+ local vector vec;
+ local float dot;
+
+ makevectors (self.angles);
+ vec = normalize (targ.origin - self.origin);
+ dot = vec * v_forward;
+
+ if ( dot > 0.3)
+ {
+ return TRUE;
+ }
+ return FALSE;
+};
+
+
+//============================================================================
+
+/*
+===========
+ChangeYaw
+
+Turns towards self.ideal_yaw at self.yaw_speed
+Sets the global variable current_yaw
+Called every 0.1 sec by monsters
+============
+*/
+/*
+
+void() ChangeYaw =
+{
+ local float ideal, move;
+
+//current_yaw = self.ideal_yaw;
+// mod down the current angle
+ current_yaw = anglemod( self.angles_y );
+ ideal = self.ideal_yaw;
+
+ if (current_yaw == ideal)
+ return;
+
+ move = ideal - current_yaw;
+ if (ideal > current_yaw)
+ {
+ if (move > 180)
+ move = move - 360;
+ }
+ else
+ {
+ if (move < -180)
+ move = move + 360;
+ }
+
+ if (move > 0)
+ {
+ if (move > self.yaw_speed)
+ move = self.yaw_speed;
+ }
+ else
+ {
+ if (move < 0-self.yaw_speed )
+ move = 0-self.yaw_speed;
+ }
+
+ current_yaw = anglemod (current_yaw + move);
+
+ self.angles_y = current_yaw;
+};
+
+*/
+
+
+//============================================================================
+
+void() HuntTarget =
+{
+ self.goalentity = self.enemy;
+ self.think = self.th_run;
+ self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
+ self.nextthink = time + 0.1;
+ SUB_AttackFinished (1); // wait a while before first attack
+};
+
+void() SightSound =
+{
+ if !(self.spawnflags & PASSIVE_ALWAYS)
+
+ local float rsnd;
+
+ if (self.classname == "monster_ogre")
+ sound_sight (self, CHAN_VOICE, "ogre/ogwake.wav", 1, ATTN_NORM);
+ else if (self.classname == "monster_ogre_marksman")
+ sound_sight (self, CHAN_VOICE, "ogre/ogwake.wav", 1, ATTN_NORM);
+ else if (self.classname == "monster_knight")
+ sound_sight (self, CHAN_VOICE, "knight/ksight.wav", 1, ATTN_NORM);
+ else if (self.classname == "monster_shambler")
+ sound_sight (self, CHAN_VOICE, "shambler/ssight.wav", 1, ATTN_NORM);
+ else if (self.classname == "monster_demon1")
+ sound_sight (self, CHAN_VOICE, "demon/sight2.wav", 1, ATTN_NORM);
+ else if (self.classname == "monster_wizard")
+ sound_sight (self, CHAN_VOICE, "wizard/wsight.wav", 1, ATTN_NORM);
+ else if (self.classname == "monster_zombie")
+ sound_sight (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_NORM);
+ else if (self.classname == "monster_dog")
+ sound_sight (self, CHAN_VOICE, "dog/dsight.wav", 1, ATTN_NORM); //dumptruck_ds
+ else if (self.classname == "monster_hell_knight")
+ sound_sight (self, CHAN_VOICE, "hknight/sight1.wav", 1, ATTN_NORM);
+ else if (self.classname == "monster_enforcer")
+ {
+ rsnd = rint(random() * 3);
+ if (rsnd == 1)
+ sound_sight (self, CHAN_VOICE, "enforcer/sight1.wav", 1, ATTN_NORM); //dumptruck_ds
+ else if (rsnd == 2)
+ sound_misc (self, CHAN_VOICE, "enforcer/sight2.wav", 1, ATTN_NORM);
+ else if (rsnd == 0)
+ sound_misc1 (self, CHAN_VOICE, "enforcer/sight3.wav", 1, ATTN_NORM);
+ else
+ sound_misc2 (self, CHAN_VOICE, "enforcer/sight4.wav", 1, ATTN_NORM);
+ }
+ else if (self.classname == "monster_army")
+ sound_sight (self, CHAN_VOICE, "soldier/sight1.wav", 1, ATTN_NORM);
+ else if (self.classname == "monster_shalrath")
+ sound_sight (self, CHAN_VOICE, "shalrath/sight.wav", 1, ATTN_NORM);
+ else if (self.classname == "monster_oldone2") //dumptruck_ds added Shub sighting SFX
+ sound_sight (self, CHAN_VOICE, "boss2/sight.wav", 1, ATTN_NONE);
+};
+
+void() FoundTarget =
+{
+ if (self.enemy.classname == "player")
+ { // let other monsters see this monster for a while
+ sight_entity = self;
+ sight_entity_time = time;
+ }
+
+ self.show_hostile = time + 1; // wake up other monsters
+
+ if !(self.spawnflags & NO_SIGHT_SOUND || self.spawnflags & PASSIVE_ALWAYS || self.spawnflags & PASSIVE_UNTIL_ATTACKED)
+ {
+ SightSound ();
+ }
+ HuntTarget ();
+
+ if (self.sight_trigger == 1) //thanks RennyC -- dumptruck_ds
+ {
+ activator = self.enemy;
+ SUB_UseAndForgetTargets ();
+ }
+};
+
+/*
+===========
+FindTarget
+
+Self is currently not attacking anything, so try to find a target
+
+Returns TRUE if an enemy was sighted
+
+When a player fires a missile, the point of impact becomes a fakeplayer so
+that monsters that see the impact will respond as if they had seen the
+player.
+
+To avoid spending too much time, only a single client (or fakeclient) is
+checked each frame. This means multi player games will have slightly
+slower noticing monsters.
+============
+*/
+float() FindTarget =
+{
+ local entity client;
+ local float r;
+
+// if the first spawnflag bit is set, the monster will only wake up on
+// really seeing the player, not another monster getting angry
+
+// spawnflags & 3 is a big hack, because zombie crucified used the first
+// spawn flag prior to the ambush flag, and I forgot about it, so the second
+// spawn flag works as well
+ if (sight_entity_time >= time - 0.1 && !(self.spawnflags & 3) )
+ {
+ client = sight_entity;
+ if (client.enemy == self.enemy)
+ return TRUE;
+ }
+ else
+ {
+ client = checkclient ();
+ if (!client)
+ return FALSE; // current check entity isn't in PVS
+ }
+
+ if ((self.spawnflags & PASSIVE_UNTIL_ATTACKED) || (self.spawnflags & PASSIVE_ALWAYS))
+ return FALSE;
+
+ if (client.flags & FL_NOTARGET || client.movetype == MOVETYPE_NOCLIP) // from Copper -- dumptruck_ds
+ return FALSE;
+
+ if (client.health <= 0)
+ return FALSE;
+
+ if (client.classname != "player")
+ if (client.enemy.health <= 0)
+ return FALSE;
+
+ if (client == self.enemy)
+ return FALSE;
+
+ if (client.flags & FL_NOTARGET)
+ return FALSE;
+ if (client.items & IT_INVISIBILITY)
+ return FALSE;
+
+ r = range (client);
+ if (r == RANGE_FAR)
+ return FALSE;
+
+ if (!visible (client))
+ return FALSE;
+
+ if (r == RANGE_NEAR)
+ {
+ if (client.show_hostile < time && !infront (client))
+ return FALSE;
+ }
+ else if (r == RANGE_MID)
+ {
+ if ( /* client.show_hostile < time || */ !infront (client))
+ return FALSE;
+ }
+
+//
+// got one
+//
+ self.enemy = client;
+ if (self.enemy.classname != "player")
+ {
+ self.enemy = self.enemy.enemy;
+ if (self.enemy.classname != "player")
+ {
+ self.enemy = world;
+ return FALSE;
+ }
+ }
+
+ FoundTarget ();
+
+ return TRUE;
+};
+
+
+//=============================================================================
+
+void(float dist) ai_forward =
+{
+ // dprint("ai_forward\n");
+ walkmove (self.angles_y, dist);
+};
+
+void(float dist) ai_back =
+{
+ // dprint("ai_back\n");
+ walkmove ( (self.angles_y+180), dist);
+};
+
+
+/*
+=============
+ai_pain
+
+stagger back a bit
+=============
+*/
+void(float dist) ai_pain =
+{
+
+ ai_back (dist);
+/*
+ local float away;
+
+ away = anglemod (vectoyaw (self.origin - self.enemy.origin)
+ + 180*(random()- 0.5) );
+
+ walkmove (away, dist);
+*/
+};
+
+/*
+=============
+ai_painforward
+
+stagger back a bit
+=============
+*/
+void(float dist) ai_painforward =
+{
+ // dprint("ai_painforward\n");
+ walkmove (self.ideal_yaw, dist);
+};
+
+/*
+=============
+ai_walk
+
+The monster is walking it's beat
+=============
+*/
+void(float dist) ai_walk =
+{
+
+ movedist = dist;
+
+ if (self.classname == "monster_dragon")
+ {
+ movetogoal (dist);
+ return;
+ }
+ // check for noticing a player
+ if (FindTarget ())
+ return;
+
+ movetogoal (dist);
+};
+
+
+/*
+=============
+ai_stand
+
+The monster is staying in one place for a while, with slight angle turns
+=============
+*/
+void() ai_stand =
+{
+ if (FindTarget ())
+ return;
+
+ if (time > self.pausetime)
+ {
+ self.th_walk ();
+ return;
+ }
+
+// change angle slightly
+
+};
+
+/*
+=============
+ai_turn
+
+don't move, but turn towards ideal_yaw
+=============
+*/
+void() ai_turn =
+{
+ if (FindTarget ())
+ return;
+
+ ChangeYaw ();
+};
+
+//=============================================================================
+
+/*
+=============
+ChooseTurn
+=============
+*/
+void(vector dest3) ChooseTurn =
+{
+ local vector dir, newdir;
+
+ dir = self.origin - dest3;
+
+ newdir_x = trace_plane_normal_y;
+ newdir_y = 0 - trace_plane_normal_x;
+ newdir_z = 0;
+
+ if (dir * newdir > 0)
+ {
+ dir_x = 0 - trace_plane_normal_y;
+ dir_y = trace_plane_normal_x;
+ }
+ else
+ {
+ dir_x = trace_plane_normal_y;
+ dir_y = 0 - trace_plane_normal_x;
+ }
+
+ dir_z = 0;
+ self.ideal_yaw = vectoyaw(dir);
+};
+
+/*
+============
+FacingIdeal
+
+============
+*/
+float() FacingIdeal =
+{
+ local float delta;
+
+ delta = anglemod(self.angles_y - self.ideal_yaw);
+ if (delta > 45 && delta < 315)
+ return FALSE;
+ return TRUE;
+};
+
+
+//=============================================================================
+
+float() WizardCheckAttack;
+float() DogCheckAttack;
+
+float() CheckAnyAttack =
+{
+ if (cutscene) // Drake devkit -- dumptruck_ds
+ if (self.enemy.classname == "camera")
+ return FALSE; // Don't attack the camera (player)!
+
+ if (!enemy_vis)
+ return FALSE;
+ if (self.classname == "monster_army")
+ return SoldierCheckAttack ();
+ if ((self.classname == "monster_ogre") || (self.classname == "monster_ogre_marksman"))
+ return OgreCheckAttack ();
+ if (self.classname == "monster_shambler")
+ return ShamCheckAttack ();
+ if (self.classname == "monster_demon1")
+ return DemonCheckAttack ();
+ if (self.classname == "monster_dog")
+ return DogCheckAttack ();
+ if (self.classname == "monster_wizard")
+ return WizardCheckAttack ();
+ return CheckAttack ();
+};
+
+
+/*
+=============
+ai_run_melee
+
+Turn and close until within an angle to launch a melee attack
+=============
+*/
+void() ai_run_melee =
+{
+ self.ideal_yaw = enemy_yaw;
+ ChangeYaw ();
+
+ if (FacingIdeal())
+ {
+ self.th_melee ();
+ self.attack_state = AS_STRAIGHT;
+ }
+};
+
+
+/*
+=============
+ai_run_missile
+
+Turn in place until within an angle to launch a missile attack
+=============
+*/
+void() ai_run_missile =
+{
+ self.ideal_yaw = enemy_yaw;
+ // dprint("ai_run_missile GO\n");
+ ChangeYaw ();
+ if (FacingIdeal())
+ {
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_turret();
+ // dprint("th_turret...\n");
+ }
+ else
+ {
+ self.th_missile ();
+ // dprint("th_missile\n");
+ }
+ self.attack_state = AS_STRAIGHT;
+ }
+};
+
+
+/*
+=============
+ai_run_slide
+
+Strafe sideways, but stay at aproximately the same range
+=============
+*/
+void() ai_run_slide =
+{
+ local float ofs;
+
+ self.ideal_yaw = enemy_yaw;
+ ChangeYaw ();
+ if (self.lefty)
+ ofs = 90;
+ else
+ ofs = -90;
+
+ if (walkmove (self.ideal_yaw + ofs, movedist))
+ return;
+
+ self.lefty = 1 - self.lefty;
+
+ walkmove (self.ideal_yaw - ofs, movedist);
+};
+
+
+/*
+=============
+ai_run
+
+The monster has an enemy it is trying to kill
+=============
+*/
+void(float dist) ai_run =
+{
+ // dprint("ai_run\n");
+ movedist = dist;
+// see if the enemy is dead
+ if ((self.enemy.health <= 0) || (self.spawnflags & PASSIVE_ALWAYS))
+ {
+ self.enemy = world;
+ // FIXME: look all around for other targets
+ if (self.oldenemy.health > 0)
+ {
+ self.enemy = self.oldenemy;
+ HuntTarget ();
+ }
+ else
+ {
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_stand ();
+ }
+ else if (self.movetarget)
+ self.th_walk ();
+ else
+ self.th_stand ();
+ return;
+ }
+ }
+
+ self.show_hostile = time + 1; // wake up other monsters
+
+// check knowledge of enemy
+ enemy_vis = visible(self.enemy);
+ if (enemy_vis)
+ self.search_time = time + 5;
+
+// look for other coop players
+ if (coop && self.search_time < time)
+ {
+ if (FindTarget ())
+ return;
+ }
+
+ enemy_infront = infront(self.enemy);
+ enemy_range = range(self.enemy);
+ enemy_yaw = vectoyaw(self.enemy.origin - self.origin);
+
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ ai_face ();
+ }
+
+ // if ((self.attack_state == AS_MISSILE) || !(self.spawnflags & I_AM_TURRET))
+ if (self.attack_state == AS_MISSILE)
+ {
+ // dprint ("ai_run_missile... from ai_run\n");
+ ai_run_missile ();
+ return;
+ }
+ // if ((self.attack_state == AS_MELEE) || !(self.spawnflags & I_AM_TURRET))
+ if (self.attack_state == AS_MELEE)
+ {
+//dprint ("ai_run_melee\n");
+ ai_run_melee ();
+ return;
+ }
+
+ if (CheckAnyAttack ())
+ return; // beginning an attack
+
+ // if ((self.attack_state == AS_SLIDING) || !(self.spawnflags & I_AM_TURRET))
+ if (self.attack_state == AS_SLIDING)
+ {
+ ai_run_slide ();
+ return;
+ }
+ // part of monster face from TheSolipsist
+ // urged to change positions
+ if (time < self.t_length) // if orientation is forced
+ {
+ ChangeYaw();
+
+ if (walkmove(self.ideal_yaw, dist))
+ return;
+
+ self.ideal_yaw += 30; // dodge left
+ ChangeYaw();
+
+ if (walkmove(self.ideal_yaw, dist))
+ return;
+
+ self.ideal_yaw -= 60; // dodge right
+ ChangeYaw();
+ ChangeYaw();
+
+ if (walkmove(self.ideal_yaw, dist))
+ return;
+
+ self.ideal_yaw += 30; // give up
+ ChangeYaw();
+ self.touch_time = self.touch_time - 0.1; // lose patience
+
+ return;
+ }
+
+if !(self.spawnflags & I_AM_TURRET) // keeps monster from moving to player - dumptruck_ds
+// head straight in
+ movetogoal (dist); // done in C code...
+};
+/*
+=============
+visibleToOther
+
+returns 1 if the entity is visible to other, even if not infront ()
+=============
+*/
+float (entity targ) visibleToOther =
+{
+ local vector spot1, spot2;
+
+ spot1 = other.origin + other.view_ofs;
+ spot2 = targ.origin + targ.view_ofs;
+ traceline(spot1, spot2, TRUE, other); // see through other monsters
+
+ if (trace_inopen && trace_inwater)
+ return FALSE; // sight line crossed contents
+
+ if (trace_fraction == 1)
+ return TRUE;
+
+ return FALSE;
+};
+
+//----------------------------------------------------------------------------

Return to the top of this page or return to the overview of this repo.

Diff qc/buttons.qc

diff --git a/qc/buttons.qc b/qc/buttons.qc
new file mode 100644
index 0000000..bc34e53
--- /dev/null
+++ b/qc/buttons.qc
@@ -0,0 +1,205 @@
+// button and multiple button
+
+void() button_wait;
+void() button_return;
+
+void() button_wait =
+{
+ self.state = STATE_TOP;
+ self.nextthink = self.ltime + self.wait;
+ self.think = button_return;
+ activator = self.enemy;
+ self.frame = 1; // use alternate textures
+
+ if (self.estate != STATE_ACTIVE)
+ return;
+
+ SUB_UseTargets();
+
+};
+
+void() button_done =
+{
+ self.state = STATE_BOTTOM;
+};
+
+void() button_return =
+{
+ if (self.estate != STATE_ACTIVE) return;
+
+ self.state = STATE_DOWN;
+ SUB_CalcMove (self.pos1, self.speed, button_done);
+ self.frame = 0; // use normal textures
+ if (self.health)
+ self.takedamage = DAMAGE_YES; // can be shot again
+};
+
+
+void() button_blocked =
+{ // do nothing, just don't ome all the way back out
+};
+
+
+void() button_fire =
+{
+ if (self.estate != STATE_ACTIVE) return;
+
+ if (self.state == STATE_UP || self.state == STATE_TOP)
+ return;
+
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+
+ self.state = STATE_UP;
+ SUB_CalcMove (self.pos2, self.speed, button_wait);
+};
+
+
+void() button_use =
+{
+ self.enemy = activator;
+ button_fire ();
+};
+
+void() button_touch =
+{
+ if (other.classname != "player")
+ return;
+ self.enemy = other;
+ button_fire ();
+};
+
+void() button_killed =
+{
+ if (self.estate != STATE_ACTIVE) return;
+
+ self.enemy = damage_attacker;
+ self.health = self.max_health;
+ self.takedamage = DAMAGE_NO; // wil be reset upon return
+ button_fire ();
+};
+
+
+
+// adapted from Copper, thanks Lunaran
+void(entity b) button_lock =
+{
+ entity oself;
+
+ if (b.estate == STATE_INACTIVE)
+ return;
+
+ oself = self;
+ self = b;
+
+ if (self.state == STATE_UP || self.state == STATE_TOP)
+ self.prevstate = STATE_TOP;
+ else
+ self.prevstate = STATE_BOTTOM;
+
+ if (self.max_health)
+ self.takedamage = DAMAGE_NO;
+ self.state = STATE_UP;
+ SUB_CalcMove (self.pos2, self.speed, button_wait);
+ self.estate = STATE_INACTIVE;
+
+ self = oself;
+}
+
+void(entity b, float dontresetstate) button_unlock =
+{
+ entity oself;
+
+ if (b.estate == STATE_ACTIVE)
+ return;
+
+ oself = self;
+ self = b;
+
+ if (!dontresetstate || self.wait != -1 || self.prevstate == STATE_BOTTOM) {
+ if (self.max_health)
+ {
+ self.takedamage = DAMAGE_YES;
+ self.health = self.max_health;
+ }
+ self.frame = 0; // use normal textures
+ self.state = STATE_DOWN;
+ SUB_CalcMove (self.pos1, self.speed, button_done);
+ }
+
+ self.estate = STATE_ACTIVE;
+
+ self = oself;
+}
+
+
+/*QUAKED func_button (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again.
+
+"angle" determines the opening direction
+"target" all entities with a matching targetname will be used
+"speed" override the default 40 speed
+"wait" override the default 1 second wait (-1 = never return)
+"lip" override the default 4 pixel lip remaining at end of move
+"health" if set, the button must be killed instead of touched
+"sounds"
+0) steam metal
+1) wooden clunk
+2) metallic click
+3) in-out
+*/
+void() func_button =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.sounds == 0)
+ {
+ precache_sound ("buttons/airbut1.wav");
+ self.noise = "buttons/airbut1.wav";
+ }
+ if (self.sounds == 1)
+ {
+ precache_sound ("buttons/switch21.wav");
+ self.noise = "buttons/switch21.wav";
+ }
+ if (self.sounds == 2)
+ {
+ precache_sound ("buttons/switch02.wav");
+ self.noise = "buttons/switch02.wav";
+ }
+ if (self.sounds == 3)
+ {
+ precache_sound ("buttons/switch04.wav");
+ self.noise = "buttons/switch04.wav";
+ }
+
+ SetMovedir ();
+
+ self.movetype = MOVETYPE_PUSH;
+ self.solid = SOLID_BSP;
+ setmodel (self, self.model);
+
+ self.blocked = button_blocked;
+ self.use = button_use;
+
+ if (self.health)
+ {
+ self.max_health = self.health;
+ self.th_die = button_killed;
+ self.takedamage = DAMAGE_YES;
+ }
+ else
+ self.touch = button_touch;
+
+ if (!self.speed)
+ self.speed = 40;
+ if (!self.wait)
+ self.wait = 1;
+ if (!self.lip)
+ self.lip = 4;
+
+ self.state = STATE_BOTTOM;
+
+ self.pos1 = self.origin;
+ self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/client.qc

diff --git a/qc/client.qc b/qc/client.qc
new file mode 100644
index 0000000..cb97b95
--- /dev/null
+++ b/qc/client.qc
@@ -0,0 +1,1447 @@
+
+// prototypes
+void () W_WeaponFrame;
+void() W_SetCurrentAmmo;
+void(entity attacker, float damage) player_pain;
+void() player_stand1;
+//void (vector org) spawn_tfog; //moved to items.qc -- dumptruck_ds
+void (vector org, entity death_owner) spawn_tdeath;
+
+
+float modelindex_eyes, modelindex_player;
+void() SUB_CheckWaiting; // in triggers.qc
+
+
+
+
+
+void() SetChangeParms =
+{
+ if (self.health <= 0)
+ {
+ SetNewParms ();
+ return;
+ }
+
+// remove items
+ self.items = self.items - (self.items &
+ (IT_KEY1 | IT_KEY2 | IT_INVISIBILITY | IT_INVULNERABILITY | IT_SUIT | IT_QUAD) );
+
+// cap super health
+ if (self.health > 100)
+ self.health = 100;
+ if (self.health < 50)
+ self.health = 50;
+ parm1 = self.items;
+ parm2 = self.health;
+ parm3 = self.armorvalue;
+ if (self.ammo_shells < 25)
+ parm4 = 25;
+ else
+ parm4 = self.ammo_shells;
+ parm5 = self.ammo_nails;
+ parm6 = self.ammo_rockets;
+ parm7 = self.ammo_cells;
+ parm8 = self.weapon;
+ parm9 = self.armortype * 100;
+};
+
+void() SetNewParms =
+{
+ parm2 = 100; // self.health
+ parm3 = 0; // self.armorvalue
+ parm5 = 0; // self.ammo_nails
+ parm6 = 0; // self.ammo_rockets
+ parm7 = 0; // self.ammo_cells
+ parm9 = 0; // self.armortype * 100
+
+// "reset_items 2" makes the player start with only the axe -- iw
+ if (world.reset_items == 2)
+ {
+ parm1 = IT_AXE; // self.items
+ parm4 = 0; // self.ammo_shells
+ parm8 = IT_AXE; // self.weapon
+ }
+ else
+ {
+ parm1 = IT_AXE | IT_SHOTGUN; // self.items
+ parm4 = 25; // self.ammo_shells
+ parm8 = IT_SHOTGUN; // self.weapon
+ }
+};
+
+void() DecodeLevelParms =
+{
+// Reset the player's inventory if they returned to the start map with
+// a rune, or if the mapper set the "reset_items" field of worldspawn to
+// a non-zero value. (The old "reset_items" check, which this replaces,
+// had a comment from dumptruck_ds thanking Spike.) -- iw
+//
+ if ((serverflags != 0 && world.model == "maps/start.bsp") ||
+ world.reset_items != 0)
+ {
+ SetNewParms ();
+ }
+
+ self.items = parm1;
+ self.health = parm2;
+ self.armorvalue = parm3;
+ self.ammo_shells = parm4;
+ self.ammo_nails = parm5;
+ self.ammo_rockets = parm6;
+ self.ammo_cells = parm7;
+ self.weapon = parm8;
+ self.armortype = parm9 * 0.01;
+};
+
+void(entity client, string savename) autosave =
+{
+ //autosavename = savename;
+ stuffcmd(client, "echo Autosaving...; wait; save ");
+ stuffcmd(client, savename);
+ stuffcmd(client, "\n");
+}
+
+/*
+=============================================================================
+
+ PLAYER GAME EDGE FUNCTIONS
+
+=============================================================================
+*/
+
+void() set_suicide_frame;
+
+// called by ClientKill and DeadThink
+void() respawn =
+{
+ if (coop)
+ {
+ // make a copy of the dead body for appearances sake
+ CopyToBodyQue (self);
+ // get the spawn parms as they were at level start
+ setspawnparms (self);
+ // respawn
+ PutClientInServer ();
+ }
+ else if (deathmatch)
+ {
+ // make a copy of the dead body for appearances sake
+ CopyToBodyQue (self);
+ // set default spawn parms
+ SetNewParms ();
+ // respawn
+ PutClientInServer ();
+ }
+ else
+ { // restart the entire server
+ localcmd ("restart\n");
+ }
+};
+
+
+/*
+============
+ClientKill
+
+Player entered the suicide command
+============
+*/
+void() ClientKill =
+
+{
+ // 1998-07-27 Suicide during intermission fix by Zhenga start
+ if ((intermission_running)&&((coop)||(deathmatch))) // not allowed during intermission
+ return;
+// 1998-07-27 Suicide during intermission fix by Zhenga end
+ bprint (self.netname);
+ bprint (" suicides\n");
+ set_suicide_frame ();
+ self.modelindex = modelindex_player;
+ self.frags = self.frags - 2; // extra penalty
+ respawn ();
+};
+
+float(vector v) CheckSpawnPoint =
+{
+ return FALSE;
+};
+
+/*
+============
+SelectSpawnPoint
+
+Returns the entity to spawn at
+============
+*/
+entity() SelectSpawnPoint =
+{
+ local entity spot;
+ local entity thing;
+ local float pcount;
+
+// testinfo_player_start is only found in regioned levels
+ spot = find (world, classname, "testplayerstart");
+ if (spot)
+ return spot;
+
+// choose a info_player_deathmatch point
+ if (coop)
+ {
+ lastspawn = find(lastspawn, classname, "info_player_coop");
+ if (lastspawn == world)
+ lastspawn = find (lastspawn, classname, "info_player_start");
+ if (lastspawn != world)
+ return lastspawn;
+ }
+ else if (deathmatch)
+ {
+ spot = lastspawn;
+ while (1)
+ {
+ spot = find(spot, classname, "info_player_deathmatch");
+ if (spot != world)
+ {
+ if (spot == lastspawn)
+ return lastspawn;
+ pcount = 0;
+ thing = findradius(spot.origin, 32);
+ while(thing)
+ {
+ if (thing.classname == "player")
+ pcount = pcount + 1;
+ thing = thing.chain;
+ }
+ if (pcount == 0)
+ {
+ lastspawn = spot;
+ return spot;
+ }
+ }
+ }
+ }
+
+ if (serverflags)
+ { // return with a rune to start
+ spot = find (world, classname, "info_player_start2");
+ if (spot)
+ return spot;
+ }
+
+ spot = find (world, classname, "info_player_start");
+ if (!spot)
+ error ("PutClientInServer: no info_player_start on level");
+
+ return spot;
+};
+
+/*
+===========
+PutClientInServer
+
+called each time a player is spawned
+============
+*/
+void() DecodeLevelParms;
+void() PlayerDie;
+void() monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+
+void() PutClientInServer =
+{
+ local entity spot;
+
+ spot = SelectSpawnPoint ();
+
+ self.classname = "player";
+ self.health = 100;
+ self.takedamage = DAMAGE_AIM;
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_WALK;
+ self.show_hostile = 0;
+ self.max_health = 100;
+ self.flags = FL_CLIENT;
+ self.air_finished = time + 12;
+ self.dmg = 2; // initial water damage
+ self.super_damage_finished = 0;
+ self.radsuit_finished = 0;
+ self.invisible_finished = 0;
+ self.invincible_finished = 0;
+ self.effects = 0;
+ self.invincible_time = 0;
+ self.deathtype = "";
+ self.gravity = 0;
+ self.wantedgravity = 0;
+ self.onladder = 0;
+ self.customkeys = 0; // support for item_key_custom -- iw
+
+ // Setup cutscene stuff. Legacy code from Zerstorer. --dumptruck_ds
+ self.script_count = 2;
+ self.script_delay = 1;
+ self.script_time = 0;
+
+
+ DecodeLevelParms ();
+
+ W_SetCurrentAmmo ();
+
+ self.attack_finished = time;
+ self.th_pain = player_pain;
+ self.th_die = PlayerDie;
+ self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+ self.deadflag = DEAD_NO;
+// paustime is set by teleporters to keep the player from moving a while
+ self.pausetime = 0;
+
+// spot = SelectSpawnPoint ();
+
+ self.origin = spot.origin + '0 0 1';
+ self.angles = spot.angles;
+ self.fixangle = TRUE; // turn this way immediately
+
+ // fog control.
+ // Looks if there's any fog values set at the current spawn point. If not, looks for those in worldspawn instead
+ if (spot.fog_density)
+ fog_save(self, spot.fog_density, spot.fog_color);
+ else if (world.fog_density)
+ fog_save(self, world.fog_density, world.fog_color);
+
+ if (spot.skyfog_density)
+ skyfog_save(self, spot.skyfog_density);
+ else if (world.skyfog_density)
+ skyfog_save(self, world.skyfog_density);
+
+ cleanUpClientStuff = 2; // decreased on subsequent frames, used to startup some fog-related stuff
+
+// oh, this is a hack!
+ setmodel (self, "progs/eyes.mdl");
+ modelindex_eyes = self.modelindex;
+
+ setmodel (self, "progs/s_null.spr"); // Drake -- dumptruck_ds
+ // setmodel (self, "progs/null_256.spr"); // Drake -- dumptruck_ds
+ mindex_inviso = self.modelindex;
+
+ setmodel (self, "progs/player.mdl");
+ modelindex_player = self.modelindex;
+
+ setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
+
+ self.view_ofs = '0 0 22';
+// Mod - Xian (May.20.97)
+// Bug where player would have velocity from their last kill
+ self.velocity = '0 0 0'; // 1998-07-21 Player moves after respawn fix by Xian
+
+ player_stand1 ();
+
+ if (deathmatch || coop)
+ {
+ makevectors(self.angles);
+ spawn_tfog (self.origin + v_forward*20);
+ }
+
+ spawn_tdeath (self.origin, self);
+};
+
+
+/*
+=============================================================================
+
+ QUAKED FUNCTIONS
+
+=============================================================================
+*/
+
+
+/*QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/player.mdl");
+}
+The normal starting point for a level.
+*/
+void() info_player_start =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+};
+
+
+/*QUAKED info_player_start2 (1 0 0) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/player.mdl");
+}
+Only used on start map for the return point from an episode.
+*/
+void() info_player_start2 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+};
+
+
+/*
+saved out by quaked in region mode
+*/
+void() testplayerstart =
+{
+};
+
+/*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/player.mdl");
+}
+potential spawning position for deathmatch games
+*/
+void() info_player_deathmatch =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+};
+
+/*QUAKED info_player_coop (1 0 1) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/player.mdl");
+}
+potential spawning position for coop games
+*/
+void() info_player_coop =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+};
+
+/*QUAKED info_monster_spawnpoint (1 0 1) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/teleport.mdl");
+}
+ spawning position for func_monster_spawner
+*/
+void() info_monster_spawnpoint =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+};
+
+/*
+===============================================================================
+
+RULES
+
+===============================================================================
+*/
+
+/*
+go to the next level for deathmatch
+only called if a time or frag limit has expired
+*/
+void() NextLevel =
+{
+ local entity o;
+
+ if (mapname == "start")
+ {
+ if (!cvar("registered"))
+ {
+ mapname = "e1m1";
+ }
+ else if (!(serverflags & 1))
+ {
+ mapname = "e1m1";
+ serverflags = serverflags | 1;
+ }
+ else if (!(serverflags & 2))
+ {
+ mapname = "e2m1";
+ serverflags = serverflags | 2;
+ }
+ else if (!(serverflags & 4))
+ {
+ mapname = "e3m1";
+ serverflags = serverflags | 4;
+ }
+ else if (!(serverflags & 8))
+ {
+ mapname = "e4m1";
+ serverflags = serverflags - 7;
+ }
+
+ o = spawn();
+ o.map = mapname;
+ }
+ else
+ {
+ // find a trigger changelevel
+ o = find(world, classname, "trigger_changelevel");
+
+ // go back to start if no trigger_changelevel
+ if (!o)
+ {
+ mapname = "start";
+ o = spawn();
+ o.map = mapname;
+ }
+ }
+
+ nextmap = o.map;
+ gameover = TRUE;
+
+ if (o.nextthink < time)
+ {
+ o.think = execute_changelevel;
+ o.nextthink = time + 0.1;
+ }
+};
+
+/*
+============
+CheckRules
+
+Exit deathmatch games upon conditions
+============
+*/
+void() CheckRules =
+{
+ local float timelimit;
+ local float fraglimit;
+
+ if (gameover) // someone else quit the game already
+ return;
+
+ timelimit = cvar("timelimit") * 60;
+ fraglimit = cvar("fraglimit");
+
+if (deathmatch && timelimit && time >= timelimit) // 1998-07-27 Timelimit/Fraglimit fix by Maddes
+ {
+ NextLevel ();
+ return;
+ }
+
+if (deathmatch && fraglimit && self.frags >= fraglimit) // 1998-07-27 Timelimit/Fraglimit fix by Maddes
+ {
+ NextLevel ();
+ return;
+ }
+};
+
+//============================================================================
+
+void() PlayerDeathThink =
+{
+ local float forward;
+
+ if ((self.flags & FL_ONGROUND))
+ {
+ forward = vlen (self.velocity);
+ forward = forward - 20;
+ if (forward <= 0)
+ self.velocity = '0 0 0';
+ else
+ self.velocity = forward * normalize(self.velocity);
+ }
+
+// wait for all buttons released
+ if (self.deadflag == DEAD_DEAD)
+ {
+ if (self.button2 || self.button1 || self.button0)
+ return;
+ self.deadflag = DEAD_RESPAWNABLE;
+ return;
+ }
+
+// wait for any button down
+ if (!self.button2 && !self.button1 && !self.button0)
+ return;
+
+ self.button0 = 0;
+ self.button1 = 0;
+ self.button2 = 0;
+ respawn();
+};
+
+/*
+===========
+PlayerClimb
+============
+*/
+void() PlayerClimb = //johnfitz
+{
+ self.velocity = '0 0 160';
+}
+
+
+void() PlayerJump =
+{
+
+ if (self.flags & FL_WATERJUMP)
+ return;
+
+ if (self.waterlevel >= 2)
+ {
+ if (self.watertype == CONTENT_WATER)
+ self.velocity_z = 100;
+ else if (self.watertype == CONTENT_SLIME)
+ self.velocity_z = 80;
+ else
+ self.velocity_z = 50;
+
+// play swiming sound
+ if (self.swim_flag < time)
+ {
+ self.swim_flag = time + 1;
+ if (random() < 0.5)
+ sound (self, CHAN_BODY, "misc/water1.wav", 1, ATTN_NORM);
+ else
+ sound (self, CHAN_BODY, "misc/water2.wav", 1, ATTN_NORM);
+ }
+
+ return;
+ }
+
+ // refactoring from Copper -- dumptruck_ds
+ if (self.movetype != MOVETYPE_NOCLIP)
+ {
+ if (!(self.flags & FL_ONGROUND)) return;
+ if ( !(self.flags & FL_JUMPRELEASED) ) return; // don't pogo stick
+ // player jumping sound
+ sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM); // h00rt
+ }
+
+ // if (!(self.flags & FL_ONGROUND))
+ // return;
+ //
+ // if ( !(self.flags & FL_JUMPRELEASED) )
+ // return; // don't pogo stick
+ // refactoring from Copper -- dumptruck_ds
+ // self.flags = not(self.flags, FL_JUMPRELEASED | FL_ONGROUND); // don't stairwalk
+
+ self.flags = self.flags - (self.flags & FL_JUMPRELEASED);
+
+ self.flags = self.flags - FL_ONGROUND; // don't stairwalk
+
+ self.button2 = 0;
+ // sound (self, CHAN_AUTO, "player/plyrjmp8.wav", 1, ATTN_NORM);
+ self.velocity_z = self.velocity_z + 270;
+};
+
+
+/*
+===========
+WaterMove
+
+============
+*/
+.float dmgtime;
+
+void() WaterMove =
+{
+//dprint (ftos(self.waterlevel));
+ // if (self.movetype == MOVETYPE_NOCLIP)
+ // return;
+ //from Copper -- dumptruck_ds
+ if (self.movetype == MOVETYPE_NOCLIP)
+ {
+ self.air_finished = time + 120;
+ return;
+ }
+
+ if (self.health < 0)
+ return;
+
+ if (self.waterlevel != 3)
+ {
+ if (self.air_finished < time)
+ sound (self, CHAN_VOICE, "player/gasp2.wav", 1, ATTN_NORM);
+ else if (self.air_finished < time + 9)
+ sound (self, CHAN_VOICE, "player/gasp1.wav", 1, ATTN_NORM);
+ self.air_finished = time + 12;
+ self.dmg = 2;
+ }
+ else if (self.air_finished < time)
+ { // drown!
+ if (self.pain_finished < time)
+ {
+ self.dmg = self.dmg + 2;
+ if (self.dmg > 15)
+ self.dmg = 10;
+ self.deathtype = "drowning";
+ T_Damage (self, world, world, self.dmg);
+ self.deathtype = "";
+ self.pain_finished = time + 1;
+ }
+ }
+
+ if (!self.waterlevel)
+ {
+ if (self.flags & FL_INWATER)
+ {
+ // play leave water sound
+ sound (self, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM);
+ self.flags = self.flags - FL_INWATER;
+ }
+ return;
+ }
+
+ if (self.watertype == CONTENT_LAVA)
+ { // do damage
+ if (self.dmgtime < time)
+ {
+ if (self.radsuit_finished > time)
+ self.dmgtime = time + 1;
+ else
+ self.dmgtime = time + 0.2;
+
+ self.deathtype = "lava";
+ T_Damage (self, world, world, 10*self.waterlevel);
+ self.deathtype = "";
+ }
+ }
+ else if (self.watertype == CONTENT_SLIME)
+ { // do damage
+ if (self.dmgtime < time && self.radsuit_finished < time)
+ {
+ self.dmgtime = time + 1;
+ self.deathtype = "slime";
+ T_Damage (self, world, world, 4*self.waterlevel);
+ self.deathtype = "";
+ }
+ }
+
+ if ( !(self.flags & FL_INWATER) )
+ {
+
+// player enter water sound
+
+ if (self.watertype == CONTENT_LAVA)
+ sound (self, CHAN_BODY, "player/inlava.wav", 1, ATTN_NORM);
+ if (self.watertype == CONTENT_WATER)
+ sound (self, CHAN_BODY, "player/inh2o.wav", 1, ATTN_NORM);
+ if (self.watertype == CONTENT_SLIME)
+ sound (self, CHAN_BODY, "player/slimbrn2.wav", 1, ATTN_NORM);
+
+ self.flags = self.flags + FL_INWATER;
+ self.dmgtime = 0;
+ }
+
+ if (! (self.flags & FL_WATERJUMP) )
+ self.velocity = self.velocity - 0.8*self.waterlevel*frametime*self.velocity;
+};
+
+void() CheckWaterJump =
+{
+ if (self.movetype == MOVETYPE_NOCLIP) // from Copper -- dumptruck_ds
+ return;
+
+ local vector start, end;
+
+// check for a jump-out-of-water
+ makevectors (self.angles);
+ start = self.origin;
+ start_z = start_z + 8;
+ v_forward_z = 0;
+ normalize(v_forward);
+ end = start + v_forward*24;
+ traceline (start, end, TRUE, self);
+ if (trace_fraction < 1)
+ { // solid at waist
+ start_z = start_z + self.maxs_z - 8;
+ end = start + v_forward*24;
+ self.movedir = trace_plane_normal * -50;
+ traceline (start, end, TRUE, self);
+ if (trace_fraction == 1)
+ { // open at eye level
+ self.flags = self.flags | FL_WATERJUMP;
+ self.velocity_z = 225;
+ self.flags = self.flags - (self.flags & FL_JUMPRELEASED);
+ self.teleport_time = time + 2; // safety net
+ return;
+ }
+ }
+};
+
+
+/*
+================
+PlayerPreThink
+
+Called every frame before physics are run
+================
+*/
+void() PlayerPreThink =
+{
+ local float do_ladder_physics;
+
+ if (intermission_running)
+ {
+ IntermissionThink (); // otherwise a button could be missed between
+ return; // the think tics
+ }
+
+ if (self.view_ofs == '0 0 0')
+ {
+ Cutscene_Think (); // Check for cutscene stuff.
+ return; // intermission or finale
+ }
+
+ // note that this code block is here, before the tests which check
+ // whether the player is dead, so that the player's gravity will be
+ // correctly updated even if they e.g. fell off a ladder because
+ // they died -- iw
+ if (self.onladder)
+ {
+ do_ladder_physics = TRUE;
+ self.gravity = 0.0000001; // not zero, because zero means "default"
+ self.onladder = 0;
+ }
+ else
+ {
+ do_ladder_physics = FALSE;
+ self.gravity = self.wantedgravity;
+ }
+
+ // If just spawned in, try to recover previous fog values from own client entity, if any
+ if (cleanUpClientStuff)
+ fog_setFromEnt(self, self);
+
+ makevectors (self.v_angle); // is this still used
+
+ CheckRules ();
+ WaterMove ();
+
+ if (self.waterlevel == 2)
+ CheckWaterJump ();
+
+ if (self.deadflag >= DEAD_DEAD)
+ {
+ PlayerDeathThink ();
+ return;
+ }
+
+ if (self.deadflag == DEAD_DYING)
+ return; // dying, so do nothing
+
+//johnfitz ladder conditions //added from Rubicon2 client.qc -- dumptruck_ds
+if (do_ladder_physics)
+{
+ if (self.button2)
+ {
+ PlayerClimb ();
+
+ /* no ladder footsteps for now
+ if (time > self.ladder_step_finished) {
+ r = random();
+ if (r > 0.66)
+ sound (self, CHAN_BODY, "ladder/metal1.wav", 0.5, ATTN_NORM);
+ else if (r > 0.33)
+ sound (self, CHAN_BODY, "ladder/metal2.wav", 0.5, ATTN_NORM);
+ else
+ sound (self, CHAN_BODY, "ladder/metal3.wav", 0.5, ATTN_NORM);
+ self.ladder_step_finished = time + 0.3;
+ }
+ */
+ }
+ else
+ {
+ self.flags = self.flags | FL_JUMPRELEASED;
+ self.velocity = 0.9 * self.velocity;
+ self.velocity_z = 0;
+ }
+}
+else
+{
+ if (self.button2)
+ PlayerJump ();
+ else
+ self.flags = self.flags | FL_JUMPRELEASED;
+} //johnfitz
+
+// teleporters can force a non-moving pause time
+ if (time < self.pausetime)
+ self.velocity = '0 0 0';
+
+ if(time > self.attack_finished && self.currentammo == 0 && self.weapon != IT_AXE)
+ {
+ self.weapon = W_BestWeapon ();
+ W_SetCurrentAmmo ();
+ }
+ // from copper -- dumptruck_ds
+ if (self.movetype == MOVETYPE_NOCLIP)
+ {
+ self.flags = self.flags | FL_FLY;
+ }
+};
+
+/*
+================
+CheckPowerups
+
+Check for turning off powerups
+================
+*/
+void() CheckPowerups =
+{
+ if (self.health <= 0)
+ return;
+
+// invisibility
+ if (self.invisible_finished)
+ {
+// sound and screen flash when items starts to run out
+ if (self.invisible_sound < time)
+ {
+ sound (self, CHAN_AUTO, "items/inv3.wav", 0.5, ATTN_IDLE);
+ self.invisible_sound = time + ((random() * 3) + 1);
+ }
+
+
+ if (self.invisible_finished < time + 3)
+ {
+ if (self.invisible_time == 1)
+ {
+ sprint (self, "Ring of Shadows magic is fading\n");
+ stuffcmd (self, "bf\n");
+ sound (self, CHAN_AUTO, "items/inv2.wav", 1, ATTN_NORM);
+ self.invisible_time = time + 1;
+ }
+
+ if (self.invisible_time < time)
+ {
+ self.invisible_time = time + 1;
+ stuffcmd (self, "bf\n");
+ }
+ }
+
+ if (self.invisible_finished < time)
+ { // just stopped
+ self.items = self.items - IT_INVISIBILITY;
+ self.invisible_finished = 0;
+ self.invisible_time = 0;
+ }
+
+ // use the eyes
+ self.frame = 0;
+ self.modelindex = modelindex_eyes;
+ }
+ else
+ self.modelindex = modelindex_player; // don't use eyes
+
+// invincibility
+ if (self.invincible_finished)
+ {
+// sound and screen flash when items starts to run out
+ if (self.invincible_finished < time + 3)
+ {
+ if (self.invincible_time == 1)
+ {
+ sprint (self, "Protection is almost burned out\n");
+ stuffcmd (self, "bf\n");
+ sound (self, CHAN_AUTO, "items/protect2.wav", 1, ATTN_NORM);
+ self.invincible_time = time + 1;
+ }
+
+ if (self.invincible_time < time)
+ {
+ self.invincible_time = time + 1;
+ stuffcmd (self, "bf\n");
+ }
+ }
+
+ if (self.invincible_finished < time)
+ { // just stopped
+ self.items = self.items - IT_INVULNERABILITY;
+ self.invincible_time = 0;
+ self.invincible_finished = 0;
+ }
+ if (self.invincible_finished > time)
+ self.effects = self.effects | EF_DIMLIGHT;
+ else
+ self.effects = self.effects - (self.effects & EF_DIMLIGHT);
+ }
+
+// super damage
+ if (self.super_damage_finished)
+ {
+
+// sound and screen flash when items starts to run out
+
+ if (self.super_damage_finished < time + 3)
+ {
+ if (self.super_time == 1)
+ {
+ sprint (self, "Quad Damage is wearing off\n");
+ stuffcmd (self, "bf\n");
+ sound (self, CHAN_AUTO, "items/damage2.wav", 1, ATTN_NORM);
+ self.super_time = time + 1;
+ }
+
+ if (self.super_time < time)
+ {
+ self.super_time = time + 1;
+ stuffcmd (self, "bf\n");
+ }
+ }
+
+ if (self.super_damage_finished < time)
+ { // just stopped
+ self.items = self.items - IT_QUAD;
+ self.super_damage_finished = 0;
+ self.super_time = 0;
+ }
+ if (self.super_damage_finished > time)
+ self.effects = self.effects | EF_DIMLIGHT;
+ else
+ self.effects = self.effects - (self.effects & EF_DIMLIGHT);
+ }
+
+// suit
+ if (self.radsuit_finished)
+ {
+ self.air_finished = time + 12; // don't drown
+
+// sound and screen flash when items starts to run out
+ if (self.radsuit_finished < time + 3)
+ {
+ if (self.rad_time == 1)
+ {
+ sprint (self, "Air supply in Biosuit expiring\n");
+ stuffcmd (self, "bf\n");
+ sound (self, CHAN_AUTO, "items/suit2.wav", 1, ATTN_NORM);
+ self.rad_time = time + 1;
+ }
+
+ if (self.rad_time < time)
+ {
+ self.rad_time = time + 1;
+ stuffcmd (self, "bf\n");
+ }
+ }
+
+ if (self.radsuit_finished < time)
+ { // just stopped
+ self.items = self.items - IT_SUIT;
+ self.rad_time = 0;
+ self.radsuit_finished = 0;
+ }
+ }
+};
+
+/*
+================
+PlayerPostThink
+
+Called every frame after physics are run
+================
+*/
+void() PlayerPostThink =
+{
+
+ if (self.view_ofs == '0 0 0')
+ return; // intermission or finale
+ if (self.deadflag)
+ return;
+
+// do weapon stuff
+
+ W_WeaponFrame ();
+
+// check to see if player landed and play landing sound
+ if ((self.jump_flag < -300) && (self.flags & FL_ONGROUND) && (self.health > 0))
+ {
+ if (self.watertype == CONTENT_WATER)
+ sound (self, CHAN_BODY, "player/h2ojump.wav", 1, ATTN_NORM);
+ else if (self.jump_flag < -650)
+ {
+ self.deathtype = "falling";
+ T_Damage (self, world, world, 5);
+ self.deathtype = "";
+ sound (self, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM);
+ }
+ else
+ sound (self, CHAN_VOICE, "player/land.wav", 1, ATTN_NORM);
+
+ self.jump_flag = 0;
+ }
+
+ if (!(self.flags & FL_ONGROUND))
+ self.jump_flag = self.velocity_z;
+
+ if (self.health > self.max_health) //dumptruck_ds -- this replaces item_megahealth_rot in items.qc
+
+ {
+ if (self.megahealth_rottime < time)
+ {
+ self.megahealth_rottime = time + 1;
+ self.health = self.health - 1;
+ }
+
+ else if (self.health <= 100) //thanks ydrol!!!
+ self.items = self.items - (self.items & IT_SUPERHEALTH);
+}
+
+CheckPowerups ();
+// from Copper -- dumptruck_ds
+if (self.movetype != MOVETYPE_NOCLIP)
+{
+ self.flags = not(self.flags, FL_FLY);
+}
+
+};
+
+
+/*
+===========
+ClientConnect
+
+called when a player connects to a server
+============
+*/
+void() ClientConnect =
+{
+ bprint (self.netname);
+ bprint (" entered the game\n");
+
+// a client connecting during an intermission can cause problems
+ if (intermission_running)
+ ExitIntermission ();
+};
+
+
+/*
+===========
+ClientDisconnect
+
+called when a player disconnects from a server
+============
+*/
+void() ClientDisconnect =
+{
+ if (gameover)
+ return;
+ // if the level end trigger has been activated, just return
+ // since they aren't *really* leaving
+
+ // let everyone else know
+ bprint (self.netname);
+ bprint (" left the game with ");
+ bprint (ftos(self.frags));
+ bprint (" frags\n");
+ sound (self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE);
+ set_suicide_frame ();
+};
+
+/*
+===========
+ClientObituary
+
+called when a player dies
+============
+*/
+void(entity targ, entity inflictor, entity attacker) ClientObituary =
+{
+ local float rnum;
+ local string deathstring, deathstring2;
+ rnum = random();
+
+ if (targ.classname == "player")
+ {
+ if (attacker.classname == "teledeath")
+ {
+ bprint (targ.netname);
+ bprint (" was telefragged by ");
+ bprint (attacker.owner.netname);
+ bprint ("\n");
+
+ attacker.owner.frags = attacker.owner.frags + 1;
+ return;
+ }
+
+ if (attacker.classname == "teledeath2")
+ {
+ bprint ("Satan's power deflects ");
+ bprint (targ.netname);
+ bprint ("'s telefrag\n");
+
+ targ.frags = targ.frags - 1;
+ return;
+ }
+// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes start
+ // double 666 telefrag
+ // (can happen often in deathmatch 4 and levels with more than one pentagram)
+ if (attacker.classname == "teledeath3")
+ {
+ bprint (targ.netname);
+ bprint (" was telefragged by ");
+ bprint (attacker.owner.netname);
+ bprint ("'s Satan's power\n");
+// 1998-07-26 only telefrag player on spot by Maddes start
+// targ.frags = targ.frags - 1;
+ attacker.owner.frags = attacker.owner.frags + 1;
+// 1998-07-26 only telefrag player on spot by Maddes end
+ return;
+ }
+// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes end
+ if (attacker.classname == "player")
+ {
+ if (targ == attacker)
+ {
+ // killed self
+ attacker.frags = attacker.frags - 1;
+ bprint (targ.netname);
+
+ if (targ.weapon == 64 && targ.waterlevel > 1)
+ {
+ bprint (" discharges into the water.\n");
+ return;
+ }
+ if (targ.weapon == IT_GRENADE_LAUNCHER)
+ bprint (" tries to put the pin back in\n");
+ else
+ bprint (" becomes bored with life\n");
+ return;
+ }
+ else if ( (teamplay == 2) && (targ.team > 0)&&(targ.team == attacker.team) )
+ {
+ if (rnum < 0.25)
+ deathstring = " mows down a teammate\n";
+ else if (rnum < 0.50)
+ deathstring = " checks his glasses\n";
+ else if (rnum < 0.75)
+ deathstring = " gets a frag for the other team\n";
+ else
+ deathstring = " loses another friend\n";
+ bprint (attacker.netname);
+ bprint (deathstring);
+ attacker.frags = attacker.frags - 1;
+ return;
+ }
+ else
+ {
+ attacker.frags = attacker.frags + 1;
+
+ rnum = attacker.weapon;
+ if (rnum == IT_AXE)
+ {
+ deathstring = " was ax-murdered by ";
+ deathstring2 = "\n";
+ }
+ if (rnum == IT_SHOTGUN)
+ {
+ deathstring = " chewed on ";
+ deathstring2 = "'s boomstick\n";
+ }
+ if (rnum == IT_SUPER_SHOTGUN)
+ {
+ deathstring = " ate 2 loads of ";
+ deathstring2 = "'s buckshot\n";
+ }
+ if (rnum == IT_NAILGUN)
+ {
+ deathstring = " was nailed by ";
+ deathstring2 = "\n";
+ }
+ if (rnum == IT_SUPER_NAILGUN)
+ {
+ deathstring = " was punctured by ";
+ deathstring2 = "\n";
+ }
+ if (rnum == IT_GRENADE_LAUNCHER)
+ {
+ deathstring = " eats ";
+ deathstring2 = "'s pineapple\n";
+ if (targ.health < -40)
+ {
+ deathstring = " was gibbed by ";
+ deathstring2 = "'s grenade\n";
+ }
+ }
+ if (rnum == IT_ROCKET_LAUNCHER)
+ {
+ deathstring = " rides ";
+ deathstring2 = "'s rocket\n";
+ if (targ.health < -40)
+ {
+ deathstring = " was gibbed by ";
+ deathstring2 = "'s rocket\n" ;
+ }
+ }
+ if (rnum == IT_LIGHTNING)
+ {
+ deathstring = " accepts ";
+ if (attacker.waterlevel > 1)
+ deathstring2 = "'s discharge\n";
+ else
+ deathstring2 = "'s shaft\n";
+ }
+ bprint (targ.netname);
+ bprint (deathstring);
+ bprint (attacker.netname);
+ bprint (deathstring2);
+ }
+ return;
+ }
+ else
+ {
+ targ.frags = targ.frags - 1;
+ bprint (targ.netname);
+
+ // custom obituary messages
+ if (inflictor.deathtype != "")
+ {
+ bprint (" ");
+ bprint (inflictor.deathtype);
+ bprint ("\n");
+ return;
+ }
+ if (attacker.deathtype != "")
+ {
+ bprint (" ");
+ bprint (attacker.deathtype);
+ bprint ("\n");
+ return;
+ }
+
+ // killed by a montser?
+ // if (attacker.flags & FL_MONSTER)
+ if ((attacker.flags & FL_MONSTER) && (attacker.obit_name == ""))
+ {
+ if (attacker.classname == "monster_army")
+ bprint (" was shot by a Grunt\n");
+ if (attacker.classname == "monster_demon1")
+ bprint (" was eviscerated by a Fiend\n");
+ if (attacker.classname == "monster_dog")
+ bprint (" was mauled by a Rottweiler\n");
+ if (attacker.classname == "monster_dragon")
+ bprint (" was fried by a Dragon\n");
+ if (attacker.classname == "monster_enforcer")
+ bprint (" was blasted by an Enforcer\n");
+ if (attacker.classname == "monster_fish")
+ bprint (" was fed to the Rotfish\n");
+ if (attacker.classname == "monster_hell_knight")
+ bprint (" was slain by a Death Knight\n");
+ if (attacker.classname == "monster_knight")
+ bprint (" was slashed by a Knight\n");
+ if (attacker.classname == "monster_ogre")
+ bprint (" was destroyed by an Ogre\n");
+ if (attacker.classname == "monster_ogre_marksman")
+ bprint (" was felled by a Marksman\n"); // dumptruck_ds
+ if (attacker.classname == "monster_oldone")
+ bprint (" became one with Shub-Niggurath\n");
+ if (attacker.classname == "monster_oldone2")// dumptruck_ds
+ bprint (" became one with Shub-Niggurath\n");
+ if (attacker.classname == "monster_boss2")// dumptruck_ds
+ bprint (" was exploded by Chthon\n");
+ if (attacker.classname == "monster_boss")// dumptruck_ds
+ bprint (" was exploded by Chthon\n");
+ if (attacker.classname == "monster_shalrath")
+ bprint (" was exploded by a Vore\n");
+ if (attacker.classname == "monster_shambler")
+ bprint (" was smashed by a Shambler\n");
+ if (attacker.classname == "monster_vomit")
+ bprint (" was vomited on by a Vomitus\n");
+ if (attacker.classname == "monster_wizard")
+ bprint (" was scragged by a Scrag\n");
+ if (attacker.classname == "monster_zombie")
+ bprint (" joins the Zombies\n");
+
+ return;
+ }
+ // obits for custom monsters -- progs_dump -- dumptruck_ds
+ if (attacker.obit_name != "")
+ {
+ bprint (" was ");
+ if !(attacker.obit_method)
+ bprint ("killed");
+ else
+ bprint (attacker.obit_method); // e.g. ripped apart
+ bprint (" by ");
+ bprint (attacker.obit_name); // a bad monster
+ bprint ("\n");
+ return;
+ }
+
+ // tricks and traps
+ if (attacker.classname == "explo_box" ||
+ attacker.classname == "play_explosion")
+ {
+ bprint (" blew up\n");
+ return;
+ }
+ if (attacker.classname == "func_laser")
+ {
+ bprint (" discovered that lasers are hot\n");
+ return;
+ }
+ if ((attacker.solid == SOLID_BSP &&
+ attacker != world &&
+ attacker.classname != "togglewall") ||
+ (inflictor.classname == "func_movewall" &&
+ !(inflictor.spawnflags & MOVEWALL_TOUCH)))
+ {
+ bprint (" was squished\n");
+ return;
+ }
+ if (attacker.classname == "trap_shooter" ||
+ attacker.classname == "trap_spikeshooter" ||
+ attacker.classname == "trap_switched_shooter")
+ {
+ // bprint (" was spiked\n");
+ bprint (" was unlucky\n"); //changed for custom shooters --dumptruck_ds
+ return;
+ }
+ if (attacker.classname == "ltrail_start" ||
+ attacker.classname == "ltrail_relay")
+ {
+ bprint (" had an electrifying experience\n");
+ return;
+ }
+ if (attacker.classname == "fireball")
+ {
+ bprint (" ate a lavaball\n");
+ return;
+ }
+ if (attacker.classname == "trigger_changelevel")
+ {
+ bprint (" tried to leave\n");
+ return;
+ }
+
+ // in-liquid deaths
+ if (targ.deathtype == "drowning")
+ {
+ if (random() < 0.5)
+ bprint (" sleeps with the fishes\n");
+ else
+ bprint (" sucks it down\n");
+ return;
+ }
+ if (targ.deathtype == "slime")
+ {
+ if (random() < 0.5)
+ bprint (" gulped a load of slime\n");
+ else
+ bprint (" can't exist on slime alone\n");
+ return;
+ }
+ if (targ.deathtype == "lava")
+ {
+ if (targ.health < -15)
+ {
+ bprint (" burst into flames\n");
+ return;
+ }
+ if (random() < 0.5)
+ bprint (" turned into hot slag\n");
+ else
+ bprint (" visits the Volcano God\n");
+ return;
+ }
+
+ // fell to their death?
+ if (targ.deathtype == "falling")
+ {
+ bprint (" fell to his death\n");
+ return;
+ }
+
+ // hell if I know; he's just dead!!!
+ bprint (" died\n");
+ }
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/combat.qc

diff --git a/qc/combat.qc b/qc/combat.qc
new file mode 100644
index 0000000..83ca79a
--- /dev/null
+++ b/qc/combat.qc
@@ -0,0 +1,366 @@
+
+void() T_MissileTouch;
+void() info_player_start;
+void(entity targ, entity inflictor, entity attacker) ClientObituary;
+
+void() monster_death_use;
+
+//============================================================================
+
+/*
+============
+CanDamage
+
+Returns true if the inflictor can directly damage the target. Used for
+explosions and melee attacks.
+============
+*/
+float(entity targ, entity inflictor) CanDamage =
+{
+// bmodels need special checking because their origin is 0,0,0
+ if (targ.movetype == MOVETYPE_PUSH)
+ {
+ traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self);
+ if (trace_fraction == 1)
+ return TRUE;
+ if (trace_ent == targ)
+ return TRUE;
+ return FALSE;
+ }
+
+ traceline(inflictor.origin, targ.origin, TRUE, self);
+ if (trace_fraction == 1)
+ return TRUE;
+ traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self);
+ if (trace_fraction == 1)
+ return TRUE;
+ traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self);
+ if (trace_fraction == 1)
+ return TRUE;
+ traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self);
+ if (trace_fraction == 1)
+ return TRUE;
+ traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self);
+ if (trace_fraction == 1)
+ return TRUE;
+
+ return FALSE;
+};
+
+
+/*
+============
+Killed
+============
+*/
+void(entity targ, entity inflictor, entity attacker) Killed =
+{
+ local entity oself;
+
+ oself = self;
+ self = targ;
+
+ if (self.health < -99)
+ self.health = -99; // don't let sbar look bad if a player
+
+ if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE)
+ { // doors, triggers, etc
+ self.th_die ();
+ self = oself;
+ return;
+ }
+
+ self.enemy = attacker;
+
+// bump the monster counter
+ if (self.flags & FL_MONSTER)
+ {
+ killed_monsters = killed_monsters + 1;
+ WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
+ }
+
+ ClientObituary (self, inflictor, attacker);
+
+ self.takedamage = DAMAGE_NO;
+ self.touch = SUB_Null;
+
+ monster_death_use();
+ self.th_die ();
+
+ self = oself;
+};
+
+
+/*
+============
+T_Damage
+
+The damage is coming from inflictor, but get mad at attacker
+This should be the only function that ever reduces health.
+============
+*/
+void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
+{
+ local vector dir;
+ local entity oldself;
+ local float save;
+ local float take;
+ local float ignore_armor; //johnfitz
+ local string death_type; //johnfitz
+
+ // don't try to damage the world. Not healthy - bmFbr
+ if (!targ)
+ return;
+
+ //johnfitz -- make sure targ.deathtype doesn't keep stale info after this function is done
+ death_type = targ.deathtype;
+ targ.deathtype = "";
+ //johnfitz
+
+ if (!targ.takedamage)
+ return;
+
+ //johnfitz -- some func_breakables ignore monster damage //added from Rubicon2 combat.qc dumptruck_ds
+ if (targ.classname == "func_breakable")
+ {
+ if (targ.spawnflags & BREAKABLE_NO_MONSTERS && attacker.flags & FL_MONSTER)
+ return;
+ }
+ //johnfitz
+
+// used by buttons and triggers to set activator for target firing
+ damage_attacker = attacker;
+
+// check for quad damage powerup on the attacker
+ if (attacker.super_damage_finished > time)
+ damage = damage * 4;
+
+ // damage mod for monsters -- dumptruck_ds
+ if (attacker.damage_mod)
+ damage = damage * attacker.damage_mod;
+
+ //don't deplete armor if drowning/burning, or protected by biosuit/pentagram/godmode (note: in ID1 pentagram/godmode doesn't actually protect your armor)
+ if (death_type == "burning" || death_type == "drowning" || targ.invincible_finished >= time || targ.flags & FL_GODMODE)
+ ignore_armor = TRUE;
+ else
+ ignore_armor = FALSE;
+//johnfitz
+// save damage based on the target's armor level
+ if (ignore_armor) //johnfitz -- some damage doesn't deplete armor
+ {
+ save = 0;
+ }
+ else
+ {
+ save = ceil(targ.armortype*damage);
+ if (save >= targ.armorvalue)
+ {
+ save = targ.armorvalue;
+ targ.armortype = 0; // lost all armor
+ targ.items = targ.items - (targ.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3));
+ }
+}
+// // 1998-08-12 Drowning doesn't hurt armor by Maddes/Athos start
+// }
+// else
+// save = 0;
+// // 1998-08-12 Drowning doesn't hurt armor by Maddes/Athos end
+ targ.armorvalue = targ.armorvalue - save;
+ take = ceil(damage-save);
+
+// add to the damage total for clients, which will be sent as a single
+// message at the end of the frame
+// FIXME: remove after combining shotgun blasts?
+ if (targ.flags & FL_CLIENT)
+ {
+ targ.dmg_take = targ.dmg_take + take;
+ targ.dmg_save = targ.dmg_save + save;
+ targ.dmg_inflictor = inflictor;
+ }
+
+// figure momentum add
+ if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
+ {
+ dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
+ dir = normalize(dir);
+ targ.velocity = targ.velocity + dir*damage*8;
+ }
+
+// check for godmode or invincibility
+ if (targ.flags & FL_GODMODE)
+ return;
+ if (targ.invincible_finished >= time)
+ {
+ if (self.invincible_sound < time)
+ {
+ sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
+ self.invincible_sound = time + 2;
+ }
+ return;
+ }
+
+// team play damage avoidance
+// 1998-07-29 Teamplay 1 fix by Maddes start
+ if ( (teamplay == 1) && (targ.team > 0) && (targ.team == attacker.team)
+ && (targ != attacker)
+ && (attacker.classname == "player")
+ && (inflictor.classname != "door") ) // because squishing a teammate is still possible
+// 1998-07-29 Teamplay 1 fix by Maddes end
+ return;
+
+// do the damage
+ targ.health = targ.health - take;
+
+// fire pain_target if appropriate
+ if ((targ.flags & FL_MONSTER) &&
+ targ.pain_target != "" &&
+ targ.health <= targ.pain_threshold)
+ {
+ oldself = self;
+ self = targ;
+ monster_pain_use ();
+ self = oldself;
+ }
+
+ if (targ.health <= 0)
+ {
+ Killed (targ, inflictor, attacker);
+ return;
+ }
+
+// react to the damage
+ oldself = self;
+ self = targ;
+
+ if ( (self.flags & FL_MONSTER) && attacker != world)
+ {
+ // get mad unless of the same class (except for soldiers)
+ if (self != attacker && attacker != self.enemy)
+ {
+ local float mode;
+ mode = 0;
+ // take highest mode so infighting happens consistently
+ if (self.infight_mode == -1 || self.infight_mode > mode)
+ {
+ mode = self.infight_mode;
+ }
+ if (mode != -1 && attacker.infight_mode > mode)
+ {
+ mode = attacker.infight_mode;
+ }
+ //soldiers of the same style will infight -- dumptruck_ds - thanks for c0burn and Shamblernaut for your help!
+ if (mode == -1)
+ {
+ if (attacker.classname == "player")
+ {
+ if (self.enemy.classname == "player")
+ self.oldenemy = self.enemy;
+ self.enemy = attacker;
+ FoundTarget ();
+ }
+ }
+ else if (
+ (self.classname != attacker.classname) ||
+ ((self.classname == "monster_army") && (self.style == attacker.style)) ||
+ (mode > 0 && self.mdl_body != attacker.mdl_body) || // infight if different models
+ (mode > 1 && self.skin != attacker.skin) || // infight if different skin
+ (mode > 2) // always infight
+ )
+ {
+ if (self.enemy.classname == "player")
+ self.oldenemy = self.enemy;
+ self.enemy = attacker;
+ FoundTarget ();
+ }
+ }
+ }
+
+ if (self.th_pain)
+ {
+ self.th_pain (attacker, take);
+ // nightmare mode monsters don't go into pain frames often
+ if (skill == 3)
+ self.pain_finished = time + 5;
+ }
+
+ self = oldself;
+};
+
+/*
+============
+T_RadiusDamage
+============
+*/
+void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =
+{
+ local float points;
+ local entity head;
+ local vector org;
+
+ head = findradius(inflictor.origin, damage+40);
+
+ while (head)
+ {
+ if (head != ignore)
+ {
+ if (head.takedamage)
+ {
+ org = head.origin + (head.mins + head.maxs)*0.5;
+ points = 0.5*vlen (inflictor.origin - org);
+ if (points < 0)
+ points = 0;
+ points = damage - points;
+ if (head == attacker)
+ points = points * 0.5;
+ if (points > 0)
+ {
+ if (CanDamage (head, inflictor))
+ { // shambler takes half damage from all explosions
+ if (head.classname == "monster_shambler")
+ T_Damage (head, inflictor, attacker, points*0.5);
+ else
+ T_Damage (head, inflictor, attacker, points);
+ }
+ }
+ }
+ }
+ head = head.chain;
+ }
+};
+
+/*
+============
+T_BeamDamage
+============
+*/
+void(entity attacker, float damage) T_BeamDamage =
+{
+ local float points;
+ local entity head;
+
+ head = findradius(attacker.origin, damage+40);
+
+ while (head)
+ {
+ if (head.takedamage)
+ {
+ points = 0.5*vlen (attacker.origin - head.origin);
+ if (points < 0)
+ points = 0;
+ points = damage - points;
+ if (head == attacker)
+ points = points * 0.5;
+ if (points > 0)
+ {
+ if (CanDamage (head, attacker))
+ {
+ if (head.classname == "monster_shambler")
+ T_Damage (head, attacker, attacker, points*0.5);
+ else
+ T_Damage (head, attacker, attacker, points);
+ }
+ }
+ }
+ head = head.chain;
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/cshift.qc

diff --git a/qc/cshift.qc b/qc/cshift.qc
new file mode 100644
index 0000000..f7410a7
--- /dev/null
+++ b/qc/cshift.qc
@@ -0,0 +1,75 @@
+
+inline void(entity client, float density, vector color) csf_save = {
+ client.csf_color = color;
+ client.csf_density = density;
+}
+
+inline void(entity client) csf_apply = {
+ stuffcmd(client, "\nv_cshift ");
+ stuffcmd(client, ftos(client.csf_color_x));
+ stuffcmd(client, " ");
+ stuffcmd(client, ftos(client.csf_color_y));
+ stuffcmd(client, " ");
+ stuffcmd(client, ftos(client.csf_color_z));
+ stuffcmd(client, " ");
+ stuffcmd(client, ftos(client.csf_density));
+ stuffcmd(client, "\n");
+}
+
+void(entity client, float density, vector color) csf_set = {
+ csf_save(client, density, color);
+ csf_apply(client);
+}
+
+void() csfcontroller_think = {
+
+ entity e = self.owner;
+
+ if (self.pain_finished > time && e.csf_density != self.csf_density) {
+
+ float density;
+ vector color;
+
+ float fraction = 1 - (self.pain_finished - time) / self.speed; //wat
+
+ density = lerpHermite(e.csf_density, self.csf_density, fraction);
+ color = lerpVectorHermite(e.csf_color, self.csf_color, fraction);
+
+ csf_set(e, density, color);
+
+ self.nextthink = time + 0.04;
+ }
+ else {
+ csf_set(e, self.csf_density, self.csf_color);
+ }
+
+}
+
+
+void(entity client) csfcontroller_start = {
+ if (client.csfcontroller.classname == "csfcontroller" && client.csfcontroller.owner == client)
+ return;
+
+ entity e = spawn();
+ client.csfcontroller = e;
+ e.owner = client;
+ e.classname = "csfcontroller";
+ e.think = csfcontroller_think;
+}
+
+
+void(entity client, float density, vector color, float spd) csf_fade = {
+ csfcontroller_start(client);
+
+ entity ct = client.csfcontroller;
+
+ ct.speed = spd;
+ ct.pain_finished = time + spd;
+ ct.csf_color = color;
+ ct.csf_density = density;
+ ct.nextthink = time + 0.04;
+}
+
+
+
+

Return to the top of this page or return to the overview of this repo.

Diff qc/csqc/csqc_defs.qc

diff --git a/qc/csqc/csqc_defs.qc b/qc/csqc/csqc_defs.qc
new file mode 100644
index 0000000..7172e91
--- /dev/null
+++ b/qc/csqc/csqc_defs.qc
@@ -0,0 +1,398 @@
+//======================================================================
+// Author : Simon "Sock" OCallaghan
+// Website: www.simonoc.com
+//
+// This is a special defs file with all the relevant CSQC references
+// Should be included into progs and csprogs to reduce duplicates
+//
+//----------------------------------------------------------------------
+// The CSQC files are setup to be self contained and easy to port
+// to other MODS, but some stuff needs to exist in other QC files
+// In world.qc the extra variables for AD are located there
+//
+//----------------------------------------------------------------------
+// Special Variables used by CSQC (Client Side Quake C)
+// The engine will keep these insync between server and client
+// Defined with the addstat/clientstat command DP/FTE
+//----------------------------------------------------------------------
+
+const float CLIENT_HEALTH = 0; // Player's health
+const float CLIENT_WEAPONMODELI = 2; // Modelidx of current viewmodel
+const float CLIENT_AMMO = 3; // player.currentammo
+const float CLIENT_ARMOR = 4;
+const float CLIENT_WEAPONFRAME = 5;
+const float CLIENT_SHELLS = 6;
+const float CLIENT_NAILS = 7;
+const float CLIENT_ROCKETS = 8;
+const float CLIENT_CELLS = 9;
+const float CLIENT_ACTIVEWEAPON = 10; // player.weapon
+const float CLIENT_TOTALSECRETS = 11;
+const float CLIENT_TOTALMONSTERS = 12;
+const float CLIENT_FOUNDSECRETS = 13;
+const float CLIENT_KILLEDMONSTERS = 14;
+// getstatbits(CLIENT_ITEMS,0,23) to read self.items
+// getstatbits(CLIENT_ITEMS,23,11) to read self.items2
+// or getstatbits(CLIENT_ITEMS,28,4) to read the visible part of serverflags
+const float CLIENT_ITEMS = 15; // self.items | (self.items2<<23)
+const float CLIENT_VIEWHEIGHT = 16; // player.view_ofs_z
+const float CLIENT_VIEW2 = 20; // Entity Qty in server's .view2 field
+const float CLIENT_VIEWZOOM = 21; // Scales fov and sensitiity
+const float CLIENT_IDEALPITCH = 25;
+const float CLIENT_PUNCHANGLE_X = 26;
+const float CLIENT_PUNCHANGLE_Y = 27;
+const float CLIENT_PUNCHANGLE_Z = 28;
+// 32-127 is custom variables (defined here and linked in world.qc)
+const float CLIENT_MODITEMS = 40; // self.moditems (AD extra stuff)
+const float CLIENT_CKEYNAME1 = 50; // self.ckeyname1
+const float CLIENT_CKEYNAME2 = 51; // self.ckeyname2
+const float CLIENT_CKEYNAME3 = 52; // self.ckeyname3
+const float CLIENT_CKEYNAME4 = 53; // self.ckeyname4
+const float CLIENT_CKEYSKIN1 = 55; // self.ckeyskin1
+const float CLIENT_CKEYSKIN2 = 56; // self.ckeyskin2
+const float CLIENT_CKEYSKIN3 = 57; // self.ckeyskin3
+const float CLIENT_CKEYSKIN4 = 58; // self.ckeyskin4
+// CEV
+const float CLIENT_VELOCITY_X = 64;
+const float CLIENT_VELOCITY_Y = 65;
+
+//----------------------------------------------------------------------
+// Duplicate of IT_ references in defs.qc
+//----------------------------------------------------------------------
+const float CSQC_SHOTGUN = 1<<0; // 1
+const float CSQC_SUPER_SHOTGUN = 1<<1; // 2
+const float CSQC_NAILGUN = 1<<2; // 4
+const float CSQC_SUPER_NAILGUN = 1<<3; // 8
+const float CSQC_GRENADE_LAUNCHER = 1<<4; // 16
+const float CSQC_ROCKET_LAUNCHER = 1<<5; // 32
+const float CSQC_LIGHTNING = 1<<6; // 64
+// const float CSQC_EXTRA_WEAPON = 1<<7; // 128
+
+const float CSQC_SHELLS = 1<<8; // 256
+const float CSQC_NAILS = 1<<9; // 512
+const float CSQC_ROCKETS = 1<<10; // 1024
+const float CSQC_CELLS = 1<<11; // 2048
+const float CSQC_AXE = 1<<12; // 4096
+
+const float CSQC_ARMOR1 = 1<<13; // 8192
+const float CSQC_ARMOR2 = 1<<14; // 16384
+const float CSQC_ARMOR3 = 1<<15; // 32768
+// const float CSQC_SUPERHEALTH = 1<<16; // 65536
+
+const float CSQC_KEY1 = 1<<17; // 131072
+const float CSQC_KEY2 = 1<<18; // 262144
+
+const float CSQC_INVISIBILITY = 1<<19; // 524288
+const float CSQC_INVULNERABILITY = 1<<20; // 1048576
+const float CSQC_SUIT = 1<<21; // 2097152
+const float CSQC_QUAD = 1<<22; // 4194304
+
+// Runes in Serverflags
+const float CSQC_RUNE1 = 1<<5; // 32
+const float CSQC_RUNE2 = 1<<6; // 64
+const float CSQC_RUNE3 = 1<<7; // 128
+const float CSQC_RUNE4 = 1<<8; // 256
+
+// Variable types
+const float EV_VOID = 0;
+const float EV_STRING = 1;
+const float EV_FLOAT = 2;
+const float EV_VECTOR = 3;
+const float EV_ENTITY = 4;
+const float EV_FIELD = 5;
+const float EV_FUNCTION = 6;
+const float EV_POINTER = 7;
+const float EV_INTEGER = 8;
+
+// ======================================================================
+// This is a merge of three (DP/FTE/QSS) engine def files
+// dpextensions+csprogsdefs from SVN ICCULUS site (DP trunk)
+// fteexentions from triptohell website
+// qsextensions from QSS devkit on triptohell website
+//
+// CSQC range #300-#399
+// ======================================================================
+
+// ----------------------------------------------------------------------
+// DP/FTE extensions ONLY
+// ----------------------------------------------------------------------
+// Forgets all rentities, polygons, and temporary dlights.
+// Resets all view properties to their default values.
+void() clearscene = #300;
+void(float mask) addentities = #301;
+// Copies the entity fields into a new rentity for
+// later rendering via addscene
+void(entity ent) addentity = #302;
+// Allows you to override default view properties like
+// viewport, fov, and whether the engine hud will be drawn.
+// Different VF_ values have slightly different arguments,
+// some are vectors, some floats.
+float(float property, ...) setproperty = #303;
+// Draws all entities, polygons, and particles on the rentity list
+// (which were added via addentities or addentity), using the various
+// view properties set via setproperty. There is no ordering dependancy.
+// The scene must generally be cleared again before more entities
+// are added, as entities will persist even over to the next frame.
+// You may call this builtin multiple times per frame, but should
+// only be called from CSQC_UpdateView.
+void() renderscene = #304;
+// Adds a temporary dlight, ready to be drawn via addscene.
+// Cubemap orientation will be read from v_forward/v_right/v_up.
+void(vector org, float radius, vector lightcolours) adddynamiclight = #305;
+void(vector org, float radius, vector lightcolours, float style, string cubemapname, float pflags) adddynamiclight2 = #305;
+// Specifies the shader to use for the following polygons, along
+// with optional flags.
+// If is2d, the polygon will be drawn as soon as the EndPolygon
+// call is made, rather than waiting for renderscene. This allows
+// complex 2d effects.
+// FTE = void(string texturename, optional float flags, optional float is2d) R_BeginPolygon = #306;
+void(string texturename, float flag, ...) R_BeginPolygon = #306;
+// Specifies a polygon vertex with its various properties
+void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex = #307;
+// Ends the current polygon. At least 3 verticies must have been
+// specified. You do not need to call beginpolygon if you wish to
+// draw another polygon with the same shader
+void() R_EndPolygon = #308;
+// Retrieve a currently-set (typically view) property, allowing you
+// to read the current viewport or other things. Due to cheat protection,
+// certain values may be unretrievable
+// define = FTE version of DP version
+#define getviewprop getproperty
+float(float property) getproperty = #309;
+vector(float property) getpropertyvec = #309;
+// Transform a 2d screen-space point (with depth) into a 3d world-space
+// point, according the various origin+angle+fov etc settings set via
+// setproperty
+vector (vector v) cs_unproject = #310;
+// Transform a 3d world-space point into a 2d screen-space point,
+// according the various origin+angle+fov etc settings set via
+// setproperty
+vector (vector v) cs_project = #311;
+// Draws a 2d line between the two 2d points
+void(float width, vector pos1, vector pos2, vector rgb, float alpha, float flag) drawline = #315;
+// Tells the engine that the image is no longer needed.
+// The image will appear to be new the next time its needed
+void(string name) freepic = #319;
+// Draws the specified string without using any markup at all,
+// even in engines that support it.
+// If UTF-8 is globally enabled in the engine, then that encoding
+// is used (without additional markup), otherwise it is raw quake chars.
+// Software engines may assume a size of '8 8 0', rgb='1 1 1',
+// alpha=1, flag&3=0, but it is not an error to draw out of the screen.
+float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring = #321;
+// Retrieves the value of the given EV_STRING stat, as a tempstring.
+// Older engines may use 4 consecutive integer stats, with a limit
+// of 15 chars (yes, really. 15.), but FTE Quake uses a separate
+// namespace for string stats and has a much higher length limit.
+string(float stnum) getstats = #332;
+// Retrieves the name of the model based upon a precache index.
+// This can be used to reduce csqc network traffic by enabling
+// model matching
+string(float mdlindex) modelnameforindex = #334;
+// Looks up a named font slot. Matches the actual font name as a last resort.
+// find font by fontname and return it's index
+float findfont(string s) = #356;
+float loadfont(string fontname, string fontmaps, string sizes, float slot, float fix_scale, float fix_voffset) = #357;
+
+// ----------------------------------------------------------------------
+// QSS (CSQC Lit) + DP/FTE extensions
+// ----------------------------------------------------------------------
+// Checks to see if the image is currently loaded.
+// Engines might lie, or cache between maps.
+float(string name) iscachedpic = #316;
+// Forces the engine to load the named image. If trywad is specified,
+// the specified name must any lack path and extension.
+string(string name, optional float trywad) precache_pic = #317;
+// Returns the dimensions of the named image. Images specified
+// with .lmp should give the original .lmp's dimensions even if
+// texture replacements use a different resolution.
+// define = FTE version of DP version
+#define drawgetimagesize draw_getimagesize
+vector(string picname) draw_getimagesize = #318;
+// Draw the given quake character at the given position.
+// If flag&4, the function will consider the char to be a unicode
+// char instead (or display as a ? if outside the 32-127 range).
+// size should normally be something like '8 8 0'.
+// rgb should normally be '1 1 1' and alpha normally 1.
+// Software engines may assume the named defaults.
+// Note that ALL text may be rescaled on the X axis due to
+// variable width fonts. The X axis may even be ignored completely.
+float(vector position, float character, vector scale, vector rgb, float alpha, float flag) drawcharacter = #320;
+// Draws an shader within the given 2d screen box. Software engines
+// may omit support for rgb+alpha, but must support rescaling,
+// and must clip to the screen without crashing
+// flag = draw method; 0=normal, 1=additive, 2=modulate, 3=modulate2
+float(vector position, string pic, vector size, vector rgb, float alpha, float flag) drawpic = #322;
+// Draws a solid block over the given 2d box, with given colour,
+// alpha, and blend mode (specified via flags).
+// flags&3=0 simple blend flags&3=1 additive blend
+float(vector position, vector size, vector rgb, float alpha, float flag) drawfill = #323;
+// Specifies a 2d clipping region (aka: scissor test).
+// 2d draw calls will all be clipped to this 2d box,
+// the area outside will not be modified by any
+// 2d draw call (even 2d polygons).
+void(float x, float y, float width, float height) drawsetcliparea = #324;
+// Reverts the scissor/clip area to the whole screen
+void(void) drawresetcliparea = #325;
+// Draws a string, interpreting markup and recolouring as appropriate
+// QSS/FTE = drawstring, DP = drawcolorcodedstring/drawcolorcodedstring2
+// float(vector position, string text, vector size, vector rgb, float alpha, float drawflag) drawstring = #326;
+float(vector position, string text, vector scale, float alpha, float flag) drawcolorcodedstring = #326;
+vector(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawcolorcodedstring2 = #326;
+// Calculates the width of the screen in virtual pixels.
+// If usecolours is 1, markup that does not affect the string
+// width will be ignored. Will always be decoded as UTF-8 if
+// UTF-8 is globally enabled.
+// If the char size is not specified, '8 8 0' will be assumed
+// float(string text, float usecolours, optional vector fontsize) stringwidth = #327;
+// QSS/FTE = float(string text, float usecolours, optional vector fontsize) stringwidth = #327;
+float(string text, float allowColorCodes, vector size) stringwidth = #327;
+// Draws a rescaled subsection of an image to the screen
+// QSS/FTE = void(vector pos, vector sz, string pic, vector srcpos, vector srcsz, vector rgb, float alpha, optional float drawflag) drawsubpic = #328;
+float(vector position, vector size, string pic, vector srcPosition, vector srcSize, vector rgb, float alpha, float flag) drawsubpic = #328;
+// Nasty convoluted DP extension. Typically returns deltas instead
+// of positions. Use CSQC_InputEvent for such things in csqc mods
+vector() getmousepos = #344;
+// Looks up an input frame from the log, setting the input_*
+// globals accordingly.
+// The sequence number range used for prediction should normally
+// be servercommandframe < sequence <= clientcommandframe.
+// The sequence equal to clientcommandframe will change between
+// input frames
+float(float framenum) getinputstate = #345;
+// Perform the engine's standard player movement prediction upon
+// the given entity using the input_* globals to describe movement
+// this may or may not take a player ent
+void(...) runstandardplayerphysics = #347;
+// Sets the position of the view, as far as the audio subsystem is
+// concerned. This should be called once per CSQC_UpdateView as it
+// will otherwise revert to default. For reverbtype,
+// see setup_reverb or treat as 'underwater'
+// FTE = void(vector origin, vector forward, vector right, vector up, optional float reverbtype) SetListener = #351;
+void(vector origin, vector forward, vector right, vector up) SetListener = #351;
+
+// ----------------------------------------------------------------------
+// This is a bit of mess with DP (below) and FTE/QSS (further below)
+// Going in different directions with the CSQC standard
+// This is all about #330 returning an INT instead of a FLOAT
+// As getstatf has optional parameters it will still work fine with DP
+// Going with the FTE/QSS direction as it still works for DP
+// ----------------------------------------------------------------------
+//float(float stnum) getstatf = #330;
+// Can optionally take first bit and count
+//float(float stnum, ...) getstati = #331;
+
+// Retrieves the numerical value of the given EV_INTEGER or EV_ENTITY stat.
+// Use getstati_punf if you wish to type-pun a float stat as an int to
+// avoid truncation issues in DP
+#define getstati_punf(stnum) (float)(__variant)getstati(stnum)
+int(float stnum) getstati = #330;
+#define getstatbits getstatf
+float(float stnum, optional float firstbit, optional float bitcount) getstatf = #331;
+
+// ----------------------------------------------------------------------
+// QSS (CSQC Lit) + DP/FTE extensions
+// ----------------------------------------------------------------------
+// Sets a model by precache index instead of by name.
+// Otherwise identical to setmodel.
+void(entity e, float mdlindex) setmodelindex = #333;
+// Part of DP_ENT_TRAILEFFECTNUM, FTE_SV_POINTPARTICLES
+// Precaches the named particle effect. If your effect name is of
+// the form 'foo.bar' then particles/foo.cfg will be loaded by the
+// client if foo.bar was not already defined.
+// Different engines will have different particle systems, this
+// specifies the QC API only
+float(string effectname) particleeffectnum = #335;
+// Part of FTE_SV_POINTPARTICLES
+// Draws the given effect between the two named points. If ent is
+// not world, distances will be cached in the entity in order to
+// avoid framerate dependancies. The entity is not otherwise used
+void(float effectnum, entity ent, vector start, vector end) trailparticles = #336;
+// Part of FTE_SV_POINTPARTICLES
+// Spawn a load of particles from the given effect at the given
+// point traveling or aiming along the direction specified.
+// The number of particles are scaled by the count argument.
+// For regular particles, the dir vector is multiplied by the
+// 'veladd' property (while orgadd will push the particles along it).
+// Decals will use it as a hint to align to the correct surface.
+// In both cases, it should normally be a unit vector, but other
+// lengths will still work. If it has length 0 then FTE will
+// assume downwards
+void(float effectnum, vector origin, optional vector dir, optional float count) pointparticles = #337;
+
+// conflicts with void(entity client, string s1) centerprint = #73;
+void(string s, ...) csqc_centerprint = #338;
+// Print into the center of the screen just as ssqc's centerprint
+// would appear
+void(string s, ...) cprint = #338;
+// This is identical to dprint except that it always prints
+// regardless of the developer cvar. Same number as in EXT_CSQC
+// Unconditionally print on the local system's console, even in
+// ssqc (doesn't care about the value of the developer cvar)
+void(string s, ...) print = #339;
+// Returns a hunam-readable name for the given keycode, as a tempstring
+string(float keynum) keynumtostring = #340;
+// Looks up the key name in the same way that the bind command would,
+// returning the keycode for that key
+float(string keyname) stringtokeynum = #341;
+// Returns the current binding for the given key (returning only the
+// command executed when no modifiers are pressed)
+string(float key, float bindmap) getkeybind_bindmap = #342;
+string(float keynum) getkeybind = #342;
+// Pass TRUE if you want the engine to release the mouse cursor
+// (absolute input events + touchscreen mode). Pass FALSE if you
+// want the engine to grab the cursor (relative input
+// events + standard looking). If the image name is specified,
+// the engine will use that image for a cursor (use an empty
+// string to clear it again), in a way that will not conflict
+// with the console. Images specified this way will be hardware
+// accelerated, if supported by the platform/port
+// QSS/FTE = void(float usecursor, optional string cursorimage, optional vector hotspot, optional float scale) setcursormode = #343;
+void(float usecursor) setcursormode = #343;
+// Reports the cursor mode this module previously attempted to use.
+// If 'effective' is true, reports the cursor mode currently active
+// (if was overriden by a different module which has precidence,
+// for instance, or if there is only a touchscreen and no mouse)
+float(float effective) getcursormode = #0;
+// Temporarily scales the player's mouse sensitivity based upon
+// something like zoom, avoiding potential cvar saving and thus
+// corruption
+void(float sens) setsensitivityscale = #346;
+// Look up a player's userinfo, to discover things like their name,
+// topcolor, bottomcolor, skin, team, *ver.
+// Also includes scoreboard info like frags, ping, pl, userid,
+// entertime, as well as voipspeaking and voiploudness
+string(float playernum, string keyname) getplayerkeyvalue = #348;
+// Cheaper version of getplayerkeyvalue that avoids the need for
+// so many tempstrings
+float(float playernum, string keyname, optional float assumevalue) getplayerkeyfloat = #0;
+// Returns if the client is currently playing a demo or not
+float() isdemo = #349;
+// Returns if the client is acting as the server (aka: listen server)
+float() isserver = #350;
+// Register the given console command, for easy console use.
+// Console commands that are later used will invoke CSQC_ConsoleCommand
+void(string cmdname) registercommand = #352;
+// Quickly check to see if the entity is currently free. This
+// function is only valid during the two-second non-reuse window,
+// after that it may give bad results. Try one second to make it
+// more robust.
+float(entity ent) wasfreed = #353;
+// Look up a key in the server's public serverinfo string
+string(string key) serverkey = #354;
+// Version of serverkey that returns the value as a float
+// (which avoids tempstrings)
+float(string key, optional float assumevalue) serverkeyfloat = #0;
+// Use proper case; refer to the id1 Write* functions!
+float() ReadByte = #360;
+float() ReadChar = #361;
+float() ReadShort = #362;
+float() ReadLong = #363;
+float() ReadCoord = #364;
+float() ReadAngle = #365;
+string() ReadString = #366;
+float() ReadFloat = #367;
+float() readentitynum = #368;
+// Replaces the title of the game window, as seen when
+// task switching or just running in windowed mode
+void(string newcaption) setwindowcaption = #0;
+

Return to the top of this page or return to the overview of this repo.

Diff qc/csqc/csqc_defsclient.qc

diff --git a/qc/csqc/csqc_defsclient.qc b/qc/csqc/csqc_defsclient.qc
new file mode 100644
index 0000000..23e7f4b
--- /dev/null
+++ b/qc/csqc/csqc_defsclient.qc
@@ -0,0 +1,759 @@
+//======================================================================
+// Author : Simon "Sock" OCallaghan
+// Website: www.simonoc.com
+//
+// Based on the qsextensions.qc file in the QSS devkit
+// This is a special defs file for csprogs.dat ONLY
+// Requires csqc_defs.qc file for 300-399 range commands
+//
+//======================================================================
+// Some extra defs (csqc/csqc_simple)
+#ifndef CSQC
+#define CSQC
+#endif
+#ifndef CSQC_SIMPLE
+#define CSQC_SIMPLE
+#endif
+// Suppress reference errors
+#pragma noref 1
+
+//----------------------------------------------------------------------
+// Mostly stuff from GLOBALVARS_T C STRUCTURE
+//----------------------------------------------------------------------
+entity self,other,world;
+float time,frametime,force_retouch;
+string mapname;
+float deathmatch,coop,teamplay,serverflags,total_secrets,total_monsters,found_secrets,killed_monsters,parm1, parm2, parm3, parm4, parm5, parm6, parm7, parm8, parm9, parm10, parm11, parm12, parm13, parm14, parm15, parm16;
+vector v_forward, v_up, v_right;
+float trace_allsolid,trace_startsolid,trace_fraction;
+vector trace_endpos,trace_plane_normal;
+float trace_plane_dist;
+entity trace_ent;
+float trace_inopen,trace_inwater;
+entity msg_entity;
+void() main,StartFrame,PlayerPreThink,PlayerPostThink,ClientKill,ClientConnect,PutClientInServer,ClientDisconnect,SetNewParms,SetChangeParms;
+void end_sys_globals;
+.float modelindex;
+.vector absmin, absmax;
+.float ltime,movetype,solid;
+.vector origin,oldorigin,velocity,angles,avelocity,punchangle;
+.string classname,model;
+.float frame,skin,effects;
+.vector mins, maxs,size;
+.void() touch,use,think,blocked;
+.float nextthink;
+.entity groundentity;
+.float health,frags,weapon;
+.string weaponmodel;
+.float weaponframe,currentammo,ammo_shells,ammo_nails,ammo_rockets,ammo_cells,items,takedamage;
+.entity chain;
+.float deadflag;
+.vector view_ofs;
+.float button0,button1,button2,impulse,fixangle;
+.vector v_angle;
+.float idealpitch;
+.string netname;
+.entity enemy;
+.float flags,colormap,team,max_health,teleport_time,armortype,armorvalue,waterlevel,watertype,ideal_yaw,yaw_speed;
+.entity aiment,goalentity;
+.float spawnflags;
+.string target,targetname;
+.float dmg_take,dmg_save;
+.entity dmg_inflictor,owner;
+.vector movedir;
+.string message;
+.float sounds;
+.string noise, noise1, noise2, noise3;
+void end_sys_fields;
+
+// Custom types redefined as accessors
+#ifdef _ACCESSORS
+accessor strbuf:float;
+accessor searchhandle:float;
+accessor hashtable:float;
+accessor infostring:string;
+accessor filestream:float;
+#else
+#define strbuf float
+#define searchhandle float
+#define hashtable float
+#define infostring string
+#define filestream float
+#endif
+
+void(string cmd) SV_ParseClientCommand;
+void() EndFrame;
+
+// Core CSQC functions called by engine
+void(float apilevel, string enginename, float engineversion) CSQC_Init;
+void(vector virtsize, float showscores) CSQC_DrawHud;
+void(vector virtsize, float showscores) CSQC_DrawScores;
+float(float evtype, float scanx, float chary, float devid) CSQC_InputEvent;
+float(float save, float take, vector dir) CSQC_Parse_Damage;
+float(string cmdstr) CSQC_ConsoleCommand;
+void() CSQC_Parse_Event;
+
+float player_localnum; // Player slot that is assigned to us
+
+const float FALSE = 0;
+const float TRUE = 1;
+const float IE_KEYDOWN = 0;
+const float IE_KEYUP = 1;
+const float IE_MOUSEDELTA = 2;
+const float IE_MOUSEABS = 3;
+const float IE_JOYAXIS = 6;
+
+//----------------------------------------------------------------------
+// Extra fields
+//----------------------------------------------------------------------
+.float gravity;
+//.float items2; /*if defined, overrides serverflags for displaying runes on the hud*/
+.float traileffectnum; /*can also be set with 'traileffect' from a map editor*/
+.float emiteffectnum; /*can also be set with 'traileffect' from a map editor*/
+.vector movement; /*describes which forward/right/up keys the player is holidng*/
+.entity viewmodelforclient; /*attaches this entity to the specified player's view. invisible to other players*/
+.float scale; /*rescales the etntiy*/
+.float alpha; /*entity opacity*/
+.vector colormod; /*tints the entity's colours*/
+.entity tag_entity;
+.float tag_index;
+.float button3;
+.float button4;
+.float button5;
+.float button6;
+.float button7;
+.float button8;
+.float viewzoom; /*rescales the user's fov*/
+.float modelflags; /*provides additional modelflags to use (effects&EF_NOMODELFLAGS to replace the original model's)*/
+
+//----------------------------------------------------------------------
+// Supported Extension Constants
+//----------------------------------------------------------------------
+const float MOVETYPE_FOLLOW = 12;
+const float SOLID_CORPSE = 5;
+const float CLIENTTYPE_DISCONNECT = 0;
+const float CLIENTTYPE_REAL = 1;
+const float CLIENTTYPE_BOT = 2;
+const float CLIENTTYPE_NOTCLIENT = 3;
+const float EF_NOSHADOW = 0x1000;
+const float EF_NOMODELFLAGS = 0x800000; /*the standard modelflags from the model are ignored*/
+const float MF_ROCKET = 0x1;
+const float MF_GRENADE = 0x2;
+const float MF_GIB = 0x4;
+const float MF_ROTATE = 0x8;
+const float MF_TRACER = 0x10;
+const float MF_ZOMGIB = 0x20;
+const float MF_TRACER2 = 0x40;
+const float MF_TRACER3 = 0x80;
+const float MSG_MULTICAST = 4;
+const float MULTICAST_ALL = 0;
+const float MULTICAST_PVS = 2;
+const float MULTICAST_ONE = 6;
+const float MULTICAST_ALL_R = 3;
+const float MULTICAST_PVS_R = 5;
+const float MULTICAST_ONE_R = 7;
+const float MULTICAST_INIT = 8;
+const float FILE_READ = 0;
+const float FILE_APPEND = 1;
+const float FILE_WRITE = 2;
+
+//----------------------------------------------------------------------
+// Vanilla Builtin list (reduced, so as to avoid conflicts)
+//----------------------------------------------------------------------
+void(vector) makevectors = #1;
+void(entity,vector) setorigin = #2;
+void(entity,string) setmodel = #3;
+void(entity,vector,vector) setsize = #4;
+float() random = #7;
+vector(vector) normalize = #9;
+void(string e) error = #10;
+void(string n) objerror = #11;
+float(vector) vlen = #12;
+entity() spawn = #14;
+void(entity e) remove = #15;
+void(string,...) dprint = #25;
+string(float) ftos = #26;
+string(vector) vtos = #27;
+float(float n) rint = #36;
+float(float n) floor = #37;
+float(float n) ceil = #38;
+float(float n) fabs = #43;
+float(string) cvar = #45;
+void(string,...) localcmd = #46;
+entity(entity) nextent = #47;
+void(string var, string val) cvar_set = #72;
+
+//----------------------------------------------------------------------
+// Builtin list
+//----------------------------------------------------------------------
+vector(vector fwd, optional vector up) vectoangles2 = #51; /*
+ Returns the angles (+x=UP) required to orient an entity to look in the given direction. The 'up' argument is required if you wish to set a roll angle, otherwise it will be limited to just monster-style turning. */
+
+float(float angle) sin = #60;
+float(float angle) cos = #61;
+float(float value) sqrt = #62;
+void(entity ent, entity ignore) tracetoss = #64;
+string(entity ent) etos = #65;
+string(entity e, string key) infokey = #80; /*
+ If e is world, returns the field 'key' from either the serverinfo or the localinfo. If e is a player, returns the value of 'key' from the player's userinfo string. There are a few special exceptions, like 'ip' which is not technically part of the userinfo. */
+
+float(entity e, string key) infokeyf = #0; /*
+ Identical to regular infokey, but returns it as a float instead of creating new tempstrings. */
+
+float(string) stof = #81;
+#define unicast(pl,reli) do{msg_entity = pl; multicast('0 0 0', reli?MULITCAST_ONE_R:MULTICAST_ONE);}while(0)
+void(vector where, float set) multicast = #82; /*
+ Once the MSG_MULTICAST network message buffer has been filled with data, this builtin is used to dispatch it to the given target, filtering by pvs for reduced network bandwidth. */
+
+void(vector start, vector mins, vector maxs, vector end, float nomonsters, entity ent) tracebox = #90; /*
+ Exactly like traceline, but a box instead of a uselessly thin point. Acceptable sizes are limited by bsp format, q1bsp has strict acceptable size values. */
+
+vector() randomvec = #91; /*
+ Returns a vector with random values. Each axis is independantly a value between -1 and 1 inclusive. */
+
+vector(vector org) getlight = #92;
+float(string cvarname, string defaultvalue) registercvar = #93; /*
+ Creates a new cvar on the fly. If it does not already exist, it will be given the specified value. If it does exist, this is a no-op.
+ This builtin has the limitation that it does not apply to configs or commandlines. Such configs will need to use the set or seta command causing this builtin to be a noop.
+ In engines that support it, you will generally find the autocvar feature easier and more efficient to use. */
+
+float(float a, float b, ...) min = #94; /*
+ Returns the lowest value of its arguments. */
+
+float(float a, float b, ...) max = #95; /*
+ Returns the highest value of its arguments. */
+
+float(float minimum, float val, float maximum) bound = #96; /*
+ Returns val, unless minimum is higher, or maximum is less. */
+
+float(float value, float exp) pow = #97;
+#define findentity findfloat
+entity(entity start, .__variant fld, __variant match) findfloat = #98; /*
+ Equivelent to the find builtin, but instead of comparing strings contents, this builtin compares the raw values. This builtin requires multiple calls in order to scan all entities - set start to the previous call's return value.
+ world is returned when there are no more entities. */
+
+float(string extname) checkextension = #99; /*
+ Checks for an extension by its name (eg: checkextension("FRIK_FILE") says that its okay to go ahead and use strcat).
+ Use cvar("pr_checkextension") to see if this builtin exists. */
+
+float(__variant funcref) checkbuiltin = #0; /*
+ Checks to see if the specified builtin is supported/mapped. This is intended as a way to check for #0 functions, allowing for simple single-builtin functions. */
+
+//----------------------------------------------------------------------
+// 100-199 Range
+//----------------------------------------------------------------------
+float(string builtinname) builtin_find = #100; /*
+ Looks to see if the named builtin is valid, and returns the builtin number it exists at. */
+
+float(float value) anglemod = #102;
+filestream(string filename, float mode, optional float mmapminsize) fopen = #110; /*
+ Opens a file, typically prefixed with "data/", for either read or write access. */
+
+void(filestream fhandle) fclose = #111;
+string(filestream fhandle) fgets = #112; /*
+ Reads a single line out of the file. The new line character is not returned as part of the string. Returns the null string on EOF (use if not(string) to easily test for this, which distinguishes it from the empty string which is returned if the line being read is blank */
+
+void(filestream fhandle, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7) fputs = #113; /*
+ Writes the given string(s) into the file. For compatibility with fgets, you should ensure that the string is terminated with a \n - this will not otherwise be done for you. It is up to the engine whether dos or unix line endings are actually written. */
+
+#define ftell fseek //c-compat
+int(filestream fhandle, optional int newoffset) fseek = #0; /*
+ Changes the current position of the file, if specified. Returns prior position, in bytes. */
+
+float(string s) strlen = #114;
+string(string s1, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7, optional string s8) strcat = #115;
+string(string s, float start, float length) substring = #116;
+vector(string s) stov = #117;
+string(string s, ...) strzone = #118; /*
+ Create a semi-permanent copy of a string that only becomes invalid once strunzone is called on the string (instead of when the engine assumes your string has left scope). */
+
+void(string s) strunzone = #119; /*
+ Destroys a string that was allocated by strunzone. Further references to the string MAY crash the game. */
+
+//----------------------------------------------------------------------
+// 200-299 FTE Range
+//----------------------------------------------------------------------
+float(float number, float quantity) bitshift = #218;
+void(vector org) te_lightningblood = #219;
+float(string s1, string sub, optional float startidx) strstrofs = #221; /*
+ Returns the 0-based offset of sub within the s1 string, or -1 if sub is not in s1.
+ If startidx is set, this builtin will ignore matches before that 0-based offset. */
+
+float(string str, float index) str2chr = #222; /*
+ Retrieves the character value at offset 'index'. */
+
+string(float chr, ...) chr2str = #223; /*
+ The input floats are considered character values, and are concatenated. */
+
+string(float ccase, float redalpha, float redchars, string str, ...) strconv = #224; /*
+ Converts quake chars in the input string amongst different representations.
+ ccase specifies the new case for letters.
+ 0: not changed.
+ 1: forced to lower case.
+ 2: forced to upper case.
+ redalpha and redchars switch between colour ranges.
+ 0: no change.
+ 1: Forced white.
+ 2: Forced red.
+ 3: Forced gold(low) (numbers only).
+ 4: Forced gold (high) (numbers only).
+ 5+6: Forced to white and red alternately.
+ You should not use this builtin in combination with UTF-8. */
+
+string(float pad, string str1, ...) strpad = #225; /*
+ Pads the string with spaces, to ensure its a specific length (so long as a fixed-width font is used, anyway). If pad is negative, the spaces are added on the left. If positive the padding is on the right. */
+
+string(infostring old, string key, string value) infoadd = #226; /*
+ Returns a new tempstring infostring with the named value changed (or added if it was previously unspecified). Key and value may not contain the \ character. */
+
+string(infostring info, string key) infoget = #227; /*
+ Reads a named value from an infostring. The returned value is a tempstring */
+
+#define strcmp strncmp
+float(string s1, string s2, optional float len, optional float s1ofs, optional float s2ofs) strncmp = #228; /*
+ Compares up to 'len' chars in the two strings. s1ofs allows you to treat s2 as a substring to compare against, or should be 0.
+ Returns 0 if the two strings are equal, a negative value if s1 appears numerically lower, and positive if s1 appears numerically higher. */
+
+float(string s1, string s2) strcasecmp = #229; /*
+ Compares the two strings without case sensitivity.
+ Returns 0 if they are equal. The sign of the return value may be significant, but should not be depended upon. */
+
+float(string s1, string s2, float len, optional float s1ofs, optional float s2ofs) strncasecmp = #230; /*
+ Compares up to 'len' chars in the two strings without case sensitivity. s1ofs allows you to treat s2 as a substring to compare against, or should be 0.
+ Returns 0 if they are equal. The sign of the return value may be significant, but should not be depended upon. */
+
+string(string s) strtrim = #0; /*
+ Trims the whitespace from the start+end of the string. */
+
+void(float num, float type, .__variant fld) clientstat = #232; /*
+ Specifies what data to use in order to send various stats, in a client-specific way.
+ 'num' should be a value between 32 and 127, other values are reserved.
+ 'type' must be set to one of the EV_* constants, one of EV_FLOAT, EV_STRING, EV_INTEGER, EV_ENTITY.
+ fld must be a reference to the field used, each player will be sent only their own copy of these fields. */
+
+void(float num, float type, string name) globalstat = #233; /*
+ Specifies what data to use in order to send various stats, in a non-client-specific way. num and type are as in clientstat, name however, is the name of the global to read in the form of a string (pass "foo"). */
+
+void(float num, float type, __variant *address) pointerstat = #0; /*
+ Specifies what data to use in order to send various stats, in a non-client-specific way. num and type are as in clientstat, address however, is the address of the variable you would like to use (pass &foo). */
+
+float(entity player) isbackbuffered = #234; /*
+ Returns if the given player's network buffer will take multiple network frames in order to clear. If this builtin returns non-zero, you should delay or reduce the amount of reliable (and also unreliable) data that you are sending to that client. */
+
+void(vector org, float count) te_bloodqw = #239;
+float(float a, float n) mod = #245;
+int(string) stoi = #259; /*
+ Converts the given string into a true integer. Base 8, 10, or 16 is determined based upon the format of the string. */
+
+string(int) itos = #260; /*
+ Converts the passed true integer into a base10 string. */
+
+int(string) stoh = #261; /*
+ Reads a base-16 string (with or without 0x prefix) as an integer. Bugs out if given a base 8 or base 10 string. :P */
+
+string(int) htos = #262; /*
+ Formats an integer as a base16 string, with leading 0s and no prefix. Always returns 8 characters. */
+
+int(float) ftoi = #0; /*
+ Converts the given float into a true integer without depending on extended qcvm instructions. */
+
+float(int) itof = #0; /*
+ Converts the given true integer into a float without depending on extended qcvm instructions. */
+
+#ifndef dotproduct
+#define dotproduct(v1,v2) ((vector)(v1)*(vector)(v2))
+#endif
+vector(vector v1, vector v2) crossproduct = #0; /*
+ Small helper function to calculate the crossproduct of two vectors. */
+
+float(float modidx, string framename) frameforname = #276; /*
+ Looks up a framegroup from a model by name, avoiding the need for hardcoding. Returns -1 on error. */
+
+float(float modidx, float framenum) frameduration = #277; /*
+ Retrieves the duration (in seconds) of the specified framegroup. */
+
+void(float buf, float fl) WriteFloat = #280;
+string(float modidx, float framenum) frametoname = #284;
+float(string name) checkcommand = #294; /*
+ Checks to see if the supplied name is a valid command, cvar, or alias. Returns 0 if it does not exist. */
+
+// ----------------------------------------------------------------------
+// 300-399 Range - Moved to CSQC DEFS file
+// ----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// 400-499 DP Range
+//----------------------------------------------------------------------
+entity(entity from, optional entity to) copyentity = #400; /*
+ Copies all fields from one entity to another. */
+
+void(entity ent, float colours) setcolors = #401; /*
+ Changes a player's colours. The bits 0-3 are the lower/trouser colour, bits 4-7 are the upper/shirt colours. */
+
+entity(.string field, string match) findchain = #402;
+entity(.float fld, float match) findchainfloat = #403;
+void(vector org, vector dir, float count) te_blood = #405;
+void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain = #409;
+void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow = #410;
+void(vector org, optional float count) te_gunshot = #418;
+void(vector org) te_spike = #419;
+void(vector org) te_superspike = #420;
+void(vector org) te_explosion = #421;
+void(vector org) te_tarexplosion = #422;
+void(vector org) te_wizspike = #423;
+void(vector org) te_knightspike = #424;
+void(vector org) te_lavasplash = #425;
+void(vector org) te_teleport = #426;
+void(vector org, float color, float colorlength) te_explosion2 = #427;
+void(entity own, vector start, vector end) te_lightning1 = #428;
+void(entity own, vector start, vector end) te_lightning2 = #429;
+void(entity own, vector start, vector end) te_lightning3 = #430;
+void(entity own, vector start, vector end) te_beam = #431;
+void(vector dir) vectorvectors = #432;
+float(entity e, float s) getsurfacenumpoints = #434;
+vector(entity e, float s, float n) getsurfacepoint = #435;
+vector(entity e, float s) getsurfacenormal = #436;
+string(entity e, float s) getsurfacetexture = #437;
+float(entity e, vector p) getsurfacenearpoint = #438;
+vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
+void(entity e, string s) clientcommand = #440;
+float(string s) tokenize = #441;
+string(float n) argv = #442;
+float() argc = #0;
+void(entity e, entity tagentity, string tagname) setattachment = #443; /* */
+
+searchhandle(string pattern, optional float caseinsensitive, optional float quiet) search_begin = #444; /*
+ initiate a filesystem scan based upon filenames. Be sure to call search_end on the returned handle. */
+
+void(searchhandle handle) search_end = #445; /* */
+
+float(searchhandle handle) search_getsize = #446; /*
+ Retrieves the number of files that were found. */
+
+string(searchhandle handle, float num) search_getfilename = #447; /*
+ Retrieves name of one of the files that was found by the initial search. */
+
+float(searchhandle handle, float num) search_getfilesize = #0; /*
+ Retrieves the size of one of the files that was found by the initial search. */
+
+string(searchhandle handle, float num) search_getfilemtime = #0; /*
+ Retrieves modification time of one of the files in %Y-%m-%d %H:%M:%S format. */
+
+string(string cvarname) cvar_string = #448;
+entity(entity start, .float fld, float match) findflags = #449;
+entity(.float fld, float match) findchainflags = #450;
+void(entity player) dropclient = #453;
+entity() spawnclient = #454; /*
+ Spawns a dummy player entity.
+ Note that such dummy players will be carried from one map to the next.
+ Warning: DP_SV_CLIENTCOLORS DP_SV_CLIENTNAME are not implemented in quakespasm, so use KRIMZON_SV_PARSECLIENTCOMMAND's clientcommand builtin to change the bot's name/colours/skin/team/etc, in the same way that clients would ask. */
+
+float(entity client) clienttype = #455;
+void(float target, string str) WriteUnterminatedString = #456;
+entity(float entnum) edict_num = #459;
+strbuf() buf_create = #460;
+void(strbuf bufhandle) buf_del = #461;
+float(strbuf bufhandle) buf_getsize = #462;
+void(strbuf bufhandle_from, strbuf bufhandle_to) buf_copy = #463;
+void(strbuf bufhandle, float sortprefixlen, float backward) buf_sort = #464;
+string(strbuf bufhandle, string glue) buf_implode = #465;
+string(strbuf bufhandle, float string_index) bufstr_get = #466;
+void(strbuf bufhandle, float string_index, string str) bufstr_set = #467;
+float(strbuf bufhandle, string str, float order) bufstr_add = #468;
+void(strbuf bufhandle, float string_index) bufstr_free = #469;
+float(float s) asin = #471;
+float(float c) acos = #472;
+float(float t) atan = #473;
+float(float c, float s) atan2 = #474;
+float(float a) tan = #475;
+float(string s) strlennocol = #476; /*
+ Returns the number of characters in the string after any colour codes or other markup has been parsed. */
+
+string(string s) strdecolorize = #477; /*
+ Flattens any markup/colours, removing them from the string. */
+
+string(float uselocaltime, string format, ...) strftime = #478;
+float(string s, string separator1, ...) tokenizebyseparator = #479;
+string(string s) strtolower = #480;
+string(string s) strtoupper = #481;
+string(string s) cvar_defstring = #482;
+void(vector origin, string sample, float volume, float attenuation) pointsound = #483;
+string(string search, string replace, string subject) strreplace = #484;
+string(string search, string replace, string subject) strireplace = #485;
+vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
+float(float caseinsensitive, string s, ...) crc16 = #494;
+float(string name) cvar_type = #495;
+float() numentityfields = #496; /*
+ Gives the number of named entity fields. Note that this is not the size of an entity, but rather just the number of unique names (ie: vectors use 4 names rather than 3). */
+
+float(string fieldname) findentityfield = #0; /*
+ Find a field index by name. */
+
+typedef .__variant field_t;
+field_t(float fieldnum) entityfieldref = #0; /*
+ Returns a field value that can be directly used to read entity fields. Be sure to validate the type with entityfieldtype before using. */
+
+string(float fieldnum) entityfieldname = #497; /*
+ Retrieves the name of the given entity field. */
+
+float(float fieldnum) entityfieldtype = #498; /*
+ Provides information about the type of the field specified by the field num. Returns one of the EV_ values. */
+
+string(float fieldnum, entity ent) getentityfieldstring = #499;
+
+//----------------------------------------------------------------------
+// 500-599 Range
+//----------------------------------------------------------------------
+float(float fieldnum, entity ent, string s) putentityfieldstring = #500;
+string(string filename, optional float makereferenced) whichpack = #503; /*
+ Returns the pak file name that contains the file specified. progs/player.mdl will generally return something like 'pak0.pak'. If makereferenced is true, clients will automatically be told that the returned package should be pre-downloaded and used, even if allow_download_refpackages is not set. */
+
+string(string in) uri_escape = #510;
+string(string in) uri_unescape = #511;
+float(entity ent) num_for_edict = #512;
+float(string str) tokenize_console = #514; /*
+ Tokenize a string exactly as the console's tokenizer would do so. The regular tokenize builtin became bastardized for convienient string parsing, which resulted in a large disparity that can be exploited to bypass checks implemented in a naive SV_ParseClientCommand function, therefore you can use this builtin to make sure it exactly matches. */
+
+float(float idx) argv_start_index = #515; /*
+ Returns the character index that the tokenized arg started at. */
+
+float(float idx) argv_end_index = #516; /*
+ Returns the character index that the tokenized arg stopped at. */
+
+string(string cvarname) cvar_description = #518; /*
+ Retrieves the description of a cvar, which might be useful for tooltips or help files. This may still not be useful. */
+
+float(optional float timetype) gettime = #519;
+string(string command, optional float bindmap) findkeysforcommand = #521; /*
+ Returns a list of keycodes that perform the given console command in a format that can only be parsed via tokenize (NOT tokenize_console). This always returns at least two values - if only one key is actually bound, -1 will be returned. The bindmap argument is listed for compatibility with dp-specific defs, but is ignored in FTE. */
+
+string(string command, optional float bindmap) findkeysforcommandex = #0; /*
+ Returns a list of key bindings in keyname format instead of keynums. Use tokenize to parse. This list may contain modifiers. May return large numbers of keys. */
+
+float(float v, optional float base) log = #532; /*
+ Determines the logarithm of the input value according to the specified base. This can be used to calculate how much something was shifted by. */
+
+float(string filename, strbuf bufhandle) buf_loadfile = #535; /*
+ Appends the named file into a string buffer (which must have been created in advance). The return value merely says whether the file was readable. */
+
+float(filestream filehandle, strbuf bufhandle, optional float startpos, optional float numstrings) buf_writefile = #536; /*
+ Writes the contents of a string buffer onto the end of the supplied filehandle (you must have already used fopen). Additional optional arguments permit you to constrain the writes to a subsection of the stringbuffer. */
+
+//----------------------------------------------------------------------
+// 600-699 Range
+//----------------------------------------------------------------------
+void(.../*, string funcname*/) callfunction = #605; /*
+ Invokes the named function. The function name is always passed as the last parameter and must always be present. The others are passed to the named function as-is */
+
+float(string s) isfunction = #607; /*
+ Returns true if the named function exists and can be called with the callfunction builtin. */
+
+float(entity e, string s, optional float offset) parseentitydata = #613; /*
+ Reads a single entity's fields into an already-spawned entity. s should contain field pairs like in a saved game: {"foo1" "bar" "foo2" "5"}. Returns <=0 on failure, otherwise returns the offset in the string that was read to. */
+
+string(string fmt, ...) sprintf = #627;
+float(entity e, float s) getsurfacenumtriangles = #628;
+vector(entity e, float s, float n) getsurfacetriangle = #629;
+
+//----------------------------------------------------------------------
+//Builtin Stubs List - present for simpler compatibility
+// Not properly supported in QuakeSpasm at this time
+//----------------------------------------------------------------------
+/*
+void(vector org, string modelname, float startframe, float endframe, float framerate) effect = #404;
+void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower = #406;
+void(vector org, vector color) te_explosionrgb = #407;
+void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube = #408;
+void(vector org, vector vel, float howmany) te_spark = #411;
+void(vector org) te_gunshotquad = #412;
+void(vector org) te_spikequad = #413;
+void(vector org) te_superspikequad = #414;
+void(vector org) te_explosionquad = #415;
+void(vector org) te_smallflash = #416;
+void(vector org, float radius, float lifetime, vector color) te_customflash = #417;
+void(vector org) te_plasmaburn = #433;
+*/
+
+//----------------------------------------------------------------------
+// Keyboard input values
+//----------------------------------------------------------------------
+const float K_TAB = 9;
+const float K_ENTER = 13;
+const float K_ESCAPE = 27;
+const float K_SPACE = 32;
+const float K_BACKSPACE = 127;
+const float K_UPARROW = 128;
+const float K_DOWNARROW = 129;
+const float K_LEFTARROW = 130;
+const float K_RIGHTARROW = 131;
+const float K_ALT = 132;
+const float K_CTRL = 133;
+const float K_SHIFT = 134;
+const float K_F1 = 135;
+const float K_F2 = 136;
+const float K_F3 = 137;
+const float K_F4 = 138;
+const float K_F5 = 139;
+const float K_F6 = 140;
+const float K_F7 = 141;
+const float K_F8 = 142;
+const float K_F9 = 143;
+const float K_F10 = 144;
+const float K_F11 = 145;
+const float K_F12 = 146;
+const float K_INS = 147;
+const float K_DEL = 148;
+const float K_PGDN = 149;
+const float K_PGUP = 150;
+const float K_HOME = 151;
+const float K_END = 152;
+const float K_KP_SLASH = 168;
+const float K_KP_STAR = 169;
+const float K_KP_MINUS = 170;
+const float K_KP_HOME = 164;
+const float K_KP_UPARROW = 165;
+const float K_KP_PGUP = 166;
+const float K_KP_PLUS = 171;
+const float K_KP_LEFTARROW = 161;
+const float K_KP_5 = 162;
+const float K_KP_RIGHTARROW = 163;
+const float K_KP_END = 158;
+const float K_KP_DOWNARROW = 159;
+const float K_KP_PGDN = 160;
+const float K_KP_ENTER = 172;
+const float K_KP_INS = 157;
+const float K_KP_DEL = 167;
+const float K_COMMAND = -170;
+const float K_MOUSE1 = 512;
+const float K_MOUSE2 = 513;
+const float K_MOUSE3 = 514;
+const float K_JOY1 = 768;
+const float K_JOY2 = 769;
+const float K_JOY3 = 770;
+const float K_JOY4 = 771;
+const float K_AUX1 = 784;
+const float K_AUX2 = 785;
+const float K_AUX3 = 786;
+const float K_AUX4 = 787;
+const float K_AUX5 = 788;
+const float K_AUX6 = 789;
+const float K_AUX7 = 790;
+const float K_AUX8 = 791;
+const float K_AUX9 = 792;
+const float K_AUX10 = 793;
+const float K_AUX11 = 794;
+const float K_AUX12 = 795;
+const float K_AUX13 = 796;
+const float K_AUX14 = 797;
+const float K_AUX15 = 798;
+const float K_AUX16 = 799;
+const float K_AUX17 = 800;
+const float K_AUX18 = 801;
+const float K_AUX19 = 802;
+const float K_AUX20 = 803;
+const float K_AUX21 = 804;
+const float K_AUX22 = 805;
+const float K_AUX23 = 806;
+const float K_AUX24 = 807;
+const float K_AUX25 = 808;
+const float K_AUX26 = 809;
+const float K_AUX27 = 810;
+const float K_AUX28 = 811;
+const float K_AUX29 = 812;
+const float K_AUX30 = 813;
+const float K_AUX31 = 814;
+const float K_AUX32 = 815;
+const float K_MWHEELUP = 515;
+const float K_MWHEELDOWN = 516;
+const float K_MOUSE4 = 517;
+const float K_MOUSE5 = 518;
+const float K_LTHUMB = 822;
+const float K_RTHUMB = 823;
+const float K_LSHOULDER = 824;
+const float K_RSHOULDER = 825;
+const float K_ABUTTON = 826;
+const float K_BBUTTON = 827;
+const float K_XBUTTON = 828;
+const float K_YBUTTON = 829;
+const float K_LTRIGGER = 830;
+const float K_RTRIGGER = 831;
+const float K_PAUSE = 153;
+
+//----------------------------------------------------------------------
+// Reset suppression of ref errors
+#pragma noref 0
+
+//----------------------------------------------------------------------
+// List of advertised extensions (not used, reference only)
+//----------------------------------------------------------------------
+//DP_CON_SET
+//DP_CON_SETA
+//DP_EF_NOSHADOW
+//DP_ENT_ALPHA
+//DP_ENT_COLORMOD
+//DP_ENT_SCALE
+//DP_ENT_TRAILEFFECTNUM
+//DP_INPUTBUTTONS
+//DP_QC_AUTOCVARS
+//DP_QC_ASINACOSATANATAN2TAN
+//DP_QC_COPYENTITY
+//DP_QC_CRC16
+//DP_QC_CVAR_DEFSTRING
+//DP_QC_CVAR_STRING
+//DP_QC_CVAR_TYPE
+//DP_QC_EDICT_NUM
+//DP_QC_ENTITYDATA
+//DP_QC_ETOS
+//DP_QC_FINDCHAIN
+//DP_QC_FINDCHAINFLAGS
+//DP_QC_FINDCHAINFLOAT
+//DP_QC_FINDFLAGS
+//DP_QC_FINDFLOAT
+//DP_QC_GETLIGHT
+//DP_QC_GETSURFACE
+//DP_QC_GETSURFACETRIANGLE
+//DP_QC_GETSURFACEPOINTATTRIBUTE
+//DP_QC_MINMAXBOUND
+//DP_QC_MULTIPLETEMPSTRINGS
+//DP_QC_RANDOMVEC
+//DP_QC_SINCOSSQRTPOW
+//DP_QC_SPRINTF
+//DP_QC_STRFTIME
+//DP_QC_STRING_CASE_FUNCTIONS
+//DP_QC_STRINGBUFFERS
+//DP_QC_STRINGCOLORFUNCTIONS
+//DP_QC_STRREPLACE
+//DP_QC_TOKENIZEBYSEPARATOR
+//DP_QC_TRACEBOX
+//DP_QC_TRACETOSS
+//DP_QC_TRACE_MOVETYPES
+//DP_QC_URI_ESCAPE
+//DP_QC_VECTOANGLES_WITH_ROLL
+//DP_QC_VECTORVECTORS
+//DP_QC_WHICHPACK
+//DP_VIEWZOOM
+//DP_REGISTERCVAR
+//DP_SV_BOTCLIENT
+//DP_SV_DROPCLIENT
+//DP_SV_POINTSOUND
+//DP_SV_PRINT
+//DP_SV_SETCOLOR
+//DP_SV_SPAWNFUNC_PREFIX
+//DP_SV_WRITEUNTERMINATEDSTRING
+//DP_TE_PARTICLERAIN
+//DP_TE_PARTICLESNOW
+//DP_TE_STANDARDEFFECTBUILTINS
+//EXT_BITSHIFT
+//FRIK_FILE
+//FTE_PART_SCRIPT
+//FTE_PART_NAMESPACES
+//FTE_PART_NAMESPACE_EFFECTINFO
+//FTE_QC_CHECKCOMMAND
+//FTE_QC_CROSSPRODUCT
+//FTE_QC_INFOKEY
+//FTE_QC_INTCONV
+//FTE_QC_MULTICAST
+//FTE_STRINGS
+//FTE_SV_POINTPARTICLES
+//KRIMZON_SV_PARSECLIENTCOMMAND
+//ZQ_QC_STRINGS

Return to the top of this page or return to the overview of this repo.

Diff qc/csqc/csqc_fteopts.qc

diff --git a/qc/csqc/csqc_fteopts.qc b/qc/csqc/csqc_fteopts.qc
new file mode 100644
index 0000000..8f7324f
--- /dev/null
+++ b/qc/csqc/csqc_fteopts.qc
@@ -0,0 +1,2 @@
+#define FTE
+#pragma TARGET FTE

Return to the top of this page or return to the overview of this repo.

Diff qc/csqc/csqc_hudvanilla.qc

diff --git a/qc/csqc/csqc_hudvanilla.qc b/qc/csqc/csqc_hudvanilla.qc
new file mode 100644
index 0000000..c3b2ac9
--- /dev/null
+++ b/qc/csqc/csqc_hudvanilla.qc
@@ -0,0 +1,958 @@
+/*======================================================================
+ All CSQC functions (Vanilla ONLY version)
+
+ * This file is heavily influenced by QSS devkit (credit=spike)
+ * re-written some functions to make better sense to me
+ * Contains all HUD elements for full quake interface (SP/Coop/Dm)
+ * Sripped out the experimental stuff included in devkit
+ * Converted most of the hardcoded values into constants
+ * Added loads of extra comments to show what is going on
+
+======================================================================*/
+float nocsqc; // CSQC State (0=on, 1=off)
+float detectDP; // Detect DP engine (using wrapper)
+float sitems; // CSQC copy of .items
+float sitems2; // CSQC copy of .items2 (or serverflags)
+float sweapon; // CSQC copy of .weapon
+float shealth; // CSQC copy of .health
+
+float sb_showscores; // Show lower tab scores
+float painfinishtime; // Track player damage for hud face
+
+float intermission; // in intermission
+float intermission_time; // when the intermission started
+
+float player_localentnum; // Entity number that csqc is attached to
+float numclientseats; // coop or splitscreen?
+float maxclients; // maximum players possible on this server
+float cltime; // increases regardless of pause or game speed
+
+.float ext_csqc; // Client Server Quake C HUD alive!
+string CSQC_PING = "csqcping"; // Test command to check if CSCQ alive
+
+// Default sizes for HUD elements
+vector HUDSIZE_320 = '320 24 0';// Background images
+vector HUDSIZE_24 = '24 24 0'; // Status Bar
+vector HUDSIZE_16 = '16 16 0'; // Inventory/Powerups
+vector HUDSIZE_816 = '8 16 0'; // Runes
+vector HUDSIZE_8 = '8 8 0'; // Ammo numbers
+vector HUDSIZE_C8 = '8 0 0'; // Character sizes
+
+// 8 pixel font table (index positions)
+float HUDFONT_WHITE = 0; // Default index = 48-57
+float HUDFONT_YELLOW = 1; // index = index - 30
+float HUDFONT_RED = 2; // index = index + 128
+
+// Default sizes for weapons
+vector HUDWPN_48 = '48 16 0'; // Vanilla LG
+vector HUDWPN_32 = '32 16 0'; // AD/Hipnotic LG
+vector HUDWPN_24 = '24 16 0'; // Default
+
+vector HUDRGB_DEF = '1 1 1';
+float baralpha; // Read scr_sbaralpha variable
+float hudalpha; // All gfx on hud bars
+
+//----------------------------------------------------------------------
+// These constants are only used in CSQC_UpdateView
+float MASK_ENGINE = 1;
+float MASK_VIEWMODEL = 2;
+float VF_MIN = 1;
+float VF_SIZE = 4;
+float VF_DRAWENGINESBAR = 20;
+float VF_DRAWCROSSHAIR = 21;
+
+//----------------------------------------------------------------------
+// Statue, Inventory and Score bars (All 320 x 24)
+string backgrd[3] = { "gfx/sbar", "gfx/ibar", "gfx/scorebar" };
+// Ranking (168 x 24), Complete (184 x 24), Inter (160 x 144)
+// Require .lmp extensions if not loaded diectly from GFX file
+string backlmp[3] = { "gfx/ranking.lmp", "gfx/complete.lmp", "gfx/inter.lmp" };
+
+//----------------------------------------------------------------------
+// Regular (24x24) brown numbers
+string number[10] = {
+ "gfx/num_0", "gfx/num_1", "gfx/num_2", "gfx/num_3", "gfx/num_4",
+ "gfx/num_5", "gfx/num_6", "gfx/num_7", "gfx/num_8", "gfx/num_9"
+};
+// Red (24x24) numbers for no armour, low HP (<25) and no ammo
+string anumber[10] = {
+ "gfx/anum_0", "gfx/anum_1", "gfx/anum_2", "gfx/anum_3", "gfx/anum_4",
+ "gfx/anum_5", "gfx/anum_6", "gfx/anum_7", "gfx/anum_8", "gfx/anum_9"
+};
+
+// Regular (24x24) characters for intermission
+string extrachar[3] = {
+ "gfx/num_colon", "gfx/num_minus", "gfx/num_slash"
+};
+
+// 24x24 pixel icons for Status Bar
+string sbitems[8] = {
+ "gfx/sb_shells", "gfx/sb_nails", "gfx/sb_rocket", "gfx/sb_cells",
+ "gfx/sb_armor1", "gfx/sb_armor2", "gfx/sb_armor3", "gfx/disc"
+};
+
+// 16x16 pixel icons for Information Bar
+string ibitems[6] = {
+ "gfx/sb_key1", "gfx/sb_key2", "gfx/sb_invis", "gfx/sb_invuln",
+ "gfx/sb_suit", "gfx/sb_quad"
+};
+
+// 8x16 pixel runes for Information Bar
+string ibrunes[4] = {
+ "gfx/sb_sigil1", "gfx/sb_sigil2", "gfx/sb_sigil3", "gfx/sb_sigil4"
+};
+
+//----------------------------------------------------------------------
+// All weapon HUD graphics are prefixed with certain characters which
+// means all weapon filenames can be generated with string commands
+// CSQC is really an advanced (QSS/FTE/DP) engine only thing and its
+// very likely that FTE_STRINGS is supported for string manipulation
+//----------------------------------------------------------------------
+// Special constants for weapons
+float WPN_ICONS = 7; // Total weapons to precache pics + flash timers
+float WPN_WIDTHLG = 6; // Odd weapon gfx width (48) default (24)
+// Record when weapons have been added (flash mechanic)
+float flashtime[WPN_ICONS];
+
+// Shotgun, SuperShotgun, Nailgun, SuperNailGun, GrenadeLauncher
+// RocketLauncher, LightningGun
+string wpnnames[WPN_ICONS] = {
+ "shotgun", "sshotgun", "nailgun", "snailgun", "rlaunch",
+ "srlaunch", "lightng"
+};
+// OFF / ON gfx (reflects active weapon)
+string wpnselect[2] = { "gfx/inv_", "gfx/inv2_" };
+// Special flash set for when the player gets weapon
+string wpnflash[5] = { "gfx/inva1_","gfx/inva2_","gfx/inva3_","gfx/inva4_","gfx/inva5_" };
+
+//----------------------------------------------------------------------
+// Frame 00-04 : Regular HP 100/80/60/40/20
+// Frame 05-09 : InPain HP 100/80/60/40/20
+// Frame 10 : Invisibility Ring + Pentagram!
+// Frame 11 : Quad Damage
+// Frame 12 : Invisibility Ring
+// Frame 13 : Pentagram (invulnerability)
+//----------------------------------------------------------------------
+string facetab[14] = {
+ "gfx/face5", "gfx/face4", "gfx/face3", "gfx/face2", "gfx/face1",
+ "gfx/face_p5", "gfx/face_p4", "gfx/face_p3", "gfx/face_p2",
+ "gfx/face_p1",
+ "gfx/face_inv2", "gfx/face_quad", "gfx/face_invis", "gfx/face_invul2"
+};
+
+//----------------------------------------------------------------------
+// Stubs for extra CSQC functions (not all supported)
+//----------------------------------------------------------------------
+// Can query or check anything types on the console here
+float(string str) CSQC_ConsoleCommand = {
+ tokenize_console(str);
+ return FALSE;
+};
+// Can query/check keyboard/mouse/joystick input with this function
+// For key events, scanx is one of the KEY_* values
+// chary is the character code (chr2str to shove it into a string)
+// For mouse events then x+y are the mouse delta/position values
+float(float evtype, float scanx, float chary, float devid) CSQC_InputEvent = {
+ return FALSE;
+};
+// This is linked to client dmg_take / dmg_save / dmg_inflictor fields
+// returning TRUE will block the red flash damage stuff
+float(float save, float take, vector dir) CSQC_Parse_Damage = {
+ painfinishtime = time + 0.2;
+ return FALSE;
+};
+// Can query/check server MSG events
+// CSQC_Parse_Event is called when the client sees a
+// #define svcfte_cgamepacket (83) message from the server
+// Not supported for DP, is called from only QSS/FTE
+void() CSQC_Parse_Event = { };
+
+// Can intercept printed messages from the server (top of screen)
+// printlvl (text filtering) 0=low, 1=medium, 2=high, 3=chat
+// con_notifytime = amount of time the text remains on screen
+// ONLY define this function, if doing something with the text!!
+void(string printmsg, float printlvl) CSQC_Parse_Print = {
+ print(printmsg);
+};
+
+// Running on the Server side of CSQC listening for commands back
+// This is never called on the client side of the progs
+void(string str) SV_ParseClientCommand = {
+ local string ostr, cmd;
+ // Save command string for later
+ ostr = str;
+ // Search for tokens in string
+ tokenize_console(str);
+ // Find the first argument of the command
+ cmd = argv(0);
+ // Is this my (AD CSQC) command?
+ if (cmd == CSQC_PING) self.ext_csqc = TRUE;
+ // Pass through original command
+ else clientcommand(self, ostr);
+};
+
+//======================================================================
+// Display 24pixel numbers to HUD (cope with red version)
+//----------------------------------------------------------------------
+void(vector pos, float value, float threshhold) Hud_DrawNoFont24 =
+{
+ local string val_str, disp_str;
+ local float disp_col, disp_len, disp_no;
+
+ // Make sure value is within range
+ if (value < 0) value = 0;
+ else if (value > 999) value = 999;
+ // Work out which number colour to use
+ if (value <= threshhold) disp_col = TRUE;
+
+ // Round number down (floor) and work out length
+ val_str = ftos(floor(value));
+ disp_len = strlen(val_str);
+ // Move to the lowest digit position first
+ pos_x = pos_x + (3 * HUDSIZE_24_x);
+
+ while (disp_len > 0) {
+ // Countdown early (range is 0-2, strlen returns 1-3)
+ disp_len = disp_len - 1;
+ // Move backward to display a digit
+ pos_x = pos_x - HUDSIZE_24_x;
+ // Convert str character to font index numbers
+ disp_no = (str2chr(val_str, disp_len) - '0');
+ // Double check for any wierd range issues
+ if (disp_no < 0 || disp_no > 9) disp_no = 0;
+ // Work out which number colour to use
+ if (disp_col) disp_str = anumber[disp_no];
+ else disp_str = number[disp_no];
+ // Draw number in correct (right-justified) position
+ drawpic(pos, disp_str, HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
+ }
+};
+
+//----------------------------------------------------------------------
+// Display 24pixel characters to HUD (limited chars available)
+//----------------------------------------------------------------------
+void(vector pos, string num) Hud_DrawCharFont24 =
+{
+ float i, c;
+ // Endless loop until end of string
+ // Keep moving draw pos forward (pos_x)
+ for(i = 0; ; i++, pos_x += HUDSIZE_24_x) {
+ // Read next character from string
+ c = str2chr(num, i);
+ // End of string found?
+ if (!c) break;
+ // Check for special characters
+ else if (c == ':' || c == '.')
+ drawpic(pos, extrachar[0], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
+ else if (c == '-')
+ drawpic(pos, extrachar[1], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
+ else if (c == '/')
+ drawpic(pos, extrachar[2], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
+ // Draw rest of the numbers
+ else if (c >= '0' && c <= '9') {
+ // Sanity check, make sure within range of array
+ c = c - 48; if (c<0 || c>9) c=0;
+ drawpic(pos, number[c], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
+ }
+ }
+};
+
+//----------------------------------------------------------------------
+// Draws small 8 pixel numbers to HUD (white/yellow/red text options)
+//----------------------------------------------------------------------
+void(vector pos, float value, float digit, float zerofill, float fontcol) Hud_DrawNoFont8 =
+{
+ local string val_str;
+ local float disp_len, disp_no;
+
+ // Make sure value is within range
+ if (value < 0) value = 0;
+ // Check max range against max digits
+ else if (value > 999 && digit >= 3) value = 999;
+ else if (value > 99 && digit == 2) value = 99;
+ else if (value > 9 && digit <= 1) value = 9;
+
+ // Round number down (floor) and work out length
+ val_str = ftos(floor(value));
+ disp_len = strlen(val_str);
+
+ // Zero fill number?
+ if (zerofill) {
+ while (disp_len < digit) {
+ // Keep adding more zero's
+ val_str = strcat("0", val_str);
+ // Exit condition?
+ disp_len = strlen(val_str);
+ }
+ }
+
+ // Move to the lowest digit position first
+ pos_x = pos_x + (digit * HUDSIZE_8_x);
+
+ while (disp_len > 0) {
+ // Countdown first (digit positions = 0-2)
+ disp_len = disp_len - 1;
+ // Move backward to display a digit
+ pos_x = pos_x - HUDSIZE_8_x;
+ // Convert character to number (font table index 48-57)
+ disp_no = str2chr(val_str, disp_len);
+ if (fontcol == HUDFONT_YELLOW) disp_no = disp_no - 30;
+ else if (fontcol == HUDFONT_RED) disp_no = disp_no + 128;
+ // Draw character from ascii font table (right-justified)
+ drawcharacter(pos, disp_no, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ }
+};
+
+//----------------------------------------------------------------------
+// Change HUD face to reflect Health, Pain or Powerups
+//----------------------------------------------------------------------
+void(vector pos) Hud_DrawFace =
+{
+ string face;
+ local float hpframe;
+
+ // Start with InvRing as it has two states
+ if (sitems & CSQC_INVISIBILITY) {
+ // InvRing + Pentagram!?! WTF!?! SandyP E4 design!
+ if (sitems & CSQC_INVULNERABILITY) face = facetab[10];
+ // Just InvRing only
+ else face = facetab[12];
+ }
+ // Quad only
+ else if (sitems & CSQC_QUAD) face = facetab[11];
+ // Pentagram only
+ else if (sitems & CSQC_INVULNERABILITY) face = facetab[13];
+ // Regular face
+ else {
+ // Work out face based on HP (100/80/60/40/20)
+ hpframe = floor(shealth / 20);
+ // Check for negative and upper (MegaHP) limits
+ if (hpframe < 0) hpframe = 0;
+ else if (hpframe > 4) hpframe = 4;
+ // Check for any pain/flinch updates
+ if (painfinishtime > time) hpframe = hpframe + 5;
+ // Final HP face
+ face = facetab[hpframe];
+ }
+
+ // Draw face - always 24x24 size, full rgb/alpha
+ drawpic(pos, face, HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
+};
+
+//----------------------------------------------------------------------
+// Update a weapon icon with selection or flash features
+//----------------------------------------------------------------------
+static void(float num, vector pos) Hud_DrawWeapon =
+{
+ local string prefix, file_str;
+ local vector gfx_size;
+ local float flash;
+
+ // The weapon flash is done every 0.1s and repeated twice!
+ // When the player gets a new weapon the time is reset
+ // This function will count the time difference for flashing
+ // Convert the flash time to a 0-10+ range
+ flash = (time - flashtime[num])*10;
+
+ // Has the flash happened twice? (finished)
+ if (flash >= 10) {
+ // Work out if this weapon is currently selected
+ if (sweapon == (1<<num)) prefix = wpnselect[1];
+ // Default is no highlight
+ else prefix = wpnselect[0];
+ }
+ // Flashing!
+ else {
+ // Is the flash into second phase?
+ if (flash < 0) flash = 0;
+ else if (flash >= 5) flash = flash - 5;
+ // flash is only 0-4 frames
+ prefix = wpnflash[flash];
+ }
+ // Merge prefix type (defined above) to weapon filename
+ // Without string (str) functions this would involve a giant table
+ // This sorta assumes that CSQC is running on an advanced engine
+ // QSS/FTE/DP all support FTE_STRINGS extra str functions
+ file_str = strcat(prefix, wpnnames[num]);
+
+ // Most weapons are 24 pixels wide (half of ammo above)
+ // As always there is an exception (lightning gun)
+ if (num == WPN_WIDTHLG) gfx_size = HUDWPN_48;
+ else gfx_size = HUDWPN_24;
+ // Show weapon GFX (active/deactive/flashing)
+ drawpic(pos, file_str, gfx_size, HUDRGB_DEF, hudalpha, 0);
+};
+
+//======================================================================
+// STATUS BAR ( Armour / Health quantities and current Ammo selected)
+//----------------------------------------------------------------------
+void (vector pos, vector virtsize) Hud_DrawSBar =
+{
+ // Draw primary HUD bar (Armour/Face/Health/Ammo)
+ drawpic(pos, backgrd[0], HUDSIZE_320, HUDRGB_DEF, baralpha, 0);
+
+ // Deal with Pentagram first, its a simple test/update
+ if (sitems & CSQC_INVULNERABILITY) {
+ // Make sure 666 is in 24 pixel giant red numbers!
+ Hud_DrawNoFont24(pos+[24,0], 666, 666);
+ // Draw a pentagram symbol in the armour HUD slot
+ drawpic(pos, sbitems[7], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
+ }
+ else {
+ // Show armour type/quantity active
+ Hud_DrawNoFont24(pos+'24 0 0', getstatf(CLIENT_ARMOR), 25);
+ // Only 3 armour types (green/yellow/red)
+ if (sitems & CSQC_ARMOR1)
+ drawpic(pos, sbitems[4], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
+ else if (sitems & CSQC_ARMOR2)
+ drawpic(pos, sbitems[5], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
+ else if (sitems & CSQC_ARMOR3)
+ drawpic(pos, sbitems[6], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
+ }
+
+ // Draw face + HP value
+ Hud_DrawFace(pos+[112,0]);
+ Hud_DrawNoFont24(pos+[136,0], shealth, 25);
+
+ // Only update ammo type/quantity if not using axe!
+ if (sweapon != CSQC_AXE) {
+ Hud_DrawNoFont24(pos+[248,0], getstatf(CLIENT_AMMO), 10);
+ if (sitems & CSQC_SHELLS)
+ drawpic(pos+[224,0], sbitems[0], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
+ else if (sitems & CSQC_NAILS)
+ drawpic(pos+[224,0], sbitems[1], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
+ else if (sitems & CSQC_ROCKETS)
+ drawpic(pos+[224,0], sbitems[2], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
+ else if (sitems & CSQC_CELLS)
+ drawpic(pos+[224,0], sbitems[3], HUDSIZE_24, HUDRGB_DEF, hudalpha, 0);
+ }
+};
+
+//======================================================================
+// INVENTORY BAR ( Ammo quantities, keys/runes and powerups )
+//----------------------------------------------------------------------
+void (vector pos, vector br) Hud_DrawIBar =
+{
+ local vector topcol, botcol;
+ local string player_frags;
+
+ // Draw background bar using scr_sbaralpha default
+ drawpic(pos, backgrd[1], HUDSIZE_320, HUDRGB_DEF, baralpha, 0);
+
+ // Always draw ammo scores
+ Hud_DrawNoFont8(pos + [10,0], getstatf(CLIENT_SHELLS), 3, FALSE, HUDFONT_YELLOW);
+ Hud_DrawNoFont8(pos + [58,0], getstatf(CLIENT_NAILS), 3, FALSE, HUDFONT_YELLOW);
+ Hud_DrawNoFont8(pos + [106,0], getstatf(CLIENT_ROCKETS), 3, FALSE, HUDFONT_YELLOW);
+ Hud_DrawNoFont8(pos + [154,0], getstatf(CLIENT_CELLS), 3, FALSE, HUDFONT_YELLOW);
+
+ // Draw weapons and highlight current one
+ if (sitems & CSQC_SHOTGUN) Hud_DrawWeapon(0, pos+[24*0,8]);
+ if (sitems & CSQC_SUPER_SHOTGUN) Hud_DrawWeapon(1, pos+[24*1,8]);
+ if (sitems & CSQC_NAILGUN) Hud_DrawWeapon(2, pos+[24*2,8]);
+ if (sitems & CSQC_SUPER_NAILGUN) Hud_DrawWeapon(3, pos+[24*3,8]);
+ if (sitems & CSQC_GRENADE_LAUNCHER) Hud_DrawWeapon(4, pos+[24*4,8]);
+ if (sitems & CSQC_ROCKET_LAUNCHER) Hud_DrawWeapon(5, pos+[24*5,8]);
+ if (sitems & CSQC_LIGHTNING) Hud_DrawWeapon(6, pos+[24*6,8]);
+
+ // Draw inventory items
+ if (sitems & CSQC_KEY1)
+ drawpic(pos+[192,8], ibitems[0], HUDSIZE_16, HUDRGB_DEF, hudalpha, 0);
+ if (sitems & CSQC_KEY2)
+ drawpic(pos+[208,8], ibitems[1], HUDSIZE_16, HUDRGB_DEF, hudalpha, 0);
+ if (sitems & CSQC_INVISIBILITY)
+ drawpic(pos+[224,8], ibitems[2], HUDSIZE_16, HUDRGB_DEF, hudalpha, 0);
+ if (sitems & CSQC_INVULNERABILITY)
+ drawpic(pos+[240,8], ibitems[3], HUDSIZE_16, HUDRGB_DEF, hudalpha, 0);
+ if (sitems & CSQC_SUIT)
+ drawpic(pos+[256,8], ibitems[4], HUDSIZE_16, HUDRGB_DEF, hudalpha, 0);
+ if (sitems & CSQC_QUAD)
+ drawpic(pos+[272,8], ibitems[5], HUDSIZE_16, HUDRGB_DEF, hudalpha, 0);
+
+ // Draw Runes (special size + location)
+ if (sitems2 & CSQC_RUNE1)
+ drawpic(pos+[288,8], ibrunes[0], HUDSIZE_816, HUDRGB_DEF, hudalpha, 0);
+ if (sitems2 & CSQC_RUNE2)
+ drawpic(pos+[296,8], ibrunes[1], HUDSIZE_816, HUDRGB_DEF, hudalpha, 0);
+ if (sitems2 & CSQC_RUNE3)
+ drawpic(pos+[304,8], ibrunes[2], HUDSIZE_816, HUDRGB_DEF, hudalpha, 0);
+ if (sitems2 & CSQC_RUNE4)
+ drawpic(pos+[312,8], ibrunes[3], HUDSIZE_816, HUDRGB_DEF, hudalpha, 0);
+
+ //should probably show team scores, but this mimics vanilla
+ if (deathmatch) {
+ // Move to space above powerups
+ pos_x += 194;
+
+ // Loop through 4 players
+ for (float i = -1; i >= -4; i--) {
+ // Read frag score of next player
+ player_frags = getplayerkeyvalue(i, "frags");
+ // No frags? stop loop
+ if (player_frags == "") break;
+ // Read deathmatch player top/bottom skin colours
+ topcol = stov(getplayerkeyvalue(i, "topcolor_rgb"));
+ botcol = stov(getplayerkeyvalue(i, "bottomcolor_rgb"));
+ // Draw skin colours (alpha was 0.75 hardcoded)
+ drawfill(pos+[0,1], [28,3], topcol, 0.75, 0);
+ drawfill(pos+[0,4], [28,4], botcol, 0.75, 0);
+ // Draw frag score (New global small font function)
+ Hud_DrawNoFont8(pos + '2 0 0', stof(player_frags), 3, FALSE, HUDFONT_WHITE);
+ // Find player entity attached to this HUD
+ if (player_localentnum == stof(getplayerkeyvalue(i, "viewentity"))) {
+ // special characters = []
+ drawcharacter(pos+[-4,0], 0xe010, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ drawcharacter(pos+[24,0], 0xe011, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ }
+ // Move forward to next hud space
+ pos_x += 8*4;
+ }
+ }
+};
+
+//======================================================================
+// Scoreboard Bar (shows monster/secret quantities and map info)
+//----------------------------------------------------------------------
+void(vector pos, float bx, float by, float bwidth, float bheight, float pixelspeed, string draw_str) Hud_ScrollTextBox =
+{
+ local float str_width, str_double, str_speed;
+ local string wide_str;
+
+ // draw debug visual box to show area on screen
+ //drawfill( pos+[bx,by], [bwidth,bheight], HUDRGB_DEF, 0.1, 0);
+
+ // Find out width of string in pixels (using font 8)
+ str_width = stringwidth( draw_str, TRUE, HUDSIZE_8);
+ // String less than window width?
+ if (str_width < bwidth) {
+ // Center the map name string in the box area
+ str_double = (bwidth - str_width) / 2;
+ // Display string normally (no scrolling required)
+ drawstring( pos+[bx+str_double, by], draw_str, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ }
+ else {
+ // Create double length string with boundary marker
+ wide_str = strcat(draw_str, " /// ", draw_str);
+ // Setup clip (scissor) area for exclusive drawing
+ drawsetcliparea( pos_x + bx, pos_y + by, bwidth, bheight);
+ str_double = stringwidth( wide_str, TRUE, HUDSIZE_8);
+ // create offset of string to make it look like its scrolling
+ str_speed = mod(cltime * pixelspeed, (str_double - str_width));
+ // draw string (with offset) inside of clip (scissor) area only
+ drawstring( pos+[bx - str_speed, by], wide_str, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ // Reset clip string area to default
+ drawresetcliparea();
+ }
+};
+
+//----------------------------------------------------------------------
+// Quakespasm scoreboard layout (no time)
+//----------------------------------------------------------------------
+void(vector pos) Hud_QSScores_SBar =
+{
+ local string skill_str, map_str;
+ local float digit;
+
+ // Clear status bar ready for map info/scores
+ drawpic(pos, backgrd[2], HUDSIZE_320, HUDRGB_DEF, baralpha, 0);
+ // Display headings
+ drawstring(pos+[8,12], "Kills:", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ drawstring(pos+[80,12], "/", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ drawstring(pos+[132,12], "Skill ", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ drawstring(pos+[208,12], "Secrets:", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ drawstring(pos+[288,12], "/", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ // Display monster/secret totals
+ Hud_DrawNoFont8(pos+[56,12], getstatf(CLIENT_KILLEDMONSTERS), 3, FALSE, HUDFONT_WHITE);
+ if (getstatf(CLIENT_TOTALMONSTERS) < 100) digit = 2;
+ else digit = 3;
+ Hud_DrawNoFont8(pos+[88,12], getstatf(CLIENT_TOTALMONSTERS), digit, FALSE, HUDFONT_WHITE);
+ Hud_DrawNoFont8(pos+[272,12], getstatf(CLIENT_FOUNDSECRETS), 2, FALSE, HUDFONT_WHITE);
+ Hud_DrawNoFont8(pos+[296,12], getstatf(CLIENT_TOTALSECRETS), 2, FALSE, HUDFONT_WHITE);
+ // Display map skill level
+ skill_str = autocvar(skill, "1");
+ drawstring(pos+[180,12], skill_str, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+
+ // Level designers Map name + File name
+ map_str = strcat(world.message, " (", mapname, ")");
+ Hud_ScrollTextBox(pos, 8, 4, 304, 8, 16, map_str);
+};
+
+//----------------------------------------------------------------------
+// The original ID scoreboard layout (no skill, map filename)
+//----------------------------------------------------------------------
+void(vector pos) Hud_IDScores_SBar =
+{
+ local float nsecs, nmins;
+
+ // Clear status bar ready for map info/scores
+ drawpic(pos, backgrd[2], HUDSIZE_320, HUDRGB_DEF, baralpha, 0);
+ // Display headings
+ drawstring(pos+[8,4], "Monsters:", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ drawstring(pos+[104,4], "/", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ drawstring(pos+[8,12], "Secrets :", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ drawstring(pos+[104,12], "/", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ drawstring(pos+[184,4], "Time :", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ drawstring(pos+[256,4], ":", HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ // Display monster/secret totals
+ Hud_DrawNoFont8(pos+[80,4], getstatf(CLIENT_KILLEDMONSTERS), 3, FALSE, HUDFONT_WHITE);
+ Hud_DrawNoFont8(pos+[112,4], getstatf(CLIENT_TOTALMONSTERS), 3, FALSE, HUDFONT_WHITE);
+ Hud_DrawNoFont8(pos+[80,12], getstatf(CLIENT_FOUNDSECRETS), 3, FALSE, HUDFONT_WHITE);
+ Hud_DrawNoFont8(pos+[112,12], getstatf(CLIENT_TOTALSECRETS), 3, FALSE, HUDFONT_WHITE);
+ // Work out time passed
+ nmins = floor(time/60);
+ nsecs = floor(time - nmins*60);
+ Hud_DrawNoFont8(pos+[232,4], nmins, 3, FALSE, HUDFONT_WHITE);
+ Hud_DrawNoFont8(pos+[264,4], nsecs, 2, TRUE, HUDFONT_WHITE);
+ // Level designers Map name
+ Hud_ScrollTextBox(pos, 140, 12, 176, 8, 16, world.message);
+};
+
+//======================================================================
+// Deathmatch scoreboard
+//----------------------------------------------------------------------
+vector(string picname, float height) Hud_AspectSize =
+{
+ local vector sz;
+ sz = drawgetimagesize(picname);
+ return [sz_x * height/sz_y, height];
+};
+
+//----------------------------------------------------------------------
+void(string picname, float screenwidth, vector pos, float height) Hud_CentrePic =
+{
+ local vector sz;
+ sz = Hud_AspectSize(picname, height);
+ pos_x += (screenwidth-sz_x)/2;
+ drawpic(pos, picname, sz, HUDRGB_DEF, hudalpha, 0);
+};
+
+//----------------------------------------------------------------------
+void(vector virtmin, vector virtsize) Hud_DMScoreboard =
+{
+ local float isspec;
+ local vector pos, topcol, botcol;
+ string player_name, player_frags, player_ping;
+
+ // Working copy
+ pos = virtmin;
+
+ // Check for 16 players?
+ player_name = getplayerkeyvalue(-16, "name");
+ if (player_name == "") pos_y += (virtsize_y-200)/2;
+
+ // Only draw the header when its not a really big game
+ player_name = getplayerkeyvalue(-24, "name");
+ if (player_name == "") {
+ pos_y += 8;
+ // Display header (ranking.lmp) gfx for DM scoreboard
+ Hud_CentrePic(backlmp[0], virtsize_x, pos, 24);
+ // A double update of Y, only spike knows why!?!
+ pos_y += 24; pos_y += 10;
+ }
+
+ // Another double X update, no idea why!
+ pos_x += (virtsize_x-320)/2;
+ pos_x += 80;
+
+ //negative numbers are players sorted by frags.
+ for (float i = -1; ; i--, pos_y += 10) {
+ // Check for next player name
+ player_name = getplayerkeyvalue(i, "name");
+ // No more in list, end loop
+ if (player_name == "") break;
+
+ // Read player stats (frag/ping)
+ isspec = stof(getplayerkeyvalue(i, "*spectator"));
+ player_frags = getplayerkeyvalue(i, "frags");
+ player_ping = getplayerkeyvalue(i, "ping");
+ // Read deathmatch player top/bottom skin colours
+ topcol = stov(getplayerkeyvalue(i, "topcolor_rgb"));
+ botcol = stov(getplayerkeyvalue(i, "bottomcolor_rgb"));
+
+ // Re-format the player name (no case conversion, force red)
+ player_name = strconv(0,2,2, player_name);
+ // Draw frag score (New global small font function)
+ Hud_DrawNoFont8(pos-[8*5,0], stof(player_ping), 3, FALSE, HUDFONT_WHITE);
+
+ // Which type of player? Spectator or Active?
+ if (isspec)
+ drawstring(pos+[4,0], "spec", [8,8], HUDRGB_DEF, hudalpha, 0);
+ else
+ {
+ // Draw skin colours (alpha was 0.75 hardcoded)
+ drawfill(pos+[0,0], [40,4], topcol, 0.75, 0);
+ drawfill(pos+[0,4], [40,4], botcol, 0.75, 0);
+
+ // Draw frag score (New global small font function)
+ Hud_DrawNoFont8(pos+[8,0], stof(player_frags), 3, FALSE, HUDFONT_WHITE);
+ // Find player entity attached to this HUD
+ if (player_localentnum == stof(getplayerkeyvalue(i, "viewentity"))) {
+ // special characters = []
+ drawcharacter(pos+[0,0], 0xe010, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ drawcharacter(pos+[32,0], 0xe011, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ }
+ }
+ // Finally draw player name
+ drawstring(pos+[64,0], player_name, HUDSIZE_8, HUDRGB_DEF, hudalpha, 0);
+ }
+};
+
+//======================================================================
+// Final Intermission
+//----------------------------------------------------------------------
+void(vector virtmin, vector virtsize) Hud_Intermission =
+{
+ local vector pos;
+ // Create positions based on virtual screen
+ pos = virtmin + (virtsize-[320,200])/2;
+
+ // Draw Intermission title and table info (Time/secret/kill)
+ Hud_CentrePic(backlmp[1], 320, pos+[0,24], 24);
+ drawpic(pos+[0,56], backlmp[2], [160,144], HUDRGB_DEF, hudalpha, 0);
+
+ // Generate complete string and then draw 1 character at time
+ // Uses Sprintf function to feed values into final string
+ // This function should be supported by Advanced engines
+ Hud_DrawCharFont24(pos+[144, 64], sprintf("%3.0f:%02.0f", intermission_time/60, intermission_time%60));
+ Hud_DrawCharFont24(pos+[144, 104], sprintf("%3.0f/%.0f", getstatf(CLIENT_FOUNDSECRETS), getstatf(CLIENT_TOTALSECRETS)));
+ Hud_DrawCharFont24(pos+[144, 144], sprintf("%3.0f/%.0f", getstatf(CLIENT_KILLEDMONSTERS), getstatf(CLIENT_TOTALMONSTERS)));
+};
+
+//======================================================================
+// Speedometer CEV
+//----------------------------------------------------------------------
+void(vector pos) Hud_Speedometer =
+{
+ local vector v;
+
+ // requires support in ssqc WorldSpawn
+ v_x = getstatf(CLIENT_VELOCITY_X);
+ v_y = getstatf(CLIENT_VELOCITY_Y);
+ v_z = 0;
+
+ Hud_DrawNoFont8(pos, vlen (v), 3, FALSE, HUDFONT_WHITE);
+};
+
+//======================================================================
+// MAIN ENTRY POINT FOR HUD!!!
+//----------------------------------------------------------------------
+void(vector virtsize, float showscores) CSQC_DrawHud =
+{
+ local vector pos, pos_speedo;
+ local float oitems, hudviewsize, i;
+
+ // Save previous HUD versions for flash function
+ oitems = sitems;
+
+ //------------------------------------------------------------------
+ // All variables have to be specially setup and passed between
+ // progs and csprogs as they are not connected in VM space
+ // By default CSQC has 30 (most commonly used) parameters setup
+ // Unfortunately some of them need to be converted (bitswapped)
+ // to make them reaable again (I blame spike for this mess)
+ // The downside to this bitswapping mess is that the serverflags
+ // is not passed to CSQC completely, only the first 4bits (runes)
+ //------------------------------------------------------------------
+ sitems = getstatbits(CLIENT_ITEMS, 0, 23);
+ sitems2 = getstatbits(CLIENT_ITEMS, 23, 9);
+ sweapon = getstatf(CLIENT_ACTIVEWEAPON);
+ shealth = getstatf(CLIENT_HEALTH);
+
+ // Don't show HUD, intermission or dead
+ if (intermission || shealth <= 0) return;
+
+ //------------------------------------------------------------------
+ // Read console variable for background HUD alpha
+ baralpha = cvar("scr_sbaralpha");
+ if (baralpha == 0) baralpha = 0.75;
+ // Default is 1 for everything else
+ hudalpha = 1;
+
+ //------------------------------------------------------------------
+ // Check if any weapons have been added to the inventory
+ // Update time so the flash function can detect it
+ // Check for player count for splitscreen!?! QSS/FTE feature
+ if (numclientseats <= 1) {
+ // Player alive and inventory changd?
+ if (shealth && sitems != oitems) {
+ // Go through all weapon flash counters
+ for (i = 0; i < WPN_ICONS; i++) {
+ // Found weapon and its new?
+ if ((sitems & (1<<i)) && !(oitems & (1<<i)))
+ // Reset timer
+ flashtime[i] = time;
+ }
+ }
+ }
+
+ //------------------------------------------------------------------
+ // Find out how much of the HUD is being displayed
+ // 100 = InfoBar & StatusBar (ALL=Default)
+ // 110 = StatusBar Only
+ // 120 = Speedometer
+ // 130 = Nothing
+ //------------------------------------------------------------------
+ // Read current HUD size
+ hudviewsize = cvar("viewsize");
+ // Any HUD to display?
+ if (hudviewsize < 130) {
+ // Override scoreboard - check if no player health
+ if (shealth <= 0) showscores = TRUE;
+ // Find out mid point of screen
+ pos_x = (virtsize_x-320)/2;
+ pos_y = virtsize_y;
+ pos_z = 0;
+
+ // trying to center the speedometer display just below
+ // the crosshair. This doesn't seem to be right but it
+ // works on my 960x720 window. CEV.
+ pos_speedo_x = virtsize_x/2.0;
+ pos_speedo_y = virtsize_y/2.0;
+ pos_speedo_z = 0;
+ Hud_Speedometer(pos_speedo - [8*1.5,-8]);
+ if (hudviewsize < 120) {
+ // Either show Sbar or Scores (bars are centered)
+ if (showscores) Hud_QSScores_SBar(pos - '0 24 0');
+ else Hud_DrawSBar(pos - '0 24 0', virtsize);
+ }
+ // Can the Info Bar be displayed?
+ if (hudviewsize < 110)
+ Hud_DrawIBar(pos - '0 48 0', virtsize);
+ }
+};
+
+//----------------------------------------------------------------------
+void(vector virtsize, float showscores) CSQC_DrawScores =
+{
+ shealth = getstatf(CLIENT_HEALTH);
+ if (intermission || showscores || shealth <= 0) {
+ if (deathmatch) Hud_DMScoreboard('0 0 0', virtsize);
+ else if (intermission) Hud_Intermission('0 0 0', virtsize);
+ }
+};
+
+//----------------------------------------------------------------------
+void(float vwidth, float vheight, float notmenu) CSQC_UpdateView =
+{
+ local vector ssize;
+ ssize_x = vwidth; ssize_y = vheight; ssize_z = 0;
+
+ // Is the CSQC functionality enabled/disabled?
+ nocsqc = cvar("cl_nocsqc");
+
+ clearscene();
+ addentities(MASK_ENGINE|MASK_VIEWMODEL);
+ setproperty(VF_MIN, '0 0');
+ setproperty(VF_SIZE, ssize);
+ // If hud is disabled, draw engine hud instead
+ setproperty(VF_DRAWENGINESBAR, nocsqc);
+ setproperty(VF_DRAWCROSSHAIR, TRUE);
+ renderscene();
+
+ // Revert back to using engine HUD?
+ if (nocsqc > 0) return;
+
+ // Required for DP engine
+ if (detectDP == TRUE) {
+ ssize_x = cvar("vid_conwidth");
+ ssize_y = cvar("vid_conheight");
+ }
+
+ // Used on intermission screen later
+ if (!intermission) intermission_time = time;
+ // Read deathmatch variable and create csprogs coop variable
+ // csprogs has no knowledge of the coop variable
+ deathmatch = stof(serverkey("deathmatch"));
+ coop = !deathmatch && maxclients > 1;
+
+ // Draw the HUDs and scoreboards
+ CSQC_DrawHud(ssize, sb_showscores);
+ CSQC_DrawScores(ssize, sb_showscores);
+};
+
+//----------------------------------------------------------------------
+// Registers HUD gfx images (all setup in string arrays)
+//----------------------------------------------------------------------
+void(float apilevel, string enginename, float engineversion) CSQC_Init =
+{
+ local float i, wadonly;
+
+ // Is the CSQC functionality enabled/disabled?
+ nocsqc = cvar("cl_nocsqc");
+ // Revert back to using engine HUD?
+ if (nocsqc > 0) return;
+
+ // Send ping back to server that CSQC client is alive
+ // This can be used on the server side to detect CSQC
+ // and change functions for new features
+ localcmd(strcat("cmd ", CSQC_PING, "\n"));
+
+ // precache from gfx.wad ONLY!?!
+ wadonly = TRUE;
+
+ // Cache all string tables
+ for (i = 0; i < 14; i++) {
+ // HUD background images (320 wide+)
+ if (i < backgrd.length) precache_pic(backgrd[i], wadonly);
+ // Large 24x24 brown/red numbers
+ if (i < number.length) {
+ precache_pic(number[i], wadonly);
+ precache_pic(anumber[i], wadonly);
+ }
+ // Large 24x24 extra font characters (intermission)
+ if (i < extrachar.length) precache_pic(extrachar[i], wadonly);
+ // Large 24x24 player face
+ if (i < facetab.length) precache_pic(facetab[i], wadonly);
+ // Large 24x24 icons
+ if (i < sbitems.length) precache_pic(sbitems[i], wadonly);
+ // Small 16x16 icons
+ if (i < ibitems.length) precache_pic(ibitems[i], wadonly);
+ // Special 8x16 runes
+ if (i < ibrunes.length) precache_pic(ibrunes[i], wadonly);
+ // All weapon setups (on/off/flashing)
+ if (i < wpnnames.length) {
+ precache_pic(strcat(wpnselect[0], wpnnames[i]),wadonly);
+ precache_pic(strcat(wpnselect[1], wpnnames[i]),wadonly);
+ precache_pic(strcat(wpnflash[0], wpnnames[i]), wadonly);
+ precache_pic(strcat(wpnflash[1], wpnnames[i]), wadonly);
+ precache_pic(strcat(wpnflash[2], wpnnames[i]), wadonly);
+ precache_pic(strcat(wpnflash[3], wpnnames[i]), wadonly);
+ precache_pic(strcat(wpnflash[4], wpnnames[i]), wadonly);
+ }
+ }
+};
+
+//----------------------------------------------------------------------
+// Wrapper for CSQC_Init to try and detect DP engine
+//----------------------------------------------------------------------
+__wrap void(float apilevel, string enginename, float engineversion) CSQC_Init =
+{
+ // Try to detect DP engine (needed for CSQC_UpdateView later)
+ if (!apilevel && !enginename && !engineversion) detectDP = TRUE;
+ // Execute previous CSQC_Init function
+ prior(apilevel, enginename, engineversion);
+
+ registercommand("+showscores");
+ registercommand("+showscores");
+ registercommand("+showteamscores");
+ registercommand("+showteamscores");
+};
+
+//----------------------------------------------------------------------
+// Wrapper for CSQC_ConsoleCommand to show different scoreboards
+//----------------------------------------------------------------------
+__wrap float(string str) CSQC_ConsoleCommand =
+{
+ if (prior(str))
+ return TRUE;
+ string c = argv(0);
+ if (c == "+showscores")
+ sb_showscores |= 1;
+ else if (c == "-showscores")
+ sb_showscores &~= 1;
+ else if (c == "+showteamscores")
+ sb_showscores |= 2;
+ else if (c == "-showteamscores")
+ sb_showscores &~= 2;
+ else return FALSE;
+ return TRUE;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/csqc/csqc_progs.src

diff --git a/qc/csqc/csqc_progs.src b/qc/csqc/csqc_progs.src
new file mode 100644
index 0000000..d23fe5d
--- /dev/null
+++ b/qc/csqc/csqc_progs.src
@@ -0,0 +1,7 @@
+../../csprogs.dat
+
+csqc_fteopts.qc
+csqc_defsclient.qc
+csqc_defs.qc
+// didn't import csqc_hudad.qc
+csqc_hudvanilla.qc

Return to the top of this page or return to the overview of this repo.

Diff qc/custom_mdls.qc

diff --git a/qc/custom_mdls.qc b/qc/custom_mdls.qc
new file mode 100644
index 0000000..266aa92
--- /dev/null
+++ b/qc/custom_mdls.qc
@@ -0,0 +1,70 @@
+/*
+
+========================================================================
+
+MAPPER-SETTABLE CUSTOM MODELS FOR MONSTERS
+
+========================================================================
+*/
+
+/*
+================
+precache_model_custom
+================
+*/
+void(.string mdl_field, string default_file) precache_model_custom =
+{
+ if (self.mdl_field != "")
+ precache_model (self.mdl_field);
+ else
+ precache_model (default_file);
+};
+
+
+void(string default_file) precache_head_model = { precache_model_custom (mdl_head, default_file); };
+void(string default_file) precache_body_model = { precache_model_custom (mdl_body, default_file); };
+void(string default_file) precache_proj_model = { precache_model_custom (mdl_proj, default_file); };
+void(string default_file) precache_gib1 = { precache_model_custom (mdl_gib1, default_file); };
+void(string default_file) precache_gib2 = { precache_model_custom (mdl_gib2, default_file); };
+void(string default_file) precache_gib3 = { precache_model_custom (mdl_gib3, default_file); };
+
+
+/*
+================
+precache_model2_custom
+================
+*/
+void(.string mdl_field, string default_file) precache_model2_custom =
+{
+ if (self.mdl_field != "")
+ precache_model2 (self.mdl_field);
+ else
+ precache_model2 (default_file);
+};
+
+
+void(string default_file) precache_head_model2 = { precache_model2_custom (mdl_head, default_file); };
+void(string default_file) precache_body_model2 = { precache_model2_custom (mdl_body, default_file); };
+void(string default_file) precache_proj_model2 = { precache_model2_custom (mdl_proj, default_file); };
+void(string default_file) precache_exproj_model2 = { precache_model2_custom (mdl_exproj, default_file); };
+
+
+/*
+================
+model_custom
+================
+*/
+void(.string mdl_field, string default_file) model_custom =
+{
+ if (self.mdl_field != "")
+ {
+ setmodel (self, self.mdl_field);
+ // dprint("CUSTOM MODEL LOADED\n");
+ }
+ else
+ setmodel (self, default_file);
+};
+
+void(string default_file) body_model = { model_custom (mdl_body, default_file); };
+// void(string default_file) head_model = { model_custom (mdl_head, default_file); };
+void(string default_file) proj_model = { model_custom (mdl_proj, default_file); };

Return to the top of this page or return to the overview of this repo.

Diff qc/custom_snd.qc

diff --git a/qc/custom_snd.qc b/qc/custom_snd.qc
new file mode 100644
index 0000000..920d093
--- /dev/null
+++ b/qc/custom_snd.qc
@@ -0,0 +1,100 @@
+/*
+========================================================================
+
+MAPPER-SETTABLE CUSTOM SOUND EFFECTS FOR MONSTERS
+
+========================================================================
+
+
+This file was created for progs_dump by Ian "iw" Walshaw, January 2020.
+
+TODO: iw to add descriptive comments to this file.
+
+
+========================================================================
+*/
+
+
+/*
+================
+precache_sound_custom
+================
+*/
+void(.string snd_field, string default_file) precache_sound_custom =
+{
+ if (self.snd_field != "")
+ precache_sound (self.snd_field);
+ else
+ precache_sound (default_file);
+};
+
+
+void(string default_file) precache_sound_attack = { precache_sound_custom (snd_attack, default_file); };
+void(string default_file) precache_sound_death = { precache_sound_custom (snd_death, default_file); };
+void(string default_file) precache_sound_hit = { precache_sound_custom (snd_hit, default_file); };
+void(string default_file) precache_sound_idle = { precache_sound_custom (snd_idle, default_file); };
+void(string default_file) precache_sound_land = { precache_sound_custom (snd_land, default_file); };
+void(string default_file) precache_sound_misc = { precache_sound_custom (snd_misc, default_file); };
+void(string default_file) precache_sound_misc1 = { precache_sound_custom (snd_misc1, default_file); };
+void(string default_file) precache_sound_misc2 = { precache_sound_custom (snd_misc2, default_file); };
+void(string default_file) precache_sound_misc3 = { precache_sound_custom (snd_misc3, default_file); };
+void(string default_file) precache_sound_move = { precache_sound_custom (snd_move, default_file); };
+void(string default_file) precache_sound_pain = { precache_sound_custom (snd_pain, default_file); };
+void(string default_file) precache_sound_sight = { precache_sound_custom (snd_sight, default_file); };
+
+
+/*
+================
+precache_sound2_custom
+================
+*/
+void(.string snd_field, string default_file) precache_sound2_custom =
+{
+ if (self.snd_field != "")
+ precache_sound2 (self.snd_field);
+ else
+ precache_sound2 (default_file);
+};
+
+
+void(string default_file) precache_sound2_attack = { precache_sound2_custom (snd_attack, default_file); };
+void(string default_file) precache_sound2_death = { precache_sound2_custom (snd_death, default_file); };
+void(string default_file) precache_sound2_hit = { precache_sound2_custom (snd_hit, default_file); };
+void(string default_file) precache_sound2_idle = { precache_sound2_custom (snd_idle, default_file); };
+void(string default_file) precache_sound2_land = { precache_sound2_custom (snd_land, default_file); };
+void(string default_file) precache_sound2_misc = { precache_sound2_custom (snd_misc, default_file); };
+void(string default_file) precache_sound2_misc1 = { precache_sound2_custom (snd_misc1, default_file); };
+void(string default_file) precache_sound2_misc2 = { precache_sound2_custom (snd_misc2, default_file); };
+void(string default_file) precache_sound2_misc3 = { precache_sound2_custom (snd_misc3, default_file); };
+void(string default_file) precache_sound2_move = { precache_sound2_custom (snd_move, default_file); };
+void(string default_file) precache_sound2_pain = { precache_sound2_custom (snd_pain, default_file); };
+void(string default_file) precache_sound2_sight = { precache_sound2_custom (snd_sight, default_file); };
+
+
+/*
+================
+sound_custom
+================
+*/
+void(.string snd_field, entity e, float chan, string default_file,
+ float vol, float atten) sound_custom =
+{
+ if (e.snd_field != "")
+ sound (e, chan, e.snd_field, vol, atten);
+ else
+ sound (e, chan, default_file, vol, atten);
+};
+
+
+void(entity e, float chan, string default_file, float vol, float atten) sound_attack = { sound_custom (snd_attack, e, chan, default_file, vol, atten); };
+void(entity e, float chan, string default_file, float vol, float atten) sound_death = { sound_custom (snd_death, e, chan, default_file, vol, atten); };
+void(entity e, float chan, string default_file, float vol, float atten) sound_hit = { sound_custom (snd_hit, e, chan, default_file, vol, atten); };
+void(entity e, float chan, string default_file, float vol, float atten) sound_idle = { sound_custom (snd_idle, e, chan, default_file, vol, atten); };
+void(entity e, float chan, string default_file, float vol, float atten) sound_land = { sound_custom (snd_land, e, chan, default_file, vol, atten); };
+void(entity e, float chan, string default_file, float vol, float atten) sound_misc = { sound_custom (snd_misc, e, chan, default_file, vol, atten); };
+void(entity e, float chan, string default_file, float vol, float atten) sound_misc1 = { sound_custom (snd_misc1, e, chan, default_file, vol, atten); };
+void(entity e, float chan, string default_file, float vol, float atten) sound_misc2 = { sound_custom (snd_misc2, e, chan, default_file, vol, atten); };
+void(entity e, float chan, string default_file, float vol, float atten) sound_misc3 = { sound_custom (snd_misc3, e, chan, default_file, vol, atten); };
+void(entity e, float chan, string default_file, float vol, float atten) sound_move = { sound_custom (snd_move, e, chan, default_file, vol, atten); };
+void(entity e, float chan, string default_file, float vol, float atten) sound_pain = { sound_custom (snd_pain, e, chan, default_file, vol, atten); };
+void(entity e, float chan, string default_file, float vol, float atten) sound_sight = { sound_custom (snd_sight, e, chan, default_file, vol, atten); };

Return to the top of this page or return to the overview of this repo.

Diff qc/cutscene.qc

diff --git a/qc/cutscene.qc b/qc/cutscene.qc
new file mode 100644
index 0000000..bbc416c
--- /dev/null
+++ b/qc/cutscene.qc
@@ -0,0 +1,939 @@
+// Heavily modified for Drake.
+
+// player_run prototype is in proto.qc.
+void() DHM_CalcMoveDone;
+void() move_camera;
+//- - - - - - - - - - - - - - - - - - -
+// This resets air capacity and drowning damage.
+void(entity ent) more_air =
+{
+//- - - - - - - - -
+ ent.air_finished = time + 12;
+ ent.dmg = 2; // initial water damage
+};
+
+// ============================================ //
+// | Movie camera trigger - dhm | //
+// ============================================ //
+
+
+// 'o' should be other, who in turn is the player who touched camera trigger.
+void(entity o) spawn_dummy =
+{
+local entity s;
+
+ s = spawn ();
+// s.origin = o.origin;
+ s.velocity = o.velocity;
+ s.angles = o.angles;
+ s.health = o.health;
+ s.weapon = o.weapon;
+ s.classname = "dummy";
+ s.movetype = MOVETYPE_NONE;
+ s.solid = SOLID_NOT;
+ setmodel (s, "progs/player.mdl"); // set temp player model in case camera can see -- dumptruck_ds
+ if (s.weapon == IT_AXE)
+ {
+ s.frame = 0; // standing there with axe -- dumptruck_ds
+ }
+ else
+ s.frame = 12; // standing there with gun -- dumptruck_ds
+ s.weaponmodel = o.weaponmodel;
+ s.flags = o.flags;
+ s.effects = o.effects;
+ s.items = o.items;
+ s.enemy = o.enemy; // PM: o.enemy changed to camera later.
+
+// Save powerups
+// Pentagram
+ if (o.invincible_finished)
+ { s.invincible_finished = o.invincible_finished - time;
+ if (o.invincible_time)
+ s.invincible_time = o.invincible_time - time;
+ }
+ else
+ s.invincible_finished = s.invincible_time = 0;
+// Ring of Shadows
+ if (o.invisible_finished)
+ { s.invisible_finished = o.invisible_finished - time;
+ if (o.invisible_time)
+ s.invisible_time = o.invisible_time - time;
+ }
+ else
+ s.invisible_finished = s.invisible_time = 0;
+// Quad Damage
+ if (o.super_damage_finished)
+ { s.super_damage_finished = o.super_damage_finished - time;
+ if (o.super_time)
+ s.super_time = o.super_time - time;
+ }
+ else
+ s.super_damage_finished = s.super_time = 0;
+// Biosuit
+ if (o.radsuit_finished)
+ { s.radsuit_finished = o.radsuit_finished - time;
+ if (o.rad_time)
+ s.rad_time = o.rad_time - time;
+ }
+ else
+ s.radsuit_finished = s.rad_time = 0;
+// // Empathy Shields
+// if (o.thorns_finished)
+// { s.thorns_finished = o.thorns_finished - time;
+// if (o.thorns_time)
+// s.thorns_time = o.thorns_time - time;
+// }
+// else
+// s.thorns_finished = s.thorns_time = 0;
+// // Cross of Deflection
+// if (o.cross_finished)
+// { s.cross_finished = o.cross_finished - time;
+// if (o.cross_time)
+// s.cross_time = o.cross_time - time;
+// }
+// else
+// s.cross_finished = s.cross_time = 0;
+// // Dark Angel Wings
+// if (o.wing_finished)
+// { s.wing_finished = o.wing_finished - time;
+// if (o.wing_time)
+// s.wing_time = o.wing_time - time;
+// }
+// else
+// s.wing_finished = s.wing_time = 0;
+// // Amulet of Reflection
+// if (o.mirror_finished)
+// { s.mirror_finished = o.mirror_finished - time;
+// if (o.mirror_time)
+// s.mirror_time = o.mirror_time - time;
+// }
+// else
+// s.mirror_finished = s.mirror_time = 0;
+// // Tome of Power
+// if (o.tome_finished)
+// { s.tome_finished = o.tome_finished - time;
+// if (o.tome_time)
+// s.tome_time = o.tome_time - time;
+// }
+// else
+// s.tome_finished = s.tome_time = 0;
+
+// FIXME: Called during touch func, don't set directly?
+ setorigin (s, o.origin);
+
+// PM: Link player to dummy, for now.
+ if (o) //.classname == "player")
+ if (!o.trigger_field)
+ o.trigger_field = s;
+};
+
+// PM: Removed 'name_player'; no longer needed.
+
+void() go_back =
+{
+local entity t, c, cvars, old;
+local string val;
+
+ t = find (world, classname, "dummy");
+ if (!t)
+ objerror ("couldn't find dummy");
+ t.solid = SOLID_NOT; // So player won't bounce back.
+ setmodel (t, ""); // remove temp player model upon return -- dumptruck_ds
+
+ c = find (world, classname, "camera");
+ if (!c)
+ objerror ("couldn't find camera");
+
+ c.oldorigin = t.origin; // So player won't bounce back to cam.
+
+// FIXME: Check the new vars.
+ setorigin (c, t.origin);
+ c.velocity = t.velocity;
+ c.view_ofs = '0 0 22'; // PM: Morph should take care of itself.
+ c.angles_x = t.angles_x;
+ c.angles_y = t.angles_y;
+ c.angles_z = 0;
+ c.health = t.health;
+ c.weapon = t.weapon;
+ c.weaponframe = 0;
+ c.weaponmodel = t.weaponmodel;
+ c.flags = t.flags;
+ c.effects = t.effects;
+ c.items = t.items;
+ c.enemy = t.enemy; // PM: Restore client's original enemy.
+
+// Restore powerups
+ if (t.invincible_finished)
+ { c.invincible_finished = time + t.invincible_finished;
+ if (t.invincible_time)
+ c.invincible_time = time + t.invincible_time;
+ }
+ if (t.invisible_finished)
+ { c.invisible_finished = time + t.invisible_finished;
+ if (t.invisible_time)
+ c.invisible_time = time + t.invisible_time;
+ }
+ if (t.super_damage_finished)
+ { c.super_damage_finished = time + t.super_damage_finished;
+ if (t.super_time)
+ c.super_time = time + t.super_time;
+ }
+ if (t.radsuit_finished)
+ { c.radsuit_finished = time + t.radsuit_finished;
+ if (t.rad_time)
+ c.rad_time = time + t.rad_time;
+ }
+ // if (t.thorns_finished)
+ // { c.thorns_finished = time + t.thorns_finished;
+ // if (t.thorns_time)
+ // c.thorns_time = time + t.thorns_time;
+ // }
+ // if (t.cross_finished)
+ // { c.cross_finished = time + t.cross_finished;
+ // if (t.cross_time)
+ // c.cross_time = time + t.cross_time;
+ // }
+ // if (t.wing_finished)
+ // { c.wing_finished = time + t.wing_finished;
+ // if (t.wing_time)
+ // c.wing_time = time + t.wing_time;
+ // }
+ // if (t.mirror_finished)
+ // { c.mirror_finished = time + t.mirror_finished;
+ // if (t.mirror_time)
+ // c.mirror_time = time + t.mirror_time;
+ // }
+ // if (t.tome_finished)
+ // { c.tome_finished = time + t.tome_finished;
+ // if (t.tome_time)
+ // c.tome_time = time + t.tome_time;
+ // }
+
+ c.fixangle = 1; // turn this way immediately
+ c.takedamage = DAMAGE_AIM;
+ c.solid = SOLID_SLIDEBOX;
+ c.movetype = MOVETYPE_WALK;
+ c.nextthink = time;
+ c.think = player_run; // PM: Reset player anim frames.
+ more_air (c); // No gasping from you!
+
+ // c.xfl = c.xfl | XFL_ITEMS; // Restore pickup again. Drake -- dumptruck_ds
+
+// Yes, you CAN change the classname here since the 'find' command already
+// found the camera. It is best to change the classname back to player now.
+ c.classname = "player";
+ cutscene = 0; // Cutscene OFF
+ stuffcmd (c, "-forward\n");
+ stuffcmd (c, "-strafe\n");
+
+// Look for any CVARSET entities to restore old cvars that
+// were changed for the cut-scene
+ if (c.ideal_yaw == -1)
+ {
+ cvars = find(world, classname, "cvar_done");
+ while (cvars) // != world)
+ {
+ if (!cvars.message)
+ cvars.message = cvars.model;
+ cvar_set (cvars.netname, cvars.script);
+ old = cvars;
+ cvars = find (cvars, classname, "cvar_done");
+ remove (old);
+ }
+ c.ideal_yaw = 0;
+ }
+
+ val = ftos (c.cnt);
+ cvar_set ("viewsize", val); //restore old viewsize
+// stuffcmd (c, "sizedown\nsizeup\n"); //hack-fix for GLquake
+
+ t.nextthink = time + 0.1;
+ t.think = SUB_Remove;
+ remove (self);
+};
+
+//===============
+// This routine short-circuits player turning and movement while in camera
+// mode. self.oldorigin is used as self.angles, and self.mangle is used as
+// self.velocity. This allows me to compute these figures in code, and
+// overwrite what the game thinks they should be. Called from 'client.qc'.
+//===============
+void() look_ahead =
+{
+// PM: Vision style cam sets angles to mangle and velocity to zeroes.
+// The camera in vision mode cutscenes cannot move.
+// if (vision)
+// {
+// self.angles = self.enemy.mangle;
+// self.fixangle = 1;
+// // self.nextthink removed since it's done in PlayerPreThink.
+// return;
+// }
+
+// PM: Using Zerstorer style cutscene code...
+ self.angles = self.oldorigin;
+ self.velocity = self.mangle;
+ self.fixangle = 1;
+ cvar_set ("viewsize", "120"); //keep screen maximized
+
+ if (self.delay == 0)
+ {
+ local vector looky;
+
+ looky_x = self.movedir_x - self.origin_x;
+ looky_y = self.movedir_y - self.origin_y;
+ looky_z = self.origin_z - self.movedir_z;
+ self.oldorigin = vectoangles (looky);
+ }
+};
+
+// This is a modified SUB_CalcMove routine.
+void(vector tdest, float tspeed, entity cam) DHM_CalcMove =
+{
+local vector vdestdelta;
+local float len, traveltime;
+
+ self.finaldest = tdest;
+ self.think = DHM_CalcMoveDone;
+
+ if (tdest == cam.origin)
+ {
+ cam.velocity = cam.mangle = '0 0 0';
+ self.nextthink = time + 0.01;
+ return;
+ }
+
+// set destdelta to the vector needed to move
+ vdestdelta = tdest - cam.origin;
+
+// calculate length of vector
+ len = vlen (vdestdelta);
+
+// divide by speed to get time to reach dest
+ traveltime = len / tspeed;
+
+ if (traveltime < 0.1)
+ {
+ cam.velocity = cam.mangle = '0 0 0';
+ self.nextthink = time + 0.01;
+ return;
+ }
+
+// set nextthink to trigger a think when dest is reached
+ self.nextthink = time + traveltime;
+
+// scale the destdelta vector by the time spent traveling to get velocity
+ cam.velocity = cam.mangle = vdestdelta * (1/traveltime);
+};
+
+//- - - - - - - - -
+// Zerstorer-only cutscene code.
+void() wait_camera =
+{
+ if (!self.wait)
+ {move_camera (); return;}
+
+ self.nextthink = time + self.wait;
+ self.think = move_camera;
+};
+
+//============
+// After moving, set origin to exact final destination
+//============
+void() DHM_CalcMoveDone =
+{
+ if (!cutscene) // Old check: if (self.enemy.classname != "camera")
+ {remove (self); return;}
+
+ setorigin(self.enemy, self.finaldest);
+ self.enemy.velocity = self.enemy.mangle = '0 0 0';
+
+ if (self.cnt == -1)
+ {remove (self); return;}
+
+ self.nextthink = time + 0.01;
+ self.think = wait_camera;
+};
+
+void() move_camera =
+{
+local entity cpt, fpt;
+local vector looky;
+
+ if (!cutscene) // Old check: if (self.enemy.classname != "camera")
+ {remove (self); return;}
+
+ cpt = find (world, targetname, self.target);
+ if (!cpt.target) //if this is the end of the line, stop camera
+ {
+ self.think = SUB_Null;
+ self.enemy.velocity = '0 0 0';
+ self.enemy.mangle = '0 0 0'; //mangle == velocity in cut-scene
+ DHM_CalcMoveDone();
+ self.cnt = -1; // remove control entity in DHM_CalcMoveDone
+ //return;
+ }
+ if (cpt.focal_point) //is there a new focal point?
+ {
+ fpt = find (world, targetname, cpt.focal_point);
+ if (!fpt)
+ objerror("Couldn't find new focal point!");
+
+ self.enemy.movedir = fpt.origin;
+ looky_x = self.enemy.movedir_x - self.enemy.origin_x;
+ looky_y = self.enemy.movedir_y - self.enemy.origin_y;
+ looky_z = self.enemy.origin_z - self.enemy.movedir_z;
+ self.enemy.oldorigin = vectoangles (looky);
+ self.enemy.angles = self.enemy.oldorigin; //oldorigin == angles in CS
+ }
+// Check for auto-focus or still camera angle
+ if (cpt.delay)
+ self.enemy.delay = cpt.delay;
+ else
+ self.enemy.delay = 0;
+
+ self.target = cpt.target;
+ self.wait = cpt.wait;
+ if(cpt.speed)
+ self.speed = cpt.speed;
+ DHM_CalcMove (cpt.origin, self.speed, self.enemy);
+};
+//- - - - - - - - -
+
+void() go_camera =
+{
+local vector looky;
+
+ cutscene = 1; // Cutscene ON.
+
+// Don't let player-turned-camera pick up items.
+ // self.xfl = self.xfl - (self.xfl & XFL_ITEMS);
+
+// Change the player into a camera
+// PM: Ok, you win! Too much stuff checks for 'player', so use 'camera'
+// to be safe. Just make sure alignment stuff doesn't break, namely
+// friendly monsters getting mad at a player when they shouldn't.
+ self.classname = "camera";
+ self.velocity = '0 0 0';
+ self.view_ofs = '0 0 0';
+ // PM: Change the modelindex to a non-zero number that points to an
+ // invisible model so that the camera entity is invisible if seen
+ // because of reflective textures or builtin chasecam (chase_active 1).
+ // Requires my custom invisible model (which is a sprite).
+ self.modelindex = mindex_inviso;
+ // Turn off glowing effects.
+ self.effects = 0;
+ self.items = 0;
+ self.weaponmodel = ""; // Remove weapon from the screen.
+//- - - - - - - - - - - - - - - - - - -
+// if (vision)
+// {
+// self.angles = self.enemy.mangle;
+// self.fixangle = 1;
+// self.movetype = MOVETYPE_NONE;
+// self.takedamage = DAMAGE_NO;
+// self.solid = SOLID_NOT;
+// self.weaponmodel= "";
+
+ // Removed thinking since it's done by PlayerPreThink->Cutscene_Think.
+// }
+//- - - - - - - - - - - - - - - - - - -
+// else // Default to Zerstorer style cutscene.
+ {
+ looky_x = self.movedir_x - self.enemy.origin_x;
+ looky_y = self.movedir_y - self.enemy.origin_y;
+ looky_z = self.enemy.origin_z - self.movedir_z;
+ self.oldorigin = vectoangles (looky);
+ self.angles = self.oldorigin; //oldorigin == angles in CS
+
+ // Check if camera is auto-focus or not
+ if (self.enemy.delay)
+ self.delay = self.enemy.delay;
+ else
+ self.delay = 0;
+
+ self.velocity = self.mangle = '0 0 0';
+
+ self.dmg = 0; // PM: Do we need this?
+ self.fixangle = 1; // turn this way immediately
+ self.movetype = MOVETYPE_NOCLIP;
+ self.takedamage = DAMAGE_NO;
+ // PM: Solid cannot be 0 or else camera can't trigger stuff by touch.
+
+ // Spawn a control function to handle moving the camera
+ if (self.enemy.target)
+ {
+ local entity control;
+
+ control = spawn();
+ control.classname = "camcontrol";
+ control.enemy = self;
+ control.target = self.enemy.target;
+ control.speed = self.enemy.speed;
+ control.nextthink = time + self.enemy.wait + 0.05;
+ control.think = move_camera;
+ }
+ }
+
+// Setting script_count to 0 is what triggers the script to play,
+// It will then play the script number.
+ if (!self.script)
+ dprint ("trigger_camera needs a script number!");
+ self.script_count = 0;
+
+ self.cnt = cvar("viewsize");
+ cvar_set ("viewsize", "120"); //Full screen
+ // PM: Vision sets 'v_idlescale' for swaying screen. Not in Drake!
+ stuffcmd (self, "sizedown\nsizeup\n"); //hack-fix for GLquake
+ stuffcmd (self, "+strafe\n");
+
+ setorigin (self, self.enemy.origin);
+
+//- - - - - - - - -
+// PM: Space invasion prevention.
+// Make the dummy solid to prevent monsters or other junk from occupying
+// the space where the player stood before the cutscene started.
+// After all, the player will be placed back when the cutscene ends,
+// and we don't want him stuck inside a monster or something.
+//
+// We need to wait until after the player becomes the camera, before we can
+// make the dummy solid. If we make the dummy solid as it spawned, the
+// player could get stuck inside the dummy (instead of moving) between
+// trigger activation and transformation to camera.
+//
+// In Vision code, player becomes camera a frame or so after trigger
+// activation. In Zer code, player becomes camera at the same time
+// the trigger activates.
+//
+// Note: If you still have trouble getting a Vision cutscene to work in a
+// certain level, move the following code to the top of 'look_ahead'.
+// Doing so would be less than ideal since the check would get called every
+// frame during the cutscene, instead of just once here.
+// The only level that still has problems with dummy made solid now
+// is 'vision.bsp', which has its own pak. Tronyn's maps, the levels
+// that really matter, have no problems.
+//- - - - - - - - -
+// 'self' is the player-turned-camera entity.
+ // '!self.trigger_field' is the world, and its classname is worldspawn.
+ if (self.trigger_field.classname == "dummy")
+ {
+ self.trigger_field.solid = SOLID_BBOX;
+ setsize (self.trigger_field, self.mins, self.maxs);
+
+ self.trigger_field = world; // Unlink now that it's done.
+ }
+//- - - - - - - - -
+};
+
+// PM: Called from either touch or use.
+void(entity who) camera_activate =
+{
+// only activate for player, 1st time touched
+ if (who.health <= 0)
+ return;
+ if (who.deadflag) // In case of Alien Quake facehugger kill.
+ return;
+ if (who.classname != "player")
+ return;
+
+// You can't touch/use this again.
+ self.touch = self.use = SUB_Null;
+
+// If player is on ground, take him off ground so no one gets confused
+ who.flags = who.flags - (who.flags & FL_ONGROUND);
+
+// put a dummy where the player was
+ spawn_dummy (who);
+
+// find camera
+ local entity t;
+
+ t = find (world, targetname, self.target);
+// if (vision)
+// {
+// if (!t)
+// objerror ("couldn't find target");
+// }
+// else
+ {
+ local entity fpt;
+
+ while ((t != world) && (t.classname != "info_movie_camera"))
+ t = find (t, targetname, self.target);
+ if (!t)
+ objerror ("couldn't find target");
+
+ // find focal point
+ fpt = find (world, targetname, self.focal_point);
+ if (!fpt)
+ objerror ("You must have a focal point!\n");
+ else
+ who.movedir = fpt.origin; //movedir used to calc focal dir
+ }
+
+// Go to the camera - not in this function, because touch functions are
+// called while looping through c code, and you don't want to move the
+// player, or something like that?
+ who.enemy = t; //save camera position, etc.
+ who.script = self.script; //save script number
+ who.script_delay = self.script_delay; //save delay for page 1
+
+// if (vision)
+// { // PM: Don't try instant start because that breaks soeexit.bsp.
+// who.nextthink = time + 0.05;
+// who.think = go_camera;
+// }
+// else
+ SUB_Think (who, go_camera);
+
+ activator = self;
+ SUB_UseTargets ();
+
+//Remove the trigger_camera from level
+ self.nextthink = time + 0.1;
+ self.think = SUB_Remove;
+};
+
+void() camera_touch =
+{
+ if (self.targetname)
+ if (self.nextthink < time)
+ return;
+ if (self.cnt == -1)
+ return;
+ camera_activate (other);
+};
+void() camera_point_touch = {camera_activate (other);};
+
+//============
+// --> QUAKED info_movie_camera (.5 .5 .5) (-8 -8 -8) (8 8 32) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+// This is the destination marker for a camera. It should have a "targetname"
+// field with the same value as a camera-trigger's "target" field.
+//============
+void() imc_touch =
+{
+local string temps;
+
+ if (other.classname != "camera")
+ return;
+ temps = self.target;
+ self.target = self.message;
+ SUB_UseTargets();
+ self.target = temps;
+ if (self.cnt)
+ return;
+
+ self.think = SUB_Remove;
+ self.nextthink = time + 10;
+ self.solid = SOLID_NOT;
+};
+
+void() info_movie_camera =
+{
+// this does nothing, just serves as a target spot
+// if (vision)
+// return;
+
+// ...more than a spot in Zer mode.
+ //self.use = SUB_Null;
+ self.solid = SOLID_TRIGGER;
+ setorigin(self, self.origin);
+ setsize(self, '-8 -8 -8', '8 8 8');
+ self.touch = imc_touch;
+};
+
+void() camera_use =
+{
+ local entity pl;
+
+ pl = find(world, classname, "player"); // Only one in single-player.
+ camera_activate (pl);
+
+// Old code.
+// self.nextthink = time + 100000;
+// force_retouch = 2; // make sure even still objects get hit
+// self.think = SUB_Null;
+};
+
+//- - - - - - - - -
+// Zerstorer-only cutscene code.
+void() gocam_use =
+{
+local entity control, temp;
+
+ control = find(world, classname, "camcontrol");
+ if (control == world)
+ dprint ("Can't find camcontrol!\n");
+
+ temp = self;
+ self = control;
+ DHM_CalcMoveDone ();
+ self = temp;
+ self.nextthink = time + 0.1;
+ self.think = SUB_Remove;
+};
+
+void() trigger_gocamera = {self.use = gocam_use;};
+
+/*QUAKED info_focal_point (.5 .5 .5) (-8 -8 -8) (8 8 32) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+This is the point that the camera will face. It should have a "targetname"
+field with the same value as a camera-trigger's "focal_point" field.
+*/
+// PM: This entity is kept only for map compatibility reasons.
+// Otherwise, this entity is redundant. Use 'info_notnull' instead.
+void() info_focal_point = {}; // just holds a spot for the focal point.
+
+void(float pt) trigger_camera_spawn =
+{
+// Update: Don't let dmsp muck up cutscenes and vice versa.
+ if (deathmatch || coop)
+ {remove (self); return;} // PM: Fix -- abort if removed.
+
+ if (pt)
+ { // The new way, this is for you Tronyn.
+ InitPointTrigger ();
+ if (!self.targetname)
+ self.touch = camera_point_touch;
+ }
+ else
+ { // The old way...
+ InitTrigger ();
+ // PM: Must always allow touch because some old maps need it.
+ self.touch = camera_touch;
+ }
+ // find the destination
+ if (!self.target)
+ objerror ("Camera trigger with no target");
+ self.use = camera_use;
+};
+
+/*QUAKED trigger_camera (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+A player touching this will be transported to the corresponding
+info_movie_camera entity. You must set the "target" field, and put a
+info_movie_camera with a "targetname" field that matches. The "script"
+key gives a starting script number, and the "script_delay" key is the
+amount of time(seconds) to stay on the first script page.
+
+If the trigger_camera has a targetname, it will only enter camera mode
+after it has been fired.
+*/
+void() trigger_camera = {trigger_camera_spawn (FALSE);};
+
+/*QUAKED trigger_camera_point (.5 .5 .5) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+When this is triggered the player will be transported to the corresponding
+info_movie_camera entity. You must set the "target" field, and put a
+info_movie_camera with a "targetname" field that matches. The "script"
+key gives a starting script number, and the "script_delay" key is the
+amount of time(seconds) to stay on the first script page.
+*/
+void() trigger_camera_point = {trigger_camera_spawn (TRUE);};
+
+//----------------------------------
+// Scripting function - dhm
+//----------------------------------
+// The original timing idea for scripts was inspired by Zoid. Study the
+// code for Zoid's CTF, it is an excellent example of good Quake-C coding.
+// Also look at all of Quake Command's stuff. Wedge rules.
+//----------------------------------
+// Script_play is called from PlayerPreThink()
+// 'self' is the player (camera)
+//----------------------------------
+void() Script_play =
+{
+local entity scrpt;
+
+ scrpt = find (world, script_num, self.script);
+ if (!scrpt)
+ dprint ("Error: script not found!");
+
+ // If script has a target, trigger it once.
+// if (!vision)
+ if (scrpt.target)
+ {
+ local entity temp;
+
+ temp = self;
+ self = scrpt;
+ SUB_UseTargets ();
+ self.target = world.null_string;
+ self = temp;
+ }
+
+ self.script_delay = scrpt.script_delay;
+ self.script_time = time + 1;
+ self.script_count = self.script_count + 1;
+ centerprint (self, scrpt.message);
+
+ if (self.script_count == self.script_delay)
+ {
+ self.script = scrpt.next_script;
+ if (self.script != "0")
+ self.script_count = 0;
+ else
+ {
+ scrpt.nextthink = time + 3;
+ scrpt.classname = "going_back";
+ scrpt.think = go_back;
+ }
+ }
+};
+
+
+//- - - - - - - - -
+// PM: Player thinking during a cutscene. Called by 'PlayerPreThink'.
+void() Cutscene_Think =
+{
+ /* --------------------------------------------
+ If we are in camera mode, play the script.
+ -------------------------------------------- */
+ // PM: Allow player to stop cutscene on any map.
+ if (self.impulse)
+ if (self.script_count != 1000000)
+ {
+ local entity goback; // PM: dhm's cutscene code.
+
+ self.script_count = 1000000;
+ // if (world.model == "maps/soeexit.bsp")
+ // { // Hack: Jump directly to intermission/credits.
+ // NextLevel ();
+ // return;
+ // }
+ // If cut-scene has ended, and user tries to exit, don't
+ // spawn a second go_back control entity.
+ goback = find(world, classname, "going_back");
+ if (!goback)
+ {
+ sprint(self, "...\n");
+ goback = spawn();
+ goback.nextthink = time + 1.5;
+ goback.think = go_back;
+ self.impulse = 0; // PM: New -- just kill cutscene.
+ }
+ }
+
+ if (cutscene) // PM: Vision didn't look_ahead here, but do it
+ look_ahead (); // anyway instead of thinking about it.
+ if (self.script_count < self.script_delay)
+ if (self.script_time < time)
+ Script_play ();
+};
+
+void() script_sound_play =
+{
+ if (self.noise != "")
+ sound (other, CHAN_AUTO, self.noise, 1, ATTN_NONE);
+ else
+ sound (other, CHAN_AUTO, self.noise1, 1, ATTN_NONE);
+};
+//- - - - - - - - -
+//============
+// --> QUAKED info_script_sound (.5 .5 .5) (-8 -8 -8) (8 8 32) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+// This is the noise player for a script.
+
+void() info_script_sound =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+ //play all the sounds available for a normal trigger
+ if (self.sounds == 0)
+ {
+ precache_sound ("misc/null.wav");
+ self.noise = "misc/null.wav";
+ }
+ else if (self.sounds == 1)
+ {
+ precache_sound ("misc/secret.wav");
+ self.noise = "misc/secret.wav";
+ }
+ else if (self.sounds == 2)
+ {
+ precache_sound ("misc/talk.wav");
+ self.noise = "misc/talk.wav";
+ }
+ else if (self.sounds == 3)
+ {
+ precache_sound ("misc/trigger1.wav");
+ self.noise = "misc/trigger1.wav";
+ }
+ else if (self.sounds == 4)
+ {
+ if (!self.noise1) //dumptruck_ds
+ {
+ objerror ("no soundfile set in noise1!\n");
+ remove(self);
+ return;
+ }
+ else
+ precache_sound (self.noise1);
+ self.noise = self.noise1;
+ }
+ self.use = script_sound_play;
+};
+
+//============
+// --> QUAKED info_script (.5 .5 .5) (-8 -8 -8) (8 8 32)
+// This is the destination marker for a script.
+// It should have a "script_num" field that signifies the script number, and
+// a "next_script" to signal the next script ("0" if this is the last page of
+// the script), a "script_delay" to signify how many seconds to display this
+// page, and of course a "message" field with the text to display.
+//
+// PM: Use 'info_notnull' instead.
+//============
+void() info_script =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+};
+
+
+// ------------------------------ //
+// | trigger_cvarset | //
+// ------------------------------ //
+//============
+// --> QUAKED trigger_cvarset (.5 .5 .5) (-8 -8 -8) (8 8 32)
+// You can set any CVAR on the server with this trigger. Put the CVAR name
+// in "netname" and put the value in "message". Useful CVAR's are
+// sv_gravity, sv_friction, fov, and v_idlescale.
+//============
+void() change_cvar =
+{
+local entity check;
+
+ cvar_set (self.netname, self.message);
+ bprint("\n\n\n\n");
+
+ self.classname = "cvar_done";
+ check = find(world, classname, "player");
+ if (!check)
+ check = find(world, classname, "camera");
+
+ check.ideal_yaw = -1;
+
+ self.nextthink = time + 0.02;
+ self.think = SUB_UseTargets;
+};
+
+void() cvarset_touch =
+{
+ if (self.cnt > time || other.health <= 0 || other.classname != "player")
+ return;
+
+ change_cvar ();
+};
+
+void() trigger_cvarset =
+{
+ if (deathmatch || coop)
+ remove (self);
+
+ InitTrigger ();
+ self.use = change_cvar;
+};
+
+
+// PM: Removed gravity and earthquake entities.
+
+//===========================/ END OF FILE /===========================//

Return to the top of this page or return to the overview of this repo.

Diff qc/defs_builtins.qc

diff --git a/qc/defs_builtins.qc b/qc/defs_builtins.qc
new file mode 100644
index 0000000..e220cfb
--- /dev/null
+++ b/qc/defs_builtins.qc
@@ -0,0 +1,223 @@
+/*==============================================================================
+ BUILTIN FUNCTIONS
+==============================================================================*/
+
+void(vector ang) makevectors = #1; // sets v_forward, etc globals
+void(entity e, vector o) setorigin = #2;
+void(entity e, string m) setmodel = #3; // set movetype and solid first
+void(entity e, vector min, vector max) setsize = #4;
+ // #5 was removed
+void() break = #6;
+float() random = #7; // returns 0 - 1
+void(entity e, float chan, string samp, float vol, float atten) sound = #8;
+vector(vector v) normalize = #9;
+void(string e) error = #10;
+void(string e) objerror = #11;
+float(vector v) vlen = #12;
+float(vector v) vectoyaw = #13;
+entity() spawn = #14;
+void(entity e) remove = #15;
+
+// sets trace_* globals
+// nomonsters can be:
+// An entity will also be ignored for testing if forent == test,
+// forent->owner == test, or test->owner == forent
+// a forent of world is ignored
+void(vector v1, vector v2, float nomonsters, entity forent) traceline = #16;
+entity() checkclient = #17; // returns a client to look for
+entity(entity start, .string fld, string match) find = #18;
+string(string s) precache_sound = #19;
+string(string s) precache_model = #20;
+void(entity client, string s) stuffcmd = #21;
+entity(vector org, float rad) findradius = #22;
+void(string s) bprint = #23;
+void(entity client, string s) sprint = #24;
+void(string s) dprint = #25;
+string(float f) ftos = #26;
+string(vector v) vtos = #27;
+void() coredump = #28; // prints all edicts
+void() traceon = #29; // turns statment trace on
+void() traceoff = #30;
+void(entity e) eprint = #31; // prints an entire edict
+float(float yaw, float dist) walkmove = #32; // returns TRUE or FALSE
+ // #33 was removed
+float() droptofloor = #34; // TRUE if landed on floor
+void(float style, string value) lightstyle = #35;
+float(float v) rint = #36; // round to nearest int
+float(float v) floor = #37; // largest integer <= v
+float(float v) ceil = #38; // smallest integer >= v
+ // #39 was removed
+float(entity e) checkbottom = #40; // true if self is on ground
+float(vector v) pointcontents = #41; // returns a CONTENT_*
+ // #42 was removed
+float(float f) fabs = #43;
+vector(entity e, float speed) aim = #44;// returns the shooting vector
+float(string s) cvar = #45; // return cvar.value
+void(string s) localcmd = #46; // put string into local que
+entity(entity e) nextent = #47; // for looping through all ents
+void(vector o, vector d, float color, float count) particle = #48; // particles
+void() ChangeYaw = #49; // turn to ideal_yaw at yaw_speed
+ // #50 was removed
+vector(vector v) vectoangles = #51;
+
+//======================================================================
+// direct client message generation
+//======================================================================
+void(float to, float f) WriteByte = #52;
+void(float to, float f) WriteChar = #53;
+void(float to, float f) WriteShort = #54;
+void(float to, float f) WriteLong = #55;
+void(float to, float f) WriteCoord = #56;
+void(float to, float f) WriteAngle = #57;
+void(float to, string s) WriteString = #58;
+void(float to, entity s) WriteEntity = #59;
+
+//======================================================================
+// broadcast client message generation
+//======================================================================
+// void(float f) bWriteByte = #59;
+// void(float f) bWriteChar = #60;
+// void(float f) bWriteShort = #61;
+// void(float f) bWriteLong = #62;
+// void(float f) bWriteCoord = #63;
+// void(float f) bWriteAngle = #64;
+// void(string s) bWriteString = #65;
+// void(entity e) bWriteEntity = #66;
+
+// Part of DP_QC_SINCOSSQRTPOW Forgive me father, for I have
+// trigonometry homework.
+// from fteextensions.qc -- CEV
+float(float angle) sin = #60;
+// Part of DP_QC_SINCOSSQRTPOW
+float(float angle) cos = #61;
+// Part of DP_QC_SINCOSSQRTPOW
+float(float value) sqrt = #62;
+
+void(float step) movetogoal = #67;
+string(string s) precache_file = #68; // no effect except for -copy
+void(entity e) makestatic = #69;
+void(string s) changelevel = #70;
+ // #71 was removed
+void(string var, string val) cvar_set = #72; // sets cvar.value
+
+//======================================================================
+// Centerprint
+//
+// The following function definitions allow the engine's builtin
+// centerprint function (builtin #73) to be called with different
+// numbers of string arguments. The string that will be printed is the
+// concatenation of the string arguments.
+//
+// These definitions work because builtin #73 is implemented in such
+// a way that it can accept multiple string arguments in this manner,
+// even though the original QuakeC code didn't take advantage of this
+// fact. A maximum of seven string arguments can be passed because
+// a function is limited to a total of eight arguments (and the first
+// argument is the client). Note that in the original engine, all of
+// the strings for a centerprint message are concatenated into a single
+// 256-char buffer, therefore excessively long messages should be
+// avoided. -- iw
+
+.float suppressCenterPrint;
+
+void(entity client, string s1) centerprint_builtin = #73;
+void(entity client, string s1, string s2) centerprint_builtin2 = #73;
+void(entity client, string s1, string s2, string s3) centerprint_builtin3 = #73;
+void(entity client, string s1, string s2, string s3, string s4)
+ centerprint_builtin4 = #73;
+void(entity client, string s1, string s2, string s3, string s4, string s5)
+ centerprint_builtin5 = #73;
+void(entity client, string s1, string s2, string s3, string s4, string s5,
+ string s6) centerprint_builtin6 = #73;
+void(entity client, string s1, string s2, string s3, string s4, string s5,
+ string s6, string s7) centerprint_builtin7 = #73;
+
+void(entity client, string s1) centerprint =
+{
+ // Is the centerprint message being used by something else?
+ if (!client.suppressCenterPrint)
+ {
+ centerprint_builtin(client, s1);
+ }
+ else
+ {
+ // Send message to client console instead
+ sprint(client, "(centerprint) ");
+ sprint(client, s1);
+ sprint(client, "\n");
+ }
+}
+
+void(entity client, string s1, string s2) centerprint2 =
+{
+ // Is the centerprint message being used by something else?
+ if (!client.suppressCenterPrint)
+ {
+ centerprint_builtin2(client, s1, s2);
+ }
+ else
+ {
+ // Send message to client console instead
+ sprint(client, "(centerprint) ");
+ sprint(client, s1);
+ sprint(client, s2);
+ sprint(client, "\n");
+ }
+}
+
+//======================================================================
+
+void(vector pos, string samp, float vol, float atten) ambientsound = #74;
+string(string s) precache_model2 = #75; // registered version only
+string(string s) precache_sound2 = #76; // registered version only
+string(string s) precache_file2 = #77; // registered version only
+void(entity e) setspawnparms = #78; // set parm1... to the values at
+ // level start for coop respawn
+
+// Part of DP_QC_TRACEBOX Exactly like traceline, but a box instead
+// of a uselessly thin point. Acceptable sizes are limited by bsp format,
+// q1bsp has strict acceptable size values.
+// brought in from fteextensions.qc -- CEV
+void(vector start, vector mins, vector maxs, vector end, float nomonsters, entity ent) tracebox = #90;
+
+// Part of DP_QC_MINMAXBOUND Returns the lowest value of its arguments.
+float(float a, float b, ...) min = #94;
+// Part of DP_QC_MINMAXBOUND Returns the highest value of its arguments.
+float(float a, float b, ...) max = #95;
+// Part of DP_QC_MINMAXBOUND Returns val, unless minimum is higher,
+// or maximum is less.
+float(float minimum, float val, float maximum) bound = #96;
+// Part of DP_QC_SINCOSSQRTPOW
+float(float value, float exp) pow = #97;
+
+// for CSQC interaction -- CEV
+void(float num, float type, .__variant fld) clientstat = #232;
+
+// Triggers a touch events between self and every SOLID_TRIGGER entity
+// that it is in contact with. This should typically just be the
+// triggers touch functions. Also optionally updates the origin of the
+// moved entity.
+void(optional entity ent, optional vector neworigin) touchtriggers = #279;
+
+// Part of DP_SV_PRINT Unconditionally print on the local system's
+// console, even in ssqc (doesn't care about the value of the
+// developer cvar).
+void(string s, ...) print = #339;
+
+// Look up a key in the server's public serverinfo string
+string(string key) serverkey = #354;
+
+// from fteextensions.qc, all part of DP_QC_ASINACOSATANATAN2TAN -- CEV
+float(float s) asin = #471;
+float(float c) acos = #472;
+float(float t) atan = #473;
+float(float c, float s) atan2 = #474;
+// float(float a) tan = #475;
+
+// Part of DP_QC_SPRINTF
+string(string fmt, ...) sprintf = #627;
+
+// Part of FTE_QC_CROSSPRODUCT
+// Small helper function to calculate the crossproduct of two vectors.
+vector(vector v1, vector v2) crossproduct = #0:crossproduct;
+

Return to the top of this page or return to the overview of this repo.

Diff qc/defs_entvars.qc

diff --git a/qc/defs_entvars.qc b/qc/defs_entvars.qc
new file mode 100644
index 0000000..59f5812
--- /dev/null
+++ b/qc/defs_entvars.qc
@@ -0,0 +1,115 @@
+/*==============================================================================
+ SOURCE FOR ENTVARS_T C STRUCTURE
+==============================================================================*/
+
+//======================================================================
+// system fields (*** = do not set in prog code, maintained by C code)
+//======================================================================
+.float modelindex; // *** model index in the precached list
+.vector absmin, absmax; // *** origin + mins / maxs
+
+.float ltime; // local time for entity
+.float movetype;
+.float solid;
+
+.vector origin; // ***
+.vector oldorigin; // ***
+.vector velocity;
+.vector angles;
+.vector avelocity;
+
+.vector punchangle; // temp angle adjust from dmg or recoil
+
+.string classname; // spawn function
+.string model;
+.float frame;
+.float skin;
+.float effects;
+
+.vector mins, maxs; // bounding box extents relative to org
+.vector size; // maxs - mins
+
+.void() touch;
+.void() use;
+.void() think;
+.void() blocked; // for doors or plats, called when
+ // can't push other
+.float nextthink;
+.entity groundentity;
+
+// stats
+.float health;
+.float frags;
+.float weapon; // one of the IT_SHOTGUN, etc flags
+.string weaponmodel;
+.float weaponframe;
+.float currentammo;
+.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
+
+.float items; // bit flags
+ // next three comments from AD
+.float takedamage; // Check by many functions for damage
+.entity chain; // Can be overwritten by find command
+.float deadflag; // Used by client functions
+
+.vector view_ofs; // add to origin to get eye point
+
+.float button0; // fire
+.float button1; // use
+.float button2; // jump
+
+.float impulse; // weapon changes
+
+.float fixangle; // Make an entity instantly turn
+.vector v_angle; // view / targeting angle for players
+.float idealpitch; // calc pitch angle for lookup up slopes
+
+.string netname;
+
+.entity enemy; // current entity enemy
+
+.float flags; // FL bitflag operations
+
+.float colormap;
+.float team;
+
+.float max_health; // players maximum health is stored here
+
+.float teleport_time; // teleport exit +back timer
+
+.float armortype; // save this fraction of incoming damage
+.float armorvalue;
+
+.float waterlevel; // 0: none, 1: feet, 2: waist, 3: eyes
+.float watertype; // a contents value
+
+.float ideal_yaw; // ideal direction for entity to face
+.float yaw_speed; // speed (in degrees) turning towards
+
+.entity aiment;
+
+.entity goalentity; // a movetarget or an enemy
+
+.float spawnflags; // mostly custom options for each entity
+
+.string target;
+.string targetname;
+
+// damage is accumulated through a frame. and sent as one single
+// message, so the super shotgun doesn't generate huge messages
+.float dmg_take;
+.float dmg_save;
+.entity dmg_inflictor;
+
+.entity owner; // who launched a missile
+.vector movedir; // mostly for doors, but also
+ // used for waterjump
+.string message; // trigger messages
+
+.float sounds; // a cd track number or sound number
+
+.string noise, noise1, noise2, noise3; // contains names of wavs to play
+
+//================================================
+void end_sys_fields; // flag for structure dumping
+//================================================

Return to the top of this page or return to the overview of this repo.

Diff qc/defs_globalvars.qc

diff --git a/qc/defs_globalvars.qc b/qc/defs_globalvars.qc
new file mode 100644
index 0000000..fac70c6
--- /dev/null
+++ b/qc/defs_globalvars.qc
@@ -0,0 +1,86 @@
+/*==============================================================================
+ SOURCE FOR GLOBALVARS_T C STRUCTURE
+==============================================================================*/
+
+//======================================================================
+// system globals
+//======================================================================
+entity self;
+entity other;
+entity world;
+float time;
+float frametime;
+
+// force all entities to touch triggers next frame. this is needed because
+// non-moving things don't normally scan for triggers, and when a trigger is
+// created (like a teleport trigger), it needs to catch everything.
+// decremented each frame, so set to 2 to guarantee everything is touched.
+float force_retouch;
+
+string mapname;
+
+float deathmatch;
+float coop;
+float teamplay;
+
+float serverflags; // propagated from level to level, used
+ // to keep track of completed episodes
+float total_secrets;
+float total_monsters;
+
+float found_secrets; // number of secrets found
+float killed_monsters; // number of monsters killed
+
+
+// spawnparms are used to encode information about clients across server
+// level changes
+float parm1, parm2, parm3, parm4, parm5, parm6, parm7, parm8,
+ parm9, parm10, parm11, parm12, parm13, parm14, parm15, parm16;
+
+//======================================================================
+// global variables set by built in functions
+//======================================================================
+vector v_forward, v_up, v_right; // set by makevectors()
+
+// set by traceline / tracebox // comments below copied from AD
+float trace_allsolid; // both start and end were in a solid
+float trace_startsolid; // the start point was in a solid
+float trace_fraction; // how much of the vector (% from 0 to 1
+ // was traced before it hit something
+vector trace_endpos; // the final position
+vector trace_plane_normal; // the normal of the surface it hit
+float trace_plane_dist; // used for angled surfaces (?)
+entity trace_ent; // the entity it hit (world if nothing)
+float trace_inopen; // if some portion of the trace is
+ // in the air
+float trace_inwater; // if some portion of the trace is
+ // in water
+
+entity msg_entity; // destination of single entity writes
+
+//======================================================================
+// required prog functions
+//======================================================================
+void() main; // only for testing
+
+void() StartFrame;
+
+void() PlayerPreThink;
+void() PlayerPostThink;
+
+void() ClientKill;
+void() ClientConnect;
+void() PutClientInServer; // call after setting the parm1... parms
+void() ClientDisconnect;
+
+void() SetNewParms; // called when a client first connects
+ // to a server. set parms so they can be
+ // saved off for restarts
+
+void() SetChangeParms; // call to set parms for self so they
+ // can be saved for a level transition
+
+
+//================================================
+void end_sys_globals; // flag for structure dumping
+//================================================

Return to the top of this page or return to the overview of this repo.

Diff qc/defs_misc.qc

diff --git a/qc/defs_misc.qc b/qc/defs_misc.qc
new file mode 100644
index 0000000..ffd7c28
--- /dev/null
+++ b/qc/defs_misc.qc
@@ -0,0 +1,676 @@
+/*==============================================================================
+ VARS NOT REFERENCED BY C CODE
+==============================================================================*/
+
+// inspired by Copper
+string version = "\nprogs_dump devkit\nversion 3.0.0";
+
+// constants
+float FALSE = 0;
+float TRUE = 1;
+float NEGATIVE = -1;
+
+// worldtype values
+float WORLDTYPE_MEDIEVAL = 0;
+float WORLDTYPE_METAL = 1;
+float WORLDTYPE_BASE = 2;
+
+// edict.flags
+float FL_FLY = 1;
+float FL_SWIM = 2;
+float FL_CLIENT = 8; // set for all client edicts
+float FL_INWATER = 16; // for enter / leave water splash
+float FL_MONSTER = 32;
+float FL_GODMODE = 64; // player cheat
+float FL_NOTARGET = 128; // player cheat
+float FL_ITEM = 256; // extra wide size for bonus items
+float FL_ONGROUND = 512; // standing on something
+float FL_PARTIALGROUND = 1024; // not all corners are valid
+float FL_WATERJUMP = 2048; // player jumping out of water
+float FL_JUMPRELEASED = 4096; // for jump debouncing
+float FL_DOUBLEJUMPED = 8192; // player has doublejumped
+float FL_WALLJUMP = 16384; // player has jumped off a wall
+float FL_NOCENTERPRINT = 65536; // don't centerprint entity's message
+ // field when its targets are used
+// edict.movetype values
+float MOVETYPE_NONE = 0; // never moves
+//float MOVETYPE_ANGLENOCLIP = 1;
+//float MOVETYPE_ANGLECLIP = 2;
+float MOVETYPE_WALK = 3; // players only
+float MOVETYPE_STEP = 4; // discrete, not real time unless fall
+float MOVETYPE_FLY = 5;
+float MOVETYPE_TOSS = 6; // gravity
+float MOVETYPE_PUSH = 7; // no clip to world, push and crush
+float MOVETYPE_NOCLIP = 8;
+float MOVETYPE_FLYMISSILE = 9; // fly with extra size against monsters
+float MOVETYPE_BOUNCE = 10;
+float MOVETYPE_BOUNCEMISSILE = 11; // bounce with extra size
+
+// edict.solid values
+float SOLID_NOT = 0; // no interaction with other objects
+float SOLID_TRIGGER = 1; // touch on edge, but not blocking
+float SOLID_BBOX = 2; // touch on edge, block
+float SOLID_SLIDEBOX = 3; // touch on edge, but not an onground
+float SOLID_BSP = 4; // bsp clip, touch on edge, block
+
+// range values
+float RANGE_MELEE = 0;
+float RANGE_NEAR = 1;
+float RANGE_MID = 2;
+float RANGE_FAR = 3;
+
+// deadflag values
+float DEAD_NO = 0;
+float DEAD_DYING = 1;
+float DEAD_DEAD = 2;
+float DEAD_RESPAWNABLE = 3;
+
+// takedamage values
+float DAMAGE_NO = 0;
+float DAMAGE_YES = 1;
+float DAMAGE_AIM = 2;
+
+// items
+float IT_AXE = 4096;
+float IT_SHOTGUN = 1;
+float IT_SUPER_SHOTGUN = 2;
+float IT_NAILGUN = 4;
+float IT_SUPER_NAILGUN = 8;
+float IT_GRENADE_LAUNCHER = 16;
+float IT_ROCKET_LAUNCHER = 32;
+float IT_LIGHTNING = 64;
+float IT_EXTRA_WEAPON = 128;
+
+float IT_SHELLS = 256;
+float IT_NAILS = 512;
+float IT_ROCKETS = 1024;
+float IT_CELLS = 2048;
+
+float IT_ARMOR1 = 8192;
+float IT_ARMOR2 = 16384;
+float IT_ARMOR3 = 32768;
+float IT_SUPERHEALTH = 65536;
+
+float IT_KEY1 = 131072;
+float IT_KEY2 = 262144;
+
+float IT_INVISIBILITY = 524288;
+float IT_INVULNERABILITY = 1048576;
+float IT_SUIT = 2097152;
+float IT_QUAD = 4194304;
+
+// point content values
+float CONTENT_EMPTY = -1;
+float CONTENT_SOLID = -2;
+float CONTENT_WATER = -3;
+float CONTENT_SLIME = -4;
+float CONTENT_LAVA = -5;
+float CONTENT_SKY = -6;
+
+float STATE_TOP = 0;
+float STATE_BOTTOM = 1;
+float STATE_UP = 2;
+float STATE_DOWN = 3;
+
+vector VEC_ORIGIN = '0 0 0';
+// Player
+vector VEC_HULL_MIN = '-16 -16 -24';
+vector VEC_HULL_MAX = '16 16 32';
+vector VEC_HULL_SIZE = '32 32 56';
+// Ogres, Shalrath, Demon, Shambler
+vector VEC_HULL2_MIN = '-32 -32 -24';
+vector VEC_HULL2_MAX = '32 32 64';
+vector VEC_HULL2_SIZE = '64 64 88';
+
+// protocol bytes
+float SVC_UPDATESTAT = 3; // required by Hipnotic code
+float SVC_SETVIEWPORT = 5; // Camera Hip. Drake devkit dumptruck_ds
+float SVC_SETVIEWANGLES = 10; // Camera Hip. Drake devkit dumptruck_ds
+float SVC_TEMPENTITY = 23;
+float SVC_KILLEDMONSTER = 27;
+float SVC_FOUNDSECRET = 28;
+float SVC_INTERMISSION = 30;
+float SVC_FINALE = 31;
+float SVC_CDTRACK = 32;
+float SVC_SELLSCREEN = 33;
+float SVC_CUTSCENE = 34; // Hipnotic Drake devkit -- dumptruck_ds
+
+float TE_SPIKE = 0;
+float TE_SUPERSPIKE = 1;
+float TE_GUNSHOT = 2;
+float TE_EXPLOSION = 3;
+float TE_TAREXPLOSION = 4;
+float TE_LIGHTNING1 = 5;
+float TE_LIGHTNING2 = 6;
+float TE_WIZSPIKE = 7;
+float TE_KNIGHTSPIKE = 8;
+float TE_LIGHTNING3 = 9;
+float TE_LAVASPLASH = 10;
+float TE_TELEPORT = 11;
+float TE_EXPLOSION2 = 12; // from doe -- dumptruck_ds
+
+// sound channels
+// channel 0 never willingly overrides
+// other channels (1-7) always override a playing sound on that channel
+float CHAN_AUTO = 0;
+float CHAN_WEAPON = 1;
+float CHAN_VOICE = 2;
+float CHAN_ITEM = 3;
+float CHAN_BODY = 4;
+
+float ATTN_NONE = 0;
+float ATTN_NORM = 1;
+float ATTN_IDLE = 2;
+float ATTN_STATIC = 3;
+
+// update types
+float UPDATE_GENERAL = 0;
+float UPDATE_STATIC = 1;
+float UPDATE_BINARY = 2;
+float UPDATE_TEMP = 3;
+
+// entity effects
+float EF_BRIGHTFIELD = 1;
+float EF_MUZZLEFLASH = 2;
+float EF_BRIGHTLIGHT = 4;
+float EF_DIMLIGHT = 8;
+
+// messages
+float MSG_BROADCAST = 0; // unreliable to all
+float MSG_ONE = 1; // reliable to one (msg_entity)
+float MSG_ALL = 2; // reliable to all
+float MSG_INIT = 3; // write to the init string
+
+// spawnflags for func_movewall
+float MOVEWALL_VISIBLE = 1;
+float MOVEWALL_TOUCH = 2;
+float MOVEWALL_NONBLOCKING = 4;
+
+// known_release values -- iw
+float KNOWN_RELEASE_NOT = 0;
+float KNOWN_RELEASE_ID1 = 1;
+float KNOWN_RELEASE_FUNC_MAPJAMX = 2;
+
+// interfacing with CSQC -- CEV
+const float CLIENT_VELOCITY_X = 64;
+const float CLIENT_VELOCITY_Y = 65;
+
+const float EV_VOID = 0;
+const float EV_STRING = 1;
+const float EV_FLOAT = 2;
+const float EV_VECTOR = 3;
+const float EV_ENTITY = 4;
+const float EV_FIELD = 5;
+const float EV_FUNCTION = 6;
+const float EV_POINTER = 7;
+const float EV_INTEGER = 8;
+
+//======================================================================
+// globals
+//======================================================================
+float movedist;
+float gameover; // set when a rule exits
+
+string string_null; // null string
+// float empty_float;
+
+entity newmis; // set by launch_spike after spawning it
+entity activator; // entity that activated a trigger or
+ // brush
+entity damage_attacker; // set by T_Damage
+float framecount;
+
+float skill;
+
+float known_release; // unique ID for a release;
+ // see values above -- iw
+
+//======================================================================
+// world fields (FIXME: make globals)
+//======================================================================
+.string wad;
+.string map;
+.float worldtype; // 0=medieval 1=metal 2=base
+.float skip_id1_overrides;
+.string killtarget;
+
+//======================================================================
+// quakeed fields
+//======================================================================
+.float light_lev; // not used ingame, parsed by light util
+.float style;
+
+//======================================================================
+// monster ai
+//======================================================================
+.void() th_stand;
+.void() th_walk;
+.void() th_run;
+.void() th_missile;
+.void() th_melee;
+.void(entity attacker, float damage) th_pain;
+.void() th_die;
+
+.entity oldenemy; // mad at this player before taking
+ // damage
+.float speed;
+
+.float lefty;
+
+.float search_time;
+.float attack_state;
+
+float AS_STRAIGHT = 1;
+float AS_SLIDING = 2;
+float AS_MELEE = 3;
+float AS_MISSILE = 4;
+float AS_TURRET = 5;
+
+//======================================================================
+// player only fields
+//======================================================================
+.float walkframe;
+
+.float attack_finished;
+.float pain_finished;
+
+.float invincible_finished;
+.float invisible_finished;
+.float super_damage_finished;
+.float radsuit_finished;
+
+.float invincible_time, invincible_sound;
+.float invisible_time, invisible_sound;
+.float super_time, super_sound;
+.float rad_time;
+.float fly_sound;
+
+.float axhitme;
+
+// set to time+0.2 whenever a client fires a weapon or takes damage.
+// Used to alert monsters that otherwise would let the player go
+.float show_hostile;
+
+.float jump_flag; // player jump flag
+.float swim_flag; // player swimming sound flag
+.float air_finished; // when time > air_finished, drown
+.float bubble_count; // keeps track of the number of bubbles
+.string deathtype; // keeps track of how the player died
+
+.float jump_time; // last time the player jumped -- CEV
+.vector primal_velocity; // velocity before engine physics -- CEV
+.float primal_speed; // speed before engine physics -- CEV
+.float boost_time; // time to simulate low friction -- CEV
+
+float input_timelength; // from fteextensions.qc -- CEV
+vector input_angles; /* +x=DOWN */
+vector input_movevalues;
+float input_buttons;
+float input_impulse;
+
+//======================================================================
+// object stuff
+//======================================================================
+.string mdl;
+.vector mangle; // angle at start
+.vector oldorigin; // only used by secret door
+.string origmodel; // switchables brushes (added by bmFbr)
+.float t_length, t_width;
+
+//======================================================================
+// doors, etc
+//======================================================================
+.vector /*dest,*/ dest1, dest2;
+.float wait; // time from firing to restarting
+.float delay; // time from activation to firing
+.entity trigger_field; // door's trigger entity
+.string noise4;
+.float aflag;
+.float dmg; // damage done by door when hit
+
+//======================================================================
+// monsters
+//======================================================================
+.float pausetime;
+.entity movetarget;
+.float homing;
+.float projexpl;
+.float proj_speed_mod;
+.float proj_basespeed;
+.float infight_mode;
+
+//======================================================================
+// misc
+//======================================================================
+.float cnt; // misc flag
+
+//======================================================================
+// subs
+//======================================================================
+.void() think1;
+.vector finaldest, finalangle;
+
+//======================================================================
+// triggers
+//======================================================================
+.float count; // for counting triggers
+
+//======================================================================
+// plats / doors / buttons
+//======================================================================
+.float lip;
+.float state;
+.vector pos1, pos2; // top and bottom positions
+.float height;
+
+//======================================================================
+// plat2 fields // progs_dump
+//======================================================================
+.float plat2Called;
+.float plat2LastMove;
+.float plat2GoTime;
+.float plat2GoTo;
+
+//======================================================================
+// elevator fields // progs_dump
+//======================================================================
+.float elevatorLastUse;
+.float elevatorOnFloor;
+.float elevatorToFloor;
+.vector elevatorDestination;
+
+//======================================================================
+// fog // progs_dump
+//======================================================================
+.vector fog_color, fog_color2;
+.float fog_density, fog_density2;
+.float skyfog_density, skyfog_density2;
+.entity fogblend_entity;
+.float distance;
+
+//======================================================================
+// sounds
+//======================================================================
+.float waitmin /*, waitmax*/;
+// .float distance;
+.float volume;
+
+//======================================================================
+// support for item_key_custom -- iw
+//======================================================================
+.string keyname;
+.float customkeys;
+
+//======================================================================
+// variables for enhanced triggering from Custents -- dumptruck_ds
+//======================================================================
+.string target2; // second target's name
+.string target3; // third target's name
+.string target4; // fourth target's name
+.string targetname2; // second name
+.string targetname3; // third name
+.string targetname4; // fourth name
+.string killtarget2; // second target to kill
+string lastnameused; // the targetname that was last used
+ // to trigger somthing
+
+//======================================================================
+// switchable shadow
+//======================================================================
+.float switchshadstyle;
+.float shadowoff;
+.entity shadowcontroller;
+.float speed2;
+
+void() misc_shadowcontroller;
+void() misc_shadowcontroller_use;
+void() shadow_fade_in;
+void() shadow_fade_out;
+string(float num) lightstyle_fade_lookup;// add. by bmFbr for switchable shadows
+
+//======================================================================
+// misc pd_additions
+//======================================================================
+.float reset_items; // dumptruck_ds
+.float spawn_angry; // dumptruck_ds
+.string mdl_debris; // dumptruck_ds
+.float keep_ammo; // dumptruck_ds
+.string obit_name; // dumptruck_ds
+.string obit_method; // dumptruck_ds
+.float damage_mod; // dumptruck_ds
+
+/*==============================================================================
+ subs.qc
+==============================================================================*/
+void(vector tdest, float tspeed, void() func) SUB_CalcMove;
+void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt;
+void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove;
+void() SUB_CalcMoveDone;
+void() SUB_CalcAngleMoveDone;
+void() SUB_Null;
+void() SUB_UseTargets;
+void() SUB_Remove;
+
+/*==============================================================================
+ combat.qc
+==============================================================================*/
+void(entity targ, entity inflictor, entity attacker, float damage) T_Damage;
+float (entity e, float healamount, float ignore) T_Heal; // health function
+float(entity targ, entity inflictor) CanDamage;
+void() DummyFunction =
+{
+ // gets rid of the last compiler warnings ; - )
+ local string w;
+ local float l;
+ w = self.wad;
+ l = self.light_lev;
+}
+.float is_waiting; // Supa, triggers, wait until activated
+ // before we can trigger?
+.float gravity; // from custdefs.qc by way of Hipnotic
+float STAT_TOTALMONSTERS = 12; // required by Hipnotic code
+
+// dumptruck_ds from Rogue eod defs
+
+/*============================================================================
+ johnfitz new defs from Rubicon2
+============================================================================*/
+float BREAKABLE_NO_MONSTERS = 1;
+
+.float wantedgravity; // thanks Spike!
+.float onladder;
+// .float ladder_step_finished; // footsteps on ladder -- dumptruck_ds
+
+// dumptruck_ds defs for breakables in rubcon2.qc
+// -- thanks to Qmaster and the Arcane Dimensions team
+/*
+.string break_template1_e;
+.string break_template2_e;
+.string break_template3_e;
+.string break_template4_e;
+.string break_template5_e;
+.string find_brk_template_model;
+*/
+
+// from remakequake -- dumptruck_ds
+
+.vector dest, dest1, dest2;
+
+void(string type, string text) print_self =
+{
+ dprint (type);
+ dprint (" '");
+ dprint (self.classname);
+ dprint ("' ");
+ dprint (text);
+ dprint (" at ");
+ dprint (vtos(self.origin));
+ dprint ("\n");
+};
+
+// TODO CEV
+void() monster_pain_use; // dumptruck_ds
+void() SUB_UsePain; // dumptruck_ds
+.float pain_threshold; // dumptruck_ds
+.string pain_target; // dumptruck_ds
+.float color; // Hipnotic
+.float megahealth_rottime; // dumptruck_ds
+.float alpha; // from RennyC func_fall in dtmisc.qc
+.float ltrailLastUsed; // from DOE lighnin
+.float style2; // c0burn's switchable lights
+.float sight_trigger; // dumptruck_ds
+.float keep_ammo; // dumptruck_ds
+.float berserk; // dumptruck_ds
+nosave float *world_sounds; // via Spike fun times! nosave=noclobber
+void() trigger_changemusic; // dumptruck_ds
+void() onlookat_touch; // dumptruck_ds
+
+// Drake Cutscenes -- Borrowed from Zerstorer.
+.string script; // dhm - denotes which script to read.
+.string next_script; // dhm - denotes the current script.
+.string script_num; // dhm - number for info_scripts.
+// .string camera_point; // dhm - target for camera to move to.
+.string focal_point; // dhm - focus point for camera.
+.float script_delay; // dhm - time until next script.
+.float script_time; // dhm - used for script timing.
+.float script_count; // dhm - ditto.
+// cutscene.qc - - -
+void() Cutscene_Think;
+float cutscene; // Set to TRUE during a cutscene.
+float mindex_inviso; // Invisible (null sprite)
+.string null_string; // Replace 'string_null' with
+ // 'world.null_string'. null string,
+ // nothing should be held here.
+// from Custents
+// variable for healing trigger
+.float heal_timer;
+.float heal_amount;
+.float health_max;
+// Constants for the healing trigger
+float HEAL_START_ON = 1;
+float HEAL_PLAYER_ONLY = 2;
+float HEAL_MONSTER_ONLY = 4;
+
+// Custom Monster Sounds START -- dumptruck_ds
+.string snd_death;
+.string snd_pain;
+.string snd_sight;
+.string snd_attack;
+.string snd_hit;
+.string snd_idle;
+.string snd_land;
+.string snd_move;
+.string snd_misc;
+.string snd_misc1;
+.string snd_misc2;
+.string snd_misc3;
+// Custom Monster Sounds END -- dumptruck_ds
+
+// Custom Model Start -- dumptruck_ds
+.string mdl_head;
+.string mdl_body;
+.string mdl_proj;
+.string mdl_exproj;
+.float skin_head;
+.float skin_proj;
+.float skin_exproj;
+.string mdl_gib1;
+.string mdl_gib2;
+.string mdl_gib3;
+// addition by bmFbr for custom model bounding box definition
+.vector mdlsz, centeroffset;
+// Custom Model End -- dumptruck_ds
+
+.float shardvalue; // ammo shard value
+
+.float drop_item; // key DropStuff
+
+float SPAWN_SILENTLY = 2097152;
+float TRIGGER_CENTERPRINTALL = 1048576;
+
+// entity state
+.float estate;
+.void() dormant_use;
+float STATE_ACTIVE = 0;
+float STATE_INACTIVE = 1;
+float STATE_INVISIBLE = 8;
+
+.float prevstate;
+
+void(entity client, float density, vector color) fog_save;
+void(entity client, float density) skyfog_save;
+void(entity client, entity fogger) fog_setFromEnt;
+void(entity client, float density, vector color) fog_set;
+void(entity client, float density) skyfog_set;
+
+nosave float cleanUpClientStuff;
+nosave float gamestarted;
+
+.string include;
+.string type;
+
+.float last_setstate_frame = light_lev;
+.entity last_setstate = aiment;
+
+// 1998-07-03 hurt_touch fix by Robert Field start
+//
+// triggers.qc
+//
+.float hurt_together_time;
+.float hurt_nextthink;
+// 1998-07-03 hurt_touch fix by Robert Field end
+
+float I_AM_TURRET = 262144; // dumptruck_ds
+.void() th_turret;
+
+.entity animcontroller;
+.entity rotatecontroller;
+.float multiplier;
+
+.float first_frame, last_frame;
+.float first_frame2, last_frame2;
+.float frtime, frtime2;
+.float animtype, animtype2;
+.vector cmins, cmaxs;
+.vector cust_avelocity;
+.float touch_time;
+
+// cshift controller
+.entity csfcontroller;
+
+.vector csf_color;
+.float csf_density;
+
+void(entity client) csf_apply;
+void(entity client, float density, vector color, float spd) csf_fade;
+void(entity client, float density, vector color) csf_set;
+
+.float fade_amt;
+
+// worldspawn default mdls
+.string h_vial_mdl;
+.string h_25_mdl;
+.string h_15_mdl;
+.string h_mega_mdl;
+
+.string s_sm_mdl;
+.string s_lg_mdl;
+
+.string n_sm_mdl;
+.string n_lg_mdl;
+
+.string r_sm_mdl;
+.string r_lg_mdl;
+
+.string c_sm_mdl;
+.string c_lg_mdl;
+
+.string a_shr_mdl;
+.string a_grn_mdl;
+.string a_ylw_mdl;
+.string a_red_mdl;
+
+.entity infight_activator;
+
+.void() customphysics;
+

Return to the top of this page or return to the overview of this repo.

Diff qc/doe_elbutton.qc

diff --git a/qc/doe_elbutton.qc b/qc/doe_elbutton.qc
new file mode 100644
index 0000000..62cd91d
--- /dev/null
+++ b/qc/doe_elbutton.qc
@@ -0,0 +1,157 @@
+// elevator button
+// pmack
+// sept 96
+
+float ELVTR_DOWN = 1;
+
+void() elvtr_button_wait;
+void() elvtr_button_return;
+
+void() elvtr_button_wait =
+{
+ elv_butn_dir = 0;
+ if (self.spawnflags & ELVTR_DOWN)
+ elv_butn_dir = -1;
+ else
+ elv_butn_dir = 1;
+
+ self.state = STATE_TOP;
+ self.nextthink = self.ltime + self.wait;
+ self.think = elvtr_button_return;
+ activator = self.enemy;
+ SUB_UseTargets();
+ self.frame = 1; // use alternate textures
+};
+
+void() elvtr_button_done =
+{
+ self.state = STATE_BOTTOM;
+};
+
+void() elvtr_button_return =
+{
+ self.state = STATE_DOWN;
+ SUB_CalcMove (self.pos1, self.speed, elvtr_button_done);
+ self.frame = 0; // use normal textures
+ if (self.health)
+ self.takedamage = DAMAGE_YES; // can be shot again
+};
+
+
+void() elvtr_button_blocked =
+{ // do nothing, just don't ome all the way back out
+};
+
+
+void() elvtr_button_fire =
+{
+ if (self.state == STATE_UP || self.state == STATE_TOP)
+ return;
+
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+
+ self.state = STATE_UP;
+ SUB_CalcMove (self.pos2, self.speed, elvtr_button_wait);
+};
+
+
+void() elvtr_button_use =
+{
+ self.enemy = activator;
+ elvtr_button_fire ();
+};
+
+void() elvtr_button_touch =
+{
+ if (other.classname != "player")
+ return;
+ self.enemy = other;
+ elvtr_button_fire ();
+};
+
+void() elvtr_button_killed =
+{
+ self.enemy = damage_attacker;
+ self.health = self.max_health;
+ self.takedamage = DAMAGE_NO; // wil be reset upon return
+ elvtr_button_fire ();
+};
+
+
+/*QUAKED func_elvtr_button (0 .5 .8) ? ELVTR_DOWN X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+ELEVATOR BUTTON ONLY!
+
+ELVTR_DOWN causes this to be a DOWN button.
+Default is UP.
+
+When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again.
+
+"angle" determines the opening direction
+"target" all entities with a matching targetname will be used
+"speed" override the default 40 speed
+"wait" override the default 1 second wait (-1 = never return)
+"lip" override the default 4 pixel lip remaining at end of move
+"health" if set, the button must be killed instead of touched
+"sounds"
+0) steam metal
+1) wooden clunk
+2) metallic click
+3) in-out
+*/
+void() func_elvtr_button =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.sounds == 0)
+ {
+ precache_sound ("buttons/airbut1.wav");
+ self.noise = "buttons/airbut1.wav";
+ }
+ if (self.sounds == 1)
+ {
+ precache_sound ("buttons/switch21.wav");
+ self.noise = "buttons/switch21.wav";
+ }
+ if (self.sounds == 2)
+ {
+ precache_sound ("buttons/switch02.wav");
+ self.noise = "buttons/switch02.wav";
+ }
+ if (self.sounds == 3)
+ {
+ precache_sound ("buttons/switch04.wav");
+ self.noise = "buttons/switch04.wav";
+ }
+
+ SetMovedir ();
+
+ self.movetype = MOVETYPE_PUSH;
+ self.solid = SOLID_BSP;
+ setmodel (self, self.model);
+
+ self.blocked = elvtr_button_blocked;
+ self.use = elvtr_button_use;
+
+ if (self.health)
+ {
+ self.max_health = self.health;
+ self.th_die = elvtr_button_killed;
+ self.takedamage = DAMAGE_YES;
+ }
+ else
+ self.touch = elvtr_button_touch;
+
+ if (!self.speed)
+ self.speed = 40;
+ if (!self.wait)
+ self.wait = 1;
+ if (!self.lip)
+ self.lip = 4;
+
+ self.state = STATE_BOTTOM;
+
+ self.pos1 = self.origin;
+ self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/doe_ltrail.qc

diff --git a/qc/doe_ltrail.qc b/qc/doe_ltrail.qc
new file mode 100644
index 0000000..0a3f0d9
--- /dev/null
+++ b/qc/doe_ltrail.qc
@@ -0,0 +1,194 @@
+// lightning trail
+// pmack
+// sept 96
+
+// float ltrailLastUsed; -- now an entity field.
+
+float LT_TOGGLE = 1;
+float LT_ACTIVE = 2;
+
+void() ltrail_chain =
+{
+ SUB_UseTargets();
+
+ self.think = SUB_Null;
+};
+
+void() ltrail_fire =
+{
+ local entity myTarget;
+
+ if (self.classname != "ltrail_end")
+ {
+ if (!self.sounds)
+ sound (self, CHAN_VOICE, "weapons/lhit.wav", 1, ATTN_NORM);
+ myTarget = find(world, targetname, self.target);
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
+ WriteEntity (MSG_BROADCAST, self);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+ WriteCoord (MSG_BROADCAST, myTarget.origin_x);
+ WriteCoord (MSG_BROADCAST, myTarget.origin_y);
+ WriteCoord (MSG_BROADCAST, myTarget.origin_z);
+ LightningDamage (self.origin, myTarget.origin, self, self.currentammo);
+ }
+
+ if ( self.items < time)
+ {
+ self.think = ltrail_chain;
+ self.nextthink = time + self.frags;
+ }
+ else
+ {
+ self.think = ltrail_fire;
+ self.nextthink = time + 0.05;
+ }
+};
+
+void() ltrail_start_fire =
+{
+ // if it's a toggle ltrail, we ignore triggers from ltrail_end's
+ // when toggled off.
+ if (self.spawnflags & LT_TOGGLE)
+ {
+ // user is not a lightning trail - change activity state.
+ if ( other.classname != "ltrail_end" )
+ {
+ if (self.spawnflags & LT_ACTIVE)
+ // currently active
+ {
+ self.spawnflags = self.spawnflags - LT_ACTIVE;
+ return;
+ }
+ else
+ // not active
+ {
+ self.spawnflags = self.spawnflags + LT_ACTIVE;
+ }
+ }
+ // user is lightning trail, but trail has been turned off.
+ // ignore the message.
+ else if (!(self.spawnflags & LT_ACTIVE))
+ return;
+ }
+
+ if (self.classname == "ltrail_start")
+ {
+ self.items = time + self.weapon;
+ ltrail_fire();
+ self.ltrailLastUsed = time;
+ }
+ else if (self.classname == "ltrail_relay")
+ {
+ self.items = time + self.weapon;
+ ltrail_fire();
+ }
+ else
+ {
+ self.think = ltrail_chain;
+ self.nextthink = time + self.frags;
+ }
+};
+
+/*QUAKED ltrail_start (0 1 0) (-8 -8 -8) (8 8 8) LT_TOGGLE START_ON X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Starting point of a lightning trail.
+Set currentammo to amount of damage you want the lightning to do.
+Default is 25.
+
+Set frags to amount of time before next item is triggered.
+Default is 0.3 seconds.
+
+Set weapon to amount of time to be firing the lightning.
+Default is 0.3 seconds.
+
+Set the LT_TOGGLE checkbox if you want the lightning shooter to continuously fire until triggered again.
+*/
+void() ltrail_start =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.ltrailLastUsed = time;
+
+ precache_sound ("weapons/lhit.wav");
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_BBOX;
+ self.use = ltrail_start_fire;
+
+ if (self.currentammo == 0)
+ self.currentammo = 25;
+
+ if (self.weapon == 0)
+ self.weapon = 0.3;
+
+ if (self.frags == 0)
+ self.frags = 0.3;
+
+ if (self.spawnflags & LT_ACTIVE)
+ {
+ self.items = time + 99999999;
+ self.think = ltrail_fire;
+ self.nextthink = time + 0.1;
+ }
+};
+
+/*QUAKED ltrail_relay (0 1 0) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Relay point of a lightning trail.
+Set currentammo to amount of damage you want the lightning to do.
+Default is 25.
+
+Set frags to amount of time before next item is triggered.
+Default is 0.3 seconds.
+
+Set weapon to amount of time to be firing the lightning.
+Default is 0.3 seconds.
+*/
+void() ltrail_relay =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("weapons/lhit.wav");
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_BBOX;
+ self.use = ltrail_start_fire;
+
+ if (self.currentammo == 0)
+ self.currentammo = 25;
+
+ if (self.weapon == 0)
+ self.weapon = 0.3;
+
+ if (self.frags == 0)
+ self.frags = 0.3;
+};
+
+/*QUAKED ltrail_end (0 1 0) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Ending point of a lightning trail.
+Does not fire any lightning.
+
+Set frags to amount of time before next item is triggered.
+Default is 0.3 seconds.
+*/
+void() ltrail_end =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("weapons/lhit.wav");
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_BBOX;
+ self.use = ltrail_start_fire;
+
+ if (self.currentammo == 0)
+ self.currentammo = 25;
+
+ if (self.weapon == 0)
+ self.weapon = 0.3;
+
+ if (self.frags == 0)
+ self.frags = 0.3;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/doe_plats.qc

diff --git a/qc/doe_plats.qc b/qc/doe_plats.qc
new file mode 100644
index 0000000..70225cd
--- /dev/null
+++ b/qc/doe_plats.qc
@@ -0,0 +1,630 @@
+// newplats.qc
+// pmack
+// september 1996
+
+// TYPES
+
+float DN_N_WAIT = 1;
+float PLT_TOGGLE = 2;
+float ELEVATOR = 4;
+float START_AT_TOP = 8;
+float PLAT2 = 16;
+float PLAT2_BOTTOM = 32;
+
+float elv_butn_dir;
+
+// ==================================
+// down N and wait code
+// ==================================
+
+void() dn_and_wait_go_up;
+void() dn_and_wait_go_down;
+void() dn_and_wait_crush;
+
+void() dn_and_wait_hit_top =
+{
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ self.state = STATE_TOP;
+};
+
+void() dn_and_wait_hit_bottom =
+{
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ self.state = STATE_BOTTOM;
+ self.think = dn_and_wait_go_up;
+ self.nextthink = self.ltime + self.health;
+};
+
+void() dn_and_wait_go_down =
+{
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ self.state = STATE_DOWN;
+ SUB_CalcMove (self.pos2, self.speed, dn_and_wait_hit_bottom);
+};
+
+void() dn_and_wait_go_up =
+{
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ self.state = STATE_UP;
+ SUB_CalcMove (self.pos1, self.speed, dn_and_wait_hit_top);
+};
+
+void() dn_and_wait_crush =
+{
+ T_Damage (other, self, self, 1);
+
+ if (self.state == STATE_UP)
+ dn_and_wait_go_down ();
+ else if (self.state == STATE_DOWN)
+ dn_and_wait_go_up ();
+ else
+ objerror ("plat_new_crush: bad self.state\n");
+};
+
+void() dn_and_wait_use =
+{
+ if (self.state != STATE_TOP)
+ return;
+
+ dn_and_wait_go_down ();
+};
+
+// ==================================
+// toggle type code
+// ==================================
+
+void() toggle_go_up;
+void() toggle_go_down;
+void() toggle_crush;
+
+void() toggle_hit_top =
+{
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ self.state = STATE_TOP;
+};
+
+void() toggle_hit_bottom =
+{
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ self.state = STATE_BOTTOM;
+};
+
+void() toggle_go_down =
+{
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ self.state = STATE_DOWN;
+ SUB_CalcMove (self.pos2, self.speed, toggle_hit_bottom);
+};
+
+void() toggle_go_up =
+{
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ self.state = STATE_UP;
+ SUB_CalcMove (self.pos1, self.speed, toggle_hit_top);
+};
+
+void() toggle_crush =
+{
+ T_Damage (other, self, self, 1);
+
+ if (self.state == STATE_UP)
+ toggle_go_down ();
+ else if (self.state == STATE_DOWN)
+ toggle_go_up ();
+ else
+ objerror ("plat_new_crush: bad self.state\n");
+};
+
+void() toggle_use =
+{
+ if (self.state == STATE_TOP)
+ toggle_go_down ();
+ else if(self.state == STATE_BOTTOM)
+ toggle_go_up ();
+};
+
+// ==================================
+// elvtr type code
+// ==================================
+
+void() elvtr_crush;
+
+void() elvtr_stop =
+{
+ self.elevatorOnFloor = self.elevatorToFloor;
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ self.state = STATE_BOTTOM;
+ self.elevatorLastUse = time;
+};
+
+void() elvtr_go =
+{
+ self.elevatorDestination = self.pos2;
+ self.elevatorDestination_z = self.pos2_z +
+ (self.height * self.elevatorToFloor);
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ self.state = STATE_UP;
+ SUB_CalcMove (self.elevatorDestination, self.speed, elvtr_stop);
+ self.elevatorLastUse = time;
+};
+
+void() elvtr_crush =
+{
+ local float tmp;
+
+// T_Damage (other, self, self, 1);
+
+ // the elevator is changing direction, so swap the floor it's coming
+ // from and the floor it's going to -- iw
+ tmp = self.elevatorOnFloor;
+ self.elevatorOnFloor = self.elevatorToFloor;
+ self.elevatorToFloor = tmp;
+
+ elvtr_go ();
+};
+
+// ===============
+// elevator use function
+// self = plat, other = elevator button, other.enemy = player
+// ===============
+void() elvtr_use =
+{
+ local float tempDist, elvPos, btnPos;
+
+ // the original DoE code allowed an elevator to be activated again
+ // when it was in the process of moving between floors (assuming the
+ // wait period was over); this resulted in sometimes unintuitive
+ // behavior, so, the following test prevents this -- iw
+ if (self.elevatorToFloor != self.elevatorOnFloor)
+ return;
+
+ // the original DoE code had a hard-coded two second wait period;
+ // this has been changed for progs_dump so that self.wait is used
+ // instead -- iw
+ if ((self.elevatorLastUse + self.wait) > time)
+ return;
+
+ self.elevatorLastUse = time;
+
+ if (elv_butn_dir == 0)
+ return;
+
+ elvPos = (self.absmin_z + self.absmax_z) * 0.5;
+ btnPos = (other.absmin_z + other.absmax_z) * 0.5;
+
+ if (elvPos > btnPos)
+ {
+ tempDist = (elvPos - btnPos) / self.height;
+ tempDist = ceil ( tempDist);
+ self.elevatorToFloor = self.elevatorOnFloor - tempDist;
+ elvtr_go ();
+ return;
+ }
+ else
+ {
+ tempDist = btnPos - elvPos;
+ if (tempDist > self.height)
+ {
+ tempDist = tempDist / self.height;
+ tempDist = floor ( tempDist );
+ self.elevatorToFloor = self.elevatorOnFloor + tempDist;
+ elvtr_go ();
+ return;
+ }
+ }
+
+ if (elv_butn_dir == -1)
+ {
+ if(self.elevatorOnFloor > 0)
+ {
+ self.elevatorToFloor = self.elevatorOnFloor - 1;
+ elvtr_go ();
+ }
+ }
+ else if(elv_butn_dir == 1)
+ {
+ if(self.elevatorOnFloor < (self.cnt - 1))
+ {
+ self.elevatorToFloor = self.elevatorOnFloor + 1;
+ elvtr_go ();
+ }
+ }
+};
+
+// ==================================
+// PLAT2 type code
+// ==================================
+
+void() plat2_center_touch;
+void() plat2_go_up;
+void() plat2_go_down;
+void() plat2_crush;
+
+void() plat2_spawn_inside_trigger =
+{
+ local entity trigger;
+ local vector tmin, tmax;
+
+//
+// middle trigger
+//
+ trigger = spawn();
+ trigger.touch = plat2_center_touch;
+ trigger.movetype = MOVETYPE_NONE;
+ trigger.solid = SOLID_TRIGGER;
+ trigger.enemy = self;
+
+ tmin = self.mins + '25 25 0';
+ tmax = self.maxs - '25 25 -8';
+ tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8);
+
+ if (self.spawnflags & PLAT_LOW_TRIGGER)
+ tmax_z = tmin_z + 8;
+
+ if (self.size_x <= 50)
+ {
+ tmin_x = (self.mins_x + self.maxs_x) / 2;
+ tmax_x = tmin_x + 1;
+ }
+ if (self.size_y <= 50)
+ {
+ tmin_y = (self.mins_y + self.maxs_y) / 2;
+ tmax_y = tmin_y + 1;
+ }
+
+ setsize (trigger, tmin, tmax);
+};
+
+void() plat2_hit_top =
+{
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ self.state = STATE_TOP;
+
+ self.plat2LastMove = time;
+ if(self.plat2Called == 1)
+ {
+ self.think = plat2_go_down;
+ self.nextthink = self.ltime + 1.5;
+ self.plat2Called = 0;
+ self.plat2LastMove = 0; // allow immediate move
+ }
+ else if(!(self.spawnflags & START_AT_TOP))
+ {
+ self.think = plat2_go_down;
+ self.nextthink = self.ltime + self.delay;
+ self.plat2Called = 0;
+ }
+};
+
+void() plat2_hit_bottom =
+{
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ self.state = STATE_BOTTOM;
+
+ self.plat2LastMove = time;
+ if(self.plat2Called == 1)
+ {
+ self.think = plat2_go_up;
+ self.nextthink = self.ltime + 1.5;
+ self.plat2Called = 0;
+ self.plat2LastMove = 0; // allow immediate move
+ }
+ else if(self.spawnflags & START_AT_TOP)
+ {
+ self.think = plat2_go_up;
+ self.nextthink = self.ltime + self.delay;
+ self.plat2Called = 0;
+ }
+};
+
+void() plat2_go_down =
+{
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ self.state = STATE_DOWN;
+ SUB_CalcMove (self.pos2, self.speed, plat2_hit_bottom);
+};
+
+void() plat2_go_up =
+{
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ self.state = STATE_UP;
+ SUB_CalcMove (self.pos1, self.speed, plat2_hit_top);
+};
+
+void() plat2_use =
+{
+ if(self.state > 4)
+ self.state = self.state - 10;
+
+ self.use = SUB_Null;
+};
+
+void() plat2_center_touch =
+{
+ local float otherState;
+ local vector platPosition;
+
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ // at this point, self is the trigger. self.enemy is the plat.
+ // this changes self to be the plat, other is the player.
+ self = self.enemy;
+
+ if ((self.plat2LastMove + 2) > time)
+ return;
+
+ if (self.state > 4) // disabled.
+ return;
+
+ if (self.plat2GoTo > STATE_BOTTOM)
+ {
+ if (self.plat2GoTime < time)
+ {
+ if (self.plat2GoTo == STATE_UP)
+ plat2_go_up();
+ else
+ plat2_go_down();
+
+ self.plat2GoTo = 0;
+ }
+ return;
+ }
+
+ if (self.state > STATE_BOTTOM) // STATE_UP or STATE_DOWN
+ return;
+
+ platPosition = (self.absmax + self.absmin) * 0.5;
+
+ if (self.state == STATE_TOP)
+ {
+ otherState = STATE_TOP;
+ if ( platPosition_z > other.origin_z )
+ otherState = STATE_BOTTOM;
+ }
+ else
+ {
+ otherState = STATE_BOTTOM;
+ if ( (other.origin_z - platPosition_z) > self.height)
+ otherState = STATE_TOP;
+ }
+
+ if (self.state == otherState)
+ {
+ self.plat2Called = 0;
+ self.plat2GoTime = time + 0.5;
+ }
+ else
+ {
+ self.plat2GoTime = time + 0.1;
+ self.plat2Called = 1;
+ }
+
+ if (self.state == STATE_BOTTOM)
+ self.plat2GoTo = STATE_UP;
+ else if(self.state == STATE_TOP)
+ self.plat2GoTo = STATE_DOWN;
+};
+
+void() plat2_crush =
+{
+ T_Damage (other, self, self, 1);
+
+ if (self.state == STATE_UP)
+ plat2_go_down ();
+ else if (self.state == STATE_DOWN)
+ plat2_go_up ();
+ else
+ objerror ("plat2_crush: bad self.state\n");
+};
+
+// ==================================
+// Common Plat Code
+// ==================================
+
+/*QUAKED func_new_plat (0 .5 .8) ? DN_N_WAIT PLT_TOGGLE ELEVATOR START_AT_TOP PLAT2 P2_BOTTOM X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+
+--------------
+DN_N_WAIT is a plat that starts at the top and when triggered, goes down, waits, then comes back up.
+health - number of seconds to wait (default 5)
+--------------
+PLT_TOGGLE is a plat that will change between the top and bottom each time it is triggered.
+--------------
+ELEVATOR is an elevator plat. You can have as many levels as you want but they must be all the same distance away. Use elevator button entity as the trigger.
+cnt is the number of floors
+height is the distance between floors
+wait is the number of seconds before the elevator can be activated again after starting or stopping (default 0)
+
+START_AT_TOP is an optional flag for elevators. It just tells the elevator that it's position is the top floor. (Default is the bottom floor) USE THIS ONLY WITH ELEVATORS!
+-------------
+PLAT2 is a fixed version of the original plat. If you want the plat to start at the bottom and move to the top on demand, use a negative height. That will tell Quake to lower the plat at spawn time. Always place this plat type in the top position when making the map. This will ensure correct lighting, hopefully. If a plat2 is the target of a trigger, it will be disabled until it has been triggered. Delay is the wait before the plat returns to original position.
+
+If you don't want to bother figuring out the height, don't put a
+value in the height
+
+delay default 3
+speed default 150
+cnt default 2
+
+P2_BOTTOM is an optional switch to have an auto-sized plat2 start at the bottom.
+--------------
+Plats are always drawn in the extended position, so they will light correctly.
+
+If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat.
+
+If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determined by the model's height.
+Set "sounds" to one of the following:
+1) base fast
+2) chain slow
+*/
+
+void() func_new_plat =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+//local entity t;
+local float negativeHeight;
+
+ negativeHeight = 0;
+
+ if (!self.t_length)
+ self.t_length = 80;
+ if (!self.t_width)
+ self.t_width = 10;
+
+ if (self.sounds == 0)
+ self.sounds = 2;
+// FIX THIS TO LOAD A GENERIC PLAT SOUND
+
+ if (self.sounds == 1) {
+ if (!self.noise || self.noise == "") self.noise = "plats/plat1.wav";
+ if (!self.noise1 || self.noise1 == "") self.noise1 = "plats/plat2.wav";
+ }
+ else if (self.sounds == 2) {
+ if (!self.noise || self.noise == "") self.noise = "plats/medplat1.wav";
+ if (!self.noise1 || self.noise1 == "") self.noise1 = "plats/medplat2.wav";
+ }
+ else if (self.sounds == 3) { // base door sound
+ if (!self.noise || self.noise == "") self.noise = "doors/hydro1.wav";
+ if (!self.noise1 || self.noise1 == "") self.noise1 = "doors/hydro2.wav";
+ }
+ else if (self.sounds == 4) { // func_train sounds
+ if (!self.noise || self.noise == "") self.noise = "plats/train1.wav";
+ if (!self.noise1 || self.noise1 == "") self.noise1 = "plats/train2.wav";
+ }
+ else {
+ if (!self.noise || self.noise == "") self.noise = "misc/null.wav";
+ if (!self.noise1 || self.noise1 == "") self.noise1 = "misc/null.wav";
+ }
+
+ precache_sound(self.noise);
+ precache_sound(self.noise1);
+
+
+ self.mangle = self.angles;
+ self.angles = '0 0 0';
+
+ self.classname = "plat";
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ setorigin (self, self.origin);
+ setmodel (self, self.model);
+ setsize (self, self.mins , self.maxs);
+
+ if (!self.speed)
+ self.speed = 150;
+
+// pos1 is the top position, pos2 is the bottom
+ self.pos1 = self.origin;
+ self.pos2 = self.origin;
+
+ if (self.height < 0)
+ {
+ negativeHeight = 1;
+ self.height = 0 - self.height;
+ }
+
+ if (self.height)
+ self.pos2_z = self.origin_z - self.height;
+ else
+ {
+ negativeHeight = 1;
+ self.height = self.size_z - 8;
+ self.pos2_z = self.origin_z - self.height;
+ }
+
+ if (self.spawnflags & DN_N_WAIT)
+ {
+ self.use = dn_and_wait_use;
+ self.blocked = dn_and_wait_crush;
+
+ if (negativeHeight == 1)
+ {
+ self.state = STATE_BOTTOM;
+ setorigin (self, self.pos2);
+ }
+ else
+ self.state = STATE_TOP;
+
+ if (!self.health)
+ self.health = 5;
+ }
+ else if (self.spawnflags & PLT_TOGGLE)
+ {
+ self.use = toggle_use;
+ self.blocked = toggle_crush;
+ if (negativeHeight == 1)
+ {
+ setorigin (self, self.pos2);
+ self.state = STATE_BOTTOM;
+ }
+ else
+ {
+ self.state = STATE_TOP;
+ }
+ }
+ else if (self.spawnflags & ELEVATOR)
+ {
+ self.elevatorLastUse = 0;
+
+ // allow the mapper to set self.wait, but don't allow a negative
+ // wait period -- iw
+ if (self.wait < 0)
+ self.wait = 0;
+
+ if (self.spawnflags & START_AT_TOP)
+ {
+ self.pos1 = self.origin;
+ self.pos2 = self.origin;
+ self.pos2_z = self.origin_z - (self.height * (self.cnt - 1));
+ self.elevatorOnFloor = self.cnt - 1;
+ self.elevatorToFloor = self.elevatorOnFloor;
+ }
+ else
+ {
+ self.pos1 = self.origin;
+ self.pos2 = self.origin;
+ self.pos1_z = self.origin_z + (self.height * (self.cnt - 1));
+ self.elevatorOnFloor = 0;
+ self.elevatorToFloor = self.elevatorOnFloor;
+ }
+
+ self.use = elvtr_use;
+ self.blocked = elvtr_crush;
+ }
+ else if (self.spawnflags & PLAT2)
+ {
+ plat2_spawn_inside_trigger (); // the "start moving" trigger
+ self.plat2Called = 0;
+ self.plat2LastMove = 0;
+ self.plat2GoTo = 0;
+ self.plat2GoTime = 0;
+ self.blocked = plat2_crush;
+
+ if (!self.delay)
+ self.delay = 3;
+
+ if (negativeHeight == 1)
+ {
+ self.state = STATE_BOTTOM;
+ // make sure START_AT_TOP isn't set. We need that...
+ self.spawnflags = PLAT2;
+ setorigin (self, self.pos2);
+ }
+ else
+ {
+ // default position is top.
+ self.spawnflags = self.spawnflags | START_AT_TOP;
+ self.state = STATE_TOP;
+ }
+
+ if (self.targetname != "")
+ {
+ self.use = plat2_use;
+ self.state = self.state + 10;
+ }
+ }
+
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/doors.qc

diff --git a/qc/doors.qc b/qc/doors.qc
new file mode 100644
index 0000000..b04f606
--- /dev/null
+++ b/qc/doors.qc
@@ -0,0 +1,945 @@
+
+float DOOR_START_OPEN = 1;
+float DOOR_DONT_LINK = 4;
+float DOOR_GOLD_KEY = 8;
+float DOOR_SILVER_KEY = 16;
+float DOOR_TOGGLE = 32;
+float DOOR_DOOM_STYLE_UNLOCK = 64;
+/*
+
+Doors are similar to buttons, but can spawn a fat trigger field around them
+to open without a touch, and they link together to form simultanious
+double/quad doors.
+
+Door.owner is the master door. If there is only one door, it points to itself.
+If multiple doors, all will point to a single one.
+
+Door.enemy chains from the master door through all doors linked in the chain.
+
+*/
+
+/*
+=============================================================================
+
+THINK FUNCTIONS
+
+=============================================================================
+*/
+
+void() door_go_down;
+void() door_go_up;
+
+void() door_blocked =
+{
+ T_Damage (other, self, self, self.dmg);
+
+// if a door has a negative wait, it would never come back if blocked,
+// so let it just squash the object to death real fast
+ if (self.wait >= 0)
+ {
+ if (self.state == STATE_DOWN)
+ door_go_up ();
+ else
+ door_go_down ();
+ }
+};
+
+
+void() door_hit_top =
+{
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ self.state = STATE_TOP;
+ if (self.spawnflags & DOOR_TOGGLE)
+ return; // don't come down automatically
+ self.think = door_go_down;
+ self.nextthink = self.ltime + self.wait;
+};
+
+void() door_hit_bottom =
+{
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ self.state = STATE_BOTTOM;
+};
+
+void() door_go_down =
+{
+ entity shadow;
+ entity oldself;
+
+ sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
+ if (self.max_health)
+ {
+ self.takedamage = DAMAGE_YES;
+ self.health = self.max_health;
+ }
+
+ self.state = STATE_DOWN;
+ SUB_CalcMove (self.pos1, self.speed, door_hit_bottom);
+
+ if(self.switchshadstyle) {
+ shadow = self.shadowcontroller;
+ oldself = self;
+ self = shadow;
+
+ if(oldself.spawnflags & DOOR_START_OPEN) {
+ shadow_fade_out();
+ shadow.shadowoff = 1;
+ } else {
+ shadow_fade_in();
+ shadow.shadowoff = 0;
+ }
+
+ self = oldself;
+
+ }
+};
+
+void() door_go_up =
+{
+ entity shadow;
+ entity oldself;
+
+ if (self.state == STATE_UP)
+ return; // allready going up
+
+ if (self.state == STATE_TOP)
+ { // reset top wait time
+ self.nextthink = self.ltime + self.wait;
+ return;
+ }
+
+ sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
+ self.state = STATE_UP;
+ SUB_CalcMove (self.pos2, self.speed, door_hit_top);
+
+ SUB_UseTargets();
+
+ if(self.switchshadstyle) {
+ shadow = self.shadowcontroller;
+ oldself = self;
+ self = shadow;
+
+ if(oldself.spawnflags & DOOR_START_OPEN) {
+ shadow_fade_in();
+ shadow.shadowoff = 0;
+ } else {
+ shadow_fade_out();
+ shadow.shadowoff = 1;
+ }
+
+ self = oldself;
+ }
+};
+
+
+void() door_group_go_down = {
+ local entity oself, starte;
+
+ oself = self;
+ starte = self;
+
+ do
+ {
+ door_go_down ();
+ self = self.enemy;
+ } while ( (self != starte) && (self != world) );
+ self = oself;
+
+};
+
+void() door_group_go_up = {
+ local entity oself, starte;
+
+ oself = self;
+ starte = self;
+
+ do
+ {
+ door_go_up ();
+ self = self.enemy;
+ } while ( (self != starte) && (self != world) );
+
+ self = oself;
+};
+
+/*
+=============================================================================
+
+ACTIVATION FUNCTIONS
+
+=============================================================================
+*/
+
+void() door_fire =
+{
+
+ if (self.owner != self)
+ objerror ("door_fire: self.owner != self");
+
+ if (self.estate != STATE_ACTIVE)
+ return;
+// self.noise4 is now played in keylock_try_to_unlock -- iw
+
+ self.message = string_null; // no more message
+
+
+ if (self.spawnflags & DOOR_TOGGLE)
+ {
+ if (self.state == STATE_UP || self.state == STATE_TOP)
+ {
+ door_group_go_down();
+ return;
+ }
+ }
+
+ // trigger all paired doors
+ door_group_go_up();
+};
+
+
+void() door_use =
+{
+ local entity oself;
+
+ self.message = ""; // door message are for touch only
+ self.owner.message = "";
+ self.enemy.message = "";
+ oself = self;
+ self = self.owner;
+ door_fire ();
+ self = oself;
+};
+
+
+void() door_trigger_touch =
+{
+ if (other.health <= 0)
+ return;
+
+ if (other.movetype == MOVETYPE_NOCLIP) // from copper -- dumptruck_ds
+ return;
+
+ if (time < self.attack_finished)
+ return;
+ self.attack_finished = time + 1;
+
+ activator = other;
+
+ self = self.owner;
+ door_use ();
+};
+
+
+void() door_killed =
+{
+ local entity oself;
+
+ oself = self;
+ self = self.owner;
+ self.health = self.max_health;
+ self.takedamage = DAMAGE_NO; // wil be reset upon return
+ door_use ();
+ self = oself;
+};
+
+
+/*
+================
+door_unlock
+
+Perform the actions which should be performed when self is successfully
+unlocked with a key.
+
+This function exists so that it can be passed as an argument to the new
+keylock_try_to_unlock function. This code was previously part of the
+door_touch function. -- iw
+================
+*/
+void() door_unlock =
+{
+ if (!(self.spawnflags & DOOR_DOOM_STYLE_UNLOCK))
+ {
+ self.touch = SUB_Null;
+ if (self.enemy)
+ self.enemy.touch = SUB_Null; // get paired door
+ }
+ door_use ();
+};
+
+
+/*
+================
+door_touch
+
+Prints messages and opens key doors
+================
+*/
+void() door_touch =
+{
+ // if (other.classname != "player")
+ // return;
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ if (self.owner.attack_finished > time)
+ return;
+
+ self.owner.attack_finished = time + 2;
+
+ if (self.owner.message != "")
+ {
+ centerprint (other, self.owner.message);
+ sound (other, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
+ }
+
+// key door stuff
+ if (!keylock_has_key_set ())
+ return;
+
+ keylock_try_to_unlock (other, "", door_unlock);
+};
+
+
+
+/*
+=============================================================================
+ENTITY STATE FUNCTIONS
+=============================================================================
+*/
+
+void(entity e, float closealldoors) door_estate_lock = {
+ local entity oself, next;
+
+ if (e.owner.estate == STATE_INACTIVE) return;
+
+ // blocks linked doors from updating the same owner repeatedly
+ if (e.owner.last_setstate == self && e.owner.last_setstate_frame == framecount) return;
+
+ oself = self;
+ self = e.owner;
+
+ self.estate = STATE_INACTIVE;
+
+ self.last_setstate = oself;
+ self.last_setstate_frame = framecount;
+
+ self.prevstate = self.state;
+
+ if (self.state == STATE_UP || self.state == STATE_TOP) {
+ if (
+ // don't close wait -1 nor toggleable doors...
+ !(self.wait == -1 || (self.spawnflags & DOOR_TOGGLE))
+ // ...unless the trigger_setstate has a "Close all doors" spawnflag on
+ || closealldoors
+ )
+ door_group_go_down();
+
+ }
+
+ if (self.max_health) {
+ next = self;
+ do {
+ //e.health = 0;
+ next.takedamage = DAMAGE_NO;
+ next = next.enemy;
+ } while ( (next != self) && (next != world) );
+ }
+
+ self = oself;
+
+}
+
+void(entity e, float openalldoors) door_estate_unlock = {
+ local entity oself, next;
+
+ if (e.owner.estate == STATE_ACTIVE) return;
+
+ // blocks linked doors from updating the same owner repeatedly
+ if (e.owner.last_setstate == self && e.owner.last_setstate_frame == framecount) return;
+
+ oself = self;
+ self = e.owner;
+
+ self.last_setstate = oself;
+ self.last_setstate_frame = framecount;
+
+ if (self.prevstate == STATE_UP || self.prevstate == STATE_TOP) {
+ if (
+ (self.wait == -1 || (self.spawnflags & DOOR_TOGGLE))
+ && openalldoors
+ ) door_group_go_up();
+ }
+
+ if (self.max_health) {
+ next = self;
+ do {
+ next.health = next.max_health;
+ next.takedamage = DAMAGE_YES;
+ next = next.enemy;
+ } while ( (next != self) && (next != world) );
+ }
+
+ self.estate = STATE_ACTIVE;
+ self = oself;
+}
+
+
+/*
+=============================================================================
+
+SPAWNING FUNCTIONS
+
+=============================================================================
+*/
+
+
+entity(vector fmins, vector fmaxs) spawn_field =
+{
+ local entity trigger;
+ local vector t1, t2;
+
+ trigger = spawn();
+ trigger.movetype = MOVETYPE_NONE;
+ trigger.solid = SOLID_TRIGGER;
+ trigger.owner = self;
+ trigger.touch = door_trigger_touch;
+
+ t1 = fmins;
+ t2 = fmaxs;
+ setsize (trigger, t1 - '60 60 8', t2 + '60 60 8');
+ return (trigger);
+};
+
+
+float (entity e1, entity e2) EntitiesTouching =
+{
+ if (e1.mins_x > e2.maxs_x)
+ return FALSE;
+ if (e1.mins_y > e2.maxs_y)
+ return FALSE;
+ if (e1.mins_z > e2.maxs_z)
+ return FALSE;
+ if (e1.maxs_x < e2.mins_x)
+ return FALSE;
+ if (e1.maxs_y < e2.mins_y)
+ return FALSE;
+ if (e1.maxs_z < e2.mins_z)
+ return FALSE;
+ return TRUE;
+};
+
+
+/*
+=============
+LinkDoors
+
+
+=============
+*/
+void() LinkDoors =
+{
+ local entity t, starte;
+ local vector cmins, cmaxs;
+
+ if (self.enemy)
+ return; // already linked by another door
+ if (self.spawnflags & 4)
+ {
+ self.owner = self.enemy = self;
+ return; // don't want to link this door
+ }
+
+ cmins = self.mins;
+ cmaxs = self.maxs;
+
+ starte = self;
+ t = self;
+
+ do
+ {
+ self.owner = starte; // master door
+
+ if (self.health)
+ starte.health = self.health;
+ if (self.targetname != "")
+ starte.targetname = self.targetname;
+ if (self.message != "")
+ starte.message = self.message;
+
+ t = find (t, classname, self.classname);
+ if (!t)
+ {
+ self.enemy = starte; // make the chain a loop
+
+ // shootable, fired, or key doors just needed the owner/enemy links,
+ // they don't spawn a field
+
+ self = self.owner;
+
+ if (self.health)
+ return;
+ if (self.targetname != "")
+ return;
+ if (keylock_has_key_set ())
+ return;
+
+ self.owner.trigger_field = spawn_field(cmins, cmaxs);
+
+ return;
+ }
+
+ if (EntitiesTouching(self,t))
+ {
+ if (t.enemy)
+ objerror ("cross connected doors");
+
+ self.enemy = t;
+ self = t;
+
+ if (t.mins_x < cmins_x)
+ cmins_x = t.mins_x;
+ if (t.mins_y < cmins_y)
+ cmins_y = t.mins_y;
+ if (t.mins_z < cmins_z)
+ cmins_z = t.mins_z;
+ if (t.maxs_x > cmaxs_x)
+ cmaxs_x = t.maxs_x;
+ if (t.maxs_y > cmaxs_y)
+ cmaxs_y = t.maxs_y;
+ if (t.maxs_z > cmaxs_z)
+ cmaxs_z = t.maxs_z;
+ }
+ } while (1 );
+
+};
+
+
+/*QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK GOLD_KEY SILVER_KEY TOGGLE X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+if two doors touch, they are assumed to be connected and operate as a unit.
+
+TOGGLE causes the door to wait in both the start and end states for a trigger event.
+
+START_OPEN causes the door to move to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors).
+
+Key doors are always wait -1.
+
+"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet
+"angle" determines the opening direction
+"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door.
+"health" if set, door must be shot open
+"speed" movement speed (100 default)
+"wait" wait before returning (3 default, -1 = never return)
+"lip" lip remaining at end of move (8 default)
+"dmg" damage to inflict when blocked (2 default)
+"cnt" if 1, leave a used key in the player's inventory (0 default)
+"keyname" if set, this is the keyname of the item_key_custom which unlocks this entity
+"noise1" sound file for the "stop moving" sound (if set, overrides "sounds")
+"noise2" sound file for the "move" sound (if set, overrides "sounds")
+"noise3" sound file for the "key required" sound (default is per worldtype)
+"noise4" sound file for the "key used" sound (default is per worldtype)
+"sounds"
+0) no sound
+1) stone
+2) base
+3) stone chain
+4) screechy metal
+*/
+
+void() func_door =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ local string default_noise1;
+ local string default_noise2;
+ entity shadow;
+ entity oldself;
+
+// self.noise3 and self.noise4 can now be overridden by the mapper, but
+// will be set to default values in keylock_init if necessary -- iw
+ keylock_init ();
+
+// self.noise1 and self.noise2 can now be overridden by the mapper -- iw
+ default_noise1 = "misc/null.wav";
+ default_noise2 = "misc/null.wav";
+ if (self.sounds == 1)
+ {
+ default_noise1 = "doors/drclos4.wav";
+ default_noise2 = "doors/doormv1.wav";
+ }
+ if (self.sounds == 2)
+ {
+ default_noise1 = "doors/hydro2.wav";
+ default_noise2 = "doors/hydro1.wav";
+ }
+ if (self.sounds == 3)
+ {
+ default_noise1 = "doors/stndr2.wav";
+ default_noise2 = "doors/stndr1.wav";
+ }
+ if (self.sounds == 4)
+ {
+ default_noise1 = "doors/ddoor2.wav";
+ default_noise2 = "doors/ddoor1.wav";
+ }
+
+ if (self.noise1 == "")
+ self.noise1 = default_noise1;
+ if (self.noise2 == "")
+ self.noise2 = default_noise2;
+
+ precache_sound (self.noise1);
+ precache_sound (self.noise2);
+
+ SetMovedir ();
+
+ self.max_health = self.health;
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ setorigin (self, self.origin);
+ setmodel (self, self.model);
+ //self.classname = "door";
+
+ self.blocked = door_blocked;
+ self.use = door_use;
+
+ if (self.spawnflags & DOOR_SILVER_KEY){
+ keylock_set_silver_key ();
+
+ if (self.keyname != "") {
+ self.netname = self.keyname;
+ self.keyname = "";
+ }
+ }
+ if (self.spawnflags & DOOR_GOLD_KEY){
+ keylock_set_gold_key ();
+
+ if (self.keyname != "") {
+ self.netname = self.keyname;
+ self.keyname = "";
+ }
+ }
+
+// support for item_key_custom -- iw
+ if (self.keyname != "")
+ {
+ keylock_set_custom_key (self.keyname);
+ self.keyname = ""; // this should not be referenced again
+ }
+
+ if (!self.speed)
+ self.speed = 100;
+ if (!self.wait)
+ self.wait = 3;
+ if (!self.lip)
+ self.lip = 8;
+ if (!self.dmg)
+ self.dmg = 2;
+
+ self.pos1 = self.origin;
+ self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
+
+// DOOR_START_OPEN is to allow an entity to be lighted in the closed position
+// but spawn in the open position
+ if (self.spawnflags & DOOR_START_OPEN)
+ {
+ setorigin (self, self.pos2);
+ self.pos2 = self.pos1;
+ self.pos1 = self.origin;
+ }
+
+ self.state = STATE_BOTTOM;
+
+ if (self.health)
+ {
+ self.takedamage = DAMAGE_YES;
+ self.th_die = door_killed;
+ }
+
+ if (self.spawnflags & DOOR_DOOM_STYLE_UNLOCK)
+ self.cnt = 1;
+
+ if (keylock_has_key_set ())
+ {
+ if (!(self.spawnflags & DOOR_DOOM_STYLE_UNLOCK))
+ {
+ self.wait = -1;
+ }
+ }
+ self.touch = door_touch;
+
+// LinkDoors can't be done until all of the doors have been spawned, so
+// the sizes can be detected properly.
+ self.think = LinkDoors;
+ self.nextthink = self.ltime + 0.1;
+
+ // creates a shadow controller entity for the door if it has switchable shadows
+ if(self.switchshadstyle) {
+
+ shadow = spawn();
+
+ self.shadowcontroller = shadow;
+
+ shadow.classname = "misc_shadowcontroller";
+ shadow.switchshadstyle = self.switchshadstyle;
+ shadow.speed = vlen(self.pos2 - self.pos1) / self.speed;
+
+ if(self.spawnflags & DOOR_START_OPEN) shadow.spawnflags = 1;
+ else shadow.spawnflags = 0;
+
+
+ oldself = self;
+
+ self = shadow;
+ misc_shadowcontroller();
+
+ self = oldself;
+ }
+};
+
+/*
+=============================================================================
+
+SECRET DOORS
+
+=============================================================================
+*/
+
+void() fd_secret_move1;
+void() fd_secret_move2;
+void() fd_secret_move3;
+void() fd_secret_move4;
+void() fd_secret_move5;
+void() fd_secret_move6;
+void() fd_secret_done;
+
+float SECRET_OPEN_ONCE = 1; // stays open
+float SECRET_1ST_LEFT = 2; // 1st move is left of arrow
+float SECRET_1ST_DOWN = 4; // 1st move is down from arrow
+float SECRET_NO_SHOOT = 8; // only opened by trigger
+float SECRET_YES_SHOOT = 16; // shootable even if targeted
+
+
+void () fd_secret_use =
+{
+ local float temp;
+
+ self.health = 10000;
+
+ // exit if still moving around...
+ if (self.origin != self.oldorigin)
+ return;
+
+ self.message = string_null; // no more message
+
+ SUB_UseTargets(); // fire all targets / killtargets
+
+ if (!(self.spawnflags & SECRET_NO_SHOOT))
+ {
+ self.th_pain = SUB_NullPain;
+ self.takedamage = DAMAGE_NO;
+ }
+ self.velocity = '0 0 0';
+
+ // Make a sound, wait a little...
+
+ sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ self.nextthink = self.ltime + 0.1;
+
+ temp = 1 - (self.spawnflags & SECRET_1ST_LEFT); // 1 or -1
+ makevectors(self.mangle);
+
+ if (!self.t_width)
+ {
+ if (self.spawnflags & SECRET_1ST_DOWN)
+ self. t_width = fabs(v_up * self.size);
+ else
+ self. t_width = fabs(v_right * self.size);
+ }
+
+ if (!self.t_length)
+ self. t_length = fabs(v_forward * self.size);
+
+ if (self.spawnflags & SECRET_1ST_DOWN)
+ self.dest1 = self.origin - v_up * self.t_width;
+ else
+ self.dest1 = self.origin + v_right * (self.t_width * temp);
+
+ self.dest2 = self.dest1 + v_forward * self.t_length;
+ SUB_CalcMove(self.dest1, self.speed, fd_secret_move1);
+ sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
+};
+
+void(entity attacker, float damage) fd_secret_pain = { fd_secret_use(); };
+
+// Wait after first movement...
+void () fd_secret_move1 =
+{
+ self.nextthink = self.ltime + 1.0;
+ self.think = fd_secret_move2;
+ sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
+};
+
+// Start moving sideways w/sound...
+void () fd_secret_move2 =
+{
+ sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
+ SUB_CalcMove(self.dest2, self.speed, fd_secret_move3);
+};
+
+// Wait here until time to go back...
+void () fd_secret_move3 =
+{
+ sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
+ if (!(self.spawnflags & SECRET_OPEN_ONCE))
+ {
+ self.nextthink = self.ltime + self.wait;
+ self.think = fd_secret_move4;
+ }
+};
+
+// Move backward...
+void () fd_secret_move4 =
+{
+ sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
+ SUB_CalcMove(self.dest1, self.speed, fd_secret_move5);
+};
+
+// Wait 1 second...
+void () fd_secret_move5 =
+{
+ self.nextthink = self.ltime + 1.0;
+ self.think = fd_secret_move6;
+ sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
+};
+
+void () fd_secret_move6 =
+{
+ sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
+ SUB_CalcMove(self.oldorigin, self.speed, fd_secret_done);
+};
+
+void () fd_secret_done =
+{
+ if (!self.targetname || self.spawnflags&SECRET_YES_SHOOT)
+ {
+ self.health = 10000;
+ self.takedamage = DAMAGE_YES;
+ self.th_pain = fd_secret_pain;
+ }
+ sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
+};
+
+void () secret_blocked =
+{
+ if (time < self.attack_finished)
+ return;
+ self.attack_finished = time + 0.5;
+ T_Damage (other, self, self, self.dmg);
+};
+
+/*
+================
+ouch
+
+Prints messages
+================
+*/
+void() secret_touch =
+{
+
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ if (self.attack_finished > time)
+ return;
+
+ self.attack_finished = time + 2;
+
+ if (self.message != "")
+ {
+ centerprint (other, self.message);
+ sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
+ }
+};
+
+
+/*QUAKED func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Basic secret door. Slides back, then to the side. Angle determines direction.
+wait = # of seconds before coming back
+1st_left = 1st move is left of arrow
+1st_down = 1st move is down from arrow
+always_shoot = even if targeted, keep shootable
+t_width = override WIDTH to move back (or height if going down)
+t_length = override LENGTH to move sideways
+"dmg" damage to inflict when blocked (2 default)
+
+If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage.
+"sounds"
+1) medieval
+2) metal
+3) base
+*/
+
+void () func_door_secret =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.sounds == 0)
+ self.sounds = 3;
+ if (self.sounds == 1)
+ {
+ precache_sound ("doors/latch2.wav");
+ precache_sound ("doors/winch2.wav");
+ precache_sound ("doors/drclos4.wav");
+ self.noise1 = "doors/latch2.wav";
+ self.noise2 = "doors/winch2.wav";
+ self.noise3 = "doors/drclos4.wav";
+ }
+ if (self.sounds == 2)
+ {
+ precache_sound ("doors/airdoor1.wav");
+ precache_sound ("doors/airdoor2.wav");
+ self.noise2 = "doors/airdoor1.wav";
+ self.noise1 = "doors/airdoor2.wav";
+ self.noise3 = "doors/airdoor2.wav";
+ }
+ if (self.sounds == 3)
+ {
+ precache_sound ("doors/basesec1.wav");
+ precache_sound ("doors/basesec2.wav");
+ self.noise2 = "doors/basesec1.wav";
+ self.noise1 = "doors/basesec2.wav";
+ self.noise3 = "doors/basesec2.wav";
+ }
+
+ if (!self.dmg)
+ self.dmg = 2;
+
+ // Magic formula...
+ self.mangle = self.angles;
+ self.angles = '0 0 0';
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ //self.classname = "door";
+ setmodel (self, self.model);
+ setorigin (self, self.origin);
+
+ self.touch = secret_touch;
+ self.blocked = secret_blocked;
+ self.speed = 50;
+ self.use = fd_secret_use;
+ if ( !self.targetname || self.spawnflags&SECRET_YES_SHOOT)
+ {
+ self.health = 10000;
+ self.takedamage = DAMAGE_YES;
+ self.th_pain = fd_secret_pain;
+ self.th_die = fd_secret_use;
+ }
+ self.oldorigin = self.origin;
+ if (!self.wait)
+ self.wait = 5; // 5 seconds before closing
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/dtmisc.qc

diff --git a/qc/dtmisc.qc b/qc/dtmisc.qc
new file mode 100644
index 0000000..c850f83
--- /dev/null
+++ b/qc/dtmisc.qc
@@ -0,0 +1,1176 @@
+//a collection of various pieces of mods and some new code -- dumptruck_ds
+
+/* Miscelanneous QuickC program
+ Copyright (c)1996 Hipnotic Interactive, Inc.
+ All rights reserved.
+ Distributed (unsupported) on 3.12.97
+*/
+
+void() play_sound_use =
+ {
+ if (self.spawnflags & 1)
+ {
+ if (self.state == 0)
+ {
+ self.state = 1;
+ sound (self, self.impulse, self.noise, self.volume, self.speed);
+ }
+ else
+ {
+ self.state = 0;
+ sound (self, self.impulse, "misc/null.wav", self.volume, self.speed);
+ }
+ }
+ else
+ {
+ sound (self, self.impulse, self.noise, self.volume, self.speed);
+ }
+ };
+
+void() PlaySoundThink =
+ {
+ local float t;
+ t = self.wait * random();
+ if (t < self.delay)
+ t = self.delay;
+ self.nextthink = time + t;
+ play_sound_use();
+ };
+
+/*QUAKED play_sound_triggered (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) toggle
+play a sound when it is used
+"toggle" determines whether sound should be stopped when triggered again
+"volume" how loud (1 default full volume)
+"noise" sound to play
+"impulse" channel on which to play sound (0-7) (0 automatic is default)
+"speed" attenuation factor
+ -1 - no attenuation
+ 1 - normal
+ 2 - idle
+ 3 - static
+*/
+void() play_sound_triggered =
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.noise) //dumptruck_ds
+ {
+ objerror ("no soundfile set in noise!\n");
+ remove(self);
+ return;
+ }
+
+ precache_sound (self.noise);
+ precache_sound ("misc/null.wav");
+ if (self.volume == 0)
+ self.volume = 1;
+ if (self.speed == 0)
+ self.speed = 1;
+ if (self.speed == -1)
+ // self.speed = 0;
+ self.speed = ATTN_NONE;
+ if (self.spawnflags & 1)
+ if (self.impulse == 0)
+ self.impulse = 7;
+ self.use = play_sound_use;
+ };
+
+/*QUAKED play_sound (0.3 0.1 0.6) (-8 -8 -8) (8 8 8)
+play a sound on a periodic basis
+"volume" how loud (1 default full volume)
+"noise" sound to play
+"wait" random time between sounds (default 20)
+"delay" minimum delay between sounds (default 2)
+"impulse" channel on which to play sound (0-7) (0 automatic is default)
+"speed" attenuation factor
+ -1 - no attenuation
+ 1 - normal
+ 2 - idle
+ 3 - static
+*/
+void() play_sound =
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ local float t;
+
+ if (!self.noise) //dumptruck_ds
+ {
+ objerror ("no soundfile set in noise!\n");
+ remove(self);
+ return;
+ }
+
+
+ play_sound_triggered();
+ if (self.wait == 0)
+ self.wait = 20;
+ if (self.delay == 0)
+ self.delay = 2;
+ self.think = PlaySoundThink;
+ t = self.wait * random();
+ if (t < self.delay)
+ t = self.delay;
+ self.nextthink = time + t;
+ };
+
+
+ //johnfitz -- ambient_general (this is from Rubicon Rumble dev kit)
+
+/*QUAKED ambient_general (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Plays any looped sound
+
+Keys:
+
+"noise" is the wav file to play
+
+"volume" default 1
+
+"speed" attenuation, default 3
+*/
+void () ambient_general =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.noise) //dumptruck_ds
+ {
+ objerror ("no soundfile set in noise!\n");
+ remove(self);
+ return;
+ }
+
+ precache_sound (self.noise);
+ if (!self.speed)
+ {
+ self.speed = ATTN_NORM;
+ }
+ if (self.speed == 0)
+ self.speed = 1;
+ if (self.speed == -1)
+ // self.speed = 0;
+ self.speed = ATTN_NONE;
+ if (!self.volume)
+ {
+ self.volume = 0.5;
+ }
+ ambientsound (self.origin, self.noise, self.volume, self.speed);
+ remove(self);
+};
+//johnfitz
+
+/*QUAKED tele_fog (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
+
+When triggered, tele_fog shows the teleport particle effects and sounds.
+
+Use this when killtageting an entity if the player can see.
+
+*/
+
+void () play_tfog = //thanks Khreathor -- dumptruck_ds
+
+{
+ spawn_tfog(self.origin);
+}
+
+void() tele_fog =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.use = play_tfog;
+};
+
+/*QUAKED play_tele (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
+
+When triggered, tele_fog shows the teleport particle effects and sounds.
+Same os tele_fog.
+
+Use this when killtageting an entity if the player can see.
+
+*/
+void() play_tele = //same as tele_fog, added for "play_xxxx" consistancy
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.use = play_tfog;
+};
+
+/*QUAKED play_explosion (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
+
+When triggered, creates a explosion at it's origin. Causes damage.
+
+*/
+
+void () play_explosion_fx = //thanks Khreathor -- dumptruck_ds
+
+{
+ self.owner = self; // GrenadeExplode uses self.owner as the attacker -- iw
+ GrenadeExplode();
+}
+
+void() play_explosion =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.use = play_explosion_fx;
+};
+
+/*QUAKED play_lavasplash (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
+
+When triggered, plays the lavasplash effect from E1M7.
+
+Use noise key for a custom sound.
+
+*/
+
+void () play_lavasplash_fx = //thanks Khreathor -- dumptruck_ds
+{
+ if (self.noise != "")
+ {
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ }
+ else
+ {
+ sound (self, CHAN_AUTO, "boss1/out1.wav", 1, ATTN_NORM);
+ }
+WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
+WriteCoord (MSG_BROADCAST, self.origin_x);
+WriteCoord (MSG_BROADCAST, self.origin_y);
+WriteCoord (MSG_BROADCAST, self.origin_z);
+};
+
+void () play_lavasplash =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.noise != "") precache_sound (self.noise);
+ precache_sound("boss1/out1.wav");
+ self.use = play_lavasplash_fx;
+};
+
+/*QUAKED meat_shower (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
+
+When triggered, plays a gib effect.
+
+Use style 0 for normal and 1 for extra large. fly_sound 0 is silent, 1 for regular gib sounds.
+
+*/
+
+void () play_meatspray = //-- dumptruck_ds -- thanks to Spike for helping with errors
+{
+ if (self.style == 1)
+ {
+ ThrowGib ("progs/gib1.mdl", random()*-80);
+ ThrowGib ("progs/gib2.mdl", random()*-80);
+ ThrowGib ("progs/gib3.mdl", random()*-80);
+ ThrowGib ("progs/gib1.mdl", random()*-75);
+ ThrowGib ("progs/gib2.mdl", random()*-75);
+ ThrowGib ("progs/gib3.mdl", random()*-75);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", random()*-65);
+ ThrowGib ("progs/gib2.mdl", random()*-65);
+ ThrowGib ("progs/gib3.mdl", random()*-65);
+ }
+ {
+ if (self.fly_sound != 1)
+ return;
+ }
+ {
+ if (random() < 0.5)
+ sound (self, CHAN_VOICE, "player/gib.wav", 1, ATTN_NORM);
+ else
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+}
+};
+
+void() meat_shower =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.use = play_meatspray;
+}
+
+/*QUAKED play_gibs (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
+
+When triggered, plays a gib effect. Same as meat_shower.
+
+Use style 0 for normal and 1 for extra large. fly_sound 0 is silent, 1 for regular gib sounds.
+
+*/
+void() play_gibs = //same as meat_shower, added for "play_xxxx" consistancy
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.use = play_meatspray;
+}
+
+void() mflash_use =
+{
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ if (self.noise != "")
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+};
+
+/*QUAKED play_mflash (0 .5 .8) (-8 -8 -8) (8 8 8)
+triggable muzzle flash effect entity
+*/
+
+void() play_mflash =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/s_null.spr");
+ if (self.noise != "") precache_sound (self.noise);
+
+ setmodel (self, "progs/s_null.spr");
+ setorigin (self, self.origin);
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_NOT;
+ setsize (self, '0 0 0', '0 0 0');
+ self.use = mflash_use;
+};
+
+//
+// play_bfield triggerable effect
+//
+
+void() bfield_toggle =
+{
+ if (!self.state)
+ {
+ self.state = 1;
+ self.effects = self.effects | EF_BRIGHTFIELD;
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ }
+ else
+ {
+ self.state = 0;
+ self.effects = self.effects - (self.effects & EF_BRIGHTFIELD);
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ }
+};
+
+/*QUAKED play_bfield (0 .5 .8) (-8 -8 -8) (8 8 8)
+a triggerable, spherical field of yellow particles
+state 1 = start on
+*/
+
+void() play_bfield =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/s_null.spr");
+ if (self.noise != "") precache_sound (self.noise);
+
+ setmodel (self, "progs/s_null.spr");
+ setorigin( self, self.origin);
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_NOT;
+ setsize (self, '0 0 0', '0 0 0');
+ if (self.state)
+ self.effects = self.effects | EF_BRIGHTFIELD;
+ self.use = bfield_toggle;
+};
+
+//
+// play_brlight triggerable effect
+//
+
+void() brlight_toggle = //dumptruck_ds -- thanks to c0burn
+{
+ if (!self.state)
+ {
+ self.state = 1;
+ self.effects = self.effects | EF_BRIGHTLIGHT;
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ }
+ else
+ {
+ self.state = 0;
+ self.effects = self.effects - (self.effects & EF_BRIGHTLIGHT);
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ }
+};
+
+/*QUAKED play_brlight (0 .5 .8) (-8 -8 -8) (8 8 8)
+a triggerable bright lighting effect
+state 1 = start on
+*/
+
+void() play_brlight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/s_null.spr");
+ if (self.noise != "") precache_sound (self.noise);
+
+ setmodel (self, "progs/s_null.spr");
+ setorigin (self, self.origin);
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_NOT;
+ setsize (self, '0 0 0', '0 0 0');
+ if (self.state)
+ self.effects = self.effects | EF_BRIGHTLIGHT;
+ self.use = brlight_toggle;
+};
+//
+// play_dimlight triggerable effect
+//
+void() dim_toggle =
+{
+ if (!self.state)
+ {
+ self.state = 1;
+ self.effects = self.effects | EF_DIMLIGHT;
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ }
+ else
+ {
+ self.state = 0;
+ self.effects = self.effects - (self.effects & EF_DIMLIGHT);
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ }
+};
+
+/*QUAKED play_dimlight (0 .5 .8) (-8 -8 -8) (8 8 8)
+a triggerable lighting effect
+state 1 = start on
+*/
+
+void() play_dimlight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/s_null.spr");
+ if (self.noise != "") precache_sound (self.noise);
+
+ setmodel (self, "progs/s_null.spr");
+ // setorigin (self, self.origin);
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_NOT;
+ setsize (self, '0 0 0', '0 0 0');
+ if (self.state)
+ self.effects = self.effects | EF_DIMLIGHT;
+ setorigin (self, self.origin);
+ self.use = dim_toggle;
+};
+
+/* misc gore */
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+/*
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+deadstuff version 1.0 - tony collen - manero@canweb.net - EfNet IRC #QuakeEd or #Trinity
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+*/
+
+/*QUAKED gib_head_demon (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_demon.mdl");
+}
+*/
+void() gib_head_demon =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_demon.mdl");
+ setmodel(self, "progs/h_demon.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-13.64 -16.77 -0.11','17.44 16.22 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_dog (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_dog.mdl");
+}
+*/
+void() gib_head_dog =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_dog.mdl");
+ setmodel(self, "progs/h_dog.mdl");
+ self.frame = 0; //was 1 -- dumptruck_ds
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-9.66 -11.89 -0.2','6.57 7.96 13.29');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_army (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_guard.mdl");
+}
+*/
+void() gib_head_army =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_guard.mdl");
+ setmodel(self, "progs/h_guard.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-9.67 -8.27 -0.28','4.05 4.8 13.41');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_hell_knight (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_hellkn.mdl");
+}*/
+void() gib_head_hell_knight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_hellkn.mdl");
+ setmodel(self, "progs/h_hellkn.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-7.9 -12.97 -0.63','10.55 8.87 21.06');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_knight (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_knight.mdl");
+}*/
+void() gib_head_knight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_knight.mdl");
+ setmodel(self, "progs/h_knight.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-8.17 -7.47 -0.13','8.36 6.5 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_enforcer (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_mega.mdl");
+}
+*/
+void() gib_head_enforcer =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_mega.mdl");
+ setmodel(self, "progs/h_mega.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-10.63 -10.23 -0.05','9.27 8.25 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_ogre (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_ogre.mdl");
+}*/
+void() gib_head_ogre =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_ogre.mdl");
+ setmodel(self, "progs/h_ogre.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-12.35 -15.7 -0.17','10.67 13.88 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_player (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_player.mdl");
+}*/
+void() gib_head_player =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_player.mdl");
+ setmodel(self, "progs/h_player.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-9.67 -12.38 -2.1','11.49 50.7 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_shalrath (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_shal.mdl");
+}*/
+void() gib_head_shalrath =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_shal.mdl");
+ setmodel(self, "progs/h_shal.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-19.85 -19.09 -1.44','13.72 16.8 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_shambler (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_shams.mdl");
+}*/
+void() gib_head_shambler =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_shams.mdl");
+ setmodel(self, "progs/h_shams.mdl");
+ self.frame = 0; //was 1, caused an error -- dumptruck_ds
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-15.15 -20.638 -0.45','21.44 21.76 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_wizard (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_wizard.mdl");
+}*/
+void() gib_head_wizard =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_wizard.mdl");
+ setmodel(self, "progs/h_wizard.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-10.41 -8.66 -0.54','6.52 10.82 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_misc_1 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/gib1.mdl");
+}*/
+void() gib_misc_1 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/gib1.mdl");
+ setmodel(self, "progs/gib1.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-3.57 -8.06 -3.34','3.69 8.31 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_misc_2 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/gib2.mdl");
+}*/
+void() gib_misc_2 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/gib2.mdl");
+ setmodel(self, "progs/gib2.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-12.68 -14.83 -6.19','13.53 14.57 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_misc_3 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/gib3.mdl");
+}*/
+void() gib_misc_3 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/gib3.mdl");
+ setmodel(self, "progs/gib3.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-18.95 -15.92 -3.13','13.17 15.66 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+/* END Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+// /*==============================================================================
+// func_fall from RennyC
+//
+// A brush that drops and fades away when touched or triggered.
+//
+// dumptruck_ds
+// noise = sound to play when triggered
+// wait = wait this long before falling
+// ==============================================================================*/
+float DONT_FADE = 1;
+float SILENT = 2;
+
+void() func_fall_think =
+{
+ if (self.cnt == TRUE && self.attack_finished < time)
+ {
+ self.solid = SOLID_BBOX;
+ // self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_TOSS;
+
+ if (!(self.spawnflags & DONT_FADE))
+ {
+
+ if (self.alpha > 0.1)
+ self.alpha = self.alpha - 0.03;
+ else
+ {
+ remove(self);
+ return;
+ }
+ }
+ }
+ self.nextthink = time + 0.1;
+};
+
+void() fall_touch =
+{
+ if (other.classname == "player")
+ {
+ if (!(other.flags & FL_ONGROUND))
+ other.flags = other.flags | FL_ONGROUND;
+ }
+
+ else if (other.flags & FL_MONSTER)
+ T_Damage (other, self, other, 50000);
+
+ else
+ return;
+
+ if (self.cnt == TRUE)
+ return;
+
+ self.attack_finished = time + self.wait;
+ self.cnt = TRUE;
+
+ if (!(self.spawnflags & SILENT))
+ {
+ if (self.noise != "")
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ else
+ sound (self, CHAN_AUTO, "buttons/switch21.wav", 1, ATTN_NORM);
+ }
+};
+
+void() fall_use = // thanks again RennyC for help on revisions --dumptruck_ds
+ {
+ self.attack_finished = time + self.wait;
+ self.cnt = TRUE;
+
+ if (self.noise != "")
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ else
+ sound (self, CHAN_AUTO, "buttons/switch21.wav", 1, ATTN_NORM);
+ };
+
+/*QUAKED func_fall (0 .5 .8) ? DONT_FADE X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+A brush that drops and fades away when touched and/or triggered.
+Add some spice to your jumping puzzles or other scripted sequences!
+Monsters will not trigger func_fall but will be gibbed if one falls on them.
+NOTE: When a func_fall brush touches another brush or entity it will stop, which can look odd in certain situations.
+noise = sound to play when triggered, the default is a switch sound.
+wait = wait this long before falling.
+Use the DONT_FADE spawnflag if desired.
+
+Falling brush upon touch
+*/
+
+void() func_fall =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound("buttons/switch21.wav");
+ if (self.noise != "") precache_sound (self.noise);
+
+
+ self.alpha = 1;
+ self.cnt = FALSE;
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ self.think = func_fall_think;
+ self.nextthink = time;
+ self.touch = fall_touch;
+ self.use = fall_use;
+ setmodel (self, self.model);
+};
+
+//=START PARTICLE-STREAM==================================================
+// from Zerstrorer mod -- dumptruck_ds
+
+void(vector start, vector end, float color1, float color2, float pdensity) Particle_Beam =
+{
+local vector spray, next;
+local float dist, loop, clr;
+
+ clr = color1;
+ spray = start - end;
+ dist = vlen(spray);
+ loop = dist / 24;
+ spray = normalize(spray);
+ next = spray * 24;
+ while(loop > 0)
+ {
+ particle (end, spray, clr, pdensity);
+ end = end + next;
+ loop = loop - 1;
+ if (clr == color1)
+ clr = color2;
+ else
+ clr = color1;
+ }
+};
+
+
+void() particle_use =
+{
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ Particle_Beam(self.origin, self.enemy.origin, self.dmg, self.cnt, 15); // was 40 - too many particles for my taste --dumptruck_ds
+};
+
+void() particle_stream_start =
+{
+local entity pspot;
+
+ pspot = find(world, targetname, self.target);
+ if(!pspot)
+ {
+ dprint("Particle stream can't find target!");
+ return;
+ }
+
+ self.enemy = pspot;
+};
+
+/*QUAKED misc_particle_stream (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+A particle stream! It appears when triggered. This entity is
+one end of the stream, target another entity as the other end-point.
+I used the info_notnull, but you should be able to target anything
+(like monsters).
+
+"target" This entities origin is the end-point of the stream
+"dmg" 1st Color - Use if you want a single color stream
+"cnt" 2nd Color - Mixes particles of both colors
+"noise" Sound to play when triggered
+*/
+void() misc_particle_stream =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if(!self.target)
+ objerror("misc_particle_stream with not target!");
+
+ if(!self.dmg)
+ self.dmg = 73;
+ if(!self.cnt)
+ self.cnt = self.dmg;
+ if(!self.noise)
+ self.noise = "misc/null.wav";
+
+ precache_sound(self.noise);
+
+ self.use = particle_use;
+ self.think = particle_stream_start;
+ self.nextthink = time + 0.2;
+};
+// from custents, modified by dumptruck_ds
+//##########################################
+//#### HEAL TRIGGER ####
+//##########################################
+// Original entity submitted by Jan Martin Mathiassen, aka. TGR
+
+void() heal_think =
+{
+ if (self.cnt == self.count)
+ {
+ dprint("trigger_heal think: full\n");
+ self.think = SUB_Null;
+ return;
+ }
+ local float recharge_amount = self.speed;
+ if (self.count < (self.cnt + self.speed))
+ {
+ recharge_amount = self.count - self.cnt;
+ }
+ dprint("trigger_heal think: [max: ");
+ dprint(ftos(self.count));
+ dprint(", current: ");
+ dprint(ftos(self.cnt));
+ dprint(", recharging: ");
+ dprint(ftos(recharge_amount));
+ dprint("]\n");
+
+ self.cnt = self.cnt + recharge_amount;
+ self.nextthink = time + self.delay;
+};
+
+void() heal_touch =
+{
+ if (self.estate != STATE_ACTIVE)
+ return;
+ if (other.movetype == MOVETYPE_NOCLIP) // from Copper -- dumptruck_ds
+ return FALSE;
+ if(self.spawnflags & HEAL_PLAYER_ONLY && other.classname != "player")
+ return;
+ if(self.spawnflags & HEAL_MONSTER_ONLY && !(other.flags & FL_MONSTER))
+ return;
+ if(other.classname != "player" && !(other.flags & FL_MONSTER))
+ return;
+
+ if(other.heal_timer > time)
+ return;
+
+ if(self.count && self.cnt <= 0)
+ {
+ if(self.message2)
+ centerprint(other, self.message2);
+ return;
+ }
+
+ if ((other.takedamage) && (other.health < self.health_max))
+ {
+
+ if (self.noise != "")
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ else
+ sound (self, CHAN_AUTO, "items/r_item1.wav", 1, ATTN_NORM);
+ local float calculated_healing;
+ if ((other.health + self.heal_amount) > self.health_max)
+ {
+ calculated_healing = self.health_max - other.health;
+ }
+ else
+ {
+ calculated_healing = self.heal_amount;
+ }
+
+ if (self.count)
+ {
+
+ if (calculated_healing > self.cnt)
+ {
+ calculated_healing = self.cnt;
+ }
+ self.cnt = self.cnt - calculated_healing;
+ if (self.delay)
+ {
+ self.think = heal_think;
+ self.nextthink = time + self.delay;
+ }
+ dprint("trigger_heal used: [max: ");
+ dprint(ftos(self.count));
+ dprint(", current: ");
+ dprint(ftos(self.cnt));
+ dprint(", using: ");
+ dprint(ftos(calculated_healing));
+ dprint("]\n");
+ }
+ if (self.message)
+ {
+ centerprint(other, self.message);
+ }
+ T_Heal (other, calculated_healing, 1);
+ other.heal_timer = time + self.wait;
+ }
+};
+
+void() heal_toggle=
+{
+ if(self.touch == SUB_Null)
+ self.touch = heal_touch;
+ else
+ self.touch = SUB_Null;
+};
+
+/*QUAKED trigger_heal (.5 .5 .5) ? HEAL_START_ON HEAL_PLAYER_ONLY HEAL_MONSTER_ONLY X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Any object touching this will be healed
+heal_amount -- the amount to heal each time (default 5)
+wait -- the time between each healing (default 1)
+health_max -- the upper limit for the healing (default 100, max 250)
+sounds -- set to 1 to enable the noise1 field for custom healing sound
+noise -- path to custom sound file
+message -- message to print on heal
+count -- maximum heal before exhausted
+speed -- amount to recharge at a time
+delay -- time before recharging
+message2 -- message to print when exhausted
+*/
+void() trigger_heal =
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+ //play custom sound for healing if noise key exists
+ precache_sound("items/r_item1.wav");
+ if (self.noise != "") precache_sound (self.noise);
+
+ InitTrigger ();
+
+ if (self.wait == 0)
+ self.wait = 1;
+ if (self.heal_amount == 0)
+ self.heal_amount = 5;
+ if (self.health_max == 0)
+ self.health_max = 100;
+ else if (self.health_max > 250)
+ self.health_max = 250;
+
+ if (self.count)
+ {
+ self.cnt = self.count;
+
+ if (self.speed && !self.delay)
+ {
+ self.delay = 10;
+ } else if (!self.speed && self.delay)
+ {
+ self.speed = 5;
+ }
+ }
+
+ // if(self.targetname)
+ // {
+ // self.use = heal_toggle;
+ // if(self.spawnflags & HEAL_START_ON)
+ // self.touch = heal_touch;
+ // else
+ // self.touch = SUB_Null;
+ // }
+ // else
+ self.touch = heal_touch;
+
+ SUB_CheckWaiting();
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/dtquake.qc

diff --git a/qc/dtquake.qc b/qc/dtquake.qc
new file mode 100644
index 0000000..e3b0c83
--- /dev/null
+++ b/qc/dtquake.qc
@@ -0,0 +1,103 @@
+// /*this is a point entity from Rubicon Rumble Pack Devkit; REQUIRES A TARGETNAME*/
+//
+// // ===== TRIGGER_SHAKE =======================================================
+//
+float VIEWONLY = 1;
+
+void() shake_think =
+{
+ if (self.attack_finished < time) // Done
+ {
+ self.nextthink = -1;
+
+ if (self.noise1 != "")
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+
+ return;
+ }
+
+ local entity plyr;
+
+ // Shake all players in the effect radius...
+
+ plyr = findradius(self.origin, self.count);
+
+ while(plyr)
+ {
+ if (plyr.flags & FL_CLIENT)
+ {
+ local float d;
+
+ // Scale effect by distance
+ d = vlen(self.origin - plyr.origin);
+ d = (self.count - d)/self.count;
+
+ if (d > 0)
+ {
+ // shake up the view
+ plyr.punchangle_x = -1 * (random() + (0.025*self.dmg*d));
+
+ // push the player around
+ if (plyr.flags & FL_ONGROUND && !(self.spawnflags & VIEWONLY))
+ {
+ d = self.dmg*d;
+ plyr.velocity_x = plyr.velocity_x + (random()*d*2 - d);
+ plyr.velocity_y = plyr.velocity_y + (random()*d*2 - d);
+ plyr.velocity_z = plyr.velocity_z + (random()*d);// always push up
+ }
+ }
+ }
+
+ plyr = plyr.chain;
+ }
+
+ // keep going
+ self.nextthink = time + 0.1;
+};
+
+void() shake_use =
+{
+ if (self.attack_finished > time) return;// already active
+
+ // Start...
+
+ if (self.noise != "")
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+
+ self.attack_finished = time + self.wait;
+ self.nextthink = time + 0.1;
+};
+
+/*QUAKED trigger_shake (.5 0 .5) (-8 -8 -8) (8 8 8) VIEWONLY X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Earthquake trigger - shakes players in it's radius when active.
+Strength of tremor is greatest at the centre.
+dmg Strength at center (default is 120)
+wait Duration of shake (default is 1)
+count Affect radius (defalt is 200)
+noise Noise to play when starting to shake
+noise1 Noise to play when stopping
+targetname Must be triggered
+Spawnflags
+VIEWONLY Shakes the view, but player movement is not affected
+*/
+void() trigger_shake =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.targetname) objerror("trigger_shake without name");
+
+ if (self.noise != "") precache_sound (self.noise);
+ if (self.noise1 != "") precache_sound (self.noise1);
+
+ if (!self.dmg) self.dmg = 120;
+ if (self.count <= 0) self.count = 200;
+ if (self.wait <= 0) self.wait = 1.0;
+
+ setorigin(self, self.origin);
+
+ self.nextthink = -1;
+ self.think = shake_think;
+ self.use = shake_use;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/fight.qc

diff --git a/qc/fight.qc b/qc/fight.qc
new file mode 100644
index 0000000..bbd7ecc
--- /dev/null
+++ b/qc/fight.qc
@@ -0,0 +1,509 @@
+
+/*
+
+A monster is in fight mode if it thinks it can effectively attack its
+enemy.
+
+When it decides it can't attack, it goes into hunt mode.
+
+*/
+
+float(float v) anglemod;
+
+void() knight_atk1;
+void() knight_runatk1;
+void() ogre_smash1;
+void() ogre_swing1;
+
+void() sham_smash1;
+void() sham_swingr1;
+void() sham_swingl1;
+
+float() DemonCheckAttack;
+void(float side) Demon_Melee;
+
+void(vector dest) ChooseTurn;
+
+void() ai_face;
+
+
+float enemy_vis, enemy_infront, enemy_range;
+float enemy_yaw;
+void() zombie_turret_missile;
+
+void() knight_attack =
+{
+ local float len;
+
+// decide if now is a good swing time
+ len = vlen(self.enemy.origin+self.enemy.view_ofs - (self.origin+self.view_ofs));
+
+ if (len<80)
+ knight_atk1 ();
+ else
+ knight_runatk1 ();
+};
+
+//=============================================================================
+
+/*
+===========
+CheckAttack
+
+The player is in view, so decide to move or launch an attack
+Returns FALSE if movement should continue
+============
+*/
+float() CheckAttack =
+{
+ local vector spot1, spot2;
+ local entity targ;
+ local float chance;
+
+ if (self.spawnflags & I_AM_TURRET) //dumptruck_ds
+ {
+ // dprint("CheckAttack...\n");
+ if ((self.classname) == ("monster_enforcer"))
+ {
+ if (self.style == 4) // lightning can only go so far
+ {
+ if (vlen(spot1 - spot2) > 900)
+ {
+ return FALSE;
+ }
+ }
+ self.attack_state = AS_MISSILE;
+ }
+ else if ((self.classname) == ("monster_hell_knight"))
+ {
+ if (self.style == 1) // lightning can only go so far
+ {
+ if (vlen(spot1 - spot2) > 900)
+ {
+ return FALSE;
+ }
+ }
+ // self.attack_state = AS_MISSILE;
+ self.th_turret ();
+ }
+ else if ((self.classname) == ("monster_shalrath"))
+ {
+ self.th_turret ();
+ }
+ else if ((self.classname) == ("monster_zombie"))
+ {
+ // dprint("CheckAttack...\n");
+ zombie_turret_missile();
+ }
+ SUB_AttackFinished (2*random());
+ return TRUE;
+ }
+
+ targ = self.enemy;
+
+// see if any entities are in the way of the shot
+ spot1 = self.origin + self.view_ofs;
+ spot2 = targ.origin + targ.view_ofs;
+
+ traceline (spot1, spot2, FALSE, self);
+
+ if ((self.spawnflags & I_AM_TURRET) && (trace_ent != targ))
+ {
+ // dprint("trace_ent...\n");
+ self.attack_state = AS_TURRET;
+ return FALSE;
+ }
+
+ if (trace_inopen && trace_inwater)
+ return FALSE; // sight line crossed contents
+
+ if (trace_ent != targ)
+ return FALSE; // don't have a clear shot
+
+ if (enemy_range == RANGE_MELEE)
+ { // melee attack
+ if (self.th_melee)
+ {
+ if (self.classname == "monster_knight")
+ knight_attack ();
+ else
+ self.th_melee ();
+ return TRUE;
+ }
+ }
+
+// missile attack
+ if (!self.th_missile)
+ return FALSE;
+
+ if (time < self.attack_finished)
+ return FALSE;
+
+ if (enemy_range == RANGE_FAR)
+ return FALSE;
+
+ if (enemy_range == RANGE_MELEE)
+ {
+ chance = 0.9;
+ self.attack_finished = 0;
+ }
+ else if (enemy_range == RANGE_NEAR)
+ {
+ if (self.th_melee)
+ chance = 0.2;
+ else
+ chance = 0.4;
+ }
+ else if (enemy_range == RANGE_MID)
+ {
+ if (self.th_melee)
+ chance = 0.05;
+ else
+ chance = 0.1;
+ }
+ else
+ chance = 0;
+
+ if (random () < chance)
+ {
+ self.th_missile ();
+ SUB_AttackFinished (2*random());
+ return TRUE;
+ }
+
+ return FALSE;
+};
+
+
+/*
+=============
+ai_face
+
+Stay facing the enemy
+=============
+*/
+void() ai_face =
+{
+ self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
+ ChangeYaw ();
+};
+
+/*
+=============
+ai_charge
+
+The monster is in a melee attack, so get as close as possible to .enemy
+=============
+*/
+float (entity targ) visible;
+float(entity targ) infront;
+float(entity targ) range;
+
+void(float d) ai_charge =
+{
+ ai_face ();
+ movetogoal (d); // done in C code...
+};
+
+void() ai_charge_side =
+{
+ local vector dtemp;
+ local float heading;
+
+// aim to the left of the enemy for a flyby
+
+ self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
+ ChangeYaw ();
+
+ makevectors (self.angles);
+ dtemp = self.enemy.origin - 30*v_right;
+ heading = vectoyaw(dtemp - self.origin);
+
+ walkmove(heading, 20);
+};
+
+
+/*
+=============
+ai_melee
+
+=============
+*/
+void() ai_melee =
+{
+ local vector delta;
+ local float ldmg;
+
+ if (!self.enemy)
+ return; // removed before stroke
+
+ delta = self.enemy.origin - self.origin;
+
+ if (vlen(delta) > 60)
+ return;
+
+ ldmg = (random() + random() + random()) * 3;
+ T_Damage (self.enemy, self, self, ldmg);
+};
+
+
+void() ai_melee_side =
+{
+ local vector delta;
+ local float ldmg;
+
+ if (!self.enemy)
+ return; // removed before stroke
+
+ ai_charge_side();
+
+ delta = self.enemy.origin - self.origin;
+
+ if (vlen(delta) > 60)
+ return;
+ if (!CanDamage (self.enemy, self))
+ return;
+ ldmg = (random() + random() + random()) * 3;
+ T_Damage (self.enemy, self, self, ldmg);
+};
+
+
+//=============================================================================
+
+/*
+===========
+SoldierCheckAttack
+
+The player is in view, so decide to move or launch an attack
+Returns FALSE if movement should continue
+============
+*/
+float() SoldierCheckAttack =
+{
+ local vector spot1, spot2;
+ local entity targ;
+ local float chance;
+
+ // dprint("SoldierAttack\n");
+ if (self.spawnflags & I_AM_TURRET) //dumptruck_ds
+ {
+ // self.th_turret ();
+ self.attack_state = AS_MISSILE;
+ SUB_AttackFinished (1 + random());
+ if (random() < 0.3)
+ self.lefty = !self.lefty;
+ return TRUE;
+ }
+
+ targ = self.enemy;
+
+// see if any entities are in the way of the shot
+ spot1 = self.origin + self.view_ofs;
+ spot2 = targ.origin + targ.view_ofs;
+
+ traceline (spot1, spot2, FALSE, self);
+
+ if (trace_inopen && trace_inwater)
+ return FALSE; // sight line crossed contents
+
+ if ((self.spawnflags & I_AM_TURRET) && (trace_ent != targ))
+ {
+ // dprint("trace_ent...\n");
+ self.attack_state = AS_TURRET;
+ return FALSE;
+ }
+
+ if (trace_ent != targ)
+ return FALSE; // don't have a clear shot
+
+// missile attack
+ if (time < self.attack_finished)
+ return FALSE;
+
+ if (enemy_range == RANGE_FAR)
+ return FALSE;
+
+ if (enemy_range == RANGE_MELEE)
+ chance = 0.9;
+ else if (enemy_range == RANGE_NEAR)
+ chance = 0.4;
+ else if (enemy_range == RANGE_MID)
+ chance = 0.05;
+ else
+ chance = 0;
+
+ if (random () < chance)
+ {
+ self.th_missile ();
+ SUB_AttackFinished (1 + random());
+ if (random() < 0.3)
+ self.lefty = !self.lefty;
+
+ return TRUE;
+ }
+
+ return FALSE;
+};
+//=============================================================================
+
+/*
+===========
+ShamCheckAttack
+
+The player is in view, so decide to move or launch an attack
+Returns FALSE if movement should continue
+============
+*/
+float() ShamCheckAttack =
+{
+ local vector spot1, spot2;
+ local entity targ;
+
+ if (enemy_range == RANGE_MELEE)
+ {
+ if (CanDamage (self.enemy, self))
+ {
+ self.attack_state = AS_MELEE;
+ return TRUE;
+ }
+ }
+
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.attack_state = AS_MISSILE;
+ SUB_AttackFinished (2 + 2*random());
+ return TRUE;
+ }
+
+ if (time < self.attack_finished)
+ return FALSE;
+
+ if (!enemy_vis)
+ return FALSE;
+
+ targ = self.enemy;
+
+// see if any entities are in the way of the shot
+ spot1 = self.origin + self.view_ofs;
+ spot2 = targ.origin + targ.view_ofs;
+
+
+ if (self.style == 0)
+ {
+ if (vlen(spot1 - spot2) > 600)
+ return FALSE;
+ }
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ if (vlen(spot1 - spot2) > 900)
+ return FALSE;
+ }
+
+ // return FALSE;
+
+ traceline (spot1, spot2, FALSE, self);
+
+ if (trace_inopen && trace_inwater)
+ return FALSE; // sight line crossed contents
+
+ if ((self.spawnflags & I_AM_TURRET) && (trace_ent != targ))
+ {
+ // dprint("trace_ent...\n");
+ self.attack_state = AS_TURRET;
+ return FALSE;
+ }
+ if (trace_ent != targ)
+ {
+ return FALSE; // don't have a clear shot
+ }
+
+// missile attack
+ if (self.style == 0 && enemy_range == RANGE_FAR)
+ return FALSE;
+
+ self.attack_state = AS_MISSILE;
+ SUB_AttackFinished (2 + 2*random());
+ return TRUE;
+};
+
+//============================================================================
+
+/*
+===========
+OgreCheckAttack
+
+The player is in view, so decide to move or launch an attack
+Returns FALSE if movement should continue
+============
+*/
+float() OgreCheckAttack =
+{
+ local vector spot1, spot2;
+ local entity targ;
+ local float chance;
+
+ // dprint("OgreCheckAttack\n");
+ if (self.spawnflags & I_AM_TURRET) //dumptruck_ds
+ {
+ self.attack_state = AS_MISSILE;
+ SUB_AttackFinished (2 + 2*random());
+ return TRUE;
+ }
+
+ if (enemy_range == RANGE_MELEE)
+ {
+ if (CanDamage (self.enemy, self))
+ {
+ self.attack_state = AS_MELEE;
+ return TRUE;
+ }
+ }
+
+ if (time < self.attack_finished)
+ return FALSE;
+
+ if (!enemy_vis)
+ return FALSE;
+
+ targ = self.enemy;
+
+// see if any entities are in the way of the shot
+ spot1 = self.origin + self.view_ofs;
+ spot2 = targ.origin + targ.view_ofs;
+
+ traceline (spot1, spot2, FALSE, self);
+
+ if (trace_inopen && trace_inwater)
+ return FALSE; // sight line crossed contents
+
+ if ((self.spawnflags & I_AM_TURRET) && (trace_ent != targ))
+ {
+ // dprint("trace_ent...\n");
+ self.attack_state = AS_TURRET;
+ return FALSE;
+ }
+
+ if (trace_ent != targ)
+ {
+ return FALSE; // don't have a clear shot
+ }
+
+
+// missile attack
+ if (time < self.attack_finished)
+ return FALSE;
+
+ if (enemy_range == RANGE_FAR)
+ return FALSE;
+
+ else if (enemy_range == RANGE_NEAR)
+ chance = 0.10;
+ else if (enemy_range == RANGE_MID)
+ chance = 0.05;
+ else
+ chance = 0;
+
+ self.attack_state = AS_MISSILE;
+ SUB_AttackFinished (1 + 2*random());
+ return TRUE;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/fog.qc

diff --git a/qc/fog.qc b/qc/fog.qc
new file mode 100644
index 0000000..ca6bf95
--- /dev/null
+++ b/qc/fog.qc
@@ -0,0 +1,544 @@
+/*
+====================
+
+Fog controllers
+Based on Copper's fog by Lunaran
+Changed by bmFbr
+
+====================
+*/
+
+float FOG_INTERVAL = 0.04166667; // 1/24;
+/*FGD
+@baseclass = Fog [
+ fog_density(string) : "Fog Density"
+ fog_color(string) : "Fog Color"
+]
+@baseclass = FogShift [
+ fog_density(string) : "Start Fog Density"
+ fog_color(string) : "Start Fog Color"
+ fog_density2(string) : "End Fog Density"
+ fog_color2(string) : "End Fog Color"
+]
+*/
+
+/*
+================
+fog_save
+================
+*/
+void( entity client, float density, vector color ) fog_save =
+{
+ if (client.classname != "player") return;
+
+ // save whatever we set the client's fog to in case of saves/loads
+ client.fog_density = density;
+ client.fog_color = color;
+}
+
+void( entity client ) fog_save_to_previous =
+{
+ if (client.classname != "player") return;
+
+ // copies the current fog to the secondary fields to transition from the current fog
+ client.fog_density2 = client.fog_density;
+ client.fog_color2 = client.fog_color;
+}
+
+void( entity client, float density) skyfog_save =
+{
+ if (client.classname != "player") return;
+
+ client.skyfog_density = density;
+}
+
+void( entity client ) skyfog_save_to_previous =
+{
+ if (client.classname != "player") return;
+
+ client.skyfog_density2 = client.skyfog_density;
+}
+/*
+================
+fog_setFromEnt
+================
+*/
+void( entity client, entity fogger ) fog_setFromEnt =
+{
+ float density;
+ //
+ // Don't set the fog if the entity has no values, because it might be a custom map with
+ // _fog on the worldspawn instead.
+ // To actually get an entity to clear the fog, density to -1.
+ // The same applies to skyfog
+
+ //eprint(fogger);
+
+ //dprint3("fog_density: ", ftos(fogger.fog_density*100), "\n");
+ if (fogger.fog_density) {
+ dprint("setting fog\n");
+ density = zeroconvert(fogger.fog_density);
+ fog_set(client, density, fogger.fog_color);
+ }
+
+ //dprint3("skyfog_density: ", ftos(fogger.skyfog_density*100), "\n");
+ if (fogger.skyfog_density) {
+ dprint("setting skyfog\n");
+ density = zeroconvert(fogger.skyfog_density);
+ skyfog_set(client, density);
+ }
+}
+
+/*
+================
+fog_set
+================
+*/
+void( entity client, float density, vector color) fog_set =
+{
+ if (client.classname != "player") return;
+
+ //dprint9("Setting fog: ", ftos(density), " ", ftos(color_x), " ", ftos(color_y), " ", ftos(color_z), "\n");
+
+ stuffcmd(client, "\nfog ");
+ stuffcmd_float(client, density);
+ stuffcmd(client, " ");
+ stuffcmd_float(client, color_x);
+ stuffcmd(client, " ");
+ stuffcmd_float(client, color_y);
+ stuffcmd(client, " ");
+ stuffcmd_float(client, color_z);
+ stuffcmd(client, "\n");
+
+ fog_save(client, density, color);
+}
+
+
+void( entity client, float density) skyfog_set =
+{
+ if (client.classname != "player") return;
+
+ //dprint3("Setting skyfog: ", ftos(density), "\n");
+
+ stuffcmd(client, "\nr_skyfog ");
+ stuffcmd_float(client, density);
+ stuffcmd(client, "\n");
+
+ skyfog_save(client, density);
+}
+
+/*
+================
+fog_blendTouch
+================
+*/
+void() fog_blendTouch =
+{
+ if (other.classname != "player")
+ return;
+
+ if (other.health <= 0)
+ return;
+
+ if (self.estate != STATE_ACTIVE)
+ return;
+
+ // fix for only first client getting a fog change when multiple coop clients are touching this at once
+ if (time != self.rad_time) // because fog is rad
+ if (time < self.attack_finished)
+ return;
+
+ float f, lerp_density, leaving;
+ float lerp_sdensity;
+ float ent_density, ent_density2, ent_sdensity, ent_sdensity2;
+ vector dorg, mid, ovel;
+ vector lerp_color;
+
+ ent_density = zeroconvert(self.fog_density);
+ ent_density2 = zeroconvert(self.fog_density2);
+
+ ent_sdensity = zeroconvert(self.skyfog_density);
+ ent_sdensity2 = zeroconvert(self.skyfog_density2);
+
+ // if you run/fall through a fogblend fast enough you can come out the other side
+ // partially blended, so check if player will exit the trigger bounds before the
+ // next touch (same class of bug as leaping through lasers in Q2)
+ ovel = other.velocity * FOG_INTERVAL;
+ leaving = ( (other.absmax_x + ovel_x < self.absmin_x) ||
+ (other.absmax_y + ovel_y < self.absmin_y) ||
+ (other.absmax_z + ovel_z < self.absmin_z) ||
+ (other.absmin_x + ovel_x > self.absmax_x) ||
+ (other.absmin_y + ovel_y > self.absmax_y) ||
+ (other.absmin_z + ovel_z > self.absmax_z) );
+
+ if (leaving)
+ {
+ // last chance to set fog correctly, so snap it to the final values
+ leaving = other.velocity * self.movedir;
+ if (leaving > 0)
+ {
+ lerp_density = ent_density2;
+ lerp_color = self.fog_color2;
+ lerp_sdensity = ent_sdensity2;
+ }
+ else
+ {
+ lerp_density = ent_density;
+ lerp_color = self.fog_color;
+ lerp_sdensity = ent_sdensity;
+ }
+ }
+ else
+ {
+ // in transition, blend proportionally between the two fogs
+ mid = (self.mins + self.maxs) * 0.5;
+ dorg = other.origin + other.view_ofs - mid;
+
+ f = dorg * self.movedir;
+ f = (f / self.distance) + 0.5;
+
+ lerp_density = lerp(ent_density, ent_density2, f);
+ lerp_color = lerpVector(self.fog_color, self.fog_color2, f);
+ lerp_sdensity = lerp(ent_sdensity, ent_sdensity2, f);
+ }
+
+ if (self.fog_density || self.fog_density2) fog_set(other, lerp_density, lerp_color);
+ if (self.skyfog_density || self.skyfog_density2) skyfog_set(other, lerp_sdensity);
+
+ self.rad_time = time;
+ self.attack_finished = time + FOG_INTERVAL;
+
+ // reset client's fogblend_entity in case it's currently being transitioned by another entity
+ other.fogblend_entity = world;
+}
+
+
+/*QUAKED trigger_fogblend (.5 .5 .2) ?
+Acts as a smoothly blending portal between two zones of different fog. Sets the fog for any client passing through it, blending their global fog settings between "fog_color"/"fog_density" and "fog_color2"/"fog_density2" proportional to their position within the trigger.
+The axis of motion on which the blend happens is defined by "angle", pointing to whatever zone has color2 and density2. Trigger therefore has two 'sides' - the side that "angle" points to, and the opposite side.
+
+"distance" - override the length of the blend period in world units - defaults to bounds size
+ on 'angle' otherwise. this is only useful for diagonal triggers.
+
+CAVEATS:
+- will 'stuffcmd' 2 dozen times per frame so try not to make these huge
+- a bug in most quake engine ports will reset the eye position smoothing that happens when climbing stairs or riding a plat on every frame that a 'stuffcmd' is sent, so fog transitions during upwards motion will cause noticeable stuttering.
+*/
+/*FGD
+@SolidClass base(Appearflags, Targetname, Target, FogShift) = trigger_fogblend :
+"Trigger: Fog Blend
+Acts as a smoothly blending portal between two zones of different fog. Sets the fog for any client passing through it, blending their global fog settings between start and end values proportional to their position within the trigger.
+
+- will 'stuffcmd' 2 dozen times per frame so try not to make these huge
+- a bug in most quake engine ports will reset the eye position smoothing that happens when climbing stairs or riding a plat on every frame that a 'stuffcmd' is sent, so fog transitions during upwards motion will cause noticeable stuttering."
+[
+ distance(integer) : "Length of blend distance (defaults to size of trigger)"
+ angle(integer) : "Axis of motion of blend (points toward end values)"
+]
+*/
+void() trigger_fogblend =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.angles == '0 0 0') // InitTrigger assumes angle 0 means no angle
+ self.angles = '0 360 0';
+
+ InitTrigger ();
+ self.touch = fog_blendTouch;
+ self.distance = zeroconvertdefault(self.distance, BoundsAngleSize(self.movedir, self.size));
+
+ SUB_CheckWaiting();
+}
+
+
+/*
+================
+fog_blendTimeThink
+used by both trigger_fog and target_fogblend
+================
+*/
+
+float FOGBLEND_ONEWAY = 1;
+float FOGBLEND_REVERSE = 2;
+float FOGBLEND_ALLCLIENTS = 4;
+float FOGBLEND_BLENDTO = 8;
+
+void(entity cl, float sTo, float f) skyfog_blendSetFraction = {
+ float s;
+
+ s = lerpHermite(cl.skyfog_density2, sTo, f);
+
+ //eprint(cl);
+ //dprint3("Fraction skyfog density: ", ftos(s), "\n");
+
+ skyfog_set(cl, s);
+};
+
+void(entity cl, vector cTo, float dTo, float f) fog_blendSetFraction = {
+ float d;
+ vector c;
+
+ d = lerpHermite(cl.fog_density2, dTo, f);
+ c = lerpVectorHermite(cl.fog_color2, cTo, f);
+
+ /*
+ eprint(cl);
+ dprint3("fog density: ", ftos(d), "\n");
+ dprint3("color: ", vtos(c), "\n");
+ dprint3("fraction: ", ftos(f), "\n");
+ */
+
+ fog_set(cl, d, c);
+};
+
+void() fog_blendTimeThink = {
+ float f;
+ float dTo, sTo;
+ vector cTo;
+
+ if (time >= self.pain_finished) {
+ f = 1;
+ }
+ else {
+ self.nextthink = time + FOG_INTERVAL;
+ if (self.state && self.speed)
+ f = 1 - (self.pain_finished - time) / self.speed;
+ else if (self.speed2)
+ f = 1 - (self.pain_finished - time) / self.speed2;
+ else
+ f = 1;
+ }
+
+ if (self.state) {
+ dTo = self.fog_density2;
+ cTo = self.fog_color2;
+ sTo = self.skyfog_density2;
+ }
+ else {
+ dTo = self.fog_density;
+ cTo = self.fog_color;
+ sTo = self.skyfog_density;
+ }
+
+ if (self.spawnflags & FOGBLEND_ALLCLIENTS) {
+ entity pl;
+ pl = nextent(world);
+ while (pl.flags & FL_CLIENT) {
+ if (pl.fogblend_entity == self) {
+ if (dTo && !(pl.fog_density2 == dTo && pl.fog_color2 == cTo))
+ fog_blendSetFraction(pl, cTo, zeroconvert(dTo), f);
+
+ if (sTo)
+ skyfog_blendSetFraction(pl, zeroconvert(sTo), f);
+
+ if (time >= self.pain_finished)
+ pl.fogblend_entity = world;
+ }
+
+ pl = nextent(pl);
+ }
+ }
+ else {
+ if (self.enemy.fogblend_entity == self) {
+ if (dTo && !(self.enemy.fog_density2 == dTo && self.enemy.fog_color2 == cTo))
+ fog_blendSetFraction(self.enemy, cTo, zeroconvert(dTo), f);
+
+ if (sTo)
+ skyfog_blendSetFraction(self.enemy, zeroconvert(sTo), f);
+
+ if (time >= self.pain_finished) {
+ self.enemy.fogblend_entity = world;
+
+ }
+ }
+ }
+
+ if (self.classname == "fog_controller"){
+ if (self.enemy.fogblend_entity != self || time >= self.pain_finished) {
+ remove(self);
+ return;
+ }
+ }
+};
+
+
+
+/**************************************
+
+target_fogblend
+
+**************************************/
+
+void() target_fogblend_use = {
+
+ self.enemy = activator;
+ if (self.enemy.classname != "player") return;
+
+
+ if (!(self.spawnflags & FOGBLEND_ONEWAY))
+ self.state = 1 - self.state;
+
+ if (self.state)
+ self.pain_finished = time + self.delay + self.speed;
+ else
+ self.pain_finished = time + self.delay + self.speed2;
+
+
+ if (self.spawnflags & FOGBLEND_ALLCLIENTS) {
+ entity pl;
+ pl = nextent(world);
+ while (pl.flags & FL_CLIENT) {
+ if (self.fog_density) fog_save_to_previous(pl);
+ if (self.skyfog_density) skyfog_save_to_previous(pl);
+
+ pl.fogblend_entity = self;
+
+ pl = nextent(pl);
+ }
+ }
+ else {
+ if (self.fog_density) fog_save_to_previous(self.enemy);
+ if (self.skyfog_density) skyfog_save_to_previous(self.enemy);
+
+ self.enemy.fogblend_entity = self;
+ }
+
+ self.nextthink = time + self.delay;
+};
+
+
+
+
+/*QUAKED target_fogblend (.5 .5 .2) (-8 -8 -8) (8 8 8) ONE_WAY REVERSE GLOBAL BLENDTO
+Blends the fog for a client. activator's fog will be blended from "fog_color" and "fog_density"
+to "fog_color2" and "fog_density2". Triggering again will blend it back, unless ONE_WAY is set.
+Set REVERSE if you're tired of swapping the values by hand.
+Set GLOBAL to affect all clients in multiplayer, not just the activator.
+
+"delay" - pause before beginning to blend
+"speed" - time to spend blending, -1 for an instant change to fog2.
+"speed2" - time to spend blending back, if different than "speed". -1 for instant.
+
+CAVEATS:
+- will 'stuffcmd' 2 dozen times per frame so try not to make this take too long
+- a bug in most quake engine ports will reset the eye position smoothing that happens when climbing stairs or riding a plat on every frame that a 'stuffcmd' is sent, so fog transitions during upwards motion will cause noticeable stuttering.
+*/
+/*FGD
+@PointClass base(Appearflags, Targetname, Target, FogShift) color(128 128 50) = target_fogblend :
+"Target: Fog Blend
+Activator's fog will be blended over time from start to end values.
+
+- will 'stuffcmd' 2 dozen times per frame so try not to make this take too long
+- a bug in most quake engine ports will reset the eye position smoothing that happens when climbing stairs or riding a plat on every frame that a 'stuffcmd' is sent, so fog transitions during upwards motion will cause noticeable stuttering."
+[
+ spawnflags(flags) = [
+ 1 : "One-Way Only" : 0
+ 2 : "Reverse Start/End" : 0
+ 4 : "All clients" : 0
+ ]
+ delay(string) : "Pause before starting blend"
+ speed(string) : "Time to blend (-1 for instant)"
+ speed2(string) : "Time to blend back, if different (-1 for instant)"
+]
+*/
+void() target_fogblend =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.fog_density && !self.skyfog_density) {
+ objerror("Neither fog density nor skyfog density set");
+ return;
+ }
+
+ self.use = target_fogblend_use;
+ self.think = fog_blendTimeThink;
+
+ if (self.spawnflags & FOGBLEND_REVERSE)
+ self.state = 1;
+ else
+ self.state = 0;
+
+ if (self.spawnflags & FOGBLEND_ONEWAY)
+ self.state = 1 - self.state;
+
+ if (!self.speed) self.speed = 1;
+ if (!self.speed2) self.speed2 = self.speed;
+
+ if (self.speed == -1) self.speed = 0;
+ if (self.speed2 == -1) self.speed2 = 0;
+}
+
+
+
+/**************************************
+
+trigger_fog
+
+**************************************/
+
+void() trigger_fog_touch = {
+ if (self.estate != STATE_ACTIVE)
+ return;
+
+ if (!(other.flags & FL_CLIENT))
+ return;
+
+ // fog already set to this value
+ if (other.fog_color == self.fog_color && other.fog_density == self.fog_density)
+ return;
+
+ // transition already occurring from this trigger
+ if (other.fogblend_entity.owner == self)
+ return;
+
+ if (self.fog_density) fog_save_to_previous(other);
+ if (self.skyfog_density) skyfog_save_to_previous(other);
+
+ // spawn a temp entity to control the transition for this client
+ entity controller;
+
+ controller = spawn();
+ controller.classname = "fog_controller";
+ controller.owner = self;
+ controller.enemy = other;
+ controller.speed2 = self.speed; // speed2 is used when state is 0
+ controller.fog_color = self.fog_color;
+ controller.fog_density = self.fog_density;
+ controller.skyfog_density = self.skyfog_density;
+
+ controller.pain_finished = time + self.delay + self.speed;
+
+ controller.think = fog_blendTimeThink;
+ controller.nextthink = time + controller.delay;
+
+ other.fogblend_entity = controller;
+};
+
+/*QUAKED trigger_fog (.5 .5 .2) ?
+Smoothly blends touching client's currently applied fog to "fog_color" and "fog_density" over time.
+
+"delay" - pause before beginning to blend.
+"speed" - time to spend blending, -1 for an instant change.
+
+CAVEATS:
+- will 'stuffcmd' 2 dozen times per second so try not to make these huge
+- a bug in most quake engine ports will reset the eye position smoothing that happens when climbing stairs or riding a plat on every frame that a 'stuffcmd' is sent, so fog transitions during upwards motion will cause noticeable stuttering.
+*/
+
+void() trigger_fog = {
+
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.fog_density && !self.skyfog_density) {
+ objerror("Neither fog density nor skyfog density set");
+ return;
+ }
+ InitTrigger ();
+ self.touch = trigger_fog_touch;
+ if (!self.speed) self.speed = 1;
+
+ SUB_CheckWaiting();
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/fteopts.qc

diff --git a/qc/fteopts.qc b/qc/fteopts.qc
new file mode 100644
index 0000000..8f7324f
--- /dev/null
+++ b/qc/fteopts.qc
@@ -0,0 +1,2 @@
+#define FTE
+#pragma TARGET FTE

Return to the top of this page or return to the overview of this repo.

Diff qc/fteqcc.ini

diff --git a/qc/fteqcc.ini b/qc/fteqcc.ini
new file mode 100644
index 0000000..2dd0b2c
--- /dev/null
+++ b/qc/fteqcc.ini
@@ -0,0 +1,240 @@
+optimisation t off # c = a*b is performed in one operation rather than two, and can
+ # cause older decompilers to fail.
+optimisation i off # if (!a) was traditionally compiled in two statements. This optimisation
+ # does it in one, but can cause some decompilers to get confused.
+optimisation p off # In the original qcc, function parameters were specified as a vector
+ # store even for floats. This fixes that.
+optimisation c default # This optimisation strips out the names of constants (but not strings)
+ # from your progs, resulting in smaller files. It makes decompilers
+ # leave out names or fabricate numerical ones.
+optimisation cs default # This optimisation strips out the names of string constants from
+ # your progs. However, this can break addons, so don't use it in
+ # those cases.
+optimisation d off # This will merge definitions of constants which are the same value.
+ # Pay extra attention to assignment to constant warnings.
+optimisation s off # This will compact the string table that is stored in the progs.
+ # It will be considerably smaller with this.
+optimisation l default # Strips out local names and definitions. Most decompiles will break
+ # on this.
+optimisation n default # This strips out the names of functions which are never called.
+ # Doesn't make much of an impact though.
+optimisation f default # This strips out the filenames of the progs. This can confuse the
+ # really old decompilers, but is nothing to the more recent ones.
+optimisation u off # Removes the entries of unreferenced variables. Doesn't make a
+ # difference in well maintained code.
+optimisation r off # Optimises the pr_globals count by overlapping temporaries. In
+ # QC, every multiplication, division or operation in general produces
+ # a temporary variable. This optimisation prevents excess, and in
+ # the case of Hexen2's gamecode, reduces the count by 50k. This
+ # is the most important optimisation, ever.
+optimisation a off # 5*6 actually emits an operation into the progs. This prevents
+ # that happening, effectivly making the compiler see 30
+optimisation pf default # Strip out stuff wasted used in function calls and strings to the
+ # precache_file builtin (which is actually a stub in quake).
+optimisation ro default # Functions ending in a return statement do not need a done statement
+ # at the end of the function. This can confuse some decompilers,
+ # making functions appear larger than they were.
+optimisation cj default # This optimisation plays an effect mostly with nested if/else statements,
+ # instead of jumping to an unconditional jump statement, it'll jump
+ # to the final destination instead. This will bewilder decompilers.
+optimisation sf default # Strips out the 'defs' of functions that were only ever called
+ # directly. This does not affect saved games, but will prevent FTE_MULTIPROGS/mutators
+ # from being able to hook functions.
+optimisation lo default # Store all locals in a single section of the pr_globals. Vastly
+ # reducing it. This effectivly does the job of overlaptemps.
+ # However, locals are no longer automatically initialised to 0 (and
+ # never were in the case of recursion, but at least then its the
+ # same type).
+ # If locals appear uninitialised, fteqcc will disable this optimisation
+ # for the affected functions, you can optionally get a warning about
+ # these locals using: #pragma warning enable F302
+optimisation vc default # Where a function is called with just a vector, this causes the
+ # function call to store three floats instead of one vector. This
+ # can save a good number of pr_globals where those vectors contain
+ # many duplicate coordinates but do not match entirly.
+optimisation cf default # Strip class field names. This will harm debugging and can result
+ # in 'gibberish' names appearing in saved games. Has no effect on
+ # engines other than FTEQW, which will not recognise these anyway.
+optimisation uf default # Strips any fields that have no references. This may result in
+ # extra warnings at load time, or disabling support for mapper-specified
+ # alpha in engines that do not provide that. FIXME: this is a little
+ # pointless until relocs are properly implemented.
+keyword asm true # Disables the 'asm' keyword. Use the writeasm flag to see an example
+ # of the asm.
+keyword break true # Disables the 'break' keyword.
+keyword case true # Disables the 'case' keyword.
+keyword class true # Disables the 'class' keyword.
+keyword const true # Disables the 'const' keyword.
+keyword continue true # Disables the 'continue' keyword.
+keyword default true # Disables the 'default' keyword.
+keyword entity true # Disables the 'entity' keyword.
+keyword enum true # Disables the 'enum' keyword.
+keyword enumflags true # Disables the 'enumflags' keyword.
+keyword extern true # Disables the 'extern' keyword. Use only on functions inside addons.
+keyword float true # Disables the 'float' keyword. (Disables the float keyword without
+ # 'local' preceeding it)
+keyword for true # Disables the 'for' keyword. Syntax: for(assignment; while; increment)
+ # {codeblock;}
+keyword goto true # Disables the 'goto' keyword.
+keyword int true # Disables the 'int' keyword.
+keyword integer true # Disables the 'integer' keyword.
+keyword noref true # Disables the 'noref' keyword.
+keyword unused false # Disables the 'unused' keyword. 'unused' means that the variable
+ # is unused, you're aware that its unused, and you'd rather not
+ # know about all the warnings this results in.
+keyword used false # Disables the 'used' keyword. 'used' means that the variable is
+ # used even if the qcc can't see how - thus preventing it from ever
+ # being stripped.
+keyword static true # Disables the 'static' keyword. 'static' means that a variable
+ # has altered scope. On globals, the variable is visible only to
+ # the current .qc file. On locals, the variable's value does not
+ # change between calls to the function. On class variables, specifies
+ # that the field is a scoped global instead of a local. On class
+ # functions, specifies that 'this' is expected to be invalid and
+ # that the function will access any memembers via it.
+keyword nonstatic true # Disables the 'nonstatic' keyword. 'nonstatic' acts upon globals+functions,
+ # reverting the defaultstatic pragma on a per-variable basis. For
+ # use by people who prefer to keep their APIs explicit.
+keyword ignore false # Disables the 'ignore' keyword. 'ignore' is expected to typically
+ # be hidden behind a 'csqconly' define, and in such a context can
+ # be used to conditionally compile functions a little more gracefully.
+ # The opposite of the 'used' keyword. These variables/functions/members
+ # are ALWAYS stripped, and effectively ignored.
+keyword nosave true # Disables the 'nosave' keyword.
+keyword inline true # Disables the 'inline' keyword.
+keyword strip true # Disables the 'strip' keyword.
+keyword shared true # Disables the 'shared' keyword.
+keyword state false # Disables the 'state' keyword.
+keyword optional true # Disables the 'optional' keyword.
+keyword inout false # Disables the 'inout' keyword.
+keyword string true # Disables the 'string' keyword.
+keyword struct true # Disables the 'struct' keyword.
+keyword switch true # Disables the 'switch' keyword.
+keyword thinktime false # Disables the 'thinktime' keyword which is used in HexenC
+keyword until false # Disables the 'until' keyword which is used in HexenC
+keyword loop false # Disables the 'loop' keyword which is used in HexenC
+keyword typedef true # Disables the 'typedef' keyword.
+keyword union true # Disables the 'union' keyword.
+keyword var true # Disables the 'var' keyword.
+keyword vector true # Disables the 'vector' keyword.
+keyword wrap true # Disables the 'wrap' keyword.
+keyword weak true # Disables the 'weak' keyword.
+keyword accumulate false # Disables the 'accumulate' keyword.
+flag acc false # Reacc is a pascall like compiler. It was released before the Quake
+ # source was released. This flag has a few effects. It sorts all
+ # qc files in the current directory into alphabetical order to compile
+ # them. It also allows Reacc global/field distinctions, as well
+ # as allows | for linebreaks. Whilst case insensitivity and lax
+ # type checking are supported by reacc, they are seperate compiler
+ # flags in fteqcc.
+flag qccx false # WARNING: This syntax makes mods inherantly engine specific.
+ # Do NOT use unless you know what you're doing.This is provided
+ # for compatibility only
+ # Any entity hacks will be unsupported in FTEQW, DP, and others,
+ # resulting in engine crashes if the code in question is executed.
+flag kce true # If you want keywords to NOT be disabled when they a variable by
+ # the same name is defined, check here.
+flag parms false # if PARM0 PARM1 etc should be defined by the compiler. These are
+ # useful if you make use of the asm keyword for function calls,
+ # or you wish to create your own variable arguments. This is an
+ # easy way to break decompilers.
+flag autoproto false # Causes compilation to take two passes instead of one. The first
+ # pass, only the definitions are read. The second pass actually
+ # compiles your code. This means you never have to remember to prototype
+ # functions again.
+flag wasm false # Writes out a qc.asm which contains all your functions but in assembler.
+ # This is a great way to look for bugs in fteqcc, but can also be
+ # used to see exactly what your functions turn into, and thus how
+ # to optimise statements better.
+flag annotate false # Annotate source code with assembler statements on compile (requires
+ # gui).
+flag nullemptystr false # Empty string immediates will have the raw value 0 instead of 1.
+flag ifstring true # Causes if(string) to behave identically to if(string!=) This is
+ # most useful with addons of course, but also has adverse effects
+ # with FRIK_FILE's fgets, where it becomes impossible to determin
+ # the end of the file. In such a case, you can still use asm {IF
+ # string 2;RETURN} to detect eof and leave the function.
+flag iffloat false # Fixes certain floating point logic.
+flag ifvector true # Fixes conditional vector logic.
+flag vectorlogic true # Fixes conditional vector logic.
+flag brokenarray false # Treat references to arrays as references to the first index of
+ # said array, to replicate an old fteqcc bug.
+flag rootconstructor false # When enabled, the root constructor should be called first like
+ # in c++.
+flag caseinsens false # Causes fteqcc to become case insensitive whilst compiling names.
+ # It's generally not advised to use this as it compiles a little
+ # more slowly and provides little benefit. However, it is required
+ # for full reacc support.
+flag lax false # Disables many errors (generating warnings instead) when function
+ # calls or operations refer to two normally incompatible types.
+ # This is required for reacc support, and can also allow certain
+ # (evil) mods to compile that were originally written for frikqcc.
+flag hashonly false # Allows use of only #constant for precompiler constants, allows
+ # certain preqcc using mods to compile
+flag lo false # This changes the behaviour of your code. It generates additional
+ # if operations to early-out in if statements. With this flag, the
+ # line if (0 && somefunction()) will never call the function. It
+ # can thus be considered an optimisation. However, due to the change
+ # of behaviour, it is not considered so by fteqcc. Note that due
+ # to inprecisions with floats, this flag can cause runaway loop
+ # errors within the player walk and run functions (without iffloat
+ # also enabled). This code is advised:
+ # player_stand1:
+ # if (self.velocity_x || self.velocity_y)
+ # player_run
+ # if (!(self.velocity_x || self.velocity_y))
+flag msvcstyle false # Generates warning and error messages in a format that msvc understands,
+ # to facilitate ide integration.
+flag debugmacros false # Print out the contents of macros that are expanded. This can help
+ # look inside macros that are expanded and is especially handy if
+ # people are using preprocessor hacks.
+flag filetimes false # Recompiles the progs only if the file times are modified.
+flag fastarrays false # Generates extra instructions inside array handling functions to
+ # detect engine and use extension opcodes only in supporting engines.
+ # Adds a global which is set by the engine if the engine supports
+ # the extra opcodes. Note that this applies to all arrays or none.
+flag assumeint false # Numerical constants are assumed to be integers, instead of floats.
+flag subscope false # Restrict the scope of locals to the block they are actually defined
+ # within, as in C.
+flag verbose false # Lots of extra compiler messages.
+flag typeexplicit false # All type conversions must be explicit or directly supported by
+ # instruction set.
+flag boundchecks true # Disable array index checks, speeding up array access but can result
+ # in your code misbehaving.
+flag attributes false # WARNING: This syntax conflicts with vector constructors.
+flag assumevar false # Initialised globals will be considered non-const by default.
+flag ssp false # Treat ** as an operator for exponents, instead of multiplying
+ # by a dereferenced pointer.
+flag cpriority false # QC treats !a&&b as equivelent to !(a&&b). When this is set, behaviour
+ # will be (!a)&&b as in C. Other operators are also affected in
+ # similar ways.
+flag allowuninit false # Permit optimisations that may result in locals being uninitialised.
+ # This may allow for greater reductions in temps.
+flag nofileline false # Ignores #pragma file(foo) and #pragma line(foo), so that errors
+ # and symbols reflect the actual lines, instead of the original
+ # source.
+flag utf8 false # String immediates will use utf-8 encoding, instead of quake's
+ # encoding.
+flag embedsrc false # Write the sourcecode into the output file. The resulting .dat
+ # can be opened as a standard zip archive (or by fteqccgui).
+ # Good for GPL compliance!
+showall off # Show all keyword options in the gui
+compileonstart off # Recompile on GUI startup
+log off # Write out a compile log
+enginebinary d:\Quakec\fteqw64.exe # Location of the engine binary to run. Change this to something
+ # else to run a different engine, but not all support debugging.
+basedir d:\Quakec # The base directory of the game that contains your sub directory
+engineargs "-game progs_dump +exec fte.cfg"
+ # The engine commandline to use when debugging. You'll likely want
+ # to ensure this contains -window as well as the appropriate -game
+ # argument.
+srcfile progs.src # The progs.src file to load to find ordering of other qc files.
+src # Additional subdir to read qc files from. Typically blank (ie:
+ # the working directory).
+tabsize 8 # Specifies the size of tabs in scintilla windows.
+extramargins off # Enables line number and folding margins.
+hexen2 off # Enable the extra tweaks needed for compatibility with hexen2 engines.
+extendedopcodes off # Utilise an extended instruction set, providing support for pointers
+ # and faster arrays and other speedups.
+parameters # Other additional parameters that are not supported by the gui.
+ # Likely including -DFOO

Return to the top of this page or return to the overview of this repo.

Diff qc/func_bob.qc

diff --git a/qc/func_bob.qc b/qc/func_bob.qc
new file mode 100644
index 0000000..494cce3
--- /dev/null
+++ b/qc/func_bob.qc
@@ -0,0 +1,198 @@
+.float attack_timer;
+.float bsporigin; // All bmodel origins are 0,0,0 check this first
+.float distance;
+.float waitmin2;
+
+float BOB_COLLISION = 2; // Collision for misc_bob
+float BOB_NONSOLID = 4; // Non solid for func_bob
+
+/*QUAKED func_bob (0 .5 .8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+A SOLID bmodel that gently moves back and forth
+-------- KEYS --------
+targetname : trigger entity (works with entity state system)
+angle : direction movement, use "360" for angle 0
+height : direction intensity (def=8)
+count : direction cycle timer (def=2s, minimum=1s)
+waitmin : Speed up scale (def=1) 1+=non linear
+waitmin2 : Slow down scale (def=0.75)
+delay : Starting time delay (def=0, -1=random)
+style : If set to 1, starts off and waits for trigger
+_dirt : -1 = will be excluded from dirtmapping
+_minlight : Minimum light level for any surface of the brush model
+_mincolor : Minimum light color for any surface (def='1 1 1' RGB)
+_shadow : Will cast shadows on other models and itself
+_shadowself : Will cast shadows on itself
+-------- SPAWNFLAGS --------
+STARTOFF : Starts off and waits for trigger - DISABLED, Ripped out ESTATE System (RennyC)
+-------- NOTES --------
+A SOLID bmodel that gently moves back and forth
+*/
+
+//----------------------------------------------------------------------
+void() func_bob_timer =
+{
+ // Keep ticking in background, use local timer (faster)
+ self.think = func_bob_timer;
+
+ if (self.bsporigin)
+ self.nextthink = self.ltime + 0.1;
+ else
+ self.nextthink = time + 0.1;
+
+ // Has the cycle completed?
+ if (self.attack_timer < time)
+ {
+ // Setup bob cycle and half way point for slowdown
+ self.attack_timer = time + self.count;
+ self.distance = time + (self.count * 0.5);
+ // Flip direction of bmodel bob
+ self.lefty = 1 - self.lefty;
+ if (self.lefty < 1)
+ self.t_length = self.height;
+ else
+ self.t_length = -self.height;
+
+ // Always reset velocity and flags
+ self.velocity = '0 0 0';
+ self.flags = 0;
+ }
+
+ // Is the direction set?
+ // This is a block condition to prevent the bmodel moving
+ if (self.lefty != -1)
+ {
+ // Slow down velocity (gradually)
+ if (self.distance < time)
+ self.velocity = self.velocity * self.waitmin2;
+ else
+ {
+ // Speed up velocity (linear/exponentially)
+ self.t_length = self.t_length * self.waitmin;
+ self.velocity = self.velocity + (self.movedir * self.t_length);
+ }
+ }
+};
+
+//----------------------------------------------------------------------
+void() func_bob_on =
+{
+ // This may have been called as a "use" function, so don't allow it
+ // to be called repeatedly -- iw
+ self.use = SUB_Null;
+
+ if (self.bsporigin)
+ {
+ self.movetype = MOVETYPE_PUSH;
+ self.solid = SOLID_BSP;
+ }
+ else
+ {
+ self.movetype = MOVETYPE_FLY;
+ self.solid = SOLID_BBOX;
+ self.flags = 0; // Reset any onground flags
+ }
+
+ if (self.spawnflags & BOB_NONSOLID)
+ self.solid = SOLID_NOT;
+
+ setmodel (self, self.mdl);
+ setsize (self, self.mins , self.maxs);
+
+ self.think = func_bob_timer;
+ if (self.bsporigin)
+ self.nextthink = self.ltime + 0.1 + self.delay;
+ else
+ self.nextthink = time + 0.1 + self.delay;
+};
+
+//----------------------------------------------------------------------
+void() func_bob_off =
+{
+ if (self.bsporigin)
+ {
+ self.movetype = MOVETYPE_PUSH;
+ self.solid = SOLID_BSP;
+ }
+ else
+ {
+ self.movetype = MOVETYPE_FLY;
+ self.solid = SOLID_BBOX;
+ }
+
+ if (self.spawnflags & BOB_NONSOLID)
+ self.solid = SOLID_NOT;
+
+ setmodel (self, self.mdl);
+ setsize (self, self.mins , self.maxs);
+ self.velocity = '0 0 0';
+
+ if (self.style & 1)
+ self.use = func_bob_on;
+};
+
+//----------------------------------------------------------------------
+void() func_bob =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.spawnflags = self.spawnflags | BOB_COLLISION;
+ if (self.spawnflags & BOB_NONSOLID)
+ self.spawnflags = self.spawnflags - (self.spawnflags & BOB_COLLISION);
+
+ // Using a custom model?
+ if (self.mdl == "")
+ {
+ self.bsporigin = TRUE;
+ self.mdl = self.model;
+ }
+ else
+ {
+ self.bsporigin = FALSE;
+ self.modelindex = 0;
+ self.model = "";
+ }
+
+ SetMovedir ();
+ self.movedir = normalize(self.movedir);
+
+ if (self.height <= 0)
+ self.height = 8; // Direction intensity
+ if (self.count < 1)
+ self.count = 2; // Direction switch timer
+ if (self.waitmin <= 0)
+ self.waitmin = 1; // Speed up
+ if (self.waitmin2 <= 0)
+ self.waitmin2 = 0.75; // Slow down
+ if (self.delay < 0)
+ self.delay = random() + random() + random();
+
+ // Setup Entity State functionality - Nope! (RennyC)
+ // if (self.targetname != "")
+ // self.use = func_bob_on;
+
+ if (!self.style) //added style key 1 for start off -- dumptruck_ds
+ func_bob_on();
+ else
+ func_bob_off();
+};
+
+//----------------------------------------------------------------------
+
+/*QUAKED misc_bob (0 0.5 0.8) (-8 -8 -8) (8 8 8) X BOB_COLLISION BOB_NONSOLID X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path" : mdl, "skin" : skin, "frame": frame});
+}
+Same as func_bob but uses a custom model instead of a brush. Use the mdl key to set the path of the model.
+*/
+void() misc_bob =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.mdl == "")
+ self.mdl = string_null;
+ precache_model(self.mdl);
+
+ func_bob();
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/func_brush.qc

diff --git a/qc/func_brush.qc b/qc/func_brush.qc
new file mode 100644
index 0000000..e5f6aaf
--- /dev/null
+++ b/qc/func_brush.qc
@@ -0,0 +1,80 @@
+//this is on hold and not in progs.src
+// crashes in QS at the moment Jaycie is looking into it
+.float solidstate;
+.float visiblestate;
+
+float START_INVISIBLE = 1;
+float START_NONSOLID = 2;
+float START_ALTFRAMES = 4;
+float TOGGLE_VISIBILITY = 8;
+float TOGGLE_SOLIDITY = 16;
+float TOGGLE_FRAMES = 32;
+
+void() func_brush_use =
+{
+ if (self.spawnflags & TOGGLE_VISIBILITY)
+ {
+ if (self.visiblestate == 1)
+ {
+ self.model = "";
+ self.visiblestate = 0;
+ }
+ else
+ {
+ self.model = self.mdl;
+ self.visiblestate = 1;
+ }
+ }
+ if (self.spawnflags & TOGGLE_SOLIDITY)
+ {
+ if (self.solidstate == 1)
+ {
+ self.solid = SOLID_NOT;
+ self.solidstate = 0;
+ }
+ else
+ {
+ self.solid = SOLID_BSP;
+ setorigin(self, self.origin);
+ self.solidstate = 1;
+ }
+ }
+ if (self.spawnflags & TOGGLE_FRAMES)
+ self.frame = 1 - self.frame;
+};
+
+void() func_brush =
+{
+ self.angles = '0 0 0';
+ self.movetype = MOVETYPE_NONE;
+ self.use = func_brush_use;
+ setmodel(self, self.model);
+ self.mdl = self.model;
+ setorigin(self, self.origin);
+
+ if (self.spawnflags & START_INVISIBLE)
+ {
+ self.visiblestate = 0;
+ self.model = "";
+ }
+ else
+ {
+ self.visiblestate = 1;
+ }
+
+ if (self.spawnflags & START_NONSOLID)
+ {
+ self.solidstate = 0;
+ self.solid = SOLID_NOT;
+ }
+ else
+ {
+ self.solidstate = 1;
+ self.solid = SOLID_BSP;
+ }
+
+ if (self.spawnflags & START_ALTFRAMES)
+ self.frame = 1;
+ else
+ self.frame = 0;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/func_fall2.qc

diff --git a/qc/func_fall2.qc b/qc/func_fall2.qc
new file mode 100644
index 0000000..ac97023
--- /dev/null
+++ b/qc/func_fall2.qc
@@ -0,0 +1,280 @@
+.float alpha; // translucency in supported engines
+.entity char; // linker entity
+float PLAYER_TRIGGERED = 1;
+float MONSTER_TRIGGERED = 2;
+float FALL_BREAKABLE = 8; //VR
+// float FALL_SOLID = 16; //VR
+
+void() fall_break_fields;
+
+void() func_fall2_think =
+{
+ self.waterlevel = self.watertype = 0; // turn off quake engine splash sound
+
+ if (self.attack_finished < time)
+ {
+ if (self.target) // fire other targets
+ SUB_UseAndForgetTargets();
+ // SUB_UseTargets();
+
+ self.solid = SOLID_NOT; // removed FALL_SOLID behavior -- dumptruck_ds
+ if (self.pos1 != '0 0 0')
+ self.avelocity = self.pos1; // apply stored avelocity vector values
+
+ if (self.pos2 && !self.velocity) // Add velocity movement
+ self.velocity = self.pos2;
+
+ if (self.cnt > 0) // cnt over 0
+ {
+ if (self.cnt >= 2)
+ {
+ self.movetype = MOVETYPE_BOUNCE;
+ if (self.velocity_z < self.lip)
+ self.velocity_z = self.lip;
+ }
+ else // cnt is 1
+ {
+ self.movetype = MOVETYPE_NOCLIP;
+ if (self.velocity_z > self.lip)
+ self.velocity_z = self.velocity_z - self.speed * (frametime * 100);
+ else
+ self.velocity_z = self.lip;
+ }
+ }
+ else // default behavior (cnt is 0)
+ {
+ self.movetype = MOVETYPE_TOSS;
+ if (self.velocity_z < self.lip)
+ self.velocity_z = self.lip;
+ }
+
+ if (self.pain_finished != -1)
+ {
+ if (self.alpha > 0.1)
+ self.alpha = self.alpha - self.pain_finished;
+ else
+ {
+ if (self.noise2)
+ sound (self, CHAN_AUTO, self.noise2, 1, ATTN_NORM);
+ remove(self);
+ return;
+ }
+ }
+
+ if (self.flags&FL_ONGROUND && self.spawnflags&FALL_BREAKABLE) { //VR
+ self.spawnflags(-)1; //aka BREAKABLE_NO_MONSTERS
+ self.spawnflags(-)2; //aka BREAK_EXPLODE
+ self.mins = self.absmin; //because of how debris origin is calculated
+ self.maxs = self.absmax;
+ self.health = self.lip*0.1; //debris gets velocity from health
+ self.cnt = self.count; //func_breakable uses cnt for quantity of debris to spawn
+ func_breakable_die(); //removes self
+ return;
+ }
+ }
+
+ self.nextthink = self.ltime + 0.1;
+};
+
+void() fall2_touch =
+{
+ if (!other.takedamage)
+ return;
+ if (other.classname != "player") // player activated only
+ return;
+ if (self.spawnflags & MONSTER_TRIGGERED) // disable on monster only, also fixes weird issue
+ return;
+
+ self.think = func_fall2_think;
+ self.nextthink = self.ltime + 0.1;
+
+ self.attack_finished = time + self.wait;
+
+ // if (self.spawnflags&FALL_SOLID) { //VR
+ // setsize(self, self.mins, self.maxs);
+ // self.solid = SOLID_BBOX;
+ // }
+ // else
+ // self.solid = SOLID_NOT;
+
+ if (self.noise)
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+
+ self.touch = SUB_Null; // disable touch, only do this once!
+
+ if (self.char)
+ remove(self.char);
+};
+
+void() func_fall2_use =
+{
+ self.think = func_fall2_think;
+ self.nextthink = self.ltime + 0.1;
+ self.touch = SUB_Null; // disable touch when used
+
+ // if (self.spawnflags&FALL_SOLID) { //VR
+ // setsize(self, self.mins, self.maxs);
+ // self.solid = SOLID_BBOX;
+ // }
+ // else
+ // self.solid = SOLID_NOT;
+
+ self.attack_finished = time + self.wait;
+ if (self.noise)
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+};
+
+void() func_fall2_field_touch =
+{
+ if (other.flags & FL_FLY) // flying monsters shouldn't trigger falling platforms
+ return;
+
+ if (other.flags & FL_MONSTER)
+ {
+ local entity oself;
+
+ oself = self;
+
+ self = self.owner;
+ self.think = func_fall2_use;
+ self.nextthink = self.owner.ltime + 0.1;
+
+ self = oself;
+
+ remove(self);
+ }
+};
+
+/*QUAKED func_fall2 (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Falling brush by RennyC with additions from whirledtsar
+
+wait - how long until the brush begins falling
+noise - the sound to make when touched / activated
+noise2 - the sound to make before it's removed, pain_finished of -1 disables noise2 as the object stays forever
+cnt - 0 is default behavior (MOVETYPE_TOSS), 1 means collisions are disabled while falling (MOVETYPE_NOCLIP), 2 turns the brush into a bouncing entity (MOVETYPE_BOUNCE)
+pain_finished - default of 0.01, higher value has the object/brush fade out faster thus in turn affecting how long it stays. -1 stays forever
+speed - speed as to how fast something falls per game frame, default is 10, higher values mean faster falling. Only for cnt of 1 (MOVETYPE_NOCLIP).
+Recommended to use lip for max fall speed on MOVETYPE_TOSS/BOUNCE entities (cnt 0 and 2) as they follow Quake's default gravity
+lip - maximum fall speed that can be achieved, caps 'speed' variable. Default is -800
+avelocity - have it spin when activated using X, Y, Z vector coordinates. MOVETYPE_BOUNCE ignores avelocity !Use an origin brush for proper spin!
+
+spawnflags:
+Default behavior allows anyone to activate func_fall2 on touch ONLY
+1 - Player activated only
+2 - Monster activated only
+8 - break on impact (use style key for textures, see manual for more)
+16 - fall solid; remains solid on ground
+
+Able to .target other entities, including other func_fall2s
+*/
+
+void() func_fall2 =
+{
+ //
+ // This is a hack to have monsters be able to trigger it by fake touch - Thanks to Nahuel
+ //
+
+ // Don't spawn on player only or if I'm a targetable
+ if (!(self.spawnflags & PLAYER_TRIGGERED) && !(self.targetname))
+ {
+ local entity func_fall2_field;
+
+ func_fall2_field = spawn();
+ func_fall2_field.owner = self;
+ self.char = func_fall2_field; // Link 'em
+ func_fall2_field.solid = SOLID_TRIGGER;
+ setsize (func_fall2_field, self.absmin, self.absmax + '0 0 8');
+ setorigin (func_fall2_field, self.origin);
+ setmodel (func_fall2_field, self.model);
+ func_fall2_field.touch = func_fall2_field_touch;
+ }
+
+ if (self.noise)
+ precache_sound(self.noise);
+ if (self.noise2)
+ precache_sound(self.noise2);
+
+ self.alpha = 1;
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+
+ if (!self.pain_finished)
+ self.pain_finished = 0.01;
+ if (!self.targetname)
+ self.touch = fall2_touch; // .touch in this instance is for players only
+ if (!self.speed)
+ self.speed = 10;
+ if (!self.lip)
+ self.lip = -800;
+ if (self.avelocity != '0 0 0')
+ {
+ self.pos1 = self.avelocity; // store it
+ self.avelocity = '0 0 0';
+ }
+ if (self.spawnflags&FALL_BREAKABLE) { //VR
+ self.pain_finished = -1; //dont fade if set to break
+ fall_break_fields();
+ }
+ self.use = func_fall2_use;
+
+ setmodel (self, self.model);
+};
+
+// * You may have to modify your multi_touch(); command in triggers.qc to allow
+// * both monsters & players to activate trigger_once/multiple. I recommend allowing
+// * the mapper themselves to select how that occurs. Default behavior is player only.
+
+void fall_break_fields ()
+{
+ break_template_setup();
+
+ self.mdl_debris = "progs/debris.mdl";
+ precache_model (self.mdl_debris);
+
+ if (self.noise1 != "") precache_sound(self.noise1);
+// adding new default sounds for "simple" breakables in 1.2.0 -- dumptruck_ds
+// here's genreic metal breaking
+ if (self.style == 0 || self.style == 11 || self.style == 12 || self.style == 17 || self.style == 18 || self.style == 19
+ || self.style == 24 || self.style == 31)
+ if !(self.noise1)
+ {
+ precache_sound("break/metal2.wav");
+ self.noise1 = "break/metal2.wav";
+ }
+ if (self.style == 3 || self.style == 4 || self.style == 5)
+ if !(self.noise1)
+ {
+ precache_sound("break/wood1.wav");
+ precache_sound("break/wood2.wav");
+ if (random() > 0.6) // wood only randomized
+ self.noise1 = "break/wood1.wav";
+ else
+ self.noise1 = "break/wood2.wav";
+ }
+ // glass sounds -- this is more of a shattering sound anyway
+ if (self.style == 6 || self.style == 7 || self.style == 8 || self.style == 9 || self.style == 10)
+ if !(self.noise1)
+ {
+ precache_sound("break/metal1.wav");
+ self.noise1 = "break/metal1.wav";
+ }
+ if (self.style == 1 || self.style == 2 || self.style == 13 || self.style == 14
+ || self.style == 15 || self.style == 16 || self.style == 20 || self.style == 21
+ || self.style == 22 || self.style == 23)
+ if !(self.noise1)
+ {
+ precache_sound("break/bricks1.wav");
+ self.noise1 = "break/bricks1.wav";
+ }
+ if (self.style == 25 || self.style == 26 || self.style == 27 || self.style == 28 || self.style == 29 || self.style == 30)
+ if !(self.noise1)
+ {
+ precache_sound("break/stones1.wav");
+ self.noise1 = "break/stones1.wav";
+ }
+
+ if (!self.health)
+ self.health = 20;
+ if (!self.count)
+ self.count = 5; // was 6 dumptruck_ds
+}

Return to the top of this page or return to the overview of this repo.

Diff qc/hip_count.qc

diff --git a/qc/hip_count.qc b/qc/hip_count.qc
new file mode 100644
index 0000000..0b91e46
--- /dev/null
+++ b/qc/hip_count.qc
@@ -0,0 +1,219 @@
+/* Counter QuickC program
+ By Jim Dose' 9/13/96
+ Copyright (c)1996 Hipnotic Interactive, Inc.
+ All rights reserved.
+ Do not distribute.
+*/
+
+float COUNTER_TOGGLE = 1;
+float COUNTER_LOOP = 2;
+float COUNTER_STEP = 4;
+float COUNTER_RESET = 8;
+float COUNTER_RANDOM = 16;
+float COUNTER_FINISHCOUNT = 32;
+float COUNTER_START_ON = 64;
+
+void() counter_on_use;
+void() counter_off_use;
+
+void() counter_think =
+ {
+ self.cnt = self.cnt + 1;
+ if ( self.spawnflags & COUNTER_RANDOM )
+ {
+ self.state = random() * self.count;
+ self.state = floor( self.state ) + 1;
+ }
+ else
+ {
+ self.state = self.cnt;
+ }
+
+ // fix func_counter and func_oncount handling of activator -- iw
+ //activator = other;
+ activator = self.enemy;
+ SUB_UseTargets();
+ self.nextthink = time + self.wait;
+
+ if ( self.spawnflags & COUNTER_STEP )
+ {
+ counter_on_use();
+ }
+
+ if ( self.cnt >= self.count )
+ {
+ self.cnt = 0;
+ if ( ( self.aflag ) || !( self.spawnflags & COUNTER_LOOP ) )
+ {
+ if (self.spawnflags & COUNTER_TOGGLE)
+ {
+ counter_on_use();
+ }
+ else
+ {
+ remove (self);
+ }
+ }
+ }
+ };
+
+// fix func_counter and func_oncount handling of activator -- iw
+void() counter_start_on_think =
+ {
+ activator = world; // to ensure it's not a random entity -- iw
+ counter_off_use();
+ };
+
+void() counter_on_use =
+ {
+ if ( ( self.cnt != 0 ) && ( self.spawnflags & COUNTER_FINISHCOUNT ) )
+ {
+ self.aflag = TRUE;
+ return;
+ }
+
+ self.use = counter_off_use;
+ self.think = SUB_Null;
+ self.aflag = FALSE;
+ };
+
+void() counter_off_use =
+ {
+ self.aflag = FALSE;
+ if (self.spawnflags & COUNTER_TOGGLE)
+ {
+ self.use = counter_on_use;
+ }
+ else
+ {
+ self.use = SUB_Null;
+ }
+
+ if ( self.spawnflags & COUNTER_RESET )
+ {
+ self.cnt = 0;
+ self.state = 0;
+ }
+ // fix func_counter and func_oncount handling of activator -- iw
+ self.enemy = activator;
+ self.think = counter_think;
+ // fix "delay" making func_counter not work -- iw
+ //if (self.delay)
+ if (self.pausetime)
+ {
+ // fix "delay" making func_counter not work -- iw
+ //self.nextthink = time + self.delay;
+ self.nextthink = time + self.pausetime;
+ }
+ else
+ {
+ counter_think();
+ }
+ };
+
+float( entity counter ) counter_GetCount =
+ {
+ if ( counter.classname == "counter" )
+ {
+ return counter.state;
+ }
+ return 0;
+ };
+
+/*QUAKED func_counter (0 0 0.5) (0 0 0) (32 32 32) TOGGLE LOOP STEP RESET RANDOM FINISHCOUNT START_ON X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+TOGGLE causes the counter to switch between an on and off state
+each time the counter is triggered.
+
+LOOP causes the counter to repeat infinitly. The count resets to zero
+after reaching the value in "count".
+
+STEP causes the counter to only increment when triggered. Effectively,
+this turns the counter into a relay with counting abilities.
+
+RESET causes the counter to reset to 0 when restarted.
+
+RANDOM causes the counter to generate random values in the range 1 to "count"
+at the specified interval.
+
+FINISHCOUNT causes the counter to continue counting until it reaches "count"
+before shutting down even after being set to an off state.
+
+START_ON causes the counter to be on when the level starts.
+
+"count" specifies how many times to repeat the event. If LOOP is set,
+it specifies how high to count before reseting to zero. Default is 10.
+
+"wait" the length of time between each trigger event. Default is 1 second.
+
+"delay" how much time to wait before firing after being switched on.
+*/
+
+void() func_counter =
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if ( !self.wait )
+ {
+ self.wait = 1;
+ }
+
+ self.count = floor( self.count );
+ if ( self.count <= 0 )
+ {
+ self.count = 10;
+ }
+
+ // fix "delay" making func_counter not work -- iw
+ self.pausetime = self.delay;
+ self.delay = 0;
+
+ self.cnt = 0;
+ self.state = 0;
+
+ self.classname = "counter";
+ self.use = counter_off_use;
+ self.think = SUB_Null;
+ if ( self.spawnflags & COUNTER_START_ON )
+ {
+ // fix func_counter and func_oncount handling of activator -- iw
+ //self.think = counter_off_use;
+ self.think = counter_start_on_think;
+ self.nextthink = time + 0.1;
+ }
+ };
+
+void() oncount_use =
+ {
+ if ( counter_GetCount( other ) == self.count )
+ {
+ // fix func_counter and func_oncount handling of activator -- iw
+ //activator = other;
+ SUB_UseTargets();
+ }
+ };
+
+/*QUAKED func_oncount (0 0 0.5) (0 0 0) (16 16 16)
+Must be used as the target for func_counter. When the counter
+reaches the value set by count, func_oncount triggers its targets.
+
+"count" specifies the value to trigger on. Default is 1.
+
+"delay" how much time to wait before firing after being triggered.
+*/
+
+void() func_oncount =
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.count = floor( self.count );
+ if ( self.count <= 0 )
+ {
+ self.count = 1;
+ }
+
+ self.classname = "oncount";
+ self.use = oncount_use;
+ self.think = SUB_Null;
+ };

Return to the top of this page or return to the overview of this repo.

Diff qc/hip_part.qc

diff --git a/qc/hip_part.qc b/qc/hip_part.qc
new file mode 100644
index 0000000..e759742
--- /dev/null
+++ b/qc/hip_part.qc
@@ -0,0 +1,316 @@
+/* Particle effects QuickC program
+ By Jim Dose' 9/19/96
+ Copyright (c)1996 Hipnotic Interactive, Inc.
+ All rights reserved.
+ Do not distribute.
+*/
+
+//float START_OFF = 1;
+float USE_COUNT = 1;
+
+void () particlefield_XZ =
+ {
+ local vector pos;
+ local vector start;
+ local vector end;
+
+ if ( ( self.spawnflags & USE_COUNT ) &&
+ ( counter_GetCount( other ) != self.cnt ) )
+ {
+ return;
+ }
+// dprint( "XZ\n" );
+
+ self.ltime = time + 0.25;
+ if ( self.noise != "" )
+ {
+ sound(self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ }
+
+ // Only show particles if client is visible.
+ // This helps to keep network traffic down to a minimum.
+ if (!checkclient() )
+ return;
+
+ start = self.dest1 + self.origin;
+ end = self.dest2 + self.origin;
+ pos_y = start_y;
+ pos_z = start_z;
+ while( pos_z <= end_z )
+ {
+ pos_x = start_x;
+ while( pos_x <= end_x )
+ {
+ particle ( pos, '0 0 0', self.color, self.count );
+ pos_x = pos_x + 16;
+ }
+ pos_z = pos_z + 16;
+ }
+ };
+
+void () particlefield_YZ =
+ {
+ local vector pos;
+ local vector start;
+ local vector end;
+
+ if ( ( self.spawnflags & USE_COUNT ) &&
+ ( counter_GetCount( other ) != self.cnt ) )
+ {
+ return;
+ }
+
+// dprint( "YZ: " );
+// dprint( vtos( self.dest1 ) );
+// dprint( " - " );
+// dprint( vtos( self.dest2 ) );
+// dprint( "\n" );
+ self.ltime = time + 0.25;
+ if ( self.noise != "" )
+ {
+ sound(self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ }
+
+ // Only show particles if client is visible.
+ // This helps to keep network traffic down to a minimum.
+ if (!checkclient() )
+ return;
+
+ start = self.dest1 + self.origin;
+ end = self.dest2 + self.origin;
+ pos_x = start_x;
+ pos_z = start_z;
+ while( pos_z < end_z )
+ {
+ pos_y = start_y;
+ while( pos_y < end_y )
+ {
+ particle ( pos, '0 0 0', self.color, self.count );
+ pos_y = pos_y + 16;
+ }
+ pos_z = pos_z + 16;
+ }
+ };
+
+void () particlefield_XY =
+ {
+ local vector pos;
+ local vector start;
+ local vector end;
+
+ if ( ( self.spawnflags & USE_COUNT ) &&
+ ( counter_GetCount( other ) != self.cnt ) )
+ {
+ return;
+ }
+
+// dprint( "XY\n" );
+ self.ltime = time + 0.25;
+ if ( self.noise != "" )
+ {
+ sound(self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ }
+
+ // Only show particles if client is visible.
+ // This helps to keep network traffic down to a minimum.
+ if (!checkclient() )
+ return;
+
+
+ start = self.dest1 + self.origin;
+ end = self.dest2 + self.origin;
+ pos_x = start_x;
+ pos_z = start_z;
+ while( pos_x < end_x )
+ {
+ pos_y = start_y;
+ while( pos_y < end_y )
+ {
+ particle ( pos, '0 0 0', self.color, self.count );
+ pos_y = pos_y + 16;
+ }
+ pos_x = pos_x + 16;
+ }
+ };
+
+void () particlefield_touch =
+ {
+ if ( !self.dmg )
+ return;
+
+ if ( time > self.ltime)
+ return;
+
+ if (time < self.attack_finished)
+ return;
+ self.attack_finished = time + 0.5;
+ T_Damage (other, self, self, self.dmg);
+ };
+
+/*QUAKED func_particlefield (0 .5 .8) ? USE_COUNT X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Creates a brief particle flash roughly the size of the defining
+brush each time it is triggered.
+
+USE_COUNT when the activator is a func_counter, the field will only
+activate when count is equal to "cnt". Same as using a func_oncount
+to trigger.
+
+"cnt" is the count to activate on when USE_COUNT is set.
+"color" is the color of the particles. Default is 192 (yellow).
+"count" is the density of the particles. Default is 2.
+"noise" is the sound to play when triggered. Do not use a looping sound here.
+"dmg" is the amount of damage to cause when touched.
+*/
+
+void() func_particlefield =
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if ( !self.color )
+ {
+ self.color = 192;
+ }
+ if ( self.count == 0 )
+ {
+ self.count = 2;
+ }
+ self.classname = "particlefield";
+ self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_NONE;
+ setmodel (self, self.model);
+ self.model = string_null;
+
+ self.origin = ( self.mins + self.maxs ) * 0.5;
+ setorigin (self, self.origin);
+ self.dest = self.maxs - self.mins - '16 16 16';
+ self.dest1 = self.mins + '8 8 8' - self.origin;
+ self.dest2 = self.maxs + '7.9 7.9 7.9' - self.origin;
+ setsize (self, self.mins, self.maxs);
+ self.touch = particlefield_touch;
+// dprint( vtos( self.dest ) );
+// dprint( " " );
+ if ( self.dest_x > self.dest_z )
+ {
+ if ( self.dest_y > self.dest_z )
+ {
+// dprint( "XY1 - " );
+// dprint( ftos( self.cnt ) );
+// dprint( "\n" );
+ self.use = particlefield_XY;
+ self.dest1_z = ( self.dest1_z + self.dest2_z ) / 2;
+ }
+ else
+ {
+// dprint( "XZ1 - " );
+// dprint( ftos( self.cnt ) );
+// dprint( "\n" );
+ self.use = particlefield_XZ;
+ self.dest1_y = ( self.dest1_y + self.dest2_y ) / 2;
+ }
+ }
+ else
+ {
+ if ( self.dest_y > self.dest_x )
+ {
+// dprint( "YZ2 - " );
+// dprint( ftos( self.cnt ) );
+// dprint( "\n" );
+ self.use = particlefield_YZ;
+ self.dest1_x = ( self.dest1_x + self.dest2_x ) / 2;
+ }
+ else
+ {
+// dprint( "XZ2 - " );
+// dprint( ftos( self.cnt ) );
+// dprint( "\n" );
+ self.use = particlefield_XZ;
+ self.dest1_y = ( self.dest1_y + self.dest2_y ) / 2;
+ }
+ }
+
+ if ( self.noise != "" )
+ {
+ precache_sound( self.noise );
+ }
+ self.ltime = time;
+ };
+
+void () blocker_touch =
+ {
+ if ( !self.dmg )
+ return;
+
+ if (time < self.attack_finished)
+ return;
+ self.attack_finished = time + 0.5;
+ T_Damage (other, self, self, self.dmg);
+ sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ };
+
+void () blocker_use =
+ {
+ if ( !self.state )
+ {
+ self.state = 1;
+ setorigin( self, self.origin - '8000 8000 8000' );
+ // sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ }
+ else
+ {
+ self.state = 0;
+ setorigin( self, self.origin + '8000 8000 8000' );
+ sound(self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ }
+ };
+
+/*QUAKED func_togglewall (0 .5 .8) ? START_OFF X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Creates a invisible wall that can be toggled on and off.
+
+START_OFF wall doesn't block until triggered.
+
+"noise" is the sound to play when wall is turned off.
+"noise1" is the sound to play when wall is blocking.
+"dmg" is the amount of damage to cause when touched.
+*/
+
+void() func_togglewall =
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.classname = "togglewall";
+ self.movetype = MOVETYPE_PUSH;
+ self.mdl = self.model;
+ setmodel (self, self.model);
+ setsize (self, self.mins, self.maxs);
+ setorigin (self, self.origin);
+ self.touch = blocker_touch;
+ self.use = blocker_use;
+ if ( !self.noise )
+ {
+ self.noise = ("misc/null.wav");
+ }
+ if ( !self.noise1 )
+ {
+ self.noise1 = ("misc/null.wav");
+ }
+
+ precache_sound( self.noise );
+ precache_sound( self.noise1 );
+
+ self.solid = SOLID_BSP;
+ self.model = string_null;
+ if ( self.spawnflags & START_OFF )
+ {
+ self.state = 0;
+ setorigin( self, self.origin + '8000 8000 8000' );
+ }
+ else
+ {
+ self.state = 1;
+ sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ }
+ };

Return to the top of this page or return to the overview of this repo.

Diff qc/hip_rotate.qc

diff --git a/qc/hip_rotate.qc b/qc/hip_rotate.qc
new file mode 100644
index 0000000..2f74ff9
--- /dev/null
+++ b/qc/hip_rotate.qc
@@ -0,0 +1,1222 @@
+/* Rotate QuickC program
+ By Jim Dose' 10/17/96
+ Copyright (c)1996 Hipnotic Interactive, Inc.
+ All rights reserved.
+ Distributed (unsupported) on 3.12.97
+*/
+
+float STATE_ACTIVE = 0;
+float STATE_INACTIVE = 1;
+float STATE_SPEEDINGUP = 2;
+float STATE_SLOWINGDOWN = 3;
+
+float STATE_CLOSED = 4;
+float STATE_OPEN = 5;
+float STATE_OPENING = 6;
+float STATE_CLOSING = 7;
+
+float STATE_WAIT = 0;
+float STATE_MOVE = 1;
+float STATE_STOP = 2;
+float STATE_FIND = 3;
+float STATE_NEXT = 4;
+
+float OBJECT_ROTATE = 0;
+float OBJECT_MOVEWALL = 1;
+float OBJECT_SETORIGIN = 2;
+
+// spawnflags for func_rotate_entity
+float ROTATE_ENTITY_TOGGLE = 1;
+float ROTATE_ENTITY_START_ON = 2;
+
+// spawnflags for path_rotate
+float PATH_ROTATE_ROTATION = 1;
+float PATH_ROTATE_ANGLES = 2;
+float PATH_ROTATE_STOP = 4;
+float PATH_ROTATE_NO_ROTATE = 8;
+float PATH_ROTATE_DAMAGE = 16;
+float PATH_ROTATE_MOVETIME = 32;
+float PATH_ROTATE_SET_DAMAGE = 64;
+
+// spawnflags for func_rotate_door
+float ROTATE_DOOR_STAYOPEN = 1;
+
+.float rotate_type;
+.vector neworigin;
+.vector rotate;
+.float endtime;
+.float duration;
+.vector finalangle;
+.string path;
+.string group;
+.string event;
+
+
+//=========================
+//
+// SUB_NormalizeAngles
+//
+//=========================
+
+vector (vector ang) SUB_NormalizeAngles =
+{
+ while( ang_x > 360 )
+ {
+ ang_x = ang_x - 360;
+ }
+ while( ang_x < 0 )
+ {
+ ang_x = ang_x + 360;
+ }
+
+ while( ang_y > 360 )
+ {
+ ang_y = ang_y - 360;
+ }
+ while( ang_y < 0 )
+ {
+ ang_y = ang_y + 360;
+ }
+
+ while( ang_z > 360 )
+ {
+ ang_z = ang_z - 360;
+ }
+ while( ang_z < 0 )
+ {
+ ang_z = ang_z + 360;
+ }
+
+ return ang;
+};
+
+/*QUAKED info_rotate (0 0.5 0) (-4 -4 -4) (4 4 4) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Used as the point of rotation for rotatable objects.
+*/
+void() info_rotate =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+// remove self after a little while, to make sure that entities that
+// have targeted it have had a chance to spawn
+ self.nextthink = time + 2;
+ self.think = SUB_Remove;
+};
+
+void() RotateTargets =
+{
+ local entity ent;
+ local vector vx;
+ local vector vy;
+ local vector vz;
+ local vector org;
+
+ makevectors (self.angles);
+
+ ent = find( world, targetname, self.target);
+ while( ent )
+ {
+ if ( ent.rotate_type == OBJECT_SETORIGIN )
+ {
+ org = ent.oldorigin;
+ vx = ( v_forward * org_x );
+ vy = ( v_right * org_y );
+ vy = vy * -1;
+ vz = ( v_up * org_z );
+ ent.neworigin = vx + vy + vz;
+ setorigin( ent, ent.neworigin + self.origin );
+ }
+ else if ( ent.rotate_type == OBJECT_ROTATE )
+ {
+ ent.angles = self.angles;
+ org = ent.oldorigin;
+ vx = ( v_forward * org_x );
+ vy = ( v_right * org_y );
+ vy = vy * -1;
+ vz = ( v_up * org_z );
+ ent.neworigin = vx + vy + vz;
+ setorigin( ent, ent.neworigin + self.origin );
+ }
+ else
+ {
+ org = ent.oldorigin;
+ vx = ( v_forward * org_x );
+ vy = ( v_right * org_y );
+ vy = vy * -1;
+ vz = ( v_up * org_z );
+ ent.neworigin = vx + vy + vz;
+ ent.neworigin = self.origin - self.oldorigin + (ent.neworigin - ent.oldorigin);
+ ent.velocity = (ent.neworigin-ent.origin)*25;
+ }
+ ent = find( ent, targetname, self.target);
+ }
+};
+
+void() RotateTargetsFinal =
+ {
+ local entity ent;
+
+ ent = find( world, targetname, self.target);
+ while( ent )
+ {
+ ent.velocity = '0 0 0';
+ if ( ent.rotate_type == OBJECT_ROTATE )
+ {
+ ent.angles = self.angles;
+ }
+ ent = find( ent, targetname, self.target);
+ }
+ };
+
+void() SetTargetOrigin =
+ {
+ local entity ent;
+
+ ent = find( world, targetname, self.target);
+ while( ent )
+ {
+ if ( ent.rotate_type == OBJECT_MOVEWALL )
+ {
+ setorigin( ent, self.origin - self.oldorigin +
+ (ent.neworigin - ent.oldorigin) );
+ }
+ else
+ {
+ setorigin( ent, ent.neworigin + self.origin );
+ }
+ ent = find( ent, targetname, self.target);
+ }
+ };
+
+void() LinkRotateTargets =
+ {
+ local entity ent;
+ local vector tempvec;
+
+ self.oldorigin = self.origin;
+ ent = find( world, targetname, self.target);
+ while( ent )
+ {
+ if ( ent.classname == "rotate_object" )
+ {
+ ent.rotate_type = OBJECT_ROTATE;
+ ent.oldorigin = ent.origin - self.oldorigin;
+ ent.neworigin = ent.origin - self.oldorigin;
+ ent.owner = self;
+ }
+ else if ( ent.classname == "func_movewall" )
+ {
+ ent.rotate_type = OBJECT_MOVEWALL;
+ tempvec = ( ent.absmin + ent.absmax ) * 0.5;
+ ent.oldorigin = tempvec - self.oldorigin;
+ ent.neworigin = ent.oldorigin;
+ ent.owner = self;
+ }
+ else
+ {
+ ent.rotate_type = OBJECT_SETORIGIN;
+ ent.oldorigin = ent.origin - self.oldorigin;
+ ent.neworigin = ent.origin - self.oldorigin;
+ }
+ ent = find (ent, targetname, self.target);
+ }
+ };
+
+void( entity ent, float amount ) hurt_setdamage =
+ {
+ ent.dmg = amount;
+ if ( !amount )
+ {
+ ent.solid = SOLID_NOT;
+ }
+ else
+ {
+ ent.solid = SOLID_TRIGGER;
+ }
+ ent.nextthink = -1;
+ };
+
+void( float amount ) SetDamageOnTargets =
+ {
+ local entity ent;
+
+ ent = find( world, targetname, self.target);
+ while( ent )
+ {
+ if ( ent.classname == "trigger_hurt" )
+ {
+ hurt_setdamage( ent, amount );
+ }
+ else if ( ent.classname == "func_movewall" )
+ {
+ ent.dmg = amount;
+ }
+ ent = find( ent, targetname, self.target);
+ }
+ };
+
+
+//************************************************
+//
+// Simple continual rotatation
+//
+//************************************************
+
+void() rotate_entity_think =
+ {
+ local float t;
+
+ t = time - self.ltime;
+ self.ltime = time;
+
+ if ( self.state == STATE_SPEEDINGUP )
+ {
+ self.count = self.count + self.cnt * t;
+ if ( self.count > 1 )
+ {
+ self.count = 1;
+ }
+
+ // get rate of rotation
+ t = t * self.count;
+ }
+ else if ( self.state == STATE_SLOWINGDOWN )
+ {
+ self.count = self.count - self.cnt * t;
+ if ( self.count < 0 )
+ {
+ RotateTargetsFinal();
+ self.state = STATE_INACTIVE;
+ self.think = SUB_Null;
+ return;
+ }
+
+ // get rate of rotation
+ t = t * self.count;
+ }
+
+ self.angles = self.angles + ( self.rotate * t );
+ self.angles = SUB_NormalizeAngles( self.angles );
+ RotateTargets();
+ self.nextthink = time + 0.02;
+ };
+
+void() rotate_entity_use =
+ {
+ // change to alternate textures
+ self.frame = 1 - self.frame;
+
+ if ( self.state == STATE_ACTIVE )
+ {
+ if ( self.spawnflags & ROTATE_ENTITY_TOGGLE )
+ {
+ if ( self.speed )
+ {
+ self.count = 1;
+ self.state = STATE_SLOWINGDOWN;
+ }
+ else
+ {
+ self.state = STATE_INACTIVE;
+ self.think = SUB_Null;
+ }
+ }
+ }
+ else if ( self.state == STATE_INACTIVE )
+ {
+ self.think = rotate_entity_think;
+ self.nextthink = time + 0.02;
+ self.ltime = time;
+ if ( self.speed )
+ {
+ self.count = 0;
+ self.state = STATE_SPEEDINGUP;
+ }
+ else
+ {
+ self.state = STATE_ACTIVE;
+ }
+ }
+ else if ( self.state == STATE_SPEEDINGUP )
+ {
+ if ( self.spawnflags & ROTATE_ENTITY_TOGGLE )
+ {
+ self.state = STATE_SLOWINGDOWN;
+ }
+ }
+ else
+ {
+ self.state = STATE_SPEEDINGUP;
+ }
+ };
+
+void() rotate_entity_firstthink =
+ {
+ LinkRotateTargets();
+ if ( self.spawnflags & ROTATE_ENTITY_START_ON )
+ {
+ self.state = STATE_ACTIVE;
+ self.think = rotate_entity_think;
+ self.nextthink = time + 0.02;
+ self.ltime = time;
+ }
+ else
+ {
+ self.state = STATE_INACTIVE;
+ self.think = SUB_Null;
+ }
+ self.use = rotate_entity_use;
+ };
+
+/*QUAKED func_rotate_entity (0 .5 .8) (-8 -8 -8) (8 8 8) TOGGLE START_ON X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Creates an entity that continually rotates. Can be toggled on and
+off if targeted.
+
+TOGGLE = allows the rotation to be toggled on/off
+
+START_ON = wether the entity is spinning when spawned. If TOGGLE is 0, entity can be turned on, but not off.
+
+If "deathtype" is set with a string, this is the message that will appear when a player is killed by the train.
+
+"rotate" is the rate to rotate.
+"target" is the center of rotation.
+"speed" is how long the entity takes to go from standing still to full speed and vice-versa.
+*/
+
+void() func_rotate_entity =
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_NONE;
+
+ setmodel (self, self.model);
+ setsize( self, self.mins, self.maxs );
+
+ if ( self.speed != 0 )
+ {
+ self.cnt = 1 / self.speed;
+ }
+
+ self.think = rotate_entity_firstthink;
+ self.nextthink = time + 0.1;
+ self.ltime = time;
+ };
+
+//************************************************
+//
+// Train with rotation functionality
+//
+//************************************************
+
+/*QUAKED path_rotate (0.5 0.3 0) (-8 -8 -8) (8 8 8) ROTATION ANGLES STOP NO_ROTATE DAMAGE MOVETIME SET_DAMAGE
+ Path for rotate_train.
+
+ ROTATION tells train to rotate at rate specified by "rotate". Use '0 0 0' to stop rotation.
+
+ ANGLES tells train to rotate to the angles specified by "angles" while traveling to this path_rotate. Use values < 0 or > 360 to guarantee that it turns in a certain direction. Having this flag set automatically clears any rotation.
+
+ STOP tells the train to stop and wait to be retriggered.
+
+ NO_ROTATE tells the train to stop rotating when waiting to be triggered.
+
+ DAMAGE tells the train to cause damage based on "dmg".
+
+ MOVETIME tells the train to interpret "speed" as the length of time to take moving from one corner to another.
+
+ SET_DAMAGE tells the train to set all targets damage to "dmg"
+
+ "noise" contains the name of the sound to play when train stops.
+ "noise1" contains the name of the sound to play when train moves.
+ "event" is a target to trigger when train arrives at path_rotate.
+*/
+void() path_rotate =
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if ( self.noise != "" )
+ {
+ precache_sound( self.noise );
+ }
+ if ( self.noise1 != "" )
+ {
+ precache_sound( self.noise1 );
+ }
+ };
+
+
+void() rotate_train;
+void() rotate_train_next;
+void() rotate_train_find;
+
+void() rotate_train_think =
+ {
+ local float t;
+ local float timeelapsed;
+
+ t = time - self.ltime;
+ self.ltime = time;
+
+ if ( ( self.endtime ) && ( time >= self.endtime ) )
+ {
+ self.endtime = 0;
+ if ( self.state == STATE_MOVE )
+ {
+ setorigin(self, self.finaldest);
+ self.velocity = '0 0 0';
+ }
+
+ if (self.think1)
+ self.think1();
+ }
+ else
+ {
+ timeelapsed = (time - self.cnt) * self.duration;
+ if ( timeelapsed > 1 )
+ timeelapsed = 1;
+ setorigin( self, self.dest1 + ( self.dest2 * timeelapsed ) );
+ }
+
+ self.angles = self.angles + ( self.rotate * t );
+ self.angles = SUB_NormalizeAngles( self.angles );
+ RotateTargets();
+
+ self.nextthink = time + 0.02;
+ };
+
+void() rotate_train_use =
+ {
+ if (self.think1 != rotate_train_find)
+ {
+ if ( self.velocity != '0 0 0' )
+ return; // already activated
+ if ( self.think1 )
+ {
+ self.think1();
+ }
+ }
+ };
+
+void() rotate_train_wait =
+ {
+ self.state = STATE_WAIT;
+
+ if ( self.goalentity.noise != "" )
+ {
+ sound (self, CHAN_VOICE, self.goalentity.noise, 1, ATTN_NORM);
+ }
+ else
+ {
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ }
+ if ( self.goalentity.spawnflags & PATH_ROTATE_ANGLES )
+ {
+ self.rotate = '0 0 0';
+ self.angles = self.finalangle;
+ }
+ if ( self.goalentity.spawnflags & PATH_ROTATE_NO_ROTATE )
+ {
+ self.rotate = '0 0 0';
+ }
+ self.endtime = self.ltime + self.goalentity.wait;
+ self.think1 = rotate_train_next;
+ };
+
+void() rotate_train_stop =
+ {
+ self.state = STATE_STOP;
+
+ if ( self.goalentity.noise != "" )
+ {
+ sound (self, CHAN_VOICE, self.goalentity.noise, 1, ATTN_NORM);
+ }
+ else
+ {
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ }
+ if ( self.goalentity.spawnflags & PATH_ROTATE_ANGLES )
+ {
+ self.rotate = '0 0 0';
+ self.angles = self.finalangle;
+ }
+ if ( self.goalentity.spawnflags & PATH_ROTATE_NO_ROTATE )
+ {
+ self.rotate = '0 0 0';
+ }
+
+ self.dmg = 0;
+ self.think1 = rotate_train_next;
+ };
+
+void() rotate_train_next =
+{
+ local entity targ;
+ local entity current;
+ local vector vdestdelta;
+ local float len, traveltime, div;
+ local string temp;
+
+ self.state = STATE_NEXT;
+
+ current = self.goalentity;
+ targ = find (world, targetname, self.path);
+ if ( targ.classname != "path_rotate" )
+ objerror( "Next target is not path_rotate" );
+
+ if ( self.goalentity.noise1 != "" )
+ {
+ self.noise1 = self.goalentity.noise1;
+ }
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+
+ self.goalentity = targ;
+ self.path = targ.target;
+ if (!self.path )
+ objerror ("rotate_train_next: no next target");
+
+ if ( targ.spawnflags & PATH_ROTATE_STOP )
+ {
+ self.think1 = rotate_train_stop;
+ }
+ else if (targ.wait)
+ {
+ self.think1 = rotate_train_wait;
+ }
+ else
+ {
+ self.think1 = rotate_train_next;
+ }
+
+ if ( current.event != "" )
+ {
+ // Trigger any events that should happen at the corner.
+ temp = self.target;
+ self.target = current.event;
+ self.message = current.message;
+ SUB_UseTargets();
+ self.target = temp;
+ self.message = string_null;
+ }
+
+ if ( current.spawnflags & PATH_ROTATE_ANGLES )
+ {
+ self.rotate = '0 0 0';
+ self.angles = self.finalangle;
+ }
+
+ if ( current.spawnflags & PATH_ROTATE_ROTATION )
+ {
+ self.rotate = current.rotate;
+ }
+
+ if ( current.spawnflags & PATH_ROTATE_DAMAGE )
+ {
+ self.dmg = current.dmg;
+ }
+
+ if ( current.spawnflags & PATH_ROTATE_SET_DAMAGE )
+ {
+ SetDamageOnTargets( current.dmg );
+ }
+
+ if ( current.speed == -1 )
+ {
+ // Warp to the next path_corner
+ setorigin( self, targ.origin );
+ self.endtime = self.ltime + 0.01;
+ SetTargetOrigin();
+
+ if ( targ.spawnflags & PATH_ROTATE_ANGLES )
+ {
+ self.angles = targ.angles;
+ }
+
+ self.duration = 1; // 1 / duration
+ self.cnt = time; // start time
+ self.dest2 = '0 0 0'; // delta
+ self.dest1 = self.origin; // original position
+ self.finaldest = self.origin;
+ }
+ else
+ {
+ self.state = STATE_MOVE;
+
+ self.finaldest = targ.origin;
+ if (self.finaldest == self.origin)
+ {
+ self.velocity = '0 0 0';
+ self.endtime = self.ltime + 0.1;
+
+ self.duration = 1; // 1 / duration
+ self.cnt = time; // start time
+ self.dest2 = '0 0 0'; // delta
+ self.dest1 = self.origin; // original position
+ self.finaldest = self.origin;
+ return;
+ }
+ // set destdelta to the vector needed to move
+ vdestdelta = self.finaldest - self.origin;
+
+ // calculate length of vector
+ len = vlen (vdestdelta);
+
+ if ( current.spawnflags & PATH_ROTATE_MOVETIME )
+ {
+ traveltime = current.speed;
+ }
+ else
+ {
+ // check if there's a speed change
+ if (current.speed>0)
+ self.speed = current.speed;
+
+ if (!self.speed)
+ objerror("No speed is defined!");
+
+ // divide by speed to get time to reach dest
+ traveltime = len / self.speed;
+ }
+
+ if (traveltime < 0.1)
+ {
+ self.velocity = '0 0 0';
+ self.endtime = self.ltime + 0.1;
+ if ( targ.spawnflags & PATH_ROTATE_ANGLES )
+ {
+ self.angles = targ.angles;
+ }
+ return;
+ }
+
+ // qcc won't take vec/float
+ div = 1 / traveltime;
+
+ if ( targ.spawnflags & PATH_ROTATE_ANGLES )
+ {
+ self.finalangle = SUB_NormalizeAngles( targ.angles );
+ self.rotate = ( targ.angles - self.angles ) * div;
+ }
+
+ // set endtime to trigger a think when dest is reached
+ self.endtime = self.ltime + traveltime;
+
+ // scale the destdelta vector by the time spent traveling to get velocity
+ self.velocity = vdestdelta * div;
+
+ self.duration = div; // 1 / duration
+ self.cnt = time; // start time
+ self.dest2 = vdestdelta; // delta
+ self.dest1 = self.origin; // original position
+ }
+ };
+
+void() rotate_train_find =
+ {
+ local entity targ;
+
+ self.state = STATE_FIND;
+
+ LinkRotateTargets();
+
+ // the first target is the point of rotation.
+ // the second target is the path.
+ targ = find ( world, targetname, self.path);
+ if ( targ.classname != "path_rotate" )
+ objerror( "Next target is not path_rotate" );
+
+ // Save the current entity
+ self.goalentity = targ;
+
+ if ( targ.spawnflags & PATH_ROTATE_ANGLES )
+ {
+ self.angles = targ.angles;
+ self.finalangle = SUB_NormalizeAngles( targ.angles );
+ }
+
+ self.path = targ.target;
+ setorigin (self, targ.origin );
+ SetTargetOrigin();
+ RotateTargetsFinal();
+ self.think1 = rotate_train_next;
+ if (!self.targetname)
+ {
+ // not triggered, so start immediately
+ self.endtime = self.ltime + 0.1;
+ }
+ else
+ {
+ self.endtime = 0;
+ }
+
+ self.duration = 1; // 1 / duration
+ self.cnt = time; // start time
+ self.dest2 = '0 0 0'; // delta
+ self.dest1 = self.origin; // original position
+ };
+
+/*QUAKED func_rotate_train (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+In path_rotate, set speed to be the new speed of the train after it reaches
+the path change. If speed is -1, the train will warp directly to the next
+path change after the specified wait time. If MOVETIME is set on the
+path_rotate, the train to interprets "speed" as the length of time to
+take moving from one corner to another.
+
+"noise" contains the name of the sound to play when train stops.
+"noise1" contains the name of the sound to play when train moves.
+Both "noise" and "noise1" defaults depend upon "sounds" variable and
+can be overridden by the "noise" and "noise1" variable in path_rotate.
+
+Also in path_rotate, if STOP is set, the train will wait until it is
+retriggered before moving on to the next goal.
+
+Trains are moving platforms that players can ride.
+"path" specifies the first path_rotate and is the starting position.
+If the train is the target of a button or trigger, it will not begin moving until activated.
+The func_rotate_train entity is the center of rotation of all objects targeted by it.
+
+If "deathtype" is set with a string, this is the message that will appear when a player is killed by the train.
+
+speed default 100
+dmg default 0
+sounds
+1) ratchet metal
+*/
+
+void() rotate_train =
+ {
+ objerror ("rotate_train entities should be changed to rotate_object with\nfunc_rotate_train controllers\n");
+ };
+
+void() func_rotate_train =
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.speed)
+ self.speed = 100;
+ if (!self.target)
+ objerror ("rotate_train without a target");
+
+ if ( !self.noise )
+ {
+ if (self.sounds == 0)
+ {
+ self.noise = ("misc/null.wav");
+ }
+
+ if (self.sounds == 1)
+ {
+ self.noise = ("plats/train2.wav");
+ }
+ }
+ if ( !self.noise1 )
+ {
+ if (self.sounds == 0)
+ {
+ self.noise1 = ("misc/null.wav");
+ }
+ if (self.sounds == 1)
+ {
+ self.noise1 = ("plats/train1.wav");
+ }
+ }
+
+ precache_sound( self.noise );
+ precache_sound( self.noise1 );
+
+ self.cnt = 1;
+ self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_STEP;
+ self.use = rotate_train_use;
+
+ setmodel (self, self.model);
+ setsize (self, self.mins, self.maxs);
+ setorigin (self, self.origin);
+
+// start trains on the second frame, to make sure their targets have had
+// a chance to spawn
+ self.ltime = time;
+ self.nextthink = self.ltime + 0.1;
+ self.endtime = self.ltime + 0.1;
+ self.think = rotate_train_think;
+ self.think1 = rotate_train_find;
+ self.state = STATE_FIND;
+
+ self.duration = 1; // 1 / duration
+ self.cnt = 0.1; // start time
+ self.dest2 = '0 0 0'; // delta
+ self.dest1 = self.origin; // original position
+
+
+ self.flags = self.flags | FL_ONGROUND;
+ };
+
+//************************************************
+//
+// Moving clip walls
+//
+//************************************************
+
+void() rotate_door_reversedirection;
+void() rotate_door_group_reversedirection;
+
+void() movewall_touch =
+ {
+ if (time < self.owner.attack_finished)
+ return;
+
+ if ( self.dmg )
+ {
+ T_Damage (other, self, self.owner, self.dmg);
+ self.owner.attack_finished = time + 0.5;
+ }
+ else if ( self.owner.dmg )
+ {
+ T_Damage (other, self, self.owner, self.owner.dmg);
+ self.owner.attack_finished = time + 0.5;
+ }
+ };
+
+void() movewall_blocked =
+ {
+ local entity temp;
+
+ if (time < self.owner.attack_finished)
+ return;
+
+ self.owner.attack_finished = time + 0.5;
+
+ if ( self.owner.classname == "func_rotate_door" )
+ {
+ temp = self;
+ self = self.owner;
+ rotate_door_group_reversedirection();
+ self = temp;
+ }
+
+ if ( self.dmg )
+ {
+ T_Damage (other, self, self.owner, self.dmg);
+ self.owner.attack_finished = time + 0.5;
+ }
+ else if ( self.owner.dmg )
+ {
+ T_Damage (other, self, self.owner, self.owner.dmg);
+ self.owner.attack_finished = time + 0.5;
+ }
+ };
+
+void() movewall_think =
+ {
+ self.ltime = time;
+ self.nextthink = time + 0.02;
+ };
+
+/*QUAKED func_movewall (0 .5 .8) ? VISIBLE TOUCH NONBLOCKING X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Used to emulate collision on rotating objects.
+
+VISIBLE causes brush to be displayed.
+
+TOUCH specifies whether to cause damage when touched by player.
+
+NONBLOCKING makes the brush non-solid. This is useless if VISIBLE is set.
+
+"dmg" specifies the damage to cause when touched or blocked.
+*/
+void() func_movewall =
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.angles = '0 0 0';
+ self.movetype = MOVETYPE_PUSH;
+ if ( self.spawnflags & MOVEWALL_NONBLOCKING )
+ {
+ self.solid = SOLID_NOT;
+ }
+ else
+ {
+ self.solid = SOLID_BSP;
+ self.blocked = movewall_blocked;
+ }
+ if ( self.spawnflags & MOVEWALL_TOUCH )
+ {
+ self.touch = movewall_touch;
+ }
+ setmodel (self,self.model);
+ if ( !( self.spawnflags & MOVEWALL_VISIBLE ) )
+ {
+ self.model = string_null;
+ }
+ self.think = movewall_think;
+ self.nextthink = time + 0.02;
+ self.ltime = time;
+ };
+
+/*QUAKED rotate_object (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+This defines an object to be rotated. Used as the target of func_rotate_door.
+*/
+void() rotate_object =
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.classname = "rotate_object";
+ self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_NONE;
+ setmodel (self,self.model);
+ setsize( self, self.mins, self.maxs );
+ self.think = SUB_Null;
+ };
+
+//************************************************
+//
+// Rotating doors
+//
+//************************************************
+
+void() rotate_door_think2 =
+ {
+ local float t;
+
+ t = time - self.ltime;
+ self.ltime = time;
+
+ // change to alternate textures
+ self.frame = 1 - self.frame;
+
+ self.angles = self.dest;
+
+ if ( self.state == STATE_OPENING )
+ {
+ self.state = STATE_OPEN;
+ }
+ else
+ {
+ if ( self.spawnflags & ROTATE_DOOR_STAYOPEN )
+ {
+ rotate_door_group_reversedirection();
+ return;
+ }
+ self.state = STATE_CLOSED;
+ }
+
+ sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
+ self.think = SUB_Null;
+
+ RotateTargetsFinal();
+ };
+
+void() rotate_door_think =
+ {
+ local float t;
+
+ t = time - self.ltime;
+ self.ltime = time;
+
+ if ( time < self.endtime )
+ {
+ self.angles = self.angles + ( self.rotate * t );
+ RotateTargets();
+ }
+ else
+ {
+ self.angles = self.dest;
+ RotateTargets();
+ self.think = rotate_door_think2;
+ }
+
+ self.nextthink = time + 0.01;
+ };
+
+void() rotate_door_reversedirection =
+ {
+ local vector start;
+
+ // change to alternate textures
+ self.frame = 1 - self.frame;
+
+ if ( self.state == STATE_CLOSING )
+ {
+ start = self.dest1;
+ self.dest = self.dest2;
+ self.state = STATE_OPENING;
+ }
+ else
+ {
+ start = self.dest2;
+ self.dest = self.dest1;
+ self.state = STATE_CLOSING;
+ }
+
+ sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
+
+ self.rotate = ( self.dest - start ) * ( 1 / self.speed );
+ self.think = rotate_door_think;
+ self.nextthink = time + 0.02;
+ self.endtime = time + self.speed - ( self.endtime - time );
+ self.ltime = time;
+ };
+
+void() rotate_door_group_reversedirection =
+ {
+ local string name;
+
+ // tell all associated rotaters to reverse direction
+ if ( self.group != "" )
+ {
+ name = self.group;
+ self = find( world, group, name);
+ while( self )
+ {
+ rotate_door_reversedirection();
+ self = find( self, group, name);
+ }
+ }
+ else
+ {
+ rotate_door_reversedirection();
+ }
+ };
+
+void() rotate_door_use =
+ {
+ local vector start;
+
+ if ( ( self.state != STATE_OPEN ) && ( self.state != STATE_CLOSED ) )
+ return;
+
+ if ( !self.cnt )
+ {
+ self.cnt = 1;
+ LinkRotateTargets();
+ }
+
+ // change to alternate textures
+ self.frame = 1 - self.frame;
+
+ if ( self.state == STATE_CLOSED )
+ {
+ start = self.dest1;
+ self.dest = self.dest2;
+ self.state = STATE_OPENING;
+ }
+ else
+ {
+ start = self.dest2;
+ self.dest = self.dest1;
+ self.state = STATE_CLOSING;
+ }
+
+ sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
+
+ self.rotate = ( self.dest - start ) * ( 1 / self.speed );
+ self.think = rotate_door_think;
+ self.nextthink = time + 0.01;
+ self.endtime = time + self.speed;
+ self.ltime = time;
+ };
+
+
+/*QUAKED func_rotate_door (0 .5 .8) (-8 -8 -8) (8 8 8) STAYOPEN X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Creates a door that rotates between two positions around a point of
+rotation each time it's triggered.
+
+STAYOPEN tells the door to reopen after closing. This prevents a trigger-
+once door from closing again when it's blocked.
+
+"dmg" specifies the damage to cause when blocked. Defaults to 2. Negative numbers indicate no damage.
+"speed" specifies how the time it takes to rotate
+
+"sounds"
+1) medieval (default)
+2) metal
+3) base
+*/
+
+void() func_rotate_door = // added slinet option - sounds 4 -- dumptruck_ds
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.target)
+ {
+ objerror( "rotate_door without target." );
+ }
+
+ self.dest1 = '0 0 0';
+ self.dest2 = self.angles;
+ self.angles = self.dest1;
+
+ // default to 2 seconds
+ if ( !self.speed )
+ {
+ self.speed = 2;
+ }
+
+ self.cnt = 0;
+
+ if (!self.dmg)
+ self.dmg = 2;
+ else if ( self.dmg < 0 )
+ {
+ self.dmg = 0;
+ }
+
+ if (self.sounds == 0)
+ {
+ //If at least one custom sound is defined, then let's ignore the presets and go for the custom sounds,
+ //otherwise let's use preset #1 by default
+ if(self.noise1=="" && self.noise2=="" && self.noise3=="")
+ {
+ self.sounds = 1;
+ }
+ else
+ {
+ if(self.noise1=="") self.noise1 = "misc/null.wav";
+ if(self.noise2=="") self.noise2 = "misc/null.wav";
+ if(self.noise3=="") self.noise3 = "misc/null.wav";
+ }
+ }
+ if (self.sounds == 1)
+ {
+ self.noise1 = "doors/latch2.wav";
+ self.noise2 = "doors/winch2.wav";
+ self.noise3 = "doors/drclos4.wav";
+ }
+ else if (self.sounds == 2)
+ {
+ self.noise2 = "doors/airdoor1.wav";
+ self.noise1 = "doors/airdoor2.wav";
+ self.noise3 = self.noise1;
+ }
+ else if (self.sounds == 3)
+ {
+ self.noise2 = "doors/basesec1.wav";
+ self.noise1 = "doors/basesec2.wav";
+ self.noise3 = self.noise1;
+ }
+ else if (self.sounds == 4)
+ {
+ self.noise1 = self.noise2 = self.noise3 = "misc/null.wav";
+ }
+ precache_sound (self.noise1);
+ precache_sound (self.noise2);
+ precache_sound (self.noise3);
+
+ self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_NONE;
+ setmodel (self, self.model);
+ setorigin( self, self.origin );
+ setsize( self, self.mins, self.maxs );
+ self.state = STATE_CLOSED;
+ self.use = rotate_door_use;
+ self.think = SUB_Null;
+ };

Return to the top of this page or return to the overview of this repo.

Diff qc/hip_trig.qc

diff --git a/qc/hip_trig.qc b/qc/hip_trig.qc
new file mode 100644
index 0000000..f8a3dec
--- /dev/null
+++ b/qc/hip_trig.qc
@@ -0,0 +1,238 @@
+//Selections from hiptrig.qc NOT the entire file
+
+/* Trigger QuickC program
+ By Jim Dose' 12/2/96
+ Copyright (c)1996 Hipnotic Interactive, Inc.
+ All rights reserved.
+ Do not distribute.
+*/
+
+float USE_SILV_KEY = 8;
+float USE_GOLD_KEY = 16;
+
+/*
+================
+keytrigger_unlock
+
+Perform the actions which should be performed when self is successfully
+unlocked with a key.
+
+This function exists so that it can be passed as an argument to the new
+keylock_try_to_unlock function. This code was previously part of the
+keytrigger_use function. -- iw
+================
+*/
+void() keytrigger_unlock =
+{
+ // we can't just remove (self) here, because this is a touch function
+ // called while C code is looping through area links...
+ self.touch = SUB_Null;
+ self.use = SUB_Null;
+ self.nextthink = time + 0.1;
+ self.think = SUB_Remove;
+ self.message = "";
+
+ SUB_UseTargets();
+};
+
+void() keytrigger_use =
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ if (self.attack_finished > time)
+ return;
+
+ self.attack_finished = time + 2;
+ keylock_try_to_unlock (activator, self.message, keytrigger_unlock);
+};
+
+void() keytrigger_touch =
+{
+ activator = other;
+ keytrigger_use();
+};
+
+/*QUAKED trigger_usekey (0 .5 0) ? X X X USE_SILV_KEY USE_GOLD_KEY X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Variable sized single use trigger that requires a key to trigger targets. Must be targeted at one or more entities.
+
+"cnt" if 1, leave a used key in the player's inventory (0 default).
+"keyname" if set, this is the keyname of the item_key_custom which unlocks this entity.
+"message" is printed when the trigger is touched without having the right key.
+"noise1" sound file for the "key required" sound (default is per worldtype).
+"noise2" sound file for the "key used" sound (default is per worldtype).
+*/
+
+void() trigger_usekey =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+// the keylock_* functions use self.noise3 and self.noise4 internally,
+// but trigger_usekey doesn't use the self.noise1 or self.noise2 fields
+// for anything, so we allow the mapper to specify custom sound files by
+// setting self.noise1 and self.noise2, but we move those values into
+// self.noise3 and self.noise4 -- iw
+ self.noise3 = self.noise1;
+ self.noise4 = self.noise2;
+ self.noise1 = "";
+ self.noise2 = "";
+
+ keylock_init ();
+
+ if (self.spawnflags & USE_SILV_KEY) {//dumptruck_ds
+ keylock_set_silver_key ();
+
+ if (self.keyname != "") {
+ self.netname = self.keyname;
+ self.keyname = "";
+ }
+ }
+ if (self.spawnflags & USE_GOLD_KEY) {//dumptruck_ds
+ keylock_set_gold_key ();
+
+ if (self.keyname != "") {
+ self.netname = self.keyname;
+ self.keyname = "";
+ }
+ }
+
+// support for item_key_custom -- iw
+ if (self.keyname != "")
+ {
+ keylock_set_custom_key (self.keyname);
+ self.keyname = ""; // this should not be referenced again
+ }
+
+ if (!keylock_has_key_set ())
+ {
+ objerror ("no key specified!");
+ return;
+ }
+
+ self.use = keytrigger_use;
+ self.touch = keytrigger_touch;
+
+ InitTrigger ();
+ SUB_CheckWaiting();
+};
+
+// void() remove_touch =
+// {
+// if (other.flags & self.cnt)
+// return;
+// other.touch = SUB_Null;
+// other.model = "";
+// remove(self);
+// };
+//
+// /*QUAKED trigger_remove (.5 .5 .5) ? ignoremonsters ignoreplayers
+// Variable sized trigger that removes the thing
+// that touches it. Does not affect monsters or
+// players.
+// */
+// void() trigger_remove =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// self.cnt = FL_CLIENT|FL_MONSTER;
+// if (self.spawnflags & 1)
+// self.cnt = self.cnt - FL_MONSTER;
+// if (self.spawnflags & 2)
+// self.cnt = self.cnt - FL_CLIENT;
+// InitTrigger ();
+// self.touch = remove_touch;
+// };
+
+/*
+==============================================================================
+
+trigger_setgravity
+
+==============================================================================
+*/
+float DT_GRAVTOFF = 8; // trigger will start off
+
+void() grav_toggle = //dumptruck_ds based on hipnotic blocker_use
+{
+ if (self.estate != STATE_ACTIVE)
+ self.estate = STATE_ACTIVE;
+ else
+ self.estate = STATE_INACTIVE;
+
+};
+
+void() trigger_gravity_touch =
+{
+ // from Copper -- dumptruck_ds
+ // if (!CheckValidTouch()) return;
+
+ if (self.estate != STATE_ACTIVE) return;
+
+ local float grav;
+
+// This is commented out so that the changing gravity will
+// affect everything, if you don't want to use all affecting
+// gravity changes, then uncomment these two lines.
+// if (other.classname != "player")
+// return;
+
+ if (self.gravity == -1)
+ grav = 1;
+ else
+ grav = self.gravity;
+
+ // the player's gravity is now managed in PlayerPreThink(), however
+ // other entities don't have special gravity management, so their
+ // gravity is still set directly -- iw
+ if (other.classname == "player")
+ other.wantedgravity = grav;
+ else
+ other.gravity = grav;
+};
+
+/*QUAKED trigger_setgravity (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+set the gravity of a player
+
+"gravity" what to set the players gravity to
+ - 0 (default) normal gravity
+ - 1 no gravity
+ - 2 almost no gravity
+ - 10 is a good setting
+ - ...
+ - 101 normal gravity
+ - 102 slightly higher gravity
+ - ...
+ - 1000 very high gravity
+
+ NOTE: the amount of gravity can only be changed by touching another
+ trigger_setgravity with a different setting. The gravity key defaults to 0
+ which is normal gravity. Lower numbers (e.g. 25) equal lower gravity. Setting
+ 100 is normal gravity. Numbers above 100 will make the player “heavier”, i.e.
+ harder to jump. If you want multiple trigger setgravity triggers in one room or
+ area, make sure the brushes are not touching each other. This can cause the
+ triggers not to work properly.
+
+*/
+void() trigger_setgravity =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ InitTrigger ();
+
+ self.use = grav_toggle; // dumptruck_ds
+ self.touch = trigger_gravity_touch;
+
+ if ( self.spawnflags & DT_GRAVTOFF ) //dumptruck_ds
+ self.estate = STATE_INACTIVE;
+
+ if (!self.gravity)
+ self.gravity = -1;
+ else
+ self.gravity = ((self.gravity - 1) / 100);
+
+ SUB_CheckWaiting();
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/intermission.qc

diff --git a/qc/intermission.qc b/qc/intermission.qc
new file mode 100644
index 0000000..33b8565
--- /dev/null
+++ b/qc/intermission.qc
@@ -0,0 +1,398 @@
+/*
+=============================================================================
+
+ LEVEL CHANGING / INTERMISSION
+
+=============================================================================
+*/
+
+float intermission_running;
+float intermission_exittime;
+entity used_exit;
+
+
+/*QUAKED info_intermission (1 0.5 0.5) (-16 -16 -16) (16 16 16) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+This is the camera point for the intermission.
+Use mangle instead of angle, so you can set pitch or roll as well as yaw. 'pitch roll yaw'
+*/
+void() info_intermission =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+};
+
+
+void() info_intermissiontext =
+{
+ if (self.message == "" || self.cnt == 0)
+ {
+ objerror("endscreen lacks required fields");
+ }
+}
+
+void(string message) ShowIntermissionMessage =
+{
+ WriteByte (MSG_ALL, SVC_FINALE);
+ WriteString (MSG_ALL, message);
+}
+
+void() StartMessageIntermission =
+{
+ WriteByte (MSG_ALL, SVC_CDTRACK);
+ WriteByte (MSG_ALL, 2);
+ WriteByte (MSG_ALL, 3);
+}
+
+void() Episode1End =
+{
+ StartMessageIntermission();
+ if (!cvar("registered"))
+ {
+ ShowIntermissionMessage("As the corpse of the monstrous entity\nChthon sinks back into the lava whence\nit rose, you grip the Rune of Earth\nMagic tightly. Now that you have\nconquered the Dimension of the Doomed,\nrealm of Earth Magic, you are ready to\ncomplete your task in the other three\nhaunted lands of Quake. Or are you? If\nyou don't register Quake, you'll never\nknow what awaits you in the Realm of\nBlack Magic, the Netherworld, and the\nElder World!");
+ }
+ else
+ {
+ ShowIntermissionMessage("As the corpse of the monstrous entity\nChthon sinks back into the lava whence\nit rose, you grip the Rune of Earth\nMagic tightly. Now that you have\nconquered the Dimension of the Doomed,\nrealm of Earth Magic, you are ready to\ncomplete your task. A Rune of magic\npower lies at the end of each haunted\nland of Quake. Go forth, seek the\ntotality of the four Runes!");
+ }
+}
+
+void() Episode2End =
+{
+ StartMessageIntermission();
+ ShowIntermissionMessage("The Rune of Black Magic throbs evilly in\nyour hand and whispers dark thoughts\ninto your brain. You learn the inmost\nlore of the Hell-Mother; Shub-Niggurath!\nYou now know that she is behind all the\nterrible plotting which has led to so\nmuch death and horror. But she is not\ninviolate! Armed with this Rune, you\nrealize that once all four Runes are\ncombined, the gate to Shub-Niggurath's\nPit will open, and you can face the\nWitch-Goddess herself in her frightful\notherworld cathedral.");
+}
+
+void() Episode3End =
+{
+ StartMessageIntermission();
+ ShowIntermissionMessage("The charred viscera of diabolic horrors\nbubble viscously as you seize the Rune\nof Hell Magic. Its heat scorches your\nhand, and its terrible secrets blight\nyour mind. Gathering the shreds of your\ncourage, you shake the devil's shackles\nfrom your soul, and become ever more\nhard and determined to destroy the\nhideous creatures whose mere existence\nthreatens the souls and psyches of all\nthe population of Earth.");
+
+}
+
+void() Episode4End =
+{
+ StartMessageIntermission();
+ ShowIntermissionMessage("Despite the awful might of the Elder\nWorld, you have achieved the Rune of\nElder Magic, capstone of all types of\narcane wisdom. Beyond good and evil,\nbeyond life and death, the Rune\npulsates, heavy with import. Patient and\npotent, the Elder Being Shub-Niggurath\nweaves her dire plans to clear off all\nlife from the Earth, and bring her own\nfoul offspring to our world! For all the\ndwellers in these nightmare dimensions\nare her descendants! Once all Runes of\nmagic power are united, the energy\nbehind them will blast open the Gateway\nto Shub-Niggurath, and you can travel\nthere to foil the Hell-Mother's plots\nin person.");
+}
+
+float() RunId1Intermissions =
+{
+ if (world.skip_id1_overrides == 0)
+ {
+ if (world.model == "maps/e1m7.bsp")
+ {
+ Episode1End();
+ return 1;
+ }
+ else if (world.model == "maps/e2m6.bsp")
+ {
+ Episode2End();
+ return 1;
+ }
+ else if (world.model == "maps/e3m6.bsp")
+ {
+ Episode3End();
+ return 1;
+ }
+ else if (world.model == "maps/e4m7.bsp")
+ {
+ Episode4End();
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+============
+FindIntermission
+
+Returns the entity to view from
+============
+*/
+entity() FindIntermission =
+{
+ local entity spot;
+ local float cyc;
+
+// look for info_intermission first
+ spot = find (world, classname, "info_intermission");
+ if (spot)
+ { // pick a random one
+ cyc = random() * 4;
+ while (cyc > 1)
+ {
+ spot = find (spot, classname, "info_intermission");
+ if (!spot)
+ spot = find (spot, classname, "info_intermission");
+ cyc = cyc - 1;
+ }
+ return spot;
+ }
+
+// then look for the start position
+ spot = find (world, classname, "info_player_start");
+ if (spot)
+ return spot;
+
+// testinfo_player_start is only found in regioned levels
+ spot = find (world, classname, "testplayerstart");
+ if (spot)
+ return spot;
+
+ objerror ("FindIntermission: no spot");
+ return world;// just to suppress the compiler warning
+};
+
+
+string nextmap;
+void() GotoNextMap =
+{
+ if (cvar("samelevel")) // if samelevel is set, stay on same level
+ changelevel (mapname);
+ else
+ changelevel (nextmap);
+};
+
+float(float start) ShowIntermissionTextEntity =
+{
+ if (!(used_exit.spawnflags & 2))
+ {
+ local entity end_message;
+ for (end_message = world; (end_message = find(end_message, classname, "info_intermissiontext"));)
+ {
+ if (end_message.cnt == (intermission_running - 1))
+ {
+ if (start == 1)
+ {
+ StartMessageIntermission();
+ }
+ ShowIntermissionMessage(end_message.message);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+void() ExitIntermission =
+{
+// skip any text in deathmatch
+ if (deathmatch)
+ {
+ GotoNextMap ();
+ return;
+ }
+
+
+
+ intermission_exittime = time + 1;
+ intermission_running = intermission_running + 1;
+//
+// run some text if at the end of an episode
+//
+ if (intermission_running == 2)
+ {
+ if (RunId1Intermissions() == 1)
+ {
+ return;
+ }
+ else
+ {
+ if (used_exit.message != "") // favor message on changelevel
+ {
+ StartMessageIntermission();
+ ShowIntermissionMessage(used_exit.message);
+ return;
+ }
+ if (ShowIntermissionTextEntity(1))
+ {
+ return;
+ }
+ }
+
+ GotoNextMap();
+ }
+
+ if (intermission_running == 3)
+ {
+ if (!cvar("registered"))
+ { // shareware episode has been completed, go to sell screen
+ WriteByte (MSG_ALL, SVC_SELLSCREEN);
+ return;
+ }
+ if (ShowIntermissionTextEntity(0))
+ {
+ return;
+ }
+ if ( (serverflags&15) == 15)
+ {
+ ShowIntermissionMessage("Now, you have all four Runes. You sense\ntremendous invisible forces moving to\nunseal ancient barriers. Shub-Niggurath\nhad hoped to use the Runes Herself to\nclear off the Earth, but now instead,\nyou will use them to enter her home and\nconfront her as an avatar of avenging\nEarth-life. If you defeat her, you will\nbe remembered forever as the savior of\nthe planet. If she conquers, it will be\nas if you had never been born.");
+ return;
+
+ }
+
+ }
+
+ if (intermission_running > 3)
+ {
+ if (ShowIntermissionTextEntity(0))
+ {
+ return;
+ }
+ }
+
+ GotoNextMap();
+};
+
+/*
+============
+IntermissionThink
+
+When the player presses attack or jump, change to the next level
+============
+*/
+void() IntermissionThink =
+{
+ if (time < intermission_exittime)
+ return;
+
+ if (!self.button0 && !self.button1 && !self.button2)
+ return;
+
+ ExitIntermission ();
+};
+
+void() execute_changelevel =
+{
+ used_exit = self;
+ local entity pos;
+
+ intermission_running = 1;
+
+// enforce a wait time before allowing changelevel
+ if (deathmatch)
+ intermission_exittime = time + 5;
+ else
+ intermission_exittime = time + 2;
+
+ WriteByte (MSG_ALL, SVC_CDTRACK);
+ WriteByte (MSG_ALL, 3);
+ WriteByte (MSG_ALL, 3);
+
+ pos = FindIntermission ();
+
+ other = find (world, classname, "player");
+ while (other != world)
+ {
+ other.view_ofs = '0 0 0';
+ other.angles = other.v_angle = pos.mangle;
+ other.fixangle = TRUE; // turn this way immediately
+ other.nextthink = time + 0.5;
+ other.takedamage = DAMAGE_NO;
+ other.solid = SOLID_NOT;
+ other.movetype = MOVETYPE_NONE;
+ other.modelindex = 0;
+ setorigin (other, pos.origin);
+ other = find (other, classname, "player");
+ fog_setFromEnt(other, pos);
+ }
+ // Drake -- dumptruck_ds
+ if (cutscene)
+ { // If player was in a cutscene when the level ended, restore viewsize.
+ pos = find (world, classname, "camera");
+ if (pos)
+ {
+ local string val;
+
+ val = ftos (pos.cnt);
+ cvar_set ("viewsize", val);
+ }
+ }
+
+ WriteByte (MSG_ALL, SVC_INTERMISSION);
+};
+
+
+void() changelevel_touch =
+{
+ if (self.estate != STATE_ACTIVE) return;
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ if ((cvar("noexit") == 1) || ((cvar("noexit") == 2) && (mapname != "start")))
+ {
+ T_Damage (other, self, self, 50000);
+ return;
+ }
+
+ if (coop || deathmatch)
+ {
+ bprint (other.netname);
+ bprint (" exited the level\n");
+ }
+
+ nextmap = self.map;
+
+ SUB_UseTargets ();
+ if ( (self.spawnflags & 16) && (deathmatch == 0) ) //use info_player_start2 -- dumptruck_ds
+ {
+ sigil_touch2();
+ }
+
+ if ( (self.spawnflags & 1) && (deathmatch == 0) )
+ { // NO_INTERMISSION
+ GotoNextMap();
+ return;
+ }
+
+
+ self.touch = SUB_Null;
+
+// we can't move people right now, because touch functions are called
+// in the middle of C movement code, so set a think time to do it
+ self.think = execute_changelevel;
+ self.nextthink = time + 0.1;
+};
+
+void() dt_exit_toggle = //dumptruck_ds based on hipnotic blocker_use
+{
+ if (self.estate != STATE_ACTIVE)
+ {
+ self.is_waiting = 0;
+ self.estate = STATE_ACTIVE;
+ }
+ else
+ {
+ self.is_waiting = 1;
+ self.estate = STATE_INACTIVE;
+ }
+};
+
+
+float DT_EXITOFF = 8;
+/*QUAKED trigger_changelevel (0.5 0.5 0.5) ? NO_INTERMISSION X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+When the player touches this, he gets sent to the map listed in the "map" variable. Unless the NO_INTERMISSION flag is set, the view will go to the info_intermission spot and display stats.
+*/
+void() trigger_changelevel =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & DT_EXITOFF) //dumptruck_ds
+ {
+ self.is_waiting = 1;
+ }
+ SUB_CheckWaiting();
+
+ self.use = dt_exit_toggle;
+ if (!self.map)
+ objerror ("changelevel trigger doesn't have map");
+
+
+ InitTrigger ();
+ self.flags = self.flags | FL_NOCENTERPRINT;
+ self.touch = changelevel_touch;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/items.qc

diff --git a/qc/items.qc b/qc/items.qc
new file mode 100644
index 0000000..7bbbf1f
--- /dev/null
+++ b/qc/items.qc
@@ -0,0 +1,2441 @@
+void (vector org) spawn_tfog;
+void() W_SetCurrentAmmo;
+/* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
+BE .8 .3 .4 IN COLOR */
+
+float ITEM_SPAWNSILENT = 32;
+float ITEM_SPAWNED = 64;
+float ITEM_SUSPENDED = 128;
+float ITEM_RESPAWNDM = 16384;
+float ITEM_DONTDROP = 8388608;
+
+.vector particles_offset;
+
+void() SUB_regen =
+{
+ self.model = self.mdl; // restore original model
+ self.solid = SOLID_TRIGGER; // allow it to be touched again
+ if (deathmatch || (self.spawnflags & ITEM_RESPAWNDM)) // Respawn with DM effects
+ sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM); // play respawn sound
+ else
+ spawn_tfog (self.origin + self.particles_offset); // play teleport sound and display particles
+ setorigin (self, self.origin);
+};
+
+// Supa, Quoth respawning items support Respawn item like in DM if 'ritem' TRUE,
+// override respawn time with 'respawndelay' if set, inc 'cnt' with each respawn
+// and if 'respawncount' is set we'll remove the item if cnt > respawncount
+// remember that SUB_Regen is already set on every item that can respawn, all we
+// need to do is give a nextthink time in order to trigger it
+.float ritem,
+ respawndelay,
+ respawncount;
+
+void(entity whatitem, float defaultdelay) CheckItemRespawn =
+{
+ if (!whatitem.ritem) // respawn item if true, otherwise abort
+ return;
+
+ whatitem.cnt = whatitem.cnt + 1; // inc before check to account for zero indexing
+
+ if (whatitem.respawncount) // limited respawns
+ if (whatitem.respawncount < whatitem.cnt)
+ return;
+
+ // okay, we're clear to set up a respawn
+
+ if (whatitem.respawndelay) // custom respawn delay?
+ whatitem.nextthink = time + whatitem.respawndelay;
+ else
+ whatitem.nextthink = time + defaultdelay;
+};
+
+
+/*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
+prints a warning message when spawned
+*/
+void() noclass =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ dprint ("noclass spawned at");
+ dprint (vtos(self.origin));
+ dprint ("\n");
+ remove (self);
+};
+
+/*
+============
+DelaySpawnItem //this is from rmq-items.qc
+
+Makes a SPAWNED item ready for pickup on a trigger event - modified a bit -- dumptruck_ds
+============
+*/
+void() DelaySpawnItem =
+{
+ self.solid = SOLID_TRIGGER;
+ setmodel (self, self.mdl);
+ setsize (self, self.pos1, self.pos2);
+
+ if (!(self.spawnflags & ITEM_SPAWNSILENT)) // SILENT, gb
+ // sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);
+ spawn_tfog (self.origin + self.particles_offset);
+
+ if (self.spawnflags & ITEM_SUSPENDED)
+ self.movetype = MOVETYPE_FLY;
+ else
+ self.movetype = MOVETYPE_TOSS;
+
+ self.use = SUB_Null;
+};
+
+
+// Supa, restore old hull and lock movement
+void() RefreshHull =
+{
+ // setsize (self, self.dest, self.dest2);
+ setsize (self, '0 0 0', '32 32 56'); //dumptruck_ds -- fix for bounding boxes
+
+ self.movetype = MOVETYPE_NONE;
+ self.velocity = '0 0 0';
+};
+
+
+/*
+============
+PlaceItem
+
+plants the object on the floor
+============
+*/
+void() PlaceItem =
+{
+ // local float oldz;
+ self.mdl = self.model; // so it can be restored on respawn
+ self.flags = FL_ITEM; // make extra wide
+ self.solid = SOLID_TRIGGER;
+ self.velocity = '0 0 0';
+
+ if (self.spawnflags & ITEM_SUSPENDED) //ijed Don't drop spawnflag
+ {
+ self.movetype = MOVETYPE_FLY;
+ }
+ else
+ {
+ // The following hack for item_health was inherited from the RMQ
+ // code, and was here when the func_mapjamx maps were created.
+ // It would have been nice to remove this code entirely, because
+ // progs_dump doesn't need it, and it breaks item_health's
+ // collision with entities that have MOVETYPE_PUSH. However,
+ // removing this code would cause some of the item_health
+ // entities in some of the func_mapjamx maps to "fall out of the
+ // level", because they're accidentally touching solid surfaces.
+ // So, to maintain backwards-compatibility, this code has been
+ // left in, but will only be run if one of the func_mapjamx maps
+ // is being played. -- iw
+ //
+ if (known_release == KNOWN_RELEASE_FUNC_MAPJAMX)
+ {
+ if (self.classname == "item_health") // Supa, CTF
+ {
+
+ // hacking around hull issues..
+ setsize (self, '0 0 0', '0 0 0'); // void hull for now
+
+ self.think = RefreshHull;
+ self.nextthink = time + 0.2;
+ }
+ }
+
+ self.movetype = MOVETYPE_TOSS;
+
+ if (!(self.spawnflags & ITEM_DONTDROP))
+ {
+ setorigin (self, self.origin + '0 0 6');
+
+ if (!droptofloor())
+ {
+ print_self ("bonus item", "fell out of level");
+ remove(self);
+ return;
+ }
+ }
+ }
+
+ if ((self.spawnflags & ITEM_SPAWNED)) // SPAWNED, gb
+ {
+ self.pos1 = self.mins;
+ self.pos2 = self.maxs;
+
+ self.model = "";
+ self.solid = SOLID_NOT;
+
+ if (self.spawnflags & ITEM_DONTDROP) self.movetype = MOVETYPE_NONE;
+
+ self.use = DelaySpawnItem;
+ }
+};
+
+
+/*
+============
+StartItem
+
+Sets the clipping size and plants the object on the floor
+============
+*/
+void() StartItem =
+{
+ self.nextthink = time + 0.3; // items start after other solids || was 0.2 -- dumptruck_ds
+ self.think = PlaceItem;
+};
+
+/*
+=========================================================================
+
+HEALTH BOX
+
+=========================================================================
+*/
+//
+// T_Heal: add health to an entity, limiting health to max_health
+// "ignore" will ignore max_health limit
+//
+float (entity e, float healamount, float ignore) T_Heal =
+{
+ if (e.health <= 0)
+ return 0;
+ if ((!ignore) && (e.health >= other.max_health))
+ return 0;
+ healamount = ceil(healamount);
+
+ e.health = e.health + healamount;
+ if ((!ignore) && (e.health >= other.max_health))
+ e.health = other.max_health;
+
+ if (e.health > 250)
+ e.health = 250;
+ return 1;
+};
+
+/*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) ROTTEN MEGAHEALTH X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ( {{ spawnflags & 1 -> { "path" : "maps/b_bh10.bsp" }, spawnflags & 2 -> { "path" : "maps/b_bh100.bsp" },
+ "maps/b_bh25.bsp" }} );
+}
+Health box. Normally gives 25 points.
+Rotten box heals 15 points.
+Megahealth will add 100 health, then start to
+rot the player back down to 100 health after 5 seconds.
+*/
+
+float H_ROTTEN = 1;
+float H_MEGA = 2;
+float H_VIAL = 4;
+.float healamount, healtype;
+void() health_touch;
+// void() item_megahealth_rot;
+
+void() item_health =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = health_touch;
+
+
+
+ if (self.spawnflags & H_ROTTEN)
+ {
+ if (!self.mdl_body && world.h_15_mdl)
+ {
+ self.mdl_body = world.h_15_mdl;
+ }
+ // precache_model("maps/b_bh10.bsp"); // dumptruck_ds custom health models and sounds START
+ if (world.style)
+ {
+ precache_body_model ("progs/h_mdls/m_h15.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/h_mdls/m_h15.mdl");
+ }
+ else
+ {
+ // setmodel(self, "maps/b_bh10.bsp");
+ precache_body_model ("maps/b_bh10.bsp");
+ body_model ("maps/b_bh10.bsp");
+ }
+ // precache_sound("items/r_item1.wav");
+ precache_sound_misc("items/r_item1.wav");
+ // self.noise = "items/r_item1.wav";
+ if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
+ self.snd_misc = "items/r_item1.wav";
+ self.noise = self.snd_misc;
+
+ // if !(self.healamount) //set your custom health amount here -- dumptruck_ds
+ self.healamount = 15;
+ self.healtype = 0;
+ if !(self.particles_offset)
+ self.particles_offset = '16 16 8'; // dumptruck_ds custom health models and sounds END
+
+ }
+ else
+ if (self.spawnflags & H_MEGA)
+ {
+ if (!self.mdl_body && world.h_mega_mdl)
+ {
+ self.mdl_body = world.h_mega_mdl;
+ }
+ // precache_model("maps/b_bh100.bsp");
+ if (world.style)
+ {
+ precache_body_model ("progs/h_mdls/m_h100.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/h_mdls/m_h100.mdl");
+ }
+ else
+ {
+ // setmodel(self, "maps/b_bh100.bsp");
+ precache_body_model ("maps/b_bh100.bsp");
+ body_model ("maps/b_bh100.bsp");
+ }
+ precache_sound_misc("items/r_item2.wav");
+ // self.noise = "items/r_item2.wav";
+ if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
+ self.snd_misc = "items/r_item2.wav";
+ self.noise = self.snd_misc;
+
+ // if !(self.healamount) //set your custom health amount here -- dumptruck_ds
+ self.healamount = 100;
+ self.healtype = 2;
+ if !(self.particles_offset)
+ self.particles_offset = '16 16 16';
+ }
+ else
+ {
+ if (!self.mdl_body && world.h_25_mdl)
+ {
+ self.mdl_body = world.h_25_mdl;
+ }
+ if (world.style)
+ {
+ precache_body_model ("progs/h_mdls/m_h25.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/h_mdls/m_h25.mdl");
+ }
+ else
+ {
+ precache_body_model ("maps/b_bh25.bsp");
+ body_model ("maps/b_bh25.bsp");
+ }
+ precache_sound_misc("items/health1.wav");
+ if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
+ self.snd_misc = "items/health1.wav";
+ self.noise = self.snd_misc;
+
+ self.healamount = 25;
+ self.healtype = 1;
+ if !(self.particles_offset)
+ self.particles_offset = '16 16 8'; // dumptruck_ds custom health models and sounds END
+ }
+ setsize (self, '0 0 0', '32 32 56');
+ StartItem ();
+};
+
+void() item_health_vial =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = health_touch;
+
+ if (!self.mdl_body && world.h_vial_mdl)
+ {
+ self.mdl_body = world.h_vial_mdl;
+ }
+
+ precache_body_model ("progs/h_mdls/pd_vial.mdl"); // model from Hexen 2 -- dumptruck_ds
+ body_model("progs/h_mdls/pd_vial.mdl");
+ precache_sound_misc("items/r_item1.wav");
+ if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
+ self.snd_misc = "items/r_item1.wav";
+ self.noise = self.snd_misc;
+
+ self.healamount = 5;
+ self.healtype = 2; // over heal and count down like mega health -- dumptruck_ds
+ setsize (self, '-16 -16 0', '16 16 56');
+ if !(self.particles_offset)
+ self.particles_offset = '0 0 0';
+ StartItem ();
+};
+
+void() health_touch =
+{
+ local float amount;
+ local string s;
+ amount = self.healamount;
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ if (self.healtype == 2) // Megahealth? Ignore max_health...
+ {
+ if (other.health >= 250)
+ return;
+ if (!T_Heal(other, amount, 1))
+ return;
+ }
+ else
+ {
+ if (!T_Heal(other, amount, 0))
+ return;
+ }
+
+ sprint(other, "You receive ");
+ s = ftos(amount);
+ sprint(other, s);
+ sprint(other, " health\n");
+
+// health touch sound
+ // sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
+ sound_misc(other, CHAN_AUTO, self.noise, 1, ATTN_NORM); //custom sounds -- dumptruck_ds
+
+ stuffcmd (other, "bf\n");
+
+ self.model = string_null;
+ self.solid = SOLID_NOT;
+
+ self.think = SUB_regen;
+
+ // Megahealth = rot down the player's super health
+ if (self.healtype == 2)
+ {
+ other.megahealth_rottime = time + 5; //thanks ydrol!!!
+ other.items = other.items | IT_SUPERHEALTH;
+ self.owner = other;
+
+ // Regarding the deathmatch respawn time below: id's original
+ // code made the megahealth respawn 20 seconds after the health
+ // of the player who collected it finished rotting down.
+ // However, this mod has already got rid of the weird old
+ // megahealth behavior whereby it monitored the player who
+ // touched it, so the original respawn logic isn't applicable.
+ // As a solution, the code below uses a respawn time of 125
+ // seconds for deathmatch, because that was the worst-case
+ // scenario of id's original code (5 seconds before the player's
+ // health started to rot, plus 100 seconds to rot down 100
+ // health points, plus the original 20 second delay before the
+ // item respawned). -- iw
+ //
+ if (!deathmatch)
+ CheckItemRespawn(self, 30);
+ else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
+ self.nextthink = time + 125;
+ }
+ else
+ {
+ if (!deathmatch)
+ CheckItemRespawn(self, 30);
+ else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
+ self.nextthink = time + 20;
+ }
+
+ activator = other;
+ SUB_UseTargets(); // fire all targets / killtargets
+};
+
+/*
+===============================================================================
+
+ARMOR
+
+===============================================================================
+*/
+
+void() armor_touch;
+void() shard_touch;
+
+
+void() shard_touch = // this from RMQ shard_touch
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ local float bit;
+
+ if ((other.items & IT_ARMOR1) ||
+ (other.items & IT_ARMOR2) ||
+ (other.items & IT_ARMOR3) ) // has armor
+ {
+ // Supa, check bounds, original armourvalue + 25
+ if (other.items & IT_ARMOR1 && other.armorvalue >= 125) return;
+ if (other.items & IT_ARMOR2 && other.armorvalue >= 175) return;
+ if (other.items & IT_ARMOR3 && other.armorvalue >= 225) return;
+
+ other.armorvalue = other.armorvalue + 5; // was 2, RMQ team
+
+ // Supa, now cap armourvalue to bounds
+ if (other.items & IT_ARMOR1 && other.armorvalue >= 125) other.armorvalue = 125;
+ else if (other.items & IT_ARMOR2 && other.armorvalue >= 175) other.armorvalue = 175;
+ else if (other.items & IT_ARMOR3 && other.armorvalue >= 225) other.armorvalue = 225;
+ }
+ else
+ {
+ other.armortype = 0.3; // shard = Green armor level
+ other.armorvalue = 5;
+ bit = IT_ARMOR1;
+ other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
+ }
+ self.solid = SOLID_NOT;
+ self.model = string_null;
+
+ // Supa, SP respawning items support
+ if (!deathmatch)
+ CheckItemRespawn(self, 30);
+ else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
+ self.nextthink = time + 20;
+ self.think = SUB_regen;
+
+ if (self.obit_name != "")
+ {
+ sprint (other, "You got ");
+ sprint (other, self.obit_name); // custom armor name
+ sprint (other, "\n");
+ }
+ else
+ sprint(other, "You got armor\n");
+ // armor touch sound
+ // sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM); // dumptruck_ds custom models and sounds START
+ if (self.snd_misc != "")
+ sound_misc(other, CHAN_AUTO, self.snd_misc, 1, ATTN_NORM);
+ else
+ sound_misc(other, CHAN_AUTO,"dump/armsh1.wav", 1, ATTN_NORM); // dumptruck_ds custom models and sounds END
+ stuffcmd (other, "bf\n");
+
+ activator = other;
+ SUB_UseTargets(); // fire all targets / killtargets
+};
+
+void() armor_touch =
+{
+ local float type, value, bit;
+
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ if (self.classname == "item_armor1")
+ {
+ type = 0.3;
+ value = 100;
+ bit = IT_ARMOR1;
+ }
+ else if (self.classname == "item_armor2")
+ {
+ type = 0.6;
+ value = 150;
+ bit = IT_ARMOR2;
+ }
+ else if (self.classname == "item_armorInv")
+ {
+ type = 0.8;
+ value = 200;
+ bit = IT_ARMOR3;
+ }
+ else
+ {
+ dprint ("WARNING: armor_touch: unknown classname: ");
+ dprint (self.classname);
+ dprint ("\n");
+ return;
+ }
+
+ if (other.armortype*other.armorvalue >= type*value)
+ return;
+
+ other.armortype = type;
+ other.armorvalue = value;
+
+ other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
+
+ self.solid = SOLID_NOT;
+ self.model = string_null;
+ // Supa, SP respawning items support
+ if (!deathmatch)
+ CheckItemRespawn(self, 30);
+ else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
+ self.nextthink = time + 20;
+ self.think = SUB_regen;
+
+ if (self.obit_name != "")
+ {
+ sprint (other, "You got ");
+ sprint (other, self.obit_name); // custom armor name
+ sprint (other, "\n");
+ }
+ else
+ sprint(other, "You got armor\n");
+// armor touch sound
+ // sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM); // dumptruck_ds custom models and sounds START
+ if (self.snd_misc != "")
+ sound_misc(other, CHAN_ITEM, self.snd_misc, 1, ATTN_NORM);
+ else
+ sound_misc(other, CHAN_ITEM,"items/armor1.wav", 1, ATTN_NORM); // dumptruck_ds custom models and sounds END
+ stuffcmd (other, "bf\n");
+
+ activator = other;
+ SUB_UseTargets(); // fire all targets / killtargets
+};
+
+/*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/armor.mdl");
+}
+*/
+
+void() item_armor_shard =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.mdl_body && world.a_shr_mdl)
+ {
+ self.mdl_body = world.a_shr_mdl;
+ }
+
+ self.touch = shard_touch;
+ // precache_model ("progs/armor.mdl"); // dumptruck_ds custom models and sounds START
+ precache_body_model ("progs/armshr.mdl");
+ // setmodel (self, "progs/armor.mdl");
+ body_model ("progs/armshr.mdl");
+ precache_sound_misc ("dump/armsh1.wav");
+ if !(self.skin) // dumptruck_ds custom models and sounds END
+ self.skin = 0;
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};
+
+void() item_armor1 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.mdl_body && world.a_grn_mdl)
+ {
+ self.mdl_body = world.a_grn_mdl;
+ }
+
+ self.touch = armor_touch;
+ // precache_model ("progs/armor.mdl"); // dumptruck_ds custom models and sounds START
+ precache_body_model ("progs/armor.mdl");
+ // setmodel (self, "progs/armor.mdl");
+ body_model ("progs/armor.mdl");
+ precache_sound_misc ("items/armor1.wav");
+ if !(self.skin) // dumptruck_ds custom models and sounds END
+ self.skin = 0;
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};
+
+/*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model({ "path": ":progs/armor.mdl", "skin": 1 }); }
+*/
+
+void() item_armor2 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.mdl_body && world.a_ylw_mdl)
+ {
+ self.mdl_body = world.a_ylw_mdl;
+ }
+
+ self.touch = armor_touch;
+ // precache_model ("progs/armor.mdl"); // dumptruck_ds custom models and sounds START
+ precache_body_model ("progs/armor.mdl");
+ // setmodel (self, "progs/armor.mdl");
+ body_model ("progs/armor.mdl");
+ if !(self.skin) // dumptruck_ds custom models and sounds END
+ self.skin = 1;
+ precache_sound_misc ("items/armor1.wav");
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};
+
+/*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model({ "path": ":progs/armor.mdl", "skin": 2 });
+}
+*/
+
+void() item_armorInv =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.mdl_body && world.a_red_mdl)
+ {
+ self.mdl_body = world.a_red_mdl;
+ }
+
+ self.touch = armor_touch;
+ // precache_model ("progs/armor.mdl"); // dumptruck_ds custom models and sounds START
+ precache_body_model ("progs/armor.mdl");
+ // setmodel (self, "progs/armor.mdl");
+ body_model ("progs/armor.mdl");
+ if !(self.skin) // dumptruck_ds custom models and sounds END
+ self.skin = 2;
+ precache_sound_misc ("items/armor1.wav");
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};
+
+/*
+===============================================================================
+
+WEAPONS
+
+===============================================================================
+*/
+
+void() bound_other_ammo =
+{
+ if (other.ammo_shells > 100)
+ other.ammo_shells = 100;
+ if (other.ammo_nails > 200)
+ other.ammo_nails = 200;
+ if (other.ammo_rockets > 100)
+ other.ammo_rockets = 100;
+ if (other.ammo_cells > 100)
+ other.ammo_cells = 100;
+};
+
+
+float(float w) RankForWeapon =
+{
+ if (self.waterlevel <= 1 && w == IT_LIGHTNING) // 1997-12-23 Thunderbolt fix by Maddes recognize waterlevel
+ return 1;
+ if (w == IT_ROCKET_LAUNCHER)
+ return 2;
+ if (w == IT_SUPER_NAILGUN)
+ return 3;
+ if (w == IT_GRENADE_LAUNCHER)
+ return 4;
+ if (w == IT_SUPER_SHOTGUN)
+ return 5;
+ if (w == IT_NAILGUN)
+ return 6;
+ if (w == IT_SHOTGUN)
+ return 7;
+ return 8;
+};
+
+/*
+=============
+Deathmatch_Weapon
+
+Deathmatch weapon change rules for picking up a weapon
+
+.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
+=============
+*/
+void(float old, float new) Deathmatch_Weapon =
+{
+ local float or, nr;
+
+// change self.weapon if desired
+ or = RankForWeapon (self.weapon);
+ nr = RankForWeapon (new);
+ if ( nr < or )
+ self.weapon = new;
+};
+
+/*
+=============
+weapon_touch
+=============
+*/
+float() W_BestWeapon;
+
+void() weapon_touch =
+{
+ local float hadammo, best, new, old;
+ local entity stemp;
+ local float leave;
+
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ if (!(other.flags & FL_CLIENT))
+ return;
+
+// if the player was using his best weapon, change up to the new one if better
+ stemp = self;
+ self = other;
+ best = W_BestWeapon();
+ self = stemp;
+
+ if (deathmatch == 2 || coop)
+ {
+ leave = 1;
+
+ // fix weapon items never firing their targets in coop or
+ // "deathmatch 2" -- iw
+ activator = other;
+ SUB_UseAndForgetTargets ();
+ }
+ else
+ {
+ leave = 0;
+ }
+
+ // johnfitz added for axe, shotgun items --dumptruck_ds from RRP /rubicon2
+ if (self.classname == "weapon_axe")
+ {
+ if (leave && (other.items & IT_AXE) )
+ return;
+ new = IT_AXE;
+ }
+ else if (self.classname == "weapon_shotgun")
+ {
+ if (leave && (other.items & IT_SHOTGUN) )
+ return;
+ hadammo = other.ammo_shells;
+ new = IT_SHOTGUN;
+ other.ammo_shells = other.ammo_shells + 5;
+ }
+ // johnfitz
+
+ else if (self.classname == "weapon_nailgun")
+ {
+ if (leave && (other.items & IT_NAILGUN) )
+ return;
+ hadammo = other.ammo_nails;
+ new = IT_NAILGUN;
+ other.ammo_nails = other.ammo_nails + 30;
+ }
+ else if (self.classname == "weapon_supernailgun")
+ {
+ if (leave && (other.items & IT_SUPER_NAILGUN) )
+ return;
+ hadammo = other.ammo_rockets;
+ new = IT_SUPER_NAILGUN;
+ other.ammo_nails = other.ammo_nails + 30;
+ }
+ else if (self.classname == "weapon_supershotgun")
+ {
+ if (leave && (other.items & IT_SUPER_SHOTGUN) )
+ return;
+ hadammo = other.ammo_rockets;
+ new = IT_SUPER_SHOTGUN;
+ other.ammo_shells = other.ammo_shells + 5;
+ }
+ else if (self.classname == "weapon_rocketlauncher")
+ {
+ if (leave && (other.items & IT_ROCKET_LAUNCHER) )
+ return;
+ hadammo = other.ammo_rockets;
+ new = IT_ROCKET_LAUNCHER;
+ other.ammo_rockets = other.ammo_rockets + 5;
+ }
+ else if (self.classname == "weapon_grenadelauncher")
+ {
+ if (leave && (other.items & IT_GRENADE_LAUNCHER) )
+ return;
+ hadammo = other.ammo_rockets;
+ new = IT_GRENADE_LAUNCHER;
+ other.ammo_rockets = other.ammo_rockets + 5;
+ }
+ else if (self.classname == "weapon_lightning")
+ {
+ if (leave && (other.items & IT_LIGHTNING) )
+ return;
+ hadammo = other.ammo_rockets;
+ new = IT_LIGHTNING;
+ other.ammo_cells = other.ammo_cells + 15;
+ }
+ else
+ {
+ objerror ("weapon_touch: unknown classname");
+ return;
+ }
+
+ sprint (other, "You got the ");
+ sprint (other, self.netname);
+ sprint (other, "\n");
+// weapon touch sound
+ sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
+ stuffcmd (other, "bf\n");
+
+ bound_other_ammo ();
+
+// change to the weapon
+ old = other.items;
+ other.items = other.items | new;
+
+ stemp = self;
+ self = other;
+
+// 1997-12-23 Thunderbolt fix by Maddes start
+/* don't separate between SinglePlayer/Coop and Deathmatch
+ if (!deathmatch)
+ self.weapon = new;
+ else
+*/
+// 1997-12-23 Thunderbolt fix by Maddes end
+ Deathmatch_Weapon (old, new);
+
+ W_SetCurrentAmmo();
+
+ self = stemp;
+
+ if (leave)
+ return;
+
+// remove it in single player, or setup for respawning in deathmatch
+ self.model = string_null;
+ self.solid = SOLID_NOT;
+ // Supa, SP respawning items support
+ if (!deathmatch)
+ CheckItemRespawn(self, 30);
+ else if (deathmatch == 1) // weapons never disappear in "deathmatch 2"
+ self.nextthink = time + 30;
+
+ self.think = SUB_regen;
+
+ activator = other;
+ SUB_UseTargets(); // fire all targets / killtargets
+};
+
+// johnfitz new items -- dumptruck_ds from RRP and rubicon2
+/*QUAKED weapon_axe (0 .5 .8) (-16 -16 0) (16 16 32)
+Axe
+*/
+void() weapon_axe =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/g_axe.mdl");
+ setmodel (self, "progs/g_axe.mdl");
+ self.weapon = IT_AXE;
+ self.netname = "Axe";
+ self.touch = weapon_touch;
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};
+/*QUAKED weapon_shotgun (0 .5 .8) (-16 -16 0) (16 16 32) X STYLE_1 STYLE_2 X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/g_shotgn.mdl"); }
+This is a pickup model that should be used when you want a player to spawn with only an axe and then later get the shotgun: (trigger_take_weapon or reset_items 2 in worldspawn). There are two models to choose from. Spawnflag 2 (the default) selects an unused “classic look” model from Rubicon 2 by metlslime. Spawnflag 4 is an alternate from Slapmap and has been used in a few mods.
+Single-barrelled Shotgun
+Shotgun
+*/
+
+void() weapon_shotgun =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/g_shotgu.mdl");
+ setmodel (self, "progs/g_shotgu.mdl"); //new shotgun model by Starshipwaters -dumptruck_ds - removed 2 older shotguns that used spawnflags
+ self.weapon = IT_SHOTGUN;
+ self.netname = "Shotgun";
+ self.touch = weapon_touch;
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};
+// johnfitz
+
+/*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/g_shot.mdl"); }
+Double-barrelled Shotgun
+*/
+
+void() weapon_supershotgun =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/g_shot.mdl");
+ setmodel (self, "progs/g_shot.mdl");
+ self.weapon = IT_SUPER_SHOTGUN;
+ self.netname = "Double-barrelled Shotgun";
+ self.touch = weapon_touch;
+ setsize (self, '-16 -16 0', '16 16 56');
+ self.particles_offset = '0 0 33';
+ StartItem ();
+};
+
+/*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/g_nail.mdl"); }
+Nailgun
+*/
+
+void() weapon_nailgun =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/g_nail.mdl");
+ setmodel (self, "progs/g_nail.mdl");
+ self.weapon = IT_NAILGUN;
+ self.netname = "nailgun";
+ self.touch = weapon_touch;
+ setsize (self, '-16 -16 0', '16 16 56');
+ self.particles_offset = '0 0 31';
+ StartItem ();
+};
+
+/*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/g_nail2.mdl"); }
+Perforator
+*/
+
+void() weapon_supernailgun =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/g_nail2.mdl");
+ setmodel (self, "progs/g_nail2.mdl");
+ self.weapon = IT_SUPER_NAILGUN;
+ self.netname = "Super Nailgun";
+ self.touch = weapon_touch;
+ setsize (self, '-16 -16 0', '16 16 56');
+ self.particles_offset = '0 0 34';
+ StartItem ();
+};
+
+/*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/g_rock.mdl"); }
+Grenade Launcher
+*/
+
+void() weapon_grenadelauncher =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/g_rock.mdl");
+ setmodel (self, "progs/g_rock.mdl");
+ self.weapon = 3;
+ self.netname = "Grenade Launcher";
+ self.touch = weapon_touch;
+ setsize (self, '-16 -16 0', '16 16 56');
+ self.particles_offset = '0 0 28';
+ StartItem ();
+};
+
+/*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/g_rock2.mdl"); }
+Rocket Launcher
+*/
+
+void() weapon_rocketlauncher =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/g_rock2.mdl");
+ setmodel (self, "progs/g_rock2.mdl");
+ self.weapon = 3;
+ self.netname = "Rocket Launcher";
+ self.touch = weapon_touch;
+ setsize (self, '-16 -16 0', '16 16 56');
+ self.particles_offset = '0 0 32';
+ StartItem ();
+};
+
+
+/*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/g_light.mdl"); }
+Thunderbolt
+*/
+
+void() weapon_lightning =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/g_light.mdl");
+ setmodel (self, "progs/g_light.mdl");
+ self.weapon = 3;
+ self.netname = "Thunderbolt";
+ self.touch = weapon_touch;
+ setsize (self, '-16 -16 0', '16 16 56');
+ self.particles_offset = '0 0 31';
+ StartItem ();
+};
+
+
+/*
+===============================================================================
+
+AMMO
+
+===============================================================================
+*/
+
+void() ammo_touch =
+{
+local entity stemp;
+local float best;
+
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+// if the player was using his best weapon, change up to the new one if better
+ stemp = self;
+ self = other;
+ best = W_BestWeapon();
+ self = stemp;
+
+
+// shotgun
+ if (self.weapon == 1)
+ {
+ if (other.ammo_shells >= 100)
+ return;
+ other.ammo_shells = other.ammo_shells + self.aflag;
+ }
+
+// spikes
+ if (self.weapon == 2)
+ {
+ if (other.ammo_nails >= 200)
+ return;
+ other.ammo_nails = other.ammo_nails + self.aflag;
+ }
+
+// rockets
+ if (self.weapon == 3)
+ {
+ if (other.ammo_rockets >= 100)
+ return;
+ other.ammo_rockets = other.ammo_rockets + self.aflag;
+ }
+
+// cells
+ if (self.weapon == 4)
+ {
+ if (other.ammo_cells >= 100)
+ return;
+ other.ammo_cells = other.ammo_cells + self.aflag;
+ }
+
+ bound_other_ammo ();
+
+ sprint (other, "You got the ");
+ sprint (other, self.netname);
+ sprint (other, "\n");
+// ammo touch sound
+ sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
+ stuffcmd (other, "bf\n");
+
+// change to a better weapon if appropriate
+
+ if ( other.weapon == best )
+ {
+ stemp = self;
+ self = other;
+ self.weapon = W_BestWeapon();
+ W_SetCurrentAmmo ();
+ self = stemp;
+ }
+
+// if changed current ammo, update it
+ stemp = self;
+ self = other;
+ W_SetCurrentAmmo();
+ self = stemp;
+
+// remove it in single player, or setup for respawning in deathmatch
+ self.model = string_null;
+ self.solid = SOLID_NOT;
+ if (!deathmatch)
+ CheckItemRespawn(self, 30);
+ else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
+ self.nextthink = time + 30;
+ self.think = SUB_regen;
+
+ activator = other;
+ SUB_UseTargets(); // fire all targets / killtargets
+};
+
+
+
+
+float WEAPON_BIG2 = 1;
+
+/*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) LARGE_BOX X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ( {{ spawnflags & 1 -> { "path" : "maps/b_shell1.bsp" }, "maps/b_shell0.bsp" }} );
+}
+Box of 20 shells.
+LARGE_BOX is a box of 40 shells.
+*/
+
+void() item_shells =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = ammo_touch;
+
+
+
+ if (self.spawnflags & WEAPON_BIG2)
+ {
+ if (!self.mdl_body && world.s_lg_mdl) self.mdl_body = world.s_lg_mdl;
+ if (world.style)
+ {
+ precache_body_model ("progs/a_mdls/m_shell2.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/a_mdls/m_shell2.mdl");
+ }
+ // precache_model ("maps/b_shell1.bsp");
+ // setmodel (self, "maps/b_shell1.bsp");
+ else
+ {
+ precache_body_model ("maps/b_shell1.bsp");
+ body_model ("maps/b_shell1.bsp");
+ }
+ if !(self.particles_offset)
+ self.particles_offset = '16 16 16';
+ self.aflag = 40;
+ }
+ else
+ {
+ if (!self.mdl_body && world.s_sm_mdl) self.mdl_body = world.s_sm_mdl;
+ if (world.style)
+ {
+ precache_body_model ("progs/a_mdls/m_shell1.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/a_mdls/m_shell1.mdl");
+ }
+ else
+ {
+ precache_body_model ("maps/b_shell0.bsp");
+ body_model ("maps/b_shell0.bsp");
+ }
+ // precache_model ("maps/b_shell0.bsp");
+ // setmodel (self, "maps/b_shell0.bsp");
+ if !(self.particles_offset)
+ self.particles_offset = '12 12 12';
+ self.aflag = 20;
+ }
+ self.weapon = 1;
+ self.netname = "shells";
+ setsize (self, '0 0 0', '32 32 56');
+ StartItem ();
+};
+
+/*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) LARGE_BOX X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ( {{ spawnflags & 1 -> { "path" : "maps/b_nail1.bsp" }, "maps/b_nail0.bsp" }} );
+}
+Box of 25 nails.
+LARGE_BOX is a box of 50 nails.
+*/
+
+void() item_spikes =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = ammo_touch;
+
+ if (self.spawnflags & WEAPON_BIG2)
+ {
+ if (!self.mdl_body && world.n_lg_mdl) self.mdl_body = world.n_lg_mdl;
+ if (world.style)
+ {
+ precache_body_model ("progs/a_mdls/m_nails2.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/a_mdls/m_nails2.mdl");
+ }
+ else
+ {
+ precache_body_model ("maps/b_nail1.bsp");
+ body_model ("maps/b_nail1.bsp");
+ }
+ // precache_model ("maps/b_nail1.bsp");
+ // setmodel (self, "maps/b_nail1.bsp");
+ if !(self.particles_offset)
+ self.particles_offset = '16 16 16';
+ self.aflag = 50;
+ }
+ else
+ {
+
+ if (!self.mdl_body && world.n_sm_mdl) self.mdl_body = world.n_sm_mdl;
+ if (world.style)
+ {
+ precache_body_model ("progs/a_mdls/m_nails1.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/a_mdls/m_nails1.mdl");
+ }
+ else
+ {
+ precache_body_model ("maps/b_nail0.bsp");
+ body_model ("maps/b_nail0.bsp");
+ }
+ // precache_model ("maps/b_nail0.bsp");
+ // setmodel (self, "maps/b_nail0.bsp");
+ if !(self.particles_offset)
+ self.particles_offset = '12 12 12';
+ self.aflag = 25;
+ }
+ self.weapon = 2;
+ self.netname = "nails";
+ setsize (self, '0 0 0', '32 32 56');
+ StartItem ();
+};
+
+/*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) LARGE_BOX X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ( {{ spawnflags & 1 -> { "path" : "maps/b_rock1.bsp" }, "maps/b_rock0.bsp" }} );
+}
+*/
+
+void() item_rockets =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = ammo_touch;
+
+ if (self.spawnflags & WEAPON_BIG2)
+ {
+
+ if (!self.mdl_body && world.r_lg_mdl) self.mdl_body = world.r_lg_mdl;
+ if (world.style)
+ {
+ precache_body_model ("progs/a_mdls/m_rock2.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/a_mdls/m_rock2.mdl");
+ }
+ else
+ {
+ precache_body_model ("maps/b_rock1.bsp");
+ body_model ("maps/b_rock1.bsp");
+ }
+ // precache_model ("maps/b_rock1.bsp");
+ // setmodel (self, "maps/b_rock1.bsp");
+ self.particles_offset = '16 8 16';
+ self.aflag = 10;
+ }
+ else
+ {
+ if (!self.mdl_body && world.r_sm_mdl) self.mdl_body = world.r_sm_mdl;
+ if (world.style)
+ {
+ precache_body_model ("progs/a_mdls/m_rock1.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/a_mdls/m_rock1.mdl");
+ }
+ else
+ {
+ precache_body_model ("maps/b_rock0.bsp");
+ body_model ("maps/b_rock0.bsp");
+ }
+ // precache_model ("maps/b_rock0.bsp");
+ // setmodel (self, "maps/b_rock0.bsp");
+ if !(self.particles_offset)
+ self.particles_offset = '8 8 16';
+ self.aflag = 5;
+ }
+ self.weapon = 3;
+ self.netname = "rockets";
+ setsize (self, '0 0 0', '32 32 56');
+ StartItem ();
+};
+
+
+/*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) LARGE_BOX X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ( {{ spawnflags & 1 -> { "path" : "maps/b_batt1.bsp" }, "maps/b_batt0.bsp" }} );
+}
+Box of 6 cells.
+LARGE_BOX is a box of 12 cells.
+*/
+
+void() item_cells =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = ammo_touch;
+
+ if (self.spawnflags & WEAPON_BIG2)
+ {
+ if (!self.mdl_body && world.c_lg_mdl) self.mdl_body = world.c_lg_mdl;
+ if (world.style)
+ {
+ precache_body_model ("progs/a_mdls/m_cells2.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/a_mdls/m_cells2.mdl");
+ }
+ else
+ {
+ precache_body_model ("maps/b_batt1.bsp");
+ body_model ("maps/b_batt1.bsp");
+ }
+ // precache_model ("maps/b_batt1.bsp");
+ // setmodel (self, "maps/b_batt1.bsp");
+ if !(self.particles_offset)
+ self.particles_offset = '16 16 16';
+ self.aflag = 12;
+ }
+ else
+ {
+ if (!self.mdl_body && world.c_sm_mdl) self.mdl_body = world.c_sm_mdl;
+ if (world.style)
+ {
+ precache_body_model ("progs/a_mdls/m_cells2.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/a_mdls/m_cells2.mdl");
+ }
+ else
+ {
+ precache_body_model ("maps/b_batt0.bsp");
+ body_model ("maps/b_batt0.bsp");
+ }
+ // precache_model ("maps/b_batt0.bsp");
+ // setmodel (self, "maps/b_batt0.bsp");
+ if !(self.particles_offset)
+ self.particles_offset = '12 12 12';
+ self.aflag = 6;
+ }
+ self.weapon = 4;
+ self.netname = "cells";
+ setsize (self, '0 0 0', '32 32 56');
+ StartItem ();
+};
+
+
+/*
+===============================================================================
+
+KEYS
+
+===============================================================================
+*/
+
+
+void() key_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+// support for item_key_custom -- iw
+ if (HasKeys (other, self.items, self.customkeys))
+ return;
+
+ sprint (other, "You got the ");
+ sprint (other, self.netname);
+ sprint (other,"\n");
+
+ sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
+ stuffcmd (other, "bf\n");
+
+// support for item_key_custom -- iw
+ GiveKeys (other, self.items, self.customkeys);
+
+ if (!coop)
+ {
+ self.solid = SOLID_NOT;
+ self.model = string_null;
+ }
+
+ activator = other;
+// fix key items firing their targets multiple times in coop -- iw
+// SUB_UseTargets(); // fire all targets / killtargets
+ SUB_UseAndForgetTargets();
+};
+
+
+void() key_setsounds =
+{
+// support for item_key_custom -- iw
+ if (self.noise != "")
+ {
+ precache_sound (self.noise);
+ return;
+ }
+
+ if (world.worldtype == WORLDTYPE_MEDIEVAL)
+ {
+ precache_sound ("misc/medkey.wav");
+ self.noise = "misc/medkey.wav";
+ }
+ if (world.worldtype == WORLDTYPE_METAL)
+ {
+ precache_sound ("misc/runekey.wav");
+ self.noise = "misc/runekey.wav";
+ }
+ if (world.worldtype == WORLDTYPE_BASE)
+ {
+ precache_sound2 ("misc/basekey.wav");
+ self.noise = "misc/basekey.wav";
+ }
+};
+
+
+/*
+============
+key_start
+
+Finish initializing self as a key item. -- iw
+============
+*/
+void() key_start =
+{
+ key_setsounds ();
+ self.particles_offset = '0 0 18';
+ self.touch = key_touch;
+ setsize (self, '-16 -16 -24', '16 16 32');
+ StartItem ();
+};
+
+
+/*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/w_s_key.mdl"); }
+SILVER key
+In order for keys to work you MUST set your map's worldtype to one of the following:
+0: medieval
+1: metal
+2: base
+*/
+
+void() item_key1 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (world.worldtype == WORLDTYPE_MEDIEVAL)
+ {
+ precache_body_model ("progs/w_s_key.mdl");
+ body_model ("progs/w_s_key.mdl");
+ }
+ else if (world.worldtype == WORLDTYPE_METAL)
+ {
+ precache_body_model ("progs/m_s_key.mdl");
+ body_model ("progs/m_s_key.mdl");
+ }
+ else if (world.worldtype == WORLDTYPE_BASE)
+ {
+ precache_body_model2 ("progs/b_s_key.mdl");
+ body_model ("progs/b_s_key.mdl");
+ }
+
+ if (self.keyname != "") self.netname = self.keyname;
+ else self.netname = SilverKeyName ();
+
+ self.items = IT_KEY1;
+
+// support for item_key_custom -- iw
+ self.customkeys = 0; // ignore any mapper-set value
+ self.noise = ""; // ignore any mapper-set value
+
+ key_start ();
+};
+
+
+/*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/w_g_key.mdl");
+}
+GOLD key
+In order for keys to work you MUST set your map's worldtype to one of the following:
+0: medieval
+1: metal
+2: base
+*/
+
+void() item_key2 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (world.worldtype == WORLDTYPE_MEDIEVAL)
+ {
+ precache_body_model ("progs/w_g_key.mdl");
+ body_model ("progs/w_g_key.mdl");
+ }
+ if (world.worldtype == WORLDTYPE_METAL)
+ {
+ precache_body_model ("progs/m_g_key.mdl");
+ body_model ("progs/m_g_key.mdl");
+ }
+ if (world.worldtype == WORLDTYPE_BASE)
+ {
+ precache_body_model2 ("progs/b_g_key.mdl");
+ body_model ("progs/b_g_key.mdl");
+ }
+
+ if (self.keyname != "") self.keyname = "";
+ else self.netname = GoldKeyName ();
+
+ self.items = IT_KEY2;
+
+// support for item_key_custom -- iw
+ self.customkeys = 0; // ignore any mapper-set value
+ self.noise = ""; // ignore any mapper-set value
+
+ key_start ();
+};
+
+
+// item_key_custom is a brand-spanking-new entity class created for
+// progs_dump -- iw
+
+/*QUAKED item_key_custom (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path" : "progs/pd_w_key.mdl", "skin" : 1});
+}
+A customizable key item.
+
+"keyname" name of the key, e.g. "bronze key" (required)
+"mdl" model file (required)
+"noise" sound file for the pickup sound (default is per worldtype)
+"skin" skin index (default 0)
+
+The "keyname" value is used both for the pickup message and to associate
+the key with the entity that it unlocks.
+
+To make a func_door or trigger_usekey require this key, set the
+"keyname" value of that entity so that it matches the "keyname" value of
+the key.
+
+If different item_key_custom entities have the same "keyname" value,
+they will be treated as different copies of the same key and may be used
+interchangeably.
+
+A map may have a maximum of 23 unique "keyname" values across all
+entities.
+
+The behavior of an item_key_custom should be as the player expects
+(based on the behavior of the silver and gold keys), except for the fact
+that it will not appear as an icon in the player's status bar when
+picked up. This is a limitation of the engine.
+*/
+
+void() item_key_custom =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.keyname == "")
+ {
+ objerror ("no keyname specified");
+ return;
+ }
+
+ if (self.mdl == "")
+ {
+ objerror ("no mdl specified");
+ return;
+ }
+
+ precache_model (self.mdl);
+ setmodel (self, self.mdl);
+ self.mdl = ""; // this should not be referenced again
+
+ self.netname = self.keyname;
+ self.keyname = ""; // this should not be referenced again
+
+ self.items = 0; // ignore any mapper-set value
+ self.customkeys = CustomKeyFlag (self.netname);
+
+ key_start ();
+};
+
+
+/*
+===============================================================================
+
+END OF LEVEL RUNES
+
+===============================================================================
+*/
+
+void() sigil_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ centerprint (other, "You got the rune!");
+
+ sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
+ stuffcmd (other, "bf\n");
+ self.solid = SOLID_NOT;
+ self.model = string_null;
+ serverflags = serverflags | (self.spawnflags & 15);
+ self.classname = ""; // so rune doors won't find it
+
+ activator = other;
+ SUB_UseTargets(); // fire all targets / killtargets
+};
+
+void() sigil_touch2 = //replacement for Skill Select Rune hack -- uses info_player_start2 if spawnflag 16 -- dumptruck_ds
+{
+ if (other.classname != "player")
+ return;
+ if (other.health <= 0)
+ return;
+
+ // centerprint (other, "You got the rune!");
+
+ // sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
+ // stuffcmd (other, "bf\n");
+ self.solid = SOLID_NOT;
+ self.model = string_null;
+ serverflags = serverflags | (self.spawnflags & 16);
+ self.classname = ""; // so rune doors won't find it
+
+ activator = other;
+ // SUB_UseTargets(); // fire all targets / killtargets
+};
+
+
+/*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4 X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ( {{ spawnflags & 1 -> { "path" : "progs/end1.mdl" }, spawnflags & 2 -> { "path" : "progs/end2.mdl" },
+ spawnflags & 4 -> { "path" : "progs/end3.mdl" }, spawnflags & 8 -> { "path" : "progs/end4.mdl" },
+ "progs/end1.mdl" }} );
+}
+End of episode rune. Use in conjuction with func_bossgate and func_episodegate.
+Spawnflag must be set to the appropriate episode.
+Episode 1 - Dimension of the Doomed - Rune of Earth Magic
+Episode 2 - The Realm of Black Magic - Rune of Black Magic
+Episode 3 - The Netherworld - Rune of Hell Magic
+Episode 4 - The Elder World - Run of Elder Magic
+*/
+
+void() item_sigil =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.spawnflags)
+ objerror ("no spawnflags");
+
+ precache_sound ("misc/runekey.wav");
+ self.noise = "misc/runekey.wav";
+
+ if (self.spawnflags & 1)
+ {
+ precache_model ("progs/end1.mdl");
+ setmodel (self, "progs/end1.mdl");
+ }
+ if (self.spawnflags & 2)
+ {
+ precache_model2 ("progs/end2.mdl");
+ setmodel (self, "progs/end2.mdl");
+ }
+ if (self.spawnflags & 4)
+ {
+ precache_model2 ("progs/end3.mdl");
+ setmodel (self, "progs/end3.mdl");
+ }
+ if (self.spawnflags & 8)
+ {
+ precache_model2 ("progs/end4.mdl");
+ setmodel (self, "progs/end4.mdl");
+ }
+
+ self.touch = sigil_touch;
+ setsize (self, '-16 -16 -24', '16 16 32');
+ self.particles_offset = '0 0 18';
+ StartItem ();
+};
+
+/*
+===============================================================================
+
+POWERUPS
+
+===============================================================================
+*/
+
+void() powerup_touch;
+
+
+void() powerup_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ sprint (other, "You got the ");
+ sprint (other, self.netname);
+ sprint (other,"\n");
+
+ // if (deathmatch)
+ // {
+ // self.mdl = self.model;
+ //
+ // if ((self.classname == "item_artifact_invulnerability") ||
+ // (self.classname == "item_artifact_invisibility"))
+ // self.nextthink = time + 60*5;
+ // else
+ // self.nextthink = time + 60;
+ //
+ // self.think = SUB_regen;
+ // }
+
+ // Supa, SP respawning items support
+ self.mdl = self.model;
+ self.think = SUB_regen;
+
+ if (!deathmatch)
+ {
+ local float spawndelay;
+
+ if (self.classname == "item_artifact_invulnerability" ||
+ self.classname == "item_artifact_invisibility" ) spawndelay = 300;
+ // else if (self.classname == "item_grappling_hook" ) spawndelay = 30;
+ else spawndelay = 60;
+
+ CheckItemRespawn(self, spawndelay);
+ }
+ else
+ {
+ if ((self.classname == "item_artifact_invulnerability") ||
+ (self.classname == "item_artifact_invisibility"))
+ self.nextthink = time + 60*5;
+ else
+ self.nextthink = time + 60;
+ }
+
+ sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ stuffcmd (other, "bf\n");
+ self.solid = SOLID_NOT;
+ other.items = other.items | self.items;
+ self.model = string_null;
+
+// do the apropriate action
+ if (self.classname == "item_artifact_envirosuit")
+ {
+ other.rad_time = 1;
+ other.radsuit_finished = time + 30;
+ }
+
+ if (self.classname == "item_artifact_invulnerability")
+ {
+ other.invincible_time = 1;
+ other.invincible_finished = time + 30;
+ }
+
+ if (self.classname == "item_artifact_invisibility")
+ {
+ other.invisible_time = 1;
+ other.invisible_finished = time + 30;
+ }
+
+ if (self.classname == "item_artifact_super_damage")
+ {
+ other.super_time = 1;
+ other.super_damage_finished = time + 30;
+ }
+
+ activator = other;
+ SUB_UseTargets(); // fire all targets / killtargets
+};
+
+/*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/invulner.mdl"); }
+Pentagram of Protection
+Player is invulnerable for 30 seconds
+*/
+void() item_artifact_invulnerability =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = powerup_touch;
+
+ // precache_model ("progs/invulner.mdl");
+ precache_body_model ("progs/invulner.mdl");
+ precache_sound ("items/protect.wav");
+ precache_sound ("items/protect2.wav"); // called in client.qc -- dumptruck_ds
+ precache_sound ("items/protect3.wav"); // called in combat.qc -- dumptruck_ds
+ self.noise = "items/protect.wav";
+ // setmodel (self, "progs/invulner.mdl");
+ body_model ("progs/invulner.mdl");
+ self.netname = "Pentagram of Protection";
+ self.items = IT_INVULNERABILITY;
+ setsize (self, '-16 -16 -24', '16 16 32');
+ if !(self.particles_offset) // t_fog fix for custom models dumptruck_ds
+ self.particles_offset = '0 0 16';
+ StartItem ();
+};
+
+/*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/suit.mdl"); }
+Biosuit
+Player takes no damage from water or slime for 30 seconds
+*/
+void() item_artifact_envirosuit =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = powerup_touch;
+
+ precache_body_model ("progs/suit.mdl");
+ precache_sound ("items/suit.wav");
+ precache_sound ("items/suit2.wav");
+ self.noise = "items/suit.wav";
+ // setmodel (self, "progs/suit.mdl");
+ body_model ("progs/suit.mdl");
+ self.netname = "Biosuit";
+ self.items = IT_SUIT;
+ setsize (self, '-16 -16 -24', '16 16 32');
+ if !(self.particles_offset) // t_fog fix for custom models dumptruck_ds
+ self.particles_offset = '0 0 32';
+ StartItem ();
+};
+
+
+/*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/invisibl.mdl"); }
+Ring of Shadows
+Player is invisible for 30 seconds
+*/
+void() item_artifact_invisibility =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = powerup_touch;
+
+ precache_body_model ("progs/invisibl.mdl");
+ precache_sound ("items/inv1.wav");
+ precache_sound ("items/inv2.wav");
+ precache_sound ("items/inv3.wav");
+ self.noise = "items/inv1.wav";
+ // setmodel (self, "progs/invisibl.mdl");
+ body_model ("progs/invisibl.mdl");
+ self.netname = "Ring of Shadows";
+ self.items = IT_INVISIBILITY;
+ setsize (self, '-16 -16 -24', '16 16 32');
+ if !(self.particles_offset) // t_fog fix for custom models dumptruck_ds
+ self.particles_offset = '0 0 0';
+ StartItem ();
+};
+
+
+/*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/quaddama.mdl"); }
+Quad Damage
+Player does 4x damage for 30 seconds
+*/
+void() item_artifact_super_damage =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = powerup_touch;
+
+ precache_body_model ("progs/quaddama.mdl");
+ precache_sound ("items/damage.wav");
+ precache_sound ("items/damage3.wav");
+ self.noise = "items/damage.wav";
+ // setmodel (self, "progs/quaddama.mdl");
+ body_model ("progs/quaddama.mdl");
+ if !(self.netname) // custom name -- dumptruck_ds
+ self.netname = "Quad Damage";
+ self.items = IT_QUAD;
+ setsize (self, '-16 -16 -24', '16 16 32');
+ if !(self.particles_offset) // t_fog fix for custom models dumptruck_ds
+ self.particles_offset = '0 0 16';
+ StartItem ();
+};
+
+
+
+/*
+===============================================================================
+
+PLAYER BACKPACKS
+
+===============================================================================
+*/
+
+void() BackpackTouch =
+{
+ local string s;
+ local float best, old, new;
+ local entity stemp;
+ local float acount;
+ // from Copper -- dumptruck_ds
+ if (other.movetype == MOVETYPE_NOCLIP)
+ return;
+ if (other.classname != "player")
+ return;
+ if (other.health <= 0)
+ return;
+
+ acount = 0;
+ sprint (other, "You get ");
+
+ if (self.items)
+ if ((other.items & self.items) == 0)
+ {
+ acount = 1;
+ sprint (other, "the ");
+ sprint (other, self.netname);
+ }
+
+// if the player was using his best weapon, change up to the new one if better
+ stemp = self;
+ self = other;
+ best = W_BestWeapon();
+ self = stemp;
+
+// change weapons
+ other.ammo_shells = other.ammo_shells + self.ammo_shells;
+ other.ammo_nails = other.ammo_nails + self.ammo_nails;
+ other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
+ other.ammo_cells = other.ammo_cells + self.ammo_cells;
+
+ new = self.items;
+ if (!new)
+ new = other.weapon;
+ old = other.items;
+ other.items = other.items | new;
+
+ bound_other_ammo ();
+
+ if (self.ammo_shells) // hack to fix an issue with custom Grunt, Ogre and Enf ammo types. - dumptruck_ds
+ // if (self.ammo_shells < 100)
+ {
+ if (acount)
+ sprint(other, ", ");
+ acount = 1;
+ s = ftos(self.ammo_shells);
+ sprint (other, s);
+ sprint (other, " shells");
+ }
+ if (self.ammo_nails)
+ {
+ if (acount)
+ sprint(other, ", ");
+ acount = 1;
+ s = ftos(self.ammo_nails);
+ sprint (other, s);
+ sprint (other, " nails");
+ }
+ if (self.ammo_rockets)
+ {
+ if (acount)
+ sprint(other, ", ");
+ acount = 1;
+ s = ftos(self.ammo_rockets);
+ sprint (other, s);
+ sprint (other, " rockets");
+ }
+ if (self.ammo_cells)
+ {
+ if (acount)
+ sprint(other, ", ");
+ acount = 1;
+ s = ftos(self.ammo_cells);
+ sprint (other, s);
+ sprint (other, " cells");
+ }
+
+ sprint (other, "\n");
+// backpack touch sound
+ sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
+ stuffcmd (other, "bf\n");
+
+// remove the backpack, change self to the player
+ remove(self);
+ self = other;
+
+// change to the weapon
+// 1997-12-23 Thunderbolt fix by Maddes start
+/* don't separate between SinglePlayer/Coop and Deathmatch
+ if (!deathmatch)
+ self.weapon = new;
+ else
+*/
+// 1997-12-23 Thunderbolt fix by Maddes end
+ Deathmatch_Weapon (old, new);
+
+ W_SetCurrentAmmo ();
+
+};
+
+/*
+===============
+DropStuff -- dumptruck_ds
+
+set drops_item on a monster to a number:
+
+1 = Silver Key
+2 = Gold Key
+3 = Health Vial
+4 = Armor Shard
+5 = Health Vial & Armor Shard
+6 = random combination of 3 Vials and/or Shards
+===============
+*/
+
+void() DropKey1 =
+{
+ local entity item;
+
+ item = spawn();
+ item.origin = self.origin - '0 0 24';
+
+ item.velocity_z = 300;
+ item.velocity_x = -100 + (random() * 200);
+ item.velocity_y = -100 + (random() * 200);
+
+ if (world.worldtype == WORLDTYPE_MEDIEVAL)
+ {
+ // precache_model ("progs/w_s_key.mdl");
+ setmodel (item, "progs/w_s_key.mdl");
+ item.noise = "misc/medkey.wav";
+ }
+ else if (world.worldtype == WORLDTYPE_METAL)
+ {
+ // precache_model ("progs/m_s_key.mdl");
+ setmodel (item, "progs/m_s_key.mdl");
+ item.noise = "misc/runekey.wav";
+ }
+ else if (world.worldtype == WORLDTYPE_BASE)
+ {
+ // precache_model2 ("progs/b_s_key.mdl");
+ setmodel (item, "progs/b_s_key.mdl");
+ item.noise = "misc/basekey.wav";
+ }
+ item.netname = SilverKeyName ();
+ item.effects = 8;
+ item.flags = FL_ITEM;
+ item.items = IT_KEY1;
+ item.solid = SOLID_TRIGGER;
+ item.movetype = MOVETYPE_TOSS;
+ setsize (item, '-16 -16 0', '16 16 56');
+ item.touch = key_touch;
+};
+
+void() DropKey2 =
+{
+ local entity item;
+
+ item = spawn();
+ item.origin = self.origin - '0 0 24';
+
+ item.velocity_z = 300;
+ item.velocity_x = -100 + (random() * 200);
+ item.velocity_y = -100 + (random() * 200);
+
+ if (world.worldtype == WORLDTYPE_MEDIEVAL)
+ {
+ // precache_model ("progs/w_s_key.mdl");
+ setmodel (item, "progs/w_g_key.mdl");
+ item.noise = "misc/medkey.wav";
+ }
+ else if (world.worldtype == WORLDTYPE_METAL)
+ {
+ // precache_model ("progs/m_s_key.mdl");
+ setmodel (item, "progs/m_g_key.mdl");
+ item.noise = "misc/runekey.wav";
+ }
+ else if (world.worldtype == WORLDTYPE_BASE)
+ {
+ // precache_model2 ("progs/b_s_key.mdl");
+ setmodel (item, "progs/b_g_key.mdl");
+ item.noise = "misc/basekey.wav";
+ }
+ item.netname = GoldKeyName ();
+ item.effects = 8;
+ item.flags = FL_ITEM;
+ item.items = IT_KEY2;
+ item.solid = SOLID_TRIGGER;
+ item.movetype = MOVETYPE_TOSS;
+ setsize (item, '-16 -16 0', '16 16 56');
+ item.touch = key_touch;
+};
+
+void() DropVial = //
+{
+ local entity item;
+
+ item = spawn();
+ item.origin = self.origin - '0 0 24';
+
+ item.velocity_z = 300;
+ item.velocity_x = -100 + (random() * 200);
+ item.velocity_y = -100 + (random() * 200);
+
+ setmodel(item, "progs/h_mdls/pd_vial.mdl");
+ item.solid = SOLID_TRIGGER;
+ item.movetype = MOVETYPE_TOSS;
+ setsize (item, '-16 -16 0', '16 16 56');
+ item.touch = health_touch;
+ item.healamount = 5;
+ item.healtype = 0;
+ item.noise = "items/r_item1.wav";
+
+ StartItem ();
+};
+
+void() DropShard = //
+{
+ local entity item;
+
+ item = spawn();
+ item.origin = self.origin - '0 0 24';
+
+ item.velocity_z = 300;
+ item.velocity_x = -100 + (random() * 200);
+ item.velocity_y = -100 + (random() * 200);
+
+ setmodel(item, "progs/armshr.mdl");
+ item.solid = SOLID_TRIGGER;
+ item.movetype = MOVETYPE_TOSS;
+ setsize (item, '-16 -16 0', '16 16 56');
+ item.touch = shard_touch;
+ item.snd_misc = "dump/armsh1.wav";
+
+ StartItem ();
+};
+
+void() DropStuff =
+{
+ local float rand_drop;
+
+ if (self.drop_item == 1)
+ {
+ DropKey1();
+ }
+ if (self.drop_item == 2)
+ {
+ DropKey2();
+ }
+ if (self.drop_item == 3)
+ {
+ DropVial();
+ }
+ if (self.drop_item == 4)
+ {
+ DropShard();
+ }
+ if (self.drop_item == 5)
+ {
+ DropVial();
+ DropShard();
+ }
+ else if (self.drop_item == 6)
+ {
+ rand_drop = rint(random() * 3);
+ if (rand_drop == 1)
+ {
+ DropShard();
+ DropVial();
+ DropVial();
+ }
+ else if (rand_drop == 2)
+ {
+ DropShard();
+ DropShard();
+ DropVial();
+ }
+ else if (rand_drop == 0)
+ {
+ DropShard();
+ DropShard();
+ DropShard();
+ }
+ else
+ {
+ DropVial();
+ DropVial();
+ DropVial();
+ }
+ }
+ return;
+};
+
+/*
+===============
+DropBackpack
+===============
+*/
+void() DropBackpack =
+{
+ local entity item;
+
+ if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells))
+ return; // nothing in it
+
+ item = spawn();
+ item.origin = self.origin - '0 0 24';
+
+ item.items = self.weapon;
+ if (item.items == IT_AXE)
+ item.netname = "Axe";
+ else if (item.items == IT_SHOTGUN)
+ item.netname = "Shotgun";
+ else if (item.items == IT_SUPER_SHOTGUN)
+ item.netname = "Double-barrelled Shotgun";
+ else if (item.items == IT_NAILGUN)
+ item.netname = "Nailgun";
+ else if (item.items == IT_SUPER_NAILGUN)
+ item.netname = "Super Nailgun";
+ else if (item.items == IT_GRENADE_LAUNCHER)
+ item.netname = "Grenade Launcher";
+ else if (item.items == IT_ROCKET_LAUNCHER)
+ item.netname = "Rocket Launcher";
+ else if (item.items == IT_LIGHTNING)
+ item.netname = "Thunderbolt";
+ else
+ item.netname = "";
+
+ item.ammo_shells = self.ammo_shells;
+ item.ammo_nails = self.ammo_nails;
+ item.ammo_rockets = self.ammo_rockets;
+ item.ammo_cells = self.ammo_cells;
+
+ item.velocity_z = 300;
+ item.velocity_x = -100 + (random() * 200);
+ item.velocity_y = -100 + (random() * 200);
+
+ item.flags = FL_ITEM;
+ item.solid = SOLID_TRIGGER;
+ item.movetype = MOVETYPE_TOSS;
+ setmodel (item, "progs/backpack.mdl");
+ setsize (item, '-16 -16 0', '16 16 56');
+ item.touch = BackpackTouch;
+
+ item.nextthink = time + 120; // remove after 2 minutes
+ item.think = SUB_Remove;
+};
+
+// dumptruck_ds
+float DEFAULT = 1;
+float SHELLS = 2;
+float NAILS = 4;
+float ROCKETS = 8;
+float CELLS = 16;
+
+void() item_backpack_message =
+{
+
+ if (!CheckValidTouch()) return; // from Copper -- dumptruck_ds
+
+ other.ammo_shells = other.ammo_shells + self.ammo_shells;
+ other.ammo_nails = other.ammo_nails + self.ammo_nails;
+ other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
+ other.ammo_cells = other.ammo_cells + self.ammo_cells;
+
+ if (self.netname != "")
+ {
+ sprint (other, "You got ");
+ sprint (other, self.netname);
+ sprint (other, "\n");
+ }
+ else
+ sprint (other, "You got a backpack!\n");
+
+ // backpack touch sound
+ // sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
+ sound_misc (other, CHAN_ITEM, self.snd_misc, 1, ATTN_NORM);
+ stuffcmd (other, "bf\n");
+ remove(self);
+ self = other;
+ bound_other_ammo();
+ W_SetCurrentAmmo ();
+
+};
+// Some of this text is from Drake -- dumptruck_ds
+/*QUAKED item_backpack (0 .5 .8) (-16 -16 0) (16 16 72) SHELLS NAILS ROCKETS CELLS X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/backpack.mdl"); }
+By default, gives roughly half the ammo from the 4 standard pickups:
+
+10 Shells
+12 Nails
+2 Rockets
+3 Cells
+
+Or you can use the spawnflags to mix and match types.
+Override the spawnflags defaults by adding custom amounts to:
+
+ammo_shells
+ammo_nails
+ammo_rockets
+ammo_cells
+
+Can trigger spawn and suspend in air, but not respawn. You can set a skin
+index if you are using a custom model with skins.
+
+The default pickup message is `You got a backpack.` But you can
+set a custom message with the netname key. 'You got' will be the prefix
+and the mapper chooses the rest of the message.
+
+e.g. For 'You got a bunch of rockets!' the netname key would be
+'a bunch of rockets!'
+*/
+void() item_backpack =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+
+ self.flags = FL_ITEM;
+ self.solid = SOLID_TRIGGER;
+ self.movetype = MOVETYPE_TOSS;
+ self.classname = "item_backpack";
+ // self.netname = self.netname;
+ if !(self.spawnflags)
+ {
+ objerror ("\bNO SPAWNFLAG SET ON item_backpack");
+ return;
+ }
+
+ if (self.spawnflags & DEFAULT)
+ {
+ self.ammo_shells = 10;
+ self.ammo_nails = 12;
+ self.ammo_rockets = 2;
+ self.ammo_cells = 3;
+ }
+
+ if (self.spawnflags & SHELLS)
+ {
+ if !(self.ammo_shells)
+ {
+ self.ammo_shells = 10;
+ }
+ }
+ if (self.spawnflags & NAILS)
+ {
+ if !(self.ammo_nails)
+ {
+ self.ammo_nails = 12;
+ }
+ }
+ if (self.spawnflags & ROCKETS)
+ {
+ if !(self.ammo_rockets)
+ {
+ self.ammo_rockets = 2;
+ }
+ }
+ if (self.spawnflags & CELLS)
+ {
+ if !(self.ammo_cells)
+ {
+ self.ammo_cells = 3;
+ }
+ }
+
+ self.touch = item_backpack_message;
+
+ if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
+ self.snd_misc = "weapons/lock4.wav";
+ precache_sound_misc(self.snd_misc);
+ precache_body_model ("progs/pd_bpack.mdl");
+ body_model ("progs/pd_bpack.mdl");
+ // setmodel (self, "progs/backpack.mdl");
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/keydata.qc

diff --git a/qc/keydata.qc b/qc/keydata.qc
new file mode 100644
index 0000000..4c78ea0
--- /dev/null
+++ b/qc/keydata.qc
@@ -0,0 +1,222 @@
+/*
+========================================================================
+
+FUNCTIONS WHICH DEAL WITH KEY ITEM BITFLAGS AND NAMES
+
+========================================================================
+
+
+This file was created for progs_dump by Ian "iw" Walshaw, January 2020.
+
+It defines functions which deal with the bitflags and names which refer
+to the key items, including the new item_key_custom.
+
+These functions are a dependency of the updated code for the key items
+(in items.qc) and also the updated code for unlockable entities (in
+keylock.qc).
+
+
+========================================================================
+*/
+
+
+string() SilverKeyName;
+string() GoldKeyName;
+float(string key_name) CustomKeyFlag;
+entity(string key_name) SpawnCustomKeyDef;
+entity(string key_name) FindCustomKeyDef;
+float(entity client, float item_flags, float customkey_flags) HasKeys;
+void(entity client, float item_flags, float customkey_flags) GiveKeys;
+void(entity client) GiveAllKeys;
+void(entity client, float item_flags, float customkey_flags) RemoveKeys;
+
+
+// The highest bitflag that will be assigned to a custom key.
+float FINAL_CUSTOM_KEY = 4194304;
+
+// The highest bitflag that has been assigned to a custom key.
+float highest_custom_key;
+
+
+/*
+============
+SilverKeyName
+
+Return the name that should be used for the silver key as per
+world.worldtype. -- iw
+============
+*/
+string() SilverKeyName =
+{
+ if (world.worldtype == WORLDTYPE_BASE)
+ return "silver keycard";
+ if (world.worldtype == WORLDTYPE_METAL)
+ return "silver runekey";
+ return "silver key";
+};
+
+
+/*
+============
+GoldKeyName
+
+Return the name that should be used for the gold key as per
+world.worldtype. -- iw
+============
+*/
+string() GoldKeyName =
+{
+ if (world.worldtype == WORLDTYPE_BASE)
+ return "gold keycard";
+ if (world.worldtype == WORLDTYPE_METAL)
+ return "gold runekey";
+ return "gold key";
+};
+
+
+/*
+================
+CustomKeyFlag
+
+Return the bitflag that should be used to represent the custom key named
+key_name.
+
+More specifically, if this is the first time that this function has been
+called for the specified key_name, then return a bitflag which has not
+previously been returned by this function for any key_name. Otherwise,
+return the same bitflag that was previously returned for the specified
+key_name. -- iw
+================
+*/
+float(string key_name) CustomKeyFlag =
+{
+ local entity key_def;
+
+ key_def = FindCustomKeyDef (key_name);
+ if (key_def == world)
+ key_def = SpawnCustomKeyDef (key_name);
+ return key_def.customkeys;
+};
+
+
+/*
+================
+SpawnCustomKeyDef
+
+Spawn and return a new custom_key_def entity which will define the
+custom key named key_name.
+
+The value of the entity's customkeys field will be a bitflag which has
+not yet been used to represent a custom key. -- iw
+================
+*/
+entity(string key_name) SpawnCustomKeyDef =
+{
+ local entity key_def;
+
+ if (highest_custom_key == FINAL_CUSTOM_KEY)
+ error ("too many custom keys");
+
+ if (highest_custom_key == 0)
+ highest_custom_key = 1;
+ else
+ highest_custom_key = highest_custom_key * 2;
+
+ key_def = spawn ();
+ key_def.classname = "custom_key_def";
+ key_def.netname = key_name;
+ key_def.customkeys = highest_custom_key;
+
+ return key_def;
+};
+
+
+/*
+================
+FindCustomKeyDef
+
+If a custom_key_def entity exists which defines the custom key named
+key_name, then find and return it, otherwise return world.
+
+If a custom_key_def entity is returned, then the value of its customkeys
+field will be the bitflag that should be used to represent the custom
+key named key_name. -- iw
+================
+*/
+entity(string key_name) FindCustomKeyDef =
+{
+ local entity key_def;
+
+ key_def = find (world, classname, "custom_key_def");
+ while (key_def != world)
+ {
+ if (key_def.netname == key_name)
+ return key_def;
+ key_def = find (key_def, classname, "custom_key_def");
+ }
+ return world;
+};
+
+
+/*
+================
+HasKeys
+
+Return TRUE if the specified client has all of the non-custom keys
+represented by the item_flags and all of the custom keys represented by
+the customkey_flags, otherwise return FALSE. -- iw
+================
+*/
+float(entity client, float item_flags, float customkey_flags) HasKeys =
+{
+ return (client.items & item_flags) == item_flags &&
+ (client.customkeys & customkey_flags) == customkey_flags;
+};
+
+
+/*
+================
+GiveKeys
+
+Give the specified client all of the non-custom keys represented by the
+item_flags and all of the custom keys represented by the
+customkey_flags. -- iw
+================
+*/
+void(entity client, float item_flags, float customkey_flags) GiveKeys =
+{
+ client.items = client.items | item_flags;
+ client.customkeys = client.customkeys | customkey_flags;
+};
+
+
+/*
+================
+GiveAllKeys
+
+Give the specified client the silver key, the gold key, and all of the
+custom keys that have been defined for the current map. -- iw
+================
+*/
+void(entity client) GiveAllKeys =
+{
+ GiveKeys (client, IT_KEY1 | IT_KEY2, highest_custom_key * 2 - 1);
+};
+
+
+/*
+================
+RemoveKeys
+
+Remove all of the non-custom keys represented by the item_flags and all
+of the custom keys represented by the customkey_flags from the specified
+client's inventory. -- iw
+================
+*/
+void(entity client, float item_flags, float customkey_flags) RemoveKeys =
+{
+ client.items = client.items -
+ (client.items & item_flags);
+ client.customkeys = client.customkeys -
+ (client.customkeys & customkey_flags);
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/keylock.qc

diff --git a/qc/keylock.qc b/qc/keylock.qc
new file mode 100644
index 0000000..1566671
--- /dev/null
+++ b/qc/keylock.qc
@@ -0,0 +1,226 @@
+/*
+========================================================================
+
+COMMON CODE FOR ENTITIES WHICH CAN BE UNLOCKED WITH KEYS
+
+========================================================================
+
+
+This file was created for progs_dump by Ian "iw" Walshaw, December 2019.
+
+It defines functions which implement the logic of the player using a key
+to unlock a locked entity. These functions are based on parts of the
+func_door code from the original game.
+
+In the original game, func_door was the only type of entity which could
+be unlocked with a key, however progs_dump also has trigger_usekey,
+which previously duplicated the same unlocking logic as func_door. The
+functions in this file were written to eliminate that duplication;
+func_door and trigger_usekey have now both been refactored to call these
+functions.
+
+This file was created as part of the prep work for implementing
+item_key_custom, with the intention of removing as much duplication as
+possible in order to make the code easier to modify and extend.
+
+
+Fields Set By These Functions
+-----------------------------
+
+The functions in this file set the following fields, therefore code
+calling these functions must not use these fields for other purposes:
+
+ - self.customkeys
+ - self.items
+ - self.netname
+ - self.noise3
+ - self.noise4
+
+
+========================================================================
+*/
+
+
+/*
+================
+keylock_init
+
+Initialize self for use with the other keylock_* functions.
+
+The following fields will be set to default values if they have not
+already been set:
+
+ - self.noise3 (the "key required" sound file).
+
+ - self.noise4 (the "key used" sound file).
+
+The default values are determined by world.worldtype. -- iw
+================
+*/
+void() keylock_init =
+{
+ local string default_noise3;
+ local string default_noise4;
+
+ if (world.worldtype == WORLDTYPE_BASE)
+ {
+ default_noise3 = "doors/basetry.wav";
+ default_noise4 = "doors/baseuse.wav";
+ }
+ else if (world.worldtype == WORLDTYPE_METAL)
+ {
+ default_noise3 = "doors/runetry.wav";
+ default_noise4 = "doors/runeuse.wav";
+ }
+ else
+ {
+ default_noise3 = "doors/medtry.wav";
+ default_noise4 = "doors/meduse.wav";
+ }
+
+ if (self.noise3 == "")
+ self.noise3 = default_noise3;
+ if (self.noise4 == "")
+ self.noise4 = default_noise4;
+
+ precache_sound (self.noise3);
+ precache_sound (self.noise4);
+};
+
+
+/*
+================
+keylock_set_silver_key
+
+Make it so that the player will need to use the silver key in order to
+unlock self. -- iw
+================
+*/
+void() keylock_set_silver_key =
+{
+ self.items = IT_KEY1;
+ self.customkeys = 0; // support for item_key_custom -- iw
+ self.netname = SilverKeyName ();
+};
+
+
+/*
+================
+keylock_set_gold_key
+
+Make it so that the player will need to use the gold key in order to
+unlock self. -- iw
+================
+*/
+void() keylock_set_gold_key =
+{
+ self.items = IT_KEY2;
+ self.customkeys = 0; // support for item_key_custom -- iw
+ self.netname = GoldKeyName ();
+};
+
+
+// support for item_key_custom -- iw
+/*
+================
+keylock_set_custom_key
+
+Make it so that the player will need to use the custom key named
+key_name in order to unlock self. -- iw
+================
+*/
+void(string key_name) keylock_set_custom_key =
+{
+ self.items = 0;
+ self.customkeys = CustomKeyFlag (key_name);
+ self.netname = key_name;
+};
+
+
+/*
+================
+keylock_has_key_set
+
+Return TRUE if one of the keylock_set_*_key functions has been called
+for self, otherwise return FALSE. -- iw
+================
+*/
+float() keylock_has_key_set =
+{
+// support for item_key_custom -- iw
+ return self.items != 0 || self.customkeys != 0;
+};
+
+
+/*
+================
+keylock_try_to_unlock
+
+Handle the logic of the specified client trying to unlock self.
+
+More specifically, if the client has the correct key to unlock self,
+then do the following:
+
+ 1. Remove the key from the client's inventory, unless self.cnt is
+ non-zero, in which case leave it in the client's inventory.
+
+ 2. Print a message to let the player know which key they used.
+
+ 3. Play the "key used" sound effect (self.noise4).
+
+ 4. Call the function specified as the success_func parameter, which
+ should perform whatever entity-specific actions are required for
+ self.
+
+Otherwise, if the client does not have the correct key to unlock self,
+then do the following:
+
+ 1. Centerprint the message "You need the [key name]", unless the
+ custom_message parameter is non-empty, in which case centerprint
+ that instead.
+
+ 2. Play the "key required" sound effect (self.noise3).
+
+The self.cnt functionality is a feature of progs_dump and was not part
+of the original game. -- iw
+================
+*/
+void(entity client, string custom_message,
+ void() success_func) keylock_try_to_unlock =
+{
+ local string s;
+
+// support for item_key_custom -- iw
+ if (!HasKeys (client, self.items, self.customkeys))
+ {
+ if (custom_message != "")
+ centerprint (client, custom_message);
+ else
+ centerprint2 (client, "You need the ", self.netname);
+ sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
+ return;
+ }
+
+// the old code in door_touch included a comment from dumptruck_ds
+// thanking RennyC re self.cnt
+ if (self.cnt)
+ {
+ s = "You used (and kept) the ";
+ }
+ else
+ {
+ // support for item_key_custom -- iw
+ RemoveKeys (client, self.items, self.customkeys);
+ s = "You used the ";
+ }
+
+ sprint (client, s);
+ sprint (client, self.netname);
+ sprint (client, "\n");
+
+// the old code in door_fire included a comment from dumptruck_ds
+// thanking c0burn re changing CHAN_VOICE to CHAN_ITEM
+ sound (self, CHAN_ITEM, self.noise4, 1, ATTN_NORM);
+
+ success_func ();
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/lights.qc

diff --git a/qc/lights.qc b/qc/lights.qc
new file mode 100644
index 0000000..c2fd36a
--- /dev/null
+++ b/qc/lights.qc
@@ -0,0 +1,503 @@
+/*========================================
+lights.qc taken from c0burn's Slipgate mod -- dumptruck_ds
+========================================*/
+
+float START_OFF = 1;
+float FADE_IN_OUT = 2;
+float SILENT_TORCH = 4; // for silent torch -- dumptruck_ds
+
+/*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Used as a positional target for spotlights, etc.
+*/
+void() info_null =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ remove(self);
+};
+
+/*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Never used in the or
+*/
+void() info_notnull =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+};
+
+/*==========
+lightstyle_lookup
+==========*/
+string(float num) lightstyle_lookup =
+{
+ switch (num)
+ {
+ // 0 normal
+ case 0:
+ return "m";
+ break;
+ // 1 FLICKER (first variety)
+ case 1:
+ return "mmnmmommommnonmmonqnmmo";
+ break;
+ // 2 SLOW STRONG PULSE
+ case 2:
+ return "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba";
+ break;
+ // 3 CANDLE (first variety)
+ case 3:
+ return "mmmmmaaaaammmmmaaaaaabcdefgabcdefg";
+ break;
+ // 4 FAST STROBE
+ case 4:
+ return "mamamamamama";
+ break;
+ // 5 GENTLE PULSE 1
+ case 5:
+ return "jklmnopqrstuvwxyzyxwvutsrqponmlkj";
+ break;
+ // 6 FLICKER (second variety)
+ case 6:
+ return "nmonqnmomnmomomno";
+ break;
+ // 7 CANDLE (second variety)
+ case 7:
+ return "mmmaaaabcdefgmmmmaaaammmaamm";
+ break;
+ // 8 CANDLE (third variety)
+ case 8:
+ return "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa";
+ break;
+ // 9 SLOW STROBE (fourth variety)
+ case 9:
+ return "aaaaaaaazzzzzzzz";
+ break;
+ // 10 FLUORESCENT FLICKER
+ case 10:
+ return "mmamammmmammamamaaamammma";
+ break;
+ // 11 SLOW PULSE NOT FADE TO BLACK
+ case 11:
+ return "abcdefghijklmnopqrrqponmlkjihgfedcba";
+ break;
+ // 12 BLINK OFF / ON (can be synced with animated textures, e.g. +0light and +1light)
+ case 12:
+ return "aamm"; // textures animate at 5fps but lights are 10fps...
+ break;
+ // DEFAULT
+ default:
+ return "a";
+ break;
+ }
+};
+
+/*==========
+setup_lightstyles
+
+Setup light animation tables. 'a' is total darkness, 'z' is maxbright.
+Styles 32+ are assigned by the light program for switchable lights.
+==========*/
+void() setup_lightstyles =
+{
+ for (float i = 0; i <= 12; i++)
+ {
+ lightstyle(i, lightstyle_lookup(i));
+ }
+};
+
+/*==========
+lightstyle_fade_lookup
+==========*/
+string(float num) lightstyle_fade_lookup =
+{
+ switch (num)
+ {
+ case 0:
+ return "a";
+ break;
+ case 1:
+ return "b";
+ break;
+ case 2:
+ return "c";
+ break;
+ case 3:
+ return "d";
+ break;
+ case 4:
+ return "e";
+ break;
+ case 5:
+ return "f";
+ break;
+ case 6:
+ return "g";
+ break;
+ case 7:
+ return "h";
+ break;
+ case 8:
+ return "i";
+ break;
+ case 9:
+ return "j";
+ break;
+ case 10:
+ return "k";
+ break;
+ case 11:
+ return "l";
+ break;
+ case 12:
+ return "m";
+ break;
+ default:
+ error("count out of range\n");
+ break;
+ }
+};
+
+/*==========
+light_fade_in
+==========*/
+void() light_fade_in =
+{
+ if (self.count < 0)
+ self.count = 0;
+ if (self.count > 12)
+ self.count = 12;
+
+ lightstyle(self.style, lightstyle_fade_lookup(self.count));
+ self.count = self.count + 1;
+ if (self.count > 12)
+ return;
+
+ self.think = light_fade_in;
+ self.nextthink = time + self.speed;
+};
+
+/*==========
+light_fade_out
+==========*/
+void() light_fade_out =
+{
+ if (self.count < 0)
+ self.count = 0;
+ if (self.count > 12)
+ self.count = 12;
+
+ lightstyle(self.style, lightstyle_fade_lookup(self.count));
+ self.count = self.count - 1;
+ if (self.count < 0)
+ return;
+
+ self.think = light_fade_out;
+ self.nextthink = time + self.speed;
+};
+
+/*==========
+light_use
+
+using a light will turn it on and off
+==========*/
+void() light_use =
+{
+ if (self.spawnflags & START_OFF)
+ {
+ self.spawnflags = self.spawnflags - START_OFF;
+ if (self.spawnflags & FADE_IN_OUT && !self.style2)
+ light_fade_in();
+ else
+ lightstyle(self.style, lightstyle_lookup(self.style2));
+ }
+ else
+ {
+ self.spawnflags = self.spawnflags + START_OFF;
+ if (self.spawnflags & FADE_IN_OUT && !self.style2)
+ light_fade_out();
+ else
+ lightstyle(self.style, "a");
+ }
+};
+
+/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF FADE_IN_OUT X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Light
+
+==========
+Spawnflags
+==========
+START_OFF - switchable lights only - light is off by default
+FADE_IN_OUT - switchable lights only - light fades in and out. can't be combined with animated lights.
+
+==========
+Keys
+==========
+"light" "n"
+Set the light intensity. Negative values are also allowed and will cause the entity to subtract light cast by other entities. Default 300.
+
+"wait" "n"
+Scale the fade distance of the light by "n". Values of n > 1 make the light fade more quickly with distance, and values < 1 make the light fade more slowly (and thus reach further). Default 1.
+
+"delay" "n"
+Select an attenuation formaula for the light:
+0 => Linear attenuation (default)
+1 => 1/x attenuation
+2 => 1/(x^2) attenuation
+3 => No attenuation (same brightness at any distance)
+4 => "local minlight" - No attenuation and like minlight,
+it won't raise the lighting above it's light value.
+Unlike minlight, it will only affect surfaces within
+line of sight of the entity.
+5 => 1/(x^2) attenuation, but slightly more attenuated and
+without the extra bright effect that "delay 2" has
+near the source.
+
+"_falloff" "n"
+Sets the distance at which the light drops to 0, in map units.
+In this mode, "wait" is ignored and "light" only controls the brightness at the center of the light, and no longer affects the falloff distance.
+Only supported on linear attenuation (delay 0) lights currently.
+
+"_color" "r g b"
+Specify red(r), green(g) and blue(b) components for the colour of the light. RGB component values are between 0 and 255 (between 0 and 1 is also accepted). Default is white light ("255 255 255").
+
+"target" "name"
+Turns the light into a spotlight, with the direction of light being towards another entity with it�s "targetname" key set to "name".
+"mangle" "yaw pitch roll"
+Turns the light into a spotlight and specifies the direction of light using yaw, pitch and roll in degrees. Yaw specifies the angle around the Z-axis from 0 to 359 degrees and pitch specifies the angle from 90 (straight up) to -90 (straight down). Roll has no effect, so use any value (e.g. 0). Often easier than the "target" method.
+
+"angle" "n"
+Specifies the angle in degrees for a spotlight cone. Default 40.
+
+"_softangle" "n"
+Specifies the angle in degrees for an inner spotlight cone (must be less than the "angle" cone. Creates a softer transition between the full brightness of the inner cone to the edge of the outer cone. Default 0 (disabled).
+
+"targetname" "name"
+Turns the light into a switchable light, toggled by another entity targeting it�s name.
+
+"speed" "n"
+If the light is switchable and FADE_IN_OUT is set, the speed at which the light transitions. Default 0.1.
+
+"style" "n"
+Set the animated light style. Default 0.
+
+"style2" "n"
+Set the animated light style for a switchable light, because style will be overriden if a targetname is set. Default 0.
+
+"_anglescale" "n" | "_anglesense" "n"
+Sets a scaling factor for how much influence the angle of incidence of light on a surface has on the brightness of the surface. n must be between 0.0 and 1.0. Smaller values mean less attenuation, with zero meaning that angle of incidence has no effect at all on the brightness. Default 0.5.
+
+"_dirtscale" "n" | "_dirtgain" "n"
+Override the global "_dirtscale" or "_dirtgain" settings to change how this light is affected by dirtmapping (ambient occlusion). See descriptions of these keys in the worldspawn section.
+
+"_dirt" "n"
+Overrides the worldspawn setting of "_dirt" for this particular light. -1 to disable dirtmapping (ambient occlusion) for this light, making it illuminate the dirtmapping shadows. 1 to enable ambient occlusion for this light. Default is to defer to the worldspawn setting.
+
+"_deviance" "n"
+Split up the light into a sphere of randomly positioned lights within radius "n" (in world units). Useful to give shadows a wider penumbra. "_samples" specifies the number of lights in the sphere. The "light" value is automatically scaled down for most lighting formulas (except linear and non-additive minlight) to attempt to keep the brightness equal. Default is 0, do not split up lights.
+
+"_samples" "n"
+Number of lights to use for "_deviance". Default 16 (only used if "_deviance" is set).
+
+"_surface" "texturename"
+Makes surfaces with the given texture name emit light, by using this light as a template which is copied across those surfaces. Lights are spaced about 128 units (though possibly closer due to bsp splitting) apart and positioned 2 units above the surfaces.
+
+"_surface_offset" "n"
+Controls the offset lights are placed above surfaces for "_surface". Default 2.
+
+"_surface_spotlight" "n"
+For a surface light template (i.e. a light with "_surface" set), setting this to "1" makes each instance into a spotlight, with the direction of light pointing along the surface normal. In other words, it automatically sets "mangle" on each of the generated lights.
+
+"_project_texture" "texture"
+Specifies that a light should project this texture. The texture must be used in the map somewhere.
+
+"_project_mangle" "yaw pitch roll"
+Specifies the yaw/pitch/roll angles for a texture projection (overriding mangle).
+
+"_project_fov" "n"
+Specifies the fov angle for a texture projection. Default 90.
+
+"_bouncescale" "n"
+Scales the amount of light that is contributed by bounces. Default is 1.0, 0.0 disables bounce lighting for this light.
+
+"_sun" "n"
+Set to 1 to make this entity a sun, as an alternative to using the sunlight worldspawn keys. If the light targets an info_null entity, the direction towards that entity sets sun direction. The light itself is disabled, so it can be placed anywhere in the map.
+
+The following light properties correspond to these sunlight settings:
+light => _sunlight
+mangle => _sunlight_mangle
+deviance => _sunlight_penumbra
+_color => _sunlight_color
+_dirt => _sunlight_dirt
+_anglescale => _anglescale
+*/
+void() light =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ // default speed for fading in/out
+ if (self.speed <= 0)
+ self.speed = 0.1;
+
+ // non-switchable light
+ if (!self.targetname)
+ {
+ remove(self);
+ return;
+ }
+
+ // switchable light
+ if (self.style >= 32)
+ {
+ self.use = light_use;
+ if (self.spawnflags & START_OFF)
+ {
+ self.count = 0;
+ lightstyle(self.style, "a");
+ }
+ else
+ {
+ self.count = 12;
+ lightstyle(self.style, lightstyle_lookup(self.style2));
+ }
+ }
+};
+
+/*QUAKED light_fluoro (0 1 0) (-8 -8 -8) (8 8 8) START_OFF FADE_IN_OUT X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Non-displayed light.
+Makes steady fluorescent humming sound.
+See the "light" entity for a full description.
+*/
+void() light_fluoro =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ ambient_light_buzz();
+ light();
+};
+
+/*QUAKED light_fluorospark (0 1 0) (-8 -8 -8) (8 8 8) START_OFF FADE_IN_OUT X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Non-displayed light.
+Makes sparking, broken fluorescent sound.
+Can't be toggled.
+Default style is 10.
+See the "light" entity for a full description.
+*/
+void() light_fluorospark =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.style)
+ self.style = 10;
+ ambient_flouro_buzz();
+ remove(self);
+};
+
+/*QUAKED light_globe (0 1 0) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Sphere globe light.
+Can't be toggled.
+See the "light" entity for a full description.
+*/
+void() light_globe =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/s_light.spr");
+ setmodel(self, "progs/s_light.spr");
+ makestatic(self);
+};
+
+/*QUAKED light_torch_small_walltorch (0 .5 0) (-10 -10 -20) (10 10 20) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model ("progs/flame.mdl"); }
+Short wall torch
+See the "light" entity for a full description.
+*/
+void() light_torch_small_walltorch =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ // precache_model("progs/flame.mdl");
+ precache_body_model("progs/flame.mdl");
+ // setmodel(self, "progs/flame.mdl");
+ body_model("progs/flame.mdl");
+ if !(self.spawnflags && SILENT_TORCH) // for silent torch -- dumptruck_ds
+ FireAmbient ();
+ makestatic(self);
+};
+
+/*QUAKED light_flame_large_yellow (0 1 0) (-10 -10 -12) (12 12 18) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model ( { "path" : "progs/flame2.mdl", "frame" : 1 } ); }
+Large yellow flame
+See the "light" entity for a full description.
+*/
+void() light_flame_large_yellow =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/flame2.mdl");
+ setmodel (self, "progs/flame2.mdl");
+ self.frame = 1;
+ FireAmbient ();
+ makestatic(self);
+};
+
+/*QUAKED light_flame_small_yellow (0 1 0) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model ("progs/flame2.mdl"); }
+Small yellow flame
+See the "light" entity for a full description.
+*/
+void() light_flame_small_yellow =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/flame2.mdl");
+ setmodel(self, "progs/flame2.mdl");
+ FireAmbient ();
+ makestatic(self);
+};
+
+/*QUAKED light_flame_small_white (0 1 0) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model ("progs/flame2.mdl"); }
+Left for compatability
+Identical to "light_flame_small_yellow"
+*/
+void() light_flame_small_white =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ light_flame_small_yellow();
+};
+
+/*QUAKED light_sprite_flame (0 1 0) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model ("progs/s_flame.spr"); }
+Large flame spite*/
+void() light_sprite_flame =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/s_flame.spr");
+ setmodel(self, "progs/s_flame.spr");
+ FireAmbient ();
+
+ self.frame = rint(random() * 13);
+ self.first_frame = 0;
+ self.last_frame = 13;
+ self.speed = 0.05;
+ self.think = misc_model_think;
+ self.nextthink = time + 0.1;
+
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/math.qc

diff --git a/qc/math.qc b/qc/math.qc
new file mode 100644
index 0000000..13985d0
--- /dev/null
+++ b/qc/math.qc
@@ -0,0 +1,209 @@
+/*
+ * math.qc
+ *
+ * Author: Joshua Skelton joshua.skelton@gmail.com
+ *
+ * A collection of helpful math functions.
+ */
+
+// Forward declarations
+float(float value, float minValue, float maxValue) clamp;
+float(float a, float b) mod;
+float(float x) sign;
+float(float value, float minValue, float maxValue) wrap;
+
+/*
+ * clamp
+ *
+ * Limits the given value to the given range.
+ *
+ * value: A number
+ *
+ * minValue: The minimum value of the range
+ *
+ * maxValue: The maximum value of the range
+ *
+ * Returns: A number within the given range.
+ */
+float(float value, float minValue, float maxValue) clamp = {
+ if (value < minValue) {
+ return minValue;
+ }
+ else if (value > maxValue) {
+ return maxValue;
+ }
+
+ return value;
+};
+
+/*
+ * mod
+ *
+ * Returns the remainder after the division of a by n
+ *
+ * a: The dividend
+ *
+ * b: The divisor
+ *
+ * Returns: The remainder of a divided by n
+ */
+float(float a, float n) mod = {
+ return a - (n * floor(a / n));
+};
+
+/*
+ * sign
+ *
+ * Returns an indication of the sign of the given number.
+ *
+ * x: A number
+ *
+ * Returns: -1 if x < 0, 0 if x == 0, 1 if x > 0.
+ */
+float(float x) sign = {
+ if (x > 0) {
+ return 1;
+ }
+ else if (x < 0) {
+ return -1;
+ }
+
+ return 0;
+};
+
+/*
+ * wrap
+ *
+ * Limits the given value to the given range and will wrap the value to the
+ * the other end of the range if exceeded.
+ *
+ * value: A number
+ *
+ * minValue: The minimum value of the range
+ *
+ * maxValue: The maximum value of the range
+ *
+ * Returns: A number within the given range.
+ */
+float(float value, float minValue, float maxValue) wrap = {
+ local float range = maxValue - minValue;
+
+ return mod(value - minValue, range + 1) + minValue;
+};
+
+
+
+float(float a, float b, float mix) lerp =
+{
+ if (mix <= 0) return a;
+ if (mix >= 1) return b;
+ return (b * mix + a * ( 1 - mix ) );
+}
+
+vector(vector a, vector b, float mix) lerpVector =
+{
+ if (mix <= 0) return a;
+ if (mix >= 1) return b;
+ return (b * mix + a * ( 1 - mix ) );
+}
+
+// for a relaxing lerp: hermite lerp.
+float(float a, float b, float mix) lerpHermite =
+{
+ if (mix <= 0) return a;
+ if (mix >= 1) return b;
+
+ local float h01;
+
+ h01 = mix * mix;
+ h01 *= 3 - 2 * mix;
+
+ return (b * h01 + a * ( 1 - h01 ) );
+}
+
+vector(vector a, vector b, float mix) lerpVectorHermite =
+{
+ if (mix <= 0) return a;
+ if (mix >= 1) return b;
+
+ local float h01;
+
+ h01 = mix * mix;
+ h01 *= 3 - 2 * mix;
+
+ return (b * h01 + a * ( 1 - h01 ) );
+}
+
+float(float anga, float angb) angledif =
+{
+ float dif;
+ dif = fabs(anga - angb);
+ if (dif > 180)
+ dif = 360 - dif;
+ return dif;
+}
+
+float(vector ang, vector base_ang, vector offset) isInAngle = {
+ if (angledif(ang_x, base_ang_x) > offset_x || angledif(ang_y, base_ang_y) > offset_y)
+ return FALSE;
+ else
+ return TRUE;
+};
+
+
+// normalizes an angle vector to the 0/+359 range
+vector(vector ang) normalizeAngles = {
+
+ ang_x = ang_x - floor(ang_x/360) * 360;
+ ang_y = ang_y - floor(ang_y/360) * 360;
+ ang_z = ang_z - floor(ang_z/360) * 360;
+
+ /*
+ while (ang_x > 360)
+ ang_x = ang_x - 360;
+
+ while (ang_x < 0)
+ ang_x = ang_x + 360;
+
+ while (ang_y > 360)
+ ang_y = ang_y - 360;
+
+ while (ang_y < 0)
+ ang_y = ang_y + 360;
+
+ while (ang_z > 360)
+ ang_z = ang_z - 360;
+
+ while (ang_z < 0)
+ ang_z = ang_z + 360;
+ */
+ return ang;
+};
+
+// normalizes an angle vector to the -180/+179 range
+vector(vector ang) normalizeAngles180 = {
+ ang_x = ((ang_x+180) - floor((ang_x+180)/360) * 360) - 180;
+ ang_y = ((ang_y+180) - floor((ang_y+180)/360) * 360) - 180;
+ ang_z = ((ang_z+180) - floor((ang_z+180)/360) * 360) - 180;
+
+ /*
+ while (ang_x > 180)
+ ang_x = ang_x - 360;
+
+ while (ang_x < -180)
+ ang_x = ang_x + 360;
+
+ while (ang_y > 180)
+ ang_y = ang_y - 360;
+
+ while (ang_y < -180)
+ ang_y = ang_y + 360;
+
+ while (ang_z > 180)
+ ang_z = ang_z - 360;
+
+ while (ang_z < -180)
+ ang_z = ang_z + 360;
+ */
+ return ang;
+};
\ No newline at end of file

Return to the top of this page or return to the overview of this repo.

Diff qc/misc.qc

diff --git a/qc/misc.qc b/qc/misc.qc
new file mode 100644
index 0000000..062b6d0
--- /dev/null
+++ b/qc/misc.qc
@@ -0,0 +1,1871 @@
+// these were moved for various reasons -- dumptruck_ds
+// /*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4)
+// Used as a positional target for spotlights, etc.
+// */
+// /void() info_null =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// remove(self);
+// };
+//
+// /*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4)
+// Used as a positional target for lightning.
+// */
+// void() info_notnull =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+// };
+//
+// //============================================================================
+//
+// float START_OFF = 1;
+//
+// void() light_use =
+// {
+// if (self.spawnflags & START_OFF)
+// {
+// lightstyle(self.style, "m");
+// self.spawnflags = self.spawnflags - START_OFF;
+// }
+// else
+// {
+// lightstyle(self.style, "a");
+// self.spawnflags = self.spawnflags + START_OFF;
+// }
+// };
+//
+// /*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
+// Non-displayed light.
+// Default light value is 300
+// Default style is 0
+// If targeted, it will toggle between on or off.
+// */
+// void() light =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// if (!self.targetname)
+// { // inert light
+// remove(self);
+// return;
+// }
+//
+// if (self.style >= 32)
+// {
+// self.use = light_use;
+// if (self.spawnflags & START_OFF)
+// lightstyle(self.style, "a");
+// else
+// lightstyle(self.style, "m");
+// }
+// };
+//
+// /*QUAKED light_fluoro (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
+// Non-displayed light.
+// Default light value is 300
+// Default style is 0
+// If targeted, it will toggle between on or off.
+// Makes steady fluorescent humming sound
+// */
+// void() light_fluoro =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// if (self.style >= 32)
+// {
+// self.use = light_use;
+// if (self.spawnflags & START_OFF)
+// lightstyle(self.style, "a");
+// else
+// lightstyle(self.style, "m");
+// }
+//
+// precache_sound ("ambience/fl_hum1.wav");
+// ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC);
+// };
+//
+// /*QUAKED light_fluorospark (0 1 0) (-8 -8 -8) (8 8 8)
+// Non-displayed light.
+// Default light value is 300
+// Default style is 10
+// Makes sparking, broken fluorescent sound
+// */
+// void() light_fluorospark =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// if (!self.style)
+// self.style = 10;
+//
+// precache_sound ("ambience/buzz1.wav");
+// ambientsound (self.origin, "ambience/buzz1.wav", 0.5, ATTN_STATIC);
+// };
+//
+// /*QUAKED light_globe (0 1 0) (-8 -8 -8) (8 8 8)
+// Sphere globe light.
+// Default light value is 300
+// Default style is 0
+// */
+// void() light_globe =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// precache_model ("progs/s_light.spr");
+// setmodel (self, "progs/s_light.spr");
+// makestatic (self);
+// };
+//
+/*QUAKED FireAmbient (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
+*/
+void() FireAmbient =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/fire1.wav");
+// attenuate fast
+ ambientsound (self.origin, "ambience/fire1.wav", 0.5, ATTN_STATIC);
+};
+
+/*QUAKED ambient_fire (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+ambinet fire sound effects added for consistency
+same as FireAmbient
+*/
+void() ambient_fire =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+FireAmbient();
+};
+
+//
+// /*QUAKED light_torch_small_walltorch (0 .5 0) (-10 -10 -20) (10 10 20)
+// Short wall torch
+// Default light value is 200
+// Default style is 0
+// */
+// void() light_torch_small_walltorch =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// precache_model ("progs/flame.mdl");
+// setmodel (self, "progs/flame.mdl");
+// FireAmbient ();
+// makestatic (self);
+// };
+//
+// /*QUAKED light_flame_large_yellow (0 1 0) (-10 -10 -12) (12 12 18)
+// Large yellow flame ball
+// */
+// void() light_flame_large_yellow =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// precache_model ("progs/flame2.mdl");
+// setmodel (self, "progs/flame2.mdl");
+// self.frame = 1;
+// FireAmbient ();
+// makestatic (self);
+// };
+//
+// /*QUAKED light_flame_small_yellow (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
+// Small yellow flame ball
+// */
+// void() light_flame_small_yellow =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// precache_model ("progs/flame2.mdl");
+// setmodel (self, "progs/flame2.mdl");
+// FireAmbient ();
+// makestatic (self);
+// };
+//
+// /*QUAKED light_flame_small_white (0 1 0) (-10 -10 -40) (10 10 40) START_OFF
+// Small white flame ball
+// */
+// void() light_flame_small_white =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// precache_model ("progs/flame2.mdl");
+// setmodel (self, "progs/flame2.mdl");
+// FireAmbient ();
+// makestatic (self);
+// };
+//
+/*QUAKED light_candle (0 1 0) (-10 -10 -40) (10 10 40) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/candle.mdl"); }
+==========
+Spawnflags
+==========
+START_OFF - switchable lights only - light is off by default
+FADE_IN_OUT - switchable lights only - light fades in and out. can't be combined with animated lights.
+
+==========
+Keys
+==========
+"light" "n"
+Set the light intensity. Negative values are also allowed and will cause the entity to subtract light cast by other entities. Default 300.
+
+"wait" "n"
+Scale the fade distance of the light by "n". Values of n > 1 make the light fade more quickly with distance, and values < 1 make the light fade more slowly (and thus reach further). Default 1.
+
+"delay" "n"
+Select an attenuation formaula for the light:
+0 => Linear attenuation (default)
+1 => 1/x attenuation
+2 => 1/(x^2) attenuation
+3 => No attenuation (same brightness at any distance)
+4 => "local minlight" - No attenuation and like minlight,
+it won't raise the lighting above it's light value.
+Unlike minlight, it will only affect surfaces within
+line of sight of the entity.
+5 => 1/(x^2) attenuation, but slightly more attenuated and
+without the extra bright effect that "delay 2" has
+near the source.
+
+"_falloff" "n"
+Sets the distance at which the light drops to 0, in map units.
+In this mode, "wait" is ignored and "light" only controls the brightness at the center of the light, and no longer affects the falloff distance.
+Only supported on linear attenuation (delay 0) lights currently.
+
+"_color" "r g b"
+Specify red(r), green(g) and blue(b) components for the colour of the light. RGB component values are between 0 and 255 (between 0 and 1 is also accepted). Default is white light ("255 255 255").
+
+"target" "name"
+Turns the light into a spotlight, with the direction of light being towards another entity with it�s "targetname" key set to "name".
+"mangle" "yaw pitch roll"
+Turns the light into a spotlight and specifies the direction of light using yaw, pitch and roll in degrees. Yaw specifies the angle around the Z-axis from 0 to 359 degrees and pitch specifies the angle from 90 (straight up) to -90 (straight down). Roll has no effect, so use any value (e.g. 0). Often easier than the "target" method.
+
+"angle" "n"
+Specifies the angle in degrees for a spotlight cone. Default 40.
+
+"_softangle" "n"
+Specifies the angle in degrees for an inner spotlight cone (must be less than the "angle" cone. Creates a softer transition between the full brightness of the inner cone to the edge of the outer cone. Default 0 (disabled).
+
+"targetname" "name"
+Turns the light into a switchable light, toggled by another entity targeting it�s name.
+
+"speed" "n"
+If the light is switchable and FADE_IN_OUT is set, the speed at which the light transitions. Default 0.1.
+
+"style" "n"
+Set the animated light style. Default 0.
+
+"style2" "n"
+Set the animated light style for a switchable light, because style will be overriden if a targetname is set. Default 0.
+
+"_anglescale" "n" | "_anglesense" "n"
+Sets a scaling factor for how much influence the angle of incidence of light on a surface has on the brightness of the surface. n must be between 0.0 and 1.0. Smaller values mean less attenuation, with zero meaning that angle of incidence has no effect at all on the brightness. Default 0.5.
+
+"_dirtscale" "n" | "_dirtgain" "n"
+Override the global "_dirtscale" or "_dirtgain" settings to change how this light is affected by dirtmapping (ambient occlusion). See descriptions of these keys in the worldspawn section.
+
+"_dirt" "n"
+Overrides the worldspawn setting of "_dirt" for this particular light. -1 to disable dirtmapping (ambient occlusion) for this light, making it illuminate the dirtmapping shadows. 1 to enable ambient occlusion for this light. Default is to defer to the worldspawn setting.
+
+"_deviance" "n"
+Split up the light into a sphere of randomly positioned lights within radius "n" (in world units). Useful to give shadows a wider penumbra. "_samples" specifies the number of lights in the sphere. The "light" value is automatically scaled down for most lighting formulas (except linear and non-additive minlight) to attempt to keep the brightness equal. Default is 0, do not split up lights.
+
+"_samples" "n"
+Number of lights to use for "_deviance". Default 16 (only used if "_deviance" is set).
+
+"_surface" "texturename"
+Makes surfaces with the given texture name emit light, by using this light as a template which is copied across those surfaces. Lights are spaced about 128 units (though possibly closer due to bsp splitting) apart and positioned 2 units above the surfaces.
+
+"_surface_offset" "n"
+Controls the offset lights are placed above surfaces for "_surface". Default 2.
+
+"_surface_spotlight" "n"
+For a surface light template (i.e. a light with "_surface" set), setting this to "1" makes each instance into a spotlight, with the direction of light pointing along the surface normal. In other words, it automatically sets "mangle" on each of the generated lights.
+
+"_project_texture" "texture"
+Specifies that a light should project this texture. The texture must be used in the map somewhere.
+
+"_project_mangle" "yaw pitch roll"
+Specifies the yaw/pitch/roll angles for a texture projection (overriding mangle).
+
+"_project_fov" "n"
+Specifies the fov angle for a texture projection. Default 90.
+
+"_bouncescale" "n"
+Scales the amount of light that is contributed by bounces. Default is 1.0, 0.0 disables bounce lighting for this light.
+
+"_sun" "n"
+Set to 1 to make this entity a sun, as an alternative to using the sunlight worldspawn keys. If the light targets an info_null entity, the direction towards that entity sets sun direction. The light itself is disabled, so it can be placed anywhere in the map.
+
+The following light properties correspond to these sunlight settings:
+light => _sunlight
+mangle => _sunlight_mangle
+deviance => _sunlight_penumbra
+_color => _sunlight_color
+_dirt => _sunlight_dirt
+_anglescale => _anglescale
+
+ //dumptruck_ds taken from honey (originally from Rogue)
+White candle
+*/
+void() light_candle =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/candle.mdl");
+ setmodel (self, "progs/candle.mdl");
+ makestatic (self);
+};
+
+void() model_candle_think =
+{
+ self.frame = self.frame + 1;
+ if (self.frame > 3)
+ self.frame = 0;
+ self.nextthink = time + 0.1;
+};
+
+void() model_candle =
+{
+
+ precache_model ("progs/candle.mdl");
+
+ setmodel (self, "progs/candle.mdl");
+
+ self.think = model_candle_think;
+ self.nextthink = time + 0.1;
+};
+
+
+//============================================================================
+
+
+/*QUAKED misc_fireball (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model ("progs/lavaball.mdl"); }
+Flying lava balls
+speed - set vertical speed of fireballs. default 1000.
+*/
+
+void() fire_fly;
+void() fire_touch;
+void() misc_fireball =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/lavaball.mdl");
+ self.classname = "fireball";
+// 1998-08-14 Incorrect setting of nextthink fix by Maddes/Lord Sméagol
+// self.nextthink = time + (random() * 5);
+ self.nextthink = time + 0.1 + (random() * 5);
+// 1998-08-14 Incorrect setting of nextthink fix by Maddes/Lord Sméagol
+ self.think = fire_fly;
+ if (!self.speed)
+ self.speed = 1000; // fixed typo QIP - dumptruck_ds
+};
+
+void() fire_fly =
+{
+local entity fireball;
+
+ fireball = spawn();
+ fireball.solid = SOLID_TRIGGER;
+ fireball.movetype = MOVETYPE_TOSS;
+ fireball.velocity = '0 0 1000';
+ fireball.velocity_x = (random() * 100) - 50;
+ fireball.velocity_y = (random() * 100) - 50;
+ fireball.velocity_z = self.speed + (random() * 200);
+ fireball.classname = "fireball";
+ setmodel (fireball, "progs/lavaball.mdl");
+ setsize (fireball, '0 0 0', '0 0 0');
+ setorigin (fireball, self.origin);
+ fireball.nextthink = time + 5;
+ fireball.think = SUB_Remove;
+ fireball.touch = fire_touch;
+
+ self.nextthink = time + (random() * 5) + 3;
+ self.think = fire_fly;
+};
+
+
+void() fire_touch =
+{
+ T_Damage (other, self, self, 20);
+ remove(self);
+};
+
+//============================================================================
+
+
+void() barrel_explode =
+{
+ self.takedamage = DAMAGE_NO;
+ self.classname = "explo_box";
+ // did say self.owner
+ T_RadiusDamage (self, self, 160, world);
+ sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
+ particle (self.origin, '0 0 0', 75, 255);
+
+ self.origin_z = self.origin_z + 32;
+ BecomeExplosion ();
+};
+
+
+
+/*QUAKED misc_explobox (0 .5 .8) (0 0 0) (32 32 64) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model("maps/b_explob.bsp");
+}
+Explosive box
+*/
+
+void() misc_explobox =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ local float oldz;
+
+ self.solid = SOLID_BBOX;
+ self.movetype = MOVETYPE_NONE;
+ precache_model ("maps/b_explob.bsp");
+ setmodel (self, "maps/b_explob.bsp");
+ precache_sound ("weapons/r_exp3.wav");
+ self.health = 20;
+ self.th_die = barrel_explode;
+ self.takedamage = DAMAGE_AIM;
+ self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+
+ self.origin_z = self.origin_z + 2;
+ oldz = self.origin_z;
+ droptofloor();
+ if (oldz - self.origin_z > 250)
+ {
+ dprint ("item fell out of level at ");
+ dprint (vtos(self.origin));
+ dprint ("\n");
+ remove(self);
+ }
+};
+
+
+
+
+/*QUAKED misc_explobox2 (0 .5 .8) (0 0 0) (32 32 64) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model("maps/b_exbox2.bsp");
+}
+Smaller explosive box
+*/
+
+void() misc_explobox2 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ local float oldz;
+
+ self.solid = SOLID_BBOX;
+ self.movetype = MOVETYPE_NONE;
+ precache_model2 ("maps/b_exbox2.bsp");
+ setmodel (self, "maps/b_exbox2.bsp");
+ precache_sound ("weapons/r_exp3.wav");
+ self.health = 20;
+ self.th_die = barrel_explode;
+ self.takedamage = DAMAGE_AIM;
+ self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+
+ self.origin_z = self.origin_z + 2;
+ oldz = self.origin_z;
+ droptofloor();
+ if (oldz - self.origin_z > 250)
+ {
+ dprint ("item fell out of level at ");
+ dprint (vtos(self.origin));
+ dprint ("\n");
+ remove(self);
+ }
+};
+
+/*==============================================================================
+trap_spikeshooter from Hipnotic -- with additions by dumptruck_ds
+==============================================================================*/
+
+//MED 11/09/96 added new spawnflags -- taken from hipdefs.qc - dumptruck_ds
+float SPAWNFLAG_SUPERSPIKE = 1;
+float SPAWNFLAG_LASER = 2;
+float SPAWNFLAG_LAVABALL = 4;
+float SPAWNFLAG_ROCKET = 8;
+float SPAWNFLAG_VOREBALL = 16;
+float SPAWNFLAG_GRENADE = 32;
+float SPAWNFLAG_GIBS = 64;
+float SPAWNFLAG_SILENT = 128;
+
+void() ShalMissileTouch = //moved from Shalrath to enable shooter version
+{
+ if (other == self.owner)
+ return; // don't explode on owner
+
+ if (other.classname == "monster_zombie")
+ T_Damage (other, self, self, 110);
+ T_RadiusDamage (self, self.owner, 40, world);
+ sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ BecomeExplosion ();
+
+
+ // self.velocity = '0 0 0';
+ // self.touch = SUB_Null;
+ // setmodel (self, "progs/s_explod.spr");
+ // self.solid = SOLID_NOT;
+ // s_explode1 ();
+};
+
+void() ZombieGrenadeTouch = //moved from zombie.qc to enable shooter version
+{
+ if (other == self.owner)
+ return; // don't explode on owner
+ if (other.takedamage)
+ {
+ T_Damage (other, self, self.owner, 10 );
+ sound (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM);
+ remove (self);
+ return;
+ }
+ sound (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
+ self.velocity = '0 0 0';
+ self.avelocity = '0 0 0';
+ self.touch = SUB_Remove;
+};
+
+
+void(vector org, vector vec) LaunchLaser;
+
+//MED 11/09/96 added lava ball and rocket
+//dumptruck_ds added voreball and grenades
+void() spikeshooter_use =
+{
+ local entity lavaball;
+ local entity voreball;
+ local entity rockettrap;
+ local entity gnade;
+ local entity zgibs;
+
+ if (self.spawnflags & SPAWNFLAG_LASER)
+ {
+ if (!(self.spawnflags & SPAWNFLAG_SILENT))
+ sound (self, CHAN_VOICE, "enforcer/enfire.wav", 1, ATTN_NORM);
+ LaunchLaser (self.origin, self.movedir);
+ newmis.spawnflags = self.spawnflags;
+ }
+ else if (self.spawnflags & SPAWNFLAG_LAVABALL)
+ {
+ if (!(self.spawnflags & SPAWNFLAG_SILENT))
+ sound (self, CHAN_VOICE, "boss1/throw.wav", 1, ATTN_NORM); //dms
+ // sound (self, CHAN_VOICE, "knight/sword2.wav", 1, ATTN_NORM); //dms
+ // sound (self, CHAN_VOICE, "weapons/ax1.wav", 1, ATTN_NORM); //dms
+ lavaball = spawn();
+ lavaball.movetype = MOVETYPE_FLYMISSILE;
+ lavaball.solid = SOLID_BBOX;
+ lavaball.classname = "lavaball";
+ // set lavaball speed
+ lavaball.velocity = self.movedir * 600; //was 300 dms
+ lavaball.angles = vectoangles(lavaball.velocity);
+ lavaball.owner = self;
+ lavaball.touch = ShalMissileTouch;
+ setmodel (lavaball, "progs/lavaball.mdl"); //dms
+ setsize (lavaball, '0 0 0', '0 0 0');
+ setorigin (lavaball, self.origin);
+ lavaball.avelocity = '0 0 400';
+ lavaball.nextthink = time + 5;
+ lavaball.think = SUB_Remove;
+ }
+
+ else if (self.spawnflags & SPAWNFLAG_ROCKET)
+ {
+ if (!(self.spawnflags & SPAWNFLAG_SILENT))
+ sound (self, CHAN_VOICE, "weapons/sgun1.wav", 1, ATTN_NORM);
+ rockettrap = spawn();
+ rockettrap.movetype = MOVETYPE_FLYMISSILE;
+ rockettrap.solid = SOLID_BBOX;
+ rockettrap.classname = "rockettrap";
+ // set rocket speed
+ rockettrap.velocity = self.movedir * 1000;
+ rockettrap.angles = vectoangles(rockettrap.velocity);
+ rockettrap.owner = self;
+ rockettrap.touch = T_MissileTouch;
+ setmodel (rockettrap, "progs/missile.mdl"); //dms
+ setsize (rockettrap, '0 0 0', '0 0 0');
+ setorigin (rockettrap, self.origin);
+ // rockettrap.avelocity = '0 0 400';
+ rockettrap.nextthink = time + 5;
+ rockettrap.think = SUB_Remove;
+ }
+ else if (self.spawnflags & SPAWNFLAG_VOREBALL)
+ {
+ if (!(self.spawnflags & SPAWNFLAG_SILENT))
+ sound (self, CHAN_VOICE, "shalrath/attack2.wav", 1, ATTN_NORM);
+ voreball = spawn();
+ voreball.movetype = MOVETYPE_FLYMISSILE;
+ voreball.solid = SOLID_BBOX;
+ voreball.classname = "voreball";
+ // set voreball speed
+ voreball.velocity = self.movedir * 600; //was 300 dms
+ voreball.angles = vectoangles(voreball.velocity);
+ voreball.owner = self;
+ voreball.touch = ShalMissileTouch;
+ setmodel (voreball, "progs/v_spike.mdl"); //dms
+ setsize (voreball, '0 0 0', '0 0 0');
+ setorigin (voreball, self.origin);
+ voreball.avelocity = '0 0 400';
+ voreball.nextthink = time + 5;
+ voreball.think = SUB_Remove;
+ }
+
+ else if (self.spawnflags & SPAWNFLAG_GRENADE)
+ {
+ if (!(self.spawnflags & SPAWNFLAG_SILENT))
+ sound (self, CHAN_VOICE, "weapons/grenade.wav", 1, ATTN_NORM);
+ gnade = spawn();
+ gnade.movetype = MOVETYPE_BOUNCE;
+ // gnade.movetype = MOVETYPE_FLYMISSILE;
+ gnade.solid = SOLID_BBOX;
+ gnade.classname = "gnade";
+ // set grenade speed
+ // gnade.velocity = self.movedir * 600; //was 300 dms
+ gnade.velocity = self.movedir * 600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
+ gnade.angles = vectoangles(gnade.velocity);
+ gnade.owner = self;
+ gnade.touch = GrenadeTouch;
+ setmodel (gnade, "progs/grenade.mdl"); //dms
+ setsize (gnade, '0 0 0', '0 0 0');
+ setorigin (gnade, self.origin);
+ gnade.avelocity = '300 300 300';
+ gnade.nextthink = time + 2.5;
+ gnade.think = GrenadeExplode;
+ }
+
+ else if (self.spawnflags & SPAWNFLAG_GIBS)
+ {
+ if (!(self.spawnflags & SPAWNFLAG_SILENT))
+ sound (self, CHAN_VOICE, "zombie/z_shot1.wav", 1, ATTN_NORM);
+ zgibs = spawn ();
+ zgibs.owner = self;
+ zgibs.movetype = MOVETYPE_BOUNCE;
+ zgibs.solid = SOLID_BBOX;
+ zgibs.classname = "zgibs";
+ setmodel (zgibs, "progs/zom_gib.mdl");
+ setsize (zgibs, '0 0 0', '0 0 0');
+ setorigin (zgibs, self.origin);
+ zgibs.velocity = self.movedir * 600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
+ zgibs.avelocity = '3000 1000 2000';
+ zgibs.touch = ZombieGrenadeTouch;
+ // set missile duration
+ zgibs.nextthink = time + 2.5;
+ zgibs.think = SUB_Remove;
+ }
+
+ else
+ {
+ if (!(self.spawnflags & SPAWNFLAG_SILENT))
+ sound (self, CHAN_VOICE, "weapons/spike2.wav", 1, ATTN_NORM);
+ launch_spike (self.origin, self.movedir);
+ newmis.velocity = self.movedir * 500;
+ if (self.spawnflags & SPAWNFLAG_SUPERSPIKE)
+ newmis.touch = superspike_touch;
+ }
+};
+
+//MED 11/01/96 added state capability
+void() shooter_think =
+{
+ if (self.state)
+ {
+ spikeshooter_use ();
+ }
+ self.nextthink = time + self.wait;
+};
+
+
+/*QUAKED trap_spikeshooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lavaball rocket silent X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+When triggered, fires a spike in the direction set in QuakeEd.
+Laser is only for REGISTERED.
+*/
+
+//MED 11/01/96 commented out setmovedir
+void() trap_spikeshooter =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.proj_speed_mod <= 0)
+ self.proj_speed_mod = 1;
+ SetMovedir ();
+ self.use = spikeshooter_use;
+ if (self.spawnflags & SPAWNFLAG_LASER)
+ {
+ precache_model2 ("progs/laser.mdl");
+
+ precache_sound2 ("enforcer/enfire.wav");
+ precache_sound2 ("enforcer/enfstop.wav");
+ }
+ else if (self.spawnflags & SPAWNFLAG_LAVABALL)
+ {
+ precache_model ("progs/lavaball.mdl");
+ // precache_sound2 ("knight/sword2.wav"); //dms
+ precache_sound2 ("boss1/throw.wav"); //dms
+ }
+ else if (self.spawnflags & SPAWNFLAG_ROCKET)
+ {
+ precache_model ("progs/missile.mdl");
+ precache_sound ("weapons/sgun1.wav");
+ }
+ else if (self.spawnflags & SPAWNFLAG_VOREBALL)
+ {
+ precache_model ("progs/v_spike.mdl");
+ precache_sound ("shalrath/attack2.wav");
+ }
+ else if (self.spawnflags & SPAWNFLAG_GRENADE)
+ {
+ precache_model ("progs/grenade.mdl");
+ precache_sound ("weapons/grenade.wav"); // grenade launcher
+ }
+ else if (self.spawnflags & SPAWNFLAG_GIBS)
+ {
+ precache_model ("progs/zom_gib.mdl");
+ precache_sound ("zombie/z_shot1.wav"); // Zombie gibs
+ precache_sound ("zombie/z_miss.wav");
+ precache_sound ("zombie/z_hit.wav");
+ }
+
+ else
+ precache_sound ("weapons/spike2.wav");
+};
+
+
+/*QUAKED trap_shooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lavaball rocket silent X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Continuously fires spikes.
+"wait" time between spike (1.0 default)
+"nextthink" delay before firing first spike, so multiple shooters can be stagered.
+*/
+void() trap_shooter =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ trap_spikeshooter ();
+
+ if (self.wait == 0)
+ self.wait = 1;
+//MED 11/01/96 added state capability
+ self.state = 1;
+ self.nextthink = self.nextthink + self.wait + self.ltime;
+ self.think = shooter_think;
+};
+
+//MED 11/01/96 added new use function
+void() trap_shooter_use =
+ {
+ self.state = 1 - self.state;
+ };
+//MED 11/01/96 added new function
+/*QUAKED trap_switched_shooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lavaball rocket silent X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Continuously fires spikes.
+"wait" time between spike (1.0 default)
+"nextthink" delay before firing first spike, so multiple shooters can be stagered.
+"state" 0 initially off, 1 initially on. (0 default)
+*/
+void() trap_switched_shooter =
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ trap_spikeshooter ();
+
+ if (self.wait == 0)
+ self.wait = 1;
+//MED 11/01/96 added state capability
+ self.nextthink = self.nextthink + self.wait + self.ltime;
+ self.think = shooter_think;
+ self.use = trap_shooter_use;
+ };
+
+/*
+===============================================================================
+
+
+===============================================================================
+*/
+
+
+void() make_bubbles;
+void() bubble_remove;
+void() bubble_bob;
+
+/*QUAKED air_bubbles (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+air bubbles entity
+
+*/
+
+void() air_bubbles =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove (self);
+ return;
+ }
+ precache_model ("progs/s_bubble.spr");
+ self.nextthink = time + 1;
+ self.think = make_bubbles;
+};
+
+void() make_bubbles =
+{
+local entity bubble;
+
+ bubble = spawn();
+ setmodel (bubble, "progs/s_bubble.spr");
+ setorigin (bubble, self.origin);
+ bubble.movetype = MOVETYPE_NOCLIP;
+ bubble.solid = SOLID_NOT;
+ bubble.velocity = '0 0 15';
+ bubble.nextthink = time + 0.5;
+ bubble.think = bubble_bob;
+ bubble.touch = bubble_remove;
+ bubble.classname = "bubble";
+ bubble.frame = 0;
+ bubble.cnt = 0;
+ setsize (bubble, '-8 -8 -8', '8 8 8');
+ self.nextthink = time + random() + 0.5;
+ self.think = make_bubbles;
+};
+
+void() bubble_split =
+{
+local entity bubble;
+ bubble = spawn();
+ setmodel (bubble, "progs/s_bubble.spr");
+ setorigin (bubble, self.origin);
+ bubble.movetype = MOVETYPE_NOCLIP;
+ bubble.solid = SOLID_NOT;
+ bubble.velocity = self.velocity;
+ bubble.nextthink = time + 0.5;
+ bubble.think = bubble_bob;
+ bubble.touch = bubble_remove;
+ bubble.classname = "bubble";
+ bubble.frame = 1;
+ bubble.cnt = 10;
+ setsize (bubble, '-8 -8 -8', '8 8 8');
+ self.frame = 1;
+ self.cnt = 10;
+ if (self.waterlevel != 3)
+ remove (self);
+};
+
+void() bubble_remove =
+{
+ if (other.classname == self.classname)
+ {
+// dprint ("bump");
+ return;
+ }
+ remove(self);
+};
+
+void() bubble_bob =
+{
+local float rnd1, rnd2, rnd3;
+
+
+ self.cnt = self.cnt + 1;
+ if (self.cnt == 4)
+ bubble_split();
+ if (self.cnt == 20)
+ remove(self);
+
+ rnd1 = self.velocity_x + (-10 + (random() * 20));
+ rnd2 = self.velocity_y + (-10 + (random() * 20));
+ rnd3 = self.velocity_z + 10 + random() * 10;
+
+ if (rnd1 > 10)
+ rnd1 = 5;
+ if (rnd1 < -10)
+ rnd1 = -5;
+
+ if (rnd2 > 10)
+ rnd2 = 5;
+ if (rnd2 < -10)
+ rnd2 = -5;
+
+ if (rnd3 < 10)
+ rnd3 = 15;
+ if (rnd3 > 30)
+ rnd3 = 25;
+
+ self.velocity_x = rnd1;
+ self.velocity_y = rnd2;
+ self.velocity_z = rnd3;
+
+ self.nextthink = time + 0.5;
+ self.think = bubble_bob;
+};
+
+/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>
+~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/
+
+/*QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8)
+
+Just for the debugging level. Don't use
+*/
+
+void() viewthing =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_NOT;
+ precache_model ("progs/player.mdl");
+ setmodel (self, "progs/player.mdl");
+};
+
+
+/*
+==============================================================================
+
+SIMPLE BMODELS
+
+==============================================================================
+*/
+
+void() func_wall_use =
+{ // change to alternate textures
+ self.frame = 1 - self.frame;
+};
+
+/*QUAKED func_wall (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+This is just a solid wall if not inhibitted
+*/
+void() func_wall =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.angles = '0 0 0';
+ self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
+ self.solid = SOLID_BSP;
+ self.use = func_wall_use;
+ setmodel (self, self.model);
+};
+
+
+/*QUAKED func_illusionary (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+A simple entity that looks solid but lets you walk through it.
+*/
+void() func_illusionary =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.angles = '0 0 0';
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_NOT;
+ setmodel (self, self.model);
+ makestatic (self);
+};
+
+
+float GATE_REVERSE = 16; // For func_episodegate and func_bossgate appear when player has all runes
+
+/*QUAKED func_episodegate (0 .5 .8) ? E1 E2 E3 E4 REVERSE_FUNCTIONALITY
+This bmodel will appear if the episode has allready been completed, so players can't reenter it.
+*/
+void() func_episodegate =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & GATE_REVERSE)
+ {
+ self.spawnflags = self.spawnflags - GATE_REVERSE; // this is to avoid a possible issue with sigil_touch2
+ if (serverflags & self.spawnflags)
+ return; // Haven't gotten rune yet
+ }
+ else
+ {
+ if (!(serverflags & self.spawnflags))
+ return; // can still enter episode
+ }
+ self.angles = '0 0 0';
+ self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
+ self.solid = SOLID_BSP;
+ self.use = func_wall_use;
+ setmodel (self, self.model);
+};
+
+/*QUAKED func_bossgate (0 .5 .8) ? X X X X REVERSE_FUNCTIONALITY
+This bmodel appears unless players have all of the episode sigils.
+*/
+void() func_bossgate =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & GATE_REVERSE)
+ {
+ if (!((serverflags & 15) == 15))
+ {
+ return; // not all complete
+ }
+ }
+ else
+ {
+ if ( (serverflags & 15) == 15 )
+ return; // all episodes completed
+ }
+ self.angles = '0 0 0';
+ self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
+ self.solid = SOLID_BSP;
+ self.use = func_wall_use;
+ setmodel (self, self.model);
+};
+
+/*****************
+func_togglevisiblewall
+
+A bmodel which you can toggle its visibility. Behaves much like a traditional func_wall in any other way,
+but you can target it to toggle visible/invisible.
+If the entity has a switchable shadow it also toggles.
+
+spawnflag 1: starts invisible
+spawnflag 2: set brush as non-solid
+
+******************/
+
+float TOGGLEVISWALL_STARTOFF = 1;
+float TOGGLEVISWALL_NOTSOLID = 2;
+
+void() func_togglevisiblewall_use =
+{
+ if(!self.state) {
+ if(!(self.spawnflags & TOGGLEVISWALL_NOTSOLID)) {
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ }
+ setmodel (self, self.origmodel);
+ if(self.switchshadstyle) lightstyle(self.switchshadstyle, "a");
+ self.state = 1;
+ } else {
+
+ self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_NONE;
+ setmodel (self, "");
+ if(self.switchshadstyle) lightstyle(self.switchshadstyle, "m");
+ self.state = 0;
+ }
+
+};
+
+void() func_togglevisiblewall =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.angles = '0 0 0';
+ self.use = func_togglevisiblewall_use;
+
+ self.origmodel = self.model;
+
+ if(self.spawnflags & TOGGLEVISWALL_STARTOFF) self.state = 1;
+ else self.state = 0;
+
+ if(self.spawnflags & TOGGLEVISWALL_NOTSOLID) {
+ self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_NONE;
+ }
+
+ func_togglevisiblewall_use();
+
+};
+
+
+/*****************
+func_shadow
+
+An invisible bmodel that can be used to only cast shadows.
+
+******************/
+
+void() func_shadow = {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.angles = '0 0 0';
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_NOT;
+
+ self.modelindex = 0;
+ self.model = "";
+
+}
+
+
+
+/********************
+misc_shadowcontroller
+
+Controls switchable shadows on any bmodel entity (except doors).
+Target entity must have set _switchableshadow set to 1.
+
+speed: Controls the time in seconds it takes to fade the shadow in. Default is 0.5, and setting it to -1 disables fading.
+speed2: Same as 'speed' but for the fade out animation. If unset it's the same value as 'speed'.
+spawnflag 1: target shadow starts as disabled
+
+*********************/
+
+float SHADOWCONTROLLER_STARTOFF = 1;
+
+void() shadow_fade_out =
+{
+ if (self.count < 0)
+ self.count = 0;
+ if (self.count > 12)
+ self.count = 12;
+
+ dprint(ftos(self.count));dprint("\n");
+
+ lightstyle(self.switchshadstyle, lightstyle_fade_lookup(self.count));
+ self.count = self.count + self.dmg;
+ if (self.count > 12)
+ return;
+
+ self.think = shadow_fade_out;
+ self.nextthink = time + self.delay;
+};
+
+void() shadow_fade_in =
+{
+ if (self.count < 0)
+ self.count = 0;
+ if (self.count > 12)
+ self.count = 12;
+
+ dprint(ftos(self.count));dprint("\n");
+
+ lightstyle(self.switchshadstyle, lightstyle_fade_lookup(self.count));
+ self.count = self.count - self.dmg;
+ if (self.count < 0)
+ return;
+
+ self.think = shadow_fade_in;
+ self.nextthink = time + self.delay;
+
+};
+
+void(float speed) misc_shadowcontroller_setsteps = {
+ // self.delay -> time between steps
+ // self.dmg -> step size
+ if(speed >= 0.24) {
+ self.delay = (speed/12);
+ self.dmg = 1;
+ }
+ else if(speed >= 0.12) {
+ self.delay = (speed/6);
+ self.dmg = 2;
+ }
+ else if(speed >= 0.06) {
+ self.delay = (speed/3);
+ self.dmg = 4;
+ }
+ else if(speed >= 0.04) {
+ self.delay = (speed/2);
+ self.dmg = 6;
+ }
+ else {
+ self.delay = 0;
+ self.dmg = 12;
+ }
+
+}
+
+void() misc_shadowcontroller_use = {
+
+ if(self.shadowoff) {
+ dprint("Fade in:\n");
+
+ misc_shadowcontroller_setsteps(self.speed);
+
+ shadow_fade_in();
+
+ self.shadowoff = 0;
+ } else {
+ dprint("Fade out:\n");
+
+ misc_shadowcontroller_setsteps(self.speed2);
+
+ shadow_fade_out();
+
+ self.shadowoff = 1;
+ }
+}
+
+void() misc_shadowcontroller = {
+ entity t1;
+
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+
+ // doesn't search for a target if switchshadstyle is already set
+ // used for built-in shadow controllers
+ if(!self.switchshadstyle) {
+
+ // we need to find only the first target entity with switchable shadows set, since shadow lightstyles are bound by targetname
+
+
+ t1 = find(world, targetname2, self.target);
+
+ while(t1 != world && !t1.switchshadstyle) {
+ t1 = find(t1, targetname2, self.target);
+ }
+
+ if(t1 == world) {
+ t1 = find(world, targetname, self.target);
+
+ while(t1 != world && !t1.switchshadstyle) {
+ t1 = find(t1, targetname, self.target);
+ }
+ }
+
+
+ if(t1 == world) {
+ dprint("\b[misc_shadowcontroller]\b _switchableshadow not set in target ");dprint(self.target);dprint("\n");
+ return;
+ }
+
+ self.switchshadstyle = t1.switchshadstyle;
+ }
+
+ if(!self.speed) self.speed = 0.5;
+ if(!self.speed2) self.speed2 = self.speed;
+
+ if(self.spawnflags & SHADOWCONTROLLER_STARTOFF) {
+ lightstyle(self.switchshadstyle, "m");
+
+ self.shadowoff = 1;
+ self.count = 12;
+
+ misc_shadowcontroller_setsteps(self.speed2);
+ }
+ else {
+ lightstyle(self.switchshadstyle, "a");
+ self.shadowoff = 0;
+ self.count = 0;
+ misc_shadowcontroller_setsteps(self.speed);
+ }
+
+ self.use = misc_shadowcontroller_use;
+}
+
+
+/*
+misc_infight
+
+target = monster that gets mad
+target2 = who target1 will be angry at
+
+spawnflag 1 = mutual hate, both targets get angry at each other instantly
+spawnflag 2 = maintain activator, makes it so the player that triggers the infighting sees centerprints triggered by it
+*/
+
+float INFIGHT_MUTUAL = 1;
+float INFIGHT_PLAYER_ACTIVATION = 2;
+
+void(entity t1, entity t2) make_angry_at =
+{
+ if (t2.health > 0 && t1.health > 0) { // checks if targets are alive
+ if (t1.enemy.classname == "player")
+ t1.oldenemy = t1.enemy;
+ t1.enemy = t2;
+
+ entity oself = self;
+ self = t1; // FoundTarget() only acts on self
+ FoundTarget();
+ self = oself;
+ }
+};
+
+void() misc_infight_use =
+{
+ local entity t1, t2;
+
+ for (t1 = world; (t1 = find(t1, targetname, self.target)); )
+ {
+ for (t2 = world; (t2 = find(t2, targetname, self.target2)); )
+ {
+ // t1 = find(world, targetname, self.target);
+ // t2 = find(world, targetname, self.target2);
+
+ if (!t1)
+ {
+ dprint("[trigger_infight] Cannot find target, checking targetname2\n");
+ t1 = find(world, targetname2, self.target);
+ }
+ if (!t1)
+ {
+ dprint("[trigger_infight] Cannot find target, checking targetname3\n");
+ t1 = find(world, targetname3, self.target);
+ }
+ if (!t1)
+ {
+ dprint("[trigger_infight] Cannot find target, checking targetname4\n");
+ t1 = find(world, targetname4, self.target);
+ }
+ if (!t1)
+ {
+ dprint("[trigger_infight] Cannot find target, exhausted all targetnames\n");
+ return;
+ }
+ if (!t2)
+ {
+ dprint("[trigger_infight] Cannot find target2 checking targetname2\n");
+ t2 = find(world, targetname2, self.target2);
+ }
+ if (!t2)
+ {
+ dprint("[trigger_infight] Cannot find target2 checking targetname3\n");
+ t2 = find(world, targetname3, self.target2);
+ }
+ if (!t2)
+ {
+ dprint("[trigger_infight] Cannot find target2 checking targetname4\n");
+ t2 = find(world, targetname4, self.target2);
+ }
+ if (!t2)
+ {
+ dprint("[trigger_infight] Cannot find target2, exhausted all targetnames\n");
+ return;
+ }
+
+ make_angry_at(t1, t2);
+
+ if (self.spawnflags & INFIGHT_PLAYER_ACTIVATION)
+ {
+ t1.infight_activator = activator;
+ t2.infight_activator = activator;
+ }
+
+ if (self.spawnflags & INFIGHT_MUTUAL)
+ make_angry_at(t2, t1);
+ }
+ }
+};
+
+void() misc_infight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.use = misc_infight_use;
+};
+
+
+
+
+
+//============================================================================
+/*QUAKED ambient_suck_wind (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_suck_wind =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/suck1.wav");
+ ambientsound (self.origin, "ambience/suck1.wav", 1, ATTN_STATIC);
+};
+
+/*QUAKED ambient_drone (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_drone =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/drone6.wav");
+ ambientsound (self.origin, "ambience/drone6.wav", 0.5, ATTN_STATIC);
+};
+
+/*QUAKED ambient_flouro_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_flouro_buzz =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/buzz1.wav");
+ ambientsound (self.origin, "ambience/buzz1.wav", 1, ATTN_STATIC);
+};
+/*QUAKED ambient_drip (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_drip =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/drip1.wav");
+ ambientsound (self.origin, "ambience/drip1.wav", 0.5, ATTN_STATIC);
+};
+/*QUAKED ambient_comp_hum (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+*/
+void() ambient_comp_hum =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/comp1.wav");
+ ambientsound (self.origin, "ambience/comp1.wav", 1, ATTN_STATIC);
+};
+/*QUAKED ambient_light_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_light_buzz =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/fl_hum1.wav");
+ ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC);
+};
+/*QUAKED ambient_swamp1 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_swamp1 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/swamp1.wav");
+ ambientsound (self.origin, "ambience/swamp1.wav", 0.5, ATTN_STATIC);
+};
+/*QUAKED ambient_swamp2 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_swamp2 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/swamp2.wav");
+ ambientsound (self.origin, "ambience/swamp2.wav", 0.5, ATTN_STATIC);
+};
+/////////////////////////////////////////////////////////////
+////////// dumptruck_ds ////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+/* Additions to Ambient Sound effects. These are hard coded into the engine and
+ usually play back automatically when the sky or water textures are used. If
+ you'd prefer to use these in custom setups, you can use the command line
+ switch -nomabient in when you VIS your map to disable the hard coded sounds. */
+
+/*QUAKED ambient_water1 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_water1 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/water1.wav");
+ ambientsound (self.origin, "ambience/water1.wav", 1, ATTN_STATIC);
+};
+/*QUAKED ambient_wind2 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_wind2 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/wind2.wav");
+ ambientsound (self.origin, "ambience/wind2.wav", 1, ATTN_STATIC);
+};
+/////////////////////////////////////////////////////////////
+////////// dumptruck_ds ////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+/* The original ambient_thunder was included in Quake but the code was missing.
+ This version is borrowed from the Zerstörer mod but modified to only play the
+ original thumder1.wav included in the game. This is also different than the
+ other ambient sounds as it plays back randomly as opposed to looping. You
+ only need one of these in your level. It will play everywhere. */
+
+void() thunder_go_boom =
+{
+ if (random() < 0.5)
+ sound (self, CHAN_AUTO, "ambience/thunder1.wav", 0.7, ATTN_NONE);
+ else
+ sound (self, CHAN_AUTO, "ambience/thunder1.wav", 1, ATTN_NONE);
+
+ self.think = thunder_go_boom;
+ self.nextthink = time + 40*random();
+};
+
+/*QUAKED ambient_thunder (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+The original ambient_thunder was included in Quake but the code was missing.
+This version is borrowed from the Zerstörer mod but modified to only play the
+original thumder1.wav included in the game. This is also different than the
+other ambient sounds as it plays back randomly as opposed to looping. You
+only need one of these in your level. It will play everywhere.
+*/
+void() ambient_thunder =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ // changed from ambient to delayed sound (sounds better)
+ precache_sound ("ambience/thunder1.wav");
+ // precache_sound ("ambience/thunder2.wav"); this file in not included in the game
+ self.think = thunder_go_boom;
+ self.nextthink = time + random();
+};
+
+
+
+//============================================================================
+
+void() noise_think =
+{
+ self.nextthink = time + 0.5;
+ sound (self, 1, "enforcer/enfire.wav", 1, ATTN_NORM);
+ sound (self, 2, "enforcer/enfstop.wav", 1, ATTN_NORM);
+ sound (self, 3, "enforcer/sight1.wav", 1, ATTN_NORM);
+ sound (self, 4, "enforcer/sight2.wav", 1, ATTN_NORM);
+ sound (self, 5, "enforcer/sight3.wav", 1, ATTN_NORM);
+ sound (self, 6, "enforcer/sight4.wav", 1, ATTN_NORM);
+ sound (self, 7, "enforcer/pain1.wav", 1, ATTN_NORM);
+};
+
+/*QUAKED misc_noisemaker (1 0.5 0) (-10 -10 -10) (10 10 10) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+For optimzation testing, starts a lot of sounds.
+*/
+
+void() misc_noisemaker =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound2 ("enforcer/enfire.wav");
+ precache_sound2 ("enforcer/enfstop.wav");
+ precache_sound2 ("enforcer/sight1.wav");
+ precache_sound2 ("enforcer/sight2.wav");
+ precache_sound2 ("enforcer/sight3.wav");
+ precache_sound2 ("enforcer/sight4.wav");
+ precache_sound2 ("enforcer/pain1.wav");
+ precache_sound2 ("enforcer/pain2.wav");
+ precache_sound2 ("enforcer/death1.wav");
+ precache_sound2 ("enforcer/idle1.wav");
+
+ self.nextthink = time + 0.1 + random();
+ self.think = noise_think;
+};
+
+
+/***********************************************
+
+target_autosave
+from Copper
+
+***********************************************/
+
+void() target_autosave_use =
+{
+ if (self.enemy)
+ {
+ activator = self.enemy;
+ self.enemy = world;
+ }
+ if (activator.classname != "player") return;
+ if (time < 2) // make sure an autosave fired from a player start doesn't happen too early
+ {
+ //if (serverflags & SVFL_RESPAWNING)
+ //{
+ // dprint("RESPAWNING flag set, skipping autosave\n");
+ // return;
+ //}
+ self.enemy = activator;
+ self.think = target_autosave_use;
+ self.nextthink = 2;
+ return;
+ }
+ // sound(activator, CHAN_VOICE, "misc/sav.wav", 0.3, ATTN_NORM);
+ autosave(activator, self.message);
+}
+
+void() toggle_autosave =
+{
+ entity e = world;
+ float printed = FALSE;
+ do {
+ e = find(e, classname, "target_autosave");
+ if (!e) break;
+
+ if (e.use == target_autosave_use)
+ {
+ e.use = SUB_Null;
+ if (!printed)
+ {
+ bprint("Autosaves disabled\n");
+ printed = TRUE;
+ }
+ } else {
+ e.use = target_autosave_use;
+ if (!printed)
+ {
+ bprint("Autosaves reenabled\n");
+ printed = TRUE;
+ }
+ }
+
+ } while (e != world);
+}
+
+/*QUAKED target_autosave (1 .0 .5) (-8 -8 -8) (8 8 8)
+Saves the game when triggered by a player. Never appears in multiplayer. the bprint tends to stomp any other prints on screen in most quake clients, so use a delayed trigger_relay if you fire this from an important pickup/trigger_counter/something else that puts text on screen more important than the autosave blurb.
+
+Keys:
+"message" change save file name, defaults to 'auto'
+*/
+/*FGD
+@Pointclass base(Target, Targetname, Appearflags) color(255 0 128) size(32 32 32) = target_autosave :
+"Saves the game when triggered by a player. Never appears in multiplayer.
+the bprint tends to stomp any other prints on screen in most quake clients, so use a delayed trigger_relay if you fire this from an important pickup/trigger_counter/something else that puts text on screen more important than the autosave blurb."
+[
+ message(string) : "Change save filename" : "auto"
+]
+*/
+void() target_autosave =
+{
+ if (deathmatch || coop)
+ {
+ remove(self);
+ return;
+ }
+
+
+ if (self.message == string_null)
+ self.message = "auto";
+ // precache_sound2("misc/sav.wav");
+ self.use = target_autosave_use;
+}
+
+
+/*
+=============================================================
+
+trigger_textstory
+
+=============================================================
+*/
+
+float TEXTSTORY_SILENT = 1;
+float TEXTSTORY_NOFADE = 2;
+
+void(entity controller) textstory_hide = {
+ if (!self.enemy || !(self.enemy.flags & FL_CLIENT)) return;
+
+ self.enemy.suppressCenterPrint = FALSE;
+ centerprint(self.enemy, "");
+
+ if (controller.noise2)
+ sound(self.enemy, CHAN_BODY, controller.noise2, 1, ATTN_NORM);
+
+ if (!(controller.spawnflags & TEXTSTORY_NOFADE))
+ csf_fade(self.enemy, 0, '0 0 0', 0.5);
+
+};
+
+void(entity controller) textstory_show = {
+ if (!self.enemy || !(self.enemy.flags & FL_CLIENT)) return;
+
+ self.enemy.suppressCenterPrint = TRUE;
+
+ centerprint_builtin(self.enemy, controller.message);
+
+ if (!self.state) {
+ if (controller.noise1)
+ sound(self.enemy, CHAN_BODY, controller.noise1, 1, ATTN_NORM);
+
+ if (!(controller.spawnflags & TEXTSTORY_NOFADE))
+ if (!self.fade_amt) //custom fade amount --dumptruck_ds
+ {
+ csf_fade(self.enemy, 160, '0 0 0', 1);
+ }
+ else
+ csf_fade(self.enemy, self.fade_amt, '0 0 0', 1);
+ }
+
+
+ self.state = 1;
+};
+
+//----------------------------------------
+
+void() trigger_textstory_hide = {
+ textstory_hide(self);
+
+ self.enemy = world;
+ self.state = 0;
+};
+
+void() trigger_textstory_show = {
+ textstory_show(self);
+
+ self.think = trigger_textstory_hide;
+ self.nextthink = time + 0.2;
+
+};
+
+void() trigger_textstory_touch = {
+
+ if (!(other.flags & FL_CLIENT)) return;
+ if (self.estate != STATE_ACTIVE) return;
+
+ // don't show message if another player is already triggering it
+ if (other != self.enemy && self.state == 1) return;
+
+ if (self.mangle && !isInAngle(other.v_angle, self.mangle, self.view_ofs))
+ return;
+
+ if (self.attack_finished < time) {
+
+ self.attack_finished = time + 0.1;
+ self.enemy = other;
+
+ trigger_textstory_show();
+ }
+};
+
+void() trigger_textstory = {
+ InitTrigger();
+ self.touch = trigger_textstory_touch;
+
+ if (self.view_ofs == '0 0 0')
+ self.view_ofs = '90 90 0';
+
+ if (self.mangle) self.mangle = normalizeAngles180(self.mangle);
+
+ if (self.noise1 == "")
+ self.noise1 = "misc/talk.wav";
+
+ if (self.noise2 == "")
+ self.noise2 = "misc/null.wav";
+
+ if (self.spawnflags & TEXTSTORY_SILENT) {
+ self.noise1 = "";
+ self.noise2 = "";
+ }
+
+
+ if (self.noise1 != "")
+ precache_sound (self.noise1);
+ if (self.noise2 != "")
+ precache_sound (self.noise2);
+
+ SUB_CheckWaiting();
+};
+
+
+//-----------------------------
+
+
+void() target_textstory_helper_hide = {
+
+ textstory_hide(self.owner);
+ remove(self);
+};
+
+void() target_textstory_helper_show = {
+ if (!self.enemy || !(self.enemy.flags & FL_CLIENT)) {
+ remove(self);
+ return;
+ }
+
+ textstory_show(self.owner);
+
+ if (self.attack_finished < time) self.think = target_textstory_helper_hide;
+
+ self.nextthink = time + 0.1;
+};
+
+void(entity tgt) target_textstory_spawn_helper = {
+ entity e;
+
+ e = spawn();
+ e.classname = "target_textstory_helper";
+ e.owner = self;
+ e.think = target_textstory_helper_show;
+ e.nextthink = time + 0.1;
+ e.attack_finished = time + self.wait;
+ e.enemy = tgt;
+};
+
+void() target_textstory_use = {
+
+ if (!(activator.flags & FL_CLIENT)) return;
+ if (self.estate != STATE_ACTIVE) return;
+
+ entity t;
+
+ if (self.spawnflags & TRIGGER_CENTERPRINTALL) {
+ t = find(world, classname, "player");
+ while (t) {
+ target_textstory_spawn_helper(t);
+ t = find(t, classname, "player");
+ }
+ }
+ else
+ target_textstory_spawn_helper(activator);
+};
+
+void() target_textstory = {
+ if (self.noise1 == "")
+ self.noise1 = "misc/talk.wav";
+
+ if (self.noise2 == "")
+ self.noise2 = "misc/null.wav";
+
+ if (self.spawnflags & TEXTSTORY_SILENT) {
+ self.noise1 = "";
+ self.noise2 = "";
+ }
+
+ if (self.noise1 != "")
+ precache_sound (self.noise1);
+ if (self.noise2 != "")
+ precache_sound (self.noise2);
+
+ if (!self.wait)
+ self.wait = 5;
+
+ self.use = target_textstory_use;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/misc_model.qc

diff --git a/qc/misc_model.qc b/qc/misc_model.qc
new file mode 100644
index 0000000..833b3dd
--- /dev/null
+++ b/qc/misc_model.qc
@@ -0,0 +1,170 @@
+/*
+ * misc_model.qc requires math.qc
+ *
+ * Author: Joshua Skelton joshua.skelton@gmail.com
+ * Edited by: Inky 20201219 Minor changes for a better integration with my own code
+ * Edited by: bmFbr for solid and gravity spawnflags and custom bbox sizes
+ * Edited by: dumptruck_ds to add start and stop animations
+ */
+
+// The starting frame of the animation
+.float first_frame;
+
+// The ending frame of the animation
+.float last_frame;
+
+// Forward declarations
+void() misc_model_think;
+
+/*QUAKED misc_model (0 0.5 0.8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path" : mdl, "skin" : skin, "frame": frame});
+}
+An entity for displaying models. A frame range can be given to animate the
+model.
+
+mdl: The model to display. Can be of type mdl, bsp, or spr.
+
+frame: The frame to display. Can be used to offset the animation.
+
+first_frame: The starting frame of the animation.
+
+last_frame: The last frame of the animation.
+*/
+
+float MISC_MODEL_GRAVITY = 1;
+float MISC_MODEL_SOLID = 2;
+float MISC_MODEL_BACK_AND_FORTH = 4;
+float MISC_MODEL_ONLY_ONCE = 8;
+float MISC_MODEL_PLAY_COUNT = 16;
+float MISC_MODEL_STARTOFF = 32;
+
+
+void() misc_model_use = {
+ if (self.state == STATE_ACTIVE) {
+ if (self.spawnflags & MISC_MODEL_SOLID) self.solid = SOLID_NOT;
+ self.model = "";
+
+ self.state = STATE_INVISIBLE;
+ setorigin(self, self.origin);
+ }
+ else {
+ if (self.spawnflags & MISC_MODEL_SOLID) self.solid = SOLID_BBOX;
+ self.model = self.mdl;
+
+ self.state = STATE_ACTIVE;
+ setorigin(self, self.origin);
+ }
+};
+
+void() misc_model = {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.mdl || self.mdl == "")
+ objerror("Model not defined");
+
+ if(!self.centeroffset) self.centeroffset = '0 0 0';
+ if(!self.mdlsz) self.mdlsz = '32 32 32';
+
+ vector vmin, vmax;
+
+ vmin_x = self.centeroffset_x - (self.mdlsz_x / 2);
+ vmin_y = self.centeroffset_y - (self.mdlsz_y / 2);
+ vmin_z = self.centeroffset_z - (self.mdlsz_z / 2);
+
+ vmax_x = self.centeroffset_x + (self.mdlsz_x / 2);
+ vmax_y = self.centeroffset_y + (self.mdlsz_y / 2);
+ vmax_z = self.centeroffset_z + (self.mdlsz_z / 2);
+
+ precache_model(self.mdl);
+ setmodel(self, self.mdl);
+
+ setsize(self, vmin, vmax);
+
+ if(self.spawnflags & MISC_MODEL_SOLID) self.solid = SOLID_BBOX;
+ else self.solid = SOLID_NOT;
+
+ if(self.spawnflags & MISC_MODEL_GRAVITY) self.movetype = MOVETYPE_TOSS;
+ else self.movetype = MOVETYPE_NONE;
+
+ self.use = misc_model_use;
+
+ if (!self.frame) {
+ self.frame = self.first_frame;
+ }
+
+ // Make static (not animate) if not given a frame range, and not affected by gravity
+ // also remains active if it has a targetname (so it can be killtargeted/toggled)
+ if (!self.last_frame
+ && !(self.spawnflags & MISC_MODEL_GRAVITY)
+ && !(self.spawnflags & MISC_MODEL_SOLID)
+ && !self.targetname
+ && !self.targetname2
+ // && !(self.spawnflags & MISC_MODEL_DONTMAKESTATIC)
+ ) makestatic(self);
+ // Make static (not animate) if not given a frame range, and not affected by gravity
+ //changed by bmFbr
+ // if (!self.last_frame && !(self.spawnflags & MISC_MODEL_GRAVITY)) {
+ // makestatic(self);
+ // return;
+ // }
+
+ if (self.last_frame) { // if it as a custom animation range
+ // Default animation speed to 10 fps
+ if (!self.speed) {
+ self.speed = 0.1;
+ }
+ self.nextthink = time + self.speed;
+ self.think = misc_model_think;
+ }
+
+ if (self.spawnflags & MISC_MODEL_STARTOFF)
+ self.state = STATE_ACTIVE;
+ else
+ self.state = STATE_INVISIBLE;
+
+ misc_model_use();
+
+};
+
+/*
+ * misc_model_think
+ *
+ * Handles animation for misc_model entity.
+ */
+void() misc_model_think = {
+ self.nextthink = time + fabs(self.speed);
+ if (self.estate != STATE_ACTIVE) return;
+
+ self.frame = self.frame + sign(self.speed);
+
+ if (self.spawnflags & MISC_MODEL_BACK_AND_FORTH && self.frame < self.first_frame)
+ {
+ self.speed = -1 * self.speed;
+ self.frame+=2;
+ }
+ else if (self.spawnflags & MISC_MODEL_BACK_AND_FORTH && self.frame > self.last_frame)
+ {
+ self.speed = -1 * self.speed;
+ self.frame-=2;
+ }
+ else
+ self.frame = wrap(self.frame, self.first_frame, self.last_frame);
+
+ if(self.spawnflags & MISC_MODEL_ONLY_ONCE && self.frame==self.last_frame && self.last_frame!=self.first_frame)
+ self.nextthink = -1;
+
+ if(self.spawnflags & MISC_MODEL_PLAY_COUNT && self.frame==self.last_frame && self.last_frame!=self.first_frame)
+ {
+ if !(self.count)
+ objerror ("Error: set count to the number of animation cycles!");
+ self.cnt = self.cnt +1;
+ dprint (ftos(self.cnt));
+ dprint ("\n");
+ if (self.cnt != self.count)
+ return FALSE;
+ else
+ self.nextthink = -1;
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/mobot.qc

diff --git a/qc/mobot.qc b/qc/mobot.qc
new file mode 100644
index 0000000..f0bf1a5
--- /dev/null
+++ b/qc/mobot.qc
@@ -0,0 +1,500 @@
+// Using "bot" creation code for func_monster_spawner
+// most of the code is from a tutorial on creating a bot monster found here:
+// https://www.quaddicted.com/webarchive/minion.planetquake.gamespy.com/tutorial/tutor9.htm
+// I added the MobotSpawnPoint, retriggering and random gen with help from
+// kreathor, 4LT, Paril, Spoike and others on the Quake Mapping Discord.
+// ===================================================================
+// Big thanks to ryanscissorhands for helping fix telefragging issues!
+// ===================================================================
+
+float MOBOT_SPAWNER_RESET = 1;
+float MOBOT_DONT_SPAWN_ANGRY = 2;
+float MOBOT_DONT_ADD_KILL_COUNT = 4;
+float MOBOT_SILENT_SPAWN = 32;
+
+/*
+============
+MobotSpawnPoint
+
+Returns the entity to spawn at
+============
+*/
+entity() MobotSpawnPoint =
+{
+ local entity spot;
+
+ // spot = find (world, classname, "info_monster_spawnpoint");
+ spot = find (world, targetname, self.target);
+
+ if (!spot)
+ objerror ("couldn't find target");
+
+ return spot;
+};
+
+// ------------------------------------------------
+void() create_mobot =
+// ------------------------------------------------
+{
+
+local entity bot, spawn_spot;
+
+// start entity and place it in world
+ bot = spawn();
+ spawn_spot = MobotSpawnPoint();
+ // spawn_spot = SelectSpawnPoint (); // let's not use deathmatch points for this -- dumptruck_ds
+ bot.origin = spawn_spot.origin + '0 0 1';
+ bot.angles = spawn_spot.angles;
+ bot.fixangle = TRUE;
+ bot.proj_speed_mod = 1;
+ if (!(self.spawnflags & MOBOT_SILENT_SPAWN)) // SILENT
+ spawn_tfog (bot.origin);
+ spawn_tdeath (bot.origin, bot);
+
+ if (self.style == 1) // spawn a Doggo
+ {
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel(bot, "progs/dog.mdl");
+ setsize (bot, '-32 -32 -24', '32 32 40');
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = dog_stand1;
+ bot.th_walk = dog_walk1;
+ bot.th_run = dog_run1;
+ bot.th_die = dog_die;
+ bot.th_melee = dog_atta1;
+ bot.th_missile = dog_leap1;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ bot.th_pain = dog_pain;
+ else
+ bot.th_pain = SUB_NullPain;
+ bot.health = 25;
+
+ // polish him up
+ bot.classname = "monster_dog";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ }
+
+if (self.style == 2) // spawn a Grunt
+ {
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel(bot, "progs/soldier.mdl");
+ setsize (bot, '-16 -16 -24', '16 16 40');
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = army_stand1;
+ bot.th_walk = army_walk1;
+ bot.th_run = army_run1;
+ bot.th_die = army_die;
+ // bot.th_melee = ogre_melee;
+ bot.th_missile = army_atk1;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ bot.th_pain = army_pain;
+ else
+ bot.th_pain = SUB_NullPain;
+ bot.health = 80;
+
+ // polish him up
+ bot.classname = "monster_army";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ }
+
+if (self.style == 3) // spawn an Enforcer
+ {
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel(bot, "progs/enforcer.mdl");
+ setsize (bot, VEC_HULL2_MIN, VEC_HULL2_MAX);
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = enf_stand1;
+ bot.th_walk = enf_walk1;
+ bot.th_run = enf_run1;
+ bot.th_die = enf_die;
+ // bot.th_melee = ogre_melee;
+ bot.th_missile = enf_atk1;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ bot.th_pain = enf_pain;
+ else
+ bot.th_pain = SUB_NullPain;
+ bot.health = 80;
+
+ // polish him up
+ bot.classname = "monster_enforcer";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ }
+
+if (self.style == 4) // spawn an Ogre
+ {
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel(bot, "progs/ogre.mdl");
+ setsize (bot, VEC_HULL2_MIN, VEC_HULL2_MAX);
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = ogre_stand1;
+ bot.th_walk = ogre_walk1;
+ bot.th_run = ogre_run1;
+ bot.th_die = ogre_die;
+ bot.th_melee = ogre_melee;
+ bot.th_missile = ogre_nail1;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ bot.th_pain = ogre_pain;
+ else
+ bot.th_pain = SUB_NullPain;
+ bot.health = 200;
+
+ // polish him up
+ bot.classname = "monster_ogre";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ }
+
+if (self.style == 5) // spawn an Fiend
+ {
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel(bot, "progs/demon.mdl");
+ setsize (bot, VEC_HULL2_MIN, VEC_HULL2_MAX);
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = demon1_stand1;
+ bot.th_walk = demon1_walk1;
+ bot.th_run = demon1_run1;
+ bot.th_die = demon_die;
+ bot.th_melee = Demon_MeleeAttack; // one of two attacks
+ bot.th_missile = demon1_jump1; // jump attack
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ bot.th_pain = demon1_pain;
+ else
+ bot.th_pain = SUB_NullPain;
+ bot.health = 300;
+
+ // polish him up
+ bot.classname = "monster_demon1";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ }
+
+if (self.style == 6) // spawn a Wizard / Scrag
+ {
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel(bot, "progs/wizard.mdl");
+ setsize (bot, '-16 -16 -24', '16 16 40');
+ bot.flags = bot.flags | FL_FLY;
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = wiz_stand1;
+ bot.th_walk = wiz_walk1;
+ bot.th_run = wiz_run1;
+ bot.th_die = wiz_die;
+ bot.th_missile = Wiz_Missile;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ bot.th_pain = Wiz_Pain;
+ else
+ bot.th_pain = SUB_NullPain;
+ bot.health = 80;
+
+ // polish him up
+ bot.classname = "monster_wizard";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ bot.mdl_proj = "progs/w_spike.mdl";
+
+ }
+
+ if (self.style == 7) // spawn a Shambler
+ {
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel(bot, "progs/shambler.mdl");
+ setsize (bot, '-16 -16 -24', '16 16 40');
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = sham_stand1;
+ bot.th_walk = sham_walk1;
+ bot.th_run = sham_run1;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ bot.th_pain = sham_pain;
+ else
+ bot.th_pain = SUB_NullPain;
+ bot.th_die = sham_die;
+ bot.th_missile = sham_magic1;
+ bot.th_melee = sham_melee;
+ bot.health = 600;
+
+ // polish him up
+ bot.classname = "monster_shambler";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 2';
+ // bot.view_ofs = '0 0 22';
+ }
+
+if (self.style == 8) // spawn a Knight
+ {
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel(bot, "progs/knight.mdl");
+ setsize (bot, '-16 -16 -24', '16 16 40');
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = knight_stand1;
+ bot.th_walk = knight_walk1;
+ bot.th_run = knight_run1;
+ bot.th_die = knight_die;
+ bot.th_melee = knight_atk1;
+ // bot.th_missile = knight_atk1;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ bot.th_pain = knight_pain;
+ else
+ bot.th_pain = SUB_NullPain;
+ bot.health = 75;
+
+ // polish him up
+ bot.classname = "monster_knight";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ }
+
+if (self.style == 9) // spawn a HellKnight
+ {
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel(bot, "progs/hknight.mdl");
+ setsize (bot, '-16 -16 -24', '16 16 40');
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = hknight_stand1;
+ bot.th_walk = hknight_walk1;
+ bot.th_run = hknight_run1;
+ bot.th_melee = hknight_melee;
+ bot.th_die = hknight_die;
+ bot.th_missile = hknight_magicc1;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ bot.th_pain = hknight_pain;
+ else
+ bot.th_pain = SUB_NullPain;
+ bot.health = 250;
+
+ // polish him up
+ bot.classname = "monster_hell_knight";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ }
+
+if (self.style == 11) // spawn a Zombie
+ {
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel(bot, "progs/zombie.mdl");
+ setsize (bot, '-16 -16 -24', '16 16 40');
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = zombie_start;
+ bot.th_walk = zombie_walk1;
+ bot.th_run = zombie_decide;
+ bot.th_pain = zombie_pain;
+ bot.th_die = zombie_die;
+ bot.th_missile = zombie_missile;
+ bot.health = 61;
+
+ // polish him up
+ bot.classname = "monster_zombie";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 2';
+ // bot.view_ofs = '0 0 22';
+ }
+if (self.style == 12) // spawn a Shalrath
+ {
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel(bot, "progs/shalrath.mdl");
+ setsize (bot, VEC_HULL2_MIN, VEC_HULL2_MAX);
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = shal_stand;
+ bot.th_walk = shal_walk1;
+ bot.th_run = shal_run1;
+ bot.th_die = shalrath_die;
+ bot.th_missile = shal_attack1;
+ bot.homing = 1; //fix for func_monster_spawner setting Voreballs to non-homing
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ bot.th_pain = shalrath_pain;
+ else
+ bot.th_pain = SUB_NullPain;
+ bot.health = 400;
+
+ // polish him up
+ bot.classname = "monster_shalrath";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ }
+
+// begin his thinking
+ bot.nextthink = time + 0.2; // this seems better with monster_use -- dumptruck_ds
+ // bot.nextthink = time + 0.1 + random();
+ if (!(self.spawnflags & MOBOT_DONT_SPAWN_ANGRY))
+ {
+ if (bot.classname != "monster_zombie") // required to avoid animation issues -- dumptruck_ds
+ bot.think = monster_use;
+ else
+ bot.think = bot.th_walk;
+ }
+ else
+ {
+ bot.think = walkmonster_start_go;
+ }
+ if (!(self.spawnflags & MOBOT_DONT_ADD_KILL_COUNT))
+ {
+ monster_update_total (1); // repacement function from iw -- dumptruck_ds
+ }
+};
+
+void() think_mobot =
+ {
+ dprint("mobot thinking\n");
+ local entity nearby; // telefrag check thanks to ryanscissorhands for this code! -- dumptruck_ds
+
+ nearby = findradius(self.origin, 128); // findradius (vector origin, float radius in Quake units)
+
+ while (nearby)
+ {
+ if (nearby.takedamage)
+ {
+ dprint("monster waiting to spawn\n");
+ self.think = think_mobot; // qss crash fix from paavohuhtala -- dumptruck_ds
+ self.nextthink = time + 1; //delay the spawn by some amount;
+ return;
+ }
+ nearby = nearby.chain;
+ }
+
+ self.count = self.count - 1;
+
+ if (self.count < 0)
+ {
+ return;
+ }
+ if (self.count!=0)
+ {
+ if !(self.wait)
+ self.nextthink = time + 5;
+ else
+ self.nextthink = time + self.wait;
+
+ if (self.style2 == 1)
+ {
+ self.style = floor(random() * 12) + 1; // random monster!! -- dumptruck_ds
+ create_mobot(); //thanks whirledtsar for your help on this -- dumptruck_ds
+ }
+ else
+ create_mobot();
+ }
+ else {
+ if (self.spawnflags & MOBOT_SPAWNER_RESET)
+ {
+ self.count = self.cnt;
+ self.think = SUB_Null;
+ }
+ }
+
+ self.think = think_mobot; // qthink I didn't realize I could do this! -- dumptruck_ds
+ };
+
+/*QUAKED func_monster_spawner (.75 0 .75) (-8 -8 -8) (8 8 8) REUSABLE X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Spawns monsters to targeted info_monster_spawnpoint
+bot
+Choose Style
+• 1 (Dog (Default)
+• 2 (Grunt)
+• 3 (Enforcer)
+• 4 (Ogre)
+• 5 (Fiend)
+• 6 (Wizard)
+• 7 (Shambler)
+• 8 (Knight)
+• 9 (HellKnight)
+• 10 (Spawn)
+• 11 (Zombie)
+• 12 (Shalrath)
+
+Style 2 set to 1 overrides Style and chooses a random monster (excluding Zombies and Vores)
+
+Default time between spawns is 5 seconds; 12 for Zombies and Vores to reduce telefrags
+
+Can set Berserk to 1 to skip most pain animations.
+
+Can only use default health, models and sounds.
+*/
+void() func_monster_spawner =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if !(self.target)
+ {
+ objerror("func_monster_spawner needs a target");
+ remove(self);
+ return;
+ }
+
+ if !(self.style)
+ self.style = 1;
+
+ if (!self.count)
+ self.count = 5;
+ self.count = self.count + 1; // fixes count display
+ self.cnt = self.count; // hold original count
+
+ self.use = think_mobot;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters.qc

diff --git a/qc/monsters.qc b/qc/monsters.qc
new file mode 100644
index 0000000..cc045ce
--- /dev/null
+++ b/qc/monsters.qc
@@ -0,0 +1,518 @@
+/* ALL MONSTERS SHOULD BE 1 0 0 IN COLOR */
+
+// name =[framenum, nexttime, nextthink] {code}
+// expands to:
+// name ()
+// {
+// self.frame=framenum;
+// self.nextthink = time + nexttime;
+// self.think = nextthink
+// <code>
+// };
+
+/*
+================
+monster_update_total
+
+Call this function to safely update total_monsters when the game is in
+progress. It adds "n" to total_monsters, then notifies all clients of
+the change. -- iw
+================
+*/
+void(float n) monster_update_total =
+{
+ total_monsters = total_monsters + n;
+
+ WriteByte (MSG_ALL, SVC_UPDATESTAT);
+ WriteByte (MSG_ALL, STAT_TOTALMONSTERS);
+ WriteLong (MSG_ALL, total_monsters);
+};
+
+/* From Preach's tutorial here: https://tomeofpreach.wordpress.com/2017/10/08/teleporting-monsters-flag/#more-2281 */
+
+//define Preach's new fields dumptruck_ds
+
+.string tele_model;
+.vector tele_mins;
+.vector tele_maxs;
+.float tele_solid;
+.float tele_movetype;
+
+void(vector org) spawn_tfog;
+void(vector org, entity death_owner) spawn_tdeath;
+
+void() monster_teleport_go =
+{
+self.solid = self.tele_solid;
+self.movetype = self.tele_movetype;
+setmodel(self, self.tele_model);
+setsize (self, self.tele_mins, self.tele_maxs);
+
+self.delay = 0; //fix for cumulative delays for counters etc. -- dumptruck_ds
+
+self.think1();
+//override the random delay some go functions apply
+self.nextthink = time + 0.1;
+ {
+ if !(self.spawnflags & SPAWN_SILENTLY)
+ {
+ if (self.wait == 0) //dumptruck_ds: if wait value is > 0 spawn silently or use a spawnflag
+ spawn_tfog (self.origin);
+ spawn_tdeath(self.origin, self);
+ }
+ }
+
+}
+
+void() monster_teleport_delay = //new from Qmaster func coding help thread
+{
+self.think = monster_teleport_go;
+ if (self.delay == -1)
+ {
+ self.nextthink = time + 0.1 + random(); //if delay is set to -1 random delay from 0.1 to 1 second - dumptruck_ds
+ return;
+ }
+self.nextthink = time + 0.1 + self.delay;
+};
+
+/*
+================
+monster_teleport_check
+
+This detects and eliminates a common map bug: a trigger-spawned monster
+which can't be activated either because it has no targetname or because
+its targetname isn't targeted by any other entity. (This map bug would
+otherwise make it impossible for the player to get 100% kills.) -- iw
+================
+*/
+void() monster_teleport_check =
+{
+ if (!SUB_IsTargeted ())
+ {
+ dprint ("WARNING: removed untargeted trigger-spawned ");
+ dprint (self.classname);
+ dprint (" at ");
+ dprint (vtos (self.origin));
+ dprint ("\n");
+
+ remove (self);
+ return;
+ }
+
+ // the targetname appears to be OK, so let's finish setting up the
+ // trigger-spawned monster -- iw
+ self.use = monster_teleport_delay; // qmaster
+ monster_update_total (1);
+};
+
+float (void() monster_start_fn) monster_teleport =
+{
+if(!(self.spawnflags & 8))
+ return FALSE;
+
+//PREACH: This monster is to be teleported in, so hide it
+self.tele_model= self.model;
+self.tele_mins = self.mins;
+self.tele_maxs = self.maxs;
+self.tele_solid = self.solid;
+self.tele_movetype = self.movetype;
+
+self.model = "";
+self.modelindex = 0;
+self.solid = SOLID_NOT;
+self.movetype = MOVETYPE_NONE;
+self.think1 = monster_start_fn;
+
+// wait for other entities to finish spawning, then check that
+// something targets this -- iw
+self.think = monster_teleport_check;
+self.nextthink = time + 0.1;
+
+return TRUE;
+}
+
+//end of Preach's new fields here
+
+// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
+/*
+================
+by: Philip Martin aka: Kryten
+When on top of monsters or players you slide. This is a QuakeC problem.
+The function below fixes that problem.
+based on code given to Kryten by: Michael Turitzin (MaNiAc)
+================
+*/
+void() monster_touch =
+{
+ //can cause problems for monsters on top of a player, so only players
+ if (other.classname != "player")
+ return;
+ if (other.health <= 0)
+ return;
+
+ if ((!(other.flags & FL_ONGROUND)) && ((other.absmin_z >= self.absmax_z - 2)))
+ other.flags = other.flags + FL_ONGROUND;
+
+ //you can add other stuff like pushable players/monsters here
+};
+// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
+
+/*
+================
+monster_use
+
+Using a monster makes it angry at the current activator
+================
+*/
+void() monster_use =
+{
+ if (self.enemy)
+ return;
+ if (self.health <= 0)
+ return;
+ if (activator.items & IT_INVISIBILITY)
+ return;
+ if (activator.flags & FL_NOTARGET)
+ return;
+ if (activator.movetype == MOVETYPE_NOCLIP) // Copper -- dumptruck_ds
+ return FALSE;
+ if (activator.classname != "player")
+ return;
+
+
+// delay reaction so if the monster is teleported, its sound is still
+// heard
+ self.enemy = activator;
+ self.nextthink = time + 0.1;
+ self.think = FoundTarget;
+};
+
+/*
+================
+monster_death_use
+
+When a mosnter dies, it fires all of its targets with the current
+enemy as activator.
+================
+*/
+void() monster_death_use =
+{
+// fall to ground
+ if (self.flags & FL_FLY)
+ self.flags = self.flags - FL_FLY;
+ if (self.flags & FL_SWIM)
+ self.flags = self.flags - FL_SWIM;
+
+ if (!self.target)
+ return;
+
+ if(self.infight_activator)
+ {
+ activator = self.infight_activator;
+ }
+ else
+ {
+ activator = self.enemy;
+ }
+ SUB_UseTargets ();
+};
+
+/*
+================
+monster_pain_use //dumptruck_ds
+
+When a monster reaches pain_threshold, it fires all of its pain_targets
+with the current enemy as activator.
+================
+*/
+void() monster_pain_use =
+{
+ if (!self.pain_target)
+ return;
+
+ activator = self.enemy;
+ SUB_UsePain ();
+};
+
+//============================================================================
+
+void() walkmonster_start_go =
+{
+ self.origin_z = self.origin_z + 1; // raise off floor a bit
+//Preach's "check" here
+
+// if(time <= 0.5)
+if(!(self.spawnflags & 8))
+{
+ droptofloor();
+
+ if !(self.spawnflags & I_AM_TURRET) // fixes an incorrect dprint -- dumptruck_ds
+ {
+ if (!walkmove(0,0))
+ {
+ dprint ("\n\n");
+ dprint (self.classname);
+ dprint (" in wall at: ");
+ dprint (vtos(self.origin));
+ dprint ("\n\n");
+ }
+ }
+}
+
+ self.takedamage = DAMAGE_AIM;
+
+ self.ideal_yaw = self.angles * '0 1 0';
+ if (!self.yaw_speed)
+ self.yaw_speed = 20;
+ self.view_ofs = '0 0 25';
+ self.use = monster_use;
+
+ self.flags = self.flags | FL_MONSTER;
+
+ if (self.target != "")
+ {
+ self.goalentity = self.movetarget = find(world, targetname, self.target);
+ self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
+ if (!self.movetarget)
+ {
+ dprint ("Monster can't find target at ");
+ dprint (vtos(self.origin));
+ dprint ("\n");
+ }
+// this used to be an objerror
+ if (self.movetarget.classname == "path_corner")
+ {
+ self.th_walk ();
+ }
+ else
+ {
+ self.pausetime = 99999999;
+ self.th_stand ();
+ }
+ }
+ else
+ {
+ self.pausetime = 99999999;
+ self.th_stand ();
+ }
+
+// spread think times so they don't all happen at same time
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
+// self.nextthink = self.nextthink + random()*0.5;
+ self.nextthink = time + 0.1 + random()*0.5;
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
+ // if ((self.spawnflags & 8) && self.spawn_angry == 1) //dumptruck_ds -- using spawn_angry set to 1 in order to spawn in "angry" monsters
+ // {
+ // monster_use();
+ // }
+ local entity pl; //dumptruck_ds -- this is Shamblernaut's method
+
+ pl = find (world, classname, "player");
+
+ if (self.spawn_angry == 1)
+ {
+ activator = pl;
+ monster_use();
+ }
+};
+
+
+void() walkmonster_start =
+
+ //Preach's tutorial
+{
+
+ if (cvar("nomonsters")) {
+ remove(self);
+ return;
+ }
+
+ if(monster_teleport(walkmonster_start_go))
+ return;
+
+// delay drop to floor to make sure all doors have been spawned
+// spread think times so they don't all happen at same time
+ self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
+// self.nextthink = self.nextthink + random()*0.5;
+ self.nextthink = time + 0.1 + random()*0.5;
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
+ self.think = walkmonster_start_go;
+ total_monsters = total_monsters + 1;
+ /// Trigger enemy after spawn (khreathor)
+
+};
+
+
+
+void() flymonster_start_go =
+{
+ self.takedamage = DAMAGE_AIM;
+
+ self.ideal_yaw = self.angles * '0 1 0';
+ if (!self.yaw_speed)
+ self.yaw_speed = 10;
+ self.view_ofs = '0 0 25';
+ self.use = monster_use;
+
+ self.flags = self.flags | FL_FLY;
+ self.flags = self.flags | FL_MONSTER;
+
+ if (!walkmove(0,0))
+ {
+ dprint ("flymonster in wall at: ");
+ dprint (vtos(self.origin));
+ dprint ("\n");
+ }
+
+ if (self.target != "")
+ {
+ self.goalentity = self.movetarget = find(world, targetname, self.target);
+ if (!self.movetarget)
+ {
+ dprint ("Monster can't find target at ");
+ dprint (vtos(self.origin));
+ dprint ("\n");
+ }
+// this used to be an objerror
+ if (self.movetarget.classname == "path_corner")
+ {
+ self.th_walk ();
+ }
+ else
+ {
+ self.pausetime = 99999999;
+ self.th_stand ();
+ }
+ }
+ else
+ {
+ self.pausetime = 99999999;
+ self.th_stand ();
+ }
+
+ self.nextthink = time + 0.1 + random()*0.5; // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol
+
+// if ((self.spawnflags & 8) && self.spawn_angry == 1) //dumptruck_ds -- using spawn_angry set to 1 in order to spawn in "angry" monsters
+// {
+// monster_use();
+// }
+//dumptruck_ds -- this is Shamblernaut's method
+ local entity pl;
+
+ pl = find (world, classname, "player");
+
+ if (self.spawn_angry == 1)
+ {
+ activator = pl;
+ monster_use();
+ }
+
+};
+
+void() flymonster_start =
+{
+ if (cvar("nomonsters")) {
+ remove(self);
+ return;
+ }
+
+ //Preach's tutorial
+
+ if(monster_teleport(flymonster_start_go))
+ return;
+
+ self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+ self.flags = self.flags | FL_FLY; // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol
+
+// spread think times so they don't all happen at same time
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
+// self.nextthink = self.nextthink + random()*0.5;
+ self.nextthink = time + 0.1 + random()*0.5;
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
+ self.think = flymonster_start_go;
+ total_monsters = total_monsters + 1;
+};
+
+
+void() swimmonster_start_go =
+{
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+
+ self.takedamage = DAMAGE_AIM;
+
+ self.ideal_yaw = self.angles * '0 1 0';
+ if (!self.yaw_speed)
+ self.yaw_speed = 10;
+ self.view_ofs = '0 0 10';
+ self.use = monster_use;
+
+ self.flags = self.flags | FL_SWIM;
+ self.flags = self.flags | FL_MONSTER;
+
+ if (self.target != "")
+ {
+ self.goalentity = self.movetarget = find(world, targetname, self.target);
+ if (!self.movetarget)
+ {
+ dprint ("Monster can't find target at ");
+ dprint (vtos(self.origin));
+ dprint ("\n");
+ }
+// this used to be an objerror
+ self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
+ self.th_walk ();
+ }
+ else
+ {
+ self.pausetime = 99999999;
+ self.th_stand ();
+ }
+
+// spread think times so they don't all happen at same time
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
+// self.nextthink = self.nextthink + random()*0.5;
+ self.nextthink = time + 0.1 + random()*0.5;
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
+// if ((self.spawnflags & 8) && self.spawn_angry == 1) //dumptruck_ds -- using spawn_angry set to 1 in order to spawn in "angry" monsters
+// {
+// monster_use();
+// }
+//dumptruck_ds -- this is Shamblernaut's method
+ local entity pl;
+
+ pl = find (world, classname, "player");
+
+ if (self.spawn_angry == 1)
+ {
+ activator = pl;
+ monster_use();
+ }
+};
+
+void() swimmonster_start =
+{
+ if (cvar("nomonsters")) {
+ remove(self);
+ return;
+ }
+ self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+ self.flags = self.flags | FL_SWIM; // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol
+
+ //Preach's tutorial
+
+ if(monster_teleport(swimmonster_start_go))
+ return;
+
+// spread think times so they don't all happen at same time
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
+// self.nextthink = self.nextthink + random()*0.5;
+ self.nextthink = time + 0.1 + random()*0.5;
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
+ self.think = swimmonster_start_go;
+ total_monsters = total_monsters + 1;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/boss.qc

diff --git a/qc/monsters/boss.qc b/qc/monsters/boss.qc
new file mode 100644
index 0000000..9e88ac1
--- /dev/null
+++ b/qc/monsters/boss.qc
@@ -0,0 +1,415 @@
+/*
+==============================================================================
+
+BOSS-ONE
+
+==============================================================================
+*/
+$cd id1/models/boss1
+$origin 0 0 -15
+$base base
+$skin skin
+$scale 5
+
+$frame rise1 rise2 rise3 rise4 rise5 rise6 rise7 rise8 rise9 rise10
+$frame rise11 rise12 rise13 rise14 rise15 rise16 rise17
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
+$frame walk9 walk10 walk11 walk12 walk13 walk14 walk15
+$frame walk16 walk17 walk18 walk19 walk20 walk21 walk22
+$frame walk23 walk24 walk25 walk26 walk27 walk28 walk29 walk30 walk31
+
+$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
+
+$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
+$frame attack9 attack10 attack11 attack12 attack13 attack14 attack15
+$frame attack16 attack17 attack18 attack19 attack20 attack21 attack22
+$frame attack23
+
+$frame shocka1 shocka2 shocka3 shocka4 shocka5 shocka6 shocka7 shocka8
+$frame shocka9 shocka10
+
+$frame shockb1 shockb2 shockb3 shockb4 shockb5 shockb6
+
+$frame shockc1 shockc2 shockc3 shockc4 shockc5 shockc6 shockc7 shockc8
+$frame shockc9 shockc10
+
+
+void(vector p) boss_missile;
+
+void() boss_face =
+{
+
+// go for another player if multi player
+ if (self.enemy.health <= 0 || random() < 0.02)
+ {
+ self.enemy = find(self.enemy, classname, "player");
+ if (!self.enemy)
+ self.enemy = find(self.enemy, classname, "player");
+ }
+ ai_face();
+};
+
+void() boss_rise1 =[ $rise1, boss_rise2 ] {
+sound_move (self, CHAN_WEAPON, "boss1/out1.wav", 1, ATTN_NORM);
+};
+void() boss_rise2 =[ $rise2, boss_rise3 ] {
+sound_sight (self, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM);
+};
+void() boss_rise3 =[ $rise3, boss_rise4 ] {};
+void() boss_rise4 =[ $rise4, boss_rise5 ] {};
+void() boss_rise5 =[ $rise5, boss_rise6 ] {};
+void() boss_rise6 =[ $rise6, boss_rise7 ] {};
+void() boss_rise7 =[ $rise7, boss_rise8 ] {};
+void() boss_rise8 =[ $rise8, boss_rise9 ] {};
+void() boss_rise9 =[ $rise9, boss_rise10 ] {};
+void() boss_rise10 =[ $rise10, boss_rise11 ] {};
+void() boss_rise11 =[ $rise11, boss_rise12 ] {};
+void() boss_rise12 =[ $rise12, boss_rise13 ] {};
+void() boss_rise13 =[ $rise13, boss_rise14 ] {};
+void() boss_rise14 =[ $rise14, boss_rise15 ] {};
+void() boss_rise15 =[ $rise15, boss_rise16 ] {};
+void() boss_rise16 =[ $rise16, boss_rise17 ] {};
+void() boss_rise17 =[ $rise17, boss_missile1 ] {};
+
+void() boss_idle1 =[ $walk1, boss_idle2 ]
+{
+// look for other players
+};
+void() boss_idle2 =[ $walk2, boss_idle3 ] {boss_face();};
+void() boss_idle3 =[ $walk3, boss_idle4 ] {boss_face();};
+void() boss_idle4 =[ $walk4, boss_idle5 ] {boss_face();};
+void() boss_idle5 =[ $walk5, boss_idle6 ] {boss_face();};
+void() boss_idle6 =[ $walk6, boss_idle7 ] {boss_face();};
+void() boss_idle7 =[ $walk7, boss_idle8 ] {boss_face();};
+void() boss_idle8 =[ $walk8, boss_idle9 ] {boss_face();};
+void() boss_idle9 =[ $walk9, boss_idle10 ] {boss_face();};
+void() boss_idle10 =[ $walk10, boss_idle11 ] {boss_face();};
+void() boss_idle11 =[ $walk11, boss_idle12 ] {boss_face();};
+void() boss_idle12 =[ $walk12, boss_idle13 ] {boss_face();};
+void() boss_idle13 =[ $walk13, boss_idle14 ] {boss_face();};
+void() boss_idle14 =[ $walk14, boss_idle15 ] {boss_face();};
+void() boss_idle15 =[ $walk15, boss_idle16 ] {boss_face();};
+void() boss_idle16 =[ $walk16, boss_idle17 ] {boss_face();};
+void() boss_idle17 =[ $walk17, boss_idle18 ] {boss_face();};
+void() boss_idle18 =[ $walk18, boss_idle19 ] {boss_face();};
+void() boss_idle19 =[ $walk19, boss_idle20 ] {boss_face();};
+void() boss_idle20 =[ $walk20, boss_idle21 ] {boss_face();};
+void() boss_idle21 =[ $walk21, boss_idle22 ] {boss_face();};
+void() boss_idle22 =[ $walk22, boss_idle23 ] {boss_face();};
+void() boss_idle23 =[ $walk23, boss_idle24 ] {boss_face();};
+void() boss_idle24 =[ $walk24, boss_idle25 ] {boss_face();};
+void() boss_idle25 =[ $walk25, boss_idle26 ] {boss_face();};
+void() boss_idle26 =[ $walk26, boss_idle27 ] {boss_face();};
+void() boss_idle27 =[ $walk27, boss_idle28 ] {boss_face();};
+void() boss_idle28 =[ $walk28, boss_idle29 ] {boss_face();};
+void() boss_idle29 =[ $walk29, boss_idle30 ] {boss_face();};
+void() boss_idle30 =[ $walk30, boss_idle31 ] {boss_face();};
+void() boss_idle31 =[ $walk31, boss_idle1 ] {boss_face();};
+
+void() boss_missile1 =[ $attack1, boss_missile2 ] {boss_face();};
+void() boss_missile2 =[ $attack2, boss_missile3 ] {boss_face();};
+void() boss_missile3 =[ $attack3, boss_missile4 ] {boss_face();};
+void() boss_missile4 =[ $attack4, boss_missile5 ] {boss_face();};
+void() boss_missile5 =[ $attack5, boss_missile6 ] {boss_face();};
+void() boss_missile6 =[ $attack6, boss_missile7 ] {boss_face();};
+void() boss_missile7 =[ $attack7, boss_missile8 ] {boss_face();};
+void() boss_missile8 =[ $attack8, boss_missile9 ] {boss_face();};
+void() boss_missile9 =[ $attack9, boss_missile10 ] {boss_missile('100 100 200');};
+void() boss_missile10 =[ $attack10, boss_missile11 ] {boss_face();};
+void() boss_missile11 =[ $attack11, boss_missile12 ] {boss_face();};
+void() boss_missile12 =[ $attack12, boss_missile13 ] {boss_face();};
+void() boss_missile13 =[ $attack13, boss_missile14 ] {boss_face();};
+void() boss_missile14 =[ $attack14, boss_missile15 ] {boss_face();};
+void() boss_missile15 =[ $attack15, boss_missile16 ] {boss_face();};
+void() boss_missile16 =[ $attack16, boss_missile17 ] {boss_face();};
+void() boss_missile17 =[ $attack17, boss_missile18 ] {boss_face();};
+void() boss_missile18 =[ $attack18, boss_missile19 ] {boss_face();};
+void() boss_missile19 =[ $attack19, boss_missile20 ] {boss_face();};
+void() boss_missile20 =[ $attack20, boss_missile21 ] {boss_missile('100 -100 200');};
+void() boss_missile21 =[ $attack21, boss_missile22 ] {boss_face();};
+void() boss_missile22 =[ $attack22, boss_missile23 ] {boss_face();};
+void() boss_missile23 =[ $attack23, boss_missile1 ] {boss_face();};
+
+void() boss_shocka1 =[ $shocka1, boss_shocka2 ] {};
+void() boss_shocka2 =[ $shocka2, boss_shocka3 ] {};
+void() boss_shocka3 =[ $shocka3, boss_shocka4 ] {};
+void() boss_shocka4 =[ $shocka4, boss_shocka5 ] {};
+void() boss_shocka5 =[ $shocka5, boss_shocka6 ] {};
+void() boss_shocka6 =[ $shocka6, boss_shocka7 ] {};
+void() boss_shocka7 =[ $shocka7, boss_shocka8 ] {};
+void() boss_shocka8 =[ $shocka8, boss_shocka9 ] {};
+void() boss_shocka9 =[ $shocka9, boss_shocka10 ] {};
+void() boss_shocka10 =[ $shocka10, boss_missile1 ] {};
+
+void() boss_shockb1 =[ $shockb1, boss_shockb2 ] {};
+void() boss_shockb2 =[ $shockb2, boss_shockb3 ] {};
+void() boss_shockb3 =[ $shockb3, boss_shockb4 ] {};
+void() boss_shockb4 =[ $shockb4, boss_shockb5 ] {};
+void() boss_shockb5 =[ $shockb5, boss_shockb6 ] {};
+void() boss_shockb6 =[ $shockb6, boss_shockb7 ] {};
+void() boss_shockb7 =[ $shockb1, boss_shockb8 ] {};
+void() boss_shockb8 =[ $shockb2, boss_shockb9 ] {};
+void() boss_shockb9 =[ $shockb3, boss_shockb10 ] {};
+void() boss_shockb10 =[ $shockb4, boss_missile1 ] {};
+
+void() boss_shockc1 =[ $shockc1, boss_shockc2 ] {};
+void() boss_shockc2 =[ $shockc2, boss_shockc3 ] {};
+void() boss_shockc3 =[ $shockc3, boss_shockc4 ] {};
+void() boss_shockc4 =[ $shockc4, boss_shockc5 ] {};
+void() boss_shockc5 =[ $shockc5, boss_shockc6 ] {};
+void() boss_shockc6 =[ $shockc6, boss_shockc7 ] {};
+void() boss_shockc7 =[ $shockc7, boss_shockc8 ] {};
+void() boss_shockc8 =[ $shockc8, boss_shockc9 ] {};
+void() boss_shockc9 =[ $shockc9, boss_shockc10 ] {};
+void() boss_shockc10 =[ $shockc10, boss_death1 ] {};
+
+void() boss_death1 = [$death1, boss_death2] {
+sound_death (self, CHAN_VOICE, "boss1/death.wav", 1, ATTN_NORM);
+};
+void() boss_death2 = [$death2, boss_death3] {};
+void() boss_death3 = [$death3, boss_death4] {};
+void() boss_death4 = [$death4, boss_death5] {};
+void() boss_death5 = [$death5, boss_death6] {};
+void() boss_death6 = [$death6, boss_death7] {};
+void() boss_death7 = [$death7, boss_death8] {};
+void() boss_death8 = [$death8, boss_death9] {};
+void() boss_death9 = [$death9, boss_death10]
+{
+ sound_move (self, CHAN_BODY, "boss1/out1.wav", 1, ATTN_NORM);
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+};
+
+void() boss_death10 = [$death9, boss_death10]
+{
+ killed_monsters = killed_monsters + 1;
+ WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // FIXME: reliable broadcast
+ SUB_UseTargets ();
+ remove (self);
+};
+
+void(vector p) boss_missile =
+{
+ local vector offang;
+ local vector org, vec, d;
+ local float t;
+
+ offang = vectoangles (self.enemy.origin - self.origin);
+ makevectors (offang);
+
+ org = self.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
+
+// lead the player on hard mode
+ if (skill > 1)
+ {
+ t = vlen(self.enemy.origin - org) / 300;
+ vec = self.enemy.velocity;
+ vec_z = 0;
+ d = self.enemy.origin + t * vec;
+ }
+ else
+ {
+ d = self.enemy.origin;
+ }
+
+ vec = normalize (d - org);
+
+ launch_spike2 (org, vec, 300);
+ // setmodel (newmis, "progs/lavaball.mdl");
+ if (self.mdl_proj != "") // dumptruck_ds custom_mdls
+ {
+ setmodel (newmis, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/lavaball.mdl");
+ }
+
+ if (!newmis.skin_proj) // dumptruck_ds
+ {
+ newmis.skin = self.skin_proj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+
+ newmis.avelocity = '200 100 300';
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ newmis.touch = T_MissileTouch; // rocket explosion
+ sound_attack (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM);
+
+// check for dead enemy
+ if (self.enemy.health <= 0)
+ boss_idle1 ();
+};
+
+
+void() boss_awake =
+{
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+ self.takedamage = DAMAGE_NO;
+
+ body_model ("progs/boss.mdl");
+ // setmodel (self, "progs/boss.mdl"); //custom_mdl -- dumptruck_ds
+ setsize (self, '-128 -128 -24', '128 128 256');
+
+ if (skill == 0)
+ self.health = 1;
+ else
+ self.health = 3;
+
+ self.enemy = activator;
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ self.yaw_speed = 20;
+ boss_rise1 ();
+};
+
+
+/*QUAKED monster_boss (1 0 0) (-128 -128 -24) (128 128 256)
+*/
+void() monster_boss =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ objerror("Incompatible spawnflag: TURRET_MODE\n");
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ // precache_model ("progs/boss.mdl");
+ precache_body_model ("progs/boss.mdl");
+ precache_head_model ("progs/h_boss.mdl");
+
+ precache_model ("progs/lavaball.mdl");
+
+ precache_sound ("weapons/rocket1i.wav");
+ precache_sound_move ("boss1/out1.wav");
+ precache_sound_sight ("boss1/sight1.wav");
+ precache_sound ("misc/power.wav");
+ precache_sound_attack ("boss1/throw.wav");
+ precache_sound_pain ("boss1/pain.wav");
+ precache_sound_death ("boss1/death.wav");
+
+ total_monsters = total_monsters + 1;
+
+ self.flags = FL_MONSTER;
+ self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+ self.use = boss_awake;
+};
+
+//===========================================================================
+
+entity le1, le2;
+float lightning_end;
+
+void() lightning_fire =
+{
+ local vector p1, p2;
+
+ if (time >= lightning_end)
+ { // done here, put the terminals back up
+ self = le1;
+ door_go_down ();
+ self = le2;
+ door_go_down ();
+ return;
+ }
+
+ p1 = (le1.mins + le1.maxs) * 0.5;
+ p1_z = le1.absmin_z - 16;
+
+ p2 = (le2.mins + le2.maxs) * 0.5;
+ p2_z = le2.absmin_z - 16;
+
+ // compensate for length of bolt
+ p2 = p2 - normalize(p2-p1)*100;
+
+ self.nextthink = time + 0.1;
+ self.think = lightning_fire;
+
+ WriteByte (MSG_ALL, SVC_TEMPENTITY);
+ WriteByte (MSG_ALL, TE_LIGHTNING3);
+ WriteEntity (MSG_ALL, world);
+ WriteCoord (MSG_ALL, p1_x);
+ WriteCoord (MSG_ALL, p1_y);
+ WriteCoord (MSG_ALL, p1_z);
+ WriteCoord (MSG_ALL, p2_x);
+ WriteCoord (MSG_ALL, p2_y);
+ WriteCoord (MSG_ALL, p2_z);
+};
+
+void() lightning_use =
+{
+ if (lightning_end >= time + 1)
+ return;
+
+ le1 = find( world, target, "lightning");
+ le2 = find( le1, target, "lightning");
+ if (!le1 || !le2)
+ {
+ dprint ("missing lightning targets\n");
+ return;
+ }
+
+ if (
+ (le1.state != STATE_TOP && le1.state != STATE_BOTTOM)
+ || (le2.state != STATE_TOP && le2.state != STATE_BOTTOM)
+ || (le1.state != le2.state) )
+ {
+// dprint ("not aligned\n");
+ return;
+ }
+
+// don't let the electrodes go back up until the bolt is done
+ le1.nextthink = -1;
+ le2.nextthink = -1;
+ lightning_end = time + 1;
+
+ sound (self, CHAN_VOICE, "misc/power.wav", 1, ATTN_NORM);
+ lightning_fire ();
+
+// advance the boss pain if down
+ self = find (world, classname, "monster_boss");
+ if (!self)
+ return;
+ self.enemy = activator;
+ if (le1.state == STATE_TOP && self.health > 0)
+ {
+ sound_pain (self, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM);
+ self.health = self.health - 1;
+ if (self.health >= 2)
+ boss_shocka1();
+ else if (self.health == 1)
+ boss_shockb1();
+ else if (self.health == 0)
+ boss_shockc1();
+ }
+};
+
+
+/*QUAKED event_lightning (0 1 1) (-16 -16 -16) (16 16 16) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Just for boss level.
+*/
+void() event_lightning =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.use = lightning_use;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/boss2.qc

diff --git a/qc/monsters/boss2.qc b/qc/monsters/boss2.qc
new file mode 100644
index 0000000..295e03b
--- /dev/null
+++ b/qc/monsters/boss2.qc
@@ -0,0 +1,491 @@
+/*
+==============================================================================
+
+BOSS-ONE
+
+==============================================================================
+*/
+$cd id1/models/boss1
+$origin 0 0 -15
+$base base
+$skin skin
+$scale 5
+
+$frame rise1 rise2 rise3 rise4 rise5 rise6 rise7 rise8 rise9 rise10
+$frame rise11 rise12 rise13 rise14 rise15 rise16 rise17
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
+$frame walk9 walk10 walk11 walk12 walk13 walk14 walk15
+$frame walk16 walk17 walk18 walk19 walk20 walk21 walk22
+$frame walk23 walk24 walk25 walk26 walk27 walk28 walk29 walk30 walk31
+
+$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
+
+$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
+$frame attack9 attack10 attack11 attack12 attack13 attack14 attack15
+$frame attack16 attack17 attack18 attack19 attack20 attack21 attack22
+$frame attack23
+
+$frame shocka1 shocka2 shocka3 shocka4 shocka5 shocka6 shocka7 shocka8
+$frame shocka9 shocka10
+
+$frame shockb1 shockb2 shockb3 shockb4 shockb5 shockb6
+
+$frame shockc1 shockc2 shockc3 shockc4 shockc5 shockc6 shockc7 shockc8
+$frame shockc9 shockc10
+
+float NO_LAVASPLASH = 2; //supress lava splash effect when raising, lowering or gibbing - dumptruck_ds
+
+void(vector p) boss2_missile;
+
+void() boss2_face =
+{
+// go for another player if multi player
+ if (self.enemy.health <= 0 || random() < 0.02)
+ {
+ self.enemy = find(self.enemy, classname, "player");
+ if (!self.enemy)
+ self.enemy = find(self.enemy, classname, "player");
+ }
+ ai_face();
+};
+
+void() boss2_rise1 =[ $rise1, boss2_rise2 ] {
+ sound_move (self, CHAN_AUTO, "boss1/out1.wav", 1, ATTN_NORM);
+};
+void() boss2_rise2 =[ $rise2, boss2_rise3 ] {
+ sound_sight (self, CHAN_AUTO, "boss1/sight1.wav", 1, ATTN_NORM);
+};
+void() boss2_rise3 =[ $rise3, boss2_rise4 ] {};
+void() boss2_rise4 =[ $rise4, boss2_rise5 ] {};
+void() boss2_rise5 =[ $rise5, boss2_rise6 ] {};
+void() boss2_rise6 =[ $rise6, boss2_rise7 ] {};
+void() boss2_rise7 =[ $rise7, boss2_rise8 ] {};
+void() boss2_rise8 =[ $rise8, boss2_rise9 ] {};
+void() boss2_rise9 =[ $rise9, boss2_rise10 ] {};
+void() boss2_rise10 =[ $rise10, boss2_rise11 ] {};
+void() boss2_rise11 =[ $rise11, boss2_rise12 ] {};
+void() boss2_rise12 =[ $rise12, boss2_rise13 ] {};
+void() boss2_rise13 =[ $rise13, boss2_rise14 ] {};
+void() boss2_rise14 =[ $rise14, boss2_rise15 ] {};
+void() boss2_rise15 =[ $rise15, boss2_rise16 ] {};
+void() boss2_rise16 =[ $rise16, boss2_rise17 ] {};
+void() boss2_rise17 =[ $rise17, boss2_missile1 ] {};
+
+void() boss2_idle1 =[ $walk1, boss2_idle2 ]
+{
+// look for other players
+};
+void() boss2_idle2 =[ $walk2, boss2_idle3 ] {boss2_face();};
+void() boss2_idle3 =[ $walk3, boss2_idle4 ] {boss2_face();};
+void() boss2_idle4 =[ $walk4, boss2_idle5 ] {boss2_face();};
+void() boss2_idle5 =[ $walk5, boss2_idle6 ] {boss2_face();};
+void() boss2_idle6 =[ $walk6, boss2_idle7 ] {boss2_face();};
+void() boss2_idle7 =[ $walk7, boss2_idle8 ] {boss2_face();};
+void() boss2_idle8 =[ $walk8, boss2_idle9 ] {boss2_face();};
+void() boss2_idle9 =[ $walk9, boss2_idle10 ] {boss2_face();};
+void() boss2_idle10 =[ $walk10, boss2_idle11 ] {boss2_face();};
+void() boss2_idle11 =[ $walk11, boss2_idle12 ] {boss2_face();};
+void() boss2_idle12 =[ $walk12, boss2_idle13 ] {boss2_face();};
+void() boss2_idle13 =[ $walk13, boss2_idle14 ] {boss2_face();};
+void() boss2_idle14 =[ $walk14, boss2_idle15 ] {boss2_face();};
+void() boss2_idle15 =[ $walk15, boss2_idle16 ] {boss2_face();};
+void() boss2_idle16 =[ $walk16, boss2_idle17 ] {boss2_face();};
+void() boss2_idle17 =[ $walk17, boss2_idle18 ] {boss2_face();};
+void() boss2_idle18 =[ $walk18, boss2_idle19 ] {boss2_face();};
+void() boss2_idle19 =[ $walk19, boss2_idle20 ] {boss2_face();};
+void() boss2_idle20 =[ $walk20, boss2_idle21 ] {boss2_face();};
+void() boss2_idle21 =[ $walk21, boss2_idle22 ] {boss2_face();};
+void() boss2_idle22 =[ $walk22, boss2_idle23 ] {boss2_face();};
+void() boss2_idle23 =[ $walk23, boss2_idle24 ] {boss2_face();};
+void() boss2_idle24 =[ $walk24, boss2_idle25 ] {boss2_face();};
+void() boss2_idle25 =[ $walk25, boss2_idle26 ] {boss2_face();};
+void() boss2_idle26 =[ $walk26, boss2_idle27 ] {boss2_face();};
+void() boss2_idle27 =[ $walk27, boss2_idle28 ] {boss2_face();};
+void() boss2_idle28 =[ $walk28, boss2_idle29 ] {boss2_face();};
+void() boss2_idle29 =[ $walk29, boss2_idle30 ] {boss2_face();};
+void() boss2_idle30 =[ $walk30, boss2_idle31 ] {boss2_face();};
+void() boss2_idle31 =[ $walk31, boss2_idle1 ] {boss2_face();};
+
+void() boss2_missile1 =[ $attack1, boss2_missile2 ] {boss2_face();};
+void() boss2_missile2 =[ $attack2, boss2_missile3 ] {boss2_face();};
+void() boss2_missile3 =[ $attack3, boss2_missile4 ] {boss2_face();};
+void() boss2_missile4 =[ $attack4, boss2_missile5 ] {boss2_face();};
+void() boss2_missile5 =[ $attack5, boss2_missile6 ] {boss2_face();};
+void() boss2_missile6 =[ $attack6, boss2_missile7 ] {boss2_face();};
+void() boss2_missile7 =[ $attack7, boss2_missile8 ] {boss2_face();};
+void() boss2_missile8 =[ $attack8, boss2_missile9 ] {boss2_face();};
+void() boss2_missile9 =[ $attack9, boss2_missile10 ] {boss2_missile('100 100 200');};
+void() boss2_missile10 =[ $attack10, boss2_missile11 ] {boss2_face();};
+void() boss2_missile11 =[ $attack11, boss2_missile12 ] {boss2_face();};
+void() boss2_missile12 =[ $attack12, boss2_missile13 ] {boss2_face();};
+void() boss2_missile13 =[ $attack13, boss2_missile14 ] {boss2_face();};
+void() boss2_missile14 =[ $attack14, boss2_missile15 ] {boss2_face();};
+void() boss2_missile15 =[ $attack15, boss2_missile16 ] {boss2_face();};
+void() boss2_missile16 =[ $attack16, boss2_missile17 ] {boss2_face();};
+void() boss2_missile17 =[ $attack17, boss2_missile18 ] {boss2_face();};
+void() boss2_missile18 =[ $attack18, boss2_missile19 ] {boss2_face();};
+void() boss2_missile19 =[ $attack19, boss2_missile20 ] {boss2_face();};
+void() boss2_missile20 =[ $attack20, boss2_missile21 ] {boss2_missile('100 -100 200');};
+void() boss2_missile21 =[ $attack21, boss2_missile22 ] {boss2_face();};
+void() boss2_missile22 =[ $attack22, boss2_missile23 ] {boss2_face();};
+void() boss2_missile23 =[ $attack23, boss2_missile1 ] {boss2_face();};
+
+void() boss2_shocka1 =[ $shocka1, boss2_shocka2 ] {};
+void() boss2_shocka2 =[ $shocka2, boss2_shocka3 ] {};
+void() boss2_shocka3 =[ $shocka3, boss2_shocka4 ] {};
+void() boss2_shocka4 =[ $shocka4, boss2_shocka5 ] {};
+void() boss2_shocka5 =[ $shocka5, boss2_shocka6 ] {};
+void() boss2_shocka6 =[ $shocka6, boss2_shocka7 ] {};
+void() boss2_shocka7 =[ $shocka7, boss2_shocka8 ] {};
+void() boss2_shocka8 =[ $shocka8, boss2_shocka9 ] {};
+void() boss2_shocka9 =[ $shocka9, boss2_shocka10 ] {};
+void() boss2_shocka10 =[ $shocka10, boss2_missile1 ] {};
+
+void() boss2_shockb1 =[ $shockb1, boss2_shockb2 ] {};
+void() boss2_shockb2 =[ $shockb2, boss2_shockb3 ] {};
+void() boss2_shockb3 =[ $shockb3, boss2_shockb4 ] {};
+void() boss2_shockb4 =[ $shockb4, boss2_shockb5 ] {};
+void() boss2_shockb5 =[ $shockb5, boss2_shockb6 ] {};
+void() boss2_shockb6 =[ $shockb6, boss2_shockb7 ] {};
+void() boss2_shockb7 =[ $shockb1, boss2_shockb8 ] {};
+void() boss2_shockb8 =[ $shockb2, boss2_shockb9 ] {};
+void() boss2_shockb9 =[ $shockb3, boss2_shockb10 ] {};
+void() boss2_shockb10 =[ $shockb4, boss2_missile1 ] {};
+
+void() boss2_shockc1 =[ $shockc1, boss2_shockc2 ] {};
+void() boss2_shockc2 =[ $shockc2, boss2_shockc3 ] {};
+void() boss2_shockc3 =[ $shockc3, boss2_shockc4 ] {};
+void() boss2_shockc4 =[ $shockc4, boss2_shockc5 ] {};
+void() boss2_shockc5 =[ $shockc5, boss2_shockc6 ] {};
+void() boss2_shockc6 =[ $shockc6, boss2_shockc7 ] {};
+void() boss2_shockc7 =[ $shockc7, boss2_shockc8 ] {};
+void() boss2_shockc8 =[ $shockc8, boss2_shockc9 ] {};
+void() boss2_shockc9 =[ $shockc9, boss2_shockc10 ] {};
+void() boss2_shockc10 =[ $shockc10, boss2_death1 ] {};
+
+void() boss2_pain1 =[ $shocka1, boss2_pain2 ] {};
+void() boss2_pain2 =[ $shocka2, boss2_pain3 ] {};
+void() boss2_pain3 =[ $shocka3, boss2_pain4 ] {};
+void() boss2_pain4 =[ $shocka4, boss2_pain5 ] {
+ sound_pain (self, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM); // pain noise
+};
+void() boss2_pain5 =[ $shocka5, boss2_pain6 ] {};
+void() boss2_pain6 =[ $shocka6, bos2s_pain7 ] {};
+void() bos2s_pain7 =[ $shocka7, boss2_pain8 ] {};
+void() boss2_pain8 =[ $shocka8, boss2_pain9 ] {};
+void() boss2_pain9 =[ $shocka9, boss2_missile1 ] {}; // auto shoot a lavaball
+
+
+void() GibBoss2 =
+{
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ // throw tons of meat chunks
+
+ local vector boss;
+ local float x, y, z;
+ local float r;
+ // local entity n;
+
+ boss = self.origin;
+ z = 16;
+ while (z <= 144)
+ {
+ x = -64;
+ while (x <= 64)
+ {
+ y = -64;
+ while (y <= 64)
+ {
+ self.origin_x = boss_x + x;
+ self.origin_y = boss_y + y;
+ self.origin_z = boss_z + z;
+
+ r = random();
+ if (r < 0.3)
+ // ThrowGib ("progs/gib1.mdl", -120);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, -120);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", -120);
+ }
+ else if (r < 0.5)
+ // ThrowGib ("progs/gib2.mdl", -120);
+ if (self.mdl_gib2 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib2, -120);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", -120);
+ }
+ else if (r < 0.7)
+ ThrowGib ("progs/lavaball.mdl", -120);
+ else
+ // ThrowGib ("progs/gib3.mdl", -120);
+ if (self.mdl_gib3 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib3, -120);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", -120);
+ }
+ y = y + 32;
+ }
+ x = x + 32;
+ }
+ z = z + 96;
+ }
+
+ local entity head;
+
+ head = spawn();
+ head.origin = self.origin + '0 0 128';
+ head.velocity_z = 600; + (random() * 200);
+ head.velocity_x = -300 + (random() * 600);
+ head.velocity_y = -200 + (random() * 600);
+ head.avelocity_x = random()*120;
+ head.avelocity_y = random()*120;
+ head.avelocity_z = random()*120;
+ head.flags = self.flags - (self.flags & FL_ONGROUND);
+ head.solid = SOLID_NOT;
+ head.movetype = MOVETYPE_BOUNCE;
+ head.takedamage = DAMAGE_NO;
+ if (self.mdl_head != "") // dumptruck_ds custom_mdls
+ {
+ setmodel (head, self.mdl_head);
+ }
+ else
+ {
+ setmodel (head, "progs/h_boss.mdl");
+ }
+
+ if (!self.skin_head) // dumptruck_ds
+ {
+ head.skin = self.skin_proj;
+ }
+ else
+ {
+ head.skin = 0;
+ }
+ setsize (head, '-67 -60 -6', '62 52 88');
+ // setsize (head, '-16 -16 0', '16 16 56');
+ head.touch = SUB_Null;
+ head.think = SUB_Remove;
+ head.nextthink = time + 120;
+ if !(self.spawnflags & NO_LAVASPLASH)
+ {
+ // killed_monsters = killed_monsters + 1; //already done in combat.qc since this is now FL_MONSTER
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
+ // WriteByte (MSG_ALL, SVC_KILLEDMONSTER); //already done in combat.qc since this is now FL_MONSTER -- dumptruck_ds
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+ }
+ remove (self);
+};
+
+void() boss2_die =
+{
+ if (self.health < -50) // if health under -15
+ {
+ GibBoss2 ();
+ return;
+ }
+ else // otherwise
+ {
+ boss2_death1 (); // normal death
+ return;
+ }
+};
+
+void() boss2_death1 = [$death1, boss2_death2] {
+ sound_death (self, CHAN_VOICE, "boss1/death.wav", 1, ATTN_NORM);
+};
+void() boss2_death2 = [$death2, boss2_death3] {};
+void() boss2_death3 = [$death3, boss2_death4] {};
+void() boss2_death4 = [$death4, boss2_death5] {};
+void() boss2_death5 = [$death5, boss2_death6] {};
+void() boss2_death6 = [$death6, boss2_death7] {};
+void() boss2_death7 = [$death7, boss2_death8] {};
+void() boss2_death8 = [$death8, boss2_death9] {};
+void() boss2_death9 = [$death9, boss2_death10]
+{
+ sound_move (self, CHAN_BODY, "boss1/out1.wav", 1, ATTN_NORM);
+ if !(self.spawnflags & NO_LAVASPLASH)
+ {
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+ }
+};
+
+void(entity attacker, float damage) boss2_pain_go =
+{
+ if (self.pain_finished > time)
+ return;
+
+ boss2_pain1();
+ self.pain_finished = time + 4;
+};
+
+void() boss2_death10 = [$death9, boss2_death10]
+{
+// unlike the code for the original monster_boss, this function doesn't
+// need to increment killed_monsters or call SUB_UseTargets(); this
+// entity gets killed by regular damage and has FL_MONSTER, so the
+// Killed() function (in combat.qc) will already have taken care of
+// those things -- iw
+
+ remove (self);
+};
+
+void(vector p) boss2_missile =
+{
+ local vector offang;
+ local vector org, vec, d;
+ local float t;
+
+ offang = vectoangles (self.enemy.origin - self.origin);
+ makevectors (offang);
+
+ org = self.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
+
+// lead the player on hard mode
+ if (skill > 1)
+ {
+ t = vlen(self.enemy.origin - org) / 300;
+ vec = self.enemy.velocity;
+ vec_z = 0;
+ d = self.enemy.origin + t * vec;
+ }
+ else
+ {
+ d = self.enemy.origin;
+ }
+
+ vec = normalize (d - org);
+
+ launch_spike2 (org, vec, 300);
+ // setmodel (newmis, "progs/lavaball.mdl");
+ if (self.mdl_proj != "") // dumptruck_ds custom_mdls
+ {
+ setmodel (newmis, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/lavaball.mdl");
+ }
+
+ if (!newmis.skin_proj) // dumptruck_ds
+ {
+ newmis.skin = self.skin_proj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+
+ newmis.avelocity = '200 100 300';
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ newmis.touch = T_MissileTouch; // rocket explosion
+ sound_attack (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM);
+
+// check for dead enemy
+ if (self.enemy.health <= 0)
+ boss2_idle1 ();
+};
+
+
+void() boss2_awake =
+{
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+ self.takedamage = DAMAGE_AIM;
+
+ body_model ("progs/boss.mdl");
+ // setmodel (self, "progs/boss.mdl");
+ setsize (self, '-128 -128 -24', '128 128 256');
+
+ if (!self.health)
+ {
+ if (skill == 0)
+ self.health = 1000;
+ else
+ self.health = 3000;
+ }
+
+// note that self.th_run has to be set in order to avoid a "NULL
+// function" Host_Error in the case where T_Damage() calls
+// FoundTarget(), which calls HuntTarget(), which uses self.th_run as
+// the next self.think -- iw
+ self.th_run = boss2_missile1;
+
+ self.th_pain = boss2_pain_go;
+ self.th_die = boss2_die;
+
+// give the boss a couple of seconds to finish rising before allowing it
+// to go into its pain animation -- iw
+ self.pain_finished = time + 2;
+
+ self.enemy = activator;
+
+ if !(self.spawnflags & NO_LAVASPLASH)
+ {
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+ }
+
+ self.yaw_speed = 20;
+ boss2_rise1 ();
+};
+
+
+/*QUAKED monster_boss2 (1 0 0) (-128 -128 -24) (128 128 256)
+*/
+void() monster_boss2 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ objerror("Incompatible spawnflag: TURRET_MODE\n");
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ } //custom sounds and models -- dumptruck_ds
+ precache_body_model ("progs/boss.mdl");
+ precache_head_model ("progs/h_boss.mdl");
+ precache_model ("progs/lavaball.mdl");
+ // precache_model ("progs/boss.mdl");
+ precache_model ("progs/h_boss.mdl");
+
+ precache_sound ("weapons/rocket1i.wav");
+ precache_sound_move ("boss1/out1.wav");
+ precache_sound_sight ("boss1/sight1.wav");
+ precache_sound ("misc/power.wav");
+ precache_sound_attack ("boss1/throw.wav");
+ precache_sound_pain ("boss1/pain.wav");
+ precache_sound_death ("boss1/death.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ total_monsters = total_monsters + 1;
+ self.flags = FL_MONSTER;
+ self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+ self.use = boss2_awake;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/demon.qc

diff --git a/qc/monsters/demon.qc b/qc/monsters/demon.qc
new file mode 100644
index 0000000..4c13b4a
--- /dev/null
+++ b/qc/monsters/demon.qc
@@ -0,0 +1,502 @@
+/*
+==============================================================================
+
+DEMON
+
+==============================================================================
+*/
+
+$cd id1/models/demon3
+$scale 0.8
+$origin 0 0 24
+$base base
+$skin base
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
+$frame stand10 stand11 stand12 stand13
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
+
+$frame run1 run2 run3 run4 run5 run6
+
+$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9 leap10
+$frame leap11 leap12
+
+$frame pain1 pain2 pain3 pain4 pain5 pain6
+
+$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
+
+$frame attacka1 attacka2 attacka3 attacka4 attacka5 attacka6 attacka7 attacka8
+$frame attacka9 attacka10 attacka11 attacka12 attacka13 attacka14 attacka15
+
+//============================================================================
+
+void() Demon_JumpTouch;
+
+void() demon1_stand1 =[ $stand1, demon1_stand2 ] {ai_stand();};
+void() demon1_stand2 =[ $stand2, demon1_stand3 ] {ai_stand();};
+void() demon1_stand3 =[ $stand3, demon1_stand4 ] {ai_stand();};
+void() demon1_stand4 =[ $stand4, demon1_stand5 ] {ai_stand();};
+void() demon1_stand5 =[ $stand5, demon1_stand6 ] {ai_stand();};
+void() demon1_stand6 =[ $stand6, demon1_stand7 ] {ai_stand();};
+void() demon1_stand7 =[ $stand7, demon1_stand8 ] {ai_stand();};
+void() demon1_stand8 =[ $stand8, demon1_stand9 ] {ai_stand();};
+void() demon1_stand9 =[ $stand9, demon1_stand10 ] {ai_stand();};
+void() demon1_stand10 =[ $stand10, demon1_stand11 ] {ai_stand();};
+void() demon1_stand11 =[ $stand11, demon1_stand12 ] {ai_stand();};
+void() demon1_stand12 =[ $stand12, demon1_stand13 ] {ai_stand();};
+void() demon1_stand13 =[ $stand13, demon1_stand1 ] {ai_stand();};
+
+void() demon1_walk1 =[ $walk1, demon1_walk2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE);
+ai_walk(8);
+};
+void() demon1_walk2 =[ $walk2, demon1_walk3 ] {ai_walk(6);};
+void() demon1_walk3 =[ $walk3, demon1_walk4 ] {ai_walk(6);};
+void() demon1_walk4 =[ $walk4, demon1_walk5 ] {ai_walk(7);};
+void() demon1_walk5 =[ $walk5, demon1_walk6 ] {ai_walk(4);};
+void() demon1_walk6 =[ $walk6, demon1_walk7 ] {ai_walk(6);};
+void() demon1_walk7 =[ $walk7, demon1_walk8 ] {ai_walk(10);};
+void() demon1_walk8 =[ $walk8, demon1_walk1 ] {ai_walk(10);};
+
+void() demon1_run1 =[ $run1, demon1_run2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE);
+ai_run(20);};
+void() demon1_run2 =[ $run2, demon1_run3 ] {ai_run(15);};
+void() demon1_run3 =[ $run3, demon1_run4 ] {ai_run(36);};
+void() demon1_run4 =[ $run4, demon1_run5 ] {ai_run(20);};
+void() demon1_run5 =[ $run5, demon1_run6 ] {ai_run(15);};
+void() demon1_run6 =[ $run6, demon1_run1 ] {ai_run(36);};
+
+void() demon1_jump1 =[ $leap1, demon1_jump2 ] {ai_face();};
+void() demon1_jump2 =[ $leap2, demon1_jump3 ] {ai_face();};
+void() demon1_jump3 =[ $leap3, demon1_jump4 ] {ai_face();};
+void() demon1_jump4 =[ $leap4, demon1_jump5 ]
+{
+ ai_face();
+ self.worldtype = 0; //fix for instakill bug -- dumptruck_ds
+ self.touch = Demon_JumpTouch;
+ makevectors (self.angles);
+ self.origin_z = self.origin_z + 1;
+ self.velocity = v_forward * 600 + '0 0 250';
+ if (self.flags & FL_ONGROUND)
+ self.flags = self.flags - FL_ONGROUND;
+};
+void() demon1_jump5 =[ $leap5, demon1_jump6 ] {};
+void() demon1_jump6 =[ $leap6, demon1_jump7 ] {};
+void() demon1_jump7 =[ $leap7, demon1_jump8 ] {};
+void() demon1_jump8 =[ $leap8, demon1_jump9 ] {};
+void() demon1_jump9 =[ $leap9, demon1_jump10 ] {};
+void() demon1_jump10 =[ $leap10, demon1_jump1 ] {
+self.nextthink = time + 3;
+// if three seconds pass, assume demon is stuck and jump again
+};
+
+void() demon1_jump11 =[ $leap11, demon1_jump12 ] {};
+void() demon1_jump12 =[ $leap12, demon1_run1 ] {};
+
+
+void() demon1_atta1 =[ $attacka1, demon1_atta2 ] {ai_charge(4);};
+void() demon1_atta2 =[ $attacka2, demon1_atta3 ] {ai_charge(0);};
+void() demon1_atta3 =[ $attacka3, demon1_atta4 ] {ai_charge(0);};
+void() demon1_atta4 =[ $attacka4, demon1_atta5 ] {ai_charge(1);};
+void() demon1_atta5 =[ $attacka5, demon1_atta6 ] {ai_charge(2); Demon_Melee(200);};
+void() demon1_atta6 =[ $attacka6, demon1_atta7 ] {ai_charge(1);};
+void() demon1_atta7 =[ $attacka7, demon1_atta8 ] {ai_charge(6);};
+void() demon1_atta8 =[ $attacka8, demon1_atta9 ] {ai_charge(8);};
+void() demon1_atta9 =[ $attacka9, demon1_atta10] {ai_charge(4);};
+void() demon1_atta10 =[ $attacka10, demon1_atta11] {ai_charge(2);};
+void() demon1_atta11 =[ $attacka11, demon1_atta12] {Demon_Melee(-200);};
+void() demon1_atta12 =[ $attacka12, demon1_atta13] {ai_charge(5);};
+void() demon1_atta13 =[ $attacka13, demon1_atta14] {ai_charge(8);};
+void() demon1_atta14 =[ $attacka14, demon1_atta15] {ai_charge(4);};
+void() demon1_atta15 =[ $attacka15, demon1_run1] {ai_charge(4);};
+
+void() demon1_pain1 =[ $pain1, demon1_pain2 ] {};
+void() demon1_pain2 =[ $pain2, demon1_pain3 ] {};
+void() demon1_pain3 =[ $pain3, demon1_pain4 ] {};
+void() demon1_pain4 =[ $pain4, demon1_pain5 ] {};
+void() demon1_pain5 =[ $pain5, demon1_pain6 ] {};
+void() demon1_pain6 =[ $pain6, demon1_run1 ] {};
+
+void(entity attacker, float damage) demon1_pain =
+{
+ if (self.touch == Demon_JumpTouch)
+ return;
+
+ if (self.pain_finished > time)
+ return;
+
+ self.pain_finished = time + 1;
+ sound_pain (self, CHAN_VOICE, "demon/dpain1.wav", 1, ATTN_NORM);
+
+ if (random()*200 > damage)
+ return; // didn't flinch
+
+ demon1_pain1 ();
+};
+
+void() demon1_die1 =[ $death1, demon1_die2 ] {
+sound_death (self, CHAN_VOICE, "demon/ddeath.wav", 1, ATTN_NORM);};
+void() demon1_die2 =[ $death2, demon1_die3 ] {};
+void() demon1_die3 =[ $death3, demon1_die4 ] {};
+void() demon1_die4 =[ $death4, demon1_die5 ] {};
+void() demon1_die5 =[ $death5, demon1_die6 ] {};
+void() demon1_die6 =[ $death6, demon1_die7 ]
+{self.solid = SOLID_NOT;};
+void() demon1_die7 =[ $death7, demon1_die8 ] {};
+void() demon1_die8 =[ $death8, demon1_die9 ] {};
+void() demon1_die9 =[ $death9, demon1_die9 ] {};
+
+void() demon_die =
+{
+// check for gib
+ if (self.health < -80)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "")
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_demon.mdl", self.health);
+ }
+ // ThrowHead ("progs/h_demon.mdl", self.health);
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+
+// regular death
+ DropStuff();
+ demon1_die1 ();
+};
+
+
+void() Demon_MeleeAttack =
+{
+ demon1_atta1 ();
+};
+
+
+/*QUAKED monster_demon1 (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/demon.mdl");
+}
+Fiend.
+
+Default heath = 300"
+
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : ""Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound"
+snd_hit(string) : "Path to custom hit sound (DEMON SLASHING)"
+snd_idle(string) : "Path to custom idle sound"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+skin_head(float) : "Skin index of custom head model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_demon1 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ objerror("Incompatible spawnflag: TURRET_MODE\n");
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ //dumptruck_ds custom_mdls
+ precache_body_model ("progs/demon.mdl");
+ precache_head_model ("progs/h_demon.mdl");
+
+ precache_sound_death ("demon/ddeath.wav");
+ precache_sound_hit ("demon/dhit2.wav");
+ precache_sound_attack ("demon/djump.wav");
+ precache_sound_pain ("demon/dpain1.wav");
+ precache_sound_idle ("demon/idle1.wav");
+ precache_sound_sight ("demon/sight2.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ // precache_gib2 ("progs/gib2.mdl");
+ // precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/demon.mdl");
+ // setmodel (self, "progs/demon.mdl");
+
+ setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 300;
+
+ self.th_stand = demon1_stand1;
+ self.th_walk = demon1_walk1;
+ self.th_run = demon1_run1;
+ self.th_die = demon_die;
+ self.th_melee = Demon_MeleeAttack; // one of two attacks
+ self.th_missile = demon1_jump1; // jump attack
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = demon1_pain;
+ else
+ self.th_pain = SUB_NullPain;
+
+ walkmonster_start();
+};
+
+
+/*
+==============================================================================
+
+DEMON
+
+==============================================================================
+*/
+
+/*
+==============
+CheckDemonMelee
+
+Returns TRUE if a melee attack would hit right now
+==============
+*/
+float() CheckDemonMelee =
+{
+ if (enemy_range == RANGE_MELEE)
+ { // FIXME: check canreach
+ self.attack_state = AS_MELEE;
+ return TRUE;
+ }
+ return FALSE;
+};
+
+/*
+==============
+CheckDemonJump
+
+==============
+*/
+float() CheckDemonJump =
+{
+ local vector dist;
+ local float d;
+
+ if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z
+ + 0.75 * self.enemy.size_z)
+ return FALSE;
+
+ if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z
+ + 0.25 * self.enemy.size_z)
+ return FALSE;
+
+ dist = self.enemy.origin - self.origin;
+ dist_z = 0;
+
+ d = vlen(dist);
+
+ if (d < 100)
+ return FALSE;
+
+ if (d > 200)
+ {
+ if (random() < 0.9)
+ return FALSE;
+ }
+
+ return TRUE;
+};
+
+float() DemonCheckAttack =
+{
+
+// if close enough for slashing, go for it
+ if (CheckDemonMelee ())
+ {
+ self.attack_state = AS_MELEE;
+ return TRUE;
+ }
+
+ if (CheckDemonJump ())
+ {
+ self.attack_state = AS_MISSILE;
+ sound_attack (self, CHAN_VOICE, "demon/djump.wav", 1, ATTN_NORM);
+ return TRUE;
+ }
+
+ return FALSE;
+};
+
+
+//===========================================================================
+
+void(float side) Demon_Melee =
+{
+ local float ldmg;
+ local vector delta;
+
+ ai_face ();
+ walkmove (self.ideal_yaw, 12); // allow a little closing
+
+ delta = self.enemy.origin - self.origin;
+
+ if (vlen(delta) > 100)
+ return;
+ if (!CanDamage (self.enemy, self))
+ return;
+
+ sound_hit (self, CHAN_WEAPON, "demon/dhit2.wav", 1, ATTN_NORM);
+ ldmg = 10 + 5*random();
+ T_Damage (self.enemy, self, self, ldmg);
+
+ makevectors (self.angles);
+ SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
+};
+
+
+void() Demon_JumpTouch =
+{
+ local float ldmg;
+
+ if (self.health <= 0)
+ return;
+
+ if (other.takedamage)
+ {
+ if ( vlen(self.velocity) > 400 )
+ {
+ if !(self.worldtype)
+ {
+ ldmg = 40 + 10*random();
+ T_Damage (other, self, self, ldmg);
+ if (other.health > 0) // is the player still alive? Preach's instakill bug check - dumptruck_ds
+ self.worldtype = 1;
+ }
+ }
+ }
+
+ if (!checkbottom(self))
+ {
+ if (self.flags & FL_ONGROUND)
+ { // jump randomly to not get hung up
+//dprint ("popjump\n");
+// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
+// self.touch = SUB_Null;
+ self.touch = monster_touch;
+// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
+ self.think = demon1_jump1;
+ self.nextthink = time + 0.1;
+
+// self.velocity_x = (random() - 0.5) * 600;
+// self.velocity_y = (random() - 0.5) * 600;
+// self.velocity_z = 200;
+// self.flags = self.flags - FL_ONGROUND;
+ }
+ return; // not on ground yet
+ }
+
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
+ // self.touch = SUB_Null;
+ self.touch = monster_touch;
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
+ self.think = demon1_jump11;
+ self.nextthink = time + 0.1;
+};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_demon (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/demon.mdl","frame":53});
+}
+*/
+void() monster_dead_demon =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/demon.mdl");
+ setmodel(self, "progs/demon.mdl");
+ self.frame = $death9;
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-43.63 -47.26 -50.53','32.48 24.65 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/dog.qc

diff --git a/qc/monsters/dog.qc b/qc/monsters/dog.qc
new file mode 100644
index 0000000..6da85bb
--- /dev/null
+++ b/qc/monsters/dog.qc
@@ -0,0 +1,503 @@
+/*
+==============================================================================
+
+DOG
+
+==============================================================================
+*/
+$cd id1/models/dog
+$origin 0 0 24
+$base base
+$skin skin
+
+$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
+
+$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
+
+$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
+$frame deathb9
+
+$frame pain1 pain2 pain3 pain4 pain5 pain6
+
+$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10
+$frame painb11 painb12 painb13 painb14 painb15 painb16
+
+$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12
+
+$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
+
+
+void() dog_leap1;
+void() dog_run1;
+
+/*
+================
+dog_bite
+
+================
+*/
+void() dog_bite =
+{
+local vector delta;
+local float ldmg;
+
+ if (!self.enemy)
+ return;
+
+ ai_charge(10);
+
+ if (!CanDamage (self.enemy, self))
+ return;
+
+ delta = self.enemy.origin - self.origin;
+
+ if (vlen(delta) > 100)
+ return;
+
+ ldmg = (random() + random() + random()) * 8;
+ T_Damage (self.enemy, self, self, ldmg);
+};
+
+void() Dog_JumpTouch =
+{
+ local float ldmg;
+
+ if (self.health <= 0)
+ return;
+
+ if (other.takedamage)
+ {
+ if ( vlen(self.velocity) > 300 )
+ {
+ if !(self.worldtype)
+ {
+ ldmg = 10 + 10*random();
+ T_Damage (other, self, self, ldmg);
+ if (other.health > 0) // is the player still alive? Preach's instakill bug check - dumptruck_ds
+ self.worldtype = 1;
+ }
+ }
+ }
+
+ if (!checkbottom(self))
+ {
+ if (self.flags & FL_ONGROUND)
+ { // jump randomly to not get hung up
+//dprint ("popjump\n");
+// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
+// self.touch = SUB_Null;
+ self.touch = monster_touch;
+// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
+ self.think = dog_leap1;
+ self.nextthink = time + 0.1;
+
+// self.velocity_x = (random() - 0.5) * 600;
+// self.velocity_y = (random() - 0.5) * 600;
+// self.velocity_z = 200;
+// self.flags = self.flags - FL_ONGROUND;
+ }
+ return; // not on ground yet
+ }
+
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
+ // self.touch = SUB_Null;
+ self.touch = monster_touch;
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
+ self.think = dog_run1;
+ self.nextthink = time + 0.1;
+};
+
+
+void() dog_stand1 =[ $stand1, dog_stand2 ] {ai_stand();};
+void() dog_stand2 =[ $stand2, dog_stand3 ] {ai_stand();};
+void() dog_stand3 =[ $stand3, dog_stand4 ] {ai_stand();};
+void() dog_stand4 =[ $stand4, dog_stand5 ] {ai_stand();};
+void() dog_stand5 =[ $stand5, dog_stand6 ] {ai_stand();};
+void() dog_stand6 =[ $stand6, dog_stand7 ] {ai_stand();};
+void() dog_stand7 =[ $stand7, dog_stand8 ] {ai_stand();};
+void() dog_stand8 =[ $stand8, dog_stand9 ] {ai_stand();};
+void() dog_stand9 =[ $stand9, dog_stand1 ] {ai_stand();};
+
+void() dog_walk1 =[ $walk1 , dog_walk2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "dog/idle.wav", 1, ATTN_IDLE); //dumptruck_ds
+ai_walk(8);};
+void() dog_walk2 =[ $walk2 , dog_walk3 ] {ai_walk(8);};
+void() dog_walk3 =[ $walk3 , dog_walk4 ] {ai_walk(8);};
+void() dog_walk4 =[ $walk4 , dog_walk5 ] {ai_walk(8);};
+void() dog_walk5 =[ $walk5 , dog_walk6 ] {ai_walk(8);};
+void() dog_walk6 =[ $walk6 , dog_walk7 ] {ai_walk(8);};
+void() dog_walk7 =[ $walk7 , dog_walk8 ] {ai_walk(8);};
+void() dog_walk8 =[ $walk8 , dog_walk1 ] {ai_walk(8);};
+
+void() dog_run1 =[ $run1 , dog_run2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "dog/idle.wav", 1, ATTN_IDLE); //dumptruck_ds
+ai_run(16);};
+void() dog_run2 =[ $run2 , dog_run3 ] {ai_run(32);};
+void() dog_run3 =[ $run3 , dog_run4 ] {ai_run(32);};
+void() dog_run4 =[ $run4 , dog_run5 ] {ai_run(20);};
+void() dog_run5 =[ $run5 , dog_run6 ] {ai_run(64);};
+void() dog_run6 =[ $run6 , dog_run7 ] {ai_run(32);};
+void() dog_run7 =[ $run7 , dog_run8 ] {ai_run(16);};
+void() dog_run8 =[ $run8 , dog_run9 ] {ai_run(32);};
+void() dog_run9 =[ $run9 , dog_run10 ] {ai_run(32);};
+void() dog_run10 =[ $run10 , dog_run11 ] {ai_run(20);};
+void() dog_run11 =[ $run11 , dog_run12 ] {ai_run(64);};
+void() dog_run12 =[ $run12 , dog_run1 ] {ai_run(32);};
+
+void() dog_atta1 =[ $attack1, dog_atta2 ] {ai_charge(10);};
+void() dog_atta2 =[ $attack2, dog_atta3 ] {ai_charge(10);};
+void() dog_atta3 =[ $attack3, dog_atta4 ] {ai_charge(10);};
+void() dog_atta4 =[ $attack4, dog_atta5 ] {
+sound_attack (self, CHAN_VOICE, "dog/dattack1.wav", 1, ATTN_NORM); //dumptruck_ds
+dog_bite();};
+void() dog_atta5 =[ $attack5, dog_atta6 ] {ai_charge(10);};
+void() dog_atta6 =[ $attack6, dog_atta7 ] {ai_charge(10);};
+void() dog_atta7 =[ $attack7, dog_atta8 ] {ai_charge(10);};
+void() dog_atta8 =[ $attack8, dog_run1 ] {ai_charge(10);};
+
+void() dog_leap1 =[ $leap1, dog_leap2 ] {ai_face();};
+void() dog_leap2 =[ $leap2, dog_leap3 ]
+{
+ ai_face();
+ self.worldtype = 0; //fix for instakill bug -- dumptruck_ds
+ self.touch = Dog_JumpTouch;
+ makevectors (self.angles);
+ self.origin_z = self.origin_z + 1;
+ self.velocity = v_forward * 300 + '0 0 200';
+ if (self.flags & FL_ONGROUND)
+ self.flags = self.flags - FL_ONGROUND;
+};
+
+void() dog_leap3 =[ $leap3, dog_leap4 ] {};
+void() dog_leap4 =[ $leap4, dog_leap5 ] {};
+void() dog_leap5 =[ $leap5, dog_leap6 ] {};
+void() dog_leap6 =[ $leap6, dog_leap7 ] {};
+void() dog_leap7 =[ $leap7, dog_leap8 ] {};
+void() dog_leap8 =[ $leap8, dog_leap9 ] {};
+void() dog_leap9 =[ $leap9, dog_leap9 ] {};
+
+void() dog_pain1 =[ $pain1 , dog_pain2 ] {};
+void() dog_pain2 =[ $pain2 , dog_pain3 ] {};
+void() dog_pain3 =[ $pain3 , dog_pain4 ] {};
+void() dog_pain4 =[ $pain4 , dog_pain5 ] {};
+void() dog_pain5 =[ $pain5 , dog_pain6 ] {};
+void() dog_pain6 =[ $pain6 , dog_run1 ] {};
+
+void() dog_painb1 =[ $painb1 , dog_painb2 ] {};
+void() dog_painb2 =[ $painb2 , dog_painb3 ] {};
+void() dog_painb3 =[ $painb3 , dog_painb4 ] {ai_pain(4);};
+void() dog_painb4 =[ $painb4 , dog_painb5 ] {ai_pain(12);};
+void() dog_painb5 =[ $painb5 , dog_painb6 ] {ai_pain(12);};
+void() dog_painb6 =[ $painb6 , dog_painb7 ] {ai_pain(2);};
+void() dog_painb7 =[ $painb7 , dog_painb8 ] {};
+void() dog_painb8 =[ $painb8 , dog_painb9 ] {ai_pain(4);};
+void() dog_painb9 =[ $painb9 , dog_painb10 ] {};
+void() dog_painb10 =[ $painb10 , dog_painb11 ] {ai_pain(10);};
+void() dog_painb11 =[ $painb11 , dog_painb12 ] {};
+void() dog_painb12 =[ $painb12 , dog_painb13 ] {};
+void() dog_painb13 =[ $painb13 , dog_painb14 ] {};
+void() dog_painb14 =[ $painb14 , dog_painb15 ] {};
+void() dog_painb15 =[ $painb15 , dog_painb16 ] {};
+void() dog_painb16 =[ $painb16 , dog_run1 ] {};
+
+void(entity attacker, float damage) dog_pain =
+{
+ sound_pain (self, CHAN_VOICE, "dog/dpain1.wav", 1, ATTN_NORM); //dumptruck_ds
+
+ if (random() > 0.5)
+ dog_pain1 ();
+ else
+ dog_painb1 ();
+};
+
+void() dog_die1 =[ $death1, dog_die2 ] {};
+void() dog_die2 =[ $death2, dog_die3 ] {};
+void() dog_die3 =[ $death3, dog_die4 ] {};
+void() dog_die4 =[ $death4, dog_die5 ] {};
+void() dog_die5 =[ $death5, dog_die6 ] {};
+void() dog_die6 =[ $death6, dog_die7 ] {};
+void() dog_die7 =[ $death7, dog_die8 ] {};
+void() dog_die8 =[ $death8, dog_die9 ] {};
+void() dog_die9 =[ $death9, dog_die9 ] {};
+
+void() dog_dieb1 =[ $deathb1, dog_dieb2 ] {};
+void() dog_dieb2 =[ $deathb2, dog_dieb3 ] {};
+void() dog_dieb3 =[ $deathb3, dog_dieb4 ] {};
+void() dog_dieb4 =[ $deathb4, dog_dieb5 ] {};
+void() dog_dieb5 =[ $deathb5, dog_dieb6 ] {};
+void() dog_dieb6 =[ $deathb6, dog_dieb7 ] {};
+void() dog_dieb7 =[ $deathb7, dog_dieb8 ] {};
+void() dog_dieb8 =[ $deathb8, dog_dieb9 ] {};
+void() dog_dieb9 =[ $deathb9, dog_dieb9 ] {};
+
+
+void() dog_die =
+{
+// check for gib
+ if (self.health < -35)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ if (self.mdl_head != "")
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_dog.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+
+// regular death
+ sound_death (self, CHAN_VOICE, "dog/ddeath.wav", 1, ATTN_NORM); //dumptruck_ds
+ self.solid = SOLID_NOT;
+
+ DropStuff();
+
+ if (random() > 0.5)
+ dog_die1 ();
+ else
+ dog_dieb1 ();
+};
+
+//============================================================================
+
+/*
+==============
+CheckDogMelee
+
+Returns TRUE if a melee attack would hit right now
+==============
+*/
+float() CheckDogMelee =
+{
+ if (enemy_range == RANGE_MELEE)
+ { // FIXME: check canreach
+ self.attack_state = AS_MELEE;
+ return TRUE;
+ }
+ return FALSE;
+};
+
+/*
+==============
+CheckDogJump
+
+==============
+*/
+float() CheckDogJump =
+{
+ local vector dist;
+ local float d;
+
+ if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z
+ + 0.75 * self.enemy.size_z)
+ return FALSE;
+
+ if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z
+ + 0.25 * self.enemy.size_z)
+ return FALSE;
+
+ dist = self.enemy.origin - self.origin;
+ dist_z = 0;
+
+ d = vlen(dist);
+
+ if (d < 80)
+ return FALSE;
+
+ if (d > 150)
+ return FALSE;
+
+ return TRUE;
+};
+
+float() DogCheckAttack =
+{
+
+// if close enough for slashing, go for it
+ if (CheckDogMelee ())
+ {
+ self.attack_state = AS_MELEE;
+ return TRUE;
+ }
+
+ if (CheckDogJump ())
+ {
+ self.attack_state = AS_MISSILE;
+ return TRUE;
+ }
+
+ return FALSE;
+};
+
+
+//===========================================================================
+
+/*QUAKED monster_dog (1 0 0) (-32 -32 -24) (32 32 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/dog.mdl");
+}
+Rottweiler.
+
+Default health = 25
+
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound"
+snd_idle(string) : "Path to custom idle sound"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+skin_head(float) : "Skin index of custom head model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_dog =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ objerror("Incompatible spawnflag: TURRET_MODE\n");
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ //dumptruck_ds -- model_custom and sounds changes
+ precache_head_model ("progs/h_dog.mdl");
+ precache_body_model ("progs/dog.mdl");
+ precache_sound_attack ("dog/dattack1.wav");
+ precache_sound_death ("dog/ddeath.wav");
+ precache_sound_pain ("dog/dpain1.wav");
+ precache_sound_sight ("dog/dsight.wav");
+ precache_sound_idle ("dog/idle.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ // dumptruck_ds
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/dog.mdl"); //dumptruck_ds
+ // setmodel (self, "progs/dog.mdl");
+
+ setsize (self, '-32 -32 -24', '32 32 40');
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 25;
+
+ self.th_stand = dog_stand1;
+ self.th_walk = dog_walk1;
+ self.th_run = dog_run1;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = dog_pain;
+ else
+ self.th_pain = SUB_NullPain;
+ self.th_die = dog_die;
+ self.th_melee = dog_atta1;
+ self.th_missile = dog_leap1;
+
+ walkmonster_start();
+};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_dog (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/dog.mdl","frame":16});
+}
+*/
+void() monster_dead_dog =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/dog.mdl");
+ setmodel(self, "progs/dog.mdl");
+ self.frame = $death8;
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-24.51 -16.5 -50.37','28.2 13.81 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/enforcer.qc

diff --git a/qc/monsters/enforcer.qc b/qc/monsters/enforcer.qc
new file mode 100644
index 0000000..2b4b594
--- /dev/null
+++ b/qc/monsters/enforcer.qc
@@ -0,0 +1,1044 @@
+/*
+==============================================================================
+
+SOLDIER / PLAYER
+
+==============================================================================
+*/
+
+$cd id1/models/enforcer
+$origin 0 -6 24
+$base base
+$skin skin
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
+$frame walk11 walk12 walk13 walk14 walk15 walk16
+
+$frame run1 run2 run3 run4 run5 run6 run7 run8
+
+$frame attack1 attack2 attack3 attack4 attack5 attack6
+$frame attack7 attack8 attack9 attack10
+
+$frame death1 death2 death3 death4 death5 death6 death7 death8
+$frame death9 death10 death11 death12 death13 death14
+
+$frame fdeath1 fdeath2 fdeath3 fdeath4 fdeath5 fdeath6 fdeath7 fdeath8
+$frame fdeath9 fdeath10 fdeath11
+
+$frame paina1 paina2 paina3 paina4
+
+$frame painb1 painb2 painb3 painb4 painb5
+
+$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8
+
+$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8
+$frame paind9 paind10 paind11 paind12 paind13 paind14 paind15 paind16
+$frame paind17 paind18 paind19
+
+
+void() Laser_Touch =
+{
+ local vector org;
+
+ if (other == self.owner)
+ return; // don't explode on owner
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove(self);
+ return;
+ }
+
+ sound_hit (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC); //dumptruck_ds
+ org = self.origin - 8*normalize(self.velocity);
+
+ if (other.health)
+ {
+ SpawnBlood (org, self.velocity*0.2, 15);
+ T_Damage (other, self, self.owner, 15);
+ }
+ else
+ {
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_GUNSHOT);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
+ }
+
+ remove(self);
+};
+
+void(vector org, vector vec) LaunchLaser =
+{
+
+ local float projspeed = self.proj_speed_mod * 600;
+
+ if (self.classname == "monster_enforcer" || self.classname == "monster_army")
+ sound_attack (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
+
+ vec = normalize(vec);
+
+ newmis = spawn();
+ newmis.snd_hit = self.snd_hit; // dumptruck_ds
+ newmis.owner = self;
+ newmis.movetype = MOVETYPE_FLY;
+ newmis.solid = SOLID_BBOX;
+ newmis.effects = EF_DIMLIGHT;
+ newmis.skin = self.skin_proj; //dumptruck_ds
+
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (newmis, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/laser.mdl");
+ }
+
+ if (!newmis.skin_proj) // dumptruck_ds
+ {
+ newmis.skin = self.skin_proj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+ // setmodel (newmis, "progs/laser.mdl");
+ setsize (newmis, '0 0 0', '0 0 0');
+
+ setorigin (newmis, org);
+
+ SetSpeed(newmis, vec, projspeed);
+ newmis.angles = vectoangles(newmis.velocity);
+ if (self.homing > 0)
+ {
+ SetupHoming(newmis, projspeed);
+ }
+ else
+ {
+ newmis.nextthink = time + 5;
+ newmis.think = SUB_Remove;
+ }
+ newmis.touch = Laser_Touch;
+};
+
+void(vector org, vector vec) EnfLaunchSpike =
+{
+
+ local float projspeed = self.proj_speed_mod * 600;
+
+ sound_attack (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
+
+ vec = normalize(vec);
+
+ newmis = spawn();
+ newmis.owner = self;
+ newmis.movetype = MOVETYPE_FLY;
+ newmis.solid = SOLID_BBOX;
+ // newmis.effects = EF_DIMLIGHT;
+ newmis.skin = self.skin_proj; //dumptruck_ds
+ // setmodel (newmis, "progs/s_spike.mdl");
+
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (newmis, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/s_spike.mdl");
+ }
+
+ if (!newmis.skin_proj) // dumptruck_ds
+ {
+ newmis.skin = self.skin_proj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+// dumptruck_ds - end
+ setsize (newmis, '0 0 0', '0 0 0');
+
+ setorigin (newmis, org);
+
+ SetSpeed(newmis, vec, projspeed);
+ newmis.angles = vectoangles(newmis.velocity);
+
+ if (self.homing > 0)
+ {
+ SetupHoming(newmis, projspeed);
+ }
+ else
+ {
+ newmis.nextthink = time + 5;
+ newmis.think = SUB_Remove;
+ }
+ newmis.touch = superspike_touch;
+};
+
+//dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
+
+void() EnfMisTouch =
+{
+ local float damg;
+
+ if (other == self.owner)
+ return; // don't explode on owner
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove(self);
+ return;
+ }
+
+ damg = 30 + random()*2; //dumptruck_ds
+
+ if (other.health)
+ {
+ if (other.classname == "monster_shambler")
+ damg = damg * 0.5; // mostly immune
+ T_Damage (other, self, self.owner, damg );
+ }
+
+ // don't do radius damage to the other, because all the damage
+ // was done in the impact
+ T_RadiusDamage (self, self.owner, 40, other); //dumptruck_ds
+
+// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
+ self.origin = self.origin - 8*normalize(self.velocity);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ BecomeExplosion ();
+};
+
+/*
+================
+EnfRocket //dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
+================
+*/
+void() EnfRocket =
+{
+ local entity missile;
+ local float projspeed = 900 * self.proj_speed_mod;
+ // self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; dumptruck_ds
+
+ sound_attack (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
+
+ self.punchangle_x = -2;
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_FLYMISSILE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "missile";
+
+// set missile speed -- dumptruck_ds below
+
+ SetSpeed(missile, normalize(self.enemy.origin - self.origin), projspeed);
+ missile.angles = vectoangles(missile.velocity);
+ missile.touch = EnfMisTouch;
+
+ // makevectors (self.v_angle);
+ // missile.velocity = aim(self, 1000);
+ // missile.velocity = missile.velocity * 1000;
+ // missile.angles = vectoangles(missile.velocity);
+
+ // missile.touch = T_MissileTouch;
+
+// set missile duration
+ if (self.homing > 0)
+ {
+ SetupHoming(missile, projspeed);
+ }
+ else
+ {
+ missile.nextthink = time + 5;
+ missile.think = SUB_Remove;
+ }
+ missile.skin = self.skin_proj; //dumptruck_ds
+
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/missile.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+// dumptruck_ds - end
+ // setmodel (missile, "progs/missile.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
+ setorigin (missile, self.origin + v_forward * 30 + v_right * 8.5 + '0 0 12'); //last number was 16 - dumptruck_ds
+ // setorigin (missile, self.origin + v_forward*8 + '0 0 16');
+};
+//end dumptruck_ds grunt missle end
+/*
+================
+EnfFireGrenade
+================
+*/
+void() EnfFireGrenade =
+{
+ local entity missile;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ sound_attack (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+
+// set missile speed
+
+ makevectors (self.angles);
+
+ missile.velocity = normalize(self.enemy.origin - self.origin);
+ missile.velocity = missile.velocity * 600;
+ missile.velocity_z = 200;
+
+ missile.avelocity = '300 300 300';
+
+ missile.angles = vectoangles(missile.velocity);
+
+ missile.touch = OgreGrenadeTouch;
+
+// set missile duration
+ missile.nextthink = time + 2.5;
+ missile.think = OgreGrenadeExplode;
+ missile.skin = self.skin_proj; //dumptruck_ds
+
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/grenade.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+// dumptruck_ds - end
+
+ // setmodel (missile, "progs/grenade.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16');
+ // setorigin (missile, self.origin);
+};
+
+void() EnfLightning =
+{
+ local vector org, dir;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ sound_attack(self, CHAN_WEAPON, "weapons/lstart.wav", 1, ATTN_NORM);
+ ai_face ();
+ makevectors (self.angles);
+ org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
+
+ dir = self.enemy.origin - self.enemy.velocity * 0.075;
+ dir = normalize (dir - org + '0 0 16');
+
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ traceline (org, self.origin + dir*900, TRUE, self);
+ }
+ else
+ {
+ traceline (org, self.origin + dir*600, TRUE, self);
+ }
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
+ WriteEntity (MSG_BROADCAST, self);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
+ WriteCoord (MSG_BROADCAST, trace_endpos_x);
+ WriteCoord (MSG_BROADCAST, trace_endpos_y);
+ WriteCoord (MSG_BROADCAST, trace_endpos_z);
+
+ LightningDamage (org, trace_endpos, self, 4);
+};
+
+
+// style stuff -- dumptruck_ds
+void() enforcer_fire =
+{
+
+if (self.style == 1)
+
+ {
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ ai_face();
+ sound_attack (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
+
+ EnfRocket();
+ return;
+ }
+
+else if (self.style == 2)
+
+ {
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ ai_face();
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ PreachFireGrenade(self.attack_elevation);
+ }
+ else
+ EnfFireGrenade();
+ return;
+ }
+
+else if (self.style == 3 || self.style ==5)
+
+ {
+ local vector foo;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ makevectors (self.angles);
+
+ foo = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
+
+ EnfLaunchSpike(foo, self.enemy.origin - self.origin);
+ return;
+ }
+
+else
+
+ local vector org;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ makevectors (self.angles);
+
+ org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
+
+ LaunchLaser(org, self.enemy.origin - self.origin);
+};
+
+//============================================================================
+
+void() enf_stand1 =[ $stand1, enf_stand2 ] {ai_stand();};
+void() enf_stand2 =[ $stand2, enf_stand3 ] {ai_stand();};
+void() enf_stand3 =[ $stand3, enf_stand4 ] {ai_stand();};
+void() enf_stand4 =[ $stand4, enf_stand5 ] {ai_stand();};
+void() enf_stand5 =[ $stand5, enf_stand6 ] {ai_stand();};
+void() enf_stand6 =[ $stand6, enf_stand7 ] {ai_stand();};
+void() enf_stand7 =[ $stand7, enf_stand1 ] {ai_stand();};
+
+void() enf_walk1 =[ $walk1 , enf_walk2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); //dumptruck_ds
+ai_walk(2);};
+void() enf_walk2 =[ $walk2 , enf_walk3 ] {ai_walk(4);};
+void() enf_walk3 =[ $walk3 , enf_walk4 ] {ai_walk(4);};
+void() enf_walk4 =[ $walk4 , enf_walk5 ] {ai_walk(3);};
+void() enf_walk5 =[ $walk5 , enf_walk6 ] {ai_walk(1);};
+void() enf_walk6 =[ $walk6 , enf_walk7 ] {ai_walk(2);};
+void() enf_walk7 =[ $walk7 , enf_walk8 ] {ai_walk(2);};
+void() enf_walk8 =[ $walk8 , enf_walk9 ] {ai_walk(1);};
+void() enf_walk9 =[ $walk9 , enf_walk10 ] {ai_walk(2);};
+void() enf_walk10 =[ $walk10, enf_walk11 ] {ai_walk(4);};
+void() enf_walk11 =[ $walk11, enf_walk12 ] {ai_walk(4);};
+void() enf_walk12 =[ $walk12, enf_walk13 ] {ai_walk(1);};
+void() enf_walk13 =[ $walk13, enf_walk14 ] {ai_walk(2);};
+void() enf_walk14 =[ $walk14, enf_walk15 ] {ai_walk(3);};
+void() enf_walk15 =[ $walk15, enf_walk16 ] {ai_walk(4);};
+void() enf_walk16 =[ $walk16, enf_walk1 ] {ai_walk(2);};
+
+void() enf_run1 =[ $run1 , enf_run2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); //dumptruck_ds
+ai_run(18);};
+void() enf_run2 =[ $run2 , enf_run3 ] {ai_run(14);};
+void() enf_run3 =[ $run3 , enf_run4 ] {ai_run(7);};
+void() enf_run4 =[ $run4 , enf_run5 ] {ai_run(12);};
+void() enf_run5 =[ $run5 , enf_run6 ] {ai_run(14);};
+void() enf_run6 =[ $run6 , enf_run7 ] {ai_run(14);};
+void() enf_run7 =[ $run7 , enf_run8 ] {ai_run(7);};
+void() enf_run8 =[ $run8 , enf_run1 ] {ai_run(11);};
+
+void() enf_atk1 =[ $attack1, enf_atk2 ] {ai_face();};
+void() enf_atk2 =[ $attack2, enf_atk3 ] {ai_face();};
+void() enf_atk3 =[ $attack3, enf_atk4 ] {ai_face();};
+void() enf_atk4 =[ $attack4, enf_atk5 ] {ai_face();};
+void() enf_atk5 =[ $attack5, enf_atk6 ] {ai_face();};
+void() enf_atk6 =[ $attack6, enf_atk7 ] {enforcer_fire();};
+void() enf_atk7 =[ $attack7, enf_atk8 ] {ai_face();};
+void() enf_atk8 =[ $attack8, enf_atk9 ] {ai_face();};
+void() enf_atk9 =[ $attack5, enf_atk10 ] {ai_face();};
+void() enf_atk10 =[ $attack6, enf_atk11 ] {enforcer_fire();};
+void() enf_atk11 =[ $attack7, enf_atk12 ] {ai_face();};
+void() enf_atk12 =[ $attack8, enf_atk13 ] {ai_face();};
+void() enf_atk13 =[ $attack9, enf_atk14 ] {ai_face();};
+void() enf_atk14 =[ $attack10, enf_run1 ] {ai_face();SUB_CheckRefire (enf_atk1);
+};
+/* modified animation frames for style Enforcers */ // dumptruck_ds
+void() enf_2atk7;
+void() enf_2atk1 =[ $attack1, enf_2atk2 ] {ai_face();self.count = 0;self.t_length= 8 + floor(random()*6);};
+void() enf_2atk2 =[ $attack2, enf_2atk3 ] {ai_face();};
+void() enf_2atk3 =[ $attack3, enf_2atk4 ] {ai_face();};
+void() enf_2atk4 =[ $attack4, enf_2atk5 ] {ai_face();};
+void() enf_2atk5 =[ $attack5, enf_2atk6 ] {ai_face();};
+
+void() enf_2atk6 ={
+self.frame = $attack6;
+self.nextthink = time + .1;
+if (self.style == 5 && self.count < self.t_length)
+{
+ self.count +=1;
+}
+else
+{
+ self.think = enf_2atk7;
+}
+ai_face();
+enforcer_fire();};
+void() enf_2atk7 =[ $attack7, enf_2atk8 ] {ai_face();};
+void() enf_2atk8 =[ $attack8, enf_2atk9 ] {ai_face();};
+void() enf_2atk9 =[ $attack9, enf_2atk10 ] {ai_face();};
+void() enf_2atk10 =[ $attack10, enf_run1 ] {ai_face();SUB_CheckRefire (enf_2atk1);
+};
+
+void() enf_4atk1 =[ $attack1, enf_4atk2 ] {ai_face();};
+void() enf_4atk2 =[ $attack2, enf_4atk3 ] {ai_face();};
+void() enf_4atk3 =[ $attack3, enf_4atk4 ] {ai_face();};
+void() enf_4atk4 =[ $attack4, enf_4atk5 ] {ai_face();};
+void() enf_4atk5 =[ $attack5, enf_4atk6 ] {ai_face();};
+void() enf_4atk6 =[ $attack6, enf_4atk7 ] {EnfLightning();};
+void() enf_4atk7 =[ $attack6, enf_4atk8 ] {EnfLightning();};
+void() enf_4atk8 =[ $attack6, enf_4atk9 ] {EnfLightning();};
+void() enf_4atk9 =[ $attack7, enf_4atk10 ] {ai_face();};
+void() enf_4atk10 =[ $attack8, enf_4atk11 ] {ai_face();};
+void() enf_4atk11 =[ $attack9, enf_4atk12 ] {ai_face();};
+void() enf_4atk12 =[ $attack10, enf_run1 ] {ai_face();SUB_CheckRefire (enf_2atk1);
+};
+////////////////////////////
+// new frames for turret mode START
+////////////////////////////
+
+void() enf_turret_atk1 =[ $attack1, enf_turret_atk2 ] {ai_face();};
+void() enf_turret_atk2 =[ $attack2, enf_turret_atk3 ] {ai_face();};
+void() enf_turret_atk3 =[ $attack3, enf_turret_atk4 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
+void() enf_turret_atk4 =[ $attack4, enf_turret_atk5 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() enf_turret_atk5 =[ $attack5, enf_turret_atk6 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() enf_turret_atk6 =[ $attack6, enf_turret_atk7 ] {enforcer_fire();};
+void() enf_turret_atk7 =[ $attack7, enf_turret_atk8 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
+void() enf_turret_atk8 =[ $attack8, enf_turret_atk9 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() enf_turret_atk9 =[ $attack5, enf_turret_atk10 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() enf_turret_atk10 =[ $attack6, enf_turret_atk11 ] {enforcer_fire();};
+void() enf_turret_atk11 =[ $attack7, enf_turret_atk12 ] {ai_face();};
+void() enf_turret_atk12 =[ $attack8, enf_turret_atk13 ] {ai_face();};
+void() enf_turret_atk13 =[ $attack9, enf_turret_atk14 ] {ai_face();};
+void() enf_turret_atk14 =[ $attack10, enf_seek_stand1 ] {ai_face();SUB_CheckRefire (enf_turret_atk1);
+};
+void() enf_seek_stand1 =[ $stand1, enf_seek_stand2 ] {ai_run(0);};
+void() enf_seek_stand2 =[ $stand2, enf_seek_stand3 ] {ai_run(0);};
+void() enf_seek_stand3 =[ $stand3, enf_seek_stand4 ] {ai_run(0);};
+void() enf_seek_stand4 =[ $stand4, enf_seek_stand5 ] {ai_run(0);};
+void() enf_seek_stand5 =[ $stand5, enf_seek_stand6 ] {ai_run(0);};
+void() enf_seek_stand6 =[ $stand6, enf_seek_stand7 ] {ai_run(0);};
+void() enf_seek_stand7 =[ $stand7, enf_seek_stand1 ] {ai_run(0);};
+
+void() enf_2turret_atk7;
+void() enf_2turret_atk1 =[ $attack1, enf_2turret_atk2 ] {ai_face();self.count = 0;self.t_length= 4 + floor(random()*4);};
+void() enf_2turret_atk2 =[ $attack2, enf_2turret_atk3 ] {ai_face();};
+void() enf_2turret_atk3 =[ $attack3, enf_2turret_atk4 ] {ai_face();};
+void() enf_2turret_atk4 =[ $attack4, enf_2turret_atk5 ] {ai_face();};
+void() enf_2turret_atk5 =[ $attack5, enf_2turret_atk6 ] {ai_face();};
+
+void() enf_2turret_atk6 ={
+self.frame = $attack6;
+self.nextthink = time + .1;
+if (self.style == 5 && self.count < self.t_length)
+{
+ self.count +=1;
+}
+else
+{
+ self.think = enf_2turret_atk7;
+}
+ai_face();
+enforcer_fire();};
+void() enf_2turret_atk7 =[ $attack7, enf_2turret_atk8 ] {ai_face();};
+void() enf_2turret_atk8 =[ $attack8, enf_2turret_atk9 ] {ai_face();};
+void() enf_2turret_atk9 =[ $attack9, enf_2turret_atk10 ] {ai_face();};
+void() enf_2turret_atk10 =[ $attack10, enf_2stand1 ] {ai_face();SUB_CheckRefire (enf_2turret_atk1);
+};
+void() enf_4turret_atk1 =[ $attack1, enf_4turret_atk2 ] {ai_face();};
+void() enf_4turret_atk2 =[ $attack2, enf_4turret_atk3 ] {ai_face();};
+void() enf_4turret_atk3 =[ $attack3, enf_4turret_atk4 ] {ai_face();};
+void() enf_4turret_atk4 =[ $attack4, enf_4turret_atk5 ] {ai_face();};
+void() enf_4turret_atk5 =[ $attack5, enf_4turret_atk6 ] {ai_face();};
+void() enf_4turret_atk6 =[ $attack6, enf_4turret_atk7 ] {EnfLightning();};
+void() enf_4turret_atk7 =[ $attack6, enf_4turret_atk8 ] {EnfLightning();};
+void() enf_4turret_atk8 =[ $attack6, enf_4turret_atk9 ] {EnfLightning();};
+void() enf_4turret_atk9 =[ $attack7, enf_4turret_atk10 ] {ai_face();};
+void() enf_4turret_atk10 =[ $attack8, enf_4turret_atk11 ] {ai_face();};
+void() enf_4turret_atk11 =[ $attack9, enf_4turret_atk12 ] {ai_face();};
+void() enf_4turret_atk12 =[ $attack10, enf_2stand1 ] {ai_face();SUB_CheckRefire (enf_2turret_atk1);
+};
+void() enf_2stand1 =[ $stand1, enf_2stand2 ] {ai_run(0);};
+void() enf_2stand2 =[ $stand2, enf_2stand3 ] {ai_run(0);};
+void() enf_2stand3 =[ $stand3, enf_2stand4 ] {ai_run(0);};
+void() enf_2stand4 =[ $stand4, enf_2stand5 ] {ai_run(0);};
+void() enf_2stand5 =[ $stand5, enf_2stand6 ] {ai_run(0);};
+void() enf_2stand6 =[ $stand6, enf_2stand7 ] {ai_run(0);};
+void() enf_2stand7 =[ $stand7, enf_2stand1 ] {ai_run(0);};
+////////////////////////////
+// new frames for turret mode END
+////////////////////////////
+void() enf_paina1 =[ $paina1, enf_paina2 ] {};
+void() enf_paina2 =[ $paina2, enf_paina3 ] {};
+void() enf_paina3 =[ $paina3, enf_paina4 ] {};
+void() enf_paina4 =[ $paina4, enf_run1 ] {};
+
+void() enf_painb1 =[ $painb1, enf_painb2 ] {};
+void() enf_painb2 =[ $painb2, enf_painb3 ] {};
+void() enf_painb3 =[ $painb3, enf_painb4 ] {};
+void() enf_painb4 =[ $painb4, enf_painb5 ] {};
+void() enf_painb5 =[ $painb5, enf_run1 ] {};
+
+void() enf_painc1 =[ $painc1, enf_painc2 ] {};
+void() enf_painc2 =[ $painc2, enf_painc3 ] {};
+void() enf_painc3 =[ $painc3, enf_painc4 ] {};
+void() enf_painc4 =[ $painc4, enf_painc5 ] {};
+void() enf_painc5 =[ $painc5, enf_painc6 ] {};
+void() enf_painc6 =[ $painc6, enf_painc7 ] {};
+void() enf_painc7 =[ $painc7, enf_painc8 ] {};
+void() enf_painc8 =[ $painc8, enf_run1 ] {};
+
+void() enf_paind1 =[ $paind1, enf_paind2 ] {};
+void() enf_paind2 =[ $paind2, enf_paind3 ] {};
+void() enf_paind3 =[ $paind3, enf_paind4 ] {};
+void() enf_paind4 =[ $paind4, enf_paind5 ] {ai_painforward(2);};
+void() enf_paind5 =[ $paind5, enf_paind6 ] {ai_painforward(1);};
+void() enf_paind6 =[ $paind6, enf_paind7 ] {};
+void() enf_paind7 =[ $paind7, enf_paind8 ] {};
+void() enf_paind8 =[ $paind8, enf_paind9 ] {};
+void() enf_paind9 =[ $paind9, enf_paind10 ] {};
+void() enf_paind10 =[ $paind10, enf_paind11 ] {};
+void() enf_paind11 =[ $paind11, enf_paind12 ] {ai_painforward(1);};
+void() enf_paind12 =[ $paind12, enf_paind13 ] {ai_painforward(1);};
+void() enf_paind13 =[ $paind13, enf_paind14 ] {ai_painforward(1);};
+void() enf_paind14 =[ $paind14, enf_paind15 ] {};
+void() enf_paind15 =[ $paind15, enf_paind16 ] {};
+void() enf_paind16 =[ $paind16, enf_paind17 ] {ai_pain(1);};
+void() enf_paind17 =[ $paind17, enf_paind18 ] {ai_pain(1);};
+void() enf_paind18 =[ $paind18, enf_paind19 ] {};
+void() enf_paind19 =[ $paind19, enf_run1 ] {};
+
+void(entity attacker, float damage) enf_pain =
+{
+ local float r;
+
+ r = random ();
+
+ if (self.pain_finished > time)
+ return;
+
+ if (r < 0.5)
+ sound_pain (self, CHAN_VOICE, "enforcer/pain1.wav", 1, ATTN_NORM); //dumptruck_ds
+ else
+ sound_misc3 (self, CHAN_VOICE, "enforcer/pain2.wav", 1, ATTN_NORM); // dumptruck_ds
+
+ if (r < 0.2)
+ {
+ self.pain_finished = time + 1;
+ // moved these here to avoid spamming pain sounds - dumptruck_ds
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+ else
+ enf_paina1 ();
+ }
+ else if (r < 0.4)
+ {
+ self.pain_finished = time + 1;
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+ else
+ enf_painb1 ();
+ }
+ else if (r < 0.7)
+ {
+ self.pain_finished = time + 1;
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+ else
+ enf_painc1 ();
+ }
+ else
+ {
+ self.pain_finished = time + 2;
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+ else
+ enf_paind1 ();
+ }
+};
+
+//============================================================================
+
+
+
+
+void() enf_die1 =[ $death1, enf_die2 ] {};
+void() enf_die2 =[ $death2, enf_die3 ] {};
+void() enf_die3 =[ $death3, enf_die4 ]
+{
+ self.solid = SOLID_NOT;
+
+ if (self.style == 1) // style ammotype check -- dumptruck_ds
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 2) // style ammotype check -- dumptruck_ds
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 3 || self.style == 5) // style ammotype check -- dumptruck_ds
+ {
+ self.ammo_nails = 5;
+ }
+ if (self.style == 0 || self.style == 4) // style ammotype check -- dumptruck_ds
+ {
+ self.ammo_cells = 5;
+ }
+ if(!self.keep_ammo)DropBackpack();
+};
+void() enf_die4 =[ $death4, enf_die5 ] {ai_forward(14);};
+void() enf_die5 =[ $death5, enf_die6 ] {ai_forward(2);};
+void() enf_die6 =[ $death6, enf_die7 ] {};
+void() enf_die7 =[ $death7, enf_die8 ] {};
+void() enf_die8 =[ $death8, enf_die9 ] {};
+void() enf_die9 =[ $death9, enf_die10 ] {ai_forward(3);};
+void() enf_die10 =[ $death10, enf_die11 ] {ai_forward(5);};
+void() enf_die11 =[ $death11, enf_die12 ] {ai_forward(5);};
+void() enf_die12 =[ $death12, enf_die13 ] {ai_forward(5);};
+void() enf_die13 =[ $death13, enf_die14 ] {};
+void() enf_die14 =[ $death14, enf_die14 ] {};
+
+void() enf_fdie1 =[ $fdeath1, enf_fdie2 ] {
+
+};
+void() enf_fdie2 =[ $fdeath2, enf_fdie3 ] {};
+void() enf_fdie3 =[ $fdeath3, enf_fdie4 ]
+{
+ self.solid = SOLID_NOT;
+
+ if (self.style == 1) // style ammotype check -- dumptruck_ds
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 2) // style ammotype check -- dumptruck_ds
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 3 || self.style == 5) // style ammotype check -- dumptruck_ds
+ {
+ self.ammo_nails = 5;
+ }
+ if (self.style == 0 || self.style == 4) // style ammotype check -- dumptruck_ds
+ {
+ self.ammo_cells = 5;
+ }
+ if(!self.keep_ammo)DropBackpack();
+};
+void() enf_fdie4 =[ $fdeath4, enf_fdie5 ] {};
+void() enf_fdie5 =[ $fdeath5, enf_fdie6 ] {};
+void() enf_fdie6 =[ $fdeath6, enf_fdie7 ] {};
+void() enf_fdie7 =[ $fdeath7, enf_fdie8 ] {};
+void() enf_fdie8 =[ $fdeath8, enf_fdie9 ] {};
+void() enf_fdie9 =[ $fdeath9, enf_fdie10 ] {};
+void() enf_fdie10 =[ $fdeath10, enf_fdie11 ] {};
+void() enf_fdie11 =[ $fdeath11, enf_fdie11 ] {};
+
+
+void() enf_die =
+{
+// check for gib
+ if (self.health < -35)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_mega.mdl", self.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+
+// regular death
+ sound_death (self, CHAN_VOICE, "enforcer/death1.wav", 1, ATTN_NORM); //dumptruck_ds
+ DropStuff();
+ if (random() > 0.5)
+ enf_die1 ();
+ else
+ enf_fdie1 ();
+};
+
+
+/*QUAKED monster_enforcer (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/enforcer.mdl");
+}
+Enforcer.
+
+Default health = 80
+
+keep_ammo(integer) : "1 = Don't drop backpack upon death"
+
+style(Choices) : "Attack type"
+0 : "Default (lasers)"
+1 : "rockets"
+2 : "grenades"
+3 : "nails"
+
+snd_death(string) : Path to custom death sound"
+snd_pain(string) : "Path to 1st custom pain sound"
+snd_sight(string) : "Path to custom sight sound for STOP!"
+snd_attack(string) : Path to custom attack sound e.g laser firing"
+snd_hit(string) : "Path to custom hit sound e.g. laser hits wall"
+snd_idle(string) : "Path to custom idle sound"
+snd_misc(string) : "Path to custom sight sound for FREEZE!"
+snd_misc1(string) : "Path to custom sight sound for YOU THERE!"
+snd_misc2(string) : "Path to custom sight sound for HALT!"
+snd_misc3(string) : "Path to 2nd custom pain sound"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+mdl_proj(string) : "Path to custom projectile model"
+skin_head(float) : "Skin index of custom head model"
+skin_proj(float) : "Skin index of custom projectile model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_enforcer =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ if (self.style >= 6)
+ objerror("style key set too high\n");
+
+ precache_body_model2 ("progs/enforcer.mdl"); // custom_mdls function -- dumptruck_ds
+ precache_head_model2 ("progs/h_mega.mdl");
+ precache_proj_model2 ("progs/laser.mdl");
+ precache_proj_model2 ("progs/s_spike.mdl");
+ precache_proj_model2 ("progs/missile.mdl");
+ //dumptruck_ds
+ precache_sound2_death ("enforcer/death1.wav");
+ precache_sound2_attack ("enforcer/enfire.wav");
+ precache_sound2_hit ("enforcer/enfstop.wav");
+ precache_sound2_idle ("enforcer/idle1.wav");
+ precache_sound2_pain ("enforcer/pain1.wav");
+ precache_sound2_misc3 ("enforcer/pain2.wav");
+ precache_sound2_sight ("enforcer/sight1.wav");
+ precache_sound2_misc ("enforcer/sight2.wav"); // these will be replaced with custom noise fields eventually - dumptruck_ds
+ precache_sound2_misc1 ("enforcer/sight3.wav");
+ precache_sound2_misc2 ("enforcer/sight4.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/enforcer.mdl"); // SPIKE to the RESCUE!!!! - got this fixed. -- dumptruck_ds
+ // // setmodel (self, "progs/enforcer.mdl"); //orginal dumptruck_ds
+
+ setsize (self, '-16 -16 -24', '16 16 40');
+
+ if (!self.proj_speed_mod)
+ {
+ self.proj_speed_mod = 1;
+ }
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 80;
+
+ self.th_stand = enf_stand1;
+ self.th_walk = enf_walk1;
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_run = enf_2stand1;
+ }
+ else
+ {
+ self.th_run = enf_run1;
+ }
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = enf_pain;
+ else
+ self.th_pain = SUB_NullPain;
+ self.th_die = enf_die;
+ if (self.style == 1 || self.style == 2 || self.style == 5) // new animation frame check -- dumptruck_ds
+ {
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_turret = enf_2turret_atk1;
+ }
+ self.th_missile = enf_2atk1;
+ }
+ else if (self.style == 0 || self.style == 3 ) // new animation frame check -- dumptruck_ds
+ {
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_turret = enf_turret_atk1;
+ }
+ self.th_missile = enf_atk1;
+ }
+ else if (self.style == 4) // new animation frame check -- dumptruck_ds
+ {
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_turret = enf_4turret_atk1;
+ }
+ self.th_missile = enf_4atk1;
+ }
+ walkmonster_start();
+};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_enforcer (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID FACE_UP X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/enforcer.mdl","frame":54});
+}
+*/
+void() monster_dead_enforcer =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/enforcer.mdl");
+ setmodel(self, "progs/enforcer.mdl");
+ if (self.spawnflags & 2)
+ {
+ self.frame = $fdeath11;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-41.16 -45.65 -51.95','21.45 25.49 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+ else
+ {
+ self.frame = $death14;
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-39.85 -29.35 -49.07','20.52 33.17 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/fish.qc

diff --git a/qc/monsters/fish.qc b/qc/monsters/fish.qc
new file mode 100644
index 0000000..b4aead5
--- /dev/null
+++ b/qc/monsters/fish.qc
@@ -0,0 +1,306 @@
+$cd id1/models/fish
+$origin 0 0 24
+$base base
+$skin skin
+
+$frame attack1 attack2 attack3 attack4 attack5 attack6
+$frame attack7 attack8 attack9 attack10 attack11 attack12 attack13
+$frame attack14 attack15 attack16 attack17 attack18
+
+$frame death1 death2 death3 death4 death5 death6 death7
+$frame death8 death9 death10 death11 death12 death13 death14 death15
+$frame death16 death17 death18 death19 death20 death21
+
+$frame swim1 swim2 swim3 swim4 swim5 swim6 swim7 swim8
+$frame swim9 swim10 swim11 swim12 swim13 swim14 swim15 swim16 swim17
+$frame swim18
+
+$frame pain1 pain2 pain3 pain4 pain5 pain6 pain7 pain8
+$frame pain9
+
+void() swimmonster_start;
+
+void() f_stand1 =[ $swim1, f_stand2 ] {ai_stand();};
+void() f_stand2 =[ $swim2, f_stand3 ] {ai_stand();};
+void() f_stand3 =[ $swim3, f_stand4 ] {ai_stand();};
+void() f_stand4 =[ $swim4, f_stand5 ] {ai_stand();};
+void() f_stand5 =[ $swim5, f_stand6 ] {ai_stand();};
+void() f_stand6 =[ $swim6, f_stand7 ] {ai_stand();};
+void() f_stand7 =[ $swim7, f_stand8 ] {ai_stand();};
+void() f_stand8 =[ $swim8, f_stand9 ] {ai_stand();};
+void() f_stand9 =[ $swim9, f_stand10 ] {ai_stand();};
+void() f_stand10 =[ $swim10, f_stand11 ] {ai_stand();};
+void() f_stand11 =[ $swim11, f_stand12 ] {ai_stand();};
+void() f_stand12 =[ $swim12, f_stand13 ] {ai_stand();};
+void() f_stand13 =[ $swim13, f_stand14 ] {ai_stand();};
+void() f_stand14 =[ $swim14, f_stand15 ] {ai_stand();};
+void() f_stand15 =[ $swim15, f_stand16 ] {ai_stand();};
+void() f_stand16 =[ $swim16, f_stand17 ] {ai_stand();};
+void() f_stand17 =[ $swim17, f_stand18 ] {ai_stand();};
+void() f_stand18 =[ $swim18, f_stand1 ] {ai_stand();};
+
+void() f_walk1 =[ $swim1, f_walk2 ] {ai_walk(8);};
+void() f_walk2 =[ $swim2, f_walk3 ] {ai_walk(8);};
+void() f_walk3 =[ $swim3, f_walk4 ] {ai_walk(8);};
+void() f_walk4 =[ $swim4, f_walk5 ] {ai_walk(8);};
+void() f_walk5 =[ $swim5, f_walk6 ] {ai_walk(8);};
+void() f_walk6 =[ $swim6, f_walk7 ] {ai_walk(8);};
+void() f_walk7 =[ $swim7, f_walk8 ] {ai_walk(8);};
+void() f_walk8 =[ $swim8, f_walk9 ] {ai_walk(8);};
+void() f_walk9 =[ $swim9, f_walk10 ] {ai_walk(8);};
+void() f_walk10 =[ $swim10, f_walk11 ] {ai_walk(8);};
+void() f_walk11 =[ $swim11, f_walk12 ] {ai_walk(8);};
+void() f_walk12 =[ $swim12, f_walk13 ] {ai_walk(8);};
+void() f_walk13 =[ $swim13, f_walk14 ] {ai_walk(8);};
+void() f_walk14 =[ $swim14, f_walk15 ] {ai_walk(8);};
+void() f_walk15 =[ $swim15, f_walk16 ] {ai_walk(8);};
+void() f_walk16 =[ $swim16, f_walk17 ] {ai_walk(8);};
+void() f_walk17 =[ $swim17, f_walk18 ] {ai_walk(8);};
+void() f_walk18 =[ $swim18, f_walk1 ] {ai_walk(8);};
+
+void() f_run1 =[ $swim1, f_run2 ] {ai_run(12);
+ if (random() < 0.5)
+ sound_idle (self, CHAN_VOICE, "fish/idle.wav", 1, ATTN_NORM);
+};
+void() f_run2 =[ $swim3, f_run3 ] {ai_run(12);};
+void() f_run3 =[ $swim5, f_run4 ] {ai_run(12);};
+void() f_run4 =[ $swim7, f_run5 ] {ai_run(12);};
+void() f_run5 =[ $swim9, f_run6 ] {ai_run(12);};
+void() f_run6 =[ $swim11, f_run7 ] {ai_run(12);};
+void() f_run7 =[ $swim13, f_run8 ] {ai_run(12);};
+void() f_run8 =[ $swim15, f_run9 ] {ai_run(12);};
+void() f_run9 =[ $swim17, f_run1 ] {ai_run(12);};
+
+void() fish_melee =
+{
+ local vector delta;
+ local float ldmg;
+
+ if (!self.enemy)
+ return; // removed before stroke
+
+ delta = self.enemy.origin - self.origin;
+
+ if (vlen(delta) > 60)
+ return;
+
+ sound_attack (self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
+ ldmg = (random() + random()) * 3;
+ T_Damage (self.enemy, self, self, ldmg);
+};
+
+void() f_attack1 =[ $attack1, f_attack2 ] {ai_charge(10);};
+void() f_attack2 =[ $attack2, f_attack3 ] {ai_charge(10);};
+void() f_attack3 =[ $attack3, f_attack4 ] {fish_melee();};
+void() f_attack4 =[ $attack4, f_attack5 ] {ai_charge(10);};
+void() f_attack5 =[ $attack5, f_attack6 ] {ai_charge(10);};
+void() f_attack6 =[ $attack6, f_attack7 ] {ai_charge(10);};
+void() f_attack7 =[ $attack7, f_attack8 ] {ai_charge(10);};
+void() f_attack8 =[ $attack8, f_attack9 ] {ai_charge(10);};
+void() f_attack9 =[ $attack9, f_attack10] {fish_melee();};
+void() f_attack10 =[ $attack10, f_attack11] {ai_charge(10);};
+void() f_attack11 =[ $attack11, f_attack12] {ai_charge(10);};
+void() f_attack12 =[ $attack12, f_attack13] {ai_charge(10);};
+void() f_attack13 =[ $attack13, f_attack14] {ai_charge(10);};
+void() f_attack14 =[ $attack14, f_attack15] {ai_charge(10);};
+void() f_attack15 =[ $attack15, f_attack16] {fish_melee();};
+void() f_attack16 =[ $attack16, f_attack17] {ai_charge(10);};
+void() f_attack17 =[ $attack17, f_attack18] {ai_charge(10);};
+void() f_attack18 =[ $attack18, f_run1 ] {ai_charge(10);};
+
+void() f_death1 =[ $death1, f_death2 ]
+ {
+ self.solid = SOLID_NOT;
+ sound_death (self, CHAN_VOICE, "fish/death.wav", 1, ATTN_NORM);
+ };
+void() f_death2 =[ $death2, f_death3 ] {};
+void() f_death3 =[ $death3, f_death4 ] {};
+void() f_death4 =[ $death4, f_death5 ] {};
+void() f_death5 =[ $death5, f_death6 ] {};
+void() f_death6 =[ $death6, f_death7 ] {};
+void() f_death7 =[ $death7, f_death8 ] {};
+void() f_death8 =[ $death8, f_death9 ] {};
+void() f_death9 =[ $death9, f_death10 ] {};
+void() f_death10 =[ $death10, f_death11 ] {};
+void() f_death11 =[ $death11, f_death12 ] {};
+void() f_death12 =[ $death12, f_death13 ] {};
+void() f_death13 =[ $death13, f_death14 ] {};
+void() f_death14 =[ $death14, f_death15 ] {};
+void() f_death15 =[ $death15, f_death16 ] {};
+void() f_death16 =[ $death16, f_death17 ] {};
+void() f_death17 =[ $death17, f_death18 ] {};
+void() f_death18 =[ $death18, f_death19 ] {};
+void() f_death19 =[ $death19, f_death20 ] {};
+void() f_death20 =[ $death20, f_death21 ] {};
+void() f_death21 =[ $death21, f_death21 ] {};
+
+void() fish_die =
+{
+ if (self.health < -35) //fish gibs -- dumptruck_ds
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ if (self.mdl_head != "")
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_dog.mdl", self.health);
+ }
+ DropStuff();
+ SUB_Remove();
+ }
+ // regular death
+ else
+ {
+ DropStuff();
+ f_death1();
+ }
+};
+
+void() f_pain1 =[ $pain1, f_pain2 ] {};
+void() f_pain2 =[ $pain2, f_pain3 ] {ai_pain(6);};
+void() f_pain3 =[ $pain3, f_pain4 ] {ai_pain(6);};
+void() f_pain4 =[ $pain4, f_pain5 ] {ai_pain(6);};
+void() f_pain5 =[ $pain5, f_pain6 ] {ai_pain(6);};
+void() f_pain6 =[ $pain6, f_pain7 ] {ai_pain(6);};
+void() f_pain7 =[ $pain7, f_pain8 ] {ai_pain(6);};
+void() f_pain8 =[ $pain8, f_pain9 ] {ai_pain(6);};
+void() f_pain9 =[ $pain9, f_run1 ] {ai_pain(6);};
+
+void(entity attacker, float damage) fish_pain =
+{
+// fish always do pain frames
+ f_pain1 ();
+};
+
+
+
+/*QUAKED monster_fish (1 0 0) (-16 -16 -24) (16 16 24) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/fish.mdl");
+}
+Rotfish.
+
+Default health = 25"
+
+snd_death(string) : "Path to custom death sound (BUBBLES)"
+snd_attack(string) : "Path to custom attack sound (CRUNCHY BITE)"
+snd_idle(string) : "Path to custom idle sound"
+
+mdl_body(string) : "Path to custom body model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_fish =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ objerror("Incompatible spawnflag: TURRET_MODE\n");
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ precache_body_model2 ("progs/fish.mdl");
+ // precache_model2 ("progs/fish.mdl");
+
+ precache_sound2_death ("fish/death.wav");
+ precache_sound2_attack ("fish/bite.wav");
+ precache_sound2_idle ("fish/idle.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/fish.mdl");
+ // setmodel (self, "progs/fish.mdl");
+
+ setsize (self, '-16 -16 -24', '16 16 24');
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 25;
+
+ self.th_stand = f_stand1;
+ self.th_walk = f_walk1;
+ self.th_run = f_run1;
+ // self.th_die = f_death1;
+ self.th_die = fish_die;
+ if !(self.berserk) //Berserk from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = fish_pain;
+ else
+ self.th_pain = SUB_NullPain;
+ self.th_melee = f_attack1;
+
+ swimmonster_start ();
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/hknight.qc

diff --git a/qc/monsters/hknight.qc b/qc/monsters/hknight.qc
new file mode 100644
index 0000000..10aa2a3
--- /dev/null
+++ b/qc/monsters/hknight.qc
@@ -0,0 +1,755 @@
+/*
+==============================================================================
+
+KNIGHT
+
+==============================================================================
+*/
+
+$cd id1/models/knight2
+$origin 0 0 24
+$base base
+$skin skin
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9
+$frame walk10 walk11 walk12 walk13 walk14 walk15 walk16 walk17
+$frame walk18 walk19 walk20
+
+$frame run1 run2 run3 run4 run5 run6 run7 run8
+
+$frame pain1 pain2 pain3 pain4 pain5
+
+$frame death1 death2 death3 death4 death5 death6 death7 death8
+$frame death9 death10 death11 death12
+
+$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
+$frame deathb9
+
+$frame char_a1 char_a2 char_a3 char_a4 char_a5 char_a6 char_a7 char_a8
+$frame char_a9 char_a10 char_a11 char_a12 char_a13 char_a14 char_a15 char_a16
+
+$frame magica1 magica2 magica3 magica4 magica5 magica6 magica7 magica8
+$frame magica9 magica10 magica11 magica12 magica13 magica14
+
+$frame magicb1 magicb2 magicb3 magicb4 magicb5 magicb6 magicb7 magicb8
+$frame magicb9 magicb10 magicb11 magicb12 magicb13
+
+$frame char_b1 char_b2 char_b3 char_b4 char_b5 char_b6
+
+$frame slice1 slice2 slice3 slice4 slice5 slice6 slice7 slice8 slice9 slice10
+
+$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 smash8 smash9 smash10
+$frame smash11
+
+$frame w_attack1 w_attack2 w_attack3 w_attack4 w_attack5 w_attack6 w_attack7
+$frame w_attack8 w_attack9 w_attack10 w_attack11 w_attack12 w_attack13 w_attack14
+$frame w_attack15 w_attack16 w_attack17 w_attack18 w_attack19 w_attack20
+$frame w_attack21 w_attack22
+
+$frame magicc1 magicc2 magicc3 magicc4 magicc5 magicc6 magicc7 magicc8
+$frame magicc9 magicc10 magicc11
+
+
+void() hknight_char_a1;
+void() hknight_run1;
+void() hk_idle_sound;
+
+void(float offset) hknight_shot =
+{
+ local vector offang;
+ local vector org, vec;
+ local float exploding = self.projexpl == 1 || (self.projexpl == 2 && offset % 2 == 0) || (self.projexpl == 3 && random()*2 < 1);
+ offang = vectoangles (self.enemy.origin - self.origin);
+ offang_y = offang_y + offset * 6;
+
+ makevectors (offang);
+
+ org = self.origin + self.mins + self.size*0.5 + v_forward * 20;
+
+// set missile speed
+ vec = normalize (v_forward);
+ vec_z = 0 - vec_z + (random() - 0.5)*0.1;
+
+ launch_spike2 (org, vec, 300);
+ newmis.classname = "knightspike";
+ // setmodel (newmis, "progs/k_spike.mdl");
+ if (exploding)
+ {
+ newmis.touch = T_HellKnightMisTouch;
+ if (self.mdl_exproj != "") // dumptruck_ds custom_mdls
+ {
+ setmodel (newmis, self.mdl_exproj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/k_spike2.mdl");
+ }
+
+ if (self.skin_exproj) // dumptruck_ds
+ {
+ newmis.skin = self.skin_exproj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+ }
+ else
+ {
+ if (self.mdl_proj != "") // dumptruck_ds custom_mdls
+ {
+ setmodel (newmis, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/k_spike.mdl");
+ }
+
+ if (self.skin_proj) // dumptruck_ds
+ {
+ newmis.skin = self.skin_proj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+ }
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ sound_attack (self, CHAN_WEAPON, "hknight/attack1.wav", 1, ATTN_NORM);
+};
+
+void() CheckForCharge =
+{
+// check for mad charge
+if (!enemy_vis)
+ return;
+if (time < self.attack_finished)
+ return;
+if ( fabs(self.origin_z - self.enemy.origin_z) > 20)
+ return; // too much height change
+if ( vlen (self.origin - self.enemy.origin) < 80)
+ return; // use regular attack
+
+// charge
+ SUB_AttackFinished (2);
+ hknight_char_a1 ();
+
+};
+
+void() CheckContinueCharge =
+{
+ if (time > self.attack_finished)
+ {
+ SUB_AttackFinished (3);
+ hknight_run1 ();
+ return; // done charging
+ }
+ if (random() > 0.5)
+ sound (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM);
+ else
+ sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
+};
+
+//===========================================================================
+
+void() hknight_stand1 =[ $stand1, hknight_stand2 ] {ai_stand();};
+void() hknight_stand2 =[ $stand2, hknight_stand3 ] {ai_stand();};
+void() hknight_stand3 =[ $stand3, hknight_stand4 ] {ai_stand();};
+void() hknight_stand4 =[ $stand4, hknight_stand5 ] {ai_stand();};
+void() hknight_stand5 =[ $stand5, hknight_stand6 ] {ai_stand();};
+void() hknight_stand6 =[ $stand6, hknight_stand7 ] {ai_stand();};
+void() hknight_stand7 =[ $stand7, hknight_stand8 ] {ai_stand();};
+void() hknight_stand8 =[ $stand8, hknight_stand9 ] {ai_stand();};
+void() hknight_stand9 =[ $stand9, hknight_stand1 ] {ai_stand();};
+
+//===========================================================================
+
+void() hknight_walk1 =[ $walk1, hknight_walk2 ] {
+hk_idle_sound();
+ai_walk(2);};
+void() hknight_walk2 =[ $walk2, hknight_walk3 ] {ai_walk(5);};
+void() hknight_walk3 =[ $walk3, hknight_walk4 ] {ai_walk(5);};
+void() hknight_walk4 =[ $walk4, hknight_walk5 ] {ai_walk(4);};
+void() hknight_walk5 =[ $walk5, hknight_walk6 ] {ai_walk(4);};
+void() hknight_walk6 =[ $walk6, hknight_walk7 ] {ai_walk(2);};
+void() hknight_walk7 =[ $walk7, hknight_walk8 ] {ai_walk(2);};
+void() hknight_walk8 =[ $walk8, hknight_walk9 ] {ai_walk(3);};
+void() hknight_walk9 =[ $walk9, hknight_walk10 ] {ai_walk(3);};
+void() hknight_walk10 =[ $walk10, hknight_walk11 ] {ai_walk(4);};
+void() hknight_walk11 =[ $walk11, hknight_walk12 ] {ai_walk(3);};
+void() hknight_walk12 =[ $walk12, hknight_walk13 ] {ai_walk(4);};
+void() hknight_walk13 =[ $walk13, hknight_walk14 ] {ai_walk(6);};
+void() hknight_walk14 =[ $walk14, hknight_walk15 ] {ai_walk(2);};
+void() hknight_walk15 =[ $walk15, hknight_walk16 ] {ai_walk(2);};
+void() hknight_walk16 =[ $walk16, hknight_walk17 ] {ai_walk(4);};
+void() hknight_walk17 =[ $walk17, hknight_walk18 ] {ai_walk(3);};
+void() hknight_walk18 =[ $walk18, hknight_walk19 ] {ai_walk(3);};
+void() hknight_walk19 =[ $walk19, hknight_walk20 ] {ai_walk(3);};
+void() hknight_walk20 =[ $walk20, hknight_walk1 ] {ai_walk(2);};
+
+//===========================================================================
+
+void() hknight_run1 =[ $run1, hknight_run2 ] {
+hk_idle_sound();
+ai_run (20); CheckForCharge (); };
+void() hknight_run2 =[ $run2, hknight_run3 ] {ai_run(25);};
+void() hknight_run3 =[ $run3, hknight_run4 ] {ai_run(18);};
+void() hknight_run4 =[ $run4, hknight_run5 ] {ai_run(16);};
+void() hknight_run5 =[ $run5, hknight_run6 ] {ai_run(14);};
+void() hknight_run6 =[ $run6, hknight_run7 ] {ai_run(25);};
+void() hknight_run7 =[ $run7, hknight_run8 ] {ai_run(21);};
+void() hknight_run8 =[ $run8, hknight_run1 ] {ai_run(13);};
+
+//============================================================================
+
+void() hknight_pain1 =[ $pain1, hknight_pain2 ] {sound_pain (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);};
+void() hknight_pain2 =[ $pain2, hknight_pain3 ] {};
+void() hknight_pain3 =[ $pain3, hknight_pain4 ] {};
+void() hknight_pain4 =[ $pain4, hknight_pain5 ] {};
+void() hknight_pain5 =[ $pain5, hknight_run1 ] {};
+
+//============================================================================
+
+void() hknight_die1 =[ $death1, hknight_die2 ] {ai_forward(10);};
+void() hknight_die2 =[ $death2, hknight_die3 ] {ai_forward(8);};
+void() hknight_die3 =[ $death3, hknight_die4 ]{self.solid = SOLID_NOT;ai_forward(7);};
+void() hknight_die4 =[ $death4, hknight_die5 ] {};
+void() hknight_die5 =[ $death5, hknight_die6 ] {};
+void() hknight_die6 =[ $death6, hknight_die7 ] {};
+void() hknight_die7 =[ $death7, hknight_die8 ] {};
+void() hknight_die8 =[ $death8, hknight_die9 ] {ai_forward(10);};
+void() hknight_die9 =[ $death9, hknight_die10 ] {ai_forward(11);};
+void() hknight_die10 =[ $death10, hknight_die11 ] {};
+void() hknight_die11 =[ $death11, hknight_die12 ] {};
+void() hknight_die12 =[ $death12, hknight_die12 ] {};
+
+void() hknight_dieb1 =[ $deathb1, hknight_dieb2 ] {};
+void() hknight_dieb2 =[ $deathb2, hknight_dieb3 ] {};
+void() hknight_dieb3 =[ $deathb3, hknight_dieb4 ] {self.solid = SOLID_NOT;};
+void() hknight_dieb4 =[ $deathb4, hknight_dieb5 ] {};
+void() hknight_dieb5 =[ $deathb5, hknight_dieb6 ] {};
+void() hknight_dieb6 =[ $deathb6, hknight_dieb7 ] {};
+void() hknight_dieb7 =[ $deathb7, hknight_dieb8 ] {};
+void() hknight_dieb8 =[ $deathb8, hknight_dieb9 ] {};
+void() hknight_dieb9 =[ $deathb9, hknight_dieb9 ] {};
+
+void() hknight_die =
+{
+// check for gib
+ if (self.health < -40)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_hellkn.mdl", self.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+
+// regular death
+ sound_death (self, CHAN_VOICE, "hknight/death1.wav", 1, ATTN_NORM);
+ DropStuff();
+ if (random() > 0.5)
+ hknight_die1 ();
+ else
+ hknight_dieb1 ();
+};
+
+
+//============================================================================
+
+void() hknight_magica1 =[ $magica1, hknight_magica2 ] {ai_face();};
+void() hknight_magica2 =[ $magica2, hknight_magica3 ] {ai_face();};
+void() hknight_magica3 =[ $magica3, hknight_magica4 ] {ai_face();};
+void() hknight_magica4 =[ $magica4, hknight_magica5 ] {ai_face();};
+void() hknight_magica5 =[ $magica5, hknight_magica6 ] {ai_face();};
+void() hknight_magica6 =[ $magica6, hknight_magica7 ] {ai_face();};
+void() hknight_magica7 =[ $magica7, hknight_magica8 ] {hknight_shot(-2);};
+void() hknight_magica8 =[ $magica8, hknight_magica9 ] {hknight_shot(-1);};
+void() hknight_magica9 =[ $magica9, hknight_magica10] {hknight_shot(0);};
+void() hknight_magica10 =[ $magica10, hknight_magica11] {hknight_shot(1);};
+void() hknight_magica11 =[ $magica11, hknight_magica12] {hknight_shot(2);};
+void() hknight_magica12 =[ $magica12, hknight_magica13] {hknight_shot(3);};
+void() hknight_magica13 =[ $magica13, hknight_magica14] {ai_face();};
+void() hknight_magica14 =[ $magica14, hknight_run1 ] {ai_face();};
+
+//============================================================================
+
+void() HellKnightLightning =
+{
+ local vector org, dir;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ sound_attack(self, CHAN_WEAPON, "weapons/lstart.wav", 1, ATTN_NORM);
+ ai_face ();
+ makevectors (self.angles);
+ org = self.origin + v_forward * 50 + '0 0 20';
+
+ dir = self.enemy.origin - self.enemy.velocity * 0.075;
+ dir = normalize (dir - org + '0 0 16');
+
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ traceline (org, self.origin + dir*900, TRUE, self);
+ }
+ else
+ {
+ traceline (org, self.origin + dir*600, TRUE, self);
+ }
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
+ WriteEntity (MSG_BROADCAST, self);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
+ WriteCoord (MSG_BROADCAST, trace_endpos_x);
+ WriteCoord (MSG_BROADCAST, trace_endpos_y);
+ WriteCoord (MSG_BROADCAST, trace_endpos_z);
+
+ LightningDamage (org, trace_endpos, self, 20);
+};
+void() hknight_magicb1 =[ $magicb1, hknight_magicb2 ] {ai_face();};
+void() hknight_magicb2 =[ $magicb2, hknight_magicb3 ] {ai_face();};
+void() hknight_magicb3 =[ $magicb3, hknight_magicb4 ] {ai_face();};
+void() hknight_magicb4 =[ $magicb4, hknight_magicb5 ] {ai_face();};
+void() hknight_magicb5 =[ $magicb5, hknight_magicb6 ] {ai_face();};
+void() hknight_magicb6 =[ $magicb6, hknight_magicb7 ] {ai_face();};
+void() hknight_magicb7 =[ $magicb7, hknight_magicb8 ] {ai_face();};
+void() hknight_magicb8 =[ $magicb8, hknight_magicb9 ] {ai_face();};
+void() hknight_magicb9 =[ $magicb9, hknight_magicb10] {ai_face();};
+void() hknight_magicb10 =[ $magicb10, hknight_magicb11] {ai_face();sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);HellKnightLightning();};
+void() hknight_magicb11 =[ $magicb11, hknight_magicb12] {ai_face();};
+void() hknight_magicb12 =[ $magicb12, hknight_magicb13] {ai_face();};
+void() hknight_magicb13 =[ $magicb13, hknight_run1] {ai_face();};
+
+//============================================================================
+
+void() hknight_magicc1 =[ $magicc1, hknight_magicc2 ] {ai_face();};
+void() hknight_magicc2 =[ $magicc2, hknight_magicc3 ] {ai_face();};
+void() hknight_magicc3 =[ $magicc3, hknight_magicc4 ] {ai_face();};
+void() hknight_magicc4 =[ $magicc4, hknight_magicc5 ] {ai_face();};
+void() hknight_magicc5 =[ $magicc5, hknight_magicc6 ] {ai_face();};
+void() hknight_magicc6 =[ $magicc6, hknight_magicc7 ] {hknight_shot(-2);};
+void() hknight_magicc7 =[ $magicc7, hknight_magicc8 ] {hknight_shot(-1);};
+void() hknight_magicc8 =[ $magicc8, hknight_magicc9 ] {hknight_shot(0);};
+void() hknight_magicc9 =[ $magicc9, hknight_magicc10] {hknight_shot(1);};
+void() hknight_magicc10 =[ $magicc10, hknight_magicc11] {hknight_shot(2);};
+void() hknight_magicc11 =[ $magicc11, hknight_run1] {hknight_shot(3);};
+
+//============================================================================
+///////////////////////////////////////
+////// turret frames START - revisions
+//////////////////////////////////////
+void() hknight_turret_magicc1 =[ $magicc1, hknight_turret_magicc2 ] {ai_face();};
+void() hknight_turret_magicc2 =[ $magicc2, hknight_turret_magicc3 ] {ai_face();};
+void() hknight_turret_magicc3 =[ $magicc3, hknight_turret_magicc4 ] {ai_face();};
+void() hknight_turret_magicc4 =[ $magicc4, hknight_turret_magicc5 ] {ai_face();};
+void() hknight_turret_magicc5 =[ $magicc5, hknight_turret_magicc6 ] {ai_face();};
+void() hknight_turret_magicc6 =[ $magicc6, hknight_turret_magicc7 ] {hknight_shot(-2);};
+void() hknight_turret_magicc7 =[ $magicc7, hknight_turret_magicc8 ] {hknight_shot(-1);};
+void() hknight_turret_magicc8 =[ $magicc8, hknight_turret_magicc9 ] {hknight_shot(0);};
+void() hknight_turret_magicc9 =[ $magicc9, hknight_turret_magicc10] {hknight_shot(1);};
+void() hknight_turret_magicc10 =[ $magicc10, hknight_turret_magicc11] {hknight_shot(2);};
+void() hknight_turret_magicc11 =[ $magicc11, hknight_turret_magicc12] {ai_face();};
+void() hknight_turret_magicc12 =[ $stand1, hknight_turret_magicc13 ] {ai_face();};
+void() hknight_turret_magicc13 =[ $stand2, hknight_turret_magicc14 ] {ai_face();};
+void() hknight_turret_magicc14 =[ $stand3, hknight_turret_magicc15 ] {ai_face();};
+void() hknight_turret_magicc15 =[ $stand4, hknight_seek_stand1 ] {ai_run(0);};
+void() hknight_seek_stand1 =[ $stand1, hknight_seek_stand2 ] {ai_run(0);};
+void() hknight_seek_stand2 =[ $stand2, hknight_seek_stand3 ] {ai_run(0);};
+void() hknight_seek_stand3 =[ $stand3, hknight_seek_stand4 ] {ai_run(0);};
+void() hknight_seek_stand4 =[ $stand4, hknight_seek_stand5 ] {ai_run(0);};
+void() hknight_seek_stand5 =[ $stand5, hknight_seek_stand6 ] {ai_run(0);};
+void() hknight_seek_stand6 =[ $stand6, hknight_seek_stand7 ] {ai_run(0);};
+void() hknight_seek_stand7 =[ $stand7, hknight_seek_stand8 ] {ai_run(0);};
+void() hknight_seek_stand8 =[ $stand8, hknight_seek_stand9 ] {ai_run(0);};
+void() hknight_seek_stand9 =[ $stand9, hknight_seek_stand1 ] {ai_run(0);};
+
+void() hknight_turret_magicb1 =[ $magicb1, hknight_turret_magicb2 ] {ai_face();};
+void() hknight_turret_magicb2 =[ $magicb2, hknight_turret_magicb3 ] {ai_face();};
+void() hknight_turret_magicb3 =[ $magicb3, hknight_turret_magicb4 ] {ai_face();};
+void() hknight_turret_magicb4 =[ $magicb4, hknight_turret_magicb5 ] {ai_face();};
+void() hknight_turret_magicb5 =[ $magicb5, hknight_turret_magicb6 ] {ai_face();};
+void() hknight_turret_magicb6 =[ $magicb6, hknight_turret_magicb7 ] {ai_face();};
+void() hknight_turret_magicb7 =[ $magicb7, hknight_turret_magicb8 ] {ai_face();};
+void() hknight_turret_magicb8 =[ $magicb8, hknight_turret_magicb9 ] {ai_face();};
+void() hknight_turret_magicb9 =[ $magicb9, hknight_turret_magicb10] {ai_face();};
+void() hknight_turret_magicb10 =[ $magicb10, hknight_turret_magicb11] {ai_face();sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);HellKnightLightning();};
+void() hknight_turret_magicb11 =[ $magicb11, hknight_turret_magicb12] {ai_face();};
+void() hknight_turret_magicb12 =[ $magicb12, hknight_turret_magicb13] {ai_face();};
+void() hknight_turret_magicb13 =[ $magicb13, hknight_seek_stand1] {ai_face();};
+/////////////////////////
+////// turret frames END
+/////////////////////////
+
+//===========================================================================
+
+void() hknight_char_a1 =[ $char_a1, hknight_char_a2 ] {ai_charge(20);};
+void() hknight_char_a2 =[ $char_a2, hknight_char_a3 ] {ai_charge(25);};
+void() hknight_char_a3 =[ $char_a3, hknight_char_a4 ] {ai_charge(18);};
+void() hknight_char_a4 =[ $char_a4, hknight_char_a5 ] {ai_charge(16);};
+void() hknight_char_a5 =[ $char_a5, hknight_char_a6 ] {ai_charge(14);};
+void() hknight_char_a6 =[ $char_a6, hknight_char_a7 ] {ai_charge(20); ai_melee();};
+void() hknight_char_a7 =[ $char_a7, hknight_char_a8 ] {ai_charge(21); ai_melee();};
+void() hknight_char_a8 =[ $char_a8, hknight_char_a9 ] {ai_charge(13); ai_melee();};
+void() hknight_char_a9 =[ $char_a9, hknight_char_a10 ] {ai_charge(20); ai_melee();};
+void() hknight_char_a10=[ $char_a10, hknight_char_a11 ] {ai_charge(20); ai_melee();};
+void() hknight_char_a11=[ $char_a11, hknight_char_a12 ] {ai_charge(18); ai_melee();};
+void() hknight_char_a12=[ $char_a12, hknight_char_a13 ] {ai_charge(16);};
+void() hknight_char_a13=[ $char_a13, hknight_char_a14 ] {ai_charge(14);};
+void() hknight_char_a14=[ $char_a14, hknight_char_a15 ] {ai_charge(25);};
+void() hknight_char_a15=[ $char_a15, hknight_char_a16 ] {ai_charge(21);};
+void() hknight_char_a16=[ $char_a16, hknight_run1 ] {ai_charge(13);};
+
+//===========================================================================
+
+void() hknight_char_b1 =[ $char_b1, hknight_char_b2 ]
+{CheckContinueCharge (); ai_charge(23); ai_melee();};
+void() hknight_char_b2 =[ $char_b2, hknight_char_b3 ] {ai_charge(17); ai_melee();};
+void() hknight_char_b3 =[ $char_b3, hknight_char_b4 ] {ai_charge(12); ai_melee();};
+void() hknight_char_b4 =[ $char_b4, hknight_char_b5 ] {ai_charge(22); ai_melee();};
+void() hknight_char_b5 =[ $char_b5, hknight_char_b6 ] {ai_charge(18); ai_melee();};
+void() hknight_char_b6 =[ $char_b6, hknight_char_b1 ] {ai_charge(8); ai_melee();};
+
+//===========================================================================
+
+void() hknight_slice1 =[ $slice1, hknight_slice2 ] {ai_charge(9);};
+void() hknight_slice2 =[ $slice2, hknight_slice3 ] {ai_charge(6);};
+void() hknight_slice3 =[ $slice3, hknight_slice4 ] {ai_charge(13);};
+void() hknight_slice4 =[ $slice4, hknight_slice5 ] {ai_charge(4);};
+void() hknight_slice5 =[ $slice5, hknight_slice6 ] {ai_charge(7); ai_melee();};
+void() hknight_slice6 =[ $slice6, hknight_slice7 ] {ai_charge(15); ai_melee();};
+void() hknight_slice7 =[ $slice7, hknight_slice8 ] {ai_charge(8); ai_melee();};
+void() hknight_slice8 =[ $slice8, hknight_slice9 ] {ai_charge(2); ai_melee();};
+void() hknight_slice9 =[ $slice9, hknight_slice10 ] {ai_melee();};
+void() hknight_slice10 =[ $slice10, hknight_run1 ] {ai_charge(3);};
+
+//===========================================================================
+
+void() hknight_smash1 =[ $smash1, hknight_smash2 ] {ai_charge(1);};
+void() hknight_smash2 =[ $smash2, hknight_smash3 ] {ai_charge(13);};
+void() hknight_smash3 =[ $smash3, hknight_smash4 ] {ai_charge(9);};
+void() hknight_smash4 =[ $smash4, hknight_smash5 ] {ai_charge(11);};
+void() hknight_smash5 =[ $smash5, hknight_smash6 ] {ai_charge(10); ai_melee();};
+void() hknight_smash6 =[ $smash6, hknight_smash7 ] {ai_charge(7); ai_melee();};
+void() hknight_smash7 =[ $smash7, hknight_smash8 ] {ai_charge(12); ai_melee();};
+void() hknight_smash8 =[ $smash8, hknight_smash9 ] {ai_charge(2); ai_melee();};
+void() hknight_smash9 =[ $smash9, hknight_smash10 ] {ai_charge(3); ai_melee();};
+void() hknight_smash10 =[ $smash10, hknight_smash11 ] {ai_charge(0);};
+void() hknight_smash11 =[ $smash11, hknight_run1 ] {ai_charge(0);};
+
+//============================================================================
+
+void() hknight_watk1 =[ $w_attack1, hknight_watk2 ] {ai_charge(2);};
+void() hknight_watk2 =[ $w_attack2, hknight_watk3 ] {ai_charge(0);};
+void() hknight_watk3 =[ $w_attack3, hknight_watk4 ] {ai_charge(0);};
+void() hknight_watk4 =[ $w_attack4, hknight_watk5 ] {ai_melee();};
+void() hknight_watk5 =[ $w_attack5, hknight_watk6 ] {ai_melee();};
+void() hknight_watk6 =[ $w_attack6, hknight_watk7 ] {ai_melee();};
+void() hknight_watk7 =[ $w_attack7, hknight_watk8 ] {ai_charge(1);};
+void() hknight_watk8 =[ $w_attack8, hknight_watk9 ] {ai_charge(4);};
+void() hknight_watk9 =[ $w_attack9, hknight_watk10 ] {ai_charge(5);};
+void() hknight_watk10 =[ $w_attack10, hknight_watk11 ] {ai_charge(3); ai_melee();};
+void() hknight_watk11 =[ $w_attack11, hknight_watk12 ] {ai_charge(2); ai_melee();};
+void() hknight_watk12 =[ $w_attack12, hknight_watk13 ] {ai_charge(2); ai_melee();};
+void() hknight_watk13 =[ $w_attack13, hknight_watk14 ] {ai_charge(0);};
+void() hknight_watk14 =[ $w_attack14, hknight_watk15 ] {ai_charge(0);};
+void() hknight_watk15 =[ $w_attack15, hknight_watk16 ] {ai_charge(0);};
+void() hknight_watk16 =[ $w_attack16, hknight_watk17 ] {ai_charge(1);};
+void() hknight_watk17 =[ $w_attack17, hknight_watk18 ] {ai_charge(1); ai_melee();};
+void() hknight_watk18 =[ $w_attack18, hknight_watk19 ] {ai_charge(3); ai_melee();};
+void() hknight_watk19 =[ $w_attack19, hknight_watk20 ] {ai_charge(4); ai_melee();};
+void() hknight_watk20 =[ $w_attack20, hknight_watk21 ] {ai_charge(6);};
+void() hknight_watk21 =[ $w_attack21, hknight_watk22 ] {ai_charge(7);};
+void() hknight_watk22 =[ $w_attack22, hknight_run1 ] {ai_charge(3);};
+
+//============================================================================
+
+void() hk_idle_sound =
+{
+ if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "hknight/idle.wav", 1, ATTN_NORM);
+};
+
+void(entity attacker, float damage) hknight_pain =
+{
+ local float r;
+
+ r = random();
+
+ if (self.pain_finished > time)
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ if (r < 0.5)
+ {
+ self.pain_finished = time + 1.5;
+ sound_pain (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);
+ }
+ return;
+ }
+
+ sound_pain (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);
+
+ if (time - self.pain_finished > 5)
+ { // always go into pain frame if it has been a while
+ hknight_pain1 ();
+ self.pain_finished = time + 1;
+ return;
+ }
+
+ if ((random()*30 > damage) )
+ return; // didn't flinch
+
+ self.pain_finished = time + 1;
+ hknight_pain1 ();
+};
+
+float hknight_type;
+
+void() hknight_melee =
+{
+ hknight_type = hknight_type + 1;
+
+ sound_misc (self, CHAN_WEAPON, "hknight/slash1.wav", 1, ATTN_NORM);
+ if (hknight_type == 1)
+ hknight_slice1 ();
+ else if (hknight_type == 2)
+ hknight_smash1 ();
+ else if (hknight_type == 3)
+ {
+ hknight_watk1 ();
+ hknight_type = 0;
+ }
+};
+
+/*QUAKED monster_hell_knight (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/hknight.mdl");
+}
+Hellknight.
+
+Default health = 250"
+
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound (MAGIC BOING)"
+snd_idle(string) : Path to custom idle sound"
+snd_misc(string) : Path to custom SWORD SLASH sound"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+mdl_proj(string) : "Path to custom projectile model"
+mdl_exproj(string) : "Path to custom projectile model for exploding projectiles"
+skin_head(float) : "Skin index of custom head model"
+skin_proj(float) : "Skin index of custom projectile model"
+skin_exproj(float) : "Skin index of custom projectile model for exploding projectiles"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+projexpl(choices) : "Exploding projectiles"
+0 : "No explosions"
+1 : "All projectiles explode"
+2 : "Every other projectile explodes"
+3 : "Random per projectile"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_hell_knight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+
+ precache_model2 ("progs/hknight.mdl");
+ precache_model2 ("progs/k_spike.mdl");
+ precache_model2 ("progs/k_spike2.mdl");
+ precache_model2 ("progs/h_hellkn.mdl");
+ //dumptruck_ds custom_mdls
+ precache_body_model2 ("progs/hknight.mdl");
+ precache_head_model2 ("progs/h_hellkn.mdl");
+ precache_proj_model2 ("progs/k_spike.mdl");
+ precache_exproj_model2 ("progs/k_spike2.mdl"); // this needed a unique name defiined in custom_mdls.qc -- dumptruck_ds
+// dumptruck_ds
+
+ precache_sound2_attack ("hknight/attack1.wav");
+ precache_sound2_death ("hknight/death1.wav");
+ precache_sound2_pain ("hknight/pain1.wav");
+ precache_sound2_sight ("hknight/sight1.wav");
+ precache_sound ("hknight/hit.wav"); // used by C code, so don't sound2
+ precache_sound2_misc ("hknight/slash1.wav");
+ precache_sound2_idle ("hknight/idle.wav");
+ precache_sound2 ("hknight/grunt.wav"); // what??? never knew about this! -- dumptruck_ds
+
+ precache_sound ("knight/sword1.wav");
+ precache_sound ("knight/sword2.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/hknight.mdl"); // custom_mdls dumptruck_ds
+ // setmodel (self, "progs/hknight.mdl");
+
+ setsize (self, '-16 -16 -24', '16 16 40');
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 250;
+
+ if (!self.proj_speed_mod)
+ {
+ self.proj_speed_mod = 1;
+ }
+
+ self.th_stand = hknight_stand1;
+ self.th_walk = hknight_walk1;
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_run = hknight_seek_stand1;
+ }
+ else
+ {
+ self.th_run = hknight_run1;
+ }
+ self.th_melee = hknight_melee;
+ if (self.style == 1)
+ {
+ self.th_missile = hknight_magicb1;
+ self.th_turret = hknight_turret_magicb1;
+ }
+ else
+ {
+ self.th_missile = hknight_magicc1;
+ self.th_turret = hknight_turret_magicc1;
+ }
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = hknight_pain;
+ else
+ self.th_pain = SUB_NullPain;
+ self.th_die = hknight_die;
+
+ walkmonster_start ();
+};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_hell_knight (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/hknight.mdl","frame":62});
+}
+*/
+void() monster_dead_hell_knight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/hknight.mdl");
+ setmodel(self, "progs/hknight.mdl");
+ if (self.spawnflags & 2)
+ {
+ self.frame = $deathb9;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-68.96 -20.43 -53.98','34.8 21.15 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+ else
+ {
+ self.frame = $death12;
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-42.05 -31.07 -51.56','46.34 25.02 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/knight.qc

diff --git a/qc/monsters/knight.qc b/qc/monsters/knight.qc
new file mode 100644
index 0000000..bdfbb0e
--- /dev/null
+++ b/qc/monsters/knight.qc
@@ -0,0 +1,418 @@
+/*
+==============================================================================
+
+KNIGHT
+
+==============================================================================
+*/
+
+$cd id1/models/knight
+$origin 0 0 24
+$base base
+$skin badass3
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
+
+$frame runb1 runb2 runb3 runb4 runb5 runb6 runb7 runb8
+
+//frame runc1 runc2 runc3 runc4 runc5 runc6
+
+$frame runattack1 runattack2 runattack3 runattack4 runattack5
+$frame runattack6 runattack7 runattack8 runattack9 runattack10
+$frame runattack11
+
+$frame pain1 pain2 pain3
+
+$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9
+$frame painb10 painb11
+
+//frame attack1 attack2 attack3 attack4 attack5 attack6 attack7
+//frame attack8 attack9 attack10 attack11
+
+$frame attackdummy
+$frame attackb1 attackb2 attackb3 attackb4 attackb5
+$frame attackb6 attackb7 attackb8 attackb9 attackb10
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9
+$frame walk10 walk11 walk12 walk13 walk14
+
+$frame kneel1 kneel2 kneel3 kneel4 kneel5
+
+$frame standing2 standing3 standing4 standing5
+
+$frame death1 death2 death3 death4 death5 death6 death7 death8
+$frame death9 death10
+
+$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
+$frame deathb9 deathb10 deathb11
+
+void() knight_stand1 =[ $stand1, knight_stand2 ] {ai_stand();};
+void() knight_stand2 =[ $stand2, knight_stand3 ] {ai_stand();};
+void() knight_stand3 =[ $stand3, knight_stand4 ] {ai_stand();};
+void() knight_stand4 =[ $stand4, knight_stand5 ] {ai_stand();};
+void() knight_stand5 =[ $stand5, knight_stand6 ] {ai_stand();};
+void() knight_stand6 =[ $stand6, knight_stand7 ] {ai_stand();};
+void() knight_stand7 =[ $stand7, knight_stand8 ] {ai_stand();};
+void() knight_stand8 =[ $stand8, knight_stand9 ] {ai_stand();};
+void() knight_stand9 =[ $stand9, knight_stand1 ] {ai_stand();};
+
+void() knight_walk1 =[ $walk1, knight_walk2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE);
+ai_walk(3);};
+void() knight_walk2 =[ $walk2, knight_walk3 ] {ai_walk(2);};
+void() knight_walk3 =[ $walk3, knight_walk4 ] {ai_walk(3);};
+void() knight_walk4 =[ $walk4, knight_walk5 ] {ai_walk(4);};
+void() knight_walk5 =[ $walk5, knight_walk6 ] {ai_walk(3);};
+void() knight_walk6 =[ $walk6, knight_walk7 ] {ai_walk(3);};
+void() knight_walk7 =[ $walk7, knight_walk8 ] {ai_walk(3);};
+void() knight_walk8 =[ $walk8, knight_walk9 ] {ai_walk(4);};
+void() knight_walk9 =[ $walk9, knight_walk10 ] {ai_walk(3);};
+void() knight_walk10 =[ $walk10, knight_walk11 ] {ai_walk(3);};
+void() knight_walk11 =[ $walk11, knight_walk12 ] {ai_walk(2);};
+void() knight_walk12 =[ $walk12, knight_walk13 ] {ai_walk(3);};
+void() knight_walk13 =[ $walk13, knight_walk14 ] {ai_walk(4);};
+void() knight_walk14 =[ $walk14, knight_walk1 ] {ai_walk(3);};
+
+
+void() knight_run1 =[ $runb1, knight_run2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE);
+ai_run(16);};
+void() knight_run2 =[ $runb2, knight_run3 ] {ai_run(20);};
+void() knight_run3 =[ $runb3, knight_run4 ] {ai_run(13);};
+void() knight_run4 =[ $runb4, knight_run5 ] {ai_run(7);};
+void() knight_run5 =[ $runb5, knight_run6 ] {ai_run(16);};
+void() knight_run6 =[ $runb6, knight_run7 ] {ai_run(20);};
+void() knight_run7 =[ $runb7, knight_run8 ] {ai_run(14);};
+void() knight_run8 =[ $runb8, knight_run1 ] {ai_run(6);};
+
+
+void() knight_runatk1 =[ $runattack1, knight_runatk2 ]
+{
+if (random() > 0.5)
+ sound_misc (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM);
+else
+ sound_attack(self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
+ai_charge(20);
+};
+void() knight_runatk2 =[ $runattack2, knight_runatk3 ] {ai_charge_side();};
+void() knight_runatk3 =[ $runattack3, knight_runatk4 ] {ai_charge_side();};
+void() knight_runatk4 =[ $runattack4, knight_runatk5 ] {ai_charge_side();};
+void() knight_runatk5 =[ $runattack5, knight_runatk6 ] {ai_melee_side();};
+void() knight_runatk6 =[ $runattack6, knight_runatk7 ] {ai_melee_side();};
+void() knight_runatk7 =[ $runattack7, knight_runatk8 ] {ai_melee_side();};
+void() knight_runatk8 =[ $runattack8, knight_runatk9 ] {ai_melee_side();};
+void() knight_runatk9 =[ $runattack9, knight_runatk10 ] {ai_melee_side();};
+void() knight_runatk10 =[ $runattack10, knight_runatk11 ] {ai_charge_side();};
+void() knight_runatk11 =[ $runattack11, knight_run1 ] {ai_charge(10);};
+
+void() knight_atk1 =[ $attackb1, knight_atk2 ]
+{
+sound_attack(self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
+ai_charge(0);};
+void() knight_atk2 =[ $attackb2, knight_atk3 ] {ai_charge(7);};
+void() knight_atk3 =[ $attackb3, knight_atk4 ] {ai_charge(4);};
+void() knight_atk4 =[ $attackb4, knight_atk5 ] {ai_charge(0);};
+void() knight_atk5 =[ $attackb5, knight_atk6 ] {ai_charge(3);};
+void() knight_atk6 =[ $attackb6, knight_atk7 ] {ai_charge(4); ai_melee();};
+void() knight_atk7 =[ $attackb7, knight_atk8 ] {ai_charge(1); ai_melee();};
+void() knight_atk8 =[ $attackb8, knight_atk9 ] {ai_charge(3);
+ai_melee();};
+void() knight_atk9 =[ $attackb9, knight_atk10] {ai_charge(1);};
+void() knight_atk10=[ $attackb10, knight_run1 ] {ai_charge(5);};
+
+//void() knight_atk9 =[ $attack9, knight_atk10 ] {};
+//void() knight_atk10 =[ $attack10, knight_atk11 ] {};
+//void() knight_atk11 =[ $attack11, knight_run1 ] {};
+
+//===========================================================================
+
+void() knight_pain1 =[ $pain1, knight_pain2 ] {};
+void() knight_pain2 =[ $pain2, knight_pain3 ] {};
+void() knight_pain3 =[ $pain3, knight_run1 ] {};
+
+void() knight_painb1 =[ $painb1, knight_painb2 ] {ai_painforward(0);};
+void() knight_painb2 =[ $painb2, knight_painb3 ] {ai_painforward(3);};
+void() knight_painb3 =[ $painb3, knight_painb4 ] {};
+void() knight_painb4 =[ $painb4, knight_painb5 ] {};
+void() knight_painb5 =[ $painb5, knight_painb6 ] {ai_painforward(2);};
+void() knight_painb6 =[ $painb6, knight_painb7 ] {ai_painforward(4);};
+void() knight_painb7 =[ $painb7, knight_painb8 ] {ai_painforward(2);};
+void() knight_painb8 =[ $painb8, knight_painb9 ] {ai_painforward(5);};
+void() knight_painb9 =[ $painb9, knight_painb10 ] {ai_painforward(5);};
+void() knight_painb10 =[ $painb10, knight_painb11 ] {ai_painforward(0);};
+void() knight_painb11 =[ $painb11, knight_run1 ] {};
+
+void(entity attacker, float damage) knight_pain =
+{
+ local float r;
+
+ if (self.pain_finished > time)
+ return;
+
+ r = random();
+
+ sound_pain (self, CHAN_VOICE, "knight/khurt.wav", 1, ATTN_NORM);
+ if (r < 0.85)
+ {
+ knight_pain1 ();
+ self.pain_finished = time + 1;
+ }
+ else
+ {
+ knight_painb1 ();
+ self.pain_finished = time + 1;
+ }
+
+};
+
+//===========================================================================
+
+void() knight_bow1 =[ $kneel1, knight_bow2 ] {ai_turn();};
+void() knight_bow2 =[ $kneel2, knight_bow3 ] {ai_turn();};
+void() knight_bow3 =[ $kneel3, knight_bow4 ] {ai_turn();};
+void() knight_bow4 =[ $kneel4, knight_bow5 ] {ai_turn();};
+
+void() knight_bow5 =[ $kneel5, knight_bow5 ] {ai_turn();};
+
+void() knight_bow6 =[ $kneel4, knight_bow7 ] {ai_turn();};
+void() knight_bow7 =[ $kneel3, knight_bow8 ] {ai_turn();};
+void() knight_bow8 =[ $kneel2, knight_bow9 ] {ai_turn();};
+void() knight_bow9 =[ $kneel1, knight_bow10 ] {ai_turn();};
+void() knight_bow10 =[ $walk1, knight_walk1 ] {ai_turn();};
+
+
+
+void() knight_die1 =[ $death1, knight_die2 ] {};
+void() knight_die2 =[ $death2, knight_die3 ] {};
+void() knight_die3 =[ $death3, knight_die4 ] {self.solid = SOLID_NOT;};
+void() knight_die4 =[ $death4, knight_die5 ] {};
+void() knight_die5 =[ $death5, knight_die6 ] {};
+void() knight_die6 =[ $death6, knight_die7 ] {};
+void() knight_die7 =[ $death7, knight_die8 ] {};
+void() knight_die8 =[ $death8, knight_die9 ] {};
+void() knight_die9 =[ $death9, knight_die10] {};
+void() knight_die10=[ $death10, knight_die10] {};
+
+
+void() knight_dieb1 =[ $deathb1, knight_dieb2 ] {};
+void() knight_dieb2 =[ $deathb2, knight_dieb3 ] {};
+void() knight_dieb3 =[ $deathb3, knight_dieb4 ] {self.solid = SOLID_NOT;};
+void() knight_dieb4 =[ $deathb4, knight_dieb5 ] {};
+void() knight_dieb5 =[ $deathb5, knight_dieb6 ] {};
+void() knight_dieb6 =[ $deathb6, knight_dieb7 ] {};
+void() knight_dieb7 =[ $deathb7, knight_dieb8 ] {};
+void() knight_dieb8 =[ $deathb8, knight_dieb9 ] {};
+void() knight_dieb9 =[ $deathb9, knight_dieb10] {};
+void() knight_dieb10 = [ $deathb10, knight_dieb11] {};
+void() knight_dieb11 = [ $deathb11, knight_dieb11] {};
+
+
+void() knight_die =
+{
+// check for gib
+ if (self.health < -40)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_knight.mdl", self.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+
+// regular death
+ sound_death (self, CHAN_VOICE, "knight/kdeath.wav", 1, ATTN_NORM);
+ DropStuff();
+ if (random() < 0.5)
+ knight_die1 ();
+ else
+ knight_dieb1 ();
+};
+
+
+/*QUAKED monster_knight (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/knight.mdl");
+}
+Knight.
+
+Default heath = 75"
+
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound (SWORD SLASH 1)"
+snd_idle(string) : "Path to custom idle sound"
+snd_misc(string) : "Path to custom sound (SWORD SLASH 2)"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+skin_head(float) : "Skin index of custom head model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_knight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ objerror("Incompatible spawnflag: TURRET_MODE\n");
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ // dumptruck_ds custom_mdls
+ precache_body_model ("progs/knight.mdl");
+ precache_head_model ("progs/h_knight.mdl");
+ //// dumptruck_ds
+ precache_sound_death ("knight/kdeath.wav");
+ precache_sound_pain ("knight/khurt.wav");
+ precache_sound_sight ("knight/ksight.wav");
+ precache_sound_attack ("knight/sword1.wav");
+ precache_sound_misc ("knight/sword2.wav");
+ precache_sound_idle ("knight/idle.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/knight.mdl"); // dumptruck_ds custom_mdls
+ // setmodel (self, "progs/knight.mdl");
+
+ setsize (self, '-16 -16 -24', '16 16 40');
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 75;
+
+ self.th_stand = knight_stand1;
+ self.th_walk = knight_walk1;
+ self.th_run = knight_run1;
+ self.th_melee = knight_atk1;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = knight_pain;
+ else
+ self.th_pain = SUB_NullPain;
+ self.th_die = knight_die;
+
+ walkmonster_start ();
+};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_knight (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID ON_SIDE X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/knight.mdl","frame":96});
+}
+*/
+void() monster_dead_knight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/knight.mdl");
+ setmodel(self, "progs/knight.mdl");
+ if (self.spawnflags & 2)
+ {
+ self.frame = $death10;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-25.56 -14.56 -50.49','26.45 40.2 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+ else
+ {
+ self.frame = $deathb11;
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-30.36 -45.6 -50.18','28.29 11.59 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/ogre.qc

diff --git a/qc/monsters/ogre.qc b/qc/monsters/ogre.qc
new file mode 100644
index 0000000..0a1f132
--- /dev/null
+++ b/qc/monsters/ogre.qc
@@ -0,0 +1,1571 @@
+float MONSTER_FLAK_OGRE = 4;
+float FL_NOSELECT = 8192; //ignored by entity selector
+.float spikecount; //bdw - saves up flak hits to do a single damage next frame - currently only used for flak ogre
+
+/*
+==============================================================================
+
+OGRE
+
+==============================================================================
+*/
+
+$cd id1/models/ogre_c
+$origin 0 0 24
+$base base
+$skin base
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7
+$frame walk8 walk9 walk10 walk11 walk12 walk13 walk14 walk15 walk16
+
+$frame run1 run2 run3 run4 run5 run6 run7 run8
+
+$frame swing1 swing2 swing3 swing4 swing5 swing6 swing7
+$frame swing8 swing9 swing10 swing11 swing12 swing13 swing14
+
+$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7
+$frame smash8 smash9 smash10 smash11 smash12 smash13 smash14
+
+$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6
+
+$frame pain1 pain2 pain3 pain4 pain5
+
+$frame painb1 painb2 painb3
+
+$frame painc1 painc2 painc3 painc4 painc5 painc6
+
+$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10
+$frame paind11 paind12 paind13 paind14 paind15 paind16
+
+$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10
+$frame paine11 paine12 paine13 paine14 paine15
+
+$frame death1 death2 death3 death4 death5 death6
+$frame death7 death8 death9 death10 death11 death12
+$frame death13 death14
+
+$frame bdeath1 bdeath2 bdeath3 bdeath4 bdeath5 bdeath6
+$frame bdeath7 bdeath8 bdeath9 bdeath10
+
+$frame pull1 pull2 pull3 pull4 pull5 pull6 pull7 pull8 pull9 pull10 pull11
+
+//=============================================================================
+
+
+void() OgreGrenadeExplode =
+{
+ T_RadiusDamage (self, self.owner, 40, world);
+ sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ self.velocity = '0 0 0';
+ self.touch = SUB_Null;
+ setmodel (self, "progs/s_explod.spr");
+ self.solid = SOLID_NOT;
+ s_explode1 ();
+};
+
+void() OgreGrenadeTouch =
+{
+ if (other == self.owner)
+ return; // don't explode on owner
+ if (other.takedamage == DAMAGE_AIM)
+ {
+ OgreGrenadeExplode();
+ return;
+ }
+ if (self.count < time) {
+ sound (self, CHAN_VOICE, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
+ }
+ self.count = time + .02;
+ if (self.velocity == '0 0 0')
+ self.avelocity = '0 0 0';
+};
+
+//BDW 31/08/00 - evil, nasty red-hot nail cluster-bomb attack... from Marcher -- dumptruck_ds
+
+void() FlakDoDamage =
+{
+ self.origin = self.oldenemy.origin + self.oldorigin; //get correct gib direction
+ T_Damage(self.oldenemy, self, self.owner, self.oldenemy.spikecount);
+ self.oldenemy.spikecount = 0;
+ remove(self);
+};
+
+void() FlakTouch =
+{
+ if (other.solid == SOLID_TRIGGER)
+ return;
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove(self);
+ return;
+ }
+
+// hit something that bleeds
+ if (other.takedamage)
+ {
+ spawn_touchblood(self.dmg);
+
+ sound(self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
+
+ if (other.spikecount) //not the first one
+ {
+ other.spikecount = other.spikecount + self.dmg;
+ remove(self);
+ return;
+ }
+
+ // the first one...
+
+ other.spikecount = self.dmg;
+
+ // stick around for a little while...
+ self.velocity = '0 0 0';
+ self.solid = SOLID_NOT;
+ self.touch = SUB_Null;
+ self.model = string_null;
+ self.oldorigin = self.origin - other.origin; //displacement from enemy origin (its gonna move next frame)
+ self.oldenemy = other;
+ self.think = FlakDoDamage;
+ self.nextthink = time + 0.05;
+ return;
+ }
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ if (self.spawnflags & MONSTER_FLAK_OGRE) //bit of a hack
+ {
+ remove(self);
+ return;
+ }
+
+ self.dmg = self.dmg - 5; //gets weaker with each bounce. also stops them getting stuck in world.
+ if (self.dmg <= 0)
+ {
+ remove(self);
+ return;
+ }
+ self.velocity = self.velocity * 0.5; //reduce crazy ricochets
+ self.movetype = MOVETYPE_BOUNCE;
+};
+
+void() BDW_OgreFireFlak =
+{
+ local float flakcount;
+ local vector dir, ang;
+ local entity flak;
+ local float projspeed = 800 * self.proj_speed_mod;
+
+ flakcount = 8;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ sound(self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
+
+// make angles out of the current displacement vector...
+ ang = vectoangles(self.enemy.origin - self.origin);
+// then get the required components...
+ makevectors(ang);
+
+ while (flakcount > 0)
+ {
+ //tighter spread...
+ dir = v_forward*10 + crandom()*v_right + crandom()*v_up;
+ dir = normalize(dir);
+ // f*cking hack...is this a v_forward problem?
+ dir_z = dir_z * -1;
+ //dir = dir*1000;
+ //dir = dir*800;
+
+
+ flak = spawn();
+
+ flak.owner = self;
+ //flymissile is a bit too all-seeing for this gun...
+ flak.movetype = MOVETYPE_FLY;
+ //flak.movetype = MOVETYPE_FLYMISSILE;
+ flak.solid = SOLID_BBOX;
+ flak.flags = FL_NOSELECT;
+ flak.touch = FlakTouch;
+ flak.angles = vectoangles(dir);
+ SetSpeed(flak, dir, projspeed);
+ if (self.homing > 0)
+ {
+ SetupHoming(flak, projspeed);
+ }
+ else
+ {
+ flak.nextthink = time + 6;
+ flak.think = SUB_Remove;
+ }
+ flak.dmg = 4;
+
+ flak.spawnflags = MONSTER_FLAK_OGRE; //this is a hack to tell FlakTouch that it came from an ogre
+ // setmodel(flak, "progs/spike.mdl");
+ flak.skin = self.skin_proj; //dumptruck_ds
+
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (flak, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (flak, "progs/spike.mdl");
+ }
+
+ if (!flak.skin_proj) // dumptruck_ds
+ {
+ flak.skin = self.skin_proj;
+ }
+ else
+ {
+ flak.skin = 0;
+ }
+ // dumptruck_ds - end
+
+ setsize(flak, '0 0 0', '0 0 0');
+ setorigin(flak, self.origin + '0 0 16');
+
+ flakcount = flakcount - 1;
+ }
+};
+/////////////////////////////////////////////////////////////
+/* start Preach Ogre Marksman tutorial here -- dumptruck_ds*/
+/////////////////////////////////////////////////////////////
+
+//speed an ogre grenade is fired at
+float OGRE_G_VEL = 600;
+
+//fixme: get the correct gravity strength for the level
+float pgrav = 800;
+
+//a default angle to fire at if the enemy is too far away
+float OGRE_DEFAULT_ELEVATION = 30;
+
+//uses QuakeC builtins to calculate tan of angle
+//WARNING: uses makevectors! This overwrites the v_forward... globals
+float(float theta) tan =
+{
+ local vector ang; //temporary used to calculate trig values
+ ang = '0 0 0';
+ ang_y = theta; //assign theta to the yaw to simplify reasoning
+ makevectors(ang);
+ return v_forward_y / v_forward_x;
+}
+
+//inverse tan function
+//takes two parameters, numerator and denominator
+//this copes better with denominator 0 and gets quadrant correct
+/*
+float(float y, float x) atan2 =
+{
+ local vector ang; //temporary used to calculate trig values
+ ang = '0 0 0';
+ ang_x = x;
+ ang_y = y;
+ return vectoyaw(ang);
+}
+*/
+
+float(float theta, vector dest) IterateElevation =
+{
+ local float a, b, c; //constants in the equation to be solved
+ local vector ofs; //displacement we wish the projectile to travel
+ local float y, z; //horizontal and vertical components of ofs
+ local float tan_theta; //trig values of the angle theta
+
+ //calculate how far we are firing
+ ofs = dest - self.origin;
+ z = ofs_z;
+ ofs_z = 0;
+ y = vlen(ofs);
+
+ //find the coefficients of the quadratic in tan(theta)
+ a = 0.5 * pgrav * y * y / (OGRE_G_VEL * OGRE_G_VEL);
+ b = -y;
+ c = a + z;
+
+ //check if the destination is too far to reach
+ if(b*b < 4*a*c)
+ return OGRE_DEFAULT_ELEVATION;
+
+ //calculate the tan value of the given theta
+ tan_theta = tan(theta);
+
+ //reuse ang to create the improved firing direction
+ theta = atan2(a*tan_theta*tan_theta - c,
+ 2*a*tan_theta + b);
+
+ //constrain the values to stop anything too mad happening
+ while(theta > 90)
+ theta = theta - 180;
+ return theta;
+}
+/*
+================
+PreachFireGrenade
+================
+*/
+void(float elevation) PreachFireGrenade =
+{
+ local entity missile;
+ local vector ang;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+
+// set missile speed
+ ang = self.angles;
+ ang_x = -elevation;
+ makevectors (ang);
+
+ missile.velocity = v_forward * OGRE_G_VEL;
+
+ missile.avelocity = '300 300 300';
+
+ missile.angles = vectoangles(missile.velocity);
+
+ missile.touch = OgreGrenadeTouch;
+
+// set missile duration
+ missile.nextthink = time + 2.5;
+ missile.think = OgreGrenadeExplode;
+ // setmodel (missile, "progs/grenade.mdl");
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/grenade.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin);
+};
+
+// end Preach tutorial
+
+/*
+================
+PreachFireZombie
+for Z-Aware Zombies in Turret Mode only
+================
+*/
+void(float elevation) PreachFireZombie =
+{
+ local entity missile;
+ local vector ang;
+
+ // self.effects = self.effects | EF_MUZZLEFLASH;
+
+ sound_attack (self, CHAN_WEAPON, "zombie/z_shot1.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+
+// set missile speed
+ ang = self.angles;
+ ang_x = -elevation;
+ makevectors (ang);
+
+ missile.velocity = v_forward * OGRE_G_VEL;
+
+ missile.avelocity = '3000 1000 2000';
+
+ missile.angles = vectoangles(missile.velocity);
+
+ missile.touch = ZombieGrenadeTouch;
+
+// set missile duration
+ missile.nextthink = time + 2.5;
+ missile.think = SUB_Remove;
+ // setmodel (missile, "progs/grenade.mdl");
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/zom_gib.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin);
+};
+
+// end Preach tutorial
+
+/*
+================
+OgreFireGrenade
+================
+*/
+void() MultiGrenadeTouch;
+void() MultiGrenadeExplode;
+
+void() OgreFireGrenade =
+{
+ local entity missile;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+ missile.skin = self.skin_proj; //dumptruck_ds
+
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/grenade.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+// dumptruck_ds - end
+// set missile speed
+
+ makevectors (self.angles);
+ missile.velocity = normalize(self.enemy.origin - self.origin);
+ missile.velocity = missile.velocity * 600;
+ missile.velocity_z = 200;
+ missile.avelocity = '300 300 300';
+ missile.angles = vectoangles(missile.velocity);
+
+ // set missile duration
+ if(self.style == 3)
+ {
+ missile.touch = MultiGrenadeTouch;
+ missile.nextthink = time + 2.5;
+ missile.think = MultiGrenadeExplode;
+ setmodel (missile, "progs/mervup.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin);
+ missile.classname = "MultiGrenade";
+ }
+ else
+ {
+ missile.touch = OgreGrenadeTouch;
+ missile.nextthink = time + 2.5;
+ missile.think = OgreGrenadeExplode;
+ // setmodel (missile, "progs/grenade.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin);
+ }
+ };
+
+ // missile.touch = OgreGrenadeTouch;
+
+// // set missile duration
+// missile.nextthink = time + 2.5;
+// missile.think = OgreGrenadeExplode;
+//
+// setmodel (missile, "progs/grenade.mdl");
+// setsize (missile, '0 0 0', '0 0 0');
+// setorigin (missile, self.origin);
+// };
+
+/*
+================
+OgreFireSpike from insideqc tutorial here: http://www.insideqc.com/qctut/lesson-33.shtml
+================
+*/
+void() OgreFireSpike =
+{
+ local vector dir;
+ // local entity old;
+
+
+ sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
+ self.attack_finished = time + .7;
+ // self.attack_finished = time + 0.2;
+ self.effects = self.effects | EF_MUZZLEFLASH; // -- dumptruck_ds
+
+ dir = normalize (self.enemy.origin - self.origin);
+
+ launch_spike (self.origin + v_right * 4 + '0 0 16', dir);
+
+ newmis.touch = superduperspike_touch; //dumptruck_ds found in client.qc
+ // setmodel (newmis, "progs/lspike.mdl");
+ newmis.skin = self.skin_proj; //dumptruck_ds
+
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (newmis, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/lspike.mdl");
+ }
+
+ if (!newmis.skin_proj) // dumptruck_ds
+ {
+ newmis.skin = self.skin_proj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+ // dumptruck_ds - end
+
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+};
+//=============================================================================
+// Multi Grenade Code from doe progs MULT_WPN.QC -- dumptruck_ds
+//=============================================================================
+void() MultiGrenadeTouch;
+
+//================================
+//================================
+void() MiniGrenadeExplode =
+{
+ if ( self.owner.classname == "player")
+ T_RadiusDamage (self, self.owner, 90, world);
+ else
+ T_RadiusDamage (self, self.owner, 60, world);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION2);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+ WriteByte (MSG_BROADCAST, 230);
+ WriteByte (MSG_BROADCAST, 5);
+
+ BecomeExplosion ();
+};
+
+//================================
+//================================
+void(float offsetAngle) MiniGrenadeLaunch =
+{
+ local entity missile/*, mpuff*/;
+ local float tempRand;
+
+ missile = spawn ();
+ missile.owner = self.owner;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "MiniGrenade";
+
+// set missile speed
+ missile.v_angle = self.v_angle;
+ missile.v_angle_y = missile.v_angle_y + offsetAngle;
+ makevectors (missile.v_angle);
+
+ missile.velocity = v_forward*100 + v_up*400;
+ tempRand = (crandom()*60) - 30;
+ missile.velocity = missile.velocity + tempRand * v_forward;
+ tempRand = (crandom()*40) - 20;
+ missile.velocity = missile.velocity + tempRand * v_right;
+ tempRand = (crandom()*60) - 30;
+ missile.velocity = missile.velocity + tempRand * v_up;
+
+ missile.avelocity = '300 300 300';
+ missile.angles = vectoangles(missile.velocity);
+ missile.touch = MultiGrenadeTouch;
+
+ setmodel (missile, "progs/mervup.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin);
+
+// set missile duration
+ missile.nextthink = time + 1 + (crandom() * 0.5);
+ missile.think = MiniGrenadeExplode;
+};
+
+//================================
+//================================
+void() MultiGrenadeExplode =
+{
+ MiniGrenadeLaunch(0);
+ MiniGrenadeLaunch(72);
+ MiniGrenadeLaunch(144);
+ MiniGrenadeLaunch(216);
+ MiniGrenadeLaunch(288);
+
+ remove (self);
+};
+
+//================================
+//================================
+void() MultiGrenadeTouch =
+{
+ if (other == self.owner)
+ return; // don't explode on owner
+ if (other.takedamage == DAMAGE_AIM)
+ {
+ if (self.classname == "MiniGrenade")
+ MiniGrenadeExplode();
+ else
+ {
+ if (self.owner.classname == "player")
+ GrenadeExplode();
+ else
+ MiniGrenadeExplode();
+ }
+ return;
+ }
+ // bounce sound
+ sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);
+ if (self.velocity == '0 0 0')
+ self.avelocity = '0 0 0';
+};
+
+//================================
+//================================
+void() W_FireMultiGrenade =
+{
+ local entity missile/*, mpuff*/;
+
+ // self.currentammo = self.ammo_multi_rockets = self.ammo_multi_rockets - 1;
+ // UpdateAmmoCounts (self);
+
+ sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+
+ // self.punchangle_x = -2;
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "MultiGrenade";
+
+ makevectors (self.angles);
+ missile.velocity = normalize(self.enemy.origin - self.origin);
+ missile.velocity = missile.velocity * 600;
+ missile.velocity_z = 200;
+ missile.avelocity = '300 300 300';
+ missile.angles = vectoangles(missile.velocity);
+
+
+// set missile speed
+ // makevectors (self.v_angle);
+ // if (self.v_angle_x)
+ // missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
+ // else
+ // {
+ // missile.velocity = aim(self, 10000);
+ // missile.velocity = missile.velocity * 600;
+ // missile.velocity_z = 200;
+ // }
+ //
+ // missile.avelocity = '300 300 300';
+ // missile.angles = vectoangles(missile.velocity);
+ missile.touch = MultiGrenadeTouch;
+
+// set missile duration
+ missile.nextthink = time + 1;
+ missile.think = MultiGrenadeExplode;
+ setmodel (missile, "progs/mervup.mdl");
+ missile.skin = self.skin_proj; //dumptruck_ds
+
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin + '0 0 16');
+};
+
+//=============================================================================
+//end doe qc -- dumptruck_ds
+//=============================================================================
+/*
+================
+OgreFireLavaBall by jaycie erysdren 2021-09-14
+================
+*/
+
+void() OgreFireLavaBall =
+{
+ local vector offang;
+ local vector org, vec, d;
+ // local float t;
+
+ offang = vectoangles (self.enemy.origin - self.origin);
+ makevectors (offang);
+
+ org = self.origin; // + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
+
+// lead the player on hard mode
+ // if (skill > 1)
+ // {
+ // t = vlen(self.enemy.origin - org) / 300;
+ // vec = self.enemy.velocity;
+ // vec_z = 0;
+ // d = self.enemy.origin + t * vec;
+ // }
+ // else
+ // {
+ d = self.enemy.origin;
+ // }
+
+ vec = normalize (d - org);
+
+ // launch_spike (org, vec);
+ launch_spike2 (self.origin + v_right * 4 + '0 0 16', vec, 600);
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ if (self.mdl_proj != "") // dumptruck_ds custom_mdls
+ {
+ setmodel (newmis, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/lavaball.mdl");
+ }
+
+ if (!newmis.skin_proj) // dumptruck_ds
+ {
+ newmis.skin = self.skin_proj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+ newmis.avelocity = self.cust_avelocity;
+ if !(newmis.avelocity)
+ newmis.avelocity = '200 100 300';
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ // newmis.touch = T_MissileTouch; // rocket explosion
+ newmis.touch = OgreGrenadeExplode;
+ sound_attack (self, CHAN_AUTO, "boss1/throw.wav", 1, ATTN_NORM);
+
+};
+
+/*
+================
+chainsaw
+
+FIXME
+================
+*/
+void(float side) chainsaw =
+{
+local vector delta;
+local float ldmg;
+
+ if (!self.enemy)
+ return;
+ if (!CanDamage (self.enemy, self))
+ return;
+
+ ai_charge(10);
+
+ delta = self.enemy.origin - self.origin;
+
+ if (vlen(delta) > 100)
+ return;
+
+ ldmg = (random() + random() + random()) * 4;
+ T_Damage (self.enemy, self, self, ldmg);
+
+ if (side)
+ {
+ makevectors (self.angles);
+ if (side == 1)
+ SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
+ else
+ SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
+ }
+};
+
+void() ogre_stand1 =[ $stand1, ogre_stand2 ] {ai_stand();};
+void() ogre_stand2 =[ $stand2, ogre_stand3 ] {ai_stand();};
+void() ogre_stand3 =[ $stand3, ogre_stand4 ] {ai_stand();};
+void() ogre_stand4 =[ $stand4, ogre_stand5 ] {ai_stand();};
+void() ogre_stand5 =[ $stand5, ogre_stand6 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
+ai_stand();
+};
+void() ogre_stand6 =[ $stand6, ogre_stand7 ] {ai_stand();};
+void() ogre_stand7 =[ $stand7, ogre_stand8 ] {ai_stand();};
+void() ogre_stand8 =[ $stand8, ogre_stand9 ] {ai_stand();};
+void() ogre_stand9 =[ $stand9, ogre_stand1 ] {ai_stand();};
+
+void() ogre_walk1 =[ $walk1, ogre_walk2 ] {ai_walk(3);};
+void() ogre_walk2 =[ $walk2, ogre_walk3 ] {ai_walk(2);};
+void() ogre_walk3 =[ $walk3, ogre_walk4 ] {
+ai_walk(2);
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
+};
+void() ogre_walk4 =[ $walk4, ogre_walk5 ] {ai_walk(2);};
+void() ogre_walk5 =[ $walk5, ogre_walk6 ] {ai_walk(2);};
+void() ogre_walk6 =[ $walk6, ogre_walk7 ] {
+ai_walk(5);
+if (random() < 0.1)
+ sound_misc (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);
+};
+void() ogre_walk7 =[ $walk7, ogre_walk8 ] {ai_walk(3);};
+void() ogre_walk8 =[ $walk8, ogre_walk9 ] {ai_walk(2);};
+void() ogre_walk9 =[ $walk9, ogre_walk10 ] {ai_walk(3);};
+void() ogre_walk10 =[ $walk10, ogre_walk11 ] {ai_walk(1);};
+void() ogre_walk11 =[ $walk11, ogre_walk12 ] {ai_walk(2);};
+void() ogre_walk12 =[ $walk12, ogre_walk13 ] {ai_walk(3);};
+void() ogre_walk13 =[ $walk13, ogre_walk14 ] {ai_walk(3);};
+void() ogre_walk14 =[ $walk14, ogre_walk15 ] {ai_walk(3);};
+void() ogre_walk15 =[ $walk15, ogre_walk16 ] {ai_walk(3);};
+void() ogre_walk16 =[ $walk16, ogre_walk1 ] {ai_walk(4);};
+
+void() ogre_run1 =[ $run1, ogre_run2 ] {ai_run(9);
+if (random() < 0.2)
+ sound_misc1 (self, CHAN_VOICE, "ogre/ogidle2.wav", 1, ATTN_IDLE);
+};
+void() ogre_run2 =[ $run2, ogre_run3 ] {ai_run(12);};
+void() ogre_run3 =[ $run3, ogre_run4 ] {ai_run(8);};
+void() ogre_run4 =[ $run4, ogre_run5 ] {ai_run(22);};
+void() ogre_run5 =[ $run5, ogre_run6 ] {ai_run(16);};
+void() ogre_run6 =[ $run6, ogre_run7 ] {ai_run(4);};
+void() ogre_run7 =[ $run7, ogre_run8 ] {ai_run(13);};
+void() ogre_run8 =[ $run8, ogre_run1 ] {ai_run(24);};
+
+void() ogre_swing1 =[ $swing1, ogre_swing2 ] {ai_charge(11);
+sound_attack (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM);
+};
+void() ogre_swing2 =[ $swing2, ogre_swing3 ] {ai_charge(1);};
+void() ogre_swing3 =[ $swing3, ogre_swing4 ] {ai_charge(4);};
+void() ogre_swing4 =[ $swing4, ogre_swing5 ] {ai_charge(13);};
+void() ogre_swing5 =[ $swing5, ogre_swing6 ] {ai_charge(9); chainsaw(0);self.angles_y = self.angles_y + random()*25;};
+void() ogre_swing6 =[ $swing6, ogre_swing7 ] {chainsaw(200);self.angles_y = self.angles_y + random()* 25;};
+void() ogre_swing7 =[ $swing7, ogre_swing8 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
+void() ogre_swing8 =[ $swing8, ogre_swing9 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
+void() ogre_swing9 =[ $swing9, ogre_swing10 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
+void() ogre_swing10 =[ $swing10, ogre_swing11 ] {chainsaw(-200);self.angles_y = self.angles_y + random()* 25;};
+void() ogre_swing11 =[ $swing11, ogre_swing12 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
+void() ogre_swing12 =[ $swing12, ogre_swing13 ] {ai_charge(3);};
+void() ogre_swing13 =[ $swing13, ogre_swing14 ] {ai_charge(8);};
+void() ogre_swing14 =[ $swing14, ogre_run1 ] {ai_charge(9);};
+
+void() ogre_smash1 =[ $smash1, ogre_smash2 ] {ai_charge(6);
+sound_attack (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM);
+};
+void() ogre_smash2 =[ $smash2, ogre_smash3 ] {ai_charge(0);};
+void() ogre_smash3 =[ $smash3, ogre_smash4 ] {ai_charge(0);};
+void() ogre_smash4 =[ $smash4, ogre_smash5 ] {ai_charge(1);};
+void() ogre_smash5 =[ $smash5, ogre_smash6 ] {ai_charge(4);};
+void() ogre_smash6 =[ $smash6, ogre_smash7 ] {ai_charge(4); chainsaw(0);};
+void() ogre_smash7 =[ $smash7, ogre_smash8 ] {ai_charge(4); chainsaw(0);};
+void() ogre_smash8 =[ $smash8, ogre_smash9 ] {ai_charge(10); chainsaw(0);};
+void() ogre_smash9 =[ $smash9, ogre_smash10 ] {ai_charge(13); chainsaw(0);};
+void() ogre_smash10 =[ $smash10, ogre_smash11 ] {chainsaw(1);};
+void() ogre_smash11 =[ $smash11, ogre_smash12 ] {ai_charge(2); chainsaw(0);
+// self.nextthink = self.nextthink + random()*0.2;}; // slight variation
+self.nextthink = time + 0.1 + random()*0.2;}; // 1998-08-14 Incorrect setting of nextthink fix by Maddes/Lord Sméagol
+void() ogre_smash12 =[ $smash12, ogre_smash13 ] {ai_charge(0);};
+void() ogre_smash13 =[ $smash13, ogre_smash14 ] {ai_charge(4);};
+void() ogre_smash14 =[ $smash14, ogre_run1 ] {ai_charge(12);};
+
+// Preach tutorial alternate animation frames for monster_ogre_marksman -- dumptruck_ds
+.float attack_elevation;
+void() ogre2_nail1 =[ $shoot1, ogre2_nail2 ] {ai_face();
+self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
+void() ogre2_nail2 =[ $shoot2, ogre2_nail3 ] {ai_face();
+self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() ogre2_nail3 =[ $shoot2, ogre2_nail4 ] {ai_face();
+self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() ogre2_nail4 =[ $shoot3, ogre_nail5 ] {ai_face();
+ PreachFireGrenade(self.attack_elevation);
+};
+// Preach tutorial alternate animation frames for monster_ogre_marksman -- dumptruck_ds
+// these are for the turret version of monster_ogre_marksman
+.float attack_elevation;
+void() ogre2_turret_attack1 =[ $shoot1, ogre2_turret_attack2 ] {ai_face();
+self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
+void() ogre2_turret_attack2 =[ $shoot2, ogre2_turret_attack3 ] {ai_face();
+self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() ogre2_turret_attack3 =[ $shoot2, ogre2_turret_attack4 ] {ai_face();
+self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() ogre2_turret_attack4 =[ $shoot3, ogre2_turret_attack5 ] {ai_face();
+ PreachFireGrenade(self.attack_elevation);};
+void() ogre2_turret_attack5 =[ $shoot4, ogre2_turret_attack6 ] {ai_face();};
+void() ogre2_turret_attack6 =[ $shoot5, ogre2_turret_attack7 ] {ai_face();};
+void() ogre2_turret_attack7 =[ $shoot5, ogre2_turret_attack8 ] {ai_face();};
+void() ogre2_turret_attack8 =[ $shoot6, ogre2_turret_attack9 ] {ai_face();};
+void() ogre2_turret_attack9 =[ $shoot6, ogre2_turret_seek1 ] {ai_face();};
+void() ogre2_turret_seek1 =[ $stand1, ogre2_turret_seek2 ] {ai_run(0);};
+void() ogre2_turret_seek2 =[ $stand2, ogre2_turret_seek3 ] {ai_run(0);};
+void() ogre2_turret_seek3 =[ $stand3, ogre2_turret_seek4 ] {ai_run(0);};
+void() ogre2_turret_seek4 =[ $stand4, ogre2_turret_seek5 ] {ai_run(0);};
+void() ogre2_turret_seek5 =[ $stand5, ogre2_turret_seek6 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
+ ai_run(0);
+};
+void() ogre2_turret_seek6 =[ $stand6, ogre2_turret_seek7 ] {ai_run(0);};
+void() ogre2_turret_seek7 =[ $stand7, ogre2_turret_seek8 ] {ai_run(0);};
+void() ogre2_turret_seek8 =[ $stand8, ogre2_turret_seek9 ] {ai_run(0);};
+void() ogre2_turret_seek9 =[ $stand9, ogre2_turret_seek1 ] {ai_run(0);};
+
+//end Preach -- dumptruck_ds
+void() ogre_nail1 =[ $shoot1, ogre_nail2 ] {ai_face();};
+void() ogre_nail2 =[ $shoot2, ogre_nail3 ] {ai_face();};
+void() ogre_nail3 =[ $shoot2, ogre_nail4 ] {ai_face();};
+void() ogre_nail4 =[ $shoot3, ogre_nail5 ] {ai_face();
+ if (self.style == 0)
+ {
+ OgreFireGrenade();
+ }
+ if (self.style == 1)
+ {
+ BDW_OgreFireFlak();
+ // OgreFireSpike();
+ }
+ else if (self.style == 2)
+ {
+ OgreFireSpike();
+ }
+ if (self.style == 3)
+ {
+ W_FireMultiGrenade();
+ }
+ if (self.style == 4) // jaycie erysdren 2021-09-14
+ {
+ OgreFireLavaBall();
+ sound_misc2 (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM); // used for initial attack sound dumptruck_ds
+ }
+};
+void() ogre_nail5 =[ $shoot4, ogre_nail6 ] {ai_face();};
+void() ogre_nail6 =[ $shoot5, ogre_nail7 ] {ai_face();};
+void() ogre_nail7 =[ $shoot6, ogre_run1 ] {ai_face();};
+//
+////////////////////////
+// turret frames START
+////////////////////////
+//
+void() ogre_turret_attack1 =[ $shoot1, ogre_turret_attack2 ] {ai_face();};
+void() ogre_turret_attack2 =[ $shoot2, ogre_turret_attack3 ] {ai_face();};
+void() ogre_turret_attack3 =[ $shoot2, ogre_turret_attack4 ] {ai_face();};
+void() ogre_turret_attack4 =[ $shoot3, ogre_turret_attack5 ] {ai_face();
+ if (self.style == 0)
+ {
+ OgreFireGrenade();
+ }
+ if (self.style == 1)
+ {
+ BDW_OgreFireFlak();
+ // OgreFireSpike();
+ }
+ else if (self.style == 2)
+ {
+ OgreFireSpike();
+ }
+ if (self.style == 3)
+ {
+ W_FireMultiGrenade();
+ }
+ if (self.style == 4) // jaycie erysdren 2021-09-14
+ {
+ OgreFireLavaBall();
+ sound_misc2 (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM); // used for initial attack sound dumptruck_ds
+ }
+};
+void() ogre_turret_attack5 =[ $shoot4, ogre_turret_attack6 ] {ai_face();};
+
+void() ogre_turret_attack6=[ $shoot5, ogre_turret_attack7 ] {ai_face();};
+void() ogre_turret_attack7=[ $shoot5, ogre_turret_attack8 ] {ai_face();};
+void() ogre_turret_attack8=[ $shoot6, ogre_turret_attack9 ] {ai_face();};
+void() ogre_turret_attack9=[ $shoot6, ogre_turret_seek1 ] {ai_face();};
+void() ogre_turret_seek1 =[ $stand1, ogre_turret_seek2 ] {ai_run(0);};
+void() ogre_turret_seek2 =[ $stand2, ogre_turret_seek3 ] {ai_run(0);};
+void() ogre_turret_seek3 =[ $stand3, ogre_turret_seek4 ] {ai_run(0);};
+void() ogre_turret_seek4 =[ $stand4, ogre_turret_seek5 ] {ai_run(0);};
+void() ogre_turret_seek5 =[ $stand5, ogre_turret_seek6 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
+ ai_run(0);
+};
+void() ogre_turret_seek6 =[ $stand6, ogre_turret_seek7 ] {ai_run(0);};
+void() ogre_turret_seek7 =[ $stand7, ogre_turret_seek8 ] {ai_run(0);};
+void() ogre_turret_seek8 =[ $stand8, ogre_turret_seek9 ] {ai_run(0);};
+void() ogre_turret_seek9 =[ $stand9, ogre_turret_seek1 ] {ai_run(0);};
+////////////////////////
+//turret frames END
+///////////////////////
+void() ogre_pain1 =[ $pain1, ogre_pain2 ] {};
+void() ogre_pain2 =[ $pain2, ogre_pain3 ] {};
+void() ogre_pain3 =[ $pain3, ogre_pain4 ] {};
+void() ogre_pain4 =[ $pain4, ogre_pain5 ] {};
+void() ogre_pain5 =[ $pain5, ogre_run1 ] {};
+
+
+void() ogre_painb1 =[ $painb1, ogre_painb2 ] {};
+void() ogre_painb2 =[ $painb2, ogre_painb3 ] {};
+void() ogre_painb3 =[ $painb3, ogre_run1 ] {};
+
+
+void() ogre_painc1 =[ $painc1, ogre_painc2 ] {};
+void() ogre_painc2 =[ $painc2, ogre_painc3 ] {};
+void() ogre_painc3 =[ $painc3, ogre_painc4 ] {};
+void() ogre_painc4 =[ $painc4, ogre_painc5 ] {};
+void() ogre_painc5 =[ $painc5, ogre_painc6 ] {};
+void() ogre_painc6 =[ $painc6, ogre_run1 ] {};
+
+
+void() ogre_paind1 =[ $paind1, ogre_paind2 ] {};
+void() ogre_paind2 =[ $paind2, ogre_paind3 ] {ai_pain(10);};
+void() ogre_paind3 =[ $paind3, ogre_paind4 ] {ai_pain(9);};
+void() ogre_paind4 =[ $paind4, ogre_paind5 ] {ai_pain(4);};
+void() ogre_paind5 =[ $paind5, ogre_paind6 ] {};
+void() ogre_paind6 =[ $paind6, ogre_paind7 ] {};
+void() ogre_paind7 =[ $paind7, ogre_paind8 ] {};
+void() ogre_paind8 =[ $paind8, ogre_paind9 ] {};
+void() ogre_paind9 =[ $paind9, ogre_paind10 ] {};
+void() ogre_paind10=[ $paind10, ogre_paind11 ] {};
+void() ogre_paind11=[ $paind11, ogre_paind12 ] {};
+void() ogre_paind12=[ $paind12, ogre_paind13 ] {};
+void() ogre_paind13=[ $paind13, ogre_paind14 ] {};
+void() ogre_paind14=[ $paind14, ogre_paind15 ] {};
+void() ogre_paind15=[ $paind15, ogre_paind16 ] {};
+void() ogre_paind16=[ $paind16, ogre_run1 ] {};
+
+void() ogre_paine1 =[ $paine1, ogre_paine2 ] {};
+void() ogre_paine2 =[ $paine2, ogre_paine3 ] {ai_pain(10);};
+void() ogre_paine3 =[ $paine3, ogre_paine4 ] {ai_pain(9);};
+void() ogre_paine4 =[ $paine4, ogre_paine5 ] {ai_pain(4);};
+void() ogre_paine5 =[ $paine5, ogre_paine6 ] {};
+void() ogre_paine6 =[ $paine6, ogre_paine7 ] {};
+void() ogre_paine7 =[ $paine7, ogre_paine8 ] {};
+void() ogre_paine8 =[ $paine8, ogre_paine9 ] {};
+void() ogre_paine9 =[ $paine9, ogre_paine10 ] {};
+void() ogre_paine10=[ $paine10, ogre_paine11 ] {};
+void() ogre_paine11=[ $paine11, ogre_paine12 ] {};
+void() ogre_paine12=[ $paine12, ogre_paine13 ] {};
+void() ogre_paine13=[ $paine13, ogre_paine14 ] {};
+void() ogre_paine14=[ $paine14, ogre_paine15 ] {};
+void() ogre_paine15=[ $paine15, ogre_run1 ] {};
+
+
+void(entity attacker, float damage) ogre_pain =
+{
+ local float r;
+
+// don't make multiple pain sounds right after each other
+ if (self.pain_finished > time)
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+
+ sound_pain (self, CHAN_VOICE, "ogre/ogpain1.wav", 1, ATTN_NORM);
+
+ r = random();
+
+ if (r < 0.25)
+ {
+ ogre_pain1 ();
+ self.pain_finished = time + 1;
+ }
+ else if (r < 0.5)
+ {
+ ogre_painb1 ();
+ self.pain_finished = time + 1;
+ }
+ else if (r < 0.75)
+ {
+ ogre_painc1 ();
+ self.pain_finished = time + 1;
+ }
+ else if (r < 0.88)
+ {
+ ogre_paind1 ();
+ self.pain_finished = time + 2;
+ }
+ else
+ {
+ ogre_paine1 ();
+ self.pain_finished = time + 2;
+ }
+};
+
+void() ogre_die1 =[ $death1, ogre_die2 ] {};
+void() ogre_die2 =[ $death2, ogre_die3 ] {};
+void() ogre_die3 =[ $death3, ogre_die4 ]
+{self.solid = SOLID_NOT;
+ // style ammotype check -- dumptruck_ds
+ if (self.style == 1) // flak style
+ {
+ self.ammo_nails = 5;
+ }
+ if (self.style == 2) // super nail style
+ {
+ self.ammo_nails = 5;
+ }
+ if (self.style == 3) //DOE multi-grenade
+ {
+ self.ammo_rockets = 2;
+ }
+ else if (self.style == 0) //default Ogre
+ {
+ self.ammo_rockets = 2;
+ }
+if(!self.keep_ammo)DropBackpack();};
+void() ogre_die4 =[ $death4, ogre_die5 ] {};
+void() ogre_die5 =[ $death5, ogre_die6 ] {};
+void() ogre_die6 =[ $death6, ogre_die7 ] {};
+void() ogre_die7 =[ $death7, ogre_die8 ] {};
+void() ogre_die8 =[ $death8, ogre_die9 ] {};
+void() ogre_die9 =[ $death9, ogre_die10 ] {};
+void() ogre_die10 =[ $death10, ogre_die11 ] {};
+void() ogre_die11 =[ $death11, ogre_die12 ] {};
+void() ogre_die12 =[ $death12, ogre_die13 ] {};
+void() ogre_die13 =[ $death13, ogre_die14 ] {};
+void() ogre_die14 =[ $death14, ogre_die14 ] {};
+
+void() ogre_bdie1 =[ $bdeath1, ogre_bdie2 ] {};
+void() ogre_bdie2 =[ $bdeath2, ogre_bdie3 ] {ai_forward(5);};
+void() ogre_bdie3 =[ $bdeath3, ogre_bdie4 ]
+{self.solid = SOLID_NOT;
+ // style ammotype check -- dumptruck_ds
+ if (self.style == 1)
+ {
+ self.ammo_nails = 5;
+ }
+ if (self.style == 2)
+ {
+ self.ammo_nails = 5;
+ }
+ if (self.style == 3) //DOE multi-grenade
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 4) // lavaball ogre jaycie erysdren 2021-09-14
+ {
+ self.ammo_rockets = 2;
+ }
+ else if (self.style == 0)
+ {
+ self.ammo_rockets = 2;
+ }
+if(!self.keep_ammo)DropBackpack();};
+void() ogre_bdie4 =[ $bdeath4, ogre_bdie5 ] {ai_forward(1);};
+void() ogre_bdie5 =[ $bdeath5, ogre_bdie6 ] {ai_forward(3);};
+void() ogre_bdie6 =[ $bdeath6, ogre_bdie7 ] {ai_forward(7);};
+void() ogre_bdie7 =[ $bdeath7, ogre_bdie8 ] {ai_forward(25);};
+void() ogre_bdie8 =[ $bdeath8, ogre_bdie9 ] {};
+void() ogre_bdie9 =[ $bdeath9, ogre_bdie10 ] {};
+void() ogre_bdie10 =[ $bdeath10, ogre_bdie10 ] {};
+
+void() ogre_die =
+{
+// check for gib
+ if (self.health < -80)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_ogre.mdl", self.health);
+ }
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+
+ sound_death (self, CHAN_VOICE, "ogre/ogdth.wav", 1, ATTN_NORM);
+
+ DropStuff();
+ if (random() < 0.5)
+ ogre_die1 ();
+ else
+ ogre_bdie1 ();
+};
+
+void() ogre_melee =
+{
+ if (random() > 0.5)
+ ogre_smash1 ();
+ else
+ ogre_swing1 ();
+};
+
+
+/*QUAKED monster_ogre (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/ogre.mdl");
+}
+Ogre.
+
+Default health = 200"
+
+style(Choices) : "Attack type" =
+0 : "Default (grenade)"
+1 : "Flak Ogre (Marcher, Quoth)"
+2 : "sniper (shoots single, deadly lava round)"
+3 : "multi-grenade (Mission Pack 2)"
+
+keep_ammo(integer) : "1 = Don't drop backpack upon death"
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound (CHAINSAW)"
+snd_idle(string) : "Path to custom idle sound (IDLE)"
+snd_misc(string) : "Path to custom sound (IDLE CHAINSAW DRAG)"
+snd_misc1(string) : "Path to custom sound (ATTACK GRUNT)"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+mdl_proj(string) : "Path to custom projectile model"
+skin_head(float) : "Skin index of custom head model"
+skin_proj(float) : "Skin index of custom projectile model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_ogre =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ // custom_mdls dumptruck_ds
+ precache_body_model ("progs/ogre.mdl");
+ precache_head_model ("progs/h_ogre.mdl");
+ precache_proj_model ("progs/grenade.mdl");
+
+ // custom_mdls dumptruck_ds
+ precache_model ("progs/mervup.mdl"); //for style 3 Orge dumptruck_ds
+ precache_model ("progs/lspike.mdl"); //for style 2 Ogre dumptruck_ds
+ precache_sound_misc ("ogre/ogdrag.wav");
+ precache_sound_death ("ogre/ogdth.wav");
+ precache_sound_idle ("ogre/ogidle.wav");
+ precache_sound_misc1 ("ogre/ogidle2.wav");
+ precache_sound_pain ("ogre/ogpain1.wav");
+ precache_sound_attack ("ogre/ogsawatk.wav");
+ precache_sound_sight ("ogre/ogwake.wav");
+ precache_sound_misc2 ("shalrath/attack2.wav");
+ precache_sound ("fish/bite.wav");
+ precache_sound ("boss1/throw.wav"); // jaycie erysdren 2021-09-14
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ // custom_mdls dumptruck_ds
+ body_model ("progs/ogre.mdl");
+ // setmodel (self, "progs/ogre.mdl");
+
+ setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
+ if (!self.proj_speed_mod)
+ {
+ self.proj_speed_mod = 1;
+ }
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 200;
+
+ self.th_stand = ogre_stand1;
+ self.th_walk = ogre_walk1;
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_run = ogre_turret_seek1;
+ }
+ else
+ {
+ self.th_run = ogre_run1;
+ }
+ self.th_die = ogre_die;
+ self.th_melee = ogre_melee;
+ self.th_missile = ogre_nail1;
+ self.th_turret = ogre_turret_attack1; //dumptruck_ds
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = ogre_pain;
+ else
+ self.th_pain = SUB_NullPain;
+
+ walkmonster_start();
+};
+
+/*QUAKED monster_ogre_marksman (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ({ "path" : "progs/ogre.mdl", "frame": 63 });
+}
+Ogre Marksman.
+Unlike vanilla Quake, this is a slightly more accurate Orge.
+
+keep_ammo(integer) : "1 = Don't drop backpack upon death"
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound (CHAINSAW)"
+snd_idle(string) : "Path to custom idle sound (IDLE)"
+snd_misc(string) : "Path to custom sound (IDLE CHAINSAW DRAG)"
+snd_misc1(string) : "Path to custom sound (ATTACK GRUNT)"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+mdl_proj(string) : "Path to custom projectile model"
+skin_head(float) : "Skin index of custom head model"
+skin_proj(float) : "Skin index of custom projectile model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_ogre_marksman =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ // custom_mdls dumptruck_ds
+ precache_body_model ("progs/ogre.mdl");
+ precache_head_model ("progs/h_ogre.mdl");
+ precache_proj_model ("progs/grenade.mdl");
+
+ precache_sound_misc ("ogre/ogdrag.wav");
+ precache_sound_death ("ogre/ogdth.wav");
+ precache_sound_idle ("ogre/ogidle.wav");
+ precache_sound_misc1 ("ogre/ogidle2.wav");
+ precache_sound_pain ("ogre/ogpain1.wav");
+ precache_sound_attack ("ogre/ogsawatk.wav");
+ precache_sound_sight ("ogre/ogwake.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ // custom_mdls dumptruck_ds
+ body_model ("progs/ogre.mdl");
+ // setmodel (self, "progs/ogre.mdl");
+
+ setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
+ if (!self.proj_speed_mod)
+ {
+ self.proj_speed_mod = 1;
+ }
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 200;
+
+ self.th_stand = ogre_stand1;
+ self.th_walk = ogre_walk1;
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_run = ogre2_turret_seek1;
+ }
+ else
+ {
+ self.th_run = ogre_run1;
+ }
+ self.th_die = ogre_die;
+ self.th_melee = ogre_melee;
+ self.th_missile = ogre2_nail1;
+ self.th_turret = ogre2_turret_attack1; //dumptruck_ds
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = ogre_pain;
+ else
+ self.th_pain = SUB_NullPain;
+
+ walkmonster_start();
+};
+
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// monster_ogre ();
+// };
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_ogre (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID ON_SIDE X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/ogre.mdl","frame":135});
+}
+*/
+void() monster_dead_ogre =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/ogre.mdl");
+ setmodel(self, "progs/ogre.mdl");
+ if (self.spawnflags & 2)
+ {
+ self.frame = $death14;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-40.64 -54.06 -54.1','29.42 54.63 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+ else
+ {
+ self.frame = $bdeath10;
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-45.64 -29.46 -54.52','33.87 39.18 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/oldone.qc

diff --git a/qc/monsters/oldone.qc b/qc/monsters/oldone.qc
new file mode 100644
index 0000000..fb470bd
--- /dev/null
+++ b/qc/monsters/oldone.qc
@@ -0,0 +1,296 @@
+/*
+==============================================================================
+
+OLD ONE
+
+==============================================================================
+*/
+$cd id1/models/old_one
+$origin 0 0 24
+$base base
+$skin skin
+$scale 1
+
+void() finale_1;
+void() finale_2;
+void() finale_3;
+void() finale_4;
+
+
+entity shub;
+
+$frame old1 old2 old3 old4 old5 old6 old7 old8 old9
+$frame old10 old11 old12 old13 old14 old15 old16 old17 old18 old19
+$frame old20 old21 old22 old23 old24 old25 old26 old27 old28 old29
+$frame old30 old31 old32 old33 old34 old35 old36 old37 old38 old39
+$frame old40 old41 old42 old43 old44 old45 old46
+
+$frame shake1 shake2 shake3 shake4 shake5 shake6 shake7 shake8
+$frame shake9 shake10 shake11 shake12 shake13 shake14
+$frame shake15 shake16 shake17 shake18 shake19 shake20
+
+//void() old_stand =[ $old1, old_stand ] {};
+
+void() old_idle1 =[ $old1, old_idle2 ] {};
+void() old_idle2 =[ $old2, old_idle3 ] {};
+void() old_idle3 =[ $old3, old_idle4 ] {};
+void() old_idle4 =[ $old4, old_idle5 ] {};
+void() old_idle5 =[ $old5, old_idle6 ] {};
+void() old_idle6 =[ $old6, old_idle7 ] {};
+void() old_idle7 =[ $old7, old_idle8 ] {};
+void() old_idle8 =[ $old8, old_idle9 ] {};
+void() old_idle9 =[ $old9, old_idle10 ] {};
+void() old_idle10 =[ $old10, old_idle11 ] {};
+void() old_idle11 =[ $old11, old_idle12 ] {};
+void() old_idle12 =[ $old12, old_idle13 ] {};
+void() old_idle13 =[ $old13, old_idle14 ] {};
+void() old_idle14 =[ $old14, old_idle15 ] {};
+void() old_idle15 =[ $old15, old_idle16 ] {};
+void() old_idle16 =[ $old16, old_idle17 ] {};
+void() old_idle17 =[ $old17, old_idle18 ] {};
+void() old_idle18 =[ $old18, old_idle19 ] {};
+void() old_idle19 =[ $old19, old_idle20 ] {};
+void() old_idle20 =[ $old20, old_idle21 ] {};
+void() old_idle21 =[ $old21, old_idle22 ] {};
+void() old_idle22 =[ $old22, old_idle23 ] {};
+void() old_idle23 =[ $old23, old_idle24 ] {};
+void() old_idle24 =[ $old24, old_idle25 ] {};
+void() old_idle25 =[ $old25, old_idle26 ] {};
+void() old_idle26 =[ $old26, old_idle27 ] {};
+void() old_idle27 =[ $old27, old_idle28 ] {};
+void() old_idle28 =[ $old28, old_idle29 ] {};
+void() old_idle29 =[ $old29, old_idle30 ] {};
+void() old_idle30 =[ $old30, old_idle31 ] {};
+void() old_idle31 =[ $old31, old_idle32 ] {};
+void() old_idle32 =[ $old32, old_idle33 ] {};
+void() old_idle33 =[ $old33, old_idle34 ] {};
+void() old_idle34 =[ $old34, old_idle35 ] {};
+void() old_idle35 =[ $old35, old_idle36 ] {};
+void() old_idle36 =[ $old36, old_idle37 ] {};
+void() old_idle37 =[ $old37, old_idle38 ] {};
+void() old_idle38 =[ $old38, old_idle39 ] {};
+void() old_idle39 =[ $old39, old_idle40 ] {};
+void() old_idle40 =[ $old40, old_idle41 ] {};
+void() old_idle41 =[ $old41, old_idle42 ] {};
+void() old_idle42 =[ $old42, old_idle43 ] {};
+void() old_idle43 =[ $old43, old_idle44 ] {};
+void() old_idle44 =[ $old44, old_idle45 ] {};
+void() old_idle45 =[ $old45, old_idle46 ] {};
+void() old_idle46 =[ $old46, old_idle1 ] {};
+
+
+void() old_thrash1 =[ $shake1, old_thrash2 ] {lightstyle(0, "m");};
+void() old_thrash2 =[ $shake2, old_thrash3 ] {lightstyle(0, "k");};
+void() old_thrash3 =[ $shake3, old_thrash4 ] {lightstyle(0, "k");};
+void() old_thrash4 =[ $shake4, old_thrash5 ] {lightstyle(0, "i");};
+void() old_thrash5 =[ $shake5, old_thrash6 ] {lightstyle(0, "g");};
+void() old_thrash6 =[ $shake6, old_thrash7 ] {lightstyle(0, "e");};
+void() old_thrash7 =[ $shake7, old_thrash8 ] {lightstyle(0, "c");};
+void() old_thrash8 =[ $shake8, old_thrash9 ] {lightstyle(0, "a");};
+void() old_thrash9 =[ $shake9, old_thrash10 ] {lightstyle(0, "c");};
+void() old_thrash10 =[ $shake10, old_thrash11 ] {lightstyle(0, "e");};
+void() old_thrash11 =[ $shake11, old_thrash12 ] {lightstyle(0, "g");};
+void() old_thrash12 =[ $shake12, old_thrash13 ] {lightstyle(0, "i");};
+void() old_thrash13 =[ $shake13, old_thrash14 ] {lightstyle(0, "k");};
+void() old_thrash14 =[ $shake14, old_thrash15 ] {lightstyle(0, "m");};
+void() old_thrash15 =[ $shake15, old_thrash16 ] {lightstyle(0, "m");
+self.cnt = self.cnt + 1;
+if (self.cnt != 3)
+ self.think = old_thrash1;
+};
+void() old_thrash16 =[ $shake16, old_thrash17 ] {lightstyle(0, "g");};
+void() old_thrash17 =[ $shake17, old_thrash18 ] {lightstyle(0, "c");};
+void() old_thrash18 =[ $shake18, old_thrash19 ] {lightstyle(0, "b");};
+void() old_thrash19 =[ $shake19, old_thrash20 ] {lightstyle(0, "a");};
+void() old_thrash20 =[ $shake20, old_thrash20 ] {finale_4();};
+
+//============================================================================
+
+void() finale_1 =
+{
+ local entity pos, pl;
+ local entity timer;
+
+// 1998-07-30 Shub kill count fix by Maddes start
+ killed_monsters = killed_monsters + 1;
+ WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // FIXME: reliable broadcast
+// 1998-07-30 Shub kill count fix by Maddes end
+
+ intermission_exittime = time + 10000000; // never allow exit
+ intermission_running = 1;
+
+ // find the intermission spot
+ pos = find (world, classname, "info_intermission");
+ if (!pos)
+ error ("no info_intermission");
+ pl = find (world, classname, "misc_teleporttrain");
+ if (!pl)
+ error ("no teleporttrain");
+ remove (pl);
+
+ WriteByte (MSG_ALL, SVC_FINALE);
+ WriteString (MSG_ALL, "");
+
+ pl = find (world, classname, "player");
+ while (pl != world)
+ {
+ pl.view_ofs = '0 0 0';
+ pl.angles = other.v_angle = pos.mangle;
+ pl.fixangle = TRUE; // turn this way immediately
+ pl.map = self.map;
+ pl.nextthink = time + 0.5;
+ pl.takedamage = DAMAGE_NO;
+ pl.solid = SOLID_NOT;
+ pl.movetype = MOVETYPE_NONE;
+ pl.modelindex = 0;
+ setorigin (pl, pos.origin);
+ pl = find (pl, classname, "player");
+ }
+
+ // make fake versions of all players as standins, and move the real
+ // players to the intermission spot
+
+ // wait for 1 second
+ timer = spawn();
+ timer.nextthink = time + 1;
+ timer.think = finale_2;
+};
+
+void() finale_2 =
+{
+ local vector o;
+
+ // start a teleport splash inside shub
+
+ o = shub.origin - '0 100 0';
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_TELEPORT);
+ WriteCoord (MSG_BROADCAST, o_x);
+ WriteCoord (MSG_BROADCAST, o_y);
+ WriteCoord (MSG_BROADCAST, o_z);
+
+ sound (shub, CHAN_VOICE, "misc/r_tele1.wav", 1, ATTN_NORM);
+
+ self.nextthink = time + 2;
+ self.think = finale_3;
+};
+
+void() finale_3 =
+{
+ // start shub thrashing wildly
+ shub.think = old_thrash1;
+ sound_death (shub, CHAN_VOICE, "boss2/death.wav", 1, ATTN_NORM);
+ lightstyle(0, "abcdefghijklmlkjihgfedcb");
+};
+
+void() finale_4 =
+{
+ // throw tons of meat chunks
+ local vector oldo;
+ local float x, y, z;
+ local float r;
+ local entity n;
+
+ sound_misc (self, CHAN_VOICE, "boss2/pop2.wav", 1, ATTN_NORM);
+
+ oldo = self.origin;
+
+ z = 16;
+ while (z <= 144)
+ {
+ x = -64;
+ while (x <= 64)
+ {
+ y = -64;
+ while (y <= 64)
+ {
+ self.origin_x = oldo_x + x;
+ self.origin_y = oldo_y + y;
+ self.origin_z = oldo_z + z;
+
+ r = random();
+ if (r < 0.3)
+ ThrowGib ("progs/gib1.mdl", -999);
+ else if (r < 0.6)
+ ThrowGib ("progs/gib2.mdl", -999);
+ else
+ ThrowGib ("progs/gib3.mdl", -999);
+ y = y + 32;
+ }
+ x = x + 32;
+ }
+ z = z + 96;
+ }
+ // start the end text
+ WriteByte (MSG_ALL, SVC_FINALE);
+ WriteString (MSG_ALL, "Congratulations and well done! You have\nbeaten the hideous Shub-Niggurath, and\nher hundreds of ugly changelings and\nmonsters. You have proven that your\nskill and your cunning are greater than\nall the powers of Quake. You are the\nmaster now. Id Software salutes you.");
+
+// put a player model down
+ n = spawn();
+ setmodel (n, "progs/player.mdl");
+ oldo = oldo - '32 264 0';
+ setorigin (n, oldo);
+ n.angles = '0 290 0';
+ n.frame = 1;
+
+ remove (self);
+
+// switch cd track
+ WriteByte (MSG_ALL, SVC_CDTRACK);
+ WriteByte (MSG_ALL, 3);
+ WriteByte (MSG_ALL, 3);
+ lightstyle(0, "m");
+};
+
+//============================================================================
+
+void(entity attacker, float damage) nopain =
+{
+ self.health = 40000;
+};
+
+//============================================================================
+
+
+/*QUAKED monster_oldone (1 0 0) (-160 -128 -24) (160 128 256)
+*/
+void() monster_oldone =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ objerror("Incompatible spawnflag: TURRET_MODE\n");
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+
+ precache_body_model2 ("progs/oldone.mdl");
+ // precache_model2 ("progs/oldone.mdl");
+
+ precache_sound2_death ("boss2/death.wav");
+// precache_sound2_idle ("boss2/idle.wav");
+ precache_sound2_sight ("boss2/sight.wav");
+ precache_sound2_misc ("boss2/pop2.wav");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/oldone.mdl"); //custom_mdls dumptruck_ds
+ // setmodel (self, "progs/oldone.mdl");
+ setsize (self, '-160 -128 -24', '160 128 256');
+
+ self.health = 40000; // kill by telefrag
+ self.think = old_idle1;
+ self.nextthink = time + 0.1;
+ self.takedamage = DAMAGE_YES;
+ self.th_pain = nopain;
+ self.th_die = finale_1;
+ self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+ shub = self;
+
+ total_monsters = total_monsters + 1;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/oldone2.qc

diff --git a/qc/monsters/oldone2.qc b/qc/monsters/oldone2.qc
new file mode 100644
index 0000000..0cd4047
--- /dev/null
+++ b/qc/monsters/oldone2.qc
@@ -0,0 +1,367 @@
+/*
+==============================================================================
+
+OLD ONE 2 - killable variant -- dumptruck_ds
+
+==============================================================================
+*/
+$cd id1/models/old2_one
+$origin 0 0 24
+$base base
+$skin skin
+$scale 1
+
+$frame old1 old2 old3 old4 old5 old6 old7 old8 old9
+$frame old10 old11 old12 old13 old14 old15 old16 old17 old18 old19
+$frame old20 old21 old22 old23 old24 old25 old26 old27 old28 old29
+$frame old30 old31 old32 old33 old34 old35 old36 old37 old38 old39
+$frame old40 old41 old42 old43 old44 old45 old46
+
+$frame shake1 shake2 shake3 shake4 shake5 shake6 shake7 shake8
+$frame shake9 shake10 shake11 shake12 shake13 shake14
+$frame shake15 shake16 shake17 shake18 shake19 shake20
+
+void() shub_face =
+{
+// go for another player if multi player
+ if (self.enemy.health <= 0 || random() < 0.02)
+ {
+ self.enemy = find(self.enemy, classname, "player");
+ if (!self.enemy)
+ self.enemy = find(self.enemy, classname, "player");
+ }
+ ai_face();
+};
+
+
+void() old2_stand =
+{
+ FindTarget ();
+};
+
+void() old2_idle1 =[ $old1, old2_idle2 ] {old2_stand();};
+void() old2_idle2 =[ $old2, old2_idle3 ] {old2_stand();};
+void() old2_idle3 =[ $old3, old2_idle4 ] {old2_stand();};
+void() old2_idle4 =[ $old4, old2_idle5 ] {old2_stand();};
+void() old2_idle5 =[ $old5, old2_idle6 ] {old2_stand();};
+void() old2_idle6 =[ $old6, old2_idle7 ] {old2_stand();};
+void() old2_idle7 =[ $old7, old2_idle8 ] {old2_stand();};
+void() old2_idle8 =[ $old8, old2_idle9 ] {old2_stand();};
+void() old2_idle9 =[ $old9, old2_idle10 ] {old2_stand();};
+void() old2_idle10 =[ $old10, old2_idle11 ] {old2_stand();};
+void() old2_idle11 =[ $old11, old2_idle12 ] {old2_stand();};
+void() old2_idle12 =[ $old12, old2_idle13 ] {old2_stand();};
+void() old2_idle13 =[ $old13, old2_idle14 ] {old2_stand();};
+void() old2_idle14 =[ $old14, old2_idle15 ] {old2_stand();};
+void() old2_idle15 =[ $old15, old2_idle16 ] {old2_stand();};
+void() old2_idle16 =[ $old16, old2_idle17 ] {old2_stand();};
+void() old2_idle17 =[ $old17, old2_idle18 ] {old2_stand();};
+void() old2_idle18 =[ $old18, old2_idle19 ] {old2_stand();};
+void() old2_idle19 =[ $old19, old2_idle20 ] {old2_stand();};
+void() old2_idle20 =[ $old20, old2_idle21 ] {old2_stand();};
+void() old2_idle21 =[ $old21, old2_idle22 ] {old2_stand();};
+void() old2_idle22 =[ $old22, old2_idle23 ] {old2_stand();};
+void() old2_idle23 =[ $old23, old2_idle24 ] {old2_stand();};
+void() old2_idle24 =[ $old24, old2_idle25 ] {old2_stand();};
+void() old2_idle25 =[ $old25, old2_idle26 ] {old2_stand();};
+void() old2_idle26 =[ $old26, old2_idle27 ] {old2_stand();};
+void() old2_idle27 =[ $old27, old2_idle28 ] {old2_stand();};
+void() old2_idle28 =[ $old28, old2_idle29 ] {old2_stand();};
+void() old2_idle29 =[ $old29, old2_idle30 ] {old2_stand();};
+void() old2_idle30 =[ $old30, old2_idle31 ] {old2_stand();};
+void() old2_idle31 =[ $old31, old2_idle32 ] {old2_stand();};
+void() old2_idle32 =[ $old32, old2_idle33 ] {old2_stand();};
+void() old2_idle33 =[ $old33, old2_idle34 ] {old2_stand();};
+void() old2_idle34 =[ $old34, old2_idle35 ] {old2_stand();};
+void() old2_idle35 =[ $old35, old2_idle36 ] {old2_stand();};
+void() old2_idle36 =[ $old36, old2_idle37 ] {old2_stand();};
+void() old2_idle37 =[ $old37, old2_idle38 ] {old2_stand();};
+void() old2_idle38 =[ $old38, old2_idle39 ] {old2_stand();};
+void() old2_idle39 =[ $old39, old2_idle40 ] {old2_stand();};
+void() old2_idle40 =[ $old40, old2_idle41 ] {old2_stand();};
+void() old2_idle41 =[ $old41, old2_idle42 ] {old2_stand();};
+void() old2_idle42 =[ $old42, old2_idle43 ] {old2_stand();};
+void() old2_idle43 =[ $old43, old2_idle44 ] {old2_stand();};
+void() old2_idle44 =[ $old44, old2_idle45 ] {old2_stand();};
+void() old2_idle45 =[ $old45, old2_idle46 ] {old2_stand();};
+void() old2_idle46 =[ $old46, old2_idle1 ] {old2_stand();};
+
+void(vector p) shub_missile =
+{
+ local vector offang;
+ local vector org, vec, d;
+ local float t;
+
+ offang = vectoangles (self.enemy.origin - self.origin);
+ makevectors (offang);
+
+ org = self.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
+
+// lead the player on hard mode
+ if (skill > 1)
+ {
+ t = vlen(self.enemy.origin - org) / 300;
+ vec = self.enemy.velocity;
+ vec_z = 0;
+ d = self.enemy.origin + t * vec;
+ }
+ else
+ {
+ d = self.enemy.origin;
+ }
+
+ vec = normalize (d - org);
+
+ local entity puff; // added this to motivate fireballs dumptruck_ds
+
+ puff = spawn ();
+
+ setmodel (puff, "progs/s_explod.spr");
+ puff.origin = (org);
+ puff.think = s_explode1;
+ puff.nextthink = time;
+
+ launch_spike2 (org, vec, 300); // lavaball in your face!
+ if (self.mdl_proj != "") // dumptruck_ds custom_mdls
+ {
+ setmodel (newmis, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/lavaball.mdl");
+ }
+
+ if (!newmis.skin_proj) // dumptruck_ds
+ {
+ newmis.skin = self.skin_proj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+
+ // setmodel (newmis, "progs/lavaball.mdl");
+ newmis.avelocity = '200 100 300';
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ newmis.touch = T_MissileTouch; // rocket explosion
+ sound_attack (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM);
+
+// check for dead enemy
+ if (self.enemy.health <= 0)
+ old2_idle1 ();
+};
+
+void() old2_attk1 =[ $old1, old2_attk2 ] {shub_face();};
+void() old2_attk2 =[ $old2, old2_attk3 ] {shub_face();};
+void() old2_attk3 =[ $old3, old2_attk4 ] {shub_face();};
+void() old2_attk4 =[ $old4, old2_attk5 ] {shub_face();};
+void() old2_attk5 =[ $old5, old2_attk6 ] {shub_face();};
+void() old2_attk6 =[ $old6, old2_attk7 ] {shub_face();};
+void() old2_attk7 =[ $old7, old2_attk8 ] {shub_face();};
+void() old2_attk8 =[ $old8, old2_attk9 ] {shub_face();};
+void() old2_attk9 =[ $old9, old2_attk10 ] {shub_missile('0 -16 416');};
+void() old2_attk10 =[ $old10, old2_attk11 ] {shub_face();};
+void() old2_attk11 =[ $old11, old2_attk12 ] {shub_face();};
+void() old2_attk12 =[ $old12, old2_attk13 ] {shub_face();};
+void() old2_attk13 =[ $old13, old2_attk14 ] {shub_face();};
+void() old2_attk14 =[ $old14, old2_attk15 ] {shub_face();};
+void() old2_attk15 =[ $old15, old2_attk16 ] {shub_face();};
+void() old2_attk16 =[ $old16, old2_attk17 ] {shub_face();};
+void() old2_attk17 =[ $old17, old2_attk18 ] {shub_face();};
+void() old2_attk18 =[ $old18, old2_attk19 ] {shub_missile('0 -16 416');};
+void() old2_attk19 =[ $old19, old2_attk20 ] {shub_face();};
+void() old2_attk20 =[ $old20, old2_attk21 ] {shub_face();};
+void() old2_attk21 =[ $old21, old2_attk22 ] {shub_face();};
+void() old2_attk22 =[ $old22, old2_attk23 ] {shub_face();};
+void() old2_attk23 =[ $old23, old2_attk24 ] {shub_face();};
+void() old2_attk24 =[ $old24, old2_attk25 ] {shub_face();};
+void() old2_attk25 =[ $old25, old2_attk26 ] {shub_face();};
+void() old2_attk26 =[ $old26, old2_attk27 ] {shub_face();};
+void() old2_attk27 =[ $old27, old2_attk28 ] {shub_missile('0 -16 416');};
+void() old2_attk28 =[ $old28, old2_attk29 ] {shub_face();};
+void() old2_attk29 =[ $old29, old2_attk30 ] {shub_face();};
+void() old2_attk30 =[ $old30, old2_attk31 ] {shub_face();};
+void() old2_attk31 =[ $old31, old2_attk32 ] {shub_face();};
+void() old2_attk32 =[ $old32, old2_attk33 ] {shub_face();};
+void() old2_attk33 =[ $old33, old2_attk34 ] {shub_face();};
+void() old2_attk34 =[ $old34, old2_attk35 ] {shub_face();};
+void() old2_attk35 =[ $old35, old2_attk36 ] {shub_face();};
+void() old2_attk36 =[ $old36, old2_attk37 ] {shub_missile('0 -16 416');};
+void() old2_attk37 =[ $old37, old2_attk38 ] {shub_face();};
+void() old2_attk38 =[ $old38, old2_attk39 ] {shub_face();};
+void() old2_attk39 =[ $old39, old2_attk40 ] {shub_face();};
+void() old2_attk40 =[ $old40, old2_attk41 ] {shub_face();};
+void() old2_attk41 =[ $old41, old2_attk42 ] {shub_face();};
+void() old2_attk42 =[ $old42, old2_attk43 ] {shub_face();};
+void() old2_attk43 =[ $old43, old2_attk44 ] {shub_face();};
+void() old2_attk44 =[ $old44, old2_attk45 ] {shub_face();};
+void() old2_attk45 =[ $old45, old2_attk46 ] {shub_missile('0 -16 416');};
+void() old2_attk46 =[ $old46, old2_attk1 ] {shub_face();};
+//death twitch --dumptruck_ds
+void() old2_twitch1 =[ $shake1, old2_twitch2 ] {sound_misc (self, CHAN_VOICE, "boss2/pop2.wav", 1, ATTN_NONE);};
+void() old2_twitch2 =[ $shake2, old2_twitch3 ] {};
+void() old2_twitch3 =[ $shake3, old2_twitch4 ] {};
+void() old2_twitch4 =[ $shake4, old2_twitch5 ] {};
+void() old2_twitch5 =[ $shake5, old2_twitch6 ] {};
+void() old2_twitch6 =[ $shake6, old2_twitch7 ] {};
+void() old2_twitch7 =[ $shake7, old2_twitch8 ] {};
+void() old2_twitch8 =[ $shake8, old2_twitch9 ] {};
+void() old2_twitch9 =[ $shake9, old2_twitch10 ] {};
+void() old2_twitch10 =[ $shake10, old2_twitch11 ] {};
+void() old2_twitch11 =[ $shake11, old2_twitch12 ] {};
+void() old2_twitch12 =[ $shake12, old2_twitch13 ] {};
+void() old2_twitch13 =[ $shake13, old2_twitch14 ] {};
+void() old2_twitch14 =[ $shake14, old2_twitch15 ] {};
+void() old2_twitch15 =[ $shake15, old2_twitch16 ] {};
+void() old2_twitch16 =[ $shake16, old2_twitch17 ] {};
+void() old2_twitch17 =[ $shake17, old2_twitch18 ] {};
+void() old2_twitch18 =[ $shake18, old2_twitch19 ] {};
+void() old2_twitch19 =[ $shake19, old2_twitch20 ] {};
+void() old2_twitch20 =[ $shake20, old2_twitch21 ] {};
+void() old2_twitch21 =[ $shake17, old2_twitch22 ] {};
+void() old2_twitch22 =[ $shake18, old2_twitch23 ] {};
+void() old2_twitch23 =[ $shake19, old2_twitch24 ] {};
+void() old2_twitch24 =[ $shake20, old2_twitch25 ] {};
+void() old2_twitch25 =[ $shake17, old2_twitch26 ] {};
+void() old2_twitch26 =[ $shake18, old2_twitch27 ] {};
+void() old2_twitch27 =[ $shake19, old2_twitch28 ] {};
+void() old2_twitch28 =[ $shake20, oldone2_die ] {};
+
+void(entity attacker, float damage) oldone2_pain =
+{
+ if (self.pain_finished > time)
+ return;
+
+ sound_pain (self, CHAN_AUTO, "oldone2/pd_pop2.wav", 1, ATTN_NORM); //new pain sound
+ old2_attk1();
+ self.pain_finished = time + 4;
+};
+
+void() oldone2_die =
+{
+// 1998-07-30 Shub kill count fix by Maddes start
+ //killed_monsters = killed_monsters + 1;
+ //WriteByte (MSG_ALL, SVC_KILLEDMONSTER); // Already done by FL_MONSTER
+// 1998-07-30 Shub kill count fix by Maddes end
+ // throw tons of meat chunks
+ local vector oldo;
+ local float x, y, z;
+ local float r;
+
+ oldo = self.origin + '0 0 112';
+
+ z = 16;
+ while (z <= 144)
+ {
+ x = -64;
+ while (x <= 64)
+ {
+ y = -64;
+ while (y <= 64)
+ {
+ self.origin_x = oldo_x + x;
+ self.origin_y = oldo_y + y;
+ self.origin_z = oldo_z + z;
+
+ r = random();
+ if (r < 0.3)
+ // ThrowGib ("progs/gib1.mdl", -120);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, -120);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", -120);
+ }
+ else if (r < 0.6)
+ // ThrowGib ("progs/gib2.mdl", -120);
+ if (self.mdl_gib2 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib2, -120);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", -120);
+ }
+ else
+ // ThrowGib ("progs/gib3.mdl", -120);
+ if (self.mdl_gib3 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib3, -120);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", -120);
+ }
+ y = y + 32;
+ }
+ x = x + 32;
+ }
+ z = z + 96;
+ }
+ particle (oldo, '0 0 0', 0, 255);
+ particle (oldo, '128 128 128', 0, 255);
+ sound_death (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
+
+ remove (self);
+}
+
+/*QUAKED monster_oldone2 (1 0 0) (-160 -128 -24) (160 128 256)
+*/
+void() monster_oldone2 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ objerror("Incompatible spawnflag: TURRET_MODE\n");
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+
+ precache_body_model2 ("progs/oldone.mdl");
+ // precache_model2 ("progs/oldone.mdl");
+
+ precache_sound2_death ("boss2/death.wav");
+ // precache_sound2_idle ("boss2/idle.wav");
+ precache_sound2_sight ("boss2/sight.wav");
+ precache_sound2_misc ("boss2/pop2.wav");
+ precache_sound2_pain ("oldone2/pd_pop2.wav");
+
+ precache_model ("progs/lavaball.mdl");
+ precache_sound ("boss1/throw.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/oldone.mdl"); //custom_mdls dumptruck_ds
+ // setmodel (self, "progs/oldone.mdl");
+ setsize (self, '-160 -128 -24', '160 128 256');
+
+ if (!self.health)
+ {
+ if (skill == 0)
+ self.health = 1000;
+ else
+ self.health = 3000;
+ }
+
+ self.flags = FL_MONSTER;
+ self.think = old2_idle1;
+ self.nextthink = time + 0.1;
+ self.takedamage = DAMAGE_AIM;
+ self.th_run = old2_attk1;
+ self.th_pain = oldone2_pain;
+ self.th_die = old2_twitch1;
+ self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+
+ total_monsters = total_monsters + 1;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/shalrath.qc

diff --git a/qc/monsters/shalrath.qc b/qc/monsters/shalrath.qc
new file mode 100644
index 0000000..f799fe4
--- /dev/null
+++ b/qc/monsters/shalrath.qc
@@ -0,0 +1,433 @@
+/*
+==============================================================================
+
+SHAL-RATH
+
+==============================================================================
+*/
+$cd id1/models/shalrath
+$origin 0 0 24
+$base base
+$skin skin
+$scale 0.7
+
+$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
+$frame attack9 attack10 attack11
+
+$frame pain1 pain2 pain3 pain4 pain5
+
+$frame death1 death2 death3 death4 death5 death6 death7
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
+$frame walk11 walk12
+
+void(entity attacker, float damage) shalrath_pain;
+void() ShalMissile;
+void() shal_stand =[ $walk1, shal_stand ] {ai_stand();};
+
+void() shal_walk1 =[ $walk2, shal_walk2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE);
+ai_walk(6);};
+void() shal_walk2 =[ $walk3, shal_walk3 ] {ai_walk(4);};
+void() shal_walk3 =[ $walk4, shal_walk4 ] {ai_walk(0);};
+void() shal_walk4 =[ $walk5, shal_walk5 ] {ai_walk(0);};
+void() shal_walk5 =[ $walk6, shal_walk6 ] {ai_walk(0);};
+void() shal_walk6 =[ $walk7, shal_walk7 ] {ai_walk(0);};
+void() shal_walk7 =[ $walk8, shal_walk8 ] {ai_walk(5);};
+void() shal_walk8 =[ $walk9, shal_walk9 ] {ai_walk(6);};
+void() shal_walk9 =[ $walk10, shal_walk10 ] {ai_walk(5);};
+void() shal_walk10 =[ $walk11, shal_walk11 ] {ai_walk(0);};
+void() shal_walk11 =[ $walk12, shal_walk12 ] {ai_walk(4);};
+void() shal_walk12 =[ $walk1, shal_walk1 ] {ai_walk(5);};
+
+void() shal_run1 =[ $walk2, shal_run2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE);
+ai_run(6);};
+void() shal_run2 =[ $walk3, shal_run3 ] {ai_run(4);};
+void() shal_run3 =[ $walk4, shal_run4 ] {ai_run(0);};
+void() shal_run4 =[ $walk5, shal_run5 ] {ai_run(0);};
+void() shal_run5 =[ $walk6, shal_run6 ] {ai_run(0);};
+void() shal_run6 =[ $walk7, shal_run7 ] {ai_run(0);};
+void() shal_run7 =[ $walk8, shal_run8 ] {ai_run(5);};
+void() shal_run8 =[ $walk9, shal_run9 ] {ai_run(6);};
+void() shal_run9 =[ $walk10, shal_run10 ] {ai_run(5);};
+void() shal_run10 =[ $walk11, shal_run11 ] {ai_run(0);};
+void() shal_run11 =[ $walk12, shal_run12 ] {ai_run(4);};
+void() shal_run12 =[ $walk1, shal_run1 ] {ai_run(5);};
+
+void() shal_attack1 =[ $attack1, shal_attack2 ] {
+sound_attack (self, CHAN_VOICE, "shalrath/attack.wav", 1, ATTN_NORM);
+ai_face();
+};
+void() shal_attack2 =[ $attack2, shal_attack3 ] {ai_face();};
+void() shal_attack3 =[ $attack3, shal_attack4 ] {ai_face();};
+void() shal_attack4 =[ $attack4, shal_attack5 ] {ai_face();};
+void() shal_attack5 =[ $attack5, shal_attack6 ] {ai_face();};
+void() shal_attack6 =[ $attack6, shal_attack7 ] {ai_face();};
+void() shal_attack7 =[ $attack7, shal_attack8 ] {ai_face();};
+void() shal_attack8 =[ $attack8, shal_attack9 ] {ai_face();};
+void() shal_attack9 =[ $attack9, shal_attack10 ] {ShalMissile();};
+void() shal_attack10 =[ $attack10, shal_attack11 ] {ai_face();};
+void() shal_attack11 =[ $attack11, shal_run1 ] {};
+//////////////////////////
+/// new frames for turret mode START
+//////////////////////////
+void() shal_turret_attack1 =[ $attack1, shal_turret_attack2 ] {
+sound_attack (self, CHAN_VOICE, "shalrath/attack.wav", 1, ATTN_NORM);
+ai_face();
+};
+void() shal_turret_attack2 =[ $attack2, shal_turret_attack3 ] {ai_face();};
+void() shal_turret_attack3 =[ $attack3, shal_turret_attack4 ] {ai_face();};
+void() shal_turret_attack4 =[ $attack4, shal_turret_attack5 ] {ai_face();};
+void() shal_turret_attack5 =[ $attack5, shal_turret_attack6 ] {ai_face();};
+void() shal_turret_attack6 =[ $attack6, shal_turret_attack7 ] {ai_face();};
+void() shal_turret_attack7 =[ $attack7, shal_turret_attack8 ] {ai_face();};
+void() shal_turret_attack8 =[ $attack8, shal_turret_attack9 ] {ai_face();};
+void() shal_turret_attack9 =[ $attack9, shal_turret_attack10 ] {ShalMissile();};
+void() shal_turret_attack10 =[ $attack10, shal_turret_attack11 ] {ai_face();};
+void() shal_turret_attack11 =[ $attack11, shal_turret_attack12 ] {ai_face();};
+void() shal_turret_attack12 =[ $walk1, shal_turret_attack13 ] {ai_face();};
+void() shal_turret_attack13 =[ $walk1, shal_turret_attack14 ] {ai_face();};
+void() shal_turret_attack14 =[ $walk1, shal_turret_attack15 ] {ai_face();};
+void() shal_turret_attack15 =[ $walk1, shal_seek_stand1 ] {ai_run(0);};
+void() shal_seek_stand1 =[ $walk1, shal_seek_stand2 ] {ai_run(0);};
+void() shal_seek_stand2 =[ $walk1, shal_seek_stand1 ] {ai_run(0);};
+//////////////////////////
+/// new frames for turret mode END
+//////////////////////////
+void() shal_pain1 =[ $pain1, shal_pain2 ] {};
+void() shal_pain2 =[ $pain2, shal_pain3 ] {};
+void() shal_pain3 =[ $pain3, shal_pain4 ] {};
+void() shal_pain4 =[ $pain4, shal_pain5 ] {};
+void() shal_pain5 =[ $pain5, shal_run1 ] {};
+
+void() shal_death1 =[ $death1, shal_death2 ] {};
+void() shal_death2 =[ $death2, shal_death3 ] {};
+void() shal_death3 =[ $death3, shal_death4 ] {};
+void() shal_death4 =[ $death4, shal_death5 ] {};
+void() shal_death5 =[ $death5, shal_death6 ] {};
+void() shal_death6 =[ $death6, shal_death7 ] {};
+void() shal_death7 =[ $death7, shal_death7 ] {};
+
+
+void(entity attacker, float damage) shalrath_pain =
+{
+ if (self.pain_finished > time)
+ return;
+
+ sound_pain (self, CHAN_AUTO, "shalrath/pain.wav", 1, ATTN_NORM); //CHAN_AUTO was voice - dumptruck_ds
+ self.pain_finished = time + 3;
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+ else
+ shal_pain1();
+};
+
+void() shalrath_die =
+{
+// check for gib
+ if (self.health < -90)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_shal.mdl", self.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+ // insert death sounds here
+ sound_death (self, CHAN_VOICE, "shalrath/death.wav", 1, ATTN_NORM);
+ DropStuff();
+ shal_death1();
+ self.solid = SOLID_NOT;
+};
+
+/*
+================
+ShalMissile
+================
+*/
+void() ShalMissileTouch;
+void() ShalMissile =
+{
+ local entity missile;
+ local vector dir;
+ local float dist, flytime;
+
+ dir = normalize((self.enemy.origin + '0 0 10') - self.origin);
+ dist = vlen (self.enemy.origin - self.origin);
+ flytime = dist * 0.002 * (1/self.proj_speed_mod);
+ if (flytime < 0.1)
+ flytime = 0.1;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ sound_misc (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = self;
+
+ missile.solid = SOLID_BBOX;
+ missile.movetype = MOVETYPE_FLYMISSILE;
+
+ if (self.mdl_proj != "") // dumptruck_ds custom_mdls
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/v_spike.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+
+ // setmodel (missile, "progs/v_spike.mdl");
+
+ setsize (missile, '0 0 0', '0 0 0');
+
+ missile.origin = self.origin + '0 0 10';
+ SetSpeed(missile, dir, 400 * self.proj_speed_mod);
+ missile.avelocity = self.avelocity; // custom spin on projectile --dumptruck_ds
+ if !(missile.avelocity)
+ missile.avelocity = '300 300 300';
+ if (self.homing > 0) // If homing is off, don't bother doing any thinking
+ {
+ missile.homing = self.homing;
+ missile.nextthink = flytime + time;
+ missile.think = MissileHome;
+ }
+ if (skill == 3)
+ missile.proj_basespeed = 350 * self.proj_speed_mod;
+ else
+ missile.proj_basespeed = 250 * self.proj_speed_mod;
+ missile.enemy = self.enemy;
+ missile.touch = ShalMissileTouch;
+};
+
+
+// void() ShalMissileTouch = --moved to misc.qc for voreball shooter --dumptruck_ds
+// {
+// if (other == self.owner)
+// return; // don't explode on owner
+//
+// if (other.classname == "monster_zombie")
+// T_Damage (other, self, self, 110);
+// T_RadiusDamage (self, self.owner, 40, world);
+// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
+//
+// WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+// WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+// WriteCoord (MSG_BROADCAST, self.origin_x);
+// WriteCoord (MSG_BROADCAST, self.origin_y);
+// WriteCoord (MSG_BROADCAST, self.origin_z);
+//
+// self.velocity = '0 0 0';
+// self.touch = SUB_Null;
+// setmodel (self, "progs/s_explod.spr");
+// self.solid = SOLID_NOT;
+// s_explode1 ();
+// };
+
+//=================================================================
+
+/*QUAKED monster_shalrath (1 0 0) (-32 -32 -24) (32 32 48) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({ "path" : "progs/shalrath.mdl", "frame": 23 });
+}
+Vore.
+
+Default health = 400
+
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound (VORE SNARL)"
+snd_idle(string) : "Path to custom idle sound"
+snd_misc(string) : "Path to custom attack2 sound (VOREBALL FIRE)"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+mdl_proj(string) : "Path to custom projectile model"
+skin_head(float) : "Skin index of custom head model"
+skin_proj(float) : "Skin index of custom projectile model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+homing(float) : "Amount that the projectile should home in target. 1 is default, 0 is none."
+
+*/
+void() monster_shalrath =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ //dumptruck_ds custom_mdls
+ precache_body_model2 ("progs/shalrath.mdl");
+ precache_head_model2 ("progs/h_shal.mdl");
+ precache_proj_model2 ("progs/v_spike.mdl");
+// dumptruck_ds
+ precache_sound2_attack ("shalrath/attack.wav");
+ precache_sound2_misc ("shalrath/attack2.wav");
+ precache_sound2_death ("shalrath/death.wav");
+ precache_sound2_idle ("shalrath/idle.wav");
+ precache_sound2_pain ("shalrath/pain.wav");
+ precache_sound2_sight ("shalrath/sight.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/shalrath.mdl");
+ // setmodel (self, "progs/shalrath.mdl");
+ setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 400;
+
+ if (!self.proj_speed_mod)
+ {
+ self.proj_speed_mod = 1;
+ }
+
+ if (!self.homing) // default to normal
+ {
+ self.homing = 1;
+ }
+ else if (self.homing < 0) // disable with negative
+ {
+ self.homing = 0;
+ }
+
+ self.th_stand = shal_stand;
+ self.th_walk = shal_walk1;
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_run = shal_seek_stand1;
+ }
+ else
+ {
+ self.th_run = shal_run1;
+ }
+
+ self.th_die = shalrath_die;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = shalrath_pain;
+ else
+ self.th_pain = SUB_NullPain;
+ self.th_missile = shal_attack1;
+ self.th_turret = shal_turret_attack1;
+ self.think = walkmonster_start;
+ self.nextthink = time + 0.1 + random ()*0.1;
+
+};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_shalrath (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/shalrath.mdl","frame":22});
+}
+*/
+void() monster_dead_shalrath =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/shalrath.mdl");
+ setmodel(self, "progs/shalrath.mdl");
+ self.frame = $death7;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-41.41 -40.06 -49.38','34.52 24.32 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/shambler.qc

diff --git a/qc/monsters/shambler.qc b/qc/monsters/shambler.qc
new file mode 100644
index 0000000..cfa6a01
--- /dev/null
+++ b/qc/monsters/shambler.qc
@@ -0,0 +1,727 @@
+/*
+==============================================================================
+
+SHAMBLER
+
+==============================================================================
+
+================
+ShamRocket
+================
+*/
+void() ShamRocket =
+{
+ local entity missile;
+ local float projspeed = 900 * self.proj_speed_mod;
+
+ sound_attack (self, CHAN_AUTO, "boss1/throw.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_FLYMISSILE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "missile";
+
+// set missile speed -- dumptruck_ds below
+
+ SetSpeed(missile, normalize(self.enemy.origin - self.origin), projspeed);
+ missile.angles = vectoangles(missile.velocity);
+ missile.avelocity = self.cust_avelocity; //custom spin of projectile
+ if !(missile.avelocity)
+ missile.avelocity = '200 100 300';
+
+ missile.touch = T_MissileTouch;
+
+// set missile duration
+ if (self.homing > 0)
+ {
+ SetupHoming(missile, projspeed);
+ }
+ else
+ {
+ missile.nextthink = time + 5;
+ missile.think = SUB_Remove;
+ }
+ missile.skin = self.skin_proj; //dumptruck_ds
+
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/lavaball.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+ setsize (missile, '0 0 0', '0 0 0');
+ makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
+ setorigin (missile, self.origin + v_forward*8 + '0 0 24');
+};
+
+
+$cd id1/models/shams
+$origin 0 0 24
+$base base
+$skin base
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
+$frame stand10 stand11 stand12 stand13 stand14 stand15 stand16 stand17
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7
+$frame walk8 walk9 walk10 walk11 walk12
+
+$frame run1 run2 run3 run4 run5 run6
+
+$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7
+$frame smash8 smash9 smash10 smash11 smash12
+
+$frame swingr1 swingr2 swingr3 swingr4 swingr5
+$frame swingr6 swingr7 swingr8 swingr9
+
+$frame swingl1 swingl2 swingl3 swingl4 swingl5
+$frame swingl6 swingl7 swingl8 swingl9
+
+$frame magic1 magic2 magic3 magic4 magic5
+$frame magic6 magic7 magic8 magic9 magic10 magic11 magic12
+
+$frame pain1 pain2 pain3 pain4 pain5 pain6
+
+$frame death1 death2 death3 death4 death5 death6
+$frame death7 death8 death9 death10 death11
+
+void() sham_stand1 =[ $stand1, sham_stand2 ] {ai_stand();};
+void() sham_stand2 =[ $stand2, sham_stand3 ] {ai_stand();};
+void() sham_stand3 =[ $stand3, sham_stand4 ] {ai_stand();};
+void() sham_stand4 =[ $stand4, sham_stand5 ] {ai_stand();};
+void() sham_stand5 =[ $stand5, sham_stand6 ] {ai_stand();};
+void() sham_stand6 =[ $stand6, sham_stand7 ] {ai_stand();};
+void() sham_stand7 =[ $stand7, sham_stand8 ] {ai_stand();};
+void() sham_stand8 =[ $stand8, sham_stand9 ] {ai_stand();};
+void() sham_stand9 =[ $stand9, sham_stand10] {ai_stand();};
+void() sham_stand10 =[ $stand10, sham_stand11] {ai_stand();};
+void() sham_stand11 =[ $stand11, sham_stand12] {ai_stand();};
+void() sham_stand12 =[ $stand12, sham_stand13] {ai_stand();};
+void() sham_stand13 =[ $stand13, sham_stand14] {ai_stand();};
+void() sham_stand14 =[ $stand14, sham_stand15] {ai_stand();};
+void() sham_stand15 =[ $stand15, sham_stand16] {ai_stand();};
+void() sham_stand16 =[ $stand16, sham_stand17] {ai_stand();};
+void() sham_stand17 =[ $stand17, sham_stand1 ] {ai_stand();};
+
+void() sham_walk1 =[ $walk1, sham_walk2 ] {ai_walk(10);};
+void() sham_walk2 =[ $walk2, sham_walk3 ] {ai_walk(9);};
+void() sham_walk3 =[ $walk3, sham_walk4 ] {ai_walk(9);};
+void() sham_walk4 =[ $walk4, sham_walk5 ] {ai_walk(5);};
+void() sham_walk5 =[ $walk5, sham_walk6 ] {ai_walk(6);};
+void() sham_walk6 =[ $walk6, sham_walk7 ] {ai_walk(12);};
+void() sham_walk7 =[ $walk7, sham_walk8 ] {ai_walk(8);};
+void() sham_walk8 =[ $walk8, sham_walk9 ] {ai_walk(3);};
+void() sham_walk9 =[ $walk9, sham_walk10] {ai_walk(13);};
+void() sham_walk10 =[ $walk10, sham_walk11] {ai_walk(9);};
+void() sham_walk11 =[ $walk11, sham_walk12] {ai_walk(7);};
+void() sham_walk12 =[ $walk12, sham_walk1 ] {ai_walk(7);
+if (random() > 0.8)
+ sound_idle (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);};
+
+void() sham_run1 =[ $run1, sham_run2 ] {ai_run(20);};
+void() sham_run2 =[ $run2, sham_run3 ] {ai_run(24);};
+void() sham_run3 =[ $run3, sham_run4 ] {ai_run(20);};
+void() sham_run4 =[ $run4, sham_run5 ] {ai_run(20);};
+void() sham_run5 =[ $run5, sham_run6 ] {ai_run(24);};
+void() sham_run6 =[ $run6, sham_run1 ] {ai_run(20);
+if (random() > 0.8)
+ sound_idle (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);
+};
+
+void() sham_smash1 =[ $smash1, sham_smash2 ] {
+sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM);
+ai_charge(2);};
+void() sham_smash2 =[ $smash2, sham_smash3 ] {ai_charge(6);};
+void() sham_smash3 =[ $smash3, sham_smash4 ] {ai_charge(6);};
+void() sham_smash4 =[ $smash4, sham_smash5 ] {ai_charge(5);};
+void() sham_smash5 =[ $smash5, sham_smash6 ] {ai_charge(4);};
+void() sham_smash6 =[ $smash6, sham_smash7 ] {ai_charge(1);};
+void() sham_smash7 =[ $smash7, sham_smash8 ] {ai_charge(0);};
+void() sham_smash8 =[ $smash8, sham_smash9 ] {ai_charge(0);};
+void() sham_smash9 =[ $smash9, sham_smash10 ] {ai_charge(0);};
+void() sham_smash10 =[ $smash10, sham_smash11 ] {
+local vector delta;
+local float ldmg;
+
+ if (!self.enemy)
+ return;
+ ai_charge(0);
+
+ delta = self.enemy.origin - self.origin;
+
+ if (vlen(delta) > 100)
+ return;
+ if (!CanDamage (self.enemy, self))
+ return;
+
+ ldmg = (random() + random() + random()) * 40;
+ T_Damage (self.enemy, self, self, ldmg);
+ sound_hit (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM);
+
+ SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
+ SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
+};
+void() sham_smash11 =[ $smash11, sham_smash12 ] {ai_charge(5);};
+void() sham_smash12 =[ $smash12, sham_run1 ] {ai_charge(4);};
+/////////////////////////////////////
+// new frames for projectile style
+////////////////////////////////////
+void() sham_proj1 =[ $smash1, sham_proj2 ] {ai_face();};
+void() sham_proj2 =[ $smash2, sham_proj3 ] {ai_face();};
+void() sham_proj3 =[ $smash3, sham_proj4 ] {ai_face();};
+void() sham_proj4 =[ $smash4, sham_proj5 ] {ai_face();};
+void() sham_proj5 =[ $smash5, sham_proj6 ] {ai_face();};
+void() sham_proj6 =[ $smash6, sham_proj7 ] {ai_face();};
+void() sham_proj7 =[ $smash7, sham_proj8 ] {ai_face();};
+void() sham_proj8 =[ $smash8, sham_proj9 ] {ai_face();};
+void() sham_proj9 =[ $smash9, sham_proj10 ] {ai_face();};
+void() sham_proj10 =[ $smash10, sham_proj11 ]
+{
+ShamRocket();
+sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); ai_face();
+};
+void() sham_proj11 =[ $smash11, sham_proj12 ] {ai_face();};
+void() sham_proj12 =[ $smash12, sham_run1 ] {ai_face();};
+/// projectile frames for turret mode
+void() sham_turret_proj1 =[ $smash1, sham_turret_proj2 ] {ai_face();};
+void() sham_turret_proj2 =[ $smash2, sham_turret_proj3 ] {ai_face();};
+void() sham_turret_proj3 =[ $smash3, sham_turret_proj4 ] {ai_face();};
+void() sham_turret_proj4 =[ $smash4, sham_turret_proj5 ] {ai_face();};
+void() sham_turret_proj5 =[ $smash5, sham_turret_proj6 ] {ai_face();};
+void() sham_turret_proj6 =[ $smash6, sham_turret_proj7 ] {ai_face();};
+void() sham_turret_proj7 =[ $smash7, sham_turret_proj8 ] {ai_face();};
+void() sham_turret_proj8 =[ $smash8, sham_turret_proj9 ] {ai_face();};
+void() sham_turret_proj9 =[ $smash9, sham_turret_proj10 ] {ai_face();};
+void() sham_turret_proj10 =[ $smash10, sham_turret_proj11 ]
+{
+ShamRocket();
+sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); ai_face();
+};
+void() sham_turret_proj11 =[ $smash11, sham_turret_proj12 ] {ai_face();};
+void() sham_turret_proj12 =[ $smash12, sham_seek_1 ] {ai_face();};
+
+void() sham_swingr1;
+
+void(float side) ShamClaw =
+{
+local vector delta;
+local float ldmg;
+
+ if (!self.enemy)
+ return;
+ ai_charge(10);
+
+ delta = self.enemy.origin - self.origin;
+
+ if (vlen(delta) > 100)
+ return;
+
+ ldmg = (random() + random() + random()) * 20;
+ T_Damage (self.enemy, self, self, ldmg);
+ sound_hit (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM);
+
+ if (side)
+ {
+ makevectors (self.angles);
+ SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
+ }
+};
+
+void() sham_swingl1 =[ $swingl1, sham_swingl2 ] {
+sound_misc (self, CHAN_VOICE, "shambler/melee2.wav", 1, ATTN_NORM);
+ai_charge(5);};
+void() sham_swingl2 =[ $swingl2, sham_swingl3 ] {ai_charge(3);};
+void() sham_swingl3 =[ $swingl3, sham_swingl4 ] {ai_charge(7);};
+void() sham_swingl4 =[ $swingl4, sham_swingl5 ] {ai_charge(3);};
+void() sham_swingl5 =[ $swingl5, sham_swingl6 ] {ai_charge(7);};
+void() sham_swingl6 =[ $swingl6, sham_swingl7 ] {ai_charge(9);};
+void() sham_swingl7 =[ $swingl7, sham_swingl8 ] {ai_charge(5); ShamClaw(250);};
+void() sham_swingl8 =[ $swingl8, sham_swingl9 ] {ai_charge(4);};
+void() sham_swingl9 =[ $swingl9, sham_run1 ] {
+ai_charge(8);
+if (random()<0.5)
+ self.think = sham_swingr1;
+};
+
+void() sham_swingr1 =[ $swingr1, sham_swingr2 ] {
+sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM);
+ai_charge(1);};
+void() sham_swingr2 =[ $swingr2, sham_swingr3 ] {ai_charge(8);};
+void() sham_swingr3 =[ $swingr3, sham_swingr4 ] {ai_charge(14);};
+void() sham_swingr4 =[ $swingr4, sham_swingr5 ] {ai_charge(7);};
+void() sham_swingr5 =[ $swingr5, sham_swingr6 ] {ai_charge(3);};
+void() sham_swingr6 =[ $swingr6, sham_swingr7 ] {ai_charge(6);};
+void() sham_swingr7 =[ $swingr7, sham_swingr8 ] {ai_charge(6); ShamClaw(-250);};
+void() sham_swingr8 =[ $swingr8, sham_swingr9 ] {ai_charge(3);};
+void() sham_swingr9 =[ $swingr9, sham_run1 ] {ai_charge(1);
+ai_charge(10);
+if (random()<0.5)
+ self.think = sham_swingl1;
+};
+
+void() sham_melee2 =
+{
+ local float chance;
+
+ chance = random();
+
+ if (chance > 0.6)
+ sham_swingr1 ();
+ else
+ sham_swingl1 ();
+};
+
+void() sham_melee =
+{
+ local float chance;
+
+ chance = random();
+
+ if (chance > 0.6 || self.health == 600) // changed to >= as you can set custom health
+ sham_smash1 ();
+ else if (chance > 0.3)
+ sham_swingr1 ();
+ else
+ sham_swingl1 ();
+};
+
+
+//============================================================================
+
+
+void() sham_arc_think =
+{
+ if (self.owner != world && self.owner.trigger_field == self)
+ self.owner.trigger_field = world;
+ remove (self);
+};
+
+
+void() CastLightning =
+{
+ local vector org, dir;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ ai_face ();
+
+ org = self.origin + '0 0 40';
+
+ dir = self.enemy.origin + '0 0 16' - org;
+ dir = normalize (dir);
+
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ traceline (org, self.origin + dir*900, TRUE, self);
+ }
+ else
+ {
+ traceline (org, self.origin + dir*600, TRUE, self);
+ }
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
+ WriteEntity (MSG_BROADCAST, self);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
+ WriteCoord (MSG_BROADCAST, trace_endpos_x);
+ WriteCoord (MSG_BROADCAST, trace_endpos_y);
+ WriteCoord (MSG_BROADCAST, trace_endpos_z);
+
+ LightningDamage (org, trace_endpos, self, 10);
+};
+
+void() sham_magic1 =[ $magic1, sham_magic2 ] {ai_face();
+ sound_misc1 (self, CHAN_WEAPON, "shambler/sattck1.wav", 1, ATTN_NORM);
+};
+void() sham_magic2 =[ $magic2, sham_magic3 ] {ai_face();};
+void() sham_magic3 =[ $magic3, sham_magic4 ] {ai_face();self.nextthink = time + 0.2;
+local entity o;
+
+self.effects = self.effects | EF_MUZZLEFLASH;
+ai_face();
+self.trigger_field = spawn();
+o = self.trigger_field;
+setmodel (o, "progs/s_light.mdl");
+setorigin (o, self.origin);
+o.owner = self;
+o.angles = self.angles;
+o.nextthink = time + 0.7;
+o.think = sham_arc_think;
+};
+void() sham_magic4 =[ $magic4, sham_magic5 ]
+{
+self.effects = self.effects | EF_MUZZLEFLASH;
+self.trigger_field.frame = 1;
+};
+void() sham_magic5 =[ $magic5, sham_magic6 ]
+{
+self.effects = self.effects | EF_MUZZLEFLASH;
+self.trigger_field.frame = 2;
+};
+void() sham_magic6 =[ $magic6, sham_magic9 ]
+{
+remove (self.trigger_field);
+self.trigger_field = world;
+CastLightning();
+sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);
+};
+void() sham_magic9 =[ $magic9, sham_magic10 ]
+{CastLightning();};
+void() sham_magic10 =[ $magic10, sham_magic11 ]
+{CastLightning();};
+void() sham_magic11 =[ $magic11, sham_magic12 ]
+{
+if (skill == 3)
+ CastLightning();
+};
+void() sham_magic12 =[ $magic12, sham_run1 ] {};
+/////////////////////////
+//// turret start
+////////////////////////
+void() sham_turret_magic1 =[ $magic1, sham_turret_magic2 ] {ai_face();
+ sound_misc1 (self, CHAN_WEAPON, "shambler/sattck1.wav", 1, ATTN_NORM);
+};
+void() sham_turret_magic2 =[ $magic2, sham_turret_magic3 ] {ai_face();};
+void() sham_turret_magic3 =[ $magic3, sham_turret_magic4 ] {ai_face();self.nextthink = time + 0.2;
+local entity o;
+
+self.effects = self.effects | EF_MUZZLEFLASH;
+ai_face();
+self.trigger_field = spawn();
+o = self.trigger_field;
+setmodel (o, "progs/s_light.mdl");
+setorigin (o, self.origin);
+o.owner = self;
+o.angles = self.angles;
+o.nextthink = time + 0.7;
+o.think = sham_arc_think;
+};
+void() sham_turret_magic4 =[ $magic4, sham_turret_magic5 ]
+{
+self.effects = self.effects | EF_MUZZLEFLASH;
+self.trigger_field.frame = 1;
+};
+void() sham_turret_magic5 =[ $magic5, sham_turret_magic6 ]
+{
+self.effects = self.effects | EF_MUZZLEFLASH;
+self.trigger_field.frame = 2;
+};
+void() sham_turret_magic6 =[ $magic6, sham_turret_magic9 ]
+{
+remove (self.trigger_field);
+self.trigger_field = world;
+CastLightning();
+sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);
+};
+void() sham_turret_magic9 =[ $magic9, sham_turret_magic10 ]
+{CastLightning();};
+void() sham_turret_magic10 =[ $magic10, sham_turret_magic11 ]
+{CastLightning();};
+void() sham_turret_magic11 =[ $magic11, sham_turret_magic12 ]
+{
+if (skill == 3)
+ CastLightning();
+};
+void() sham_turret_magic12 =[ $magic12, sham_turret_magic13 ] {};
+void() sham_turret_magic13 =[ $stand14, sham_turret_magic14 ] {ai_face();};
+void() sham_turret_magic14 =[ $stand15, sham_turret_magic15 ] {ai_face();};
+void() sham_turret_magic15 =[ $stand16, sham_turret_magic16 ] {ai_face();};
+void() sham_turret_magic16 =[ $stand17, sham_seek_1 ] {};
+void() sham_seek_1 =[ $stand1, sham_seek_2 ] {ai_run(0);};
+void() sham_seek_2 =[ $stand2, sham_seek_3 ] {ai_run(0);};
+void() sham_seek_3 =[ $stand3, sham_seek_4 ] {ai_run(0);};
+void() sham_seek_4 =[ $stand4, sham_seek_5 ] {ai_run(0);};
+void() sham_seek_5 =[ $stand5, sham_seek_6 ] {ai_run(0);};
+void() sham_seek_6 =[ $stand6, sham_seek_7 ] {ai_run(0);};
+void() sham_seek_7 =[ $stand7, sham_seek_8 ] {ai_run(0);};
+void() sham_seek_8 =[ $stand8, sham_seek_9 ] {ai_run(0);};
+void() sham_seek_9 =[ $stand9, sham_seek_10] {ai_run(0);};
+void() sham_seek_10 =[ $stand10, sham_seek_11] {ai_run(0);};
+void() sham_seek_11 =[ $stand11, sham_seek_12] {ai_run(0);};
+void() sham_seek_12 =[ $stand12, sham_seek_13] {ai_run(0);};
+void() sham_seek_13 =[ $stand13, sham_seek_14] {ai_run(0);};
+void() sham_seek_14 =[ $stand14, sham_seek_15] {ai_run(0);};
+void() sham_seek_15 =[ $stand15, sham_seek_16] {ai_run(0);};
+void() sham_seek_16 =[ $stand16, sham_seek_17] {ai_run(0);};
+void() sham_seek_17 =[ $stand17, sham_seek_1 ] {ai_run(0);};
+/////////////////////////
+//// turret end
+////////////////////////
+
+void() sham_pain1 =[ $pain1, sham_pain2 ] {};
+void() sham_pain2 =[ $pain2, sham_pain3 ] {};
+void() sham_pain3 =[ $pain3, sham_pain4 ] {};
+void() sham_pain4 =[ $pain4, sham_pain5 ] {};
+void() sham_pain5 =[ $pain5, sham_pain6 ] {};
+void() sham_pain6 =[ $pain6, sham_run1 ] {};
+
+void(entity attacker, float damage) sham_pain =
+{
+ sound_pain (self, CHAN_VOICE, "shambler/shurt2.wav", 1, ATTN_NORM);
+
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+
+ if (self.health <= 0)
+ return; // allready dying, don't go into pain frame
+
+ if (random()*400 > damage)
+ return; // didn't flinch
+
+ if (self.pain_finished > time)
+ return;
+ self.pain_finished = time + 2;
+
+ if (self.trigger_field != world && self.trigger_field.owner == self)
+ self.trigger_field.frame = 2;
+ self.trigger_field = world;
+
+ sham_pain1 ();
+};
+
+
+//============================================================================
+
+void() sham_death1 =[ $death1, sham_death2 ] {};
+void() sham_death2 =[ $death2, sham_death3 ] {};
+void() sham_death3 =[ $death3, sham_death4 ] {self.solid = SOLID_NOT;};
+void() sham_death4 =[ $death4, sham_death5 ] {};
+void() sham_death5 =[ $death5, sham_death6 ] {};
+void() sham_death6 =[ $death6, sham_death7 ] {};
+void() sham_death7 =[ $death7, sham_death8 ] {};
+void() sham_death8 =[ $death8, sham_death9 ] {};
+void() sham_death9 =[ $death9, sham_death10 ] {};
+void() sham_death10 =[ $death10, sham_death11 ] {};
+void() sham_death11 =[ $death11, sham_death11 ] {};
+
+void() sham_die =
+{
+// check for gib
+ if (self.health < -60)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_shams.mdl", self.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+
+// regular death
+ sound_death (self, CHAN_VOICE, "shambler/sdeath.wav", 1, ATTN_NORM);
+ DropStuff();
+ sham_death1 ();
+};
+
+//============================================================================
+
+
+/*QUAKED monster_shambler (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/shambler.mdl");
+}
+Shambler.
+
+Default health = 600
+
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound (GRUNT)"
+snd_hit(string) : "Path to custom hit sound (FLESH TEARING)"
+snd_idle(string) : "Path to custom idle sound"
+snd_misc(string) : "Path to custom sound (GRUNT 2)"
+snd_misc1(string) : "Path to custom sound (LIGHTNING ZAP)"
+snd_misc2(string) : "Path to custom sound (LIGHTNING BOOM)"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+skin_head(float) : "Skin index of custom head model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_shambler =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ precache_body_model ("progs/shambler.mdl"); // custom_mdls dumptruck_ds
+ precache_head_model ("progs/h_shams.mdl"); // custom_mdls dumptruck_ds
+ // precache_model ("progs/shambler.mdl");
+ precache_model ("progs/s_light.mdl");
+ // precache_model ("progs/h_shams.mdl");
+ precache_model ("progs/bolt.mdl");
+ precache_proj_model ("progs/lavaball.mdl");
+
+ precache_sound_misc1 ("shambler/sattck1.wav");
+ precache_sound_misc2 ("shambler/sboom.wav");
+ precache_sound_death ("shambler/sdeath.wav");
+ precache_sound_pain ("shambler/shurt2.wav");
+ precache_sound_idle ("shambler/sidle.wav");
+ precache_sound_sight ("shambler/ssight.wav");
+ precache_sound_attack ("shambler/melee1.wav");
+ precache_sound_misc ("shambler/melee2.wav");
+ precache_sound_hit ("shambler/smack.wav");
+ precache_sound ("boss1/throw.wav"); // jaycie erysdren 2021-09-14
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+ body_model ("progs/shambler.mdl");
+ // setmodel (self, "progs/shambler.mdl");
+
+ setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 600;
+ if (self.proj_speed_mod <= 0)
+ {
+ self.proj_speed_mod = 1;
+ }
+
+ self.th_stand = sham_stand1;
+ self.th_walk = sham_walk1;
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_run = sham_seek_1;
+ }
+ else
+ {
+ self.th_run = sham_run1;
+ }
+ self.th_die = sham_die;
+ if (self.style == 1)
+ self.th_melee = sham_melee2;
+ else
+ self.th_melee = sham_melee;
+ if (self.style == 1)
+ self.th_missile = sham_proj1;
+ else
+ self.th_missile = sham_magic1;
+ if (self.style == 1)
+ self.th_turret = sham_turret_proj1;
+ else
+ self.th_turret = sham_turret_magic1;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = sham_pain;
+ else
+ self.th_pain = SUB_NullPain;
+
+ walkmonster_start();
+};
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_shambler (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/shambler.mdl","frame":93});
+}
+*/
+void() monster_dead_shambler =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/shambler.mdl");
+ setmodel(self, "progs/shambler.mdl");
+ self.frame = $death11;
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-77.09 -72.17 -51.52','47.44 98.15 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/soldier.qc

diff --git a/qc/monsters/soldier.qc b/qc/monsters/soldier.qc
new file mode 100644
index 0000000..5c22745
--- /dev/null
+++ b/qc/monsters/soldier.qc
@@ -0,0 +1,709 @@
+/*
+==============================================================================
+
+SOLDIER / PLAYER
+
+==============================================================================
+*/
+
+$cd id1/models/soldier3
+$origin 0 -6 24
+$base base
+$skin skin
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8
+
+$frame death1 death2 death3 death4 death5 death6 death7 death8
+$frame death9 death10
+
+$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
+$frame deathc9 deathc10 deathc11
+
+$frame load1 load2 load3 load4 load5 load6 load7 load8 load9 load10 load11
+
+$frame pain1 pain2 pain3 pain4 pain5 pain6
+
+$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10
+$frame painb11 painb12 painb13 painb14
+
+$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10
+$frame painc11 painc12 painc13
+
+$frame run1 run2 run3 run4 run5 run6 run7 run8
+
+$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6 shoot7 shoot8 shoot9
+
+$frame prowl_1 prowl_2 prowl_3 prowl_4 prowl_5 prowl_6 prowl_7 prowl_8
+$frame prowl_9 prowl_10 prowl_11 prowl_12 prowl_13 prowl_14 prowl_15 prowl_16
+$frame prowl_17 prowl_18 prowl_19 prowl_20 prowl_21 prowl_22 prowl_23 prowl_24
+
+/*
+==============================================================================
+SOLDIER CODE
+==============================================================================
+*/
+void() genforcer_fire =
+{
+ local vector org;
+
+ // self.effects = self.effects | EF_MUZZLEFLASH; //redundant -- dumptruck_ds
+ makevectors (self.angles);
+
+ org = self.origin + v_forward * 30 + v_right * 5 + '0 0 12';
+
+ LaunchLaser(org, self.enemy.origin - self.origin);
+};
+/*
+================
+GruntFireGrenade
+================
+*/
+void() GruntFireGrenade =
+{
+ local entity missile;
+
+ // self.effects = self.effects | EF_MUZZLEFLASH; //redundant -- dumptruck_ds
+
+ sound_attack (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+
+// set missile speed
+
+ makevectors (self.angles);
+
+ missile.velocity = normalize(self.enemy.origin - self.origin);
+ missile.velocity = missile.velocity * 600;
+ missile.velocity_z = 200;
+
+ missile.avelocity = '300 300 300';
+
+ missile.angles = vectoangles(missile.velocity);
+
+ missile.touch = OgreGrenadeTouch;
+
+// set missile duration
+ missile.nextthink = time + 2.5;
+ missile.think = OgreGrenadeExplode;
+
+ // setmodel (missile, "progs/grenade.mdl");
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/grenade.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin + v_forward * 30 + v_right * 5 + '0 0 16'); //dumptruck_ds
+};
+
+/*
+================
+MonFireSpike // used for Grunts
+================
+*/
+
+void() MonFireSpike =
+{
+ local vector dir;
+ // local entity old;
+
+ sound_attack (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
+ if (self.style == 5)
+ self.attack_finished = time + 1.5;
+ else
+ self.attack_finished = time + 0.2;
+
+ dir = normalize (self.enemy.origin - self.origin);
+ makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
+
+ launch_spike (self.origin + v_forward * 30 + v_right * 5 + '0 0 12', dir); //dumptruck_ds
+ // launch_spike (self.origin + '0 0 16', dir);
+
+ //newmis.touch = superspike_touch;
+ // setmodel (newmis, "progs/s_spike.mdl");
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (newmis, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/s_spike.mdl");
+ }
+
+ if (!newmis.skin_proj) // dumptruck_ds
+ {
+ newmis.skin = self.skin_proj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+ // dumptruck_ds - end
+
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+};
+
+void() army_fire;
+
+void() army_stand1 =[ $stand1, army_stand2 ] {ai_stand();};
+void() army_stand2 =[ $stand2, army_stand3 ] {ai_stand();};
+void() army_stand3 =[ $stand3, army_stand4 ] {ai_stand();};
+void() army_stand4 =[ $stand4, army_stand5 ] {ai_stand();};
+void() army_stand5 =[ $stand5, army_stand6 ] {ai_stand();};
+void() army_stand6 =[ $stand6, army_stand7 ] {ai_stand();};
+void() army_stand7 =[ $stand7, army_stand8 ] {ai_stand();};
+void() army_stand8 =[ $stand8, army_stand1 ] {ai_stand();};
+
+void() army_walk1 =[ $prowl_1, army_walk2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE);
+ai_walk(1);};
+void() army_walk2 =[ $prowl_2, army_walk3 ] {ai_walk(1);};
+void() army_walk3 =[ $prowl_3, army_walk4 ] {ai_walk(1);};
+void() army_walk4 =[ $prowl_4, army_walk5 ] {ai_walk(1);};
+void() army_walk5 =[ $prowl_5, army_walk6 ] {ai_walk(2);};
+void() army_walk6 =[ $prowl_6, army_walk7 ] {ai_walk(3);};
+void() army_walk7 =[ $prowl_7, army_walk8 ] {ai_walk(4);};
+void() army_walk8 =[ $prowl_8, army_walk9 ] {ai_walk(4);};
+void() army_walk9 =[ $prowl_9, army_walk10 ] {ai_walk(2);};
+void() army_walk10 =[ $prowl_10, army_walk11 ] {ai_walk(2);};
+void() army_walk11 =[ $prowl_11, army_walk12 ] {ai_walk(2);};
+void() army_walk12 =[ $prowl_12, army_walk13 ] {ai_walk(1);};
+void() army_walk13 =[ $prowl_13, army_walk14 ] {ai_walk(0);};
+void() army_walk14 =[ $prowl_14, army_walk15 ] {ai_walk(1);};
+void() army_walk15 =[ $prowl_15, army_walk16 ] {ai_walk(1);};
+void() army_walk16 =[ $prowl_16, army_walk17 ] {ai_walk(1);};
+void() army_walk17 =[ $prowl_17, army_walk18 ] {ai_walk(3);};
+void() army_walk18 =[ $prowl_18, army_walk19 ] {ai_walk(3);};
+void() army_walk19 =[ $prowl_19, army_walk20 ] {ai_walk(3);};
+void() army_walk20 =[ $prowl_20, army_walk21 ] {ai_walk(3);};
+void() army_walk21 =[ $prowl_21, army_walk22 ] {ai_walk(2);};
+void() army_walk22 =[ $prowl_22, army_walk23 ] {ai_walk(1);};
+void() army_walk23 =[ $prowl_23, army_walk24 ] {ai_walk(1);};
+void() army_walk24 =[ $prowl_24, army_walk1 ] {ai_walk(1);};
+
+void() army_run1 =[ $run1, army_run2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE);
+ai_run(11);};
+void() army_run2 =[ $run2, army_run3 ] {ai_run(15);};
+void() army_run3 =[ $run3, army_run4 ] {ai_run(10);};
+void() army_run4 =[ $run4, army_run5 ] {ai_run(10);};
+void() army_run5 =[ $run5, army_run6 ] {ai_run(8);};
+void() army_run6 =[ $run6, army_run7 ] {ai_run(15);};
+void() army_run7 =[ $run7, army_run8 ] {ai_run(10);};
+void() army_run8 =[ $run8, army_run1 ] {ai_run(8);};
+
+
+void() army_atk6;
+void() army_atk1 =[ $shoot1, army_atk2 ] {ai_face();self.count = 0;self.t_length= 4 + floor(random()*4);};
+void() army_atk2 =[ $shoot2, army_atk3 ] {ai_face();};
+void() army_atk3 =[ $shoot3, army_atk4 ] {ai_face();};
+void() army_atk4 =[ $shoot4, army_atk5 ] {ai_face();};
+void() army_atk5 ={
+self.frame = $shoot5;
+self.nextthink = time + .1;
+if (self.style == 5 && self.count < self.t_length)
+{
+ self.count +=1;
+}
+else
+{
+ self.think = army_atk6;
+}
+ai_face();
+army_fire();
+self.effects = self.effects | EF_MUZZLEFLASH;};
+void() army_atk6 =[ $shoot6, army_atk7 ] {ai_face();};
+void() army_atk7 =[ $shoot7, army_atk8 ] {ai_face();SUB_CheckRefire (army_atk1);};
+void() army_atk8 =[ $shoot8, army_atk9 ] {ai_face();};
+void() army_atk9 =[ $shoot9, army_run1 ] {ai_face();};
+// new frames for turrets
+void() army_turret_atk6;
+void() army_turret_atk1 =[ $shoot1, army_turret_atk2 ] {ai_face();self.count = 0;self.t_length= 4 + floor(random()*4);};
+void() army_turret_atk2 =[ $shoot2, army_turret_atk3 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
+void() army_turret_atk3 =[ $shoot3, army_turret_atk4 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() army_turret_atk4 =[ $shoot4, army_turret_atk5 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() army_turret_atk5 ={
+self.frame = $shoot5;
+self.nextthink = time + .1;
+if (self.style == 5 && self.count < self.t_length)
+{
+ self.count +=1;
+}
+else
+{
+ self.think = army_turret_atk6;
+}
+ai_face();
+army_fire();
+self.effects = self.effects | EF_MUZZLEFLASH;};
+void() army_turret_atk6 =[ $shoot6, army_turret_atk7 ] {ai_face();};
+void() army_turret_atk7 =[ $shoot7, army_turret_atk8 ] {ai_face();SUB_CheckRefire (army_turret_atk1);};
+void() army_turret_atk8 =[ $shoot8, army_turret_atk9 ] {ai_face();};
+void() army_turret_atk9 =[ $stand4, army_turret_atk10 ] {ai_face();};
+void() army_turret_atk10 =[ $stand5, army_seeking_stand1 ] {ai_face();};
+void() army_seeking_stand1 =[ $stand1, army_seeking_stand2 ] {ai_run(0);};
+void() army_seeking_stand2 =[ $stand2, army_seeking_stand3 ] {ai_run(0);};
+void() army_seeking_stand3 =[ $stand3, army_seeking_stand4 ] {ai_run(0);};
+void() army_seeking_stand4 =[ $stand4, army_seeking_stand5 ] {ai_run(0);};
+void() army_seeking_stand5 =[ $stand5, army_seeking_stand6 ] {ai_run(0);};
+void() army_seeking_stand6 =[ $stand6, army_seeking_stand7 ] {ai_run(0);};
+void() army_seeking_stand7 =[ $stand7, army_seeking_stand8 ] {ai_run(0);};
+void() army_seeking_stand8 =[ $stand8, army_seeking_stand1 ] {ai_run(0);};
+// new frames for turrets end
+
+void() army_pain1 =[ $pain1, army_pain2 ] {};
+void() army_pain2 =[ $pain2, army_pain3 ] {};
+void() army_pain3 =[ $pain3, army_pain4 ] {};
+void() army_pain4 =[ $pain4, army_pain5 ] {};
+void() army_pain5 =[ $pain5, army_pain6 ] {};
+void() army_pain6 =[ $pain6, army_run1 ] {ai_pain(1);};
+
+void() army_painb1 =[ $painb1, army_painb2 ] {};
+void() army_painb2 =[ $painb2, army_painb3 ] {ai_painforward(13);};
+void() army_painb3 =[ $painb3, army_painb4 ] {ai_painforward(9);};
+void() army_painb4 =[ $painb4, army_painb5 ] {};
+void() army_painb5 =[ $painb5, army_painb6 ] {};
+void() army_painb6 =[ $painb6, army_painb7 ] {};
+void() army_painb7 =[ $painb7, army_painb8 ] {};
+void() army_painb8 =[ $painb8, army_painb9 ] {};
+void() army_painb9 =[ $painb9, army_painb10] {};
+void() army_painb10=[ $painb10, army_painb11] {};
+void() army_painb11=[ $painb11, army_painb12] {};
+void() army_painb12=[ $painb12, army_painb13] {ai_pain(2);};
+void() army_painb13=[ $painb13, army_painb14] {};
+void() army_painb14=[ $painb14, army_run1 ] {};
+
+void() army_painc1 =[ $painc1, army_painc2 ] {};
+void() army_painc2 =[ $painc2, army_painc3 ] {ai_pain(1);};
+void() army_painc3 =[ $painc3, army_painc4 ] {};
+void() army_painc4 =[ $painc4, army_painc5 ] {};
+void() army_painc5 =[ $painc5, army_painc6 ] {ai_painforward(1);};
+void() army_painc6 =[ $painc6, army_painc7 ] {ai_painforward(1);};
+void() army_painc7 =[ $painc7, army_painc8 ] {};
+void() army_painc8 =[ $painc8, army_painc9 ] {ai_pain(1);};
+void() army_painc9 =[ $painc9, army_painc10] {ai_painforward(4);};
+void() army_painc10=[ $painc10, army_painc11] {ai_painforward(3);};
+void() army_painc11=[ $painc11, army_painc12] {ai_painforward(6);};
+void() army_painc12=[ $painc12, army_painc13] {ai_painforward(8);};
+void() army_painc13=[ $painc13, army_run1] {};
+
+void(entity attacker, float damage) army_pain =
+{
+ local float r;
+
+ if (self.pain_finished > time)
+ return;
+
+ r = random();
+
+ if (r < 0.2)
+ { // turret checks moved here to play pain sounds correctly - dumptruck_ds
+ self.pain_finished = time + 0.6;
+ sound_pain (self, CHAN_VOICE, "soldier/pain1.wav", 1, ATTN_NORM);
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+ else
+ army_pain1 ();
+ }
+ else if (r < 0.6)
+ {
+ self.pain_finished = time + 1.1;
+ sound_misc (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM);
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+ else
+ army_painb1 ();
+ }
+ else
+ {
+ self.pain_finished = time + 1.1;
+ sound_misc (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM);
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+ else
+ army_painc1 ();
+ }
+};
+
+void() army_fire =
+{ //dumptruck_ds start rocket grunt stuff
+
+if (self.style == 1)
+
+ {
+ ai_face();
+
+ W_GruntRocket();
+ }
+
+else if (self.style == 2)
+
+ {
+ ai_face();
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ PreachFireGrenade(self.attack_elevation);
+ }
+ else
+ GruntFireGrenade();
+ }
+
+else if (self.style == 3)
+
+ {
+ ai_face();
+ genforcer_fire();
+ }
+
+else if (self.style == 4 || self.style == 5)
+
+ {
+ ai_face();
+ MonFireSpike();
+ }
+
+else
+
+ {
+ local vector dir;
+ local entity en;
+
+ ai_face();
+
+ sound_attack (self, CHAN_WEAPON, "soldier/sattck1.wav", 1, ATTN_NORM);
+
+ // fire somewhat behind the player, so a dodging player is harder to hit
+ en = self.enemy;
+
+ dir = en.origin - en.velocity*0.2;
+ dir = normalize (dir - self.origin);
+
+ FireBullets (4, dir, '0.1 0.1 0');
+ }
+
+};
+
+void() army_die1 =[ $death1, army_die2 ] {};
+void() army_die2 =[ $death2, army_die3 ] {};
+void() army_die3 =[ $death3, army_die4 ]
+{self.solid = SOLID_NOT;
+// style ammotype check -- dumptruck_ds
+ if (self.style == 1)
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 2)
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 3)
+ {
+ self.ammo_cells = 5;
+ }
+ if (self.style == 4 || self.style == 5)
+ {
+ self.ammo_nails = 5;
+ }
+ else if (self.style == 0)
+ {
+ self.ammo_shells = 5;
+ }
+if(!self.keep_ammo)DropBackpack();};
+void() army_die4 =[ $death4, army_die5 ] {};
+void() army_die5 =[ $death5, army_die6 ] {};
+void() army_die6 =[ $death6, army_die7 ] {};
+void() army_die7 =[ $death7, army_die8 ] {};
+void() army_die8 =[ $death8, army_die9 ] {};
+void() army_die9 =[ $death9, army_die10 ] {};
+void() army_die10 =[ $death10, army_die10 ] {};
+
+void() army_cdie1 =[ $deathc1, army_cdie2 ] {};
+void() army_cdie2 =[ $deathc2, army_cdie3 ] {ai_back(5);};
+void() army_cdie3 =[ $deathc3, army_cdie4 ]
+{self.solid = SOLID_NOT;
+// style ammotype check -- dumptruck_ds
+ if (self.style == 1)
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 2)
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 3)
+ {
+ self.ammo_cells = 5;
+ }
+ if (self.style == 4 || self.style == 5)
+ {
+ self.ammo_nails = 5;
+ }
+ else if (self.style == 0)
+ {
+ self.ammo_shells = 5;
+ }
+if(!self.keep_ammo)DropBackpack();ai_back(4);}; //dumptruck_ds
+void() army_cdie4 =[ $deathc4, army_cdie5 ] {ai_back(13);};
+void() army_cdie5 =[ $deathc5, army_cdie6 ] {ai_back(3);};
+void() army_cdie6 =[ $deathc6, army_cdie7 ] {ai_back(4);};
+void() army_cdie7 =[ $deathc7, army_cdie8 ] {};
+void() army_cdie8 =[ $deathc8, army_cdie9 ] {};
+void() army_cdie9 =[ $deathc9, army_cdie10 ] {};
+void() army_cdie10 =[ $deathc10, army_cdie11 ] {};
+void() army_cdie11 =[ $deathc11, army_cdie11 ] {};
+
+
+void() army_die =
+{
+// check for gib
+ if (self.health < -35)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_guard.mdl", self.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+
+// regular death
+ sound_death (self, CHAN_VOICE, "soldier/death1.wav", 1, ATTN_NORM);
+ DropStuff();
+ if (random() < 0.5)
+ army_die1 ();
+ else
+ army_cdie1 ();
+};
+
+
+/*QUAKED monster_army (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/soldier.mdl");
+}
+Grunt.
+
+Default health = 30"
+
+keep_ammo "1 = Don't drop backpack upon death"
+snd_death "Path to custom death sound"
+snd_pain "Path to custom pain sound"
+snd_sight "Path to custom sight sound"
+snd_attack "Path to custom attack sound (GUNSHOT)"
+snd_idle "Path to custom idle sound"
+snd_misc "Path to custom sound (PAIN 2)"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+skin_head(float) : "Skin index of custom head model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+style "Attack type"
+0 "Default (shotgun)"
+1 "Rockets"
+2 "Grenades"
+3 "lasers"
+4 "Nails"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_army =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ //dumptruck_ds custom_mdls
+ precache_body_model ("progs/soldier.mdl");
+ precache_head_model ("progs/h_guard.mdl");
+ precache_proj_model ("progs/missile.mdl"); // used if style == 1
+ precache_proj_model ("progs/grenade.mdl"); // used if style == 2
+ precache_model2 ("progs/laser.mdl"); // used if style == 3
+ //dumptruck_ds custom_mdls
+ precache_model ("progs/gib1.mdl");
+ precache_model ("progs/gib2.mdl");
+ precache_model ("progs/gib3.mdl");
+
+ precache_sound_death ("soldier/death1.wav");
+ precache_sound_idle ("soldier/idle.wav");
+ precache_sound_pain ("soldier/pain1.wav");
+ precache_sound_misc ("soldier/pain2.wav");
+ precache_sound_attack ("soldier/sattck1.wav");
+ precache_sound_sight ("soldier/sight1.wav");
+ precache_sound2 ("enforcer/enfire.wav"); // used if style == 3
+ precache_sound2 ("enforcer/enfstop.wav"); // used if style == 3
+
+ precache_sound ("player/udeath.wav"); // gib death
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ //dumptruck_ds custom_mdls
+ body_model ("progs/soldier.mdl");
+
+ setsize (self, '-16 -16 -24', '16 16 40');
+
+ if (!self.proj_speed_mod)
+ {
+ self.proj_speed_mod = 1;
+ }
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 30;
+
+ self.th_stand = army_stand1;
+ self.th_walk = army_walk1;
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_run = army_seeking_stand1;
+ }
+ else
+ {
+ self.th_run = army_run1;
+ }
+ self.th_missile = army_atk1;
+ self.th_turret = army_turret_atk1;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = army_pain;
+ else
+ self.th_pain = SUB_NullPain;
+ self.th_die = army_die;
+
+ walkmonster_start ();
+};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_army (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID FACE_UP X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/soldier.mdl","frame":28});
+}
+*/
+void() monster_dead_army =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/soldier.mdl");
+ setmodel(self, "progs/soldier.mdl");
+ if (self.spawnflags & 2)
+ {
+ self.frame = $death10;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-38.27 -30.47 -50.3','22.1 25.35 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+ else
+ {
+ self.frame = $deathc11;
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-39.85 -29.35 -49.07','20.52 33.17 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/wizard.qc

diff --git a/qc/monsters/wizard.qc b/qc/monsters/wizard.qc
new file mode 100644
index 0000000..dfde2b0
--- /dev/null
+++ b/qc/monsters/wizard.qc
@@ -0,0 +1,580 @@
+/*
+==============================================================================
+
+WIZARD
+
+==============================================================================
+*/
+
+$cd id1/models/a_wizard
+$origin 0 0 24
+$base wizbase
+$skin wizbase
+
+$frame hover1 hover2 hover3 hover4 hover5 hover6 hover7 hover8
+$frame hover9 hover10 hover11 hover12 hover13 hover14 hover15
+
+$frame fly1 fly2 fly3 fly4 fly5 fly6 fly7 fly8 fly9 fly10
+$frame fly11 fly12 fly13 fly14
+
+$frame magatt1 magatt2 magatt3 magatt4 magatt5 magatt6 magatt7
+$frame magatt8 magatt9 magatt10 magatt11 magatt12 magatt13
+
+$frame pain1 pain2 pain3 pain4
+
+$frame death1 death2 death3 death4 death5 death6 death7 death8
+
+/*
+==============================================================================
+
+WIZARD
+
+If the player moves behind cover before the missile is launched, launch it
+at the last visible spot with no velocity leading, in hopes that the player
+will duck back out and catch it.
+==============================================================================
+*/
+
+/*
+=============
+LaunchMissile
+
+Sets the given entities velocity and angles so that it will hit self.enemy
+if self.enemy maintains it's current velocity
+0.1 is moderately accurate, 0.0 is totally accurate
+=============
+*/
+void(entity missile, float mspeed, float accuracy) LaunchMissile =
+{
+ local vector vec, move;
+ local float fly;
+
+ makevectors (self.angles);
+
+// set missile speed
+ vec = self.enemy.origin + self.enemy.mins + self.enemy.size * 0.7 - missile.origin;
+
+// calc aproximate time for missile to reach vec
+ fly = vlen (vec) / mspeed;
+
+// get the entities xy velocity
+ move = self.enemy.velocity;
+ move_z = 0;
+
+// project the target forward in time
+ vec = vec + move * fly;
+
+ vec = normalize(vec);
+ vec = vec + accuracy*v_up*(random()- 0.5) + accuracy*v_right*(random()- 0.5);
+
+ missile.velocity = vec * mspeed;
+
+ missile.angles = '0 0 0';
+ missile.angles_y = vectoyaw(missile.velocity);
+
+ if (self.projexpl)
+ {
+ missile.touch = T_WizardMisTouch;
+ }
+
+// set missile duration
+ missile.nextthink = time + 5;
+ missile.think = SUB_Remove;
+};
+
+
+void() wiz_run1;
+void() wiz_side1;
+
+/*
+=================
+WizardCheckAttack
+=================
+*/
+float() WizardCheckAttack =
+{
+ local vector spot1, spot2;
+ local entity targ;
+ local float chance;
+
+ if (time < self.attack_finished)
+ return FALSE;
+ if (!enemy_vis)
+ return FALSE;
+
+ if (enemy_range == RANGE_FAR)
+ {
+ if (self.attack_state != AS_STRAIGHT)
+ {
+ self.attack_state = AS_STRAIGHT;
+ wiz_run1 ();
+ }
+ return FALSE;
+ }
+
+ targ = self.enemy;
+
+// see if any entities are in the way of the shot
+ spot1 = self.origin + self.view_ofs;
+ spot2 = targ.origin + targ.view_ofs;
+
+ traceline (spot1, spot2, FALSE, self);
+
+ if (trace_ent != targ)
+ { // don't have a clear shot, so move to a side
+ if (self.attack_state != AS_STRAIGHT)
+ {
+ self.attack_state = AS_STRAIGHT;
+ wiz_run1 ();
+ }
+ return FALSE;
+ }
+
+ if (enemy_range == RANGE_MELEE)
+ chance = 0.9;
+ else if (enemy_range == RANGE_NEAR)
+ chance = 0.6;
+ else if (enemy_range == RANGE_MID)
+ chance = 0.2;
+ else
+ chance = 0;
+
+ if (random () < chance)
+ {
+ self.attack_state = AS_MISSILE;
+ return TRUE;
+ }
+
+ if (enemy_range == RANGE_MID)
+ {
+ if (self.attack_state != AS_STRAIGHT)
+ {
+ self.attack_state = AS_STRAIGHT;
+ wiz_run1 ();
+ }
+ }
+ else
+ {
+ if (self.attack_state != AS_SLIDING)
+ {
+ self.attack_state = AS_SLIDING;
+ wiz_side1 ();
+ }
+ }
+
+ return FALSE;
+};
+
+/*
+=================
+WizardAttackFinished
+=================
+*/
+void() WizardAttackFinished =
+{
+ if (enemy_range >= RANGE_MID || !enemy_vis)
+ {
+ self.attack_state = AS_STRAIGHT;
+ self.think = wiz_run1;
+ }
+ else
+ {
+ self.attack_state = AS_SLIDING;
+ self.think = wiz_side1;
+ }
+};
+
+/*
+==============================================================================
+
+FAST ATTACKS
+
+==============================================================================
+*/
+void() Wiz_AttackSound = // this is a hack to fix Wizard custom attack sounds
+{
+ sound_attack (self, CHAN_AUTO, "wizard/wattack.wav", 1, ATTN_NORM);
+};
+
+void() Wiz_FastFire =
+{
+ local vector vec;
+ local vector dst;
+ local entity oldself;
+ local float projspeed = self.owner.proj_speed_mod * 600;
+
+ if (self.owner.health > 0)
+ {
+ self.owner.effects = self.owner.effects | EF_MUZZLEFLASH;
+
+ makevectors (self.enemy.angles);
+ dst = self.enemy.origin - 13*self.movedir;
+
+ vec = normalize(dst - self.origin);
+ // sound_attack (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM);
+ launch_spike (self.origin, vec);
+ SetSpeed(newmis, vec, projspeed);
+ newmis.owner = self.owner;
+ newmis.classname = "wizspike";
+ if (self.owner.projexpl)
+ {
+ // dprint("spawning exploding wizard proj from fastfire\n");
+ newmis.touch = T_WizardMisTouch;
+ }
+ if (self.owner.homing)
+ {
+ oldself = self;
+ self = self.owner;
+ SetupHoming(newmis, projspeed);
+ self = oldself;
+ }
+ setmodel(newmis, self.owner.mdl_proj);
+ newmis.skin = self.owner.skin_proj;
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+
+ }
+
+ remove (self);
+};
+
+
+void() Wiz_StartFast =
+{
+ local entity missile;
+
+ // sound_attack (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM);
+ self.v_angle = self.angles;
+ makevectors (self.angles);
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.nextthink = time + 0.6;
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right*14);
+ missile.enemy = self.enemy;
+ missile.nextthink = time + 0.8;
+ missile.think = Wiz_FastFire;
+ missile.movedir = v_right;
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.nextthink = time + 1;
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right* -14);
+ missile.enemy = self.enemy;
+ missile.nextthink = time + 0.3;
+ missile.think = Wiz_FastFire;
+ missile.movedir = VEC_ORIGIN - v_right;
+};
+
+void() Wiz_idlesound =
+{
+local float wr;
+ wr = random() * 5;
+
+ if (self.fly_sound < time)
+ {
+ self.fly_sound = time + 2;
+ if (wr > 4.5)
+ sound_idle (self, CHAN_VOICE, "wizard/widle1.wav", 1, ATTN_IDLE);
+ if (wr < 1.5)
+ sound_misc (self, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_IDLE);
+ }
+ return;
+};
+
+void() wiz_stand1 =[ $hover1, wiz_stand2 ] {ai_stand();};
+void() wiz_stand2 =[ $hover2, wiz_stand3 ] {ai_stand();};
+void() wiz_stand3 =[ $hover3, wiz_stand4 ] {ai_stand();};
+void() wiz_stand4 =[ $hover4, wiz_stand5 ] {ai_stand();};
+void() wiz_stand5 =[ $hover5, wiz_stand6 ] {ai_stand();};
+void() wiz_stand6 =[ $hover6, wiz_stand7 ] {ai_stand();};
+void() wiz_stand7 =[ $hover7, wiz_stand8 ] {ai_stand();};
+void() wiz_stand8 =[ $hover8, wiz_stand1 ] {ai_stand();};
+
+void() wiz_walk1 =[ $hover1, wiz_walk2 ] {ai_walk(8);
+Wiz_idlesound();};
+void() wiz_walk2 =[ $hover2, wiz_walk3 ] {ai_walk(8);};
+void() wiz_walk3 =[ $hover3, wiz_walk4 ] {ai_walk(8);};
+void() wiz_walk4 =[ $hover4, wiz_walk5 ] {ai_walk(8);};
+void() wiz_walk5 =[ $hover5, wiz_walk6 ] {ai_walk(8);};
+void() wiz_walk6 =[ $hover6, wiz_walk7 ] {ai_walk(8);};
+void() wiz_walk7 =[ $hover7, wiz_walk8 ] {ai_walk(8);};
+void() wiz_walk8 =[ $hover8, wiz_walk1 ] {ai_walk(8);};
+
+void() wiz_side1 =[ $hover1, wiz_side2 ] {ai_run(8);
+Wiz_idlesound();};
+void() wiz_side2 =[ $hover2, wiz_side3 ] {ai_run(8);};
+void() wiz_side3 =[ $hover3, wiz_side4 ] {ai_run(8);};
+void() wiz_side4 =[ $hover4, wiz_side5 ] {ai_run(8);};
+void() wiz_side5 =[ $hover5, wiz_side6 ] {ai_run(8);};
+void() wiz_side6 =[ $hover6, wiz_side7 ] {ai_run(8);};
+void() wiz_side7 =[ $hover7, wiz_side8 ] {ai_run(8);};
+void() wiz_side8 =[ $hover8, wiz_side1 ] {ai_run(8);};
+
+void() wiz_run1 =[ $fly1, wiz_run2 ] {ai_run(16);
+Wiz_idlesound();
+};
+void() wiz_run2 =[ $fly2, wiz_run3 ] {ai_run(16);};
+void() wiz_run3 =[ $fly3, wiz_run4 ] {ai_run(16);};
+void() wiz_run4 =[ $fly4, wiz_run5 ] {ai_run(16);};
+void() wiz_run5 =[ $fly5, wiz_run6 ] {ai_run(16);};
+void() wiz_run6 =[ $fly6, wiz_run7 ] {ai_run(16);};
+void() wiz_run7 =[ $fly7, wiz_run8 ] {ai_run(16);};
+void() wiz_run8 =[ $fly8, wiz_run9 ] {ai_run(16);};
+void() wiz_run9 =[ $fly9, wiz_run10 ] {ai_run(16);};
+void() wiz_run10 =[ $fly10, wiz_run11 ] {ai_run(16);};
+void() wiz_run11 =[ $fly11, wiz_run12 ] {ai_run(16);};
+void() wiz_run12 =[ $fly12, wiz_run13 ] {ai_run(16);};
+void() wiz_run13 =[ $fly13, wiz_run14 ] {ai_run(16);};
+void() wiz_run14 =[ $fly14, wiz_run1 ] {ai_run(16);};
+
+void() wiz_fast1 =[ $magatt1, wiz_fast2 ] {ai_face();Wiz_StartFast();Wiz_AttackSound();};
+void() wiz_fast2 =[ $magatt2, wiz_fast3 ] {ai_face();};
+void() wiz_fast3 =[ $magatt3, wiz_fast4 ] {ai_face();};
+void() wiz_fast4 =[ $magatt4, wiz_fast5 ] {ai_face();};
+void() wiz_fast5 =[ $magatt5, wiz_fast6 ] {ai_face();};
+void() wiz_fast6 =[ $magatt6, wiz_fast7 ] {ai_face();};
+void() wiz_fast7 =[ $magatt5, wiz_fast8 ] {ai_face();Wiz_AttackSound();};
+void() wiz_fast8 =[ $magatt4, wiz_fast9 ] {ai_face();};
+void() wiz_fast9 =[ $magatt3, wiz_fast10 ] {ai_face();};
+void() wiz_fast10 =[ $magatt2, wiz_run1 ] {ai_face();SUB_AttackFinished(2);WizardAttackFinished ();};
+
+void() wiz_pain1 =[ $pain1, wiz_pain2 ] {};
+void() wiz_pain2 =[ $pain2, wiz_pain3 ] {};
+void() wiz_pain3 =[ $pain3, wiz_pain4 ] {};
+void() wiz_pain4 =[ $pain4, wiz_run1 ] {};
+
+void() wiz_death1 =[ $death1, wiz_death2 ] {
+
+self.velocity_x = -200 + 400*random();
+self.velocity_y = -200 + 400*random();
+self.velocity_z = 100 + 100*random();
+self.flags = self.flags - (self.flags & FL_ONGROUND);
+sound_death (self, CHAN_VOICE, "wizard/wdeath.wav", 1, ATTN_NORM);
+};
+void() wiz_death2 =[ $death2, wiz_death3 ] {};
+void() wiz_death3 =[ $death3, wiz_death4 ]{self.solid = SOLID_NOT;};
+void() wiz_death4 =[ $death4, wiz_death5 ] {};
+void() wiz_death5 =[ $death5, wiz_death6 ] {};
+void() wiz_death6 =[ $death6, wiz_death7 ] {};
+void() wiz_death7 =[ $death7, wiz_death8 ] {};
+void() wiz_death8 =[ $death8, wiz_death8 ] {};
+
+void() wiz_die =
+{
+// check for gib
+ if (self.health < -40)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_wizard.mdl", self.health);
+ }
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+ DropStuff();
+ wiz_death1 ();
+};
+
+void(entity attacker, float damage) Wiz_Pain =
+{
+ sound_pain (self, CHAN_VOICE, "wizard/wpain.wav", 1, ATTN_NORM);
+ if (random()*70 > damage)
+ return; // didn't flinch
+
+ wiz_pain1 ();
+};
+
+
+void() Wiz_Missile =
+{
+ wiz_fast1();
+};
+
+/*QUAKED monster_wizard (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/wizard.mdl");
+}
+Wizard a.k.a. Scrag.
+
+Default health = 80
+
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound"
+snd_idle(string) : "Path to custom idle sound"
+snd_misc(string) : "Path to custom sound (IDLE 2)"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+skin_head(float) : "Skin index of custom head model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+projexpl(choices) : "Exploding projectiles"
+0 : "No explosions"
+1 : "All projectiles explode"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_wizard =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ objerror("Incompatible spawnflag: TURRET_MODE\n");
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+
+ if (!self.mdl_proj)
+ {
+ self.mdl_proj = "progs/w_spike.mdl";
+ }
+
+ // dumptruck_ds custom_mdls
+ precache_body_model ("progs/wizard.mdl");
+ precache_head_model ("progs/h_wizard.mdl");
+ precache_proj_model ("progs/w_spike.mdl");
+ ////dumptruck_ds
+ precache_sound_hit ("wizard/hit.wav"); // used by c code
+ precache_sound_attack ("wizard/wattack.wav");
+ precache_sound_death ("wizard/wdeath.wav");
+ precache_sound_idle ("wizard/widle1.wav");
+ precache_sound_misc ("wizard/widle2.wav");
+ precache_sound_pain ("wizard/wpain.wav");
+ precache_sound_sight ("wizard/wsight.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/wizard.mdl");
+ // setmodel (self, "progs/wizard.mdl"); //dumptruck_ds
+
+ setsize (self, '-16 -16 -24', '16 16 40');
+
+ if (!self.proj_speed_mod)
+ {
+ self.proj_speed_mod = 1;
+ }
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 80;
+
+ self.th_stand = wiz_stand1;
+ self.th_walk = wiz_walk1;
+ self.th_run = wiz_run1;
+ self.th_missile = Wiz_Missile;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = Wiz_Pain;
+ else
+ self.th_pain = SUB_NullPain;
+ self.th_die = wiz_die;
+
+ flymonster_start ();
+};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_wizard (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/wizard.mdl","frame":53});
+}
+*/
+void() monster_dead_wizard =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/wizard.mdl");
+ setmodel(self, "progs/wizard.mdl");
+ self.frame = $death8;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-50.75 -27.46 -55.19','31.81 33.61 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/zombie.qc

diff --git a/qc/monsters/zombie.qc b/qc/monsters/zombie.qc
new file mode 100644
index 0000000..3230c93
--- /dev/null
+++ b/qc/monsters/zombie.qc
@@ -0,0 +1,865 @@
+/*
+==============================================================================
+
+ZOMBIES!.qc - Version 1.1
+by Ace_Dave
+http://www.trenton.edu/~weiden/quake
+Weiden@Trenton.EDU
+
+==============================================================================
+*/
+$cd /raid/quake/id1/models/zombie
+
+$origin 0 0 24
+
+$base base
+$skin skin
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8
+$frame stand9 stand10 stand11 stand12 stand13 stand14 stand15
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 walk11
+$frame walk12 walk13 walk14 walk15 walk16 walk17 walk18 walk19
+
+$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12
+$frame run13 run14 run15 run16 run17 run18
+
+$frame atta1 atta2 atta3 atta4 atta5 atta6 atta7 atta8 atta9 atta10 atta11
+$frame atta12 atta13
+
+$frame attb1 attb2 attb3 attb4 attb5 attb6 attb7 attb8 attb9 attb10 attb11
+$frame attb12 attb13 attb14
+
+$frame attc1 attc2 attc3 attc4 attc5 attc6 attc7 attc8 attc9 attc10 attc11
+$frame attc12
+
+$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10
+$frame paina11 paina12
+
+$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10
+$frame painb11 painb12 painb13 painb14 painb15 painb16 painb17 painb18 painb19
+$frame painb20 painb21 painb22 painb23 painb24 painb25 painb26 painb27 painb28
+
+$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10
+$frame painc11 painc12 painc13 painc14 painc15 painc16 painc17 painc18
+
+$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10
+$frame paind11 paind12 paind13
+
+$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10
+$frame paine11 paine12 paine13 paine14 paine15 paine16 paine17 paine18 paine19
+$frame paine20 paine21 paine22 paine23 paine24 paine25 paine26 paine27 paine28
+$frame paine29 paine30
+
+$frame cruc_1 cruc_2 cruc_3 cruc_4 cruc_5 cruc_6
+
+float SPAWN_CRUCIFIED = 1;
+float SPAWN_DEAD_CRUCIFIED = 4;
+float SPAWN_SLEEPING = 16; //changed from 2 which was Zer default
+// float SPAWN_DEAD = 4; -- not used in progs_dump -- dumptruck_ds -- this is from Zer src for my reference
+// float SPAWN_DEAD_CRUCIFIED = 8; -- not used in progs_dump -- dumptruck_ds -- this is from Zer src for my reference
+
+//=============================================================================
+.float inpain;
+
+// motionless crucified zombie
+void() zombie_dead_cruc1 = [$cruc_1, zombie_dead_cruc1] {self.nextthink = time + 1;};
+
+// new "stand" - for sleeping zombies
+void() zombie_stand1 =[ $paine11, zombie_stand2 ]
+{
+ self.solid = SOLID_NOT;
+ if (self.count == 0) //dumptruck_ds -- count value > 0 to leave the zombie sleeping until triggered!
+ ai_stand();
+};
+void() zombie_stand2 =[ $paine11, zombie_stand1 ]
+{
+ if (self.count == 0)
+ ai_stand();
+};
+
+// old "stand" - called when standing only
+void() alt_zombie_stand1 =[ $stand1, alt_zombie_stand2 ] {self.health = 60; ai_stand();};
+void() alt_zombie_stand2 =[ $stand2, zombie_stand3 ] {ai_stand();};
+void() zombie_stand3 =[ $stand3, zombie_stand4 ] {ai_stand();};
+void() zombie_stand4 =[ $stand4, zombie_stand5 ] {ai_stand();};
+void() zombie_stand5 =[ $stand5, zombie_stand6 ] {ai_stand();};
+void() zombie_stand6 =[ $stand6, zombie_stand7 ] {ai_stand();};
+void() zombie_stand7 =[ $stand7, zombie_stand8 ] {ai_stand();};
+void() zombie_stand8 =[ $stand8, zombie_stand9 ] {ai_stand();};
+void() zombie_stand9 =[ $stand9, zombie_stand10 ] {ai_stand();};
+void() zombie_stand10 =[ $stand10, zombie_stand11 ] {ai_stand();};
+void() zombie_stand11 =[ $stand11, zombie_stand12 ] {ai_stand();};
+void() zombie_stand12 =[ $stand12, zombie_stand13 ] {ai_stand();};
+void() zombie_stand13 =[ $stand13, zombie_stand14 ] {ai_stand();};
+void() zombie_stand14 =[ $stand14, zombie_stand15 ] {ai_stand();};
+void() zombie_stand15 =[ $stand15, alt_zombie_stand1 ] {ai_stand();};
+
+void() zombie_cruc1 = [ $cruc_1, zombie_cruc2 ] {
+if (random() < 0.1)
+ sound_idle (self, CHAN_VOICE, "zombie/idle_w2.wav", 1, ATTN_STATIC);};
+void() zombie_cruc2 = [ $cruc_2, zombie_cruc3 ] {self.nextthink = time + 0.1 + random()*0.1;};
+void() zombie_cruc3 = [ $cruc_3, zombie_cruc4 ] {self.nextthink = time + 0.1 + random()*0.1;};
+void() zombie_cruc4 = [ $cruc_4, zombie_cruc5 ] {self.nextthink = time + 0.1 + random()*0.1;};
+void() zombie_cruc5 = [ $cruc_5, zombie_cruc6 ] {self.nextthink = time + 0.1 + random()*0.1;};
+void() zombie_cruc6 = [ $cruc_6, zombie_cruc1 ] {self.nextthink = time + 0.1 + random()*0.1;};
+
+void() zombie_walk1 =[ $walk1, zombie_walk2 ] {
+ self.solid = SOLID_SLIDEBOX;
+ self.health = 60; //so he doesn't fall
+ ai_walk(0);};
+void() zombie_walk2 =[ $walk2, zombie_walk3 ] {ai_walk(2);};
+void() zombie_walk3 =[ $walk3, zombie_walk4 ] {ai_walk(3);};
+void() zombie_walk4 =[ $walk4, zombie_walk5 ] {ai_walk(2);};
+void() zombie_walk5 =[ $walk5, zombie_walk6 ] {ai_walk(1);};
+void() zombie_walk6 =[ $walk6, zombie_walk7 ] {ai_walk(0);};
+void() zombie_walk7 =[ $walk7, zombie_walk8 ] {ai_walk(0);};
+void() zombie_walk8 =[ $walk8, zombie_walk9 ] {ai_walk(0);};
+void() zombie_walk9 =[ $walk9, zombie_walk10 ] {ai_walk(0);};
+void() zombie_walk10 =[ $walk10, zombie_walk11 ] {ai_walk(0);};
+void() zombie_walk11 =[ $walk11, zombie_walk12 ] {ai_walk(2);};
+void() zombie_walk12 =[ $walk12, zombie_walk13 ] {ai_walk(2);};
+void() zombie_walk13 =[ $walk13, zombie_walk14 ] {ai_walk(1);};
+void() zombie_walk14 =[ $walk14, zombie_walk15 ] {ai_walk(0);};
+void() zombie_walk15 =[ $walk15, zombie_walk16 ] {ai_walk(0);};
+void() zombie_walk16 =[ $walk16, zombie_walk17 ] {ai_walk(0);};
+void() zombie_walk17 =[ $walk17, zombie_walk18 ] {ai_walk(0);};
+void() zombie_walk18 =[ $walk18, zombie_walk19 ] {ai_walk(0);};
+void() zombie_walk19 =[ $walk19, zombie_walk1 ] {
+ai_walk(0);
+if (random() < 0.2)
+ sound_misc (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);};
+
+void() zombie_run1 =[ $run1, zombie_run2 ] {
+ if (self.spawnflags & SPAWN_SLEEPING)
+ { // sloppy hack, but it fixes the illusionary zombie bug
+ body_model ("progs/zombie.mdl"); //custom_mdls dumptruck_ds
+ // setmodel (self, "progs/zombie.mdl");
+ setsize (self, '-16 -16 -24', '16 16 40');
+ }
+ ai_run(1);
+ self.inpain = 0;};
+void() zombie_run2 =[ $run2, zombie_run3 ] {ai_run(1);};
+void() zombie_run3 =[ $run3, zombie_run4 ] {ai_run(0);};
+void() zombie_run4 =[ $run4, zombie_run5 ] {ai_run(1);};
+void() zombie_run5 =[ $run5, zombie_run6 ] {ai_run(2);};
+void() zombie_run6 =[ $run6, zombie_run7 ] {ai_run(3);};
+void() zombie_run7 =[ $run7, zombie_run8 ] {ai_run(4);};
+void() zombie_run8 =[ $run8, zombie_run9 ] {ai_run(4);};
+void() zombie_run9 =[ $run9, zombie_run10 ] {ai_run(2);};
+void() zombie_run10 =[ $run10, zombie_run11 ] {ai_run(0);};
+void() zombie_run11 =[ $run11, zombie_run12 ] {ai_run(0);};
+void() zombie_run12 =[ $run12, zombie_run13 ] {ai_run(0);};
+void() zombie_run13 =[ $run13, zombie_run14 ] {ai_run(2);};
+void() zombie_run14 =[ $run14, zombie_run15 ] {ai_run(4);};
+void() zombie_run15 =[ $run15, zombie_run16 ] {ai_run(6);};
+void() zombie_run16 =[ $run16, zombie_run17 ] {ai_run(7);};
+void() zombie_run17 =[ $run17, zombie_run18 ] {ai_run(3);};
+void() zombie_run18 =[ $run18, zombie_run1 ] {
+ai_run(8);
+if (random() < 0.2)
+ sound_misc (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
+if (random() > 0.8)
+ sound_sight (self, CHAN_VOICE, "zombie/z_idle1.wav", 1, ATTN_IDLE);
+};
+
+/*
+=============================================================================
+
+ATTACKS
+
+=============================================================================
+*/
+// void() Z_hit =
+// {
+// sound_hit (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM);
+// };
+//
+// void() Z_land =
+// {
+// sound_land (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
+// };
+
+// void() ZombieGrenadeTouch2 =
+// {
+// if (other == self.owner)
+// return; // don't explode on owner
+// if (other.takedamage)
+// {
+// // Z_hit();
+// T_Damage (other, self, self.owner, 10 );
+// sound_hit (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM);
+// remove (self);
+// return;
+// }
+// // Z_land();
+// sound_land (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
+// self.velocity = '0 0 0';
+// self.avelocity = '0 0 0';
+// self.touch = SUB_Remove;
+// };
+
+/*
+================
+ZombieFireGrenade
+================
+*/
+void(vector st) ZombieFireGrenade =
+{
+ local entity missile;
+ local vector org;
+
+ sound_attack (self, CHAN_WEAPON, "zombie/z_shot1.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+
+// calc org
+ org = self.origin + st_x * v_forward + st_y * v_right + (st_z - 24) * v_up;
+
+// set missile speed
+
+ makevectors (self.angles);
+
+ missile.velocity = normalize(self.enemy.origin - org);
+ missile.velocity = missile.velocity * 600;
+ missile.velocity_z = 200;
+
+ missile.avelocity = '3000 1000 2000';
+
+ missile.touch = ZombieGrenadeTouch;
+
+// set missile duration
+ missile.nextthink = time + 2.5;
+ missile.think = SUB_Remove;
+ // setmodel (missile, "progs/zom_gib.mdl");
+ if (self.mdl_proj != "") // dumptruck_ds custom_mdls
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/zom_gib.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, org);
+};
+
+
+void() zombie_atta1 =[ $atta1, zombie_atta2 ] {ai_face();};
+void() zombie_atta2 =[ $atta2, zombie_atta3 ] {ai_face();};
+void() zombie_atta3 =[ $atta3, zombie_atta4 ] {ai_face();};
+void() zombie_atta4 =[ $atta4, zombie_atta5 ] {ai_face();};
+void() zombie_atta5 =[ $atta5, zombie_atta6 ] {ai_face();};
+void() zombie_atta6 =[ $atta6, zombie_atta7 ] {ai_face();};
+void() zombie_atta7 =[ $atta7, zombie_atta8 ] {ai_face();};
+void() zombie_atta8 =[ $atta8, zombie_atta9 ] {ai_face();};
+void() zombie_atta9 =[ $atta9, zombie_atta10 ] {ai_face();};
+void() zombie_atta10 =[ $atta10, zombie_atta11 ] {ai_face();};
+void() zombie_atta11 =[ $atta11, zombie_atta12 ] {ai_face();};
+void() zombie_atta12 =[ $atta12, zombie_atta13 ] {ai_face();};
+void() zombie_atta13 =[ $atta13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -22 30');};
+
+void() zombie_attb1 =[ $attb1, zombie_attb2 ] {ai_face();};
+void() zombie_attb2 =[ $attb2, zombie_attb3 ] {ai_face();};
+void() zombie_attb3 =[ $attb3, zombie_attb4 ] {ai_face();};
+void() zombie_attb4 =[ $attb4, zombie_attb5 ] {ai_face();};
+void() zombie_attb5 =[ $attb5, zombie_attb6 ] {ai_face();};
+void() zombie_attb6 =[ $attb6, zombie_attb7 ] {ai_face();};
+void() zombie_attb7 =[ $attb7, zombie_attb8 ] {ai_face();};
+void() zombie_attb8 =[ $attb8, zombie_attb9 ] {ai_face();};
+void() zombie_attb9 =[ $attb9, zombie_attb10 ] {ai_face();};
+void() zombie_attb10 =[ $attb10, zombie_attb11 ] {ai_face();};
+void() zombie_attb11 =[ $attb11, zombie_attb12 ] {ai_face();};
+void() zombie_attb12 =[ $attb12, zombie_attb13 ] {ai_face();};
+void() zombie_attb13 =[ $attb13, zombie_attb14 ] {ai_face();};
+void() zombie_attb14 =[ $attb13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -24 29');};
+
+void() zombie_attc1 =[ $attc1, zombie_attc2 ] {ai_face();};
+void() zombie_attc2 =[ $attc2, zombie_attc3 ] {ai_face();};
+void() zombie_attc3 =[ $attc3, zombie_attc4 ] {ai_face();};
+void() zombie_attc4 =[ $attc4, zombie_attc5 ] {ai_face();};
+void() zombie_attc5 =[ $attc5, zombie_attc6 ] {ai_face();};
+void() zombie_attc6 =[ $attc6, zombie_attc7 ] {ai_face();};
+void() zombie_attc7 =[ $attc7, zombie_attc8 ] {ai_face();};
+void() zombie_attc8 =[ $attc8, zombie_attc9 ] {ai_face();};
+void() zombie_attc9 =[ $attc9, zombie_attc10 ] {ai_face();};
+void() zombie_attc10 =[ $attc10, zombie_attc11 ] {ai_face();};
+void() zombie_attc11 =[ $attc11, zombie_attc12 ] {ai_face();};
+void() zombie_attc12 =[ $attc12, zombie_run1 ] {ai_face();ZombieFireGrenade('-12 -19 29');};
+
+void() zombie_missile =
+{
+ local float r;
+
+ r = random();
+
+ if (r < 0.3)
+ zombie_atta1 ();
+ else if (r < 0.6)
+ zombie_attb1 ();
+ else
+ zombie_attc1 ();
+};
+//////////////////////////
+/// turret frames START
+/////////////////////////
+void() zombie_turret_atta1 =[ $atta1, zombie_turret_atta2 ] {self.health = 60;ai_face();};
+void() zombie_turret_atta2 =[ $atta2, zombie_turret_atta3 ] {ai_face();};
+void() zombie_turret_atta3 =[ $atta3, zombie_turret_atta4 ] {ai_face();};
+void() zombie_turret_atta4 =[ $atta4, zombie_turret_atta5 ] {ai_face();};
+void() zombie_turret_atta5 =[ $atta5, zombie_turret_atta6 ] {ai_face();};
+void() zombie_turret_atta6 =[ $atta6, zombie_turret_atta7 ] {ai_face();};
+void() zombie_turret_atta7 =[ $atta7, zombie_turret_atta8 ] {ai_face();};
+void() zombie_turret_atta8 =[ $atta8, zombie_turret_atta9 ] {ai_face();};
+void() zombie_turret_atta9 =[ $atta9, zombie_turret_atta10 ] {ai_face();};
+void() zombie_turret_atta10 =[ $atta10, zombie_turret_atta11 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
+void() zombie_turret_atta11 =[ $atta11, zombie_turret_atta12 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() zombie_turret_atta12 =[ $atta12, zombie_turret_atta13 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() zombie_turret_atta13 =[ $atta13, alt_zombie_seek_stand1 ] {ai_run(0);PreachFireZombie(self.attack_elevation);};
+
+void() zombie_turret_attb1 =[ $attb1, zombie_turret_attb2 ] {self.health = 60;ai_face();};
+void() zombie_turret_attb2 =[ $attb2, zombie_turret_attb3 ] {ai_face();};
+void() zombie_turret_attb3 =[ $attb3, zombie_turret_attb4 ] {ai_face();};
+void() zombie_turret_attb4 =[ $attb4, zombie_turret_attb5 ] {ai_face();};
+void() zombie_turret_attb5 =[ $attb5, zombie_turret_attb6 ] {ai_face();};
+void() zombie_turret_attb6 =[ $attb6, zombie_turret_attb7 ] {ai_face();};
+void() zombie_turret_attb7 =[ $attb7, zombie_turret_attb8 ] {ai_face();};
+void() zombie_turret_attb8 =[ $attb8, zombie_turret_attb9 ] {ai_face();};
+void() zombie_turret_attb9 =[ $attb9, zombie_turret_attb10 ] {ai_face();};
+void() zombie_turret_attb10 =[ $attb10, zombie_turret_attb11 ] {ai_face();};
+void() zombie_turret_attb11 =[ $attb11, zombie_turret_attb12 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
+void() zombie_turret_attb12 =[ $attb12, zombie_turret_attb13 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() zombie_turret_attb13 =[ $attb13, zombie_turret_attb14 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() zombie_turret_attb14 =[ $attb13, alt_zombie_seek_stand1 ] {ai_run(0);PreachFireZombie(self.attack_elevation);};
+
+void() zombie_turret_attc1 =[ $attc1, zombie_turret_attc2 ] {self.health = 60;ai_face();};
+void() zombie_turret_attc2 =[ $attc2, zombie_turret_attc3 ] {ai_face();};
+void() zombie_turret_attc3 =[ $attc3, zombie_turret_attc4 ] {ai_face();};
+void() zombie_turret_attc4 =[ $attc4, zombie_turret_attc5 ] {ai_face();};
+void() zombie_turret_attc5 =[ $attc5, zombie_turret_attc6 ] {ai_face();};
+void() zombie_turret_attc6 =[ $attc6, zombie_turret_attc7 ] {ai_face();};
+void() zombie_turret_attc7 =[ $attc7, zombie_turret_attc8 ] {ai_face();};
+void() zombie_turret_attc8 =[ $attc8, zombie_turret_attc9 ] {ai_face();};
+void() zombie_turret_attc9 =[ $attc9, zombie_turret_attc10 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
+void() zombie_turret_attc10 =[ $attc10, zombie_turret_attc11 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() zombie_turret_attc11 =[ $attc11, zombie_turret_attc12 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() zombie_turret_attc12 =[ $attc12, alt_zombie_seek_stand1 ] {ai_run(0);PreachFireZombie(self.attack_elevation);};
+void() alt_zombie_seek_stand1 =[ $stand1, alt_zombie_seek_stand2 ] {self.health = 60; ai_run(0);};
+void() alt_zombie_seek_stand2 =[ $stand2, zombie_seek_stand3 ] {ai_run(0);};
+void() zombie_seek_stand3 =[ $stand3, zombie_seek_stand4 ] {ai_run(0);};
+void() zombie_seek_stand4 =[ $stand4, zombie_seek_stand5 ] {ai_run(0);};
+void() zombie_seek_stand5 =[ $stand5, zombie_seek_stand6 ] {ai_run(0);};
+void() zombie_seek_stand6 =[ $stand6, zombie_seek_stand7 ] {ai_run(0);};
+void() zombie_seek_stand7 =[ $stand7, zombie_seek_stand8 ] {ai_run(0);};
+void() zombie_seek_stand8 =[ $stand8, zombie_seek_stand9 ] {ai_run(0);};
+void() zombie_seek_stand9 =[ $stand9, zombie_seek_stand10 ] {ai_run(0);};
+void() zombie_seek_stand10 =[ $stand10, zombie_seek_stand11 ] {ai_run(0);};
+void() zombie_seek_stand11 =[ $stand11, zombie_seek_stand12 ] {ai_run(0);};
+void() zombie_seek_stand12 =[ $stand12, zombie_seek_stand13 ] {ai_run(0);};
+void() zombie_seek_stand13 =[ $stand13, zombie_seek_stand14 ] {ai_run(0);};
+void() zombie_seek_stand14 =[ $stand14, zombie_seek_stand15 ] {ai_run(0);};
+void() zombie_seek_stand15 =[ $stand15, alt_zombie_seek_stand1 ] {ai_run(0);};
+
+void() zombie_turret_missile =
+{
+ local float r;
+
+ r = random();
+
+ if (r < 0.3)
+ zombie_turret_attb1 ();
+ else if (r < 0.6)
+ zombie_turret_atta1 ();
+ else
+ zombie_turret_attc1 ();
+};
+//////////////////////////
+/// turret frames END
+/////////////////////////
+
+/*
+=============================================================================
+
+PAIN
+
+=============================================================================
+*/
+
+void() zombie_paina1 =[ $paina1, zombie_paina2 ] {sound_pain (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);};
+void() zombie_paina2 =[ $paina2, zombie_paina3 ] {ai_painforward(3);};
+void() zombie_paina3 =[ $paina3, zombie_paina4 ] {ai_painforward(1);};
+void() zombie_paina4 =[ $paina4, zombie_paina5 ] {ai_pain(1);};
+void() zombie_paina5 =[ $paina5, zombie_paina6 ] {ai_pain(3);};
+void() zombie_paina6 =[ $paina6, zombie_paina7 ] {ai_pain(1);};
+void() zombie_paina7 =[ $paina7, zombie_paina8 ] {};
+void() zombie_paina8 =[ $paina8, zombie_paina9 ] {};
+void() zombie_paina9 =[ $paina9, zombie_paina10 ] {};
+void() zombie_paina10 =[ $paina10, zombie_paina11 ] {};
+void() zombie_paina11 =[ $paina11, zombie_paina12 ] {};
+void() zombie_paina12 =[ $paina12, zombie_run1 ] {};
+
+void() zombie_painb1 =[ $painb1, zombie_painb2 ] {sound_misc2 (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);};
+void() zombie_painb2 =[ $painb2, zombie_painb3 ] {ai_pain(2);};
+void() zombie_painb3 =[ $painb3, zombie_painb4 ] {ai_pain(8);};
+void() zombie_painb4 =[ $painb4, zombie_painb5 ] {ai_pain(6);};
+void() zombie_painb5 =[ $painb5, zombie_painb6 ] {ai_pain(2);};
+void() zombie_painb6 =[ $painb6, zombie_painb7 ] {};
+void() zombie_painb7 =[ $painb7, zombie_painb8 ] {};
+void() zombie_painb8 =[ $painb8, zombie_painb9 ] {};
+void() zombie_painb9 =[ $painb9, zombie_painb10 ] {sound_misc3 (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);};
+void() zombie_painb10 =[ $painb10, zombie_painb11 ] {};
+void() zombie_painb11 =[ $painb11, zombie_painb12 ] {};
+void() zombie_painb12 =[ $painb12, zombie_painb13 ] {};
+void() zombie_painb13 =[ $painb13, zombie_painb14 ] {};
+void() zombie_painb14 =[ $painb14, zombie_painb15 ] {};
+void() zombie_painb15 =[ $painb15, zombie_painb16 ] {};
+void() zombie_painb16 =[ $painb16, zombie_painb17 ] {};
+void() zombie_painb17 =[ $painb17, zombie_painb18 ] {};
+void() zombie_painb18 =[ $painb18, zombie_painb19 ] {};
+void() zombie_painb19 =[ $painb19, zombie_painb20 ] {};
+void() zombie_painb20 =[ $painb20, zombie_painb21 ] {};
+void() zombie_painb21 =[ $painb21, zombie_painb22 ] {};
+void() zombie_painb22 =[ $painb22, zombie_painb23 ] {};
+void() zombie_painb23 =[ $painb23, zombie_painb24 ] {};
+void() zombie_painb24 =[ $painb24, zombie_painb25 ] {};
+void() zombie_painb25 =[ $painb25, zombie_painb26 ] {ai_painforward(1);};
+void() zombie_painb26 =[ $painb26, zombie_painb27 ] {};
+void() zombie_painb27 =[ $painb27, zombie_painb28 ] {};
+void() zombie_painb28 =[ $painb28, zombie_run1 ] {};
+
+void() zombie_painc1 =[ $painc1, zombie_painc2 ] {sound_misc2 (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);};
+void() zombie_painc2 =[ $painc2, zombie_painc3 ] {};
+void() zombie_painc3 =[ $painc3, zombie_painc4 ] {ai_pain(3);};
+void() zombie_painc4 =[ $painc4, zombie_painc5 ] {ai_pain(1);};
+void() zombie_painc5 =[ $painc5, zombie_painc6 ] {};
+void() zombie_painc6 =[ $painc6, zombie_painc7 ] {};
+void() zombie_painc7 =[ $painc7, zombie_painc8 ] {};
+void() zombie_painc8 =[ $painc8, zombie_painc9 ] {};
+void() zombie_painc9 =[ $painc9, zombie_painc10 ] {};
+void() zombie_painc10 =[ $painc10, zombie_painc11 ] {};
+void() zombie_painc11 =[ $painc11, zombie_painc12 ] {ai_painforward(1);};
+void() zombie_painc12 =[ $painc12, zombie_painc13 ] {ai_painforward(1);};
+void() zombie_painc13 =[ $painc13, zombie_painc14 ] {};
+void() zombie_painc14 =[ $painc14, zombie_painc15 ] {};
+void() zombie_painc15 =[ $painc15, zombie_painc16 ] {};
+void() zombie_painc16 =[ $painc16, zombie_painc17 ] {};
+void() zombie_painc17 =[ $painc17, zombie_painc18 ] {};
+void() zombie_painc18 =[ $painc18, zombie_run1 ] {};
+
+void() zombie_paind1 =[ $paind1, zombie_paind2 ] {sound_pain (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);};
+void() zombie_paind2 =[ $paind2, zombie_paind3 ] {};
+void() zombie_paind3 =[ $paind3, zombie_paind4 ] {};
+void() zombie_paind4 =[ $paind4, zombie_paind5 ] {};
+void() zombie_paind5 =[ $paind5, zombie_paind6 ] {};
+void() zombie_paind6 =[ $paind6, zombie_paind7 ] {};
+void() zombie_paind7 =[ $paind7, zombie_paind8 ] {};
+void() zombie_paind8 =[ $paind8, zombie_paind9 ] {};
+void() zombie_paind9 =[ $paind9, zombie_paind10 ] {ai_pain(1);};
+void() zombie_paind10 =[ $paind10, zombie_paind11 ] {};
+void() zombie_paind11 =[ $paind11, zombie_paind12 ] {};
+void() zombie_paind12 =[ $paind12, zombie_paind13 ] {};
+void() zombie_paind13 =[ $paind13, zombie_run1 ] {};
+
+void() zombie_paine1 =[ $paine1, zombie_paine2 ] {
+if (self.axhitme == 2) // Chainsaw will gib zombie
+{
+ T_Damage(self, world, world, 80);
+ return;
+}
+sound_pain (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);
+self.health = 60;
+};
+void() zombie_paine2 =[ $paine2, zombie_paine3 ] {ai_pain(8);};
+void() zombie_paine3 =[ $paine3, zombie_paine4 ] {ai_pain(5);};
+void() zombie_paine4 =[ $paine4, zombie_paine5 ] {ai_pain(3);};
+void() zombie_paine5 =[ $paine5, zombie_paine6 ] {ai_pain(1);};
+void() zombie_paine6 =[ $paine6, zombie_paine7 ] {ai_pain(2);};
+void() zombie_paine7 =[ $paine7, zombie_paine8 ] {ai_pain(1);};
+void() zombie_paine8 =[ $paine8, zombie_paine9 ] {ai_pain(1);};
+void() zombie_paine9 =[ $paine9, zombie_paine10 ] {ai_pain(2);};
+void() zombie_paine10 =[ $paine10, zombie_paine11 ] {
+sound_misc3 (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);
+self.solid = SOLID_NOT;
+};
+void() zombie_paine11 =[ $paine11, zombie_paine12 ] {self.nextthink = self.nextthink + 5;self.health = 60;};
+void() zombie_paine12 =[ $paine12, zombie_paine13 ]{
+// see if ok to stand up
+self.health = 60;
+sound_misc (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
+self.solid = SOLID_SLIDEBOX;
+if (!walkmove (0, 0))
+{
+ self.think = zombie_paine11;
+ self.solid = SOLID_NOT;
+ return;
+}
+};
+void() zombie_paine13 =[ $paine13, zombie_paine14 ] {};
+void() zombie_paine14 =[ $paine14, zombie_paine15 ] {};
+void() zombie_paine15 =[ $paine15, zombie_paine16 ] {};
+void() zombie_paine16 =[ $paine16, zombie_paine17 ] {};
+void() zombie_paine17 =[ $paine17, zombie_paine18 ] {};
+void() zombie_paine18 =[ $paine18, zombie_paine19 ] {};
+void() zombie_paine19 =[ $paine19, zombie_paine20 ] {};
+void() zombie_paine20 =[ $paine20, zombie_paine21 ] {};
+void() zombie_paine21 =[ $paine21, zombie_paine22 ] {};
+void() zombie_paine22 =[ $paine22, zombie_paine23 ] {};
+void() zombie_paine23 =[ $paine23, zombie_paine24 ] {};
+void() zombie_paine24 =[ $paine24, zombie_paine25 ] {};
+void() zombie_paine25 =[ $paine25, zombie_paine26 ] {ai_painforward(5);};
+void() zombie_paine26 =[ $paine26, zombie_paine27 ] {ai_painforward(3);};
+void() zombie_paine27 =[ $paine27, zombie_paine28 ] {ai_painforward(1);};
+void() zombie_paine28 =[ $paine28, zombie_paine29 ] {ai_pain(1);};
+void() zombie_paine29 =[ $paine29, zombie_paine30 ] {};
+void() zombie_paine30 =[ $paine30, zombie_run1 ] {};
+
+void() zombie_die =
+{
+ sound_death (self, CHAN_VOICE, "zombie/z_gib.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_zombie.mdl", self.health/*, self.dest*/); //commented out dest -- dumptruck_ds
+ }
+ // ThrowGib ("progs/gib1.mdl", self.health/*, self.dest*/);
+ // ThrowGib ("progs/gib2.mdl", self.health/*, self.dest*/);
+ // ThrowGib ("progs/gib3.mdl", self.health/*, self.dest*/);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ DropStuff();
+};
+
+/*
+=================
+zombie_pain
+
+Zombies can only be killed (gibbed) by doing 60 hit points of damage
+in a single frame (rockets, grenades, quad shotgun, quad nailgun).
+
+A hit of 25 points or more (super shotgun, quad nailgun) will always put it
+down to the ground.
+
+A hit of from 10 to 40 points in one frame will cause it to go down if it
+has been twice in two seconds, otherwise it goes into one of the four
+fast pain frames.
+
+A hit of less than 10 points of damage (winged by a shotgun) will be ignored.
+
+FIXME: don't use pain_finished because of nightmare hack
+=================
+*/
+void(entity attacker, float take) zombie_pain =
+{
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.health = 60; // always reset health
+
+ if (take >= 60)
+ {
+ zombie_die();
+ }
+ else
+ return;
+ }
+
+ local float r;
+
+ self.health = 60; // always reset health
+
+ if (take < 9)
+ return; // totally ignore
+
+ if (self.inpain == 2)
+ return; // down on ground, so don't reset any counters
+
+// go down immediately if a big enough hit
+ if ((take >= 25) || (self.axhitme == 2))
+ {
+ self.inpain = 2;
+ zombie_paine1 ();
+ return;
+ }
+
+ if (self.inpain)
+ {
+// if hit again in next gre seconds while not in pain frames, definately drop
+ self.pain_finished = time + 3;
+ return; // currently going through an animation, don't change
+ }
+
+ if (self.pain_finished > time)
+ {
+// hit again, so drop down
+ self.inpain = 2;
+ zombie_paine1 ();
+ return;
+ }
+
+// gp into one of the fast pain animations
+ self.inpain = 1;
+
+ r = random();
+ if (r < 0.25)
+ zombie_paina1 ();
+ else if (r < 0.5)
+ zombie_painb1 ();
+ else if (r < 0.75)
+ zombie_painc1 ();
+ else
+ zombie_paind1 ();
+};
+
+void() zombie_decide = // stand up if orig. lying down, else just start running
+{
+ if (self.health==61)
+ zombie_paine12();
+ else
+ zombie_run1();
+
+ self.th_run = zombie_run1;
+};
+
+void() zombie_use = // wake up a sleeping zombie!
+
+{
+ self.count = 0;
+ //attacker = other;
+ monster_use();
+};
+
+void() zombie_start = // determine if zombie is to be lying down, or standing
+{
+ self.count = 1; //dumptruck_ds -- Don't start zombie_stand1 yet!
+ self.use = zombie_use; //dumptruck_ds -- makes self.count = 0 so zombie_stand1 is called
+
+ if (self.spawnflags & SPAWN_SLEEPING)
+ {
+ if (!SUB_IsTargeted ())
+ {
+ dprint ("WARNING: removed untargeted sleeping zombie at ");
+ dprint (vtos (self.origin));
+ dprint ("\n");
+
+ monster_update_total (-1);
+ remove (self);
+ return;
+ }
+ self.inpain = 2;
+ zombie_stand1 ();
+ }
+ else
+ {
+ alt_zombie_stand1 ();
+ }
+
+ self.th_stand = alt_zombie_stand1;
+};
+
+// void() zombie_start2 = //unused in progs_dump -- dumptruck_ds
+// {
+// local vector org;
+// local entity teldeath;
+//
+// if (self.style)
+// {
+// makevectors (self.angles);
+// org = self.origin + 16 * v_forward;
+// spawn_tfog (org);
+// teldeath = spawn();
+// teldeath.origin = org;
+// teldeath.owner = self;
+// // teldeath.think = sf64_teledeath; -- not used in progs_dump -- dumptruck_ds
+// teldeath.nextthink = time + 0.1;
+// }
+//
+// self.solid = SOLID_SLIDEBOX;
+// self.movetype = MOVETYPE_STEP;
+//
+// setmodel (self, "progs/zombie.mdl");
+//
+// setsize (self, '-16 -16 -24', '16 16 40');
+// self.health = 61;
+//
+// walkmonster_start();
+// };
+
+//============================================================================
+
+/*QUAKED monster_zombie (1 0 0) (-16 -16 -24) (16 16 32) CRUCIFIED AMBUSH CRUCIFIED_MOTIONLESS TRIGGER_SPAWNED SPAWN_SLEEPING X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ( {{ spawnflags & 1 -> { "path" : "progs/zombie.mdl", "frame" : 192 }, "progs/zombie.mdl" }} );
+}
+If crucified, stick the bounding box 12 pixels back into a wall to look right.
+
+Default health = 60
+
+If SPAWN_SLEEPING is used there must be a targetname set. The zombie will stand up when targeted. Crucified motionless zombies are silent and do not animate." //dumptruck_ds
+
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_attack(string) : "Path to custom attack sound (WHOOSH)"
+snd_idle(string) : "Path to custom idle sound (CRUCIFIED ONLY)"
+snd_misc(string) : "Path to custom (IDLE 2) sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_misc2(string) : "Path to custom (PAIN 2) sound"
+snd_misc3(string) : "Path to custom (FALLING) sound"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+mdl_proj(string) : "Path to custom projectile model"
+skin_head(float) : "Skin index of custom head model"
+skin_proj(float) : "Skin index of custom projectile model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+spawnflags(Flags) =
+1 : "Crucified"
+2 : "Ambush"
+4 : "Crucified motionless"
+16 : "Spawn Sleeping"
+*/
+void() monster_zombie =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch /*&& (!(self.spawnflags & SPAWN_DEAD_CRUCIFIED))*/)
+ {
+ remove(self);
+ return;
+ }
+
+ precache_body_model ("progs/zombie.mdl"); //custom_mdls dumptruck_ds
+ precache_head_model ("progs/h_zombie.mdl");
+ precache_proj_model ("progs/zom_gib.mdl");
+ // precache_model ("progs/zombie.mdl");
+ // precache_model ("progs/h_zombie.mdl");
+ // precache_model ("progs/zom_gib.mdl");
+
+ precache_sound_misc ("zombie/z_idle.wav");
+ precache_sound_sight ("zombie/z_idle1.wav");
+ precache_sound_attack ("zombie/z_shot1.wav");
+ precache_sound_death ("zombie/z_gib.wav");
+ precache_sound_pain ("zombie/z_pain.wav");
+ precache_sound_misc2 ("zombie/z_pain1.wav");
+ precache_sound_misc3 ("zombie/z_fall.wav");
+ precache_sound ("zombie/z_miss.wav");
+ precache_sound ("zombie/z_hit.wav");
+
+ precache_sound_idle ("zombie/idle_w2.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.th_stand = zombie_start;
+ self.th_walk = zombie_walk1;
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_run = alt_zombie_seek_stand1;
+ }
+ else
+ {
+ self.th_run = zombie_decide;
+ }
+
+ self.th_pain = zombie_pain;
+ self.th_die = zombie_die;
+ self.th_turret = zombie_turret_missile;
+ self.th_missile = zombie_missile;
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/zombie.mdl"); //custom_mdls dumptruck_ds
+ // setmodel (self, "progs/zombie.mdl");
+
+ setsize (self, '-16 -16 -24', '16 16 40');
+ self.health = 61;
+
+ if (self.spawnflags & SPAWN_CRUCIFIED)
+ {
+ self.movetype = MOVETYPE_NONE;
+ zombie_cruc1 ();
+ }
+ else if (self.spawnflags & SPAWN_DEAD_CRUCIFIED)
+ {
+ self.movetype = MOVETYPE_NONE;
+ zombie_dead_cruc1 ();
+ }
+ else
+ walkmonster_start();
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/newflags.qc

diff --git a/qc/newflags.qc b/qc/newflags.qc
new file mode 100644
index 0000000..07d8ff5
--- /dev/null
+++ b/qc/newflags.qc
@@ -0,0 +1,205 @@
+/*
+========================================================================
+
+NEW SPAWNFLAGS FOR ALL ENTITIES
+
+========================================================================
+
+
+This file was created for progs_dump by Ian "iw" Walshaw, August 2019.
+
+It defines functions which can be called to implement the following new
+spawnflags:
+
+ 4096 Not in Coop
+ 8192 Not in Single Player
+ 32768 Not on Hard Only
+ 65536 Not on Nightmare Only
+
+(Spawnflag 16384 is not used here because it's already used for
+something else in progs_dump.)
+
+The new spawnflags complement and complete the set of built-in
+spawnflags provided by the engine, which of course are:
+
+ 256 Not on Easy
+ 512 Not on Normal
+ 1024 Not on Hard or Nightmare
+ 2048 Not in Deathmatch
+
+In conjunction with the old spawnflags, the new spawnflags make it
+possible to exclude any entity from any combination of game modes and/or
+skill levels.
+
+
+"Not in Coop" and "Not in Single Player"
+----------------------------------------
+
+These spawnflags were inspired by Quoth 2 (Kell and Necros, 2008), which
+included two additional spawnflags for all entities: "Not in Coop" and
+"Coop Only". In contrast to Quoth 2, the spawnflags implemented here
+are "Not in Coop" and "Not in Single Player", for symmetry with the
+built-in "Not in Deathmatch" spawnflag.
+
+
+"Not on Hard Only" and "Not on Nightmare Only"
+----------------------------------------------
+
+The set of built-in spawnflags doesn't allow a mapper to treat the Hard
+and Nightmare skill levels differently, because it only includes one
+spawnflag, 1024, which excludes an entity from both Hard and Nightmare.
+The new "Not on Hard Only" and "Not on Nightmare Only" spawnflags allow
+the mapper to exclude an entity from one of these skill levels without
+affecting the other.
+
+
+========================================================================
+*/
+
+
+// The new spawnflags. (16384 is already used elsewhere.)
+float SPAWNFLAG_NOT_IN_COOP = 4096; // Not in Coop
+float SPAWNFLAG_NOT_IN_SP = 8192; // Not in Single Player
+float SPAWNFLAG_NOT_ON_SKILL2 = 32768; // Not on Hard Only
+float SPAWNFLAG_NOT_ON_SKILL3 = 65536; // Not on Nightmare Only
+
+// The number of entities inhibited by each of the new spawnflags.
+float total_not_in_coop;
+float total_not_in_sp;
+float total_not_on_skill2;
+float total_not_on_skill3;
+
+// TRUE if the developer summary has been printed.
+float done_inhibition_summary;
+
+
+/*
+================
+InitNewSpawnflags
+
+This function is intended to be called from the top of the worldspawn
+function (in world.qc). -- iw
+================
+*/
+void() InitNewSpawnflags =
+{
+ // Initialize the global variables.
+ total_not_in_coop = 0;
+ total_not_in_sp = 0;
+ total_not_on_skill2 = 0;
+ total_not_on_skill3 = 0;
+ done_inhibition_summary = FALSE;
+
+ // In the original code, the value of the skill cvar was not copied
+ // into the skill global until the first call to StartFrame.
+ // However, the new SUB_Inhibit function will need to check what the
+ // skill is before then, so, the value is copied here. -- iw
+ skill = cvar ("skill");
+};
+
+
+/*
+================
+SUB_Inhibit
+
+This function is intended to be called from the top of every spawn
+function, like this:
+
+ if (SUB_Inhibit ())
+ return;
+
+If the entity's spawnflags mean that it should be inhibited in the
+current game mode or on the current skill level, this function will
+remove the entity and return TRUE, otherwise this function will take no
+action and return FALSE. -- iw
+================
+*/
+float() SUB_Inhibit =
+{
+ if (coop && (self.spawnflags & SPAWNFLAG_NOT_IN_COOP))
+ {
+ total_not_in_coop = total_not_in_coop + 1;
+ remove (self);
+ return TRUE;
+ }
+
+ if (!coop && !deathmatch && (self.spawnflags & SPAWNFLAG_NOT_IN_SP))
+ {
+ total_not_in_sp = total_not_in_sp + 1;
+ remove (self);
+ return TRUE;
+ }
+
+ // The built-in skill level spawnflags are ignored in Deathmatch, so
+ // we ignore the new ones in Deathmatch, too. -- iw
+ if (!deathmatch)
+ {
+ if (skill == 2 && (self.spawnflags & SPAWNFLAG_NOT_ON_SKILL2))
+ {
+ total_not_on_skill2 = total_not_on_skill2 + 1;
+ remove (self);
+ return TRUE;
+ }
+
+ if (skill == 3 && (self.spawnflags & SPAWNFLAG_NOT_ON_SKILL3))
+ {
+ total_not_on_skill3 = total_not_on_skill3 + 1;
+ remove (self);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+};
+
+
+/*
+================
+PrintInhibitionTotal
+
+This just dprints the summary line about the total number of entities
+inhibited by one of the new spawnflags (see PrintInhibitionSummary
+below). -- iw
+================
+*/
+void(float total, string spawnflag_name) PrintInhibitionTotal =
+{
+ if (total == 0)
+ return;
+
+ dprint ("... ");
+ dprint (ftos (total));
+ dprint (" with '");
+ dprint (spawnflag_name);
+ dprint ("' spawnflag\n");
+};
+
+
+/*
+================
+PrintInhibitionSummary
+
+This function is intended to be called from the top of the StartFrame
+function (in world.qc), like this:
+
+ if (!done_inhibition_summary)
+ PrintInhibitionSummary ();
+
+The engine already logs a developer message about the number of entities
+inhibited by the built-in spawnflags; this function logs a message about
+the number of entities inhibited by the new spawnflags. -- iw
+================
+*/
+void() PrintInhibitionSummary =
+{
+ dprint (ftos (total_not_in_coop + total_not_in_sp +
+ total_not_on_skill2 + total_not_on_skill3));
+ dprint (" additional entities inhibited by the progs.dat\n");
+
+ PrintInhibitionTotal (total_not_in_coop, "Not in Coop");
+ PrintInhibitionTotal (total_not_in_sp, "Not in Single Player");
+ PrintInhibitionTotal (total_not_on_skill2, "Not on Hard Only");
+ PrintInhibitionTotal (total_not_on_skill3, "Not on Nightmare Only");
+
+ done_inhibition_summary = TRUE;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/plats.qc

diff --git a/qc/plats.qc b/qc/plats.qc
new file mode 100644
index 0000000..f6c5166
--- /dev/null
+++ b/qc/plats.qc
@@ -0,0 +1,786 @@
+
+
+void() plat_center_touch;
+void() plat_outside_touch;
+void() plat_trigger_use;
+void() plat_go_up;
+void() plat_go_down;
+void() plat_crush;
+float PLAT_LOW_TRIGGER = 1;
+
+void() plat_spawn_inside_trigger =
+{
+ local entity trigger;
+ local vector tmin, tmax;
+
+//
+// middle trigger
+//
+ trigger = spawn();
+ trigger.touch = plat_center_touch;
+ trigger.movetype = MOVETYPE_NONE;
+ trigger.solid = SOLID_TRIGGER;
+ trigger.enemy = self;
+
+ tmin = self.mins + '25 25 0';
+ tmax = self.maxs - '25 25 -8';
+ tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8);
+ if (self.spawnflags & PLAT_LOW_TRIGGER)
+ tmax_z = tmin_z + 8;
+
+ if (self.size_x <= 50)
+ {
+ tmin_x = (self.mins_x + self.maxs_x) / 2;
+ tmax_x = tmin_x + 1;
+ }
+ if (self.size_y <= 50)
+ {
+ tmin_y = (self.mins_y + self.maxs_y) / 2;
+ tmax_y = tmin_y + 1;
+ }
+
+ setsize (trigger, tmin, tmax);
+};
+
+void() plat_hit_top =
+{
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ self.state = STATE_TOP;
+ self.think = plat_go_down;
+ self.nextthink = self.ltime + 3;
+};
+
+void() plat_hit_bottom =
+{
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ self.state = STATE_BOTTOM;
+};
+
+void() plat_go_down =
+{
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ self.state = STATE_DOWN;
+ SUB_CalcMove (self.pos2, self.speed, plat_hit_bottom);
+};
+
+void() plat_go_up =
+{
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ self.state = STATE_UP;
+ SUB_CalcMove (self.pos1, self.speed, plat_hit_top);
+};
+
+void() plat_center_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ self = self.enemy;
+ if (self.state == STATE_BOTTOM)
+ plat_go_up ();
+ else if (self.state == STATE_TOP)
+ self.nextthink = self.ltime + 1; // delay going down
+};
+
+void() plat_outside_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+//dprint ("plat_outside_touch\n");
+ self = self.enemy;
+ if (self.state == STATE_TOP)
+ plat_go_down ();
+};
+
+void() plat_trigger_use =
+{
+ if (self.think)
+ return; // allready activated
+ plat_go_down();
+};
+
+
+void() plat_crush =
+{
+//dprint ("plat_crush\n");
+
+ T_Damage (other, self, self, 1);
+
+ if (self.state == STATE_UP)
+ plat_go_down ();
+ else if (self.state == STATE_DOWN)
+ plat_go_up ();
+ else
+ objerror ("plat_crush: bad self.state\n");
+};
+
+void() plat_use =
+{
+ self.use = SUB_Null;
+ if (self.state != STATE_UP)
+ objerror ("plat_use: not in up state");
+ plat_go_down();
+};
+
+
+/*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+speed default 150
+
+Plats are always drawn in the extended position, so they will light correctly.
+
+If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat.
+
+If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determined by the model's height.
+Set "sounds" to one of the following:
+1) base fast
+2) chain slow
+*/
+
+
+void() func_plat =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.t_length)
+ self.t_length = 80;
+ if (!self.t_width)
+ self.t_width = 10;
+
+ if (self.sounds == 0)
+ self.sounds = 2;
+// FIX THIS TO LOAD A GENERIC PLAT SOUND
+
+ if (self.sounds == 1)
+ {
+ precache_sound ("plats/plat1.wav");
+ precache_sound ("plats/plat2.wav");
+ self.noise = "plats/plat1.wav";
+ self.noise1 = "plats/plat2.wav";
+ }
+
+ if (self.sounds == 2)
+ {
+ precache_sound ("plats/medplat1.wav");
+ precache_sound ("plats/medplat2.wav");
+ self.noise = "plats/medplat1.wav";
+ self.noise1 = "plats/medplat2.wav";
+ }
+
+
+ self.mangle = self.angles;
+ self.angles = '0 0 0';
+
+ self.classname = "plat";
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ setorigin (self, self.origin);
+ setmodel (self, self.model);
+ setsize (self, self.mins , self.maxs);
+
+ self.blocked = plat_crush;
+ if (!self.speed)
+ self.speed = 150;
+
+// pos1 is the top position, pos2 is the bottom
+ self.pos1 = self.origin;
+ self.pos2 = self.origin;
+ if (self.height)
+ self.pos2_z = self.origin_z - self.height;
+ else
+ self.pos2_z = self.origin_z - self.size_z + 8;
+
+ self.use = plat_trigger_use;
+
+ plat_spawn_inside_trigger (); // the "start moving" trigger
+
+ if (self.targetname != "")
+ {
+ self.state = STATE_UP;
+ self.use = plat_use;
+ }
+ else
+ {
+ setorigin (self, self.pos2);
+ self.state = STATE_BOTTOM;
+ }
+};
+
+//============================================================================
+// TRAINS
+//============================================================================
+void() train_next;
+void() func_train_find;
+
+float TRAIN_RETRIGGER = 1;
+float TRAIN_MOVEONTRIGGER = 2;
+float TRAIN_STOPONTRIGGER = 4;
+float TRAIN_NONSOLID = 8;
+float TRAIN_NOROTATE = 16;
+float TRAIN_ROTATEY = 32;
+float TRAIN_CUSTOMALIGN = 64;
+
+float TRAIN_NEXT_WAIT = 0; //normal movement
+float TRAIN_NEXT_STOP = 1; // force a stop on the next path_corner
+float TRAIN_NEXT_CONTINUE = 2; // force continue on the next path_corner (ignores wait time)
+
+float TRAIN_STYLE_SINGLEANIM = 1;
+
+float TRAIN_ANIMTYPE_FORWARD = 1;
+float TRAIN_ANIMTYPE_BACKFORTH = 2;
+
+void() train_blocked = {
+ if (time < self.attack_finished) return;
+
+ self.attack_finished = time + 0.5;
+ T_Damage (other, self, self, self.dmg);
+};
+
+
+// Use function for when the train is stopped.
+// Makes the train continue on path_corners with wait -1,
+// or forces a continue if the "move on trigger" spawnflag is set.
+void() train_use = {
+
+ if (self.spawnflags & TRAIN_MOVEONTRIGGER || self.wait < 0) {
+ train_next();
+ return;
+ }
+
+ // Train has already moved after startup, and has no "stop on trigger" flag,
+ // so ignore activation.
+ if (self.think != func_train_find && self.cnt != TRAIN_NEXT_STOP)
+ return;
+
+ train_next();
+};
+
+// Use function for when the train is moving.
+// Forces a stop or an instant continue on the next path_corner depending on the spawnflag set
+void() train_moving_use = {
+ if (self.spawnflags & TRAIN_MOVEONTRIGGER || self.wait < 0)
+ self.cnt = TRAIN_NEXT_CONTINUE;
+ else if (self.spawnflags & TRAIN_STOPONTRIGGER)
+ self.cnt = TRAIN_NEXT_STOP;
+}
+
+// path_corner has been reached, so decide what to do next
+void() train_wait = {
+ float localtime;
+ if (self.movetype == MOVETYPE_PUSH) localtime = self.ltime;
+ else localtime = time;
+
+ self.use = train_use; //ready to be re-triggered
+
+ // from Copper
+ // Trains now fire their path_corners' targets on arrival.
+ // If a player is riding the train, treat them as activator.
+ activator = nextent(world);
+ while (!EntitiesTouching(self,activator) && activator.classname == "player")
+ activator = nextent(activator);
+ if (activator.classname != "player")
+ activator = nextent(world); // default to player1 wherever they are
+ SUB_UseEntTargets(self.enemy);
+
+ if (self.enemy.speed) self.speed2 = self.enemy.speed; // sets the speed from the current path_corner
+
+ // copies the modeltrain animation parameters set in the path_corner, if any
+ if (self.classname == "misc_modeltrain") {
+ if (self.enemy.first_frame) self.first_frame = self.enemy.first_frame;
+ if (self.enemy.last_frame) self.last_frame = self.enemy.last_frame;
+ if (self.enemy.first_frame2) self.first_frame2 = self.enemy.first_frame2;
+ if (self.enemy.last_frame2) self.last_frame2 = self.enemy.last_frame2;
+ if (self.enemy.frtime) self.frtime = self.enemy.frtime;
+ if (self.enemy.frtime2) self.frtime2 = self.enemy.frtime2;
+ if (self.enemy.animtype) self.animtype = self.enemy.animtype;
+ if (self.enemy.animtype2) self.animtype2 = self.enemy.animtype2;
+ if (self.enemy.multiplier) self.multiplier = self.enemy.multiplier;
+ }
+
+ self.think = train_next;
+
+ // train is moving normally and path_corner has a wait set, so pause for that time.
+ if (self.wait > 0 && self.cnt == TRAIN_NEXT_WAIT && !(self.spawnflags & TRAIN_RETRIGGER)) {
+ // state: stopped
+ self.state = 0;
+ if (self.classname == "misc_modeltrain") SUB_CallAsSelf(self.animcontroller.think, self.animcontroller);
+ self.nextthink = localtime + self.wait;
+
+ //play stopping sound. If path_corner has a custom sound, play that instead
+ if (self.enemy.noise != "") sound(self, CHAN_WEAPON, self.enemy.noise, 1, ATTN_NORM);
+ else sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ }
+ // train is moving normally and path_corner has no wait time,
+ // or has been forced to move instantly through a triggering.
+ else if (self.cnt != TRAIN_NEXT_STOP && !self.wait && !(self.spawnflags & TRAIN_RETRIGGER)) {
+
+ //play "passing by" sound, if any. If path_corner has a custom one, play that instead
+ if (self.enemy.noise2 != "") sound(self, CHAN_WEAPON, self.enemy.noise2, 1, ATTN_NORM);
+ else if (self.noise2 != "") sound(self, CHAN_WEAPON, self.noise2, 1, ATTN_NORM);
+
+ self.nextthink = -1; // move instantly
+ train_next();
+ }
+ // path_corner has wait -1, or train has been forced to stop through a triggering.
+ // Also catches the backwards compatible case for the original rubicon2 "retrigger" flag.
+ else {
+ //play stopping sound. If path_corner has a custom sound, play that instead
+ if (self.enemy.noise != "") sound(self, CHAN_WEAPON, self.enemy.noise, 1, ATTN_NORM);
+ else sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+
+ // state: stopped
+ self.state = 0;
+
+ if (self.classname == "misc_modeltrain") SUB_CallAsSelf(self.animcontroller.think, self.animcontroller);
+ self.nextthink = -1;
+ }
+
+
+};
+
+// searches for the next path_corner and sends the train on its way
+void() train_next = {
+ local entity targ;
+ vector destang, displ;
+
+ targ = find(world, targetname, self.target);
+
+ if (!targ || self.target == "")
+ objerror("train_next: no next target");
+
+ self.target = targ.target;
+
+ // gets the wait time from the upcoming path_corner if set
+ if (targ.wait){
+ // wait -2 on the path_corner forces it to continue moving (no wait),
+ // even if the train has a default wait time
+ if (targ.wait == -2) self.wait = 0;
+ else self.wait = targ.wait;
+ }
+ // uses train's current wait time otherwise
+ else
+ self.wait = self.pausetime;
+
+ self.enemy = targ;
+
+ sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+
+ if(!(!self.wait && self.cnt == TRAIN_NEXT_CONTINUE)) self.cnt = TRAIN_NEXT_WAIT;
+
+ //store up any premature triggerings until current movement is finished
+ self.use = train_moving_use;
+
+ if (self.classname == "misc_modeltrain") {
+ if (!(self.spawnflags & TRAIN_NOROTATE)) {
+ destang = vectoangles(targ.origin - self.origin);
+ if (self.spawnflags & TRAIN_ROTATEY) {
+ destang_x = self.angles_x;
+ destang_z = self.angles_z;
+ }
+ if (self.multiplier > 0) SUB_CalcAngleMoveController(destang, self.speed2*self.multiplier, SUB_Null, self.rotatecontroller);
+ else self.angles = destang;
+ }
+ }
+
+ if (!self.state) {
+ self.state = 1;
+ if (self.classname == "misc_modeltrain" && self.style != TRAIN_STYLE_SINGLEANIM)
+ SUB_CallAsSelf(self.animcontroller.think, self.animcontroller);
+ }
+ // if the TRAIN_CUSTOMALIGN flag is checked then the train should align
+ // with its path_corners based on the location of an "origin" brush added
+ // to the train by the mapper instead of the mins corner
+ // -therektafire
+ float doDisplace;
+ if (self.spawnflags & TRAIN_CUSTOMALIGN) doDisplace = 0.0;
+ else doDisplace = 1.0;
+
+ if (self.classname != "misc_modeltrain") displ = self.mins;
+
+ SUB_CalcMove(targ.origin - (displ * doDisplace), self.speed2, train_wait);
+};
+
+// searches for the first path_corner after the train entity is initialized
+void() func_train_find = {
+ local entity targ;
+ float localtime;
+ vector displ;
+
+ if (self.movetype == MOVETYPE_PUSH) localtime = self.ltime;
+ else localtime = time;
+
+ targ = find(world, targetname, self.target);
+ self.target = targ.target;
+
+ float doDisplace;
+ if (self.spawnflags & TRAIN_CUSTOMALIGN) doDisplace = 0.0;
+ else doDisplace = 1.0;
+
+ if (self.classname != "misc_modeltrain") displ = self.mins;
+ self.enemy = targ;
+ setorigin(self, targ.origin - (displ * doDisplace));
+ if (targ.speed) self.speed2 = targ.speed; // uses speed from the 1st path corner if set
+
+ if (!self.targetname)
+ { // not triggered, so start immediately
+ self.nextthink = localtime + 0.1;
+ self.think = train_next;
+ }
+};
+
+/*QUAKED func_train (0 .5 .8) ? RETRIGGER
+Trains are moving platforms that players can ride.
+The targets origin specifies the min point of the train at each corner.
+The train spawns at the first target it is pointing at.
+If the train is the target of a button or trigger, it will not begin moving until activated.
+
+RETRIGGER: stop at each path_corner and don't resume until triggered again (ignores wait time)
+
+speed default 100
+dmg default 2
+sounds
+1) ratchet metal
+2) base
+
+*/
+void() func_train =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.speed)
+ self.speed = 100;
+ if (!self.target)
+ objerror ("func_train without a target");
+ if (!self.dmg)
+ self.dmg = 2;
+
+ if(self.spawnflags & TRAIN_STOPONTRIGGER && self.spawnflags & TRAIN_MOVEONTRIGGER)
+ objerror("func_train: Stop and move on trigger set at the same time");
+
+
+
+ if (self.sounds == 1) {
+ if (self.noise == "") self.noise = ("plats/train2.wav");
+ if (self.noise1 == "") self.noise1 = ("plats/train1.wav");
+ }
+ else if (self.sounds == 2) { // base door sound
+ if (self.noise == "") self.noise = "doors/hydro2.wav";
+ if (self.noise1 == "") self.noise1 = "doors/hydro1.wav";
+ }
+ else {
+ if (self.noise == "") self.noise = ("misc/null.wav");
+ if (self.noise1 == "") self.noise1 = ("misc/null.wav");
+ }
+
+ // backwards compatibility with previous version
+ if (self.noise3 != "") self.noise = self.noise3;
+ if (self.noise4 != "") self.noise1 = self.noise4;
+
+ precache_sound(self.noise);
+ precache_sound(self.noise1);
+ if (self.noise2 != "") precache_sound(self.noise2);
+
+
+ self.cnt = TRAIN_NEXT_WAIT;
+
+ if (self.spawnflags & TRAIN_NONSOLID) {
+ self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_NOCLIP;
+ }
+ else {
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ }
+
+ self.blocked = train_blocked;
+ self.use = train_use;
+ //self.classname = "train";
+
+ setmodel (self, self.model);
+ setsize (self, self.mins , self.maxs);
+ setorigin (self, self.origin);
+
+ // start trains on the second frame, to make sure their targets have had
+ // a chance to spawn
+
+ if (self.movetype == MOVETYPE_PUSH) self.nextthink = self.ltime + 0.1;
+ else self.nextthink = time + 0.1;
+
+ self.think = func_train_find;
+
+ self.speed2 = self.speed;
+};
+
+
+//===================================================
+
+
+void() animcontroller_think = {
+ entity tr;
+ tr = self.owner;
+
+ float first, last, step, atype, dir, nextframe;
+
+ // train just went from stopped to moving or vice-versa,
+ // and have both animations set
+ if (self.state != tr.state && tr.style != TRAIN_STYLE_SINGLEANIM) {
+ if (tr.state) { // just started moving
+ tr.frame = zeroconvert(tr.first_frame2);
+ }
+ else { // just stopped
+ tr.frame = zeroconvert(tr.first_frame);
+ }
+ tr.distance = 1; // reset back/forth status
+ self.state = tr.state;
+ }
+
+ else {
+ if (self.state && tr.style != TRAIN_STYLE_SINGLEANIM) { // moving train animation, if set
+ first = zeroconvert(tr.first_frame2);
+ last = zeroconvert(tr.last_frame2);
+ atype = tr.animtype2;
+ }
+ else { // stopped/default train animation
+ first = zeroconvert(tr.first_frame);
+ last = zeroconvert(tr.last_frame);
+ atype = tr.animtype;
+ }
+
+ if (first > last) step = dir = -1; // reverse direction
+ else step = dir = 1;
+
+ // back-and-forth is going the other way, so invert the step's signal
+ if (tr.distance < 0) step = step * (-1);
+
+ nextframe = tr.frame + step;
+
+ if (atype == TRAIN_ANIMTYPE_BACKFORTH){
+ if (dir > 0 && (nextframe > last || nextframe < first) ||
+ dir < 0 && (nextframe > first || nextframe < last)
+ ) {
+ nextframe = tr.frame - step;
+ tr.distance = tr.distance * (-1);
+ }
+ }
+
+ if (dir > 0) nextframe = wrap(nextframe, first, last);
+ else nextframe = wrap(nextframe, last, first);
+
+ tr.frame = nextframe;
+
+ }
+
+ self.think = animcontroller_think;
+ if (self.state || tr.style == TRAIN_STYLE_SINGLEANIM) self.nextthink = time + tr.frtime;
+ else self.nextthink = time + tr.frtime2;
+};
+
+void() misc_modeltrain = {
+
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model(self.mdl);
+
+ func_train();
+
+ if (self.spawnflags & TRAIN_NONSOLID)
+ self.solid = SOLID_NOT;
+ else {
+ self.solid = SOLID_BBOX;
+ if (self.cmins == VEC_ORIGIN) self.cmins = '-8 -8 -8';
+ if (self.cmaxs == VEC_ORIGIN) self.cmaxs = '8 8 8';
+ }
+
+ self.movetype = MOVETYPE_NOCLIP;
+ setmodel (self, self.mdl);
+ setsize (self, self.cmins , self.cmaxs);
+ setorigin (self, self.origin);
+
+ entity rot, anim;
+
+ rot = spawn();
+ self.rotatecontroller = rot;
+ rot.classname = "rotatecontroller";
+ rot.owner = self;
+
+ anim = spawn();
+ self.animcontroller = anim;
+ anim.classname = "animcontroller";
+ anim.owner = self;
+
+ anim.think = animcontroller_think;
+ anim.nextthink = time + 0.2;
+
+ self.distance = 1;
+
+ if (!self.frtime) self.frtime = 0.1;
+ if (!self.frtime2) self.frtime2 = self.frtime;
+ if (!self.multiplier) self.multiplier = 1;
+
+
+ // make sure all first and last frame fields are filled
+ if (self.first_frame && !self.last_frame) self.last_frame = self.first_frame;
+ else if (!self.first_frame && self.last_frame) self.first_frame = self.last_frame;
+
+ if (self.first_frame2 && !self.last_frame2) self.last_frame2 = self.first_frame2;
+ else if (!self.first_frame2 && self.last_frame2) self.first_frame2 = self.last_frame2;
+
+ if (!self.first_frame2) self.style = TRAIN_STYLE_SINGLEANIM;
+
+ if (!self.animtype) self.animtype = TRAIN_ANIMTYPE_FORWARD;
+ if (!self.animtype2) self.animtype2 = self.animtype;
+
+ self.frame = self.first_frame;
+
+};
+
+
+//===================================================
+
+
+//Code for the fixed teleporttrain written by c0burn and modified by ZungryWare
+void() teleporttrain_calcmove;
+void() teleporttrain_next =
+{
+ local vector dir;
+ setorigin(self, self.enemy.origin + '16 16 16');
+
+ if (!self.target)
+ {
+ self.enemy = world;
+ return;
+ }
+ self.enemy = find(world, targetname, self.target);
+ if (self.enemy.classname == "path_corner")
+ {
+ dir = normalize((self.enemy.origin + '16 16 16') - self.origin);
+ self.velocity = dir * self.speed;
+ self.target = self.enemy.target;
+ }
+ else
+ {
+ objerror("unable to find target\n");
+ remove(self);
+ }
+ teleporttrain_calcmove();
+};
+void() teleporttrain_wait =
+{
+ local float wait_time;
+ if (self.enemy.wait > 0)
+ wait_time = self.enemy.wait;
+ else
+ wait_time = .1;
+ self.velocity = '0 0 0';
+ self.nextthink = time + wait_time;
+ self.think = teleporttrain_next;
+
+}
+void() teleporttrain_calcmove =
+{
+ local float len;
+ local vector delta;
+ local float spd;
+
+ delta = (self.enemy.origin + '16 16 16') - self.origin;
+ len = vlen(delta);
+ spd = vlen(self.velocity);
+ self.nextthink = time + (len / spd);
+ self.think = teleporttrain_wait;
+};
+void() teleporttrain_use =
+{
+ if (self.velocity == '0 0 0')
+ {
+ teleporttrain_next();
+ }
+};
+void() teleporttrain_find =
+{
+ // always start positioned on the first path_corner
+ self.enemy = find(world, targetname, self.target);
+ if (self.enemy.classname == "path_corner")
+ {
+ setorigin (self, self.enemy.origin + '16 16 16');
+ self.target = self.enemy.target;
+ }
+ else
+ {
+ objerror("unable to find target\n");
+ remove(self);
+ return;
+ }
+
+ if (self.spawnflags & 4) // start immediately even with a targetname
+ {
+ teleporttrain_next();
+ }
+ // not triggered, so start immediately
+ else if (!self.targetname)
+ {
+ teleporttrain_next();
+ }
+ else
+ {
+ self.use = teleporttrain_use;
+ }
+};
+/*QUAKED misc_teleporttrain (.5 .5 .5) (-16 -16 -16) (16 16 16) X DONT_ROTATE START_ON_WITH_TARGETNAME INVISIBLE X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/teleport.mdl"); }
+This was used for the final boss level in the original game. In progs_dump you can use this as a moving decoration or even target it as a spawn point for a func_monster_spawner. Make sure and select the Don't Rotate spawnflag though or you'll experience a pretty hilarious effect!
+
+You set this up like a func_train using path_corners. By default, it will move automatically between path corners upon map load. However, you can have it wait to move by giving it a targetname. If you need to target it as a spawner and want it to move on map load, use the Start On spawnflag.
+
+You can add effects, use a custom model using the mdl_body keyvalue and even make it invisible with spawnflag 8.
+
+Effects
+0: "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+
+Teleporter target for final boss level. Must target a series of 'path_corner' entities.
+It will position itself on its first target at map load.
+If a targetname is set, it must be triggered to start moving, otherwise it will start automatically.
+*/
+void() misc_teleporttrain =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.target)
+ {
+ objerror ("misc_teleporttrain has no target");
+ remove(self);
+ return;
+ }
+ if (self.speed <= 0)
+ {
+ self.speed = 100;
+ }
+
+ self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_FLY;
+ precache_body_model ("progs/teleport.mdl"); // custom custom_mdls -- dumptruck_ds
+ precache_model ("progs/s_null.spr"); // invisble -- dumptruck_ds
+ if (self.spawnflags & 8)
+ // setmodel (self, "progs/s_null.spr");
+ body_model ("progs/s_null.spr");
+ else
+ body_model ("progs/teleport.mdl");
+ // precache_model ("progs/teleport.mdl");
+ setsize (self, '-16 -16 -16', '16 16 16');
+
+ //Causes the ball to spin around like it was originally intended to.
+ if (!(self.spawnflags & 2)) //don't spin - helpful for invisible spawner -- dumptruck_ds
+ self.avelocity = '40 80 120';
+ // self.avelocity = '100 200 300';
+
+ self.think = teleporttrain_find;
+ self.nextthink = time + 0.1;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/player.qc

diff --git a/qc/player.qc b/qc/player.qc
new file mode 100644
index 0000000..ec61c1c
--- /dev/null
+++ b/qc/player.qc
@@ -0,0 +1,762 @@
+
+void() bubble_bob;
+
+/*
+==============================================================================
+
+PLAYER
+
+==============================================================================
+*/
+
+$cd id1/models/player_4
+$origin 0 -6 24
+$base base
+$skin skin
+
+//
+// running
+//
+$frame axrun1 axrun2 axrun3 axrun4 axrun5 axrun6
+
+$frame rockrun1 rockrun2 rockrun3 rockrun4 rockrun5 rockrun6
+
+//
+// standing
+//
+$frame stand1 stand2 stand3 stand4 stand5
+
+$frame axstnd1 axstnd2 axstnd3 axstnd4 axstnd5 axstnd6
+$frame axstnd7 axstnd8 axstnd9 axstnd10 axstnd11 axstnd12
+
+
+//
+// pain
+//
+$frame axpain1 axpain2 axpain3 axpain4 axpain5 axpain6
+
+$frame pain1 pain2 pain3 pain4 pain5 pain6
+
+
+//
+// death
+//
+
+$frame axdeth1 axdeth2 axdeth3 axdeth4 axdeth5 axdeth6
+$frame axdeth7 axdeth8 axdeth9
+
+$frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8
+$frame deatha9 deatha10 deatha11
+
+$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
+$frame deathb9
+
+$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
+$frame deathc9 deathc10 deathc11 deathc12 deathc13 deathc14 deathc15
+
+$frame deathd1 deathd2 deathd3 deathd4 deathd5 deathd6 deathd7
+$frame deathd8 deathd9
+
+$frame deathe1 deathe2 deathe3 deathe4 deathe5 deathe6 deathe7
+$frame deathe8 deathe9
+
+//
+// attacks
+//
+$frame nailatt1 nailatt2
+
+$frame light1 light2
+
+$frame rockatt1 rockatt2 rockatt3 rockatt4 rockatt5 rockatt6
+
+$frame shotatt1 shotatt2 shotatt3 shotatt4 shotatt5 shotatt6
+
+$frame axatt1 axatt2 axatt3 axatt4 axatt5 axatt6
+
+$frame axattb1 axattb2 axattb3 axattb4 axattb5 axattb6
+
+$frame axattc1 axattc2 axattc3 axattc4 axattc5 axattc6
+
+$frame axattd1 axattd2 axattd3 axattd4 axattd5 axattd6
+
+
+/*
+==============================================================================
+PLAYER
+==============================================================================
+*/
+
+void() player_run;
+
+void() player_stand1 =[ $axstnd1, player_stand1 ]
+{
+ self.weaponframe=0;
+ if (self.velocity_x || self.velocity_y)
+ {
+ self.walkframe=0;
+ player_run();
+ return;
+ }
+
+ if (self.weapon == IT_AXE)
+ {
+ if (self.walkframe >= 12)
+ self.walkframe = 0;
+ self.frame = $axstnd1 + self.walkframe;
+ }
+ else
+ {
+ if (self.walkframe >= 5)
+ self.walkframe = 0;
+ self.frame = $stand1 + self.walkframe;
+ }
+ self.walkframe = self.walkframe + 1;
+};
+
+void() player_run =[ $rockrun1, player_run ]
+{
+ self.weaponframe=0;
+ if (!self.velocity_x && !self.velocity_y)
+ {
+ self.walkframe=0;
+ player_stand1();
+ return;
+ }
+
+ if (self.weapon == IT_AXE)
+ {
+ if (self.walkframe == 6)
+ self.walkframe = 0;
+ self.frame = $axrun1 + self.walkframe;
+ }
+ else
+ {
+ if (self.walkframe == 6)
+ self.walkframe = 0;
+ self.frame = self.frame + self.walkframe;
+ }
+ self.walkframe = self.walkframe + 1;
+};
+
+
+void() player_shot1 = [$shotatt1, player_shot2 ] {self.weaponframe=1;
+self.effects = self.effects | EF_MUZZLEFLASH;};
+void() player_shot2 = [$shotatt2, player_shot3 ] {self.weaponframe=2;};
+void() player_shot3 = [$shotatt3, player_shot4 ] {self.weaponframe=3;};
+void() player_shot4 = [$shotatt4, player_shot5 ] {self.weaponframe=4;};
+void() player_shot5 = [$shotatt5, player_shot6 ] {self.weaponframe=5;};
+void() player_shot6 = [$shotatt6, player_run ] {self.weaponframe=6;};
+
+void() player_axe1 = [$axatt1, player_axe2 ] {self.weaponframe=1;};
+void() player_axe2 = [$axatt2, player_axe3 ] {self.weaponframe=2;};
+void() player_axe3 = [$axatt3, player_axe4 ] {self.weaponframe=3;W_FireAxe();};
+void() player_axe4 = [$axatt4, player_run ] {self.weaponframe=4;};
+
+void() player_axeb1 = [$axattb1, player_axeb2 ] {self.weaponframe=5;};
+void() player_axeb2 = [$axattb2, player_axeb3 ] {self.weaponframe=6;};
+void() player_axeb3 = [$axattb3, player_axeb4 ] {self.weaponframe=7;W_FireAxe();};
+void() player_axeb4 = [$axattb4, player_run ] {self.weaponframe=8;};
+
+void() player_axec1 = [$axattc1, player_axec2 ] {self.weaponframe=1;};
+void() player_axec2 = [$axattc2, player_axec3 ] {self.weaponframe=2;};
+void() player_axec3 = [$axattc3, player_axec4 ] {self.weaponframe=3;W_FireAxe();};
+void() player_axec4 = [$axattc4, player_run ] {self.weaponframe=4;};
+
+void() player_axed1 = [$axattd1, player_axed2 ] {self.weaponframe=5;};
+void() player_axed2 = [$axattd2, player_axed3 ] {self.weaponframe=6;};
+void() player_axed3 = [$axattd3, player_axed4 ] {self.weaponframe=7;W_FireAxe();};
+void() player_axed4 = [$axattd4, player_run ] {self.weaponframe=8;};
+
+
+//============================================================================
+
+void() player_nail1 =[$nailatt1, player_nail2 ]
+{
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ if (!self.button0)
+ {player_run ();return;}
+ self.weaponframe = self.weaponframe + 1;
+ if (self.weaponframe == 9)
+ self.weaponframe = 1;
+ SuperDamageSound();
+ W_FireSpikes (4);
+ self.attack_finished = time + 0.2;
+};
+void() player_nail2 =[$nailatt2, player_nail1 ]
+{
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ if (!self.button0)
+ {player_run ();return;}
+ self.weaponframe = self.weaponframe + 1;
+ if (self.weaponframe == 9)
+ self.weaponframe = 1;
+ SuperDamageSound();
+ W_FireSpikes (-4);
+ self.attack_finished = time + 0.2;
+};
+
+//============================================================================
+
+void() player_light1 =[$light1, player_light2 ]
+{
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ if (!self.button0)
+ {player_run ();return;}
+ self.weaponframe = self.weaponframe + 1;
+ if (self.weaponframe == 5)
+ self.weaponframe = 1;
+ SuperDamageSound();
+ W_FireLightning();
+ self.attack_finished = time + 0.2;
+};
+void() player_light2 =[$light2, player_light1 ]
+{
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ if (!self.button0)
+ {player_run ();return;}
+ self.weaponframe = self.weaponframe + 1;
+ if (self.weaponframe == 5)
+ self.weaponframe = 1;
+ SuperDamageSound();
+ W_FireLightning();
+ self.attack_finished = time + 0.2;
+};
+
+//============================================================================
+
+
+void() player_rocket1 =[$rockatt1, player_rocket2 ] {self.weaponframe=1;
+self.effects = self.effects | EF_MUZZLEFLASH;};
+void() player_rocket2 =[$rockatt2, player_rocket3 ] {self.weaponframe=2;};
+void() player_rocket3 =[$rockatt3, player_rocket4 ] {self.weaponframe=3;};
+void() player_rocket4 =[$rockatt4, player_rocket5 ] {self.weaponframe=4;};
+void() player_rocket5 =[$rockatt5, player_rocket6 ] {self.weaponframe=5;};
+void() player_rocket6 =[$rockatt6, player_run ] {self.weaponframe=6;};
+void(float num_bubbles) DeathBubbles;
+
+void() PainSound =
+{
+local float rs;
+
+ if (self.health < 0)
+ return;
+
+ if (damage_attacker.classname == "teledeath")
+ {
+ sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
+ return;
+ }
+
+// water pain sounds
+ if (self.watertype == CONTENT_WATER && self.waterlevel == 3)
+ {
+ DeathBubbles(1);
+ if (random() > 0.5)
+ sound (self, CHAN_VOICE, "player/drown1.wav", 1, ATTN_NORM);
+ else
+ sound (self, CHAN_VOICE, "player/drown2.wav", 1, ATTN_NORM);
+ return;
+ }
+
+// slime pain sounds
+ if (self.watertype == CONTENT_SLIME)
+ {
+// FIX ME put in some steam here
+// 1998-08-10 Player gulps bubbles when hurt in slime by Maddes start
+ if (self.waterlevel == 3)
+ DeathBubbles(1);
+// 1998-08-10 Player gulps bubbles when hurt in slime by Maddes end
+ if (random() > 0.5)
+ sound (self, CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM);
+ else
+ sound (self, CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM);
+ return;
+ }
+
+ if (self.watertype == CONTENT_LAVA)
+ {
+ if (random() > 0.5)
+ sound (self, CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM);
+ else
+ sound (self, CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM);
+ return;
+ }
+
+ if (self.pain_finished > time)
+ {
+ self.axhitme = 0;
+ return;
+ }
+ self.pain_finished = time + 0.5;
+
+// don't make multiple pain sounds right after each other
+
+// ax pain sound
+ if (self.axhitme == 1)
+ {
+ self.axhitme = 0;
+ sound (self, CHAN_VOICE, "player/axhit1.wav", 1, ATTN_NORM);
+ return;
+ }
+
+
+ rs = rint((random() * 5) + 1);
+
+ self.noise = "";
+ if (rs == 1)
+ self.noise = "player/pain1.wav";
+ else if (rs == 2)
+ self.noise = "player/pain2.wav";
+ else if (rs == 3)
+ self.noise = "player/pain3.wav";
+ else if (rs == 4)
+ self.noise = "player/pain4.wav";
+ else if (rs == 5)
+ self.noise = "player/pain5.wav";
+ else
+ self.noise = "player/pain6.wav";
+
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ return;
+};
+
+void() player_pain1 = [ $pain1, player_pain2 ] {PainSound();self.weaponframe=0;};
+void() player_pain2 = [ $pain2, player_pain3 ] {};
+void() player_pain3 = [ $pain3, player_pain4 ] {};
+void() player_pain4 = [ $pain4, player_pain5 ] {};
+void() player_pain5 = [ $pain5, player_pain6 ] {};
+void() player_pain6 = [ $pain6, player_run ] {};
+
+void() player_axpain1 = [ $axpain1, player_axpain2 ] {PainSound();self.weaponframe=0;};
+void() player_axpain2 = [ $axpain2, player_axpain3 ] {};
+void() player_axpain3 = [ $axpain3, player_axpain4 ] {};
+void() player_axpain4 = [ $axpain4, player_axpain5 ] {};
+void() player_axpain5 = [ $axpain5, player_axpain6 ] {};
+void() player_axpain6 = [ $axpain6, player_run ] {};
+
+void(entity attacker, float damage) player_pain =
+{
+ if (self.weaponframe)
+ return;
+
+ if (self.invisible_finished > time)
+ return; // eyes don't have pain frames
+
+ if (self.weapon == IT_AXE)
+ player_axpain1 ();
+ else
+ player_pain1 ();
+};
+
+void() player_diea1;
+void() player_dieb1;
+void() player_diec1;
+void() player_died1;
+void() player_diee1;
+void() player_die_ax1;
+
+void() DeathBubblesSpawn =
+{
+local entity bubble;
+ if ((self.owner.waterlevel != 3) && (self.owner.health > 0)) // 1998-08-14 Improved bubble spawn by Maddes
+// 1998-08-14 Bubblespawner remove fix by Perged start
+{
+ remove(self); // remove bubble spawner
+// 1998-08-14 Bubblespawner remove fix by Perged end
+ return;
+} // 1998-08-14 Bubblespawner remove fix by Perged return;
+ bubble = spawn();
+ setmodel (bubble, "progs/s_bubble.spr");
+ setorigin (bubble, self.owner.origin + '0 0 24');
+ bubble.movetype = MOVETYPE_NOCLIP;
+ bubble.solid = SOLID_NOT;
+ bubble.velocity = '0 0 15';
+ bubble.nextthink = time + 0.5;
+ bubble.think = bubble_bob;
+ bubble.classname = "bubble";
+ bubble.frame = 0;
+ bubble.cnt = 0;
+ setsize (bubble, '-8 -8 -8', '8 8 8');
+// 1998-08-14 Improved bubble spawn by Maddes start
+// self.nextthink = time + 0.1;
+ self.nextthink = time + 0.01;
+// 1998-08-14 Improved bubble spawn by Maddes end
+ self.think = DeathBubblesSpawn;
+ self.air_finished = self.air_finished + 1;
+ if (self.air_finished >= self.bubble_count)
+ remove(self);
+};
+
+void(float num_bubbles) DeathBubbles =
+{
+local entity bubble_spawner;
+
+ bubble_spawner = spawn();
+ setorigin (bubble_spawner, self.origin);
+ bubble_spawner.movetype = MOVETYPE_NONE;
+ bubble_spawner.solid = SOLID_NOT;
+// 1998-08-14 Improved bubble spawn by Maddes start
+// bubble_spawner.nextthink = time + 0.1;
+ bubble_spawner.nextthink = time + 0.01;
+// 1998-08-14 Improved bubble spawn by Maddes end
+ bubble_spawner.think = DeathBubblesSpawn;
+ bubble_spawner.air_finished = 0;
+ bubble_spawner.owner = self;
+ bubble_spawner.bubble_count = num_bubbles;
+// return; // 1998-08-14 unnecessary by Maddes
+};
+
+
+void() DeathSound =
+{
+local float rs;
+
+ // water death sounds
+ if (self.waterlevel == 3)
+ {
+ DeathBubbles(20);
+ sound (self, CHAN_VOICE, "player/h2odeath.wav", 1, ATTN_NONE);
+ return;
+ }
+
+ rs = rint ((random() * 4) + 1);
+ if (rs == 1)
+ self.noise = "player/death1.wav";
+ if (rs == 2)
+ self.noise = "player/death2.wav";
+ if (rs == 3)
+ self.noise = "player/death3.wav";
+ if (rs == 4)
+ self.noise = "player/death4.wav";
+ if (rs == 5)
+ self.noise = "player/death5.wav";
+
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NONE);
+ return;
+};
+
+
+void() PlayerDead =
+{
+ self.nextthink = -1;
+// allow respawn after a certain time
+ self.deadflag = DEAD_DEAD;
+};
+
+vector(float dm) VelocityForDamage =
+{
+ local vector v;
+
+ v_x = 100 * crandom();
+ v_y = 100 * crandom();
+ v_z = 200 + 100 * random();
+
+ if (dm > -50)
+ {
+// dprint ("level 1\n");
+ v = v * 0.7;
+ }
+ else if (dm > -200)
+ {
+// dprint ("level 3\n");
+ v = v * 2;
+ }
+ else
+ v = v * 10;
+
+ return v;
+};
+
+void(string gibname, float dm) ThrowGib =
+{
+ local entity new;
+
+ new = spawn();
+ new.origin = self.origin;
+ setmodel (new, gibname);
+ setsize (new, '0 0 0', '0 0 0');
+ new.velocity = VelocityForDamage (dm);
+ new.movetype = MOVETYPE_BOUNCE;
+ new.solid = SOLID_NOT;
+ new.avelocity_x = random()*600;
+ new.avelocity_y = random()*600;
+ new.avelocity_z = random()*600;
+ new.think = SUB_Remove;
+ new.ltime = time;
+ new.nextthink = time + 10 + random()*10;
+ new.frame = 0;
+ new.flags = 0;
+};
+
+void(string gibname, float dm) ThrowHead =
+{
+ setmodel (self, gibname);
+ self.skin = self.skin_head; // dumptruck_ds custom_mdl changes
+ if !(self.skin_head)
+ self.skin_head = 0;
+ // end dumptruck_ds
+ self.frame = 0;
+ self.nextthink = -1;
+ self.movetype = MOVETYPE_BOUNCE;
+ self.takedamage = DAMAGE_NO;
+ self.solid = SOLID_NOT;
+ self.view_ofs = '0 0 8';
+ setsize (self, '-16 -16 0', '16 16 56');
+ self.velocity = VelocityForDamage (dm);
+ self.origin_z = self.origin_z - 24;
+ self.flags = self.flags - (self.flags & FL_ONGROUND);
+ self.avelocity = crandom() * '0 600 0';
+};
+
+
+void() GibPlayer =
+{
+ ThrowHead ("progs/h_player.mdl", self.health);
+ ThrowGib ("progs/gib1.mdl", self.health);
+ ThrowGib ("progs/gib2.mdl", self.health);
+ ThrowGib ("progs/gib3.mdl", self.health);
+
+ self.deadflag = DEAD_DEAD;
+
+ if (damage_attacker.classname == "teledeath")
+ {
+ sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
+ return;
+ }
+
+ if (damage_attacker.classname == "teledeath2")
+ {
+ sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
+ return;
+ }
+
+ if (random() < 0.5)
+ sound (self, CHAN_VOICE, "player/gib.wav", 1, ATTN_NONE);
+ else
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NONE);
+};
+
+void() PlayerDie =
+{
+ local float i;
+
+// 1998-07-23 Palette shift when player dies with quad/pentagram fix by Maddes start
+// self.items = self.items - (self.items & IT_INVISIBILITY);
+ self.items = self.items - (self.items & (IT_INVISIBILITY | IT_INVULNERABILITY | IT_SUIT | IT_QUAD) );
+// 1998-07-23 Palette shift when player dies with quad/pentagram fix by Maddes end self.invisible_finished = 0; // don't die as eyes
+ self.invincible_finished = 0;
+ self.super_damage_finished = 0;
+ self.radsuit_finished = 0;
+ self.effects = 0; // 1998-07-23 Glowing corpse of players which had quad/pentagram until respawn fix by Maddes
+ self.modelindex = modelindex_player; // don't use eyes
+
+ if (deathmatch || coop)
+ DropBackpack();
+
+ self.weaponmodel="";
+ self.view_ofs = '0 0 -8';
+ self.deadflag = DEAD_DYING;
+ self.solid = SOLID_NOT;
+ self.flags = self.flags - (self.flags & FL_ONGROUND);
+ self.movetype = MOVETYPE_TOSS;
+ if (self.velocity_z < 10)
+ self.velocity_z = self.velocity_z + random()*300;
+
+ if (self.health < -40)
+ {
+ GibPlayer ();
+ return;
+ }
+
+ DeathSound();
+
+ self.angles_x = 0;
+ self.angles_z = 0;
+
+ if (self.weapon == IT_AXE)
+ {
+ player_die_ax1 ();
+ return;
+ }
+
+ i = cvar("temp1");
+ if (!i)
+ i = 1 + floor(random()*6);
+
+ if (i == 1)
+ player_diea1();
+ else if (i == 2)
+ player_dieb1();
+ else if (i == 3)
+ player_diec1();
+ else if (i == 4)
+ player_died1();
+ else
+ player_diee1();
+
+};
+
+void() set_suicide_frame =
+{ // used by klill command and diconnect command
+ if (self.model != "progs/player.mdl")
+ return; // allready gibbed
+ self.frame = $deatha11;
+ self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_TOSS;
+ self.deadflag = DEAD_DEAD;
+ self.nextthink = -1;
+};
+
+
+void() player_diea1 = [ $deatha1, player_diea2 ] {};
+void() player_diea2 = [ $deatha2, player_diea3 ] {};
+void() player_diea3 = [ $deatha3, player_diea4 ] {};
+void() player_diea4 = [ $deatha4, player_diea5 ] {};
+void() player_diea5 = [ $deatha5, player_diea6 ] {};
+void() player_diea6 = [ $deatha6, player_diea7 ] {};
+void() player_diea7 = [ $deatha7, player_diea8 ] {};
+void() player_diea8 = [ $deatha8, player_diea9 ] {};
+void() player_diea9 = [ $deatha9, player_diea10 ] {};
+void() player_diea10 = [ $deatha10, player_diea11 ] {};
+void() player_diea11 = [ $deatha11, player_diea11 ] {PlayerDead();};
+
+void() player_dieb1 = [ $deathb1, player_dieb2 ] {};
+void() player_dieb2 = [ $deathb2, player_dieb3 ] {};
+void() player_dieb3 = [ $deathb3, player_dieb4 ] {};
+void() player_dieb4 = [ $deathb4, player_dieb5 ] {};
+void() player_dieb5 = [ $deathb5, player_dieb6 ] {};
+void() player_dieb6 = [ $deathb6, player_dieb7 ] {};
+void() player_dieb7 = [ $deathb7, player_dieb8 ] {};
+void() player_dieb8 = [ $deathb8, player_dieb9 ] {};
+void() player_dieb9 = [ $deathb9, player_dieb9 ] {PlayerDead();};
+
+void() player_diec1 = [ $deathc1, player_diec2 ] {};
+void() player_diec2 = [ $deathc2, player_diec3 ] {};
+void() player_diec3 = [ $deathc3, player_diec4 ] {};
+void() player_diec4 = [ $deathc4, player_diec5 ] {};
+void() player_diec5 = [ $deathc5, player_diec6 ] {};
+void() player_diec6 = [ $deathc6, player_diec7 ] {};
+void() player_diec7 = [ $deathc7, player_diec8 ] {};
+void() player_diec8 = [ $deathc8, player_diec9 ] {};
+void() player_diec9 = [ $deathc9, player_diec10 ] {};
+void() player_diec10 = [ $deathc10, player_diec11 ] {};
+void() player_diec11 = [ $deathc11, player_diec12 ] {};
+void() player_diec12 = [ $deathc12, player_diec13 ] {};
+void() player_diec13 = [ $deathc13, player_diec14 ] {};
+void() player_diec14 = [ $deathc14, player_diec15 ] {};
+void() player_diec15 = [ $deathc15, player_diec15 ] {PlayerDead();};
+
+void() player_died1 = [ $deathd1, player_died2 ] {};
+void() player_died2 = [ $deathd2, player_died3 ] {};
+void() player_died3 = [ $deathd3, player_died4 ] {};
+void() player_died4 = [ $deathd4, player_died5 ] {};
+void() player_died5 = [ $deathd5, player_died6 ] {};
+void() player_died6 = [ $deathd6, player_died7 ] {};
+void() player_died7 = [ $deathd7, player_died8 ] {};
+void() player_died8 = [ $deathd8, player_died9 ] {};
+void() player_died9 = [ $deathd9, player_died9 ] {PlayerDead();};
+
+void() player_diee1 = [ $deathe1, player_diee2 ] {};
+void() player_diee2 = [ $deathe2, player_diee3 ] {};
+void() player_diee3 = [ $deathe3, player_diee4 ] {};
+void() player_diee4 = [ $deathe4, player_diee5 ] {};
+void() player_diee5 = [ $deathe5, player_diee6 ] {};
+void() player_diee6 = [ $deathe6, player_diee7 ] {};
+void() player_diee7 = [ $deathe7, player_diee8 ] {};
+void() player_diee8 = [ $deathe8, player_diee9 ] {};
+void() player_diee9 = [ $deathe9, player_diee9 ] {PlayerDead();};
+
+void() player_die_ax1 = [ $axdeth1, player_die_ax2 ] {};
+void() player_die_ax2 = [ $axdeth2, player_die_ax3 ] {};
+void() player_die_ax3 = [ $axdeth3, player_die_ax4 ] {};
+void() player_die_ax4 = [ $axdeth4, player_die_ax5 ] {};
+void() player_die_ax5 = [ $axdeth5, player_die_ax6 ] {};
+void() player_die_ax6 = [ $axdeth6, player_die_ax7 ] {};
+void() player_die_ax7 = [ $axdeth7, player_die_ax8 ] {};
+void() player_die_ax8 = [ $axdeth8, player_die_ax9 ] {};
+void() player_die_ax9 = [ $axdeth9, player_die_ax9 ] {PlayerDead();};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED player_dead_axe (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/player.mdl","frame":49});
+}
+*/
+void() player_dead_axe =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/player.mdl");
+ setmodel(self, "progs/player.mdl");
+ self.frame = $axdeth9;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-38.72 -5.83 -50.45','28.73 33.85 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+
+};
+
+/*QUAKED player_dead_face_down (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/player.mdl","frame":84});
+}
+*/
+void() player_dead_face_down =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/player.mdl");
+ setmodel(self, "progs/player.mdl");
+ self.frame = $deathc14;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-50.28 -23.55 -49.85','30.66 14.49 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+
+};
+
+/*QUAKED player_dead_on_side (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/player.mdl","frame":102});
+}
+*/
+void() player_dead_on_side =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/player.mdl");
+ setmodel(self, "progs/player.mdl");
+ self.frame = $deathe9;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-38.72 -5.83 -50.45','28.73 33.85 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+
+};
+/* END Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */

Return to the top of this page or return to the overview of this repo.

Diff qc/progs.src

diff --git a/qc/progs.src b/qc/progs.src
new file mode 100644
index 0000000..381f092
--- /dev/null
+++ b/qc/progs.src
@@ -0,0 +1,76 @@
+../progs.dat
+#pragma autoproto
+
+fteopts.qc
+defs_globalvars.qc // globalvars_t
+defs_entvars.qc // entvars_t
+defs_builtins.qc // builtin functions (& overrides)
+defs_misc.qc // additional
+newflags.qc // new spawnflags for all entities
+math.qc // Code by Joshua Skelton
+utility.qc
+
+subs.qc // modified targets, triggers and killtargets
+
+fight.qc
+custom_snd.qc // mapper-settable sound FX for monsters - iw
+custom_mdls.qc // mapper-settable models for monsters - iw
+ai.qc
+combat.qc
+keydata.qc // functions which deal with key item bitflags + names
+items.qc
+weapons.qc
+world.qc
+intermission.qc
+client.qc
+cutscene.qc // Drake version -- dumptruck_ds
+player.qc
+keylock.qc // common code for entities unlockable with keys
+doors.qc
+buttons.qc
+triggers.qc // added trigger_push_custom based on Hipnotic
+plats.qc
+misc.qc
+lights.qc // c0burn's excellent switchable lights
+fog.qc // fog triggers
+cshift.qc // background color shift controller
+
+// monsters
+monsters.qc // modified by dumptruck_ds from Preach's
+ // spawning tutorial | fish count fixed
+monsters/boss.qc
+monsters/boss2.qc // killable Chthon
+monsters/dog.qc
+monsters/demon.qc
+monsters/knight.qc
+monsters/ogre.qc
+monsters/shambler.qc
+monsters/soldier.qc
+monsters/wizard.qc
+monsters/zombie.qc // modified ver. of Ace_Dave's zombies from Rubicon2
+monsters/enforcer.qc // registered
+monsters/fish.qc // registered
+monsters/hknight.qc // registered
+monsters/oldone.qc // registered
+monsters/oldone2.qc // killable Shub
+monsters/shalrath.qc // registered
+
+dtmisc.qc // sound code from Hipnotic & Rubicon Rumble
+ // and misc visual effects
+
+misc_model.qc // Code by Joshua Skelton
+
+hip_count.qc // Hipnotic counter
+hip_part.qc // Hipnotic particlefield and func_togglewall
+hip_rotate.qc // from Hipnotic thanks RennyC
+hip_trig.qc // Hipnotic triggers qc
+doe_elbutton.qc // Rogue elevator code
+doe_ltrail.qc // from DOE lightnin.qc
+doe_plats.qc // Rogue MP newplats.qc
+
+rubicon2.qc // selections from Rubicon2 QC
+dtquake.qc // triggerable earthquake from Zer cutscenes
+func_bob.qc // RennyC's stand alone version based on AD
+func_fall2.qc // Renny's improved version.
+mobot.qc // Using "bot" creation code for func_monster_spawner
+

Return to the top of this page or return to the overview of this repo.

Diff qc/rubicon2.qc

diff --git a/qc/rubicon2.qc b/qc/rubicon2.qc
new file mode 100644
index 0000000..0e9280f
--- /dev/null
+++ b/qc/rubicon2.qc
@@ -0,0 +1,1010 @@
+//selections from Rubicon 2 qc by john fitzgibbons
+//and AD breakable code modified by Qmaster,iw and dumptruck_ds
+float BREAKABLE_NO_MONSTERS = 1;
+float BREAK_EXPLODE = 2;
+float BREAK_CUSTOM = 4;
+float START_OFF = 1;
+float SPARKS_BLUE = 2;
+float SPARKS_PALE = 4;
+
+void() make_breakable_debris;
+
+/*
+===============================================================================
+func_explobox
+===============================================================================
+*/
+
+void () func_explobox_explode_silent =
+{
+ self.takedamage = DAMAGE_NO;
+ self.origin = ((self.absmin + self.absmax) * 0.5);
+ self.classname = "explo_box";
+ T_RadiusDamage (self, self, self.dmg, world);
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+ BecomeExplosion ();
+
+};
+
+void () func_explobox_explode = {
+ // sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
+ func_explobox_explode_silent();
+};
+
+void () func_explobox_die =
+{
+ self.nextthink = 0.2; //for some reason, time + 0.2 doesn't work
+ self.think = func_explobox_explode;
+};
+
+/*QUAKED func_explobox (0 .5 .8) ? START_OFF X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+An exploding brush entity. Works just like misc_explobox.
+
+Keys:
+
+"health" Default 20
+
+"dmg" default 100
+
+*/
+void () func_explobox =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ setmodel (self, self.model);
+ precache_sound ("weapons/r_exp3.wav");
+ if (!self.health)
+ {
+ self.health = 20;
+ }
+ if (!self.dmg)
+ {
+ self.dmg = 100;
+ }
+ self.th_die = func_explobox_die;
+ self.takedamage = DAMAGE_AIM;
+};
+
+
+/*
+===============================================================================
+func_breakable
+===============================================================================
+*/
+
+.string break_template1;
+.string break_template2;
+.string break_template3;
+.string break_template4;
+.string break_template5;
+.float brk_obj_count1;
+.float brk_obj_count2;
+.float brk_obj_count3;
+.float brk_obj_count4;
+.float brk_obj_count5;
+
+
+// template system from Qmaster -- dumptruck_ds
+void() make_breakable_templates_debris = {
+ local float i;
+ local entity new;
+
+ i = 0;
+ if (self.break_template1 != "") {
+ while (i < self.brk_obj_count1) {
+ new = spawn();
+ new.model = self.break_template1;
+ new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
+ new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
+ new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
+ setmodel (new, new.model); //dumptruck_ds
+ setsize (new, '0 0 0', '0 0 0');
+ new.velocity = VelocityForDamage (self.health*2);
+ new.movetype = MOVETYPE_BOUNCE;
+ new.solid = SOLID_NOT;
+ new.avelocity_x = random()*600;
+ new.avelocity_y = random()*600;
+ new.avelocity_z = random()*600;
+ new.think = SUB_Remove;
+ new.ltime = time;
+ new.nextthink = time + 10 + random()*10;
+ new.flags = 0;
+ i++;
+ }
+ }
+
+ i = 0;
+ if (self.break_template2 != "") {
+ while (i < self.brk_obj_count2) {
+ new = spawn();
+ new.model = self.break_template2;
+ new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
+ new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
+ new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
+ setmodel (new, new.model); //dumptruck_ds
+ setsize (new, '0 0 0', '0 0 0');
+ new.velocity = VelocityForDamage (self.health*2);
+ new.movetype = MOVETYPE_BOUNCE;
+ new.solid = SOLID_NOT;
+ new.avelocity_x = random()*600;
+ new.avelocity_y = random()*600;
+ new.avelocity_z = random()*600;
+ new.think = SUB_Remove;
+ new.ltime = time;
+ new.nextthink = time + 10 + random()*10;
+ new.flags = 0;
+ i++;
+ }
+ }
+
+ i = 0;
+ if (self.break_template3 != "") {
+ while (i < self.brk_obj_count3) {
+ new = spawn();
+ new.model = self.break_template3;
+ new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
+ new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
+ new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
+ setmodel (new, new.model); //dumptruck_ds
+ setsize (new, '0 0 0', '0 0 0');
+ new.velocity = VelocityForDamage (self.health*2);
+ new.movetype = MOVETYPE_BOUNCE;
+ new.solid = SOLID_NOT;
+ new.avelocity_x = random()*600;
+ new.avelocity_y = random()*600;
+ new.avelocity_z = random()*600;
+ new.think = SUB_Remove;
+ new.ltime = time;
+ new.nextthink = time + 10 + random()*10;
+ new.flags = 0;
+ i++;
+ }
+ }
+
+ i = 0;
+ if (self.break_template4 != "") {
+ while (i < self.brk_obj_count4) {
+ new = spawn();
+ new.model = self.break_template4;
+ new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
+ new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
+ new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
+ setmodel (new, new.model); //dumptruck_ds
+ setsize (new, '0 0 0', '0 0 0');
+ new.velocity = VelocityForDamage (self.health*2);
+ new.movetype = MOVETYPE_BOUNCE;
+ new.solid = SOLID_NOT;
+ new.avelocity_x = random()*600;
+ new.avelocity_y = random()*600;
+ new.avelocity_z = random()*600;
+ new.think = SUB_Remove;
+ new.ltime = time;
+ new.nextthink = time + 10 + random()*10;
+ new.flags = 0;
+ i++;
+ }
+ }
+
+ i = 0;
+ if (self.break_template5 != "") {
+ while (i < self.brk_obj_count5) {
+ new = spawn();
+ new.model = self.break_template5;
+ new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
+ new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
+ new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
+ setmodel (new, new.model); //dumptruck_ds
+ setsize (new, '0 0 0', '0 0 0');
+ new.velocity = VelocityForDamage (self.health*2);
+ new.movetype = MOVETYPE_BOUNCE;
+ new.solid = SOLID_NOT;
+ new.avelocity_x = random()*600;
+ new.avelocity_y = random()*600;
+ new.avelocity_z = random()*600;
+ new.think = SUB_Remove;
+ new.ltime = time;
+ new.nextthink = time + 10 + random()*10;
+ new.flags = 0;
+ i++;
+ }
+ }
+};
+
+
+//Below this is from Rubicon2 -- dumptruck_ds
+
+void() make_breakable_debris = {
+ local float i;
+ i = 0;
+ while (i < self.cnt)
+ {
+ local entity new;
+
+ new = spawn();
+ new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
+ new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
+ new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
+ // setmodel (new, "progs/debris.mdl"); this was originally just an mdl from Rubicon2, now you set custom model via spawnflag or use the builtin from Rubicon2 -- dumptruck_ds
+ setmodel (new, self.mdl_debris); //dumptruck_ds
+ setsize (new, '0 0 0', '0 0 0');
+ new.velocity = VelocityForDamage (self.health*2);
+ new.movetype = MOVETYPE_BOUNCE;
+ new.solid = SOLID_NOT;
+ new.avelocity_x = random()*600;
+ new.avelocity_y = random()*600;
+ new.avelocity_z = random()*600;
+ new.think = SUB_Remove;
+ new.ltime = time;
+ new.nextthink = time + 10 + random()*10;
+ new.flags = 0;
+
+ // randomly choose size
+ if (random() > 0.333)
+ new.frame = 1; //larger
+ else
+ new.frame = 2; //smaller
+
+ // choose skin based on "style" key
+ if (self.style == 1)
+ new.skin = 1;
+ if (self.style == 2)
+ new.skin = 2;
+ if (self.style == 3) // new debris skins start here - dumptruck_ds
+ new.skin = 3;
+ if (self.style == 4)
+ new.skin = 4;
+ if (self.style == 5)
+ new.skin = 5;
+ if (self.style == 6)
+ new.skin = 6;
+ if (self.style == 7)
+ new.skin = 7;
+ if (self.style == 8)
+ new.skin = 8;
+ if (self.style == 9)
+ new.skin = 9;
+ if (self.style == 10)
+ new.skin = 10;
+ if (self.style == 11)
+ new.skin = 11;
+ if (self.style == 12)
+ new.skin = 12;
+ if (self.style == 13)
+ new.skin = 13;
+ if (self.style == 14)
+ new.skin = 14;
+ if (self.style == 15)
+ new.skin = 15;
+ if (self.style == 16)
+ new.skin = 16;
+ if (self.style == 17)
+ new.skin = 17;
+ if (self.style == 18)
+ new.skin = 18;
+ if (self.style == 19)
+ new.skin = 19;
+ if (self.style == 20)
+ new.skin = 20;
+ if (self.style == 21)
+ new.skin = 21;
+ if (self.style == 22)
+ new.skin = 22;
+ if (self.style == 23)
+ new.skin = 23;
+ if (self.style == 24)
+ new.skin = 24;
+ if (self.style == 25)
+ new.skin = 25;
+ if (self.style == 26)
+ new.skin = 26;
+ if (self.style == 27)
+ new.skin = 27;
+ if (self.style == 28)
+ new.skin = 28;
+ if (self.style == 29)
+ new.skin = 29;
+ if (self.style == 30)
+ new.skin = 30;
+ if (self.style == 31)// new debris skins end here - dumptruck_ds
+ new.skin = 31;
+
+ i = i + 1;
+ }
+};
+
+void () func_breakable_die = {
+ //dumptruck_ds -- set the spawnflag for cosmetic explosion effect; use "dmg" value to hurt the player
+ {
+ local entity ent; //thanks to Qmaster!!! He helped me sort out noise1 playing from 0 0 0 with this temp entity - dumptruck_ds
+
+ ent = spawn();
+ ent.origin = ((self.absmin + self.absmax) * 0.5);
+ setsize (ent, '0 0 0', '0 0 0');
+ ent.solid = SOLID_NOT;
+ ent.think = SUB_Remove;
+ // ent.ltime = time;
+ ent.nextthink = time + 60;
+
+ sound(ent, CHAN_AUTO, self.noise1, 1, ATTN_NORM);
+ // remove (self);
+ }
+
+ // this is to ensure that any debris from another func_breakable
+ // which is resting on top of this func_breakable is not left
+ // floating in mid-air after this entity is removed -- iw
+ SUB_DislodgeRestingEntities ();
+
+ if (self.spawnflags & BREAK_EXPLODE) {
+ if (self.spawnflags & BREAK_CUSTOM) {
+ make_breakable_templates_debris ();
+ } else {
+ make_breakable_debris ();
+ }
+ func_explobox_explode_silent(); // to let us use noise2
+ // sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); this is broken as of 1.1.0 no custom explosion sound for now -- dumptruck_ds
+ remove (self);
+ } else {
+ self.origin = ((self.absmin + self.absmax) * 0.5);
+ setorigin (self, self.origin);
+ DropStuff();
+ if (self.spawnflags & BREAK_CUSTOM) {
+ if (self.switchshadstyle) lightstyle(self.switchshadstyle, "m");
+ make_breakable_templates_debris ();
+ remove (self);
+ } else {
+ if (self.switchshadstyle) lightstyle(self.switchshadstyle, "m");
+ make_breakable_debris ();
+ remove (self);
+ }
+ }
+};
+
+void () func_breakable_killed =
+{
+ activator = damage_attacker;
+ SUB_UseTargets ();
+ func_breakable_die ();
+};
+
+void () func_breakable_use =
+{
+ activator = other;
+ SUB_UseTargets ();
+ func_breakable_die ();
+};
+
+/*QUAKED func_breakable (0 .5 .8) ? NO_MONSTERS X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+"Breakable - See manual for full details
+
+Defaults to built-in .mdl file with 32 styles, cnt is number of pieces of debris to spawn (built-in only)
+Or use spawnflag 4 and break_template1-4 to set path of custom .mdl or .bsp models.
+brk_object_count1-4 sets the number of pieces of each break_template when using custom .mdl or bsp models.
+If noise1 is not set it will default to various sounds in sounds/break folder
+Use spawnflag 2 for an explosion, dmg is amount of damage inflicted"
+
+spawnflags(flags)
+1 : "No Monster Damage" : 0 : "Only the player can break"
+2 : "Explosion" : 0 : "Produces explosion effect and sound"
+4 : "Use custom mdls or bsp models" : 0 : "Uses models specified in break_template1, 2, etc"
+
+style(choices) : "Built-in debris style" : 0
+0 : "Green Metal (default)"
+1 : "Red Metal"
+2 : "Concrete"
+3 : "Pine wood"
+4 : "Brown wood"
+5 : "Red wood"
+6 : "Stained Glass Yellow Flames"
+7 : "Stained Glass Red Rays"
+8 : "Stained Glass Yellow Dragon"
+9 : "Stained Glass Blue Dragon"
+10 : "Stained Glass Red Dragon"
+11 : "Light Copper"
+12 : "Dark Copper"
+13 : "Tan Bricks Large"
+14 : "Brown Bricks Large"
+15 : "Green Bricks Large"
+16 : "Generic Light Brown"
+17 : "Red Brown Computer"
+18 : "Grey Black Computer"
+19 : "Blue Green Metal"
+20 : "Blue Green Runic Wall"
+21 : "Brown Metal"
+22 : "Dark Brown Metal"
+23 : "Medium Brown Metal"
+24 : "Blue Metal"
+25 : "Green Stonework"
+26 : "Blue Stonework"
+27 : "Brown Bricks"
+28 : "Tan Blue Bricks"
+29 : "Red Bricks"
+30 : "Blue Bricks"
+31 : "Metal Rivets"
+
+noise1(string) : "Break noise (overrides default sounds)"
+cnt(integer) : "Number of pieces of debris to spawn" : 5
+health(integer) : "Health of breakable" : 20
+dmg(integer) : "Amount of Explosive Damage" : 20
+break_template1(string) : "Template 1 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
+break_template2(string) : "Template 2 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
+break_template3(string) : "Template 3 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
+break_template4(string) : "Template 4 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
+break_template5(string) : "Template 5 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
+brk_obj_count1(integer) : "Template 1 spawn count"
+brk_obj_count2(integer) : "Template 2 spawn count"
+brk_obj_count3(integer) : "Template 3 spawn count"
+brk_obj_count4(integer) : "Template 4 spawn count"
+brk_obj_count5(integer) : "Template 5 spawn count"
+*/
+
+void() break_template_setup = {
+ if (self.break_template1 != "") precache_model(self.break_template1);
+ if (self.break_template2 != "") precache_model(self.break_template2);
+ if (self.break_template3 != "") precache_model(self.break_template3);
+ if (self.break_template4 != "") precache_model(self.break_template4);
+ if (self.break_template5 != "") precache_model(self.break_template5);
+};
+
+void () func_breakable = {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ break_template_setup();
+
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ setmodel (self, self.model);
+ self.mdl_debris = "progs/debris.mdl";
+ precache_model (self.mdl_debris);
+ precache_sound ("blob/hit1.wav");
+
+ if (self.noise1 != "") precache_sound(self.noise1);
+// adding new default sounds for "simple" breakables in 1.2.0 -- dumptruck_ds
+// here's genreic metal breaking
+ if (self.style == 0 || self.style == 11 || self.style == 12 || self.style == 17 || self.style == 18 || self.style == 19
+ || self.style == 24 || self.style == 31)
+ if !(self.noise1)
+ {
+ precache_sound("break/metal2.wav");
+ self.noise1 = "break/metal2.wav";
+ }
+ if (self.style == 3 || self.style == 4 || self.style == 5)
+ if !(self.noise1)
+ {
+ precache_sound("break/wood1.wav");
+ precache_sound("break/wood2.wav");
+ if (random() > 0.6) // wood only randomized
+ self.noise1 = "break/wood1.wav";
+ else
+ self.noise1 = "break/wood2.wav";
+ }
+ // glass sounds -- this is more of a shattering sound anyway
+ if (self.style == 6 || self.style == 7 || self.style == 8 || self.style == 9 || self.style == 10)
+ if !(self.noise1)
+ {
+ precache_sound("break/metal1.wav");
+ self.noise1 = "break/metal1.wav";
+ }
+ if (self.style == 1 || self.style == 2 || self.style == 13 || self.style == 14
+ || self.style == 15 || self.style == 16 || self.style == 20 || self.style == 21
+ || self.style == 22 || self.style == 23)
+ if !(self.noise1)
+ {
+ precache_sound("break/stones1.wav");
+ precache_sound("break/bricks1.wav");
+ if (random() > 0.6) // wood only randomized
+ self.noise1 = "break/bricks1.wav";
+ else
+ self.noise1 = "break/stones1.wav";
+ }
+ if (self.style == 25 || self.style == 26 || self.style == 27 || self.style == 28 || self.style == 29 || self.style == 30)
+ if !(self.noise1)
+ {
+ precache_sound("break/stones1.wav");
+ precache_sound("break/bricks1.wav");
+ if (random() > 0.6) // wood only randomized
+ self.noise1 = "break/stones1.wav";
+ else
+ self.noise1 = "break/bricks1.wav";
+ }
+ // else
+ // (self.noise1 = "blob/hit1.wav");
+
+ if (!self.health)
+ self.health = 20;
+ if (!self.cnt)
+ self.cnt = 5; // was 6 dumptruck_ds
+
+ if (self.targetname != "")
+ {
+ self.use = func_breakable_use;
+ }
+ else
+ {
+ self.takedamage = DAMAGE_YES;
+ self.th_die = func_breakable_killed;
+ }
+
+ if (self.switchshadstyle) lightstyle(self.switchshadstyle, "a");
+};
+
+/*
+===============================================================================
+trigger_ladder
+===============================================================================
+*/
+
+void() ladder_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ // prevent the player "sticking" to a ladder if they are standing on
+ // the platform at the top of the ladder with the bottom of their
+ // bounding box flush with the top of the trigger -- iw
+ if (other.absmin_z + 1 >= self.absmax_z - 1)
+ return;
+
+ // if the trigger has an angles field, check player's facing direction
+ if (self.movedir != '0 0 0')
+ {
+ makevectors (other.angles);
+ if (v_forward * self.movedir < 0)
+ return; // not facing the right way
+ }
+ other.onladder = 1;
+}
+
+/*QUAKED trigger_ladder (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+invisible ladder entity. when player is touching this entity, he can climb by pushing 'jump'
+
+Keys:
+
+"angle" the direction player must be facing to climb ladder
+*/
+void() trigger_ladder =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ // ignore an "up" or "down" angle (doesn't make sense for a ladder)
+ if (self.angles_y == -1 || self.angles_y == -2)
+ {
+ dprint ("WARNING: trigger_ladder ignored bad 'angle' value: ");
+ dprint (ftos (self.angles_y));
+ dprint ("\n");
+
+ self.angles_y = 0;
+ }
+
+ InitTrigger ();
+ self.touch = ladder_touch;
+
+ SUB_CheckWaiting();
+};
+/*
+===============================================================================
+func_laser
+===============================================================================
+*/
+float LASER_SOLID = 2;
+.string message2;
+.float alpha;
+
+
+void() laser_helper_think =
+{
+ if (!self.owner || self.owner.classname != "func_laser")
+ {
+ remove(self);
+ return;
+ }
+
+
+ if (!(self.owner.spawnflags & START_OFF))
+ self.owner.alpha = self.alpha * 0.8 + self.alpha * random() * 0.4;
+
+ self.nextthink = time + 0.05;
+};
+
+void() func_laser_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (other.movetype == MOVETYPE_NOCLIP)
+ return;
+
+ if (other.takedamage && self.attack_finished < time)
+ {
+ T_Damage (other, self, self, self.dmg);
+ self.attack_finished = time + 0.1;
+ }
+
+};
+
+void () func_laser_use =
+{
+ if (self.spawnflags & START_OFF)
+ {
+ setorigin(self, '0 0 0');
+ self.spawnflags = self.spawnflags - START_OFF;
+
+ // changed for progs_dump: the laser sound is now emitted from
+ // the func_laser itself instead of from the activator -- iw
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+
+ if (activator.classname == "player" && self.message != "")
+ {
+ centerprint (activator, self.message);
+ }
+ }
+ else
+ {
+ // changed for progs_dump: the laser sound is now emitted from
+ // the func_laser itself instead of from the activator -- iw
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+
+ setorigin(self, '0 0 9000');
+ self.spawnflags = self.spawnflags + START_OFF;
+
+ if (activator.classname == "player" && self.message2 != "")
+ {
+ centerprint (activator, self.message2);
+ }
+ }
+};
+
+/*QUAKED func_laser (0 .5 .8) ? START_OFF LASER_SOLID X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+A toggleable laser, hurts to touch, can be used to block players
+
+START_OFF: Laser starts off.
+
+LASER_SOLID: Laser blocks movement while turned on.
+
+Keys:
+
+"dmg" damage to do on touch. default 1
+
+"alpha" approximate alpha you want the laser drawn at. default 0.5. alpha will vary by 20% of this value.
+
+"message" message to display when activated
+
+"message2" message to display when deactivated
+
+*/
+void () func_laser =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ local entity helper;
+
+ setmodel (self, self.model);
+
+ precache_sound ("buttons/switch02.wav");
+ precache_sound ("buttons/switch04.wav");
+
+ if (self.spawnflags & LASER_SOLID)
+ {
+ self.solid = SOLID_BSP; //so you can shoot between lasers in a single bmodel
+ self.movetype = MOVETYPE_PUSH; //required becuase of SOLID_BSP
+ }
+ else
+ {
+ self.solid = SOLID_TRIGGER;
+ self.movetype = MOVETYPE_NONE;
+ }
+
+ if (!self.alpha)
+ self.alpha = 0.5;
+
+ if (!self.dmg)
+ self.dmg = 1;
+
+ self.use = func_laser_use;
+ self.touch = func_laser_touch;
+
+ if (self.spawnflags & START_OFF)
+ setorigin(self, '0 0 9000');
+ {
+ if (self.noise != "") precache_sound(self.noise);
+
+ else
+ (self.noise = "buttons/switch02.wav");
+ }
+ {
+ if (self.noise1 != "") precache_sound(self.noise1);
+
+ else
+ (self.noise1 = "buttons/switch04.wav");
+ }
+
+
+
+
+ //spawn a second entity to handle alpha changes, since MOVETYPE_PUSH doesn't support think functions
+ helper = spawn();
+ helper.alpha = self.alpha;
+ helper.owner = self;
+ helper.nextthink = 0.05;
+ helper.think = laser_helper_think;
+};
+
+/*
+===============================================================================
+misc_sparks
+===============================================================================
+*/
+
+void() sparks_fade1 = [0, sparks_fade2] {self.alpha = 0.8; self.nextthink = time + 0.05;};
+void() sparks_fade2 = [0, sparks_fade3] {self.alpha = 0.6; self.nextthink = time + 0.05;};
+void() sparks_fade3 = [0, sparks_fade4] {self.alpha = 0.4; self.nextthink = time + 0.05;};
+void() sparks_fade4 = [0, SUB_Remove] {self.alpha = 0.2; self.nextthink = time + 0.05;};
+
+void() sparks_use =
+{
+ if (self.spawnflags & START_OFF)
+ self.spawnflags = self.spawnflags - START_OFF;
+ else
+ self.spawnflags = self.spawnflags + START_OFF;
+};
+
+void() make_sparks;
+
+void() spark_turnofflight =
+{
+ SUB_UseTargets();
+ self.think = make_sparks;
+ self.nextthink = time + (random() + 0.5)*self.wait - 0.15;
+}
+
+void() make_sparks =
+{
+
+ if (self.spawnflags & START_OFF)
+ {
+ self.nextthink = time + 0.1;
+ self.think = make_sparks;
+ }
+ else
+ {
+ local float i;
+ i = -0.25*self.cnt + random()*0.5*self.cnt;
+ while (i < self.cnt)
+ {
+
+ local entity spark;
+ spark = spawn();
+ spark.owner = self;
+ setmodel (spark, "progs/spark.mdl");
+ setorigin (spark, self.origin);
+ spark.movetype = MOVETYPE_BOUNCE;
+ spark.solid = SOLID_TRIGGER;
+ spark.gravity = 0.3;
+ spark.velocity_x = -40 + random() * 80;
+ spark.velocity_y = -40 + random() * 80;
+ spark.velocity_z = -40 + random() * 80;
+ spark.avelocity = '3000 3000 3000';
+ spark.nextthink = time + 0.5 + 1.5*random();
+ spark.think = sparks_fade1;
+ spark.classname = "spark";
+
+ if (random() < 0.33)
+ spark.skin = 0;
+ else if (random() < 0.5)
+ spark.skin = 1;
+ else
+ spark.skin = 2;
+
+ if (self.spawnflags & SPARKS_PALE)
+ spark.skin = spark.skin + 6;
+ else if (self.spawnflags & SPARKS_BLUE)
+ spark.skin = spark.skin + 3;
+
+ setsize (spark, '0 0 0', '0 0 0');
+ i = i + 1;
+ }
+ if (self.sounds == 1)
+ {
+ if (self.noise != "")
+ {
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_STATIC);
+ }
+ else
+ sound (self, CHAN_AUTO, "enforcer/enfstop.wav", 1, ATTN_STATIC);
+ }
+ SUB_UseTargets();
+ self.nextthink = time + 0.1 + random() * 0.1;
+ self.think = spark_turnofflight;
+
+ }
+
+};
+
+/*QUAKED misc_sparks (0 .5 .8) (-8 -8 -8) (8 8 8) START_OFF SPARKS_BLUE SPARKS_PALE X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Produces a burst of yellow sparks at random intervals. If targeted, it will toggle between on or off. If it targets a light, that light will flash allong with each burst of sparks. Note: targeted lights should be set to START_OFF.
+
+SPARKS_BLUE: sparks are blue in color
+
+SPARKS_PALE: sparks are pale yellow in color
+
+Keys:
+
+"wait" is the average delay between bursts (variance is 1/2 wait). Default is 2.
+
+"cnt" is the average number of sparks in a burst (variance is 1/4 cnt). Default is 15.
+
+"sounds"
+0) no sound
+1) sparks
+*/
+void() misc_sparks =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/spark.mdl");
+ if (!self.noise)
+ precache_sound ("dump/spark.wav");
+ else
+ precache_sound (self.noise);
+
+ if (!self.movedir)
+ self.movedir = '0 0 -30';
+ if (!self.wait)
+ self.wait = 2;
+ if (!self.cnt)
+ self.cnt = 15;
+
+ self.use = sparks_use;
+ self.nextthink = time + random()*0.1;
+ self.think = make_sparks;
+};
+
+/*
+===============================================================================
+misc_particles a.k.a. misc_splash
+===============================================================================
+*/
+void() splash_use =
+{
+ if (self.spawnflags & START_OFF)
+ self.spawnflags = self.spawnflags - START_OFF;
+ else
+ self.spawnflags = self.spawnflags + START_OFF;
+};
+
+void() splash_think =
+{
+ if (self.spawnflags & START_OFF)
+ {
+ self.nextthink = time + 0.1;
+ self.think = splash_think;
+ }
+ else
+ {
+ local vector vec;
+ local float variance;
+ variance = vlen(self.movedir) / 2;
+ vec_x = self.movedir_x - variance + random() * variance * 2;
+ vec_y = self.movedir_y - variance + random() * variance * 2;
+ vec_z = self.movedir_z - variance + random() * variance * 2;
+ particle (self.origin, vec, self.color, self.volume);
+ self.nextthink = time + self.wait;
+ }
+};
+
+//
+//misc_particles
+//
+// renamed from misc_splash (Rubcion 2) --dumptruck_ds
+//
+
+/*QUAKED misc_particles (0 .5 .8) (-8 -8 -8) (8 8 8) START_OFF X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Produces a continuous particle splash for waterfalls and other effects
+
+"color" color of particles. 0 through 15, corresponds to a row of the quake palette. (default 0)
+
+"movedir" average movement vector of particles (default 0 0 4)
+
+"wait" time between particle generation cycles. (default 0.1)
+
+"volume" density of particles. (default 10)
+
+
+*/
+void() misc_particles =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.wait)
+ self.wait = 0.1;
+ if (!self.movedir)
+ self.movedir = '0 0 4';
+ if (!self.volume)
+ self.volume = 10;
+ self.color = self.color * 16;
+
+ self.use = splash_use;
+ self.nextthink = time + self.wait;
+ self.think = splash_think;
+};
+
+//##########################################
+//#### Particle Sprayer ####
+//##########################################
+
+//this is from Custents not Rubicon2 -- dumptruck_ds
+//renamed from func to misc
+
+/*QUAKED misc_particlespray (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Shoots particles either when triggered, or contiuously when not triggered by anything.
+"color" is the palette color of the particles
+
+"count" is the number of particles to make each time
+
+"delay" is the delay between each triggering
+
+"noise" is the name of the wav file to play when triggered
+
+"movedir" is the vector distance that the particles will travel before disappearing. (in x y z)
+
+"duration" is the amount of time that the it will continue to release particles so that it can release a long stream of particles with only one triggering.
+*/
+
+.float endtime;
+.float duration;
+
+void() partspray_think =
+{
+ particle (self.origin, self.movedir, self.color, self.count);
+
+ if(!self.targetname || self.endtime > time)
+ self.nextthink = time + self.delay;
+
+ if(self.noise != "")
+ sound(self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ else
+ sound(self, CHAN_AUTO, "misc/null.wav", 1, ATTN_NORM);
+
+};
+
+void() partspray_use =
+{
+ self.endtime = time + self.duration;
+ partspray_think();
+};
+
+void() misc_particlespray =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if ( !self.color )
+ self.color = 47;
+ if ( self.count <= 0 )
+ self.count = 15;
+ if(self.delay <= 0)
+ self.delay = 0.1;
+ self.classname = "particlespray";
+ if (self.noise != "")
+ precache_sound(self.noise);
+ precache_sound ("misc/null.wav");
+ self.think = partspray_think;
+ if(!self.targetname)
+ self.nextthink = time + 0.1 + self.delay;
+ else
+ self.use = partspray_use;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/subs.qc

diff --git a/qc/subs.qc b/qc/subs.qc
new file mode 100644
index 0000000..71c715a
--- /dev/null
+++ b/qc/subs.qc
@@ -0,0 +1,741 @@
+
+
+void() SUB_Null = {};
+
+void(entity attacker, float damage) SUB_NullPain = {};
+
+void() SUB_Remove = {remove(self);};
+
+
+/*
+QuakeEd only writes a single float for angles (bad idea), so up and down are
+just constant angles.
+*/
+void() SetMovedir =
+{
+ if (self.angles == '0 -1 0')
+ self.movedir = '0 0 1';
+ else if (self.angles == '0 -2 0')
+ self.movedir = '0 0 -1';
+ else
+ {
+ makevectors (self.angles);
+ self.movedir = v_forward;
+ }
+
+ self.angles = '0 0 0';
+};
+
+
+/*
+=============
+SUB_CallAsSelf
+
+wrap the self/oself shuffle for code cleanliness elsewhere
+===============
+*/
+void(void() fun, entity newself) SUB_CallAsSelf =
+{
+ local entity oself;
+
+ oself = self;
+ self = newself;
+ fun();
+ self = oself;
+}
+
+/*
+================
+InitTrigger
+================
+*/
+void() InitTrigger =
+{
+// trigger angles are used for one-way touches. An angle of 0 is assumed
+// to mean no restrictions, so use a yaw of 360 instead.
+ if (self.angles != '0 0 0')
+ SetMovedir ();
+ self.solid = SOLID_TRIGGER;
+ setmodel (self, self.model); // set size and link into world
+ self.movetype = MOVETYPE_NONE;
+ self.modelindex = 0;
+ self.model = "";
+};
+
+// Drake -- dumptruck_ds
+// PM: The point trigger version of InitTrigger.
+void() InitPointTrigger =
+{
+ local vector v1, v2;
+
+ v1 = self.origin;
+ v2 = v1 + self.mangle;
+ self.model = "";
+ setorigin (self, '0 0 0');
+ InitTrigger (); // Calls 'setmodel', so do first.
+ setsize (self, v1, v2); // Calling 'setmodel' resets entity size.
+};
+
+/*
+=============
+SUB_CalcMove
+
+calculate self.velocity and self.nextthink to reach dest from
+self.origin traveling at speed
+===============
+*/
+void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt =
+{
+ local entity stemp;
+ stemp = self;
+ self = ent;
+
+ SUB_CalcMove (tdest, tspeed, func);
+ self = stemp;
+};
+
+void(vector tdest, float tspeed, void() func) SUB_CalcMove =
+{
+ local vector vdestdelta;
+ local float len, traveltime, localtime;
+
+ if (!tspeed)
+ objerror("No speed is defined!");
+
+ if (self.movetype == MOVETYPE_PUSH) localtime = self.ltime;
+ else localtime = time;
+
+ self.think1 = func;
+ self.finaldest = tdest;
+ self.think = SUB_CalcMoveDone;
+
+ if (tdest == self.origin)
+ {
+ self.velocity = '0 0 0';
+ self.nextthink = localtime + 0.1;
+ return;
+ }
+
+// set destdelta to the vector needed to move
+ vdestdelta = tdest - self.origin;
+
+// calculate length of vector
+ len = vlen (vdestdelta);
+
+// divide by speed to get time to reach dest
+ traveltime = len / tspeed;
+
+ if (traveltime < 0.1)
+ {
+ self.velocity = '0 0 0';
+ self.nextthink = localtime + 0.1;
+ return;
+ }
+
+// set nextthink to trigger a think when dest is reached
+ self.nextthink = localtime + traveltime;
+
+// scale the destdelta vector by the time spent traveling to get velocity
+ self.velocity = vdestdelta * (1/traveltime); // qcc won't take vec/float
+};
+
+/*
+============
+After moving, set origin to exact final destination
+============
+*/
+void() SUB_CalcMoveDone =
+{
+ setorigin(self, self.finaldest);
+ self.velocity = '0 0 0';
+ self.nextthink = -1;
+ if (self.think1)
+ self.think1();
+};
+
+/*
+=============
+SUB_CalcAngleMove
+
+calculate self.avelocity and self.nextthink to reach destangle from
+self.angles rotating
+
+The calling function should make sure self.think is valid
+===============
+*/
+void(entity ent, vector destangle, float tspeed, void() func) SUB_CalcAngleMoveEnt =
+{
+local entity stemp;
+ stemp = self;
+ self = ent;
+ SUB_CalcAngleMove (destangle, tspeed, func);
+ self = stemp;
+};
+
+void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove =
+{
+local vector destdelta;
+local float len, traveltime;
+
+ if (!tspeed)
+ objerror("No speed is defined!");
+
+// set destdelta to the vector needed to move
+ destdelta = destangle - self.angles;
+
+// calculate length of vector
+ len = vlen (destdelta);
+
+// divide by speed to get time to reach dest
+ traveltime = len / tspeed;
+
+// set nextthink to trigger a think when dest is reached
+ self.nextthink = self.ltime + traveltime;
+
+// scale the destdelta vector by the time spent traveling to get velocity
+ self.avelocity = destdelta * (1 / traveltime);
+
+ self.think1 = func;
+ self.finalangle = destangle;
+ self.think = SUB_CalcAngleMoveDone;
+};
+
+/*
+============
+After rotating, set angle to exact final angle
+============
+*/
+void() SUB_CalcAngleMoveDone =
+{
+ self.angles = self.finalangle;
+ self.avelocity = '0 0 0';
+ self.nextthink = -1;
+ if (self.think1)
+ self.think1();
+};
+
+/*
+=============
+SUB_CalcAngleMoveController
+
+Same as SUB_CalcAngleMove, but using a separate controller entity
+to not lose track of current think functions.
+
+===============
+*/
+void() SUB_CalcAngleMoveDoneController;
+
+void(vector destangle, float tspeed, void() func, entity controller) SUB_CalcAngleMoveController =
+{
+ local vector destdelta;
+ local float len, traveltime;
+
+ if (!tspeed)
+ objerror("No speed is defined!");
+
+ // set destdelta to the vector needed to move
+
+ destdelta = normalizeAngles180(destangle - self.angles);
+ /*dprint3("destangle: ", vtos(destangle), "\n");
+ dprint3("self.angles: ", vtos( self.angles), "\n");
+ dprint3("destdelta: ", vtos(destdelta), "\n");
+ */
+
+ // calculate length of vector
+ len = vlen (destdelta);
+
+ // divide by speed to get time to reach dest
+ traveltime = len / tspeed;
+
+ // set nextthink to trigger a think when dest is reached
+ controller.nextthink = time + traveltime;
+
+ // scale the destdelta vector by the time spent traveling to get velocity
+ self.avelocity = destdelta * (1 / traveltime);
+
+ // Makes sure controller.owner points to self so it can be referenced later in the think function
+ controller.owner = self;
+ controller.think1 = func;
+ controller.finalangle = destangle;
+ controller.think = SUB_CalcAngleMoveDoneController;
+};
+
+/*
+============
+After rotating, set angle to exact final angle
+============
+*/
+void() SUB_CalcAngleMoveDoneController =
+{
+ self.owner.angles = self.finalangle;
+ self.owner.avelocity = '0 0 0';
+ self.nextthink = -1;
+ if (self.think1)
+ SUB_CallAsSelf(self.think1, self.owner);
+};
+
+
+//=============================================================================
+
+void() DelayThink =
+{
+ activator = self.enemy;
+ SUB_UseTargets ();
+ remove(self);
+};
+
+/* ### (added targets, killtargets, and targetnames)
+==============================
+SUB_UseTargets
+
+the global "activator" should be set to the entity that initiated the firing.
+
+If self.delay is set, a DelayedUse entity will be created that will actually
+do the SUB_UseTargets after that many seconds have passed.
+
+Centerprints any self.message to the activator.
+
+Removes all entities with a targetname that match self.killtarget,
+or killtarget2, so some events can remove other triggers.
+
+Search for (string)targetname, targetname2, targetname3, and targetname 4
+in all entities that match (string)self.target, self.target2, self.target3,
+or self.target4 and use their .use function.
+==============================
+*/
+void(string matchstring, .string matchfield) SUB_UseSpecificTarget =
+{
+ local entity t, stemp, otemp, act;
+
+ act = activator;
+ t = find (world, matchfield, matchstring);
+ while ( t != world )
+ {
+ stemp = self;
+ otemp = other;
+ self = t;
+ other = stemp;
+ if (self.use != SUB_Null)
+ {
+ if (self.use)
+ {
+ lastnameused = matchstring;
+ self.use ();
+ }
+ }
+ self = stemp;
+ other = otemp;
+ activator = act;
+ t = find (t, matchfield, matchstring);
+ }
+};
+
+void() SUB_UseTargets =
+{
+// local entity t, stemp, otemp, act;
+ local entity t;
+
+ if (self.estate != STATE_ACTIVE) return;
+//
+// check for a delay
+//
+ if (self.delay)
+ {
+ // create a temp object to fire at a later time
+ t = spawn();
+ t.classname = "DelayedUse";
+ t.nextthink = time + self.delay;
+ t.think = DelayThink;
+ t.enemy = activator;
+ t.message = self.message;
+ t.killtarget = self.killtarget;
+ t.killtarget2 = self.killtarget2;
+ t.target = self.target;
+ t.target2 = self.target2;
+ t.target3 = self.target3;
+ t.target4 = self.target4;
+ return;
+ }
+
+
+//
+// print the message
+//
+ if (self.message != "" && !(self.flags & FL_NOCENTERPRINT)) {
+ if (self.spawnflags & TRIGGER_CENTERPRINTALL) {
+ t = find(world, classname, "player");
+ while (t) {
+ centerprint (t, self.message);
+ if (!self.noise)
+ sound (t, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
+ t = find(t, classname, "player");
+ }
+ }
+
+ else if (activator.classname == "player") {
+ centerprint (activator, self.message);
+ if (!self.noise)
+ sound (activator, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
+ }
+ }
+
+//
+// kill the killtarget entities
+//
+ if (self.killtarget != "")
+ {
+ t = find(world, targetname, self.killtarget);
+ while(t != world)
+ {
+ if(t.switchshadstyle) lightstyle(t.switchshadstyle, "m");
+ remove(t);
+ t = find(t, targetname, self.killtarget);
+ }
+ t = find(world, targetname2, self.killtarget);
+ while(t != world)
+ {
+ if(t.switchshadstyle) lightstyle(t.switchshadstyle, "m");
+ remove(t);
+ t = find(t, targetname2, self.killtarget);
+ }
+ t = find(world, targetname3, self.killtarget);
+ while(t != world)
+ {
+ if(t.switchshadstyle) lightstyle(t.switchshadstyle, "m");
+ remove(t);
+ t = find(t, targetname3, self.killtarget);
+ }
+ t = find(world, targetname4, self.killtarget);
+ while(t != world)
+ {
+ if(t.switchshadstyle) lightstyle(t.switchshadstyle, "m");
+ remove(t);
+ t = find(t, targetname4, self.killtarget);
+ }
+ }
+
+//
+// kill the killtaget2 entities
+//
+ if (self.killtarget2 != "")
+ {
+ t = find(world, targetname, self.killtarget2);
+ while(t != world)
+ {
+ if(t.switchshadstyle) lightstyle(t.switchshadstyle, "m");
+ remove(t);
+ t = find(t, targetname, self.killtarget2);
+ }
+ t = find(world, targetname2, self.killtarget2);
+ while(t != world)
+ {
+ if(t.switchshadstyle) lightstyle(t.switchshadstyle, "m");
+ remove(t);
+ t = find(t, targetname2, self.killtarget2);
+ }
+ t = find(world, targetname3, self.killtarget2);
+ while(t != world)
+ {
+ if(t.switchshadstyle) lightstyle(t.switchshadstyle, "m");
+ remove(t);
+ t = find(t, targetname3, self.killtarget2);
+ }
+ t = find(world, targetname4, self.killtarget2);
+ while(t != world)
+ {
+ if(t.switchshadstyle) lightstyle(t.switchshadstyle, "m");
+ remove(t);
+ t = find(t, targetname4, self.killtarget2);
+ }
+ }
+
+//
+// fire targets
+//
+
+// target 1
+ if (self.target != "")
+ {
+ SUB_UseSpecificTarget(self.target, targetname);
+ SUB_UseSpecificTarget(self.target, targetname2);
+ SUB_UseSpecificTarget(self.target, targetname3);
+ SUB_UseSpecificTarget(self.target, targetname4);
+ }
+
+// target 2
+ if (self.target2 != "")
+ {
+ SUB_UseSpecificTarget(self.target2, targetname);
+ SUB_UseSpecificTarget(self.target2, targetname2);
+ SUB_UseSpecificTarget(self.target2, targetname3);
+ SUB_UseSpecificTarget(self.target2, targetname4);
+ }
+
+// target 3
+ if (self.target3 != "")
+ {
+ SUB_UseSpecificTarget(self.target3, targetname);
+ SUB_UseSpecificTarget(self.target3, targetname2);
+ SUB_UseSpecificTarget(self.target3, targetname3);
+ SUB_UseSpecificTarget(self.target3, targetname4);
+ }
+
+// target 4
+ if (self.target4 != "")
+ {
+ SUB_UseSpecificTarget(self.target4, targetname);
+ SUB_UseSpecificTarget(self.target4, targetname2);
+ SUB_UseSpecificTarget(self.target4, targetname3);
+ SUB_UseSpecificTarget(self.target4, targetname4);
+ }
+};
+
+void(string matchstring) SUB_UseName =
+{
+ SUB_UseSpecificTarget(matchstring, targetname);
+ SUB_UseSpecificTarget(matchstring, targetname2);
+ SUB_UseSpecificTarget(matchstring, targetname3);
+ SUB_UseSpecificTarget(matchstring, targetname4);
+};
+// ### end of Custents triggering code
+
+/*
+=============
+SUB_UseEntTargets
+===============
+*/
+void(entity t) SUB_UseEntTargets =
+{
+ if (t == world) return;
+ activator = self;
+ entity oself = self;
+ self = t;
+ SUB_UseTargets();
+ self = oself;
+}
+
+/*
+================
+SUB_UseAndForgetTargets
+
+This calls SUB_UseTargets, then clears all of self's fields that cause
+SUB_UseTargets to do things. The intention is that if SUB_UseTargets
+gets called again in the future, it won't do anything. Call this
+function if you want an entity to fire its targets just this once, and
+never again.
+
+Note that this function relies on the fact that SUB_UseTargets has
+already been modified to work around the engine bug involving tests of
+the form 'if (string)', i.e. that the tests in SUB_UseTargets are now of
+the form 'if (string != "")'. -- iw
+================
+*/
+void() SUB_UseAndForgetTargets =
+{
+ SUB_UseTargets ();
+
+ self.delay = 0;
+ self.killtarget = "";
+ self.killtarget2 = "";
+ self.message = "";
+ self.target = "";
+ self.target2 = "";
+ self.target3 = "";
+ self.target4 = "";
+};
+
+/*
+================
+SUB_FieldIsTargeted
+
+Return TRUE if the "fld" field of this entity is non-empty and matches
+the target (or target2/3/4 or pain_target) field of any other entity,
+otherwise return FALSE. -- iw
+================
+*/
+float(.string fld) SUB_FieldIsTargeted =
+{
+ if (self.fld == "")
+ return FALSE;
+
+ // the following function calls are staggered to avoid the silly
+ // "return value conflict" problem with traditional compilers -- iw
+
+ if (find (world, target, self.fld) != world)
+ return TRUE;
+
+ if (find (world, target2, self.fld) != world)
+ return TRUE;
+
+ if (find (world, target3, self.fld) != world)
+ return TRUE;
+
+ if (find (world, target4, self.fld) != world)
+ return TRUE;
+
+ if (find (world, pain_target, self.fld) != world)
+ return TRUE;
+
+ return FALSE;
+};
+
+/*
+================
+SUB_IsTargeted
+
+Return TRUE if the targetname (or targetname2/3/4) field of this entity
+is non-empty and matches the target (or target2/3/4 or pain_target)
+field of any other entity, otherwise return FALSE. -- iw
+================
+*/
+float() SUB_IsTargeted =
+{
+ // the following function calls are staggered to avoid the silly
+ // "return value conflict" problem with traditional compilers -- iw
+
+ if (SUB_FieldIsTargeted (targetname))
+ return TRUE;
+
+ if (SUB_FieldIsTargeted (targetname2))
+ return TRUE;
+
+ if (SUB_FieldIsTargeted (targetname3))
+ return TRUE;
+
+ if (SUB_FieldIsTargeted (targetname4))
+ return TRUE;
+
+ return FALSE;
+};
+
+//
+// pain_target //dumptruck_ds
+//
+void() SUB_UsePain =
+{
+ if (self.pain_target != "")
+ {
+ SUB_UseSpecificTarget (self.pain_target, targetname);
+ SUB_UseSpecificTarget (self.pain_target, targetname2);
+ SUB_UseSpecificTarget (self.pain_target, targetname3);
+ SUB_UseSpecificTarget (self.pain_target, targetname4);
+ }
+ self.pain_target = ""; //dumptruck_ds via Discord - thanks Spike, Snaut and QueenJazz
+};
+
+/*
+
+in nightmare mode, all attack_finished times become 0
+some monsters refire twice automatically
+
+*/
+
+void(float normal) SUB_AttackFinished =
+{
+ self.cnt = 0; // refire count for nightmare
+ if (skill != 3)
+ self.attack_finished = time + normal;
+};
+
+float (entity targ) visible;
+
+void (void() thinkst) SUB_CheckRefire =
+{
+ if (skill != 3)
+ return;
+ if (self.cnt == 1)
+ return;
+ if (!visible (self.enemy))
+ return;
+ self.cnt = 1;
+ self.think = thinkst;
+};
+
+/*
+================
+SUB_DislodgeRestingEntities
+
+This clears the FL_ONGROUND flag from any entities that are on top of
+self.
+
+The engine does not update the FL_ONGROUND flag automatically in some
+cases, with the result that certain types of entities can be left
+floating in mid-air if the entity they are resting on is removed from
+under them. This function is intended to be called in the case where
+self is going to be removed, to ensure that other entities are not left
+floating. -- iw
+================
+*/
+void() SUB_DislodgeRestingEntities =
+{
+ local entity e;
+
+ e = nextent (world);
+ while (e != world)
+ {
+ if ((e.flags & FL_ONGROUND) && e.groundentity == self)
+ e.flags = e.flags - (e.flags & FL_ONGROUND);
+ e = nextent (e);
+ }
+};
+//------------------------------------------------------------------------//
+// Drake -- This makes an entity do a think function right now.
+//------------------------------------------------------------------------//
+void(entity ent, void() thinkst) SUB_Think =
+{
+ local entity swap;
+
+ swap = self;
+ self = ent;
+ thinkst ();
+ self = swap;
+};
+
+/// from Copper -- dumptruck_ds (orginally found in triggers.qc)
+/*
+================================
+CheckValidTouch
+health and playerhood checks were duplicated everywhere
+added noclip check because Quake's default still-touch-everything noclip is awful
+================================
+*/
+float() CheckValidTouch =
+{
+ if (other.classname != "player")
+ return FALSE;
+ if (other.health <= 0)
+ return FALSE;
+ if (other.movetype == MOVETYPE_NOCLIP)
+ return FALSE;
+ if (self.estate != STATE_ACTIVE)
+ return FALSE;
+ return TRUE;
+}
+float(float a, float b) not = { return a - (a & b); } // fix not issue in client.qc - Copper -- dumptruck_ds
+
+void() SUB_EndWaiting = {
+ self.is_waiting = 0;
+ self.estate = STATE_ACTIVE;
+ if (self.use == SUB_EndWaiting) self.use = self.dormant_use;
+
+ // special case for teleports, makes it ignore the fact that it has a targetname when touched
+ if (self.classname == "trigger_teleport") {
+ self.is_waiting = -1;
+ }
+};
+
+void() SUB_CheckWaiting = {
+ if (self.is_waiting > 0) {
+ self.dormant_use = self.use;
+ self.use = SUB_EndWaiting;
+ self.estate = STATE_INACTIVE;
+
+ dprint("Spawned a waiting ");
+ dprint(self.classname);
+ dprint(" with targetname ");
+ dprint(self.targetname);
+ dprint(" and target ");
+ dprint(self.target);
+ dprint("\n");
+ }
+};
\ No newline at end of file

Return to the top of this page or return to the overview of this repo.

Diff qc/triggers.qc

diff --git a/qc/triggers.qc b/qc/triggers.qc
new file mode 100644
index 0000000..cda0c06
--- /dev/null
+++ b/qc/triggers.qc
@@ -0,0 +1,1781 @@
+
+// entity s;
+
+
+void() trigger_reactivate =
+{
+ self.solid = SOLID_TRIGGER;
+};
+
+//=============================================================================
+
+float SPAWNFLAG_NOMESSAGE = 1;
+float SPAWNFLAG_NOTOUCH = 1;
+float SPAWNFLAG_TURNS_OFF = 2; //used for Wait for retrigger spawnflag
+
+// the wait time has passed, so set back up for another activation
+void() multi_wait =
+{
+ if (self.max_health)
+ {
+ self.health = self.max_health;
+ self.takedamage = DAMAGE_YES;
+ self.solid = SOLID_BBOX;
+ }
+};
+
+
+// the trigger was just touched/killed/used
+// self.enemy should be set to the activator so it can be held through a delay
+// so wait for the delay time before firing
+void() multi_trigger =
+{
+ if (self.nextthink > time)
+ {
+ return; // allready been triggered
+ }
+
+ if (self.classname == "trigger_secret")
+ {
+ if (self.enemy.classname != "player")
+ return;
+ if (cutscene)
+ return; // Don't activate in cutscene mode
+ found_secrets = found_secrets + 1;
+ WriteByte (MSG_ALL, SVC_FOUNDSECRET);
+ }
+
+ if (self.noise != "")
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+
+// don't trigger again until reset
+ self.takedamage = DAMAGE_NO;
+
+ activator = self.enemy;
+
+ SUB_UseTargets();
+
+ if (self.wait > 0)
+ {
+ self.think = multi_wait;
+ self.nextthink = time + self.wait;
+ if (self.spawnflags & SPAWNFLAG_TURNS_OFF)
+ {
+ self.is_waiting = 1;
+ SUB_CheckWaiting();
+ }
+ }
+ else
+ { // we can't just remove (self) here, because this is a touch function
+ // called wheil C code is looping through area links...
+ self.touch = SUB_Null;
+ self.nextthink = time + 0.1;
+ self.think = SUB_Remove;
+ }
+};
+
+void() multi_killed = //dumptruck_ds
+{
+ if (self.estate != STATE_ACTIVE) // Supa, restore health and do nothing if we're still waiting to be activated
+ {
+ self.health = self.max_health; // nyah nyah~!
+ self.takedamage = DAMAGE_YES;
+ self.solid = SOLID_BBOX;
+
+ return;
+ }
+
+ self.enemy = damage_attacker;
+ multi_trigger();
+};
+
+void() multi_use = //dumptruck_ds
+{
+ self.enemy = activator;
+ multi_trigger();
+};
+
+void() multi_touch = //dumptruck_ds
+{
+
+ if (other.classname != "player")
+ return;
+
+ // from Copper -- dumptruck_ds
+ if (other.movetype == MOVETYPE_NOCLIP)
+ return;
+
+ if (self.estate != STATE_ACTIVE)
+ return;
+
+// if the trigger has an angles field, check player's facing direction
+ if (self.movedir != '0 0 0')
+ {
+ makevectors (other.angles);
+ if (v_forward * self.movedir < 0)
+ return; // not facing the right way
+ }
+
+ self.enemy = other;
+ multi_trigger ();
+};
+
+/*QUAKED trigger_multiple (.5 .5 .5) ? notouch WAIT_FOR_RETRIGGER X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Variable sized repeatable trigger. Must be targeted at one or more entities. If "health" is set, the trigger must be killed to activate each time.
+If "WAIT_FOR_RETRIGGER" is set, it must be triggered by another entity before it can trigger again.
+If "delay" is set, the trigger waits some time after activating before firing.
+"wait" : Seconds between triggerings. (.2 default)
+If notouch is set, the trigger is only fired by other entities, not by touching.
+NOTOUCH has been obsoleted by trigger_relay!
+sounds
+1) secret
+2) beep beep
+3) large switch
+set "message" to text string
+"is_waiting" : If set to 1, this trigger will do nothing until another trigger activates it
+*/
+void() trigger_multiple =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.sounds == 1)
+ {
+ precache_sound ("misc/secret.wav");
+ self.noise = "misc/secret.wav";
+ }
+ else if (self.sounds == 2)
+ {
+ precache_sound ("misc/talk.wav");
+ self.noise = "misc/talk.wav";
+ }
+ else if (self.sounds == 3)
+ {
+ precache_sound ("misc/trigger1.wav");
+ self.noise = "misc/trigger1.wav";
+ }
+
+ if (!self.wait)
+ {
+ self.wait = 0.2;
+ }
+ else if (self.wait < 0 && (self.spawnflags & SPAWNFLAG_TURNS_OFF))
+ {
+ objerror("Wait for retrigger and negative wait don't make sense");
+ }
+ self.use = multi_use;
+
+ InitTrigger ();
+
+ if (self.health)
+ {
+ if (self.spawnflags & SPAWNFLAG_NOTOUCH)
+ objerror ("health and notouch don't make sense\n");
+ self.max_health = self.health;
+ self.th_die = multi_killed;
+ self.takedamage = DAMAGE_YES;
+ self.solid = SOLID_BBOX;
+ setorigin (self, self.origin); // make sure it links into the world
+ }
+ else
+ {
+ if ( !(self.spawnflags & SPAWNFLAG_NOTOUCH) )
+ {
+ self.touch = multi_touch;
+ }
+ }
+
+ SUB_CheckWaiting();
+};
+
+
+/*QUAKED trigger_once (.5 .5 .5) ? notouch X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Variable sized trigger. Triggers once, then removes itself. You must set the key "target" to the name of another object in the level that has a matching
+"targetname". If "health" is set, the trigger must be killed to activate.
+If notouch is set, the trigger is only fired by other entities, not by touching.
+if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired.
+if "angle" is set, the trigger will only fire when someone is facing the direction of the angle. Use "360" for an angle of 0.
+sounds
+1) secret
+2) beep beep
+3) large switch
+set "message" to text string
+*/
+void() trigger_once =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.wait = -1;
+ trigger_multiple();
+};
+
+//=============================================================================
+
+/*QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+This fixed size trigger cannot be touched, it can only be fired by other events. It can contain killtargets, targets, delays, and messages.
+*/
+void() trigger_relay =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.use = SUB_UseTargets;
+};
+
+
+//=============================================================================
+
+/*QUAKED trigger_secret (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+secret counter trigger
+sounds
+1) secret
+2) beep beep
+set "message" to text string
+*/
+void() trigger_secret =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ total_secrets = total_secrets + 1;
+ self.wait = -1;
+ if (!self.message)
+ self.message = "You found a secret area!";
+ if (!self.sounds)
+ self.sounds = 1;
+
+ if (self.sounds == 1)
+ {
+ precache_sound ("misc/secret.wav");
+ self.noise = "misc/secret.wav";
+ }
+ else if (self.sounds == 2)
+ {
+ precache_sound ("misc/talk.wav");
+ self.noise = "misc/talk.wav";
+ }
+
+ trigger_multiple ();
+};
+
+//=============================================================================
+
+
+void() counter_use =
+{
+ if (self.estate != STATE_ACTIVE) return;
+
+ self.count = self.count - 1;
+ if (self.count < 0)
+ return;
+
+ if (self.count != 0)
+ {
+ if (activator.classname == "player"
+ && (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
+ {
+ if (self.count >= 4)
+ centerprint (activator, "There are more to go...");
+ else if (self.count == 3)
+ centerprint (activator, "Only 3 more to go...");
+ else if (self.count == 2)
+ centerprint (activator, "Only 2 more to go...");
+ else
+ centerprint (activator, "Only 1 more to go...");
+ }
+ return;
+ }
+
+ if (activator.classname == "player"
+ && (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
+ centerprint(activator, "Sequence completed!");
+ self.enemy = activator;
+ multi_trigger ();
+};
+
+/*QUAKED trigger_counter (.5 .5 .5) ? nomessage X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Acts as an intermediary for an action that takes multiple inputs.
+
+If nomessage is not set, t will print "1 more.. " etc when triggered and "sequence complete" when finished.
+
+After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself.
+*/
+void() trigger_counter =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.wait = -1;
+ if (!self.count)
+ self.count = 2;
+
+ self.use = counter_use;
+};
+
+/*
+==============================================================================
+
+TELEPORT TRIGGERS with added functions from Zerstrorer and Qmaster
+-- dumptruck_ds
+
+==============================================================================
+*/
+
+float PLAYER_ONLY = 1;
+float SILENT = 2;
+float RANDOM = 4;
+float TELE_STEALTH = 8;
+float MONSTER_ONLY = 16;
+float TELE_DD = 32;
+
+void() play_teleport =
+{
+ local float v;
+ local string tmpstr;
+
+ v = random() * 5;
+ if (v < 1)
+ tmpstr = "misc/r_tele1.wav";
+ else if (v < 2)
+ tmpstr = "misc/r_tele2.wav";
+ else if (v < 3)
+ tmpstr = "misc/r_tele3.wav";
+ else if (v < 4)
+ tmpstr = "misc/r_tele4.wav";
+ else
+ tmpstr = "misc/r_tele5.wav";
+
+ sound (self, CHAN_VOICE, tmpstr, 1, ATTN_NORM);
+ remove (self);
+};
+
+void(vector org) spawn_tfog =
+{
+ local entity s;
+
+ s = spawn ();
+ s.origin = org;
+ s.spawnflags = self.spawnflags; //dumptruck_ds
+ s.nextthink = time + 0.2;
+ s.think = play_teleport;
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_TELEPORT);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
+};
+
+
+void() tdeath_touch =
+{
+ if (other == self.owner)
+ return;
+
+// frag anyone who teleports in on top of an invincible player
+ if (other.classname == "player")
+ {
+// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes start
+ if (self.owner.classname != "player")
+ { // other monsters explode themselves
+ T_Damage (self.owner, self, self, 50000);
+ return;
+ }
+// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes end
+ if (other.invincible_finished > time)
+// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes start
+ { //player on spot has active pentagram
+ if (self.owner.invincible_finished > time)
+ { // teleported player has active pentagram too
+ // can happen often in deathmatch 4
+ // and levels with more than one pentagram
+ self.classname = "teledeath3";
+ other.invincible_finished = 0;
+ T_Damage (other, self, self, 50000); // kill player on spot
+/* 1998-07-26 only telefrag player on spot by Maddes
+ local entity other2;
+ other2 = self.owner;
+ self.owner = other;
+ other2.invincible_finished = 0;
+ T_Damage (other2, self, self, 50000); // kill teleported player
+*/
+ }
+ else // 1998-07-26 only telefrag player on spot by Maddes
+ { // 1998-07-26 only telefrag player on spot by Maddes
+// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes end
+ self.classname = "teledeath2";
+// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes start
+ T_Damage (self.owner, self, self, 50000);
+ } // 1998-07-26 only telefrag player on spot by Maddes
+ return;
+ }
+
+/*
+ if (self.owner.classname != "player")
+ { // other monsters explode themselves
+ T_Damage (self.owner, self, self, 50000);
+ return;
+ }
+*/
+// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes end
+
+ }
+
+ if (other.health)
+ {
+ T_Damage (other, self, self, 50000);
+ }
+};
+
+
+void(vector org, entity death_owner) spawn_tdeath =
+{
+local entity death;
+
+ death = spawn();
+ death.classname = "teledeath";
+ death.movetype = MOVETYPE_NONE;
+ death.solid = SOLID_TRIGGER;
+ death.angles = '0 0 0';
+ setsize (death, death_owner.mins - '1 1 1', death_owner.maxs + '1 1 1');
+ setorigin (death, org);
+ death.touch = tdeath_touch;
+ death.nextthink = time + 0.2;
+ death.think = SUB_Remove;
+ death.owner = death_owner;
+
+ force_retouch = 2; // make sure even still objects get hit
+};
+
+/*-----------------------------------------------*/
+/*| more Zerstrorer-- dumptruck_ds |*/
+/*| teleport_randomspot - returns a random spot |*/
+/*| to teleport to among all of the |*/
+/*| "info_teleport_random" entities in the |*/
+/*| level. self.count is number of spots |*/
+/*-----------------------------------------------*/
+entity() teleport_randomspot =
+{
+local float rndm;
+// local float rndm, num1;
+local entity spot,first;
+
+ rndm = rint(random() * (self.count - 1));
+ spot = find(world, classname, "info_teleport_random");
+ if(!spot)
+ dprint("No random teleport points found!\n");
+ first = spot;
+
+ while (rndm > 0)
+ {
+ rndm = rndm - 1;
+ spot = find(spot, classname, "info_teleport_random");
+ }
+
+ if (spot == world)
+ {
+ dprint("Random spot found world!!\n");
+ spot = first;
+ }
+
+ return spot;
+};
+// end dumptruck_ds
+void() teleport_touch =
+{
+local entity t;
+local vector org;
+
+ if (self.estate != STATE_ACTIVE) return;
+
+ if (self.targetname != "")
+ {
+ if (self.nextthink < time)
+ {
+ return; // not fired yet
+ }
+ }
+
+ if (self.spawnflags & PLAYER_ONLY)
+ {
+ if (other.classname != "player")
+ return;
+ }
+
+ if (self.spawnflags & MONSTER_ONLY) // is this going to work? dumptruck_ds
+ {
+ if (other.classname == "player")
+ return;
+ }
+
+ if (other.movetype == MOVETYPE_NOCLIP) // from Copper -- dumptruck_ds
+ return;
+
+ if (self.is_waiting == TRUE) // Supa, is this trigger waiting to be activated?
+ return;
+
+ if (self.is_waiting != -1) // Special case
+ if (self.targetname != "")
+ {
+ if (self.nextthink < time)
+ {
+ return; // not fired yet
+ }
+ }
+
+// only teleport living creatures
+ if (other.health <= 0 || other.solid != SOLID_SLIDEBOX)
+ return;
+
+ SUB_UseTargets ();
+
+ // put a tfog where the player was
+ // ### dhm - if stealth, don't spawn a fog
+ if (!(self.spawnflags & TELE_STEALTH))
+ spawn_tfog (other.origin);
+
+ //dhm - if this is a random teleporter, pick a random spot!
+ if (self.spawnflags & RANDOM)
+ t = teleport_randomspot();
+ else if ((self.spawnflags & TELE_DD) && other.classname == "player")
+ t = find (world, targetname, self.noise);
+ else
+ t = find (world, targetname, self.target);
+
+ if (!t)
+ objerror ("couldn't find target");
+
+// // put a tfog where the player was
+// spawn_tfog (other.origin);
+//
+// t = find (world, targetname, self.target);
+// if (!t)
+// objerror ("couldn't find target");
+
+// spawn a tfog flash in front of the destination
+ makevectors (t.mangle);
+ org = t.origin + 32 * v_forward;
+
+// ### dhm - if stealth, don't spawn a fog
+if (!(self.spawnflags & TELE_STEALTH))
+ spawn_tfog (org);
+
+ spawn_tdeath(t.origin, other);
+
+// move the player and lock him down for a little while
+ if (!other.health)
+ {
+ other.origin = t.origin;
+ other.velocity = (v_forward * other.velocity_x) + (v_forward * other.velocity_y);
+ return;
+ }
+
+ setorigin (other, t.origin);
+ other.angles = t.mangle;
+ if (other.classname == "player")
+ {
+ fog_setFromEnt(other, t); // retrieves fog values from teleport destination, if any
+
+ other.fixangle = 1; // turn this way immediately
+ other.teleport_time = time + 0.7;
+ if (other.flags & FL_ONGROUND)
+ other.flags = other.flags - FL_ONGROUND;
+ other.velocity = v_forward * 300;
+ }
+ other.flags = other.flags - other.flags & FL_ONGROUND;
+
+ if ((self.spawnflags & MONSTER_ONLY) && other.classname != "player")
+ {
+ other.fixangle = 1; // turn this way immediately
+ other.teleport_time = time + 0.7;
+ if (other.flags & FL_ONGROUND)
+ other.flags = other.flags - FL_ONGROUND;
+ other.velocity = v_forward * 300;
+ }
+ other.flags = other.flags - other.flags & FL_ONGROUND;
+};
+// this is from Qmaster:
+
+// "I created an info_teleport_changedest
+// target = targetname of trigger_teleport to affect
+// message = targetname of new info_teleport_destination (or whatever entity
+// really) to now teleport to
+
+// So that I can automatically update the teleporter under my coagula map as you
+// progress rather than have a bunch of triggers that I need to killtarget.
+// Falling is not fatal then, but it does put you back some. Works as a sorta
+// checkpoint system but also builds on my older idea for saving time in coop
+// implemented in my Terracity map eons ago.
+
+// looking at vanilla, you would only need to change trig.target to match
+// self.message if you were to add this.""
+
+void() teleport_destchange =
+{
+ local entity trig;
+
+ trig = find(world,targetname,self.target);
+ if (!trig || trig.classname != "trigger_teleport") {
+ dprint("\b[TELEPORT_DESTCHANGE]\b Cannot find trigger_teleport\n");
+ return;
+ }
+
+ trig.goalentity = find (world, targetname, self.message);
+ if (!trig.goalentity) {
+ dprint("\b[TELEPORT_DESTCHANGE]\b Cannot find teleport destination\n");
+ return;
+ }
+
+ makevectors (trig.goalentity.mangle);
+ trig.goalentity.movedir = v_forward;
+ trig.goalentity.pos1 = trig.goalentity.origin + 32 * trig.goalentity.movedir;
+
+ trig.target = self.message; //dumptruck_ds see comment above
+};
+
+/*QUAKED info_teleport_changedest (0 0.5 0) (-4 -4 -4) (4 4 4) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Allows a mapper to change the target of a teleport_trigger. Useful in maps where
+the player may fall into a void and the mapper wants to update where they "respawn"
+as they progress through the level. Could also be used for teleport puzzles and more.
+target = trigger_teleport to change
+message = new info_teleport_destination's targetname to switch to
+targetname = name of this entity so we can use it
+*/
+void() info_teleport_changedest =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.use = teleport_destchange;
+ if (self.targetname == "") {
+ dprint("\b[ERROR]\b info_teleport_changedest with no targetname");
+ remove(self);
+ }
+
+ if (self.target == "") {
+ dprint("\b[ERROR]\b info_teleport_changedest with no target");
+ remove(self);
+ }
+
+ if (self.message == "") {
+ dprint("\b[ERROR]\b info_teleport_changedest with no message set for new destination");
+ remove(self);
+ }
+};
+
+/*QUAKED info_teleport_destination (.5 .5 .5) (-8 -8 -8) (8 8 32) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/player.mdl");
+}
+This is the destination marker for a teleporter. It should have a "targetname" field with the same value as a teleporter's "target" field.
+*/
+void() info_teleport_destination =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+// this does nothing, just serves as a target spot
+ self.mangle = self.angles;
+ self.angles = '0 0 0';
+ self.model = "";
+ self.origin = self.origin + '0 0 27';
+ if (!self.targetname)
+ objerror ("no targetname");
+};
+
+/*QUAKED info_teleport_random (.5 .5 .5) (-8 -8 -8) (8 8 32) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/player.mdl");
+}
+This is a random destination marker for a teleporter.
+*/
+void() info_teleport_random =
+{
+// this does nothing, just serves as a target spot
+ self.mangle = self.angles;
+ self.angles = '0 0 0';
+ self.model = "";
+ self.origin = self.origin + '0 0 27';
+};
+
+void() teleport_use =
+{
+ self.nextthink = time + 0.2;
+ force_retouch = 2; // make sure even still objects get hit
+ self.think = SUB_Null;
+};
+
+// -------------------------
+/*QUAKED trigger_teleport (.5 .5 .5) ? PLAYER_ONLY SILENT RANDOM STEALTH X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Any object touching this will be transported to the corresponding
+info_teleport_destination entity. You must set the "target" field,
+and create an object with a "targetname" field that matches.
+
+If the trigger_teleport has a targetname, it will only teleport entities
+when it has been fired.
+
+SILENT(2) eliminates the teleporter ambient noise (good for hidden monster teleporters.
+RANDOM(4) causes the teleporter to send the player to a random destination
+ among the info_teleport_random markers in the level. You MUST place a
+ "count" field that is the number of info_teleport_random entities you
+ placed.
+STEALTH(8) eliminates the particle flash and noise when an entity is teleported.
+MONSTER_ONLY(16) will only teleport monsters
+*/void() trigger_teleport =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ local vector o;
+
+ InitTrigger ();
+ self.touch = teleport_touch;
+ // find the destination
+ if (!self.target)
+ objerror ("no target");
+ self.use = teleport_use;
+
+ if (!(self.spawnflags & SILENT))
+ {
+ precache_sound ("ambience/hum1.wav");
+ o = (self.mins + self.maxs)*0.5;
+ ambientsound (o, "ambience/hum1.wav",0.5 , ATTN_STATIC);
+ }
+
+ SUB_CheckWaiting();
+};
+
+/*
+==============================================================================
+
+trigger_setskill
+
+==============================================================================
+*/
+
+void() trigger_skill_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ cvar_set ("skill", self.message);
+};
+
+/*QUAKED trigger_setskill (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+sets skill level to the value of "message".
+Only used on start map.
+*/
+void() trigger_setskill =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ InitTrigger ();
+ self.touch = trigger_skill_touch;
+
+ SUB_CheckWaiting();
+};
+
+
+/*
+==============================================================================
+
+ONLY REGISTERED TRIGGERS
+
+==============================================================================
+*/
+
+void() trigger_onlyregistered_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+ if (self.attack_finished > time)
+ return;
+
+ self.attack_finished = time + 2;
+ if (cvar("registered"))
+ {
+ self.message = "";
+ SUB_UseTargets ();
+ remove (self);
+ }
+ else
+ {
+ if (self.message != "")
+ {
+ centerprint (other, self.message);
+ sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
+ }
+ }
+};
+
+/*QUAKED trigger_onlyregistered (.5 .5 .5) ?
+Only fires if playing the registered version, otherwise prints the message
+*/
+void() trigger_onlyregistered =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("misc/talk.wav");
+ InitTrigger ();
+ self.touch = trigger_onlyregistered_touch;
+
+ SUB_CheckWaiting();
+};
+
+//============================================================================
+
+// 1998-07-03 hurt_touch fix by Robert Field start
+/*
+void() hurt_on =
+{
+ self.solid = SOLID_TRIGGER;
+ self.nextthink = -1;
+};
+*/
+// 1998-07-03 hurt_touch fix by Robert Field end
+
+void() hurt_touch =
+{
+
+ if (self.estate != STATE_ACTIVE) return;
+
+ // from Copper -- dumptruck_ds
+ if (other.movetype == MOVETYPE_NOCLIP)
+ return;
+
+ if (other.takedamage && self.nextthink < time)
+ {
+// 1998-07-03 hurt_touch fix by Robert Field start
+// self.solid = SOLID_NOT;
+ if (time != self.hurt_together_time)
+ if (time < self.hurt_nextthink)
+ return;
+// 1998-07-03 hurt_touch fix by Robert Field end
+ T_Damage (other, self, self, self.dmg);
+// 1998-07-03 hurt_touch fix by Robert Field start
+// self.think = hurt_on;
+// self.nextthink = time + 1;
+ self.hurt_together_time = time;
+ self.hurt_nextthink = time + 1;
+// 1998-07-03 hurt_touch fix by Robert Field end
+ }
+ return;
+};
+
+/*QUAKED trigger_hurt (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Any object touching this will be hurt
+set dmg to damage amount
+defalt dmg = 5
+*/
+void() trigger_hurt =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ InitTrigger ();
+ self.touch = hurt_touch;
+ if (!self.dmg)
+ self.dmg = 5;
+
+ SUB_CheckWaiting();
+};
+
+//============================================================================
+
+//////////////////////////////////////////////////////////////////////////////
+// start dumptruck_ds additions //////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+float PUSH_ONCE = 1;
+float DT_STARTOFF = 8; // trigger will start off
+float DT_SILENT = 16; // push silently
+float DT_NOISE = 32; // use custom sound using noise key/value
+
+void() trigger_push_touch =
+{
+ if (self.estate != STATE_ACTIVE) return;
+
+ // from Copper -- dumptruck_ds
+ if (other.movetype == MOVETYPE_NOCLIP)
+ return;
+ if (other.classname == "grenade")
+ other.velocity = self.speed * self.movedir * 10;
+ else if (other.health > 0)
+ {
+ other.velocity = self.speed * self.movedir * 10;
+ if (other.classname == "player")
+ if (!(self.spawnflags & DT_SILENT))
+ {
+ if (other.fly_sound < time)
+ if (!(self.spawnflags & DT_NOISE))
+ {
+ other.fly_sound = time + 1.5;
+ sound (other, CHAN_AUTO, "ambience/windfly.wav", 1, ATTN_NORM);
+ }
+ else
+ {
+ other.fly_sound = time + 1.5;
+ sound (other, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ }
+ }
+ }
+ if (self.spawnflags & PUSH_ONCE)
+ remove(self);
+};
+
+// void() trigger_push_use = //dumptruck_ds
+// {
+// self.is_waiting = !self.is_waiting;
+// }
+
+/*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Pushes the player
+*/
+void() trigger_push = //dumptruck_ds
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ InitTrigger ();
+ precache_sound ("ambience/windfly.wav");
+ self.touch = trigger_push_touch;
+
+ if (!self.speed)
+ self.speed = 1000;
+
+ SUB_CheckWaiting();
+};
+
+void() push_toggle = //dumptruck_ds was based on hipnotic blocker_use now Alklaine estate
+
+{
+ if (self.estate != STATE_ACTIVE)
+ self.estate = STATE_ACTIVE;
+ else
+ self.estate = STATE_INACTIVE;
+};
+
+/*QUAKED trigger_push_custom (.5 .5 .5) ? PUSH_ONCE DT_STARTOFF DT_SILENT X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+
+dumptruck_ds
+
+trigger_push_custom is a new entity. This can be used to create traps,
+jumppads, currents in water and more.
+
+If DT_STARTOFF flag is set, this disables the trigger. This can be targeted and
+toggled off and on. If the DT_SILENT flag is set it won't make the windfly
+sound. Use DT_CUSTOM spawnflag and the noise key/value to use a custom push
+sound. Custom sounds should be "one off" sounds NOT be looping.
+
+Adapted from Hipnotic's func_togglewall */
+
+void() trigger_push_custom =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ InitTrigger();
+ precache_sound ("ambience/windfly.wav");
+ self.use = push_toggle;
+ self.touch = trigger_push_touch;
+
+ if ( self.spawnflags & DT_STARTOFF )
+ {
+ self.estate = STATE_INACTIVE;
+ }
+
+ if ( self.noise != "" )
+ {
+ precache_sound(self.noise);
+ }
+
+ if (!self.speed)
+ self.speed = 1000;
+
+ SUB_CheckWaiting();
+};
+
+
+//============================================================================
+
+void() trigger_monsterjump_touch =
+{
+ if (self.estate != STATE_ACTIVE) return;
+
+ if ( other.flags & (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER )
+ return;
+
+// set XY even if not on ground, so the jump will clear lips
+ other.velocity_x = self.movedir_x * self.speed;
+ other.velocity_y = self.movedir_y * self.speed;
+
+ if ( !(other.flags & FL_ONGROUND) )
+ return;
+
+ other.flags = other.flags - FL_ONGROUND;
+
+ other.velocity_z = self.height;
+};
+
+/*QUAKED trigger_monsterjump (.5 .5 .5) ? X X X DT_STARTOFF X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Walking monsters that touch this will jump in the direction of the trigger's angle
+"speed" default to 200, the speed thrown forward
+"height" default to 200, the speed thrown upwards
+
+If DT_STARTOFF flag is set, this makes the trigger
+inactive. This can be targeted and toggled off and on.
+*/
+void() trigger_monsterjump =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.use = push_toggle;
+ if ( self.spawnflags & DT_STARTOFF ) // dumptruck_ds
+ {
+ self.estate = STATE_INACTIVE;
+ }
+ if (!self.speed)
+ self.speed = 200;
+ if (!self.height)
+ self.height = 200;
+ if (self.angles == '0 0 0')
+ self.angles = '0 360 0';
+ InitTrigger ();
+ self.touch = trigger_monsterjump_touch;
+
+ SUB_CheckWaiting();
+};
+//////////////////////////////////////////////////////////////////////////////
+// end dumptruck_ds additions //////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+//This is necros' trigger_void from Lost Chapters pack, modified by dumptruck_ds
+
+float MONSTER_SAFE = 1;
+float PLAYER_SAFE = 2;
+
+void() trigger_void_touch =
+{
+ if (self.estate != STATE_ACTIVE) return;
+
+ if (other.movetype == MOVETYPE_NOCLIP) // from Copper -- dumptruck_ds
+ return FALSE;
+
+ if (self.spawnflags & MONSTER_SAFE && other.flags & FL_MONSTER) return; //ignore monsters
+ if (self.spawnflags & PLAYER_SAFE && other.flags & FL_CLIENT) return; // ignore players
+
+ if (other.takedamage)
+ {
+ other.invincible_finished = 0; // kills even with Pentagram, this took forever to figure out!! -- dumptruck_ds
+ T_Damage (other, self, self, other.health + 1000 /*, DTH_TRIGGER_VOID, 1, 1*/);
+
+ if (other.flags & FL_MONSTER)
+ remove(other);
+ }
+
+ if (other.classname == "gib" ||
+ other.classname == "grenade" ||
+ other.classname == "spike" ||
+ other.classname == "missile")
+ remove(other);
+
+ if (other.flags & FL_ITEM)
+ remove(other);
+
+ force_retouch = 2;
+};
+
+/*QUAKED trigger_void (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Use this for a 'void' area. removes monsters, gibs, ammo, etc... also kills player.
+*/
+void() trigger_void =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ InitTrigger ();
+ self.touch = trigger_void_touch;
+
+ SUB_CheckWaiting();
+};
+
+/*==============================================================================
+GIVE AND TAKE STUFF (WIP)
+
+This is Axe only at the moment. Need to research removing all weapons.
+==============================================================================*/
+
+void() take_weapon_use = //thanks to ShanJaq and Spike for their help on this.
+
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ if (!(other.flags & FL_CLIENT))
+ return;
+
+ {
+ multi_trigger();
+ other.items &= ~IT_SHOTGUN;
+ other.currentammo = !other.ammo_shells;
+ other.ammo_shells = !other.ammo_shells;
+ other.items = other.items - ( other.items & IT_SHELLS);
+ W_SetCurrentAmmo();
+ W_BestWeapon();
+ }
+};
+/*QUAKED trigger_take_weapon (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Removes shotgun upon touch. You can also set "reset_items" in the worldspawn entity to accomplish an axe only start.
+*/
+void() trigger_take_weapon =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.wait = -1;
+ trigger_multiple();
+ self.touch = take_weapon_use;
+
+ SUB_CheckWaiting();
+};
+
+void(float newtrack) changemusic =
+{
+ *world_sounds = newtrack; //changing the field via a pointer
+ //world.sounds has now been changed via our pointer, newly connecting players (like those connecting after the game is loaded) will get sent the new cd track's number.
+
+ //let everyone currently on the server know.
+ WriteByte(MSG_ALL, SVC_CDTRACK);
+ WriteByte(MSG_ALL, newtrack); //initial track
+ WriteByte(MSG_ALL, newtrack); //looped track... should generally be set the same as the initial track as most engines ignore it entirely so it might as well be sane for those that care.
+};
+
+//thanks to jleww via changemusic.rar --dumptruck_ds
+
+void() trigger_changemusic_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ if (!(other.flags & FL_CLIENT))
+ {
+ return;
+ }
+ changemusic(self.sounds);
+ self.touch = SUB_Null;
+ self.nextthink = (time + 0.1);
+ self.think = SUB_Remove;
+};
+/*QUAKED trigger_changemusic (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+A trigger brush that changes the currently playing music track. The number of the track to play goes in the sounds key (just like worldspawn). */
+void() trigger_changemusic =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+ if (!self.sounds)
+ {
+ objerror("ERROR: trigger_changemusic needs valid track number in sounds field");
+ return;
+ }
+ InitTrigger();
+ self.touch = trigger_changemusic_touch;
+
+ SUB_CheckWaiting();
+};
+
+void() trigger_cdtrack_use = //point entity version uses count for music track number for backwards compatibly in Adoria mod -- dumptruck_ds
+{
+ changemusic(self.count);
+};
+/*QUAKED trigger_cdtrack (.7 .7 .7) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+A point entity that changes the currently playing music track when triggered. The number of the track to play goes in the count key. e.g. 32 for track32.ogg See manual trigger_changemusic for more information on formats and more.
+
+NOTE: the track number uses the count key here but trigger_changemusic uses the sound key for the same info.
+*/
+void() trigger_cdtrack =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+ if (!self.count)
+ {
+ objerror("ERROR: trigger_cdtrack needs valid track number in count field");
+ return;
+ }
+ InitTrigger();
+ self.use = trigger_cdtrack_use;
+};
+///////////////////////////////////////////////////////////////
+//trigger_look (a.k.a. trigger_onlookat from NullPointPaladin!)
+///////////////////////////////////////////////////////////////
+void() onlookat_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ if (self.nextthink > time)
+ {
+ return; // allready been triggered
+ }
+
+ //added player view offset to make this more accurate to the player crosshairs
+ local vector player_offset;
+ player_offset = other.origin + other.view_ofs;
+
+ makevectors(other.v_angle);
+
+ //using speed to determine the reach of the trace
+ if(!self.speed)
+ self.speed = 500;
+ traceline(player_offset, (player_offset + (v_forward * self.speed)), FALSE, other);
+
+ if ((trace_ent.targetname == self.target))
+ {
+ // Play message if available
+ if (self.message != "")
+ {
+ centerprint (other, self.message);
+ }
+ self.use = multi_trigger;
+ SUB_UseTargets();
+
+ if (self.noise != "")
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ else
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+
+ // added wait
+ if (self.wait > 0)
+ {
+ self.think = multi_wait;
+ self.nextthink = time + self.wait;
+ }
+ else
+ { // we can't just remove (self) here, because this is a touch function
+ // called wheil C code is looping through area links...
+ self.touch = SUB_Null;
+ self.nextthink = time + 0.1;
+ self.think = SUB_Remove;
+ }
+ }
+};
+/*QUAKED trigger_look (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+This will trigger when a player is within the brush trigger and looks directly at a target entity.
+Use the first target key for the "looked at entity" and use the subsequent targets (2-4) to trigger other events.
+
+speed = Distance from player to search for trigger, adjust if the target is too far from the trigger (default 500 units)
+wait = Time between re-triggering (default 0)
+sounds = 0-3 are standard Quake trigger choices, 4 allows a custom sound, requires a path set in noise1 key
+noise1 = Path to custom sound. Use with sounds key set to 4 (e.g. fish/bite.wav)
+
+See manual for complete details. See pd_cutscenes sample map for example
+*/
+void() trigger_look =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ //play all the sounds available for a normal trigger
+ if (self.sounds == 0)
+ {
+ precache_sound ("misc/null.wav");
+ self.noise = "misc/null.wav";
+ }
+ else if (self.sounds == 1)
+ {
+ precache_sound ("misc/secret.wav");
+ self.noise = "misc/secret.wav";
+ }
+ else if (self.sounds == 2)
+ {
+ precache_sound ("misc/talk.wav");
+ self.noise = "misc/talk.wav";
+ }
+ else if (self.sounds == 3)
+ {
+ precache_sound ("misc/trigger1.wav");
+ self.noise = "misc/trigger1.wav";
+ }
+ else if (self.sounds == 4)
+ {
+ if (!self.noise1) //dumptruck_ds
+ {
+ objerror ("no soundfile set in noise1!\n");
+ remove(self);
+ return;
+ }
+ else
+ precache_sound (self.noise1);
+ self.noise = self.noise1;
+ }
+
+ InitTrigger();
+ self.touch = onlookat_touch;
+
+ SUB_CheckWaiting();
+};
+
+void() trigger_target_change_use =
+{
+ if (self.estate != STATE_ACTIVE) return;
+
+ for (entity e = world; (e = find(e, targetname, self.target)); )
+ {
+ if (!self.cnt || self.cnt == 1)
+ {
+ e.target = self.message;
+ }
+ else if (self.cnt == 2)
+ {
+ e.target2 = self.message;
+ }
+ else if (self.cnt == 3)
+ {
+ e.target3 = self.message;
+ }
+ else if (self.cnt == 4)
+ {
+ e.target4 = self.message;
+ }
+ }
+};
+
+
+/*QUAKED trigger_changetarget (.5 .5 .5) ?
+Changes an entity's target field
+
+target = entity to change
+message = new value for target field
+cnt = target field to change, null defaults to target
+
+*/
+void() trigger_changetarget =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.use = trigger_target_change_use;
+};
+
+
+
+
+/*
+=============================================================
+
+target_setstate
+
+=============================================================
+*/
+float SETSTATE_STARTOFF = 1;
+float SETSTATE_CLOSEALLDOORS = 2;
+float SETSTATE_DONTRESETBUTTON = 4;
+
+float(entity e) entity_get_state = {
+ if(e.classname == "func_door") return e.owner.estate;
+ else return e.estate;
+};
+
+void(entity e, float state, float flags) entity_set_state = {
+ float closealldoors;
+
+ if(e.classname == "func_button") {
+ if (state == STATE_ACTIVE) button_unlock(e, flags & SETSTATE_DONTRESETBUTTON);
+ else button_lock(e);
+ }
+ else if(e.classname == "func_door") {
+ if (flags & SETSTATE_CLOSEALLDOORS) closealldoors = 1;
+
+ if (state == STATE_ACTIVE) door_estate_unlock(e, closealldoors);
+ else door_estate_lock(e, closealldoors);
+ }
+ else e.estate = state;
+
+ if (e.is_waiting > 0 && state == STATE_ACTIVE) {
+ SUB_CallAsSelf(SUB_EndWaiting, e);
+ }
+
+ //if (e.touch && e.touch != SUB_Null) {
+ // force_retouch = 2;
+ //}
+};
+
+void(string matchstring, .string matchfield, float state, float flags) target_setstate_set_target = {
+ local entity t;
+
+ t = find (world, matchfield, matchstring);
+ while (t != world) {
+ if(state == -1){
+ if(entity_get_state(t) == STATE_ACTIVE) entity_set_state(t, STATE_INACTIVE, flags);
+ else entity_set_state(t, STATE_ACTIVE, flags);
+ }
+ else entity_set_state(t, state, flags);
+
+ t = find (t, matchfield, matchstring);
+ }
+};
+
+void(float state) target_setstate_set_alltargets = {
+ if (self.target && self.target != "") {
+ target_setstate_set_target(self.target, targetname, state, self.spawnflags);
+ target_setstate_set_target(self.target, targetname2, state, self.spawnflags);
+ target_setstate_set_target(self.target, targetname3, state, self.spawnflags);
+ target_setstate_set_target(self.target, targetname4, state, self.spawnflags);
+ }
+ if (self.target2 && self.target2 != "") {
+ target_setstate_set_target(self.target2, targetname, state, self.spawnflags);
+ target_setstate_set_target(self.target2, targetname2, state, self.spawnflags);
+ target_setstate_set_target(self.target2, targetname3, state, self.spawnflags);
+ target_setstate_set_target(self.target2, targetname4, state, self.spawnflags);
+ }
+ if (self.target3 && self.target3 != "") {
+ target_setstate_set_target(self.target3, targetname, state, self.spawnflags);
+ target_setstate_set_target(self.target3, targetname2, state, self.spawnflags);
+ target_setstate_set_target(self.target3, targetname3, state, self.spawnflags);
+ target_setstate_set_target(self.target3, targetname4, state, self.spawnflags);
+ }
+ if (self.target4 && self.target4 != "") {
+ target_setstate_set_target(self.target4, targetname, state, self.spawnflags);
+ target_setstate_set_target(self.target4, targetname2, state, self.spawnflags);
+ target_setstate_set_target(self.target4, targetname3, state, self.spawnflags);
+ target_setstate_set_target(self.target4, targetname4, state, self.spawnflags);
+ }
+};
+
+void() target_setstate_use = {
+ local float state;
+
+ if (self.style == 1) state = STATE_ACTIVE;
+ else if (self.style == 2) state = STATE_INACTIVE;
+ else state = -1;
+
+ target_setstate_set_alltargets(state);
+
+};
+
+void() target_setstate_startoff_think = {
+ target_setstate_set_alltargets(STATE_INACTIVE);
+};
+
+void() target_setstate = {
+ self.use = target_setstate_use;
+
+ if(self.spawnflags & SETSTATE_STARTOFF) {
+ // wait a bit while doors finish being set up
+ self.think = target_setstate_startoff_think;
+ self.nextthink = time + 0.2;
+ }
+};
+
+
+
+
+/*
+=============================================================
+
+trigger_filter
+
+=============================================================
+*/
+
+
+float FILTER_FIELD_STATE = 0;
+float FILTER_FIELD_HEALTH = 1;
+float FILTER_FIELD_WEAPON = 2;
+float FILTER_FIELD_FLAGS = 3;
+float FILTER_FIELD_SPAWNFLAGS = 4;
+float FILTER_FIELD_CLASSNAME = 5;
+float FILTER_FIELD_ESTATE = 6;
+float FILTER_FIELD_TARGETNAME = 8;
+float FILTER_FIELD_ITEMS = 10;
+float FILTER_FIELD_COUNT = 11;
+float FILTER_FIELD_CNT = 12;
+float FILTER_FIELD_TYPE = 13;
+
+
+float FILTER_FIELDTYPE_FLOAT = 0;
+float FILTER_FIELDTYPE_STRING = 1;
+float FILTER_FIELDTYPE_FLAG = 2;
+
+float FILTER_OP_EQUALS = 0;
+float FILTER_OP_LT = 1;
+float FILTER_OP_LTE = 2;
+float FILTER_OP_GT = 3;
+float FILTER_OP_GTE = 4;
+float FILTER_OP_BITMASK_AND = 5;
+float FILTER_OP_BITMASK_OR = 6;
+
+void() trigger_filter_use = {
+ self.state = 0;
+
+ if (self.estate != STATE_ACTIVE) return;
+
+ entity targ;
+ float targfloat;
+ string targstring;
+
+ float fieldtype, op, result;
+
+ if (self.include != "") {
+ targ = find(world, targetname, self.include);
+ if (!targ) targ = find(world, targetname2, self.include);
+ if (!targ) return;
+ }
+ else
+ targ = activator;
+
+ op = self.weapon;
+
+ switch (self.style) {
+ case FILTER_FIELD_STATE:
+ fieldtype = FILTER_FIELDTYPE_FLOAT;
+ targfloat = targ.state;
+ break;
+
+ case FILTER_FIELD_ESTATE:
+ fieldtype = FILTER_FIELDTYPE_FLOAT;
+ targfloat = targ.estate;
+ break;
+
+ case FILTER_FIELD_HEALTH:
+ fieldtype = FILTER_FIELDTYPE_FLOAT;
+ targfloat = targ.health;
+ break;
+
+ case FILTER_FIELD_COUNT:
+ fieldtype = FILTER_FIELDTYPE_FLOAT;
+ targfloat = targ.count;
+ break;
+
+ case FILTER_FIELD_CNT:
+ fieldtype = FILTER_FIELDTYPE_FLOAT;
+ targfloat = targ.cnt;
+ break;
+
+ case FILTER_FIELD_WEAPON:
+ fieldtype = FILTER_FIELDTYPE_FLOAT;
+ targfloat = targ.weapon;
+ break;
+
+ case FILTER_FIELD_FLAGS:
+ fieldtype = FILTER_FIELDTYPE_FLAG;
+ targfloat = targ.flags;
+ break;
+
+ case FILTER_FIELD_SPAWNFLAGS:
+ fieldtype = FILTER_FIELDTYPE_FLAG;
+ targfloat = targ.spawnflags;
+ break;
+
+ case FILTER_FIELD_ITEMS:
+ fieldtype = FILTER_FIELDTYPE_FLAG;
+ targfloat = targ.items;
+ break;
+
+ case FILTER_FIELD_CLASSNAME:
+ fieldtype = FILTER_FIELDTYPE_STRING;
+ targstring = targ.classname;
+ break;
+
+ case FILTER_FIELD_TARGETNAME:
+ fieldtype = FILTER_FIELDTYPE_STRING;
+ targstring = targ.targetname;
+ break;
+
+ case FILTER_FIELD_TYPE:
+ fieldtype = FILTER_FIELDTYPE_STRING;
+ targstring = targ.type;
+ break;
+ }
+
+ if (fieldtype == FILTER_FIELDTYPE_FLOAT) {
+ if (op == FILTER_OP_EQUALS) {if (targfloat == self.count) result = 1;}
+ else if (op == FILTER_OP_LT) {if (targfloat < self.count) result = 1;}
+ else if (op == FILTER_OP_LTE) {if (targfloat <= self.count) result = 1;}
+ else if (op == FILTER_OP_GT) {if (targfloat > self.count) result = 1;}
+ else if (op == FILTER_OP_GTE) {if (targfloat >= self.count) result = 1;}
+ else if (op == FILTER_OP_BITMASK_AND) {if (targfloat & self.count) result = 1;}
+ else if (op == FILTER_OP_BITMASK_OR) {if (targfloat | self.count) result = 1;}
+ else {if (targfloat == self.count) result = 1;}
+ }
+ else if (fieldtype == FILTER_FIELDTYPE_FLAG) {
+ if (op == FILTER_OP_EQUALS) {if (targfloat == self.aflag) result = 1;}
+ else if (op == FILTER_OP_BITMASK_AND) {if (targfloat & self.aflag) result = 1;}
+ else if (op == FILTER_OP_BITMASK_OR) {if (targfloat | self.aflag) result = 1;}
+ else {if (targfloat == self.aflag) result = 1;}
+ }
+ else if (fieldtype == FILTER_FIELDTYPE_STRING) {
+
+ if (targstring == self.type) result = 1;
+ }
+ else {
+ objerror ("invalid fieldtype");
+ return;
+ }
+
+ if (self.spawnflags & 1) result = 1 - result; // negate
+
+ if (result) {
+ self.state = 1;
+
+ if (self.spawnflags & 2 && activator.owner) activator = activator.owner; // relay activator as owner
+
+ SUB_UseTargets();
+ if (other.classname == "trigger_everything" && other.spawnflags & 1) {
+ if (other.wait) other.attack_finished = time + other.wait;
+ }
+
+ }
+};
+
+void() trigger_filter = {
+ self.use = trigger_filter_use;
+
+};
+
+
+/*
+=============================================================
+
+trigger_everything
+
+=============================================================
+*/
+
+void() trigger_everything_touch = {
+ if (self.estate != STATE_ACTIVE) return;
+
+ if (time < self.attack_finished) return;
+
+ activator = other;
+
+ SUB_UseSpecificTarget(self.target, targetname);
+
+ if (self.wait)
+ if (!(self.spawnflags & 1)) self.attack_finished = time + self.wait;
+
+};
+
+void() trigger_everything = {
+ InitTrigger();
+
+ self.touch = trigger_everything_touch;
+ SUB_CheckWaiting();
+};
+
+
+/*
+=============================================================
+
+target_setcount
+
+=============================================================
+*/
+
+void(string name, .string fld) target_setcount_set = {
+ local entity t;
+
+ t = find(world, fld, name);
+
+ while (t) {
+ if (self.style == 1)
+ t.count += self.count;
+ else
+ t.count = self.count;
+
+ t = find(t, fld, name);
+ }
+};
+
+void() target_setcount_use = {
+ if (self.target && self.target != "") {
+ target_setcount_set(self.target, targetname);
+ target_setcount_set(self.target, targetname2);
+ target_setcount_set(self.target, targetname3);
+ target_setcount_set(self.target, targetname4);
+ }
+ if (self.target2 && self.target2 != "") {
+ target_setcount_set(self.target2, targetname);
+ target_setcount_set(self.target2, targetname2);
+ target_setcount_set(self.target2, targetname3);
+ target_setcount_set(self.target2, targetname4);
+ }
+ if (self.target3 && self.target3 != "") {
+ target_setcount_set(self.target3, targetname);
+ target_setcount_set(self.target3, targetname2);
+ target_setcount_set(self.target3, targetname3);
+ target_setcount_set(self.target3, targetname4);
+ }
+ if (self.target4 && self.target4 != "") {
+ target_setcount_set(self.target4, targetname);
+ target_setcount_set(self.target4, targetname2);
+ target_setcount_set(self.target4, targetname3);
+ target_setcount_set(self.target4, targetname4);
+ }
+
+ if (self.spawnflags & 1) {
+ if (self.style == 1)
+ activator.count += activator.count;
+ else
+ activator.count = activator.count;
+ }
+};
+
+void() target_setcount = {
+ self.use = target_setcount_use;
+
+};
+
+void() trigger_monsterface_touch =
+{
+ // only affect ground monsters
+ if ( other.flags & (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER )
+ return;
+
+ if (!visibleToOther(other.enemy)) { // enemy is hidden
+ other.t_length = time + self.wait + 0.2; // don't dodge around, just go straight
+ other.ideal_yaw = self.angles_y; // face where I want
+ }
+}
+
+void() trigger_monsterface_init =
+{
+ self.solid = SOLID_TRIGGER;
+ setmodel (self, self.model); // set size and link into world
+ self.movetype = MOVETYPE_NONE;
+ self.modelindex = 0;
+ self.model = "";
+
+ if (self.angles == '0 0 0')
+ self.angles = '0 360 0';
+
+ self.touch = trigger_monsterface_touch;
+}
+
+/*QUAKED trigger_monsterface (.5 .0 .5)
+Running monsters that do not see their target and touch this will face in the direction of the trigger's angle instead of the unseen target.
+Use this trigger to make monsters leave their sniping spot and execute complex maneuvers.
+
+Keys:
+"angle" absolute angle in which the monster should face
+"targetname" entity name
+"wait" time to wait between retriggers
+*/
+void() trigger_monsterface =
+{
+ if (SUB_Inhibit())
+ return;
+
+ trigger_monsterface_init();
+ // InitTrigger();
+}

Return to the top of this page or return to the overview of this repo.

Diff qc/utility.qc

diff --git a/qc/utility.qc b/qc/utility.qc
new file mode 100644
index 0000000..7e98b90
--- /dev/null
+++ b/qc/utility.qc
@@ -0,0 +1,218 @@
+void(string s, string ss) dprint2 =
+ { dprint(s); dprint(ss); }
+void(string s, string ss, string sss) dprint3 =
+ { dprint(s); dprint(ss); dprint(sss); }
+void(string s, string ss, string sss, string ssss) dprint4 =
+ { dprint(s); dprint(ss); dprint(sss); dprint(ssss); }
+void(string s, string ss, string sss, string ssss, string sssss) dprint5 =
+ { dprint(s); dprint(ss); dprint(sss); dprint(ssss); dprint(sssss); }
+void(string s, string ss, string sss, string ssss, string sssss, string ssssss) dprint6 =
+ { dprint(s); dprint(ss); dprint(sss); dprint(ssss); dprint(sssss); dprint(ssssss);}
+void(string s, string ss, string sss, string ssss, string sssss, string ssssss, string sssssss) dprint7 =
+ { dprint(s); dprint(ss); dprint(sss); dprint(ssss); dprint(sssss); dprint(ssssss); dprint(sssssss);}
+void(string s, string ss, string sss, string ssss, string sssss, string ssssss, string sssssss, string ssssssss) dprint8 =
+ { dprint(s); dprint(ss); dprint(sss); dprint(ssss); dprint(sssss); dprint(ssssss); dprint(sssssss); dprint(ssssssss); }
+void(string s, string ss, string sss, string ssss, string sssss, string ssssss, string sssssss, string ssssssss, string sssssssss) dprint9 =
+ { dprint(s); dprint(ss); dprint(sss); dprint(ssss); dprint(sssss); dprint(ssssss); dprint(sssssss); dprint(ssssssss); dprint(sssssssss); }
+
+/**********************************
+ Sourced from utility.qc from smej2
+ **********************************/
+
+
+float(float in) bprint_int =
+{
+ in = floor(in);
+ if (in <= 0) return 0;
+
+ float digit;
+ digit = in - bprint_int(in / 10);
+
+ switch(digit) {
+ case 9:
+ bprint("9"); break;
+ case 8:
+ bprint("8"); break;
+ case 7:
+ bprint("7"); break;
+ case 6:
+ bprint("6"); break;
+ case 5:
+ bprint("5"); break;
+ case 4:
+ bprint("4"); break;
+ case 3:
+ bprint("3"); break;
+ case 2:
+ bprint("2"); break;
+ case 1:
+ bprint("1"); break;
+ case 0:
+ bprint("0"); break;
+ }
+
+ return in * 10;
+}
+
+
+float(float in, float def) defaultFl = {
+ if (in) return in;
+ else return def;
+}
+
+
+// shorthand for turning -1 to 0 for keyvalues for which 0 is a valid non-default selection
+float(float in) zeroconvert =
+{
+ if (in == -1) return 0;
+ return in;
+}
+float(float in, float def) zeroconvertdefault =
+{
+ if (in == -1) return 0;
+ if (in == 0) return def;
+ return in;
+}
+
+
+
+
+// for measuring how large an entity is along an arbitrary vector
+// FIXME: this is trash and it returns trash
+float(vector v, vector s) BoundsAngleSize =
+{
+ v_x = fabs(v_x);
+ v_y = fabs(v_y);
+ v_z = fabs(v_z);
+
+ // size is always + + + but this is in case I switch the parameters somewhere
+ s_x = fabs(s_x);
+ s_y = fabs(s_y);
+ s_z = fabs(s_z);
+
+ return v * s;
+}
+
+//count -4 = numclients in coop
+/*void(.float fld) playercount_convert =
+{
+ if (self.fld != -4) return;
+ if (!coop)
+ self.fld = 1;
+ else
+ self.fld = clients;
+}
+*/
+
+
+// wonderful stuffcmd code from Honey by czg
+
+/*
+=============
+stuffcmd_float
+
+This is a horrible hack that I am ashamed of!
+===============
+*/
+void stuffcmd_digit( entity client, float f) =
+{
+ float d;
+ d = floor(f);
+ d = mod(d, 10);
+
+ //CLOSE YOUR EYES, HONEY! DON'T LOOK!
+ if(d == 0)
+ stuffcmd(client, "0");
+ else if(d == 1)
+ stuffcmd(client, "1");
+ else if(d == 2)
+ stuffcmd(client, "2");
+ else if(d == 3)
+ stuffcmd(client, "3");
+ else if(d == 4)
+ stuffcmd(client, "4");
+ else if(d == 5)
+ stuffcmd(client, "5");
+ else if(d == 6)
+ stuffcmd(client, "6");
+ else if(d == 7)
+ stuffcmd(client, "7");
+ else if(d == 8)
+ stuffcmd(client, "8");
+ else if(d == 9)
+ stuffcmd(client, "9");
+}
+
+void stuffcmd_int( entity client, float f, float numdigits) =
+{
+
+ float tmp;
+
+
+ if(f == 0)
+ {
+ stuffcmd( client, "0");
+ return;
+ }
+
+ if(f < 0)
+ {
+ // Yeah sure.
+ stuffcmd( client, "-");
+ f = fabs(f);
+ }
+
+ if(numdigits <= 0)
+ {
+ tmp = f;
+ numdigits = 1;
+ while(tmp >= 1){
+ tmp = tmp / 10;
+ numdigits = numdigits * 10;
+ }
+ }
+
+ //I don't know what I'm thinking here...
+ //I need to do this to get zero-padding to work.
+
+ while( numdigits > 1 )
+ {
+ numdigits = numdigits / 10;
+ tmp = f / numdigits;
+ stuffcmd_digit( client, tmp);
+ }
+}
+
+void stuffcmd_float( entity client, float f) =
+{
+ float intpart, decpart, isNegative;
+
+ isNegative = FALSE;
+
+ if(f == 0)
+ {
+ stuffcmd( client, "0");
+ return;
+ }
+
+ if(f < 0)
+ {
+ // easier this way
+ isNegative = TRUE;
+ f = fabs(f);
+ }
+
+ // 1: stuff the integer part.
+ intpart = floor(f);
+ if(isNegative)
+ stuffcmd( client, "-");
+ stuffcmd_int( client, intpart, 0);
+
+ // 2: stuff the decimal point.
+ stuffcmd( client, ".");
+
+ // 3: stuff the decimal part.
+ decpart = mod( f, 1);
+ decpart = decpart * 10000;
+ stuffcmd_int( client, decpart, 10000);
+}

Return to the top of this page or return to the overview of this repo.

Diff qc/weapons.qc

diff --git a/qc/weapons.qc b/qc/weapons.qc
new file mode 100644
index 0000000..8dacf7b
--- /dev/null
+++ b/qc/weapons.qc
@@ -0,0 +1,1807 @@
+/*
+*/
+void (entity targ, entity inflictor, entity attacker, float damage) T_Damage;
+void () player_run;
+void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
+void(vector org, vector vel, float damage) SpawnBlood;
+void() SuperDamageSound;
+void() create_mobot; //dumptruck_ds mobot.qc
+void(entity mis, float speed) SetupHoming;
+
+void(entity mis, vector dir, float speed) SetSpeed =
+{
+ if (cvar("sv_maxvelocity") > speed)
+ {
+ mis.velocity = dir * speed;
+ }
+ else {
+ mis.velocity = dir * cvar("sv_maxvelocity");
+ }
+};
+
+// called by worldspawn
+void() W_Precache =
+{
+ precache_sound ("weapons/r_exp3.wav"); // new rocket explosion
+ precache_sound ("weapons/rocket1i.wav"); // spike gun
+ precache_sound ("weapons/sgun1.wav");
+ precache_sound ("weapons/guncock.wav"); // player shotgun
+ precache_sound ("weapons/ric1.wav"); // ricochet (used in c code)
+ precache_sound ("weapons/ric2.wav"); // ricochet (used in c code)
+ precache_sound ("weapons/ric3.wav"); // ricochet (used in c code)
+ precache_sound ("weapons/spike2.wav"); // super spikes
+ precache_sound ("weapons/tink1.wav"); // spikes tink (used in c code)
+ precache_sound ("weapons/grenade.wav"); // grenade launcher
+ precache_sound ("weapons/bounce.wav"); // grenade bounce
+ precache_sound ("weapons/shotgn2.wav"); // super shotgun
+
+// dumptruck_ds mobot.qc precaches START
+
+ precache_model ("progs/ogre.mdl");
+ precache_model ("progs/h_ogre.mdl");
+ precache_model ("progs/grenade.mdl");
+ precache_sound ("ogre/ogdrag.wav");
+ precache_sound ("ogre/ogdth.wav");
+ precache_sound ("ogre/ogidle.wav");
+ precache_sound ("ogre/ogidle2.wav");
+ precache_sound ("ogre/ogpain1.wav");
+ precache_sound ("ogre/ogsawatk.wav");
+ precache_sound ("ogre/ogwake.wav");
+
+ precache_model ("progs/demon.mdl");
+ precache_model ("progs/h_demon.mdl");
+
+ precache_sound ("demon/ddeath.wav");
+ precache_sound ("demon/dhit2.wav");
+ precache_sound ("demon/djump.wav");
+ precache_sound ("demon/dpain1.wav");
+ precache_sound ("demon/idle1.wav");
+ precache_sound ("demon/sight2.wav");
+
+ precache_model2 ("progs/enforcer.mdl");
+ precache_model2 ("progs/h_mega.mdl");
+ precache_model2 ("progs/laser.mdl");
+ precache_model2 ("progs/s_spike.mdl");
+
+ precache_sound2 ("enforcer/death1.wav");
+ precache_sound2 ("enforcer/enfire.wav");
+ precache_sound2 ("enforcer/enfstop.wav");
+ precache_sound2("enforcer/idle1.wav");
+ precache_sound2 ("enforcer/pain1.wav");
+ precache_sound2 ("enforcer/pain2.wav");
+ precache_sound2 ("enforcer/sight1.wav");
+ precache_sound2 ("enforcer/sight2.wav");
+ precache_sound2 ("enforcer/sight3.wav");
+ precache_sound2("enforcer/sight4.wav");
+
+ precache_model ("progs/soldier.mdl");
+ precache_model ("progs/h_guard.mdl");
+
+ precache_model ("progs/gib1.mdl");
+ precache_model ("progs/gib2.mdl");
+ precache_model ("progs/gib3.mdl");
+
+ precache_sound ("soldier/death1.wav");
+ precache_sound ("soldier/idle.wav");
+ precache_sound ("soldier/pain1.wav");
+ precache_sound ("soldier/pain2.wav");
+ precache_sound ("soldier/sattck1.wav");
+ precache_sound ("soldier/sight1.wav");
+ precache_sound ("player/udeath.wav"); // gib death
+
+ precache_model ("progs/h_dog.mdl");
+ precache_model ("progs/dog.mdl");
+ precache_sound ("dog/dattack1.wav");
+ precache_sound("dog/ddeath.wav");
+ precache_sound ("dog/dpain1.wav");
+ precache_sound ("dog/dsight.wav");
+ precache_sound ("dog/idle.wav");
+
+ precache_model ("progs/wizard.mdl");
+ precache_model ("progs/h_wizard.mdl");
+ precache_model ("progs/w_spike.mdl");
+
+ precache_sound ("wizard/hit.wav"); // used by c code
+ precache_sound ("wizard/wattack.wav");
+ precache_sound ("wizard/wdeath.wav");
+ precache_sound ("wizard/widle1.wav");
+ precache_sound ("wizard/widle2.wav");
+ precache_sound ("wizard/wpain.wav");
+ precache_sound ("wizard/wsight.wav");
+
+ precache_model2 ("progs/shalrath.mdl");
+ precache_model2 ("progs/h_shal.mdl");
+ precache_model2 ("progs/v_spike.mdl");
+
+ precache_sound2 ("shalrath/attack.wav");
+ precache_sound2 ("shalrath/attack2.wav");
+ precache_sound2 ("shalrath/death.wav");
+ precache_sound2 ("shalrath/idle.wav");
+ precache_sound2 ("shalrath/pain.wav");
+ precache_sound2 ("shalrath/sight.wav");
+
+ precache_model ("progs/knight.mdl");
+ precache_model ("progs/h_knight.mdl");
+
+ precache_sound ("knight/kdeath.wav");
+ precache_sound ("knight/khurt.wav");
+ precache_sound ("knight/ksight.wav");
+ precache_sound ("knight/sword1.wav");
+ precache_sound ("knight/sword2.wav");
+ precache_sound ("knight/idle.wav");
+
+ precache_model2 ("progs/hknight.mdl");
+ precache_model2 ("progs/k_spike.mdl");
+ precache_model2 ("progs/k_spike2.mdl");
+ precache_model2 ("progs/h_hellkn.mdl");
+ precache_model2 ("progs/hknight.mdl");
+ precache_model2 ("progs/h_hellkn.mdl");
+ precache_model2 ("progs/k_spike.mdl");
+
+ precache_sound2 ("hknight/attack1.wav");
+ precache_sound2 ("hknight/death1.wav");
+ precache_sound2 ("hknight/pain1.wav");
+ precache_sound2 ("hknight/sight1.wav");
+ precache_sound ("hknight/hit.wav"); // used by C code, so don't sound2
+ precache_sound2 ("hknight/slash1.wav");
+ precache_sound2 ("hknight/idle.wav");
+ precache_sound2 ("hknight/grunt.wav");
+ precache_sound ("knight/sword1.wav");
+ precache_sound ("knight/sword2.wav");
+
+ precache_sound2 ("blob/death1.wav");
+ precache_sound2 ("blob/hit1.wav");
+ precache_sound2 ("blob/land1.wav");
+ precache_sound2 ("blob/sight1.wav");
+
+ precache_model ("progs/zombie.mdl");
+ precache_model ("progs/h_zombie.mdl");
+ precache_model ("progs/zom_gib.mdl");
+
+ precache_sound ("zombie/z_idle.wav");
+ precache_sound ("zombie/z_idle1.wav");
+ precache_sound ("zombie/z_shot1.wav");
+ precache_sound ("zombie/z_gib.wav");
+ precache_sound ("zombie/z_pain.wav");
+ precache_sound ("zombie/z_pain1.wav");
+ precache_sound ("zombie/z_fall.wav");
+ precache_sound ("zombie/z_miss.wav");
+ precache_sound ("zombie/z_hit.wav");
+ precache_sound ("zombie/idle_w2.wav");
+
+ precache_model ("progs/shambler.mdl");
+ precache_model ("progs/s_light.mdl");
+ precache_model ("progs/h_shams.mdl");
+ precache_model ("progs/bolt.mdl");
+
+ precache_sound ("shambler/sattck1.wav");
+ precache_sound ("shambler/sboom.wav");
+ precache_sound ("shambler/sdeath.wav");
+ precache_sound ("shambler/shurt2.wav");
+ precache_sound ("shambler/sidle.wav");
+ precache_sound ("shambler/ssight.wav");
+ precache_sound ("shambler/melee1.wav");
+ precache_sound ("shambler/melee2.wav");
+ precache_sound ("shambler/smack.wav");
+
+ // dumptruck_ds mobot.qc END
+};
+
+float() crandom =
+{
+ return 2*(random() - 0.5);
+};
+
+/*
+================
+W_FireAxe
+================
+*/
+void() W_FireAxe =
+{
+ local vector source;
+ local vector org;
+
+ makevectors (self.v_angle);
+ source = self.origin + '0 0 16';
+ traceline (source, source + v_forward*64, FALSE, self);
+ if (trace_fraction == 1.0)
+ return;
+ org = trace_endpos - v_forward*4;
+
+ if (trace_ent.takedamage)
+ {
+ trace_ent.axhitme = 1;
+ SpawnBlood (org, '0 0 0', 20);
+ T_Damage (trace_ent, self, self, 20);
+ }
+ else
+ { // hit wall
+ sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_GUNSHOT);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
+ }
+};
+
+
+//============================================================================
+
+
+vector() wall_velocity =
+{
+ local vector vel;
+
+ vel = normalize (self.velocity);
+ vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
+ vel = vel + 2*trace_plane_normal;
+ vel = vel * 200;
+
+ return vel;
+};
+
+
+/*
+================
+SpawnMeatSpray
+================
+*/
+void(vector org, vector vel) SpawnMeatSpray =
+{
+ local entity missile;
+
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_NOT;
+
+ makevectors (self.angles);
+
+ missile.velocity = vel;
+ missile.velocity_z = missile.velocity_z + 250 + 50*random();
+
+ missile.avelocity = '3000 1000 2000';
+
+// set missile duration
+ missile.nextthink = time + 1;
+ missile.think = SUB_Remove;
+
+ setmodel (missile, "progs/zom_gib.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, org);
+};
+
+/*
+================
+SpawnBlood
+================
+*/
+void(vector org, vector vel, float damage) SpawnBlood =
+{
+ particle (org, vel*0.1, 73, damage*2);
+};
+
+/*
+================
+spawn_touchblood
+================
+*/
+void(float damage) spawn_touchblood =
+{
+ local vector vel;
+
+ vel = wall_velocity () * 0.2;
+ SpawnBlood (self.origin + vel*0.01, vel, damage);
+};
+
+
+/*
+================
+SpawnChunk
+================
+*/
+void(vector org, vector vel) SpawnChunk =
+{
+ particle (org, vel*0.02, 0, 10);
+};
+
+/*
+==============================================================================
+
+MULTI-DAMAGE
+
+Collects multiple small damages into a single damage
+
+==============================================================================
+*/
+
+entity multi_ent;
+float multi_damage;
+
+void() ClearMultiDamage =
+{
+ multi_ent = world;
+ multi_damage = 0;
+};
+
+void() ApplyMultiDamage =
+{
+ if (!multi_ent)
+ return;
+ T_Damage (multi_ent, self, self, multi_damage);
+};
+
+void(entity hit, float damage) AddMultiDamage =
+{
+ if (!hit)
+ return;
+
+ if (hit != multi_ent)
+ {
+ ApplyMultiDamage ();
+ multi_damage = damage;
+ multi_ent = hit;
+ }
+ else
+ multi_damage = multi_damage + damage;
+};
+
+/*
+==============================================================================
+
+BULLETS
+
+==============================================================================
+*/
+
+/*
+================
+TraceAttack
+================
+*/
+void(float damage, vector dir) TraceAttack =
+{
+ local vector vel, org;
+
+ vel = normalize(dir + v_up*crandom() + v_right*crandom());
+ vel = vel + 2*trace_plane_normal;
+ vel = vel * 200;
+
+ org = trace_endpos - dir*4;
+
+ if (trace_ent.takedamage)
+ {
+ SpawnBlood (org, vel*0.2, damage);
+ AddMultiDamage (trace_ent, damage);
+ }
+ else
+ {
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_GUNSHOT);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
+ }
+};
+
+/*
+================
+FireBullets
+
+Used by shotgun, super shotgun, and enemy soldier firing
+Go to the trouble of combining multiple pellets into a single damage call.
+================
+*/
+void(float shotcount, vector dir, vector spread) FireBullets =
+{
+ local vector direction;
+ local vector src;
+
+ makevectors(self.v_angle);
+
+ src = self.origin + v_forward*10;
+ src_z = self.absmin_z + self.size_z * 0.7;
+
+ ClearMultiDamage ();
+ while (shotcount > 0)
+ {
+ direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up;
+
+ traceline (src, src + direction*2048, FALSE, self);
+ if (trace_fraction != 1.0)
+ TraceAttack (4, direction);
+
+ shotcount = shotcount - 1;
+ }
+ ApplyMultiDamage ();
+};
+
+/*
+================
+W_FireShotgun
+================
+*/
+void() W_FireShotgun =
+{
+ local vector dir;
+
+ sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);
+
+ self.punchangle_x = -2;
+
+ self.currentammo = self.ammo_shells = self.ammo_shells - 1;
+ dir = aim (self, 100000);
+ FireBullets (6, dir, '0.04 0.04 0');
+};
+
+
+/*
+================
+W_FireSuperShotgun
+================
+*/
+void() W_FireSuperShotgun =
+{
+ local vector dir;
+
+ if (self.currentammo == 1)
+ {
+ W_FireShotgun ();
+ return;
+ }
+
+ sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);
+
+ self.punchangle_x = -4;
+
+ self.currentammo = self.ammo_shells = self.ammo_shells - 2;
+ dir = aim (self, 100000);
+ FireBullets (14, dir, '0.14 0.08 0');
+};
+
+
+/*
+==============================================================================
+
+ROCKETS
+
+==============================================================================
+*/
+
+void() s_explode1 = [0, s_explode2] {};
+void() s_explode2 = [1, s_explode3] {};
+void() s_explode3 = [2, s_explode4] {};
+void() s_explode4 = [3, s_explode5] {};
+void() s_explode5 = [4, s_explode6] {};
+void() s_explode6 = [5, SUB_Remove] {};
+
+void() BecomeExplosion =
+{
+ self.movetype = MOVETYPE_NONE;
+ self.velocity = '0 0 0';
+ self.touch = SUB_Null;
+ setmodel (self, "progs/s_explod.spr");
+ self.solid = SOLID_NOT;
+ s_explode1 ();
+};
+
+void() T_MissileTouch =
+{
+ local float damg;
+
+ if (other == self.owner)
+ return; // don't explode on owner
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove(self);
+ return;
+ }
+
+ damg = 100 + random()*20;
+
+ if (other.health)
+ {
+ if (other.classname == "monster_shambler")
+ damg = damg * 0.5; // mostly immune
+ T_Damage (other, self, self.owner, damg );
+ }
+
+ // don't do radius damage to the other, because all the damage
+ // was done in the impact
+ T_RadiusDamage (self, self.owner, 120, other);
+
+// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
+ self.origin = self.origin - 8*normalize(self.velocity);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ BecomeExplosion ();
+
+};
+//dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
+
+void(float direct, float splash) T_MonsterMisTouch =
+{
+ local float damg;
+
+ if (other == self.owner)
+ return; // don't explode on owner
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove(self);
+ return;
+ }
+
+ damg = direct + random()*2; //dumptruck_ds
+
+ if (other.health)
+ {
+ if (other.classname == "monster_shambler")
+ damg = damg * 0.5; // mostly immune
+ T_Damage (other, self, self.owner, damg );
+ }
+
+ // don't do radius damage to the other, because all the damage
+ // was done in the impact
+ T_RadiusDamage (self, self.owner, splash, other); //dumptruck_ds
+
+// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
+ self.origin = self.origin - 8*normalize(self.velocity);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ BecomeExplosion ();
+};
+
+void() T_GruntMisTouch =
+{
+ T_MonsterMisTouch(30, 40);
+};
+
+ // less direct damage, more splash than grunt
+ // TODO: add damage modifier
+void() T_HellKnightMisTouch =
+{
+ T_MonsterMisTouch(20, 50);
+};
+
+// big damage. explody scrag should be beefy.
+// TODO: add damage modifier
+void() T_WizardMisTouch =
+{
+ T_MonsterMisTouch(50, 50);
+};
+//dumptruck_ds end
+
+/*
+================
+W_FireRocket
+================
+*/
+void() W_FireRocket =
+{
+ local entity missile;
+
+ self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
+
+ sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
+
+ self.punchangle_x = -2;
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_FLYMISSILE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "missile";
+
+// set missile speed
+
+ makevectors (self.v_angle);
+ missile.velocity = aim(self, 1000);
+ missile.velocity = missile.velocity * 1000;
+ missile.angles = vectoangles(missile.velocity);
+
+ missile.touch = T_MissileTouch;
+
+// set missile duration
+ missile.nextthink = time + 5;
+ missile.think = SUB_Remove;
+
+ setmodel (missile, "progs/missile.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin + v_forward*8 + '0 0 16');
+};
+/*
+================
+W_GruntRocket //dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
+================
+*/
+void() W_GruntRocket =
+{
+ local entity missile;
+
+ // self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; dumptruck_ds
+
+ sound_attack (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
+
+ self.punchangle_x = -2;
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_FLYMISSILE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "missile";
+
+// set missile speed -- dumptruck_ds below
+
+ missile.velocity = normalize(self.enemy.origin - self.origin);
+ SetSpeed(missile, missile.velocity, 900*self.proj_speed_mod);
+ missile.angles = vectoangles(missile.velocity);
+ missile.touch = T_GruntMisTouch;
+
+ // makevectors (self.v_angle);
+ // missile.velocity = aim(self, 1000);
+ // missile.velocity = missile.velocity * 1000;
+ // missile.angles = vectoangles(missile.velocity);
+
+ // missile.touch = T_MissileTouch;
+
+// set missile duration
+ if (self.homing > 0)
+ {
+ SetupHoming(missile, 900 * self.proj_speed_mod);
+ }
+ else {
+ missile.nextthink = time + 5;
+ missile.think = SUB_Remove;
+ }
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/missile.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+// dumptruck_ds - end
+
+ // setmodel (missile, "progs/missile.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
+ setorigin (missile, self.origin + v_forward * 30 + v_right * 5 + '0 0 12');
+ // setorigin (missile, self.origin + v_forward*8 + '0 0 16');
+};
+
+//end dumptruck_ds grunt missle end
+
+/*
+===============================================================================
+
+LIGHTNING
+
+===============================================================================
+*/
+
+/*
+=================
+LightningDamage
+=================
+*/
+void(vector p1, vector p2, entity from, float damage) LightningDamage =
+{
+ local entity e1, e2;
+ local vector f;
+
+ f = p2 - p1;
+ normalize (f);
+ f_x = 0 - f_y;
+ f_y = f_x;
+ f_z = 0;
+ f = f*16;
+
+ e1 = e2 = world;
+
+ traceline (p1, p2, FALSE, self);
+ if (trace_ent.takedamage)
+ {
+ particle (trace_endpos, '0 0 100', 225, damage*4);
+ T_Damage (trace_ent, from, from, damage);
+ if (self.classname == "player")
+ {
+ if (other.classname == "player")
+ trace_ent.velocity_z = trace_ent.velocity_z + 400;
+ }
+ }
+ e1 = trace_ent;
+
+ traceline (p1 + f, p2 + f, FALSE, self);
+ if (trace_ent != e1 && trace_ent.takedamage)
+ {
+ particle (trace_endpos, '0 0 100', 225, damage*4);
+ T_Damage (trace_ent, from, from, damage);
+ }
+ e2 = trace_ent;
+
+ traceline (p1 - f, p2 - f, FALSE, self);
+ if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
+ {
+ particle (trace_endpos, '0 0 100', 225, damage*4);
+ T_Damage (trace_ent, from, from, damage);
+ }
+};
+
+
+void() W_FireLightning =
+{
+ local vector org;
+ local float cells;
+
+ if (self.ammo_cells < 1)
+ {
+ self.weapon = W_BestWeapon ();
+ W_SetCurrentAmmo ();
+ return;
+ }
+
+// explode if under water
+ if (self.waterlevel > 1)
+ {
+ cells = self.ammo_cells;
+ self.ammo_cells = 0;
+ W_SetCurrentAmmo ();
+ T_RadiusDamage (self, self, 35*cells, world);
+ return;
+ }
+
+ if (self.t_width < time)
+ {
+ sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
+ self.t_width = time + 0.6;
+ }
+ self.punchangle_x = -2;
+
+ self.currentammo = self.ammo_cells = self.ammo_cells - 1;
+
+ org = self.origin + '0 0 16';
+
+ traceline (org, org + v_forward*600, TRUE, self);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
+ WriteEntity (MSG_BROADCAST, self);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
+ WriteCoord (MSG_BROADCAST, trace_endpos_x);
+ WriteCoord (MSG_BROADCAST, trace_endpos_y);
+ WriteCoord (MSG_BROADCAST, trace_endpos_z);
+
+ LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30);
+};
+
+
+//=============================================================================
+
+
+/*
+================
+GrenadeExplode2
+
+This is the same as the original GrenadeExplode function except that it
+will ignore the entity specified by the "ignore" parameter when dealing
+damage. -- iw
+================
+*/
+void(entity ignore) GrenadeExplode2 =
+{
+ T_RadiusDamage (self, self.owner, 120, ignore);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ BecomeExplosion ();
+};
+
+
+/*
+================
+GrenadeExplode
+
+Refactored. -- iw
+================
+*/
+void() GrenadeExplode =
+{
+ GrenadeExplode2 (world);
+};
+
+
+/*
+================
+GrenadeTouch
+
+This has been modified to fix a bug in the original code, which is that
+an entity with a very large bounding box (e.g. the size of monster_boss
+or monster_oldone) would receive little or no damage from a grenade
+impact. (In the original game, this bug didn't really matter because
+the largest DAMAGE_AIM entities were Shambler-sized.)
+
+In the original code, this function simply called GrenadeExplode, which
+called T_RadiusDamage, which deals an amount of damage based on the
+distance to the center of the victim's bounding box. Therefore, the
+larger the victim's bounding box, the lower the amount of damage that
+a grenade impact could deal.
+
+This modified version of GrenadeTouch adds a hack so that an entity
+which is larger than Shambler-size is treated differently: damage will
+be dealt to it using the same logic as a rocket impact, i.e. T_Damage
+will be called to deal damage to the impacted entity, and then radius
+damage will be dealt to any other entities in the vicinity. Grenades
+and rockets have always dealt the same amount of radius damage, so
+making the impact damage the same seemed a reasonable solution.
+
+The reason this logic is only used for very large entities is because
+I didn't want to affect the amount of damage that grenades deal to any
+of the original monsters under any circumstances. -- iw
+================
+*/
+void() GrenadeTouch =
+{
+ local float damg;
+
+ if (other == self.owner)
+ return; // don't explode on owner
+ if (other.takedamage == DAMAGE_AIM)
+ {
+ // see the explanation above -- iw
+ if (other.size_x > VEC_HULL2_SIZE_x ||
+ other.size_y > VEC_HULL2_SIZE_y ||
+ other.size_z > VEC_HULL2_SIZE_z)
+ {
+ // note that the logic for monster_shambler's partial immunity
+ // to explosions is not required because this is only for
+ // entities which are larger than monster_shambler -- iw
+ damg = 100 + random () * 20;
+ T_Damage (other, self, self.owner, damg);
+ GrenadeExplode2 (other);
+ return;
+ }
+ GrenadeExplode ();
+ return;
+ }
+ if (self.count < time) {
+ sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
+ }
+ self.count = time + .02;
+ if (self.velocity == '0 0 0')
+ self.avelocity = '0 0 0';
+};
+
+
+/*
+================
+W_FireGrenade
+================
+*/
+void() W_FireGrenade =
+{
+ local entity missile;
+
+ self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
+
+ sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+
+ self.punchangle_x = -2;
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "grenade";
+
+// set missile speed
+
+ makevectors (self.v_angle);
+
+ if (self.v_angle_x)
+ missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
+ else
+ {
+ missile.velocity = aim(self, 10000);
+ missile.velocity = missile.velocity * 600;
+ missile.velocity_z = 200;
+ }
+
+ missile.avelocity = '300 300 300';
+
+ missile.angles = vectoangles(missile.velocity);
+
+ missile.touch = GrenadeTouch;
+
+// set missile duration
+ missile.nextthink = time + 2.5;
+ missile.think = GrenadeExplode;
+
+ setmodel (missile, "progs/grenade.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin);
+};
+
+
+//=============================================================================
+
+void() spike_touch;
+void() superspike_touch;
+
+
+/*
+===============
+launch_spike
+
+Used for both the player and the ogre
+===============
+*/
+
+void(vector org, vector dir, float speed) launch_spike2 = {
+ newmis = spawn ();
+ newmis.owner = self;
+ newmis.movetype = MOVETYPE_FLYMISSILE;
+ newmis.solid = SOLID_BBOX;
+
+ newmis.angles = vectoangles(dir);
+
+ newmis.touch = spike_touch;
+ newmis.classname = "spike";
+ if (self.homing > 0)
+ {
+ SetupHoming(newmis, speed);
+ }
+ else
+ {
+ newmis.think = SUB_Remove;
+ newmis.nextthink = time + 6;
+ }
+ setmodel (newmis, "progs/spike.mdl");
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ setorigin (newmis, org);
+
+ SetSpeed(newmis, dir, speed * (self.proj_speed_mod ? self.proj_speed_mod : 1));
+};
+void(vector org, vector dir) launch_spike = {
+ launch_spike2(org,dir,1000);
+};
+
+void() W_FireSuperSpikes =
+{
+ local vector dir;
+
+ sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
+ self.attack_finished = time + 0.2;
+ self.currentammo = self.ammo_nails = self.ammo_nails - 2;
+ dir = aim (self, 1000);
+ launch_spike (self.origin + '0 0 16', dir);
+ newmis.touch = superspike_touch;
+ setmodel (newmis, "progs/s_spike.mdl");
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ self.punchangle_x = -2;
+};
+
+void(float ox) W_FireSpikes =
+{
+ local vector dir;
+
+ makevectors (self.v_angle);
+
+ if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
+ {
+ W_FireSuperSpikes ();
+ return;
+ }
+
+ if (self.ammo_nails < 1)
+ {
+ self.weapon = W_BestWeapon ();
+ W_SetCurrentAmmo ();
+ return;
+ }
+
+ sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
+ self.attack_finished = time + 0.2;
+ self.currentammo = self.ammo_nails = self.ammo_nails - 1;
+ dir = aim (self, 1000);
+ // launch_spike (self.origin + '0 0 16' + v_right*ox, dir);
+ launch_spike (self.origin + self.view_ofs + v_up * -8 + v_right*ox, dir); //seven Nailgun position fix - thanks to Greenwood -- dumptruck_ds
+
+ self.punchangle_x = -2;
+
+ };
+
+
+
+void() spike_touch =
+{
+ if (other == self.owner)
+ return;
+
+ if (other.solid == SOLID_TRIGGER)
+ return; // trigger field, do nothing
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove(self);
+ return;
+ }
+
+// hit something that bleeds
+ if (other.takedamage)
+ {
+ spawn_touchblood (9);
+ T_Damage (other, self, self.owner, 9);
+ }
+ else
+ {
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ if (self.owner.snd_hit)
+ {
+ sound (self, CHAN_WEAPON, self.owner.snd_hit, 1, ATTN_STATIC); //dumptruck_ds
+ WriteByte(MSG_BROADCAST, TE_GUNSHOT);
+ }
+
+ else if (self.classname == "wizspike")
+ WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
+ else if (self.classname == "knightspike")
+ WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
+ else
+ WriteByte (MSG_BROADCAST, TE_SPIKE);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+ }
+
+ remove(self);
+
+};
+
+void() superspike_touch =
+{
+ if (other == self.owner)
+ return;
+
+ if (other.solid == SOLID_TRIGGER)
+ return; // trigger field, do nothing
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove(self);
+ return;
+ }
+
+// hit something that bleeds
+ if (other.takedamage)
+ {
+ spawn_touchblood (18);
+ T_Damage (other, self, self.owner, 18);
+ }
+ else
+ {
+ if (self.owner.snd_hit)
+ {
+ sound (self, CHAN_WEAPON, self.owner.snd_hit, 1, ATTN_STATIC); //dumptruck_ds
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte(MSG_BROADCAST, TE_GUNSHOT);
+ }
+ else
+ {
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
+ }
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+ }
+
+ remove(self);
+
+};
+void() superduperspike_touch = //dumptruck_ds for Style 2 Ogre see ogre.qc
+{
+ if (other == self.owner)
+ return;
+
+ if (other.solid == SOLID_TRIGGER)
+ return; // trigger field, do nothing
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove(self);
+ return;
+ }
+
+// hit something that bleeds
+ if (other.takedamage)
+ {
+ spawn_touchblood (36);
+ T_Damage (other, self, self.owner, 36);
+ sound(self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
+ }
+ else
+ {
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+ }
+
+ remove(self);
+};
+
+/*
+===============================================================================
+
+PLAYER WEAPON USE
+
+===============================================================================
+*/
+
+void() W_SetCurrentAmmo =
+{
+ player_run (); // get out of any weapon firing states
+
+ self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) );
+
+ if (self.weapon == IT_AXE)
+ {
+ self.currentammo = 0;
+ self.weaponmodel = "progs/v_axe.mdl";
+ self.weaponframe = 0;
+ }
+ else if (self.weapon == IT_SHOTGUN)
+ {
+ self.currentammo = self.ammo_shells;
+ self.weaponmodel = "progs/v_shot.mdl";
+ self.weaponframe = 0;
+ self.items = self.items | IT_SHELLS;
+ }
+ else if (self.weapon == IT_SUPER_SHOTGUN)
+ {
+ self.currentammo = self.ammo_shells;
+ self.weaponmodel = "progs/v_shot2.mdl";
+ self.weaponframe = 0;
+ self.items = self.items | IT_SHELLS;
+ }
+ else if (self.weapon == IT_NAILGUN)
+ {
+ self.currentammo = self.ammo_nails;
+ self.weaponmodel = "progs/v_nail.mdl";
+ self.weaponframe = 0;
+ self.items = self.items | IT_NAILS;
+ }
+ else if (self.weapon == IT_SUPER_NAILGUN)
+ {
+ self.currentammo = self.ammo_nails;
+ self.weaponmodel = "progs/v_nail2.mdl";
+ self.weaponframe = 0;
+ self.items = self.items | IT_NAILS;
+ }
+ else if (self.weapon == IT_GRENADE_LAUNCHER)
+ {
+ self.currentammo = self.ammo_rockets;
+ self.weaponmodel = "progs/v_rock.mdl";
+ self.weaponframe = 0;
+ self.items = self.items | IT_ROCKETS;
+ }
+ else if (self.weapon == IT_ROCKET_LAUNCHER)
+ {
+ self.currentammo = self.ammo_rockets;
+ self.weaponmodel = "progs/v_rock2.mdl";
+ self.weaponframe = 0;
+ self.items = self.items | IT_ROCKETS;
+ }
+ else if (self.weapon == IT_LIGHTNING)
+ {
+ self.currentammo = self.ammo_cells;
+ self.weaponmodel = "progs/v_light.mdl";
+ self.weaponframe = 0;
+ self.items = self.items | IT_CELLS;
+ }
+ else
+ {
+ self.currentammo = 0;
+ self.weaponmodel = "";
+ self.weaponframe = 0;
+ }
+};
+
+float() W_BestWeapon =
+{
+ local float it;
+
+ it = self.items;
+
+ if (self.waterlevel <= 1 && self.ammo_cells >= 1 && (it & IT_LIGHTNING) )
+ return IT_LIGHTNING;
+ if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
+ return IT_SUPER_NAILGUN;
+ if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
+ return IT_SUPER_SHOTGUN;
+ if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
+ return IT_NAILGUN;
+ if(self.ammo_shells >= 1 && (it & IT_SHOTGUN) )
+ return IT_SHOTGUN;
+ return IT_AXE;
+};
+
+float() W_CheckNoAmmo =
+{
+ if (self.currentammo > 0)
+ return TRUE;
+
+ if (self.weapon == IT_AXE)
+ return TRUE;
+
+ self.weapon = W_BestWeapon ();
+
+ W_SetCurrentAmmo ();
+
+// drop the weapon down
+ return FALSE;
+};
+
+/*
+============
+W_Attack
+
+An attack impulse can be triggered now
+============
+*/
+void() player_axe1;
+void() player_axeb1;
+void() player_axec1;
+void() player_axed1;
+void() player_shot1;
+void() player_nail1;
+void() player_light1;
+void() player_rocket1;
+
+void() W_Attack =
+{
+ local float r;
+
+ if (!W_CheckNoAmmo ())
+ return;
+
+ makevectors (self.v_angle); // calculate forward angle for velocity
+ self.show_hostile = time + 1; // wake monsters up
+
+ if (self.weapon == IT_AXE)
+ {
+ sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
+ r = random();
+ if (r < 0.25)
+ player_axe1 ();
+ else if (r<0.5)
+ player_axeb1 ();
+ else if (r<0.75)
+ player_axec1 ();
+ else
+ player_axed1 ();
+ self.attack_finished = time + 0.5;
+ }
+ else if (self.weapon == IT_SHOTGUN)
+ {
+ player_shot1 ();
+ W_FireShotgun ();
+ self.attack_finished = time + 0.5;
+ }
+ else if (self.weapon == IT_SUPER_SHOTGUN)
+ {
+ player_shot1 ();
+ W_FireSuperShotgun ();
+ self.attack_finished = time + 0.7;
+ }
+ else if (self.weapon == IT_NAILGUN)
+ {
+ player_nail1 ();
+ }
+ else if (self.weapon == IT_SUPER_NAILGUN)
+ {
+ player_nail1 ();
+ }
+ else if (self.weapon == IT_GRENADE_LAUNCHER)
+ {
+ player_rocket1();
+ W_FireGrenade();
+ self.attack_finished = time + 0.6;
+ }
+ else if (self.weapon == IT_ROCKET_LAUNCHER)
+ {
+ player_rocket1();
+ W_FireRocket();
+ self.attack_finished = time + 0.8;
+ }
+ else if (self.weapon == IT_LIGHTNING)
+ {
+ player_light1();
+ self.attack_finished = time + 0.1;
+ sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
+ }
+};
+
+/*
+============
+W_ChangeWeapon
+
+============
+*/
+void() W_ChangeWeapon =
+{
+ local float it, am, fl;
+
+ it = self.items;
+ am = 0;
+
+ if (self.impulse == 1)
+ {
+ fl = IT_AXE;
+ }
+ else if (self.impulse == 2)
+ {
+ fl = IT_SHOTGUN;
+ if (self.ammo_shells < 1)
+ am = 1;
+ }
+ else if (self.impulse == 3)
+ {
+ fl = IT_SUPER_SHOTGUN;
+ if (self.ammo_shells < 2)
+ am = 1;
+ }
+ else if (self.impulse == 4)
+ {
+ fl = IT_NAILGUN;
+ if (self.ammo_nails < 1)
+ am = 1;
+ }
+ else if (self.impulse == 5)
+ {
+ fl = IT_SUPER_NAILGUN;
+ if (self.ammo_nails < 2)
+ am = 1;
+ }
+ else if (self.impulse == 6)
+ {
+ fl = IT_GRENADE_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ am = 1;
+ }
+ else if (self.impulse == 7)
+ {
+ fl = IT_ROCKET_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ am = 1;
+ }
+ else if (self.impulse == 8)
+ {
+ fl = IT_LIGHTNING;
+ if (self.ammo_cells < 1)
+ am = 1;
+ }
+ else
+ {
+ dprint ("WARNING: W_ChangeWeapon: bad impulse: ");
+ dprint (ftos (self.impulse));
+ dprint ("\n");
+ return;
+ }
+
+ self.impulse = 0;
+
+ if (!(self.items & fl))
+ { // don't have the weapon or the ammo
+ sprint (self, "no weapon.\n");
+ return;
+ }
+
+ if (am)
+ { // don't have the ammo
+ sprint (self, "not enough ammo.\n");
+ return;
+ }
+
+//
+// set weapon, set ammo
+//
+ self.weapon = fl;
+ W_SetCurrentAmmo ();
+};
+
+/*
+============
+CheatCommand
+============
+*/
+void() CheatCommand =
+{
+// 1998-07-29 Cheats coop fix by Maddes start
+// if (deathmatch || coop)
+ if (deathmatch)
+// 1998-07-29 Cheats coop fix by Maddes end
+ return;
+
+ self.ammo_rockets = 100;
+ self.ammo_nails = 200;
+ self.ammo_shells = 100;
+ self.items = self.items |
+ IT_AXE |
+ IT_SHOTGUN |
+ IT_SUPER_SHOTGUN |
+ IT_NAILGUN |
+ IT_SUPER_NAILGUN |
+ IT_GRENADE_LAUNCHER |
+ IT_ROCKET_LAUNCHER;
+ GiveAllKeys (self); // support for item_key_custom -- iw
+
+ self.ammo_cells = 200;
+ self.items = self.items | IT_LIGHTNING;
+
+ self.weapon = IT_ROCKET_LAUNCHER;
+ self.impulse = 0;
+ W_SetCurrentAmmo ();
+};
+
+/*
+============
+CycleWeaponCommand
+
+Go to the next weapon with ammo
+============
+*/
+void() CycleWeaponCommand =
+{
+ local float it, am;
+
+ it = self.items;
+ self.impulse = 0;
+
+ while (1)
+ {
+ am = 0;
+
+ if (self.weapon == IT_LIGHTNING)
+ {
+ self.weapon = IT_AXE;
+ }
+ else if (self.weapon == IT_AXE)
+ {
+ self.weapon = IT_SHOTGUN;
+ if (self.ammo_shells < 1)
+ am = 1;
+ }
+ else if (self.weapon == IT_SHOTGUN)
+ {
+ self.weapon = IT_SUPER_SHOTGUN;
+ if (self.ammo_shells < 2)
+ am = 1;
+ }
+ else if (self.weapon == IT_SUPER_SHOTGUN)
+ {
+ self.weapon = IT_NAILGUN;
+ if (self.ammo_nails < 1)
+ am = 1;
+ }
+ else if (self.weapon == IT_NAILGUN)
+ {
+ self.weapon = IT_SUPER_NAILGUN;
+ if (self.ammo_nails < 2)
+ am = 1;
+ }
+ else if (self.weapon == IT_SUPER_NAILGUN)
+ {
+ self.weapon = IT_GRENADE_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ am = 1;
+ }
+ else if (self.weapon == IT_GRENADE_LAUNCHER)
+ {
+ self.weapon = IT_ROCKET_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ am = 1;
+ }
+ else if (self.weapon == IT_ROCKET_LAUNCHER)
+ {
+ self.weapon = IT_LIGHTNING;
+ if (self.ammo_cells < 1)
+ am = 1;
+ }
+
+ if ( (it & self.weapon) && am == 0)
+ {
+ W_SetCurrentAmmo ();
+ return;
+ }
+ }
+
+};
+
+/*
+============
+CycleWeaponReverseCommand
+
+Go to the prev weapon with ammo
+============
+*/
+void() CycleWeaponReverseCommand =
+{
+ local float it, am;
+
+ it = self.items;
+ self.impulse = 0;
+
+ while (1)
+ {
+ am = 0;
+
+ if (self.weapon == IT_LIGHTNING)
+ {
+ self.weapon = IT_ROCKET_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ am = 1;
+ }
+ else if (self.weapon == IT_ROCKET_LAUNCHER)
+ {
+ self.weapon = IT_GRENADE_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ am = 1;
+ }
+ else if (self.weapon == IT_GRENADE_LAUNCHER)
+ {
+ self.weapon = IT_SUPER_NAILGUN;
+ if (self.ammo_nails < 2)
+ am = 1;
+ }
+ else if (self.weapon == IT_SUPER_NAILGUN)
+ {
+ self.weapon = IT_NAILGUN;
+ if (self.ammo_nails < 1)
+ am = 1;
+ }
+ else if (self.weapon == IT_NAILGUN)
+ {
+ self.weapon = IT_SUPER_SHOTGUN;
+ if (self.ammo_shells < 2)
+ am = 1;
+ }
+ else if (self.weapon == IT_SUPER_SHOTGUN)
+ {
+ self.weapon = IT_SHOTGUN;
+ if (self.ammo_shells < 1)
+ am = 1;
+ }
+ else if (self.weapon == IT_SHOTGUN)
+ {
+ self.weapon = IT_AXE;
+ }
+ else if (self.weapon == IT_AXE)
+ {
+ self.weapon = IT_LIGHTNING;
+ if (self.ammo_cells < 1)
+ am = 1;
+ }
+
+ if ( (it & self.weapon) && am == 0)
+ {
+ W_SetCurrentAmmo ();
+ return;
+ }
+ }
+
+};
+
+/*
+============
+ServerflagsCommand
+
+Just for development
+============
+*/
+void() ServerflagsCommand =
+{
+// 1998-07-29 Cheats coop fix by Maddes start
+ if (deathmatch)
+ return;
+// 1998-07-29 Cheats coop fix by Maddes end
+ serverflags = serverflags * 2 + 1;
+};
+
+void() QuadCheat =
+{
+// 1998-07-29 Cheats coop fix by Maddes start
+// if (deathmatch || coop)
+ if (deathmatch)
+// 1998-07-29 Cheats coop fix by Maddes end
+ return;
+ self.super_time = 1;
+ self.super_damage_finished = time + 30;
+ self.items = self.items | IT_QUAD;
+ dprint ("quad cheat\n");
+};
+
+/*
+============
+ImpulseCommands
+
+============
+*/
+void() ImpulseCommands =
+{
+ if (self.impulse >= 1 && self.impulse <= 8)
+ W_ChangeWeapon ();
+
+ if (self.impulse == 9)
+ CheatCommand ();
+ if (self.impulse == 10)
+ CycleWeaponCommand ();
+ if (self.impulse == 11)
+ ServerflagsCommand ();
+ if (self.impulse == 12)
+ CycleWeaponReverseCommand ();
+
+ if (self.impulse == 255)
+ QuadCheat ();
+// dumptruck_ds version inspired by Copper
+ if (self.impulse == 100)
+ sprint(self, version);
+
+ // if (self.impulse == 101) // debugging armor shards -- dumptruck_ds
+ // dprint ("Armortype is");
+ // dprint (ftos(self.armortype));
+ // dprint ("\n");
+
+ self.impulse = 0;
+};
+
+/*
+============
+W_WeaponFrame
+
+Called every frame so impulse events can be handled as well as possible
+============
+*/
+void() W_WeaponFrame =
+{
+ if (time < self.attack_finished)
+ return;
+
+if (self.impulse) // 1998-08-14 Constantly checking all impulses fix by Perged
+ ImpulseCommands ();
+
+// check for attack
+ if (self.button0)
+ {
+ SuperDamageSound ();
+ W_Attack ();
+ }
+};
+
+/*
+========
+SuperDamageSound
+
+Plays sound if needed
+========
+*/
+void() SuperDamageSound =
+{
+ if (self.super_damage_finished > time)
+ {
+ if (self.super_sound < time)
+ {
+ self.super_sound = time + 1;
+ sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
+ }
+ }
+ return;
+};
+
+void() MissileHome =
+{
+ local vector dir, vtemp;
+ vtemp = self.enemy.origin + '0 0 10';
+
+ if (self.enemy.health < 1)
+ {
+ remove(self);
+ return;
+ }
+ dir = normalize(vtemp - self.origin);
+ if (self.homing < 1 && self.homing > 0) // can't do better than 100% homing
+ {
+ /*
+ This finds a vector somewhere between the vector the projectile is currently
+ travelling on and the vector that it would normally snap to for homing
+
+ homing = .25 means it will go 25% to the new direction, but keep 75% of the
+ original vector, resulting in a wider turning range.
+ */
+ dir = normalize((dir * self.homing) + normalize(self.velocity * (1 - self.homing)));
+ }
+ if (!self.avelocity)
+ self.angles = vectoangles(dir);
+ SetSpeed(self, dir, self.proj_basespeed);
+
+ if (self.homing > 0)
+ {
+ if (self.homing < 1 && self.attack_finished && self.attack_finished < time )
+ {
+ //dprint("incrementing homing | ");
+ //dprint("old: ");
+ //dprint(ftos(self.homing));
+ //dprint(" | new: ");
+ self.homing = self.homing + 0.005;
+ //dprint(ftos(self.homing));
+ //dprint("\n");
+ }
+ self.nextthink = time + 0.2;
+ self.think = MissileHome;
+ }
+};
+
+void(entity mis, float speed) SetupHoming =
+{
+ local vector dir;
+ local float dist, flytime, speedmod;
+ if (self.proj_speed_mod > 1)
+ {
+ speedmod = 1/self.proj_speed_mod;
+ }
+ else if (speed > 250)
+ {
+ speedmod = 1 / (speed / 250);
+ }
+ else
+ {
+ speedmod = 1;
+ }
+ dir = normalize((self.enemy.origin + '0 0 10') - self.origin);
+ dist = vlen (self.enemy.origin - self.origin);
+ flytime = dist * 0.002 * speedmod;
+ if (flytime < 0.1)
+ flytime = 0.1;
+
+ mis.enemy = self.enemy;
+ mis.proj_basespeed = speed;
+ mis.homing = self.homing;
+ mis.nextthink = flytime + time;
+ mis.think = MissileHome;
+ if (self.waitmin > 0)
+ {
+ mis.attack_finished = time + self.waitmin; // store time to start increasing
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/world.qc

diff --git a/qc/world.qc b/qc/world.qc
new file mode 100644
index 0000000..84555aa
--- /dev/null
+++ b/qc/world.qc
@@ -0,0 +1,621 @@
+
+void() InitBodyQue;
+
+
+void() main =
+{
+ dprint ("main function\n");
+
+// these are just commands the the prog compiler to copy these files
+
+ precache_file ("progs.dat");
+ precache_file ("gfx.wad");
+ precache_file ("quake.rc");
+ precache_file ("default.cfg");
+
+ precache_file ("end1.bin");
+ precache_file2 ("end2.bin");
+
+ precache_file ("demo1.dem");
+ precache_file ("demo2.dem");
+ precache_file ("demo3.dem");
+
+//
+// these are all of the lumps from the cached.ls files
+//
+ precache_file ("gfx/palette.lmp");
+ precache_file ("gfx/colormap.lmp");
+
+ precache_file2 ("gfx/pop.lmp");
+
+ precache_file ("gfx/complete.lmp");
+ precache_file ("gfx/inter.lmp");
+
+ precache_file ("gfx/ranking.lmp");
+ precache_file ("gfx/vidmodes.lmp");
+ precache_file ("gfx/finale.lmp");
+ precache_file ("gfx/conback.lmp");
+ precache_file ("gfx/qplaque.lmp");
+
+ precache_file ("gfx/menudot1.lmp");
+ precache_file ("gfx/menudot2.lmp");
+ precache_file ("gfx/menudot3.lmp");
+ precache_file ("gfx/menudot4.lmp");
+ precache_file ("gfx/menudot5.lmp");
+ precache_file ("gfx/menudot6.lmp");
+
+ precache_file ("gfx/menuplyr.lmp");
+ precache_file ("gfx/bigbox.lmp");
+ precache_file ("gfx/dim_modm.lmp");
+ precache_file ("gfx/dim_drct.lmp");
+ precache_file ("gfx/dim_ipx.lmp");
+ precache_file ("gfx/dim_tcp.lmp");
+ precache_file ("gfx/dim_mult.lmp");
+ precache_file ("gfx/mainmenu.lmp");
+
+ precache_file ("gfx/box_tl.lmp");
+ precache_file ("gfx/box_tm.lmp");
+ precache_file ("gfx/box_tr.lmp");
+
+ precache_file ("gfx/box_ml.lmp");
+ precache_file ("gfx/box_mm.lmp");
+ precache_file ("gfx/box_mm2.lmp");
+ precache_file ("gfx/box_mr.lmp");
+
+ precache_file ("gfx/box_bl.lmp");
+ precache_file ("gfx/box_bm.lmp");
+ precache_file ("gfx/box_br.lmp");
+
+ precache_file ("gfx/sp_menu.lmp");
+ precache_file ("gfx/ttl_sgl.lmp");
+ precache_file ("gfx/ttl_main.lmp");
+ precache_file ("gfx/ttl_cstm.lmp");
+
+ precache_file ("gfx/mp_menu.lmp");
+
+ precache_file ("gfx/netmen1.lmp");
+ precache_file ("gfx/netmen2.lmp");
+ precache_file ("gfx/netmen3.lmp");
+ precache_file ("gfx/netmen4.lmp");
+ precache_file ("gfx/netmen5.lmp");
+
+ precache_file ("gfx/sell.lmp");
+
+ precache_file ("gfx/help0.lmp");
+ precache_file ("gfx/help1.lmp");
+ precache_file ("gfx/help2.lmp");
+ precache_file ("gfx/help3.lmp");
+ precache_file ("gfx/help4.lmp");
+ precache_file ("gfx/help5.lmp");
+
+ precache_file ("gfx/pause.lmp");
+ precache_file ("gfx/loading.lmp");
+
+ precache_file ("gfx/p_option.lmp");
+ precache_file ("gfx/p_load.lmp");
+ precache_file ("gfx/p_save.lmp");
+ precache_file ("gfx/p_multi.lmp");
+
+// sounds loaded by C code
+ precache_sound ("misc/menu1.wav");
+ precache_sound ("misc/menu2.wav");
+ precache_sound ("misc/menu3.wav");
+
+ precache_sound ("ambience/water1.wav");
+ precache_sound ("ambience/wind2.wav");
+
+// shareware
+ precache_file ("maps/start.bsp");
+
+ precache_file ("maps/e1m1.bsp");
+ precache_file ("maps/e1m2.bsp");
+ precache_file ("maps/e1m3.bsp");
+ precache_file ("maps/e1m4.bsp");
+ precache_file ("maps/e1m5.bsp");
+ precache_file ("maps/e1m6.bsp");
+ precache_file ("maps/e1m7.bsp");
+ precache_file ("maps/e1m8.bsp");
+
+// registered
+ precache_file2 ("gfx/pop.lmp");
+
+ precache_file2 ("maps/e2m1.bsp");
+ precache_file2 ("maps/e2m2.bsp");
+ precache_file2 ("maps/e2m3.bsp");
+ precache_file2 ("maps/e2m4.bsp");
+ precache_file2 ("maps/e2m5.bsp");
+ precache_file2 ("maps/e2m6.bsp");
+ precache_file2 ("maps/e2m7.bsp");
+
+ precache_file2 ("maps/e3m1.bsp");
+ precache_file2 ("maps/e3m2.bsp");
+ precache_file2 ("maps/e3m3.bsp");
+ precache_file2 ("maps/e3m4.bsp");
+ precache_file2 ("maps/e3m5.bsp");
+ precache_file2 ("maps/e3m6.bsp");
+ precache_file2 ("maps/e3m7.bsp");
+
+ precache_file2 ("maps/e4m1.bsp");
+ precache_file2 ("maps/e4m2.bsp");
+ precache_file2 ("maps/e4m3.bsp");
+ precache_file2 ("maps/e4m4.bsp");
+ precache_file2 ("maps/e4m5.bsp");
+ precache_file2 ("maps/e4m6.bsp");
+ precache_file2 ("maps/e4m7.bsp");
+ precache_file2 ("maps/e4m8.bsp");
+
+ precache_file2 ("maps/end.bsp");
+
+ precache_file2 ("maps/dm1.bsp");
+ precache_file2 ("maps/dm2.bsp");
+ precache_file2 ("maps/dm3.bsp");
+ precache_file2 ("maps/dm4.bsp");
+ precache_file2 ("maps/dm5.bsp");
+ precache_file2 ("maps/dm6.bsp");
+};
+
+
+/*
+================
+DetectKnownRelease
+
+This detects whether the current map is from a known release for which
+a backwards-compatibility hack should be applied, and sets the
+known_release global accordingly. -- iw
+================
+*/
+void() DetectKnownRelease =
+{
+ local string release_name;
+
+ known_release = KNOWN_RELEASE_NOT;
+ release_name = "";
+
+ if (mapname == "dm1" ||
+ mapname == "dm2" ||
+ mapname == "dm3" ||
+ mapname == "dm4" ||
+ mapname == "dm5" ||
+ mapname == "dm6" ||
+ mapname == "e1m1" ||
+ mapname == "e1m2" ||
+ mapname == "e1m3" ||
+ mapname == "e1m4" ||
+ mapname == "e1m5" ||
+ mapname == "e1m6" ||
+ mapname == "e1m7" ||
+ mapname == "e1m8" ||
+ mapname == "e2m1" ||
+ mapname == "e2m2" ||
+ mapname == "e2m3" ||
+ mapname == "e2m4" ||
+ mapname == "e2m5" ||
+ mapname == "e2m6" ||
+ mapname == "e2m7" ||
+ mapname == "e3m1" ||
+ mapname == "e3m2" ||
+ mapname == "e3m3" ||
+ mapname == "e3m4" ||
+ mapname == "e3m5" ||
+ mapname == "e3m6" ||
+ mapname == "e3m7" ||
+ mapname == "e4m1" ||
+ mapname == "e4m2" ||
+ mapname == "e4m3" ||
+ mapname == "e4m4" ||
+ mapname == "e4m5" ||
+ mapname == "e4m6" ||
+ mapname == "e4m7" ||
+ mapname == "e4m8" ||
+ mapname == "end" ||
+ (mapname == "start" && world.message == "Introduction"))
+ {
+ known_release = KNOWN_RELEASE_ID1;
+ release_name = "id1";
+ }
+
+ if (mapname == "jamx_artistical" ||
+ mapname == "jamx_bloodshot" ||
+ mapname == "jamx_fw" ||
+ mapname == "jamx_hcm" ||
+ mapname == "jamx_ionous" ||
+ mapname == "jamx_jcr" ||
+ mapname == "jamx_kalebclark" ||
+ mapname == "jamx_mafon" ||
+ //mapname == "jamx_mugwump" || // dummy map
+ mapname == "jamx_naitelveni" ||
+ mapname == "jamx_newhouse" ||
+ mapname == "jamx_pinchy" ||
+ mapname == "jamx_strwrk" ||
+ mapname == "jamx_ukko" ||
+ mapname == "jamx_yoder" ||
+ (mapname == "start" && world.message == "An Unending Dusk"))
+ {
+ known_release = KNOWN_RELEASE_FUNC_MAPJAMX;
+ release_name = "func_mapjamx";
+ }
+
+ if (release_name != "")
+ {
+ dprint ("WARNING: progs.dat detected a map from ");
+ dprint (release_name);
+ dprint (", attempting to behave compatibly\n");
+ }
+};
+
+
+entity lastspawn;
+
+//=======================
+/*QUAKED worldspawn (0 0 0) ?
+Only used for the world entity.
+
+Optionally set reset_items to one of the following values:
+0: don't reset the player's inventory
+1: reset to shotgun, axe, and 25 shells
+2: reset to axe only
+
+message(string) : "Level name"
+
+worldtype(choices) : "Ambience" : 0 =
+0 : "Medieval"
+1 : "Runic (metal)"
+2 : "Present (base)"
+
+sounds(integer) : "CD track to play" : 0
+
+light(integer) : "Ambient light" : 0 : "Set a global minimum light level of 'n' across the whole map. This is an easy way to eliminate completely dark areas of the level, however you may lose some contrast as a result, so use with care. Default 0"
+
+reset_items(choices) : "Reset the player's inventory on spawn" : 0 =
+0 "Don't reset the player's inventory"
+1 "Reset to shotgun, axe, and 25 shells"
+2 "Reset to axe only"
+
+_sunlight(integer) : "Sunlight" : 0 : "Set the brightness of the sunlight coming from an unseen sun in the sky. Sky brushes (or more accurately bsp leafs with sky contents) will emit sunlight at an angle specified by the _sun_mangle key. Default 0"
+
+_sun_mangle(string) : "Sun mangle (Yaw pitch roll)" : "0 -90 0" : "Specifies the direction of sunlight using yaw(x), pitch(y) and roll(z) in degrees. Yaw specifies the angle around the Z-axis from 0 to 359 degrees and pitch specifies the angle from 90 (straight up) to -90 (straight down). Roll has no effect, so use any value (e.g. 0). Default is straight down (0 -90 0)"
+
+_sunlight_penumbra(integer) : "Sunlight penumbra in degrees" : 0 : "Specifies the penumbra width, in degrees, of sunlight. Useful values are 3-4 for a gentle soft edge, or 10-20+ for more diffuse sunlight. Default is 0"
+
+_sunlight_color(color255) : "Sunlight color R G B" : "255 255 255" : "Specify red(r), green(g) and blue(b) components for the colour of the sunlight. RGB component values are between 0 and 255 (between 0 and 1 is also accepted). Default is white light (255 255 255)"
+
+_sunlight2(integer) : "Sunlight 2 brightness" : 0 : "Set the brightness of a large dome of lights positioned around the map (16K unit radius). Useful for simulating higly diffused light (e.g. cloudy skies) in outdoor areas. Default 0"
+
+_sunlight2_color(color255) : "Sunlight 2 color R G B" : "255 255 255" : "Specifies the colour of _sunlight2, same format as _sunlight_color. Default is white light (255 255 255)"
+
+_sunlight3(integer) : "Sunlight 3 brightness" : 0 : "Same as _sunlight2 but creates lights on the bottom hemisphere. Default 0"
+
+_sunlight3_color(color255) : "Sunlight 3 color R G B" : "255 255 255" : "Specifies the colour of _sunlight3, same format as _sunlight_color. Default is white light (255 255 255)"
+
+_dist(integer) : "Global light scale" : 1 : "Scales the fade distance of all lights by a factor of n. If n is more than 1 lights fade more quickly with distance and if n is less than 1, lights fade more slowly with distance and light reaches further"
+
+_range(float) : "Global light range" : "0.5" : "Scales the brightness range of all lights without affecting their fade discance. Values of n more than 0.5 makes lights brighter and n less than 0.5 makes lights less bright. The same effect can be achieved on individual lights by adjusting both the 'light' and 'wait' attributes"
+
+_anglescale(float) : "Light angle scale" : "0.5" : "Sets a scaling factor for how much influence the angle of incidence of sunlight on a surface has on the brightness of the surface. n must be between 0.0 and 1.0. Smaller values mean less attenuation, with zero meaning that angle of incidence has no effect at all on the brightness. Default 0.5"
+
+_dirt(integer) : "Dirt mapping (AO)" : -1 : "1 enables dirtmapping (ambient occlusion) on all lights, borrowed from q3map2. This adds shadows to corners and crevices. You can override the global setting for specific lights with the _dirt light entity key or _sunlight_dirt, _sunlight2_dirt, and _minlight_dirt worldspawn keys. Default is no dirtmapping (-1)"
+
+_sunlight_dirt(integer) : "Sunlight dirt" : -1 : "1 enables dirtmapping (ambient occlusion) on sunlight, -1 to disable (making it illuminate the dirtmapping shadows). Default is to use the value of '_dirt'"
+
+_sunlight2_dirt(integer) : "Sublight 2 dirt" : -1 : "1 enables dirtmapping (ambient occlusion) on sunlight2, -1 to disable. Default is to use the value of '_dirt'"
+
+_minlight_dirt(integer) : "Minlight dirt" : -1 : "1 enables dirtmapping (ambient occlusion) on minlight, -1 to disable. Default is to use the value of '_dirt'"
+
+_dirtmode(integer) : "Dirt mode" : 0 : "Choose between ordered (0, default) and randomized (1) dirtmapping."
+
+_dirtdepth(integer) : "Dirt depth" : 128 : "Maximum depth of occlusion checking for dirtmapping, default 128."
+
+_dirtscale(integer) : "Dirt scale" : 1 : "Scale factor used in dirt calculations, default 1. Lower values (e.g. 0.5) make the dirt fainter, 2.0 would create much darker shadows"
+
+_dirtgain(integer) : "Dirt gain" : 1 : "Exponent used in dirt calculation, default 1. Lower values (e.g. 0.5) make the shadows darker and stretch further away from corners"
+
+_gamma(integer) : "Lightmap gamma" : 1 : "Adjust brightness of final lightmap. Default 1, >1 is brighter, <1 is darker"
+
+fog(string) : "Fog Command" : : "ENGINE only 'console command' for setting fog parameters, Density/R/G/B example = (0.05 0.3 0.3 0.3)."
+
+fog_density(string) : "Fog Density example = (0.05)"
+
+fog_color(string) : "Fog Color R/G/B example = (0.3 0.3 0.3)"
+
+sky(string) : "Sky Texture" : : "Must have compatible skybox textures in gfx/env folder."
+*/
+//=======================
+void() worldspawn =
+{
+ DetectKnownRelease ();
+
+ InitNewSpawnflags (); // new spawnflags for all entities -- iw
+
+ lastspawn = world;
+
+ if (cvar("pr_checkextension"))
+ {
+ clientstat (CLIENT_VELOCITY_X, EV_FLOAT, velocity_x);
+ clientstat (CLIENT_VELOCITY_Y, EV_FLOAT, velocity_y);
+ }
+
+ InitBodyQue ();
+
+// custom map attributes
+ if (self.model == "maps/e1m8.bsp" && self.skip_id1_overrides == 0)
+ cvar_set ("sv_gravity", "100");
+ else
+ cvar_set ("sv_gravity", "800");
+
+ cutscene = 0; // No cutscene is active during worldspawn. Drake -- dumptruck_ds
+
+ world_sounds = &world.sounds; //Spike via dumptruck_ds || not read-only yet...
+
+// the area based ambient sounds MUST be the first precache_sounds
+
+// player precaches
+ W_Precache (); // get weapon precaches
+
+// sounds used from C physics code
+ precache_sound_land ("demon/dland2.wav"); // landing thud
+ precache_sound ("misc/h2ohit1.wav"); // landing splash
+
+// setup precaches always needed
+ precache_sound ("items/itembk2.wav"); // item respawn sound
+ precache_sound ("player/plyrjmp8.wav"); // player jump
+ precache_sound ("player/land.wav"); // player landing
+ precache_sound ("player/land2.wav"); // player hurt landing
+ precache_sound ("player/drown1.wav"); // drowning pain
+ precache_sound ("player/drown2.wav"); // drowning pain
+ precache_sound ("player/gasp1.wav"); // gasping for air
+ precache_sound ("player/gasp2.wav"); // taking breath
+ precache_sound ("player/h2odeath.wav"); // drowning death
+
+ precache_sound ("misc/talk.wav"); // talk
+ precache_sound ("player/teledth1.wav"); // telefrag
+ precache_sound ("misc/r_tele1.wav"); // teleport sounds
+ precache_sound ("misc/r_tele2.wav");
+ precache_sound ("misc/r_tele3.wav");
+ precache_sound ("misc/r_tele4.wav");
+ precache_sound ("misc/r_tele5.wav");
+ precache_sound ("weapons/lock4.wav"); // ammo pick up
+ precache_sound ("weapons/pkup.wav"); // weapon up
+ precache_sound ("items/armor1.wav"); // armor up
+ precache_sound ("weapons/lhit.wav"); //lightning
+ precache_sound ("weapons/lstart.wav"); //lightning start
+
+ // iw -- fix powerup cheat sounds // noticed this in Copper so why not? --ds
+ // sounds used by cheats
+ precache_sound ("items/suit2.wav"); // suit (finish)
+ precache_sound ("items/protect2.wav"); // pent (finish)
+ precache_sound ("items/protect3.wav"); // pent (protect)
+ precache_sound ("items/inv2.wav"); // ring (finish)
+ precache_sound ("items/inv3.wav"); // ring (idle)
+ precache_sound ("items/damage2.wav"); // quad (finish)
+ precache_sound ("items/damage3.wav"); // quad (attack)
+ // iw -- END
+
+ precache_sound ("misc/power.wav"); //lightning for boss
+
+// player gib sounds
+ precache_sound ("player/gib.wav"); // player gib sound
+ precache_sound ("player/udeath.wav"); // player gib sound
+ precache_sound ("player/tornoff2.wav"); // gib sound
+
+// player pain sounds
+
+ precache_sound ("player/pain1.wav");
+ precache_sound ("player/pain2.wav");
+ precache_sound ("player/pain3.wav");
+ precache_sound ("player/pain4.wav");
+ precache_sound ("player/pain5.wav");
+ precache_sound ("player/pain6.wav");
+
+// player death sounds
+ precache_sound ("player/death1.wav");
+ precache_sound ("player/death2.wav");
+ precache_sound ("player/death3.wav");
+ precache_sound ("player/death4.wav");
+ precache_sound ("player/death5.wav");
+
+// ax sounds
+ precache_sound ("weapons/ax1.wav"); // ax swoosh
+ precache_sound ("player/axhit1.wav"); // ax hit meat
+ precache_sound ("player/axhit2.wav"); // ax hit world
+
+ precache_sound ("player/h2ojump.wav"); // player jumping into water
+ precache_sound ("player/slimbrn2.wav"); // player enter slime
+ precache_sound ("player/inh2o.wav"); // player enter water
+ precache_sound ("player/inlava.wav"); // player enter lava
+ precache_sound ("misc/outwater.wav"); // leaving water sound
+
+ precache_sound ("player/lburn1.wav"); // lava burn
+ precache_sound ("player/lburn2.wav"); // lava burn
+
+ precache_sound ("misc/water1.wav"); // swimming
+ precache_sound ("misc/water2.wav"); // swimming
+
+ precache_model ("progs/player.mdl");
+ precache_model ("progs/s_null.spr"); // Invisible -- Drake -- dumptruck_ds
+ // precache_model ("progs/null_256.spr"); // Invisible -- Drake -- dumptruck_ds
+ precache_model ("progs/eyes.mdl");
+ precache_model ("progs/h_player.mdl");
+ precache_model ("progs/gib1.mdl");
+ precache_model ("progs/gib2.mdl");
+ precache_model ("progs/gib3.mdl");
+
+ precache_model ("progs/s_bubble.spr"); // drowning bubbles
+ precache_model ("progs/s_explod.spr"); // sprite explosion
+
+ precache_model ("progs/v_axe.mdl");
+ precache_model ("progs/v_shot.mdl");
+ precache_model ("progs/v_nail.mdl");
+ precache_model ("progs/v_rock.mdl");
+ precache_model ("progs/v_shot2.mdl");
+ precache_model ("progs/v_nail2.mdl");
+ precache_model ("progs/v_rock2.mdl");
+
+ precache_model ("progs/bolt.mdl"); // for lightning gun
+ precache_model ("progs/bolt2.mdl"); // for lightning gun
+ precache_model ("progs/bolt3.mdl"); // for boss shock
+ precache_model ("progs/lavaball.mdl"); // for testing
+
+ precache_model ("progs/missile.mdl");
+ precache_model ("progs/grenade.mdl");
+ precache_model ("progs/spike.mdl");
+ // dumptruck_ds added w_spike due to errors
+ // with custom_mdls in precache_proj_model in wizard.qc
+ // precache_model ("progs/w_spike.mdl");
+ // this is on hold for now head and body are working
+ precache_model ("progs/s_spike.mdl");
+
+ precache_model ("progs/backpack.mdl");
+
+ precache_model ("progs/zom_gib.mdl");
+
+ precache_model ("progs/v_light.mdl");
+
+ precache_model ("progs/w_s_key.mdl"); // dumptruck_ds needed for DropStuff
+ precache_model ("progs/w_g_key.mdl"); //
+ precache_sound ("misc/medkey.wav");
+ precache_sound ("misc/runekey.wav");
+ precache_model ("progs/m_s_key.mdl");
+ precache_model ("progs/m_g_key.mdl");
+ precache_sound2 ("misc/basekey.wav");
+ precache_model2 ("progs/b_s_key.mdl");
+ precache_model2 ("progs/b_g_key.mdl");
+ precache_model ("progs/h_mdls/pd_vial.mdl"); // DropVial -- dumptruck_ds
+ precache_sound ("items/r_item1.wav");
+ precache_sound ("dump/armsh1.wav"); // DropShard -- dumptruck_ds
+ precache_model ("progs/armshr.mdl");
+
+//
+// Setup light animation tables. 'a' is total darkness, 'z' is maxbright.
+//
+
+ // 0 normal
+ lightstyle(0, "m");
+
+ // 1 FLICKER (first variety)
+ lightstyle(1, "mmnmmommommnonmmonqnmmo");
+
+ // 2 SLOW STRONG PULSE
+ lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
+
+ // 3 CANDLE (first variety)
+ lightstyle(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");
+
+ // 4 FAST STROBE
+ lightstyle(4, "mamamamamama");
+
+ // 5 GENTLE PULSE 1
+ lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");
+
+ // 6 FLICKER (second variety)
+ lightstyle(6, "nmonqnmomnmomomno");
+
+ // 7 CANDLE (second variety)
+ lightstyle(7, "mmmaaaabcdefgmmmmaaaammmaamm");
+
+ // 8 CANDLE (third variety)
+ lightstyle(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");
+
+ // 9 SLOW STROBE (fourth variety)
+ lightstyle(9, "aaaaaaaazzzzzzzz");
+
+ // 10 FLUORESCENT FLICKER
+ lightstyle(10, "mmamammmmammamamaaamammma");
+
+ // 11 SLOW PULSE NOT FADE TO BLACK
+ lightstyle(11, "abcdefghijklmnopqrrqponmlkjihgfedcba");
+
+ // styles 32-62 are assigned by the light program for switchable lights
+
+ // 63 testing
+ lightstyle(63, "a");
+};
+
+void() RestartLoopSounds_think = {
+ sound(self, self.impulse, self.noise, self.volume, self.speed);
+};
+
+void() RestartLoopSounds = {
+ entity e;
+ e = find(world, classname, "play_sound_triggered");
+ while (e) {
+
+ if (e.spawnflags & 3 == 3) { // both "toggle" and "looped" need to be set
+ if (e.state == 1) {
+ e.nextthink = time + 0.1;
+ e.think = RestartLoopSounds_think;
+ }
+ }
+
+ e = find(e, classname, "play_sound_triggered");
+ }
+};
+
+
+void() StartFrame =
+{
+ if (!done_inhibition_summary) // new spawnflags for all entities -- iw
+ PrintInhibitionSummary ();
+
+ teamplay = cvar("teamplay");
+ skill = cvar("skill");
+ framecount = framecount + 1;
+
+ if (cleanUpClientStuff) {
+ cleanUpClientStuff -= 1;
+
+ RestartLoopSounds();
+ }
+ else if (!gamestarted && framecount > 2)
+ {
+ if (framecount != 3)
+ cleanUpClientStuff += 2;
+
+ gamestarted = TRUE;
+ }
+};
+
+/*
+==============================================================================
+
+BODY QUE
+
+==============================================================================
+*/
+
+entity bodyque_head;
+
+void() bodyque =
+{ // just here so spawn functions don't complain after the world
+ // creates bodyques
+};
+
+void() InitBodyQue =
+{
+ bodyque_head = spawn();
+ bodyque_head.classname = "bodyque";
+ bodyque_head.owner = spawn();
+ bodyque_head.owner.classname = "bodyque";
+ bodyque_head.owner.owner = spawn();
+ bodyque_head.owner.owner.classname = "bodyque";
+ bodyque_head.owner.owner.owner = spawn();
+ bodyque_head.owner.owner.owner.classname = "bodyque";
+ bodyque_head.owner.owner.owner.owner = bodyque_head;
+};
+
+
+// make a body que entry for the given ent so the ent can be
+// respawned elsewhere
+void(entity ent) CopyToBodyQue =
+{
+ bodyque_head.angles = ent.angles;
+ bodyque_head.model = ent.model;
+ bodyque_head.modelindex = ent.modelindex;
+ bodyque_head.frame = ent.frame;
+ bodyque_head.colormap = ent.colormap;
+ bodyque_head.movetype = ent.movetype;
+ bodyque_head.velocity = ent.velocity;
+ bodyque_head.flags = 0;
+ setorigin (bodyque_head, ent.origin);
+ setsize (bodyque_head, ent.mins, ent.maxs);
+ bodyque_head = bodyque_head.owner;
+};

Return to the top of this page or return to the overview of this repo.