12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544 |
- /* Copyright (C) 1996-2022 id Software LLC
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- See file, 'COPYING', for details.
- */
- 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() HasteSound;
- // called by worldspawn
- void() W_Precache =
- {
- precache_sound ("hknight/hit.wav"); // flamethrower
- 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
- precache_sound2 ("blob/land1.wav"); // chain go splorch!
- precache_sound ("weapons/chain1.wav");
- // precache_sound ("weapons/chain2.wav");
- // precache_sound ("weapons/chain3.wav");
- // precache_sound ("weapons/bounce2.wav");
- // ZOID:
- // normally the weapon models are precached in the individual item
- // creation routines. But since we've added impulse 21 we can drop
- // weapons at any time. Must precache all weapon models.
- precache_model ("progs/g_shot.mdl");
- precache_model ("progs/g_nail.mdl");
- precache_model ("progs/g_nail2.mdl");
- precache_model ("progs/g_rock.mdl");
- precache_model ("progs/g_rock2.mdl");
- precache_model ("progs/g_light.mdl");
- };
- 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);
- //stuffcmd (self, "vibrate tactile/player/axhit2.bnvib");
- 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;
- makevectorsfixed(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);
- //stuffcmd (self, "vibrate tactile/weapons/guncock.bnvib");
- 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);
- //stuffcmd (self, "vibrate tactile/weapons/shotgn2.bnvib");
- 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);
- 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 ();
- };
- /*
- ================
- 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);
- //stuffcmd (self, "vibrate tactile/weapons/sgun1.bnvib");
- 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');
- };
- /*
- ===============================================================================
- 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);
- //stuffcmd (self, "vibrate tactile/weapons/lhit.bnvib");
- 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);
- };
- //=============================================================================
- void() GrenadeExplode =
- {
- T_RadiusDamage (self, self.owner, 120, 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() GrenadeTouch =
- {
- if (other == self.owner)
- return; // don't explode on owner
- if (other.takedamage == DAMAGE_AIM)
- {
- GrenadeExplode();
- return;
- }
- sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
- 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);
- //stuffcmd (self, "vibrate tactile/weapons/grenade.bnvib");
- 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 spd) launch_spike =
- {
- newmis = spawn ();
- newmis.owner = self;
- newmis.movetype = MOVETYPE_FLYMISSILE;
- newmis.solid = SOLID_BBOX;
- newmis.angles = vectoangles(dir);
-
- newmis.touch = spike_touch;
- newmis.classname = "spike";
- newmis.think = SUB_Remove;
- newmis.nextthink = time + 6;
- setmodel (newmis, "progs/spike.mdl");
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- setorigin (newmis, org);
- newmis.velocity = dir * spd;
- };
- void() W_FireSuperSpikes =
- {
- local vector dir;
-
- sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
- //stuffcmd (self, "vibrate tactile/weapons/spike2.bnvib");
- self.attack_finished = time + 0.2;
- self.currentammo = self.ammo_nails = self.ammo_nails - 2;
- dir = aim (self, 1000);
- if (self.player_flag & ITEM_RUNE3_FLAG) {
- HasteSound();
- launch_spike (self.origin + '0 0 16', dir, 2000);
- } else
- launch_spike (self.origin + '0 0 16', dir, 1000);
- newmis.classname = "super_spike";
- 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);
- //stuffcmd (self, "vibrate tactile/weapons/rocket1i.bnvib");
- self.attack_finished = time + 0.2;
- self.currentammo = self.ammo_nails = self.ammo_nails - 1;
- dir = aim (self, 1000);
- if (self.player_flag & ITEM_RUNE3_FLAG) {
- HasteSound();
- launch_spike (self.origin + '0 0 16' + v_right*ox, dir, 2000);
- } else
- launch_spike (self.origin + '0 0 16' + v_right*ox, dir, 1000);
- 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.classname == "wizard_spike")
- WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
- else if (self.classname == "knight_spike")
- 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
- {
- 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.weaponframe = 0;
- 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_HOOK)
- {
- self.currentammo = 0;
- self.weaponmodel = "progs/v_star.mdl";
- }
- else if (self.weapon == IT_SHOTGUN)
- {
- self.currentammo = self.ammo_shells;
- self.weaponmodel = "progs/v_shot.mdl";
- 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.items = self.items | IT_SHELLS;
- }
- else if (self.weapon == IT_NAILGUN)
- {
- self.currentammo = self.ammo_nails;
- self.weaponmodel = "progs/v_nail.mdl";
- 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.items = self.items | IT_NAILS;
- }
- else if (self.weapon == IT_GRENADE_LAUNCHER)
- {
- self.currentammo = self.ammo_rockets;
- self.weaponmodel = "progs/v_rock.mdl";
- 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.items = self.items | IT_ROCKETS;
- }
- else if (self.weapon == IT_LIGHTNING)
- {
- self.currentammo = self.ammo_cells;
- self.weaponmodel = "progs/v_light.mdl";
- self.items = self.items | IT_CELLS;
- }
- else
- {
- self.currentammo = 0;
- self.weaponmodel = string_null;
- }
- };
- float() W_BestWeapon =
- {
- local float it;
-
- it = self.items;
- if (self.waterlevel <= 1 && self.ammo_cells >= 1 && (it & IT_LIGHTNING) )
- return IT_LIGHTNING;
- else if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
- return IT_SUPER_NAILGUN;
- else if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
- return IT_SUPER_SHOTGUN;
- else if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
- return IT_NAILGUN;
- else if(self.ammo_shells >= 1 && (it & IT_SHOTGUN) )
- return IT_SHOTGUN;
- return IT_AXE;
- };
- float(entity playerEnt, float old, float new) W_WantsToChangeWeapon =
- {
- float playerFlags = CheckPlayerEXFlags(playerEnt);
- if((playerFlags & PEF_CHANGENEVER) != 0)
- {
- return 0;
- }
-
- if(((playerFlags & PEF_CHANGEONLYNEW) != 0) && old == new)
- {
- return 0;
- }
- return 1;
- };
- float() W_HasNoAmmo =
- {
- if (self.currentammo)
- return FALSE;
- if (self.weapon == IT_AXE || self.weapon == IT_HOOK)
- return FALSE; // doesnt need ammo
-
- self.weapon = W_BestWeapon ();
- W_SetCurrentAmmo ();
-
- // drop the weapon down
- return TRUE;
- };
- /*
- ============
- 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() player_chain1;
- void() player_chain3;
- void() W_Attack =
- {
- local float r;
- if ( W_HasNoAmmo() ) {
- 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);
- //stuffcmd (self, "vibrate tactile/weapons/ax1.bnvib");
- 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 ();
- // RUNE: rune of hell magic
- if (self.player_flag & ITEM_RUNE3_FLAG) {
- self.attack_finished = time + 0.3;
- HasteSound();
- } else
- self.attack_finished = time + 0.5;
- }
- else if (self.weapon == IT_SHOTGUN)
- {
- player_shot1 ();
- W_FireShotgun ();
- // RUNE: rune of hell magic
- if (self.player_flag & ITEM_RUNE3_FLAG) {
- self.attack_finished = time + 0.3;
- HasteSound();
- } else
- self.attack_finished = time + 0.5;
- }
- else if (self.weapon == IT_SUPER_SHOTGUN)
- {
- player_shot1 ();
- W_FireSuperShotgun ();
- // RUNE: rune of hell magic
- if (self.player_flag & ITEM_RUNE3_FLAG) {
- self.attack_finished = time + 0.4;
- HasteSound();
- } else
- 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();
- // RUNE: rune of hell magic
- if (self.player_flag & ITEM_RUNE3_FLAG) {
- self.attack_finished = time + 0.3;
- HasteSound();
- } else
- self.attack_finished = time + 0.6;
- }
- else if (self.weapon == IT_ROCKET_LAUNCHER)
- {
- player_rocket1();
- W_FireRocket();
- // RUNE: rune of hell magic
- if (self.player_flag & ITEM_RUNE3_FLAG) {
- self.attack_finished = time + 0.4;
- HasteSound();
- } else
- 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);
- //stuffcmd (self, "vibrate tactile/weapons/lstart.bnvib");
- }
- else if (self.weapon == IT_HOOK)
- {
- if (!self.hook_out)
- player_chain1();
- else
- player_chain3();
- self.attack_finished = time + 0.1;
- }
- };
- /*
- ============
- W_ChangeWeapon
- ============
- */
- void() W_ChangeWeapon =
- {
- local float it, am, fl;
-
- fl = it = self.items;
- am = 0;
-
- if (self.impulse == 1)
- {
- if (self.weapon == IT_HOOK)
- fl = IT_AXE;
- else
- fl = IT_HOOK;
- }
- else if (self.impulse == 31)
- {
- 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 if (self.impulse == 22)
- {
- fl = IT_HOOK;
- }
- self.impulse = 0;
-
- if (!(self.items & fl))
- { // don't have the weapon or the ammo
- sprint (self, "$qc_no_weapon");
- return;
- }
-
- if (am)
- { // don't have the ammo
- sprint (self, "$qc_not_enough_ammo");
- return;
- }
- //
- // set weapon, set ammo
- //
- self.weapon = fl;
- W_SetCurrentAmmo ();
- };
- /*
- ============
- CheatCommand
- ============
- */
- void CheatCommand() {
- if ( ( deathmatch || coop ) && cheats_allowed == 0 ) { // mal: allow impulse 9 IF cheats allowed
- return;
- }
- self.ammo_rockets = 100;
- self.ammo_nails = 200;
- self.ammo_shells = 100;
- self.items = self.items |
- IT_AXE |
- IT_HOOK |
- IT_SHOTGUN |
- IT_SUPER_SHOTGUN |
- IT_NAILGUN |
- IT_SUPER_NAILGUN |
- IT_GRENADE_LAUNCHER |
- IT_ROCKET_LAUNCHER |
- IT_KEY1 | IT_KEY2;
- self.ammo_cells = 200;
- self.items = self.items | IT_LIGHTNING;
-
- // mal: also give full armor...
- self.armortype = 0.8;
- self.armorvalue = 200;
- self.items = self.items - ( self.items & ( IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3 ) ) + IT_ARMOR3;
- 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_HOOK;
- }
- else if (self.weapon == IT_HOOK)
- {
- 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 ( (self.items & 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_HOOK;
- }
- else if (self.weapon == IT_HOOK)
- {
- 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 =
- {
- serverflags = serverflags * 2 + 1;
- // ZOID: Bug fix
- serverflags = (serverflags & 15);
- };
- void() QuadCheat =
- {
- if (!cheats_allowed)
- return;
- self.super_time = 1;
- self.super_damage_finished = time + 30;
- self.items = self.items | IT_QUAD;
- dprint ("quad cheat\n");
- };
- //ZOID: Uhm, where am I?
- void() PrintLocation =
- {
- local string p;
- p = vtos(self.origin);
- sprint(self, "You are at ");
- sprint(self, p);
- sprint(self, "\n");
- };
- /*
- ============
- ImpulseCommands
- ============
- */
- void() ImpulseCommands =
- {
- if ((self.impulse >= 1 && self.impulse <= 8) || self.impulse == 22 || self.impulse == 31)
- W_ChangeWeapon ();
- if (self.impulse == 9)
- CheatCommand ();
- if (!self.observer && self.impulse == 10)
- CycleWeaponCommand ();
- if (self.impulse == 11)
- ServerflagsCommand ();
- if (self.impulse == 12)
- CycleWeaponReverseCommand();
- if (self.impulse == 99)
- PrintLocation();
-
- // *TEAMPLAY*
- // If we're allowed to drop items, enable impulse 20 and 21
- else if (!self.observer && (teamplay & TEAM_DROP_ITEMS) && self.impulse == 20)
- TossBackpack ();
- else if (!self.observer && (teamplay & TEAM_DROP_ITEMS) && self.impulse == 21)
- TossWeapon ();
- // *TEAMPLAY*
- // Impulse 25 prints info about the current teamplay settings.
- else if (self.impulse == 25)
- TeamPrintSettings ();
- else if (self.impulse == 255)
- QuadCheat ();
-
- 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)
- ImpulseCommands ();
-
- // check for attack
- if ( self.button0 ) {
- SuperDamageSound ();
- W_Attack ();
- }
- };
- /*
- ========
- Resistancesound
- Plays sound if needed
- ========
- */
- void(entity who) ResistanceSound =
- {
- // RUNE play resistance sound if player has Earth Magic
- if (who.player_flag & ITEM_RUNE1_FLAG) {
- if (who.invincible_sound < time) {
- who.invincible_sound = time + 1;
- sound(who, CHAN_BODY, "rune/rune1.wav", 1, ATTN_NORM);
- }
- }
- };
- /*
- ========
- SuperDamageSound
- Plays sound if needed
- ========
- */
- void() SuperDamageSound =
- {
- // RUNE play super damage sound if player has Black Magic, too
- if ((self.player_flag & ITEM_RUNE2_FLAG) &&
- (self.super_damage_finished > time)) {
- if (self.super_sound < time) {
- self.super_sound = time + 1;
- sound (self, CHAN_BODY, "rune/rune22.wav", 1, ATTN_NORM);
- }
- }
- 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);
- }
- }
- if (self.player_flag & ITEM_RUNE2_FLAG) {
- if (self.super_sound < time) {
- self.super_sound = time + 1;
- sound (self, CHAN_BODY, "rune/rune2.wav", 1, ATTN_NORM);
- }
- }
- };
- /*
- ========
- RegenerationSound
- Plays sound if needed
- ========
- */
- void() RegenerationSound =
- {
- // RUNE play healing sound if player has Elder Magic
- if (self.player_flag & ITEM_RUNE4_FLAG) {
- if (self.regeneration_sound < time) {
- self.regeneration_sound = time + 1;
- sound(self, CHAN_BODY, "rune/rune4.wav", 1, ATTN_NORM);
- }
- }
- };
- /*
- ========
- HasteSound
- Plays sound if needed
- ========
- */
- void() HasteSound =
- {
- // RUNE play haste (Chthon's roar) sound if player has Hell Magic
- if (self.player_flag & ITEM_RUNE3_FLAG) {
- if (self.haste_sound < time) {
- self.haste_sound = time + 1;
- sound(self, CHAN_BODY, "rune/rune3.wav", 1, ATTN_NORM);
- }
- }
- };
|