123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118 |
- /* 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.
- */
- // updated to quake v1.06 10/8/96
- // prototypes
- void () W_WeaponFrame;
- void() W_SetCurrentAmmo;
- void() player_pain;
- void() player_stand1;
- void (vector org) spawn_tfog;
- void (vector org, entity death_owner) spawn_tdeath;
- void(entity targ, entity attacker) dmatch_score;
- float modelindex_eyes, modelindex_player;
- /*
- =============================================================================
- LEVEL CHANGING / INTERMISSION
- =============================================================================
- */
- float intermission_running;
- float intermission_exittime;
- /*QUAKED info_intermission (1 0.5 0.5) (-16 -16 -16) (16 16 16)
- 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 =
- {
- };
- void() SetChangeParms =
- {
- if (self.health <= 0 || deathmatch)
- {
- SetNewParms ();
- parm14 = self.steam; // Save the current team of the player
- return;
- }
- // remove items
- self.items = self.items - (self.items & (IT_KEY1 | IT_KEY2 |
- IT_INVULNERABILITY | IT_SUIT |
- IT_QUAD | IT_INVISIBILITY) );
-
- self.items2 = self.items2 - (self.items2 &
- (IT2_ANTIGRAV | IT2_SHIELD | IT2_SUPERHEALTH));
- self.gravity = 1.0;
-
- // cap super health
- if (self.health > self.max_health)
- self.health = self.max_health;
- if (self.health < self.max_health / 2)
- self.health = self.max_health / 2;
- teamplay = cvar ( "teamplay" );
- if (teamplay >= TEAM_CTF) // don't carry items between levels in CTF
- SetNewParms();
- else
- {
- parm1 = self.items;
- parm2 = self.health;
- parm3 = self.armorvalue;
- if (self.ammo_shells1 < 25)
- parm4 = 25;
- else
- parm4 = self.ammo_shells1;
- parm5 = self.ammo_nails1;
- parm6 = self.ammo_rockets1;
- parm7 = self.ammo_cells1;
- parm8 = self.weapon;
- parm9 = self.armortype * 100;
- parm10 = self.items2;
- parm11 = self.ammo_lava_nails;
- parm12 = self.ammo_multi_rockets;
- parm13 = self.ammo_plasma;
- }
- parm14 = self.steam; // save team setting
- };
- void() SetNewParms =
- {
- //ZOID--
- if (deathmatch && teamplay >= TEAM_CTF) {
- parm1 = IT_SHOTGUN | IT_AXE | IT_GRAPPLE;
- parm10 = IT2_ARMOR1;
- parm3 = 50;
- parm9 = 30;
- } else {
- parm1 = IT_SHOTGUN | IT_AXE;
- parm3 = 0;
- parm9 = 0;
- parm10 = 0;
- }
- //--ZOID
- if (skill == 3 && !deathmatch)
- parm2 = 50;
- else
- parm2 = 100;
- parm4 = 25;
- parm5 = 0;
- parm6 = 0;
- parm7 = 0;
- parm8 = 1;
- parm11 = 0;
- parm12 = 0;
- parm13 = 0;
- //ZOID--
- parm14 = -1; // CTF: reset current team selection
- //--ZOID
- };
- void() DecodeLevelParms =
- {
- if (serverflags)
- {
- if (world.model == "maps/start.bsp")
- SetNewParms (); // take away all stuff on starting new episode
- }
- if (world.model == "maps/r2m1.bsp" && !deathmatch)
- SetNewParms ();
- // PGM - 01/29 change to have level 8 reset all your stuff.
-
- self.items = parm1;
- self.health = parm2;
- self.armorvalue = parm3;
- self.ammo_shells1 = parm4;
- self.ammo_nails1 = parm5;
- self.ammo_rockets1 = parm6;
- self.ammo_cells1 = parm7;
- // cute bug, if grapple was selected, it still will be on level change
- if (parm8 == IT_GRAPPLE && teamplay < TEAM_CTF)
- self.weapon = IT_AXE;
- else
- self.weapon = parm8;
- self.armortype = parm9 * 0.01;
- self.items2 = parm10;
- self.ammo_lava_nails = parm11;
- self.ammo_multi_rockets = parm12;
- self.ammo_plasma = parm13;
- //ZOID--
- if (TeamColorIsLegal(parm14)) {
- self.steam = parm14;
- TeamSetSkin();
- }
- //--ZOID
- };
- /*
- ============
- 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");
- };
- string nextmap;
- void() GotoNextMap =
- {
- if (cvar("samelevel")) // if samelevel is set, stay on same level
- changelevel (mapname);
- else
- changelevel (nextmap);
- };
- 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 (world.model == "maps/e1m7.bsp")
- {
- WriteByte (MSG_ALL, SVC_CDTRACK);
- WriteByte (MSG_ALL, 2);
- WriteByte (MSG_ALL, 3);
- if (!cvar("registered"))
- {
- WriteByte (MSG_ALL, SVC_FINALE);
- WriteString (MSG_ALL, "$qc_finale_e1_shareware");
- }
- else
- {
- WriteByte (MSG_ALL, SVC_FINALE);
- WriteString (MSG_ALL, "$qc_finale_e1");
- }
- return;
- }
- else if (world.model == "maps/e2m6.bsp")
- {
- WriteByte (MSG_ALL, SVC_CDTRACK);
- WriteByte (MSG_ALL, 2);
- WriteByte (MSG_ALL, 3);
- WriteByte (MSG_ALL, SVC_FINALE);
- WriteString (MSG_ALL, "$qc_finale_e2");
- return;
- }
- else if (world.model == "maps/e3m6.bsp")
- {
- WriteByte (MSG_ALL, SVC_CDTRACK);
- WriteByte (MSG_ALL, 2);
- WriteByte (MSG_ALL, 3);
- WriteByte (MSG_ALL, SVC_FINALE);
- WriteString (MSG_ALL, "$qc_finale_e3");
- return;
- }
- else if (world.model == "maps/e4m7.bsp")
- {
- WriteByte (MSG_ALL, SVC_CDTRACK);
- WriteByte (MSG_ALL, 2);
- WriteByte (MSG_ALL, 3);
- WriteByte (MSG_ALL, SVC_FINALE);
- WriteString (MSG_ALL, "$qc_finale_e4");
- return;
- }
- else if (world.model == "maps/r1m7.bsp")
- {
- WriteByte (MSG_ALL, SVC_FINALE);
- //------------------------------------- end here
- WriteString (MSG_ALL, "$qc_finale_r1");
- return;
- }
- if (coop && mapname == "r2m8" )
- {
- localcmd("menu_credits\n");
- localcmd("disconnect\n");
- return;
- }
- else
- {
- GotoNextMap();
- }
- }
-
- if (intermission_running == 3)
- {
- if (!cvar("registered"))
- { // shareware episode has been completed, go to sell screen
- WriteByte (MSG_ALL, SVC_SELLSCREEN);
- return;
- }
-
- if ( (serverflags&15) == 15)
- {
- WriteByte (MSG_ALL, SVC_FINALE);
- WriteString (MSG_ALL, "$qc_finale_all_runes");
- return;
- }
-
- }
- if (coop)
- {
- if ( mapname == "r2m8" )
- {
- localcmd("menu_credits\n");
- localcmd("disconnect\n");
- return;
- }
- }
- else
- {
- 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 =
- {
- 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");
- }
- WriteByte (MSG_ALL, SVC_INTERMISSION);
- if (campaign && world.model == "maps/r1m7.bsp")
- {
- WriteByte (MSG_ALL, SVC_ACHIEVEMENT);
- WriteString(MSG_ALL, "ACH_COMPLETE_R1M7");
- }
- };
- void() changelevel_touch =
- {
- local entity pos;
- if (other.classname != "player")
- return;
- if ((cvar("noexit") == 1) || ((cvar("noexit") == 2) && (mapname != "start")))
- {
- T_Damage (other, self, self, 50000);
- return;
- }
- if (coop || deathmatch)
- {
- bprint("$qc_exited", other.netname);
- }
-
- nextmap = self.map;
- SUB_UseTargets ();
- 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;
- };
- /*QUAKED trigger_changelevel (0.5 0.5 0.5) ? NO_INTERMISSION
- 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 (!self.map)
- objerror ("chagnelevel trigger doesn't have map");
-
- InitTrigger ();
- self.touch = changelevel_touch;
- };
- /*
- =============================================================================
- 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 ();
- // set the skin correctly.
- TeamSetSkin();
- }
- else
- { // restart the entire server
- cvar_set("campaign", ftos(campaign));
- localcmd ("restart\n");
- }
- };
- /*
- ============
- ClientKill
- Player entered the suicide command
- ============
- */
- void() ClientKill =
- {
- local entity vSphere;
- // ZOID--
- if (self.suicide_count > 3)
- {
- sprint(self, "$qc_suicided_too_much");
- return;
- }
- TeamDropFlagOfPlayer(self);
- self.suicide_count = self.suicide_count + 1;
- // --ZOID
- if ( tag_token_owner == self)
- {
- self.health = 0;
- self.solid = SOLID_NOT;
- tag_token_drop();
- }
- if ( self.items2 & IT2_V_SPHERE)
- {
- vSphere = find ( world, classname, "Vengeance");
- while (vSphere)
- {
- if ( vSphere.owner == self )
- {
- remove (vSphere);
- }
- vSphere = find(vSphere, classname, "Vengeance");
- }
- }
- bprint("$qc_suicides", self.netname);
- set_suicide_frame ();
- self.modelindex = modelindex_player;
- self.frags = self.frags - 2; // extra penalty
- respawn ();
- };
- /*
- ============
- PlayerVisibleToSpawnPoint
- Returns true if player can see this point
- ============
- */
- float PlayerVisibleToSpawnPoint( entity point ) {
- local vector spot1, spot2;
- local entity player = find( world, classname, "player" );
- while ( player ) {
- if ( player.health > 0 ) {
- spot1 = point.origin + player.view_ofs;
- spot2 = player.origin + player.view_ofs;
- traceline( spot1, spot2, TRUE, point );
- if ( trace_fraction >= 1.0f ) {
- return TRUE;
- }
- }
- player = find( player, classname, "player" );
- }
- return FALSE;
- }
- float IDEAL_DIST_FROM_DM_SPAWN_POINT = 384;
- float MIN_DIST_FROM_DM_SPAWN_POINT = 84;
- /*
- ============
- SelectSpawnPoint
- Returns the entity to spawn at
- ============
- */
- entity() SelectSpawnPointRogue =
- {
- local entity spot;
- local entity thing;
- local float pcount;
- //ZOID--
- local entity startspot;
- local float t;
- //--ZOID
-
- // 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)
- {
- startspot = spot = lastspawn;
- t = 0;
- if (!self.ctf_killed && teamplay >= TEAM_CTF)
- {
- if (self.steam == TEAM1)
- {
- startspot = spot = team1_lastspawn;
- t = TEAM1;
- }
- else if (self.steam == TEAM2)
- {
- startspot = spot = team2_lastspawn;
- t = TEAM2;
- }
- }
-
- while (1)
- {
- if (t == TEAM1)
- spot = find(spot, classname, "info_player_team1");
- else if (t == TEAM2)
- spot = find(spot, classname, "info_player_team2");
- else
- spot = find(spot, classname, "info_player_deathmatch");
- if (spot != world)
- {
- if (spot == startspot)
- return startspot;
- pcount = 0;
- thing = findradius(spot.origin, 32);
- while(thing)
- {
- if (thing.classname == "player")
- pcount = pcount + 1;
- thing = thing.chain;
- }
- if (pcount == 0)
- {
- if (t == TEAM1)
- team1_lastspawn = spot;
- else if (t == TEAM2)
- team2_lastspawn = spot;
- else
- lastspawn = spot;
- return spot;
- }
- }
- else
- t = 0;
- // pgm fix for ctf in levels w/o ctf support
- }
- }
- 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;
- };
- entity SelectSpawnPointEX(float forceSpawn) {
- local entity spot, thing;
- local float numspots, totalspots;
- local float pcount;
- local entity spots;
- numspots = 0;
- totalspots = 0;
- // 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 ) {
- // find all spots that don't have visible players nearby
- spots = world;
- spot = find( world, classname, "info_player_deathmatch" );
- while( spot ) {
- totalspots = totalspots + 1;
- thing = findradius( spot.origin, IDEAL_DIST_FROM_DM_SPAWN_POINT );
- pcount = 0;
- while( thing ) {
- if ( thing.classname == "player" && thing.health > 0 ) {
- pcount = pcount + 1;
- }
- thing = thing.chain;
- }
- if ( pcount == 0 ) {
- if ( PlayerVisibleToSpawnPoint( spot ) ) {
- pcount = pcount + 1;
- }
- }
- if ( pcount == 0 ) { // good spot!
- spot.goalentity = spots;
- spots = spot;
- numspots = numspots + 1;
- }
- // Get the next spot in the chain
- spot = find( spot, classname, "info_player_deathmatch" );
- }
- totalspots = totalspots - 1;
- // on small maps with few spawn points, our "ideal" spawn conditions may not be possible to meet
- // so fallback to just trying to pick a point without a player on top of it, so we don't start
- // a spawn frag loop
- if ( numspots == 0 ) {
- spot = find( world, classname, "info_player_deathmatch" );
- while( spot ) {
- thing = findradius( spot.origin, MIN_DIST_FROM_DM_SPAWN_POINT );
- pcount = 0;
- while( thing ) {
- if ( thing.classname == "player" && thing.health > 0 ) {
- pcount = pcount + 1;
- }
- thing = thing.chain;
- }
- if ( pcount == 0 ) { // good spot!
- spot.goalentity = spots;
- spots = spot;
- numspots = numspots + 1;
- }
- // Get the next spot in the chain
- spot = find( spot, classname, "info_player_deathmatch" );
- }
- }
- // uncomment to force a deferred spawn
- // if (forceSpawn == FALSE) return world;
- if ( !numspots ) {
- if (forceSpawn == FALSE) {
- return world;
- }
- // no spots available so just pick one at random
- totalspots = rint( ( random() * totalspots ) );
- spot = find( world, classname, "info_player_deathmatch" );
- while( totalspots > 0 ) {
- totalspots = totalspots - 1;
- spot = find( spot, classname, "info_player_deathmatch" );
- }
- return spot;
- }
-
- // Generate a random number between 1 and numspots
- numspots = numspots - 1;
-
- numspots = rint( ( random() * numspots ) );
- spot = spots;
- while( numspots > 0 ) {
- spot = spot.goalentity;
- numspots = numspots - 1;
- }
-
- 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;
- };
- entity SelectSpawnPoint(float forceSpawn) {
- // use the original rogue spawn logic in tctf
- if (teamplay >= TEAM_CTF) {
- return SelectSpawnPointRogue();
- } else {
- return SelectSpawnPointEX(forceSpawn);
- }
- }
- /*
- ===========
- PutClientInServer
- called each time a player is spawned
- ============
- */
- void() DecodeLevelParms;
- void() PlayerDie;
- void() player_touch;
- void() PutClientInServer =
- {
- local entity spot;
- self.classname = "player";
- if (skill == 3 && !deathmatch)
- self.health = 50;
- else
- self.health = 100;
- self.takedamage = DAMAGE_AIM;
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_WALK;
- self.show_hostile = 0;
- if (skill == 3 && !deathmatch)
- self.max_health = 50;
- else
- 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.shield_finished = 0;
- self.antigrav_finished = 0;
-
- //ZOID--
- self.ctf_lastreturnedflag = -10;
- self.ctf_lastfraggedcarrier = -10;
- self.ctf_flagsince = -10;
- self.ctf_lasthurtcarrier = -10;
- //--ZOID
- if ( coop ) {
- self.team = TEAM_HUMANS;
- }
- DecodeLevelParms ();
- // spawn selection must be after DecodeLevelParms because of team stuff
- spot = SelectSpawnPoint ();
-
- W_SetCurrentAmmo ();
- self.attack_finished = time;
- self.th_pain = player_pain;
- self.th_die = PlayerDie;
-
- 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
- self.touch = player_touch;
- // oh, this is a hack!
- setmodel (self, "progs/eyes.mdl");
- modelindex_eyes = 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';
- player_stand1 ();
-
- if (deathmatch || coop)
- {
- makevectors(self.angles);
- spawn_tfog (self.origin + v_forward*20);
- }
- //Grapple stuff
- self.on_hook = FALSE;
- self.hook_out = FALSE;
- spawn_tdeath (self.origin, self);
-
- stuffcmd(self, "-attack\n"); // prevent shooting after respawning
- };
- /*
- =============================================================================
- QUAKED FUNCTIONS
- =============================================================================
- */
- /*QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 24)
- The normal starting point for a level.
- */
- void() info_player_start =
- {
- };
- /*QUAKED info_player_start2 (1 0 0) (-16 -16 -24) (16 16 24)
- Only used on start map for the return point from an episode.
- */
- void() info_player_start2 =
- {
- };
- /*
- saved out by quaked in region mode
- */
- void() testplayerstart =
- {
- };
- /*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -24) (16 16 24)
- potential spawning position for deathmatch games
- */
- void() info_player_deathmatch =
- {
- SpawnRunes();
- };
- /*QUAKED info_player_coop (1 0 1) (-16 -16 -24) (16 16 24)
- potential spawning position for coop games
- */
- void() info_player_coop =
- {
- };
- /*
- ===============================================================================
- RULES
- ===============================================================================
- */
- /*
- go to the next level for deathmatch
- */
- 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;
- }
- */
- // PGM 03/02/97 - make it always go to rogue level1 when in our progs
- mapname = "r1m1";
- 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 (timelimit && time >= timelimit)
- {
- NextLevel ();
- return;
- }
-
- if (fraglimit && self.frags >= fraglimit)
- {
- NextLevel ();
- return;
- }
- //ZOID--
- // update team scores?
- TeamCheckUpdate();
- //--ZOID
- };
- //============================================================================
- void() PlayerDeathThink =
- {
- local entity old_self;
- 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);
- }
- if (self.spawn_deferred)
- {
- local entity spot;
-
- spot = SelectSpawnPoint(FALSE);
- //dprint("time {} >= self.spawn_deferred {}\n", ftos(time), ftos(self.spawn_deferred));
- if (spot != world || time >= self.spawn_deferred) {
- respawn();
- }
- return;
- }
- // 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();
- };
- void() PlayerJump =
- {
- local vector start, end;
-
- 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;
- }
- if (!(self.flags & FL_ONGROUND))
- return;
- if ( !(self.flags & FL_JUMPRELEASED) )
- return; // don't pogo stick
- self.flags = self.flags - (self.flags & FL_JUMPRELEASED);
- self.flags = self.flags - FL_ONGROUND; // don't stairwalk
-
- self.button2 = 0;
- // player jumping sound
- sound (self, CHAN_BODY, "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;
- 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;
- T_Damage (self, world, world, self.dmg);
- 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;
- T_Damage (self, world, world, 10*self.waterlevel);
- }
- }
- else if (self.watertype == CONTENT_SLIME)
- { // do damage
- if (self.dmgtime < time && self.radsuit_finished < time)
- {
- self.dmgtime = time + 1;
- T_Damage (self, world, world, 4*self.waterlevel);
- }
- }
-
- 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 =
- {
- 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 mspeed, aspeed;
- local float r;
- if (intermission_running)
- {
- IntermissionThink (); // otherwise a button could be missed between
- return; // the think tics
- }
-
- if (self.view_ofs == '0 0 0')
- return; // intermission or finale
- if (earthquake_active)
- {
- if ( self.flags & FL_ONGROUND )
- {
- self.velocity_x = self.velocity_x +
- (random() * earthquake_intensity * 2) -
- earthquake_intensity;
- self.velocity_y = self.velocity_y +
- (random() * earthquake_intensity * 2) -
- earthquake_intensity;
- self.velocity_z = self.velocity_z +
- (random() * earthquake_intensity * 2) -
- earthquake_intensity;
- }
- }
- makevectors (self.v_angle); // is this still used
- //ZOID--
- // TeamCheckLock performs all necessary teamlock checking, and performs all
- // actions needed.
- TeamCheckLock();
- //--ZOID
- CheckMOTD();
- CheckRules ();
- WaterMove ();
- if (self.waterlevel == 2)
- CheckWaterJump ();
- if (self.deadflag >= DEAD_DEAD)
- {
- PlayerDeathThink ();
- return;
- }
-
- if (self.deadflag == DEAD_DYING)
- return; // dying, so do nothing
- if (self.button2)
- {
- PlayerJump ();
- }
- else
- self.flags = self.flags | FL_JUMPRELEASED;
- // teleporters can force a non-moving pause time
- if (time < self.pausetime)
- self.velocity = '0 0 0';
-
- if (self.items2 & IT2_ANTIGRAV)
- {
- if ( time > self.AGping )
- {
- sound ( self, CHAN_AUTO, "belt/use.wav", 0.4, ATTN_NORM);
- self. AGping = time + 3;
- if(self. AGping >= (self.antigrav_finished - 3))
- self. AGping = self.antigrav_finished + 3;
- }
- }
- RuneApplyElder(self); // regeneration rune
- // Track the grapple
- if (self.hook_out)
- GrappleService();
- };
-
- /*
- ================
- 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, "$qc_ring_fade");
- 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, "$qc_protection_fade");
- 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_PENTALIGHT;
- else
- self.effects = self.effects - (self.effects & EF_PENTALIGHT);
- }
- // 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, "$qc_quad_fade");
- 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_QUADLIGHT;
- else
- self.effects = self.effects - (self.effects & EF_QUADLIGHT);
- }
- // 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, "$qc_biosuit_fade");
- 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;
- }
- }
-
- if(self.shield_finished)
- {
- if ( self.shield_finished < time + 3)
- {
- if (self.shield_time == 1)
- {
- sprint (self, "$qc_shield_failing");
- sound (self, CHAN_AUTO, "shield/fadeout.wav", 1, ATTN_NORM);
- self.shield_time = 0;
- }
- if (self.shield_time < time)
- {
- self.shield_time = time + 1;
- stuffcmd (self, "bf\n");
- }
- }
-
- if ( self.shield_finished < time)
- {
- sprint (self, "$qc_shield_lost");
- self.shield_finished = 0;
- self.items2 = self.items2 - IT2_SHIELD;
- }
- }
- if(self.antigrav_finished)
- {
- if ( self.antigrav_finished < time + 3)
- {
- if (self.antigrav_time == 1)
- {
- sprint (self, "$qc_antigrav_failing");
- self.antigrav_time = 0;
- sound (self, CHAN_AUTO, "belt/fadeout.wav", 1, ATTN_NORM);
- }
- if (self.antigrav_time < time)
- {
- self.antigrav_time = time + 1;
- stuffcmd (self, "bf\n");
- }
- }
-
- if ( self.antigrav_finished < time)
- {
- sprint (self, "$qc_antigrav_lost");
- self.antigrav_finished = 0;
- self.items2 = self.items2 - IT2_ANTIGRAV;
- self.gravity = 1.0;
- }
- }
- };
- /*
- ================
- PlayerPostThink
- Called every frame after physics are run
- ================
- */
- void() xpackEnding;
- void() PlayerPostThink =
- {
- local float mspeed, aspeed;
- local float r;
-
- if (self.view_ofs == '0 0 0')
- return; // intermission or finale
- if (self.deadflag)
- return;
-
- if (cutscene_running)
- {
- xpackEnding();
- }
-
- // 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)
- {
- T_Damage (self, world, world, 5);
- sound (self, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM);
- self.deathtype = "falling";
- }
- 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;
- CheckPowerups ();
- };
- /*
- ===========
- ClientConnect
- called when a player connects to a server
- ============
- */
- void() ClientConnect =
- {
- bprint("$qc_entered", self.netname);
-
- //ZOID--
- self.suicide_count = 0;
- self.ctf_killed = 0;
- SetMOTD();
- // If this is our first connection, parm14 is < 0
- // Set lastteam negative.
- if (parm14 < 0 && teamplay > 0)
- {
- if (cvar("gamecfg") & GAMECFG_USE_COLOR)
- self.steam = self.team; // accept joining players color if legal
- else
- self.steam = -50; // always reassign
- TeamCheckLock();
- }
- //--ZOID
- // 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("$qc_left_game", self.netname, ftos(self.frags));
- sound (self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE);
- sphere_remove(self);
- if ( tag_token_owner == self)
- tag_token_drop();
-
- //ZOID--
- TeamDropFlagOfPlayer(self);
- self.steam = -50;
- self.team = 0;
- //--ZOID
- set_suicide_frame ();
- };
- /*
- ===========
- ClientObituary
- called when a player dies
- ============
- */
- void(entity targ, entity attacker) ClientObituary =
- {
- local float rnum;
- local string deathstring, deathstring2;
- rnum = random();
- if (targ.classname == "player")
- {
- // ZOID--
- TeamResetCarrier(targ);
- // --ZOID
- if (attacker.classname == "teledeath")
- {
- bprint("$qc_telefragged", targ.netname, attacker.owner.netname);
- attacker.owner.frags = attacker.owner.frags + 1;
- return;
- }
- if (attacker.classname == "teledeath2")
- {
- bprint("$qc_satans_power", targ.netname);
- targ.frags = targ.frags - 1;
- return;
- }
- if (attacker.classname == "player")
- {
- if (targ == attacker)
- {
- // killed self
- attacker.frags = attacker.frags - 1;
-
- if (targ.weapon == 64 && targ.waterlevel > 1)
- {
- if (targ.watertype == CONTENT_SLIME)
- bprint("$qc_discharge_slime", targ.netname);
- else if (targ.watertype == CONTENT_LAVA)
- bprint("$qc_discharge_lava", targ.netname);
- else
- bprint("$qc_discharge_water", targ.netname);
- return;
- }
- if (targ.weapon == 16)
- bprint("$qc_suicide_pin", targ.netname);
- else if (rnum < 0.50)
- bprint("$qc_suicide_bored", targ.netname);
- //ZOID--
- //gibbed for changing teams
- else if (teamplay && (targ.team != targ.steam))
- {
- if (cvar("gamecfg") & GAMECFG_ALLOW_CHG)
- bprint("$qc_changed_teams", targ.netname);
- else
- bprint("$qc_tried_change_teams", targ.netname);
- }
- //--ZOID
- else
- bprint("$qc_suicide_loaded", targ.netname);
- return;
- }
- else if ( (teamplay == 2) && (targ.team > 0)&&(targ.team == attacker.team) )
- {
- if (rnum < 0.25)
- bprint("$qc_ff_teammate", attacker.netname);
- else if (rnum < 0.50)
- bprint("$qc_ff_glasses", attacker.netname);
- else if (rnum < 0.75)
- bprint("$qc_ff_otherteam", attacker.netname);
- else
- bprint("$qc_ff_friend", attacker.netname);
- attacker.frags = attacker.frags - 1;
- return;
- }
- else
- {
- if (teamplay == TEAM_DMATCH_TAG)
- dmatch_score (targ, attacker);
- else
- {
- attacker.frags = attacker.frags + 1;
- //ZOID--
- TeamAssists(targ, attacker);
- //--ZOID
- }
- rnum = attacker.weapon;
- if (rnum == IT_AXE)
- {
- bprint("$qc_death_ax", targ.netname, attacker.netname);
- return;
- }
- //ZOID--
- if (rnum == IT_GRAPPLE)
- {
- bprint("$qc_death_grappled", targ.netname, attacker.netname);
- return;
- }
- //--ZOID
- if (rnum == IT_SHOTGUN)
- {
- bprint("$qc_death_sg", targ.netname, attacker.netname);
- return;
- }
- if (rnum == IT_SUPER_SHOTGUN)
- {
- bprint("$qc_death_dbl", targ.netname, attacker.netname);
- return;
- }
- if (rnum == IT_NAILGUN)
- {
- bprint("$qc_death_nail", targ.netname, attacker.netname);
- return;
- }
- if (rnum == IT_SUPER_NAILGUN)
- {
- bprint("$qc_death_sng", targ.netname, attacker.netname);
- return;
- }
- if (rnum == IT_GRENADE_LAUNCHER)
- {
- if (targ.health < -40)
- {
- bprint("$qc_death_gl1", targ.netname, attacker.netname);
- return;
- }
- else
- {
- bprint("$qc_death_gl2", targ.netname, attacker.netname);
- return;
- }
- }
- if (rnum == IT_ROCKET_LAUNCHER)
- {
- if (attacker.super_damage_finished > 0 && targ.health < -40)
- {
- rnum = random();
- if (rnum < 0.3)
- {
- bprint("$qc_death_rl_quad1", targ.netname, attacker.netname);
- return;
- }
- else if (rnum < 0.6)
- {
- bprint("$qc_death_rl_quad2", targ.netname, attacker.netname);
- return;
- }
- else
- {
- bprint("$qc_death_rl1", targ.netname, attacker.netname);
- return;
- }
- }
- else
- {
- if (targ.health < -40)
- {
- bprint("$qc_death_rl2", targ.netname, attacker.netname);
- return;
- }
- else
- {
- bprint("$qc_death_rl3", targ.netname, attacker.netname);
- return;
- }
- }
- }
- if (rnum == IT_LIGHTNING)
- {
- if (attacker.waterlevel > 1)
- {
- bprint("$qc_death_lg1", targ.netname, attacker.netname);
- if (attacker.invincible_finished)
- {
- msg_entity = attacker;
- WriteByte (MSG_ONE, SVC_ACHIEVEMENT);
- WriteString(MSG_ONE, "ACH_SURVIVE_DISCHARGE");
- }
- }
- else
- bprint("$qc_death_lg2", targ.netname, attacker.netname);
-
- return;
- }
-
- if (rnum == IT_LAVA_NAILGUN || rnum == IT_LAVA_SUPER_NAILGUN)
- {
- bprint("$qc_death_burned", targ.netname, attacker.netname);
- return;
- }
- else if (rnum == IT_PLASMA_GUN)
- {
- bprint("$qc_death_fused", targ.netname, attacker.netname);
- return;
- }
- else if (rnum == IT_MULTI_GRENADE || rnum == IT_MULTI_ROCKET)
- {
- bprint("$qc_death_blasted", targ.netname, attacker.netname);
- return;
- }
- }
- return;
- }
- else
- {
- targ.frags = targ.frags - 1;
- // killed by a montser?
- if (attacker.flags & FL_MONSTER)
- {
- if (attacker.classname == "monster_army")
- bprint ("$qc_ks_grunt", targ.netname);
- if (attacker.classname == "monster_demon1")
- bprint ("$qc_ks_fiend", targ.netname);
- if (attacker.classname == "monster_dog")
- bprint ("$qc_ks_rottweiler", targ.netname);
- if (attacker.classname == "monster_dragon")
- bprint ("$qc_ks_dragon1", targ.netname);
- if (attacker.classname == "monster_dragon_dead")
- bprint ("$qc_ks_dragon2", targ.netname);
- if (attacker.classname == "monster_enforcer")
- bprint ("$qc_ks_enforcer", targ.netname);
- if (attacker.classname == "monster_fish")
- bprint ("$qc_ks_rotfish", targ.netname);
- if (attacker.classname == "monster_hell_knight")
- bprint ("$qc_ks_deathknight", targ.netname);
- if (attacker.classname == "monster_knight")
- bprint ("$qc_ks_knight", targ.netname);
- if (attacker.classname == "monster_ogre")
- bprint ("$qc_ks_ogre", targ.netname);
- if (attacker.classname == "monster_oldone")
- bprint ("$qc_ks_shub", targ.netname);
- if (attacker.classname == "monster_shalrath")
- bprint ("$qc_ks_vore", targ.netname);
- if (attacker.classname == "monster_shambler")
- bprint ("$qc_ks_shambler", targ.netname);
- if (attacker.classname == "monster_tarbaby")
- bprint ("$qc_ks_spawn", targ.netname);
- if (attacker.classname == "monster_vomit")
- bprint ("$qc_ks_vomitus", targ.netname);
- if (attacker.classname == "monster_wizard")
- bprint ("$qc_ks_scrag", targ.netname);
- if (attacker.classname == "monster_zombie")
- bprint ("$qc_ks_zombie", targ.netname);
- if (attacker.classname == "monster_eel")
- bprint ("$qc_ks_eel", targ.netname);
- if (attacker.classname == "monster_wrath")
- bprint ("$qc_ks_wrath", targ.netname);
- if (attacker.classname == "monster_super_wrath")
- bprint ("$qc_ks_overlord", targ.netname);
- if (attacker.classname == "monster_sword")
- bprint ("$qc_ks_swordsman", targ.netname);
- if (attacker.classname == "monster_lava_man")
- bprint ("$qc_ks_hephaestus", targ.netname);
- if (attacker.classname == "monster_morph")
- bprint ("$qc_ks_guardian", targ.netname);
- if (attacker.classname == "monster_mummy")
- bprint ("$qc_ks_mummy", targ.netname);
- return;
- }
- // tricks and traps
- if (attacker.classname == "explo_box")
- {
- bprint ("$qc_ks_blew_up", targ.netname);
- return;
- }
- if (attacker.solid == SOLID_BSP && attacker != world)
- {
- bprint ("$qc_death_squish", targ.netname);
- return;
- }
- if (attacker.classname == "trap_shooter" || attacker.classname == "trap_spikeshooter")
- {
- bprint ("$qc_ks_spiked", targ.netname);
- return;
- }
- if (attacker.classname == "fireball")
- {
- bprint ("$qc_ks_lavaball", targ.netname);
- return;
- }
- if (attacker.classname == "trigger_changelevel")
- {
- bprint ("$qc_ks_tried_leave", targ.netname);
- return;
- }
- if (attacker.classname == "ltrail_start" ||
- attacker.classname == "ltrail_relay")
- {
- bprint ("$qc_ks_rode_lightning", targ.netname);
- return;
- }
- if (attacker.classname == "pendulum")
- {
- bprint ("$qc_ks_cleaved", targ.netname);
- return;
- }
- if (attacker.classname == "buzzsaw")
- {
- bprint ("$qc_ks_sliced", targ.netname);
- return;
- }
- if (attacker.classname == "plasma")
- {
- bprint ( "$qc_ks_plasma", targ.netname);
- return;
- }
- if (attacker.classname == "Vengeance")
- {
- // vengeance sphere doesn't count as a negative frag
- targ.frags = targ.frags + 1;
- bprint ( "$qc_death_vengeance", targ.netname);
- return;
- }
- if (attacker.classname == "power_shield")
- {
- // shield attacks should count for frags too..
- // shield death doesn't count as a negative frag
- targ.frags = targ.frags + 1;
- attacker.owner.frags = attacker.owner.frags + 1;
- TeamAssists(targ, attacker.owner); //PGM
- bprint("$qc_death_smashed", targ.netname, attacker.owner.netname);
- return;
- }
- // in-water deaths
- rnum = targ.watertype;
- if (rnum == -3)
- {
- if (random() < 0.5)
- bprint("$qc_death_drown1", targ.netname);
- else
- bprint("$qc_death_drown2", targ.netname);
- return;
- }
- else if (rnum == -4)
- {
- if (random() < 0.5)
- bprint("$qc_death_slime1", targ.netname);
- else
- bprint("$qc_death_slime2", targ.netname);
- return;
- }
- else if (rnum == -5)
- {
- if (targ.health < -15)
- {
- bprint("$qc_death_lava1", targ.netname);
- return;
- }
- if (random() < 0.5)
- bprint("$qc_death_lava2", targ.netname);
- else
- bprint("$qc_death_lava3", targ.netname);
- return;
- }
- if (attacker.solid == SOLID_BSP && attacker != world)
- {
- bprint("$qc_death_squish", targ.netname);
- return;
- }
- if (targ.deathtype == "falling")
- {
- targ.deathtype = string_null;
- bprint("$qc_death_fall", targ.netname);
- return;
- }
- bprint("$qc_death_died", targ.netname);
- }
- }
- };
|