123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217 |
- /*
- Copyright (C) 1997-2001 Id Software, Inc.
- 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.
- */
- #include "g_local.h"
- qboolean Pickup_Weapon (edict_t *ent, edict_t *other);
- void Use_Weapon (edict_t *ent, gitem_t *inv);
- void Drop_Weapon (edict_t *ent, gitem_t *inv);
- void Weapon_Blaster (edict_t *ent);
- void Weapon_Shotgun (edict_t *ent);
- void Weapon_SuperShotgun (edict_t *ent);
- void Weapon_Machinegun (edict_t *ent);
- void Weapon_Chaingun (edict_t *ent);
- void Weapon_HyperBlaster (edict_t *ent);
- void Weapon_RocketLauncher (edict_t *ent);
- void Weapon_Grenade (edict_t *ent);
- void Weapon_GrenadeLauncher (edict_t *ent);
- void Weapon_Railgun (edict_t *ent);
- void Weapon_BFG (edict_t *ent);
- gitem_armor_t jacketarmor_info = { 25, 50, .30, .00, ARMOR_JACKET};
- gitem_armor_t combatarmor_info = { 50, 100, .60, .30, ARMOR_COMBAT};
- gitem_armor_t bodyarmor_info = {100, 200, .80, .60, ARMOR_BODY};
- static int jacket_armor_index;
- static int combat_armor_index;
- static int body_armor_index;
- static int power_screen_index;
- static int power_shield_index;
- #define HEALTH_IGNORE_MAX 1
- #define HEALTH_TIMED 2
- void Use_Quad (edict_t *ent, gitem_t *item);
- static int quad_drop_timeout_hack;
- //======================================================================
- /*
- ===============
- GetItemByIndex
- ===============
- */
- gitem_t *GetItemByIndex (int index)
- {
- if (index == 0 || index >= game.num_items)
- return NULL;
- return &itemlist[index];
- }
- /*
- ===============
- FindItemByClassname
- ===============
- */
- gitem_t *FindItemByClassname (char *classname)
- {
- int i;
- gitem_t *it;
- it = itemlist;
- for (i=0 ; i<game.num_items ; i++, it++)
- {
- if (!it->classname)
- continue;
- if (!Q_stricmp(it->classname, classname))
- return it;
- }
- return NULL;
- }
- /*
- ===============
- FindItem
- ===============
- */
- gitem_t *FindItem (char *pickup_name)
- {
- int i;
- gitem_t *it;
- it = itemlist;
- for (i=0 ; i<game.num_items ; i++, it++)
- {
- if (!it->pickup_name)
- continue;
- if (!Q_stricmp(it->pickup_name, pickup_name))
- return it;
- }
- return NULL;
- }
- //======================================================================
- void DoRespawn (edict_t *ent)
- {
- if (ent->team)
- {
- edict_t *master;
- int count;
- int choice;
- master = ent->teammaster;
- for (count = 0, ent = master; ent; ent = ent->chain, count++)
- ;
- choice = rand() % count;
- for (count = 0, ent = master; count < choice; ent = ent->chain, count++)
- ;
- }
- ent->svflags &= ~SVF_NOCLIENT;
- ent->solid = SOLID_TRIGGER;
- gi.linkentity (ent);
- // send an effect
- ent->s.event = EV_ITEM_RESPAWN;
- }
- void SetRespawn (edict_t *ent, float delay)
- {
- ent->flags |= FL_RESPAWN;
- ent->svflags |= SVF_NOCLIENT;
- ent->solid = SOLID_NOT;
- ent->nextthink = level.time + delay;
- ent->think = DoRespawn;
- gi.linkentity (ent);
- }
- //======================================================================
- qboolean Pickup_Powerup (edict_t *ent, edict_t *other)
- {
- int quantity;
- quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)];
- if ((skill->value == 1 && quantity >= 2) || (skill->value >= 2 && quantity >= 1))
- return false;
- if ((coop->value) && (ent->item->flags & IT_STAY_COOP) && (quantity > 0))
- return false;
- other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
- if (deathmatch->value)
- {
- if (!(ent->spawnflags & DROPPED_ITEM) )
- SetRespawn (ent, ent->item->quantity);
- if (((int)dmflags->value & DF_INSTANT_ITEMS) || ((ent->item->use == Use_Quad) && (ent->spawnflags & DROPPED_PLAYER_ITEM)))
- {
- if ((ent->item->use == Use_Quad) && (ent->spawnflags & DROPPED_PLAYER_ITEM))
- quad_drop_timeout_hack = (ent->nextthink - level.time) / FRAMETIME;
- ent->item->use (other, ent->item);
- }
- }
- return true;
- }
- void Drop_General (edict_t *ent, gitem_t *item)
- {
- Drop_Item (ent, item);
- ent->client->pers.inventory[ITEM_INDEX(item)]--;
- ValidateSelectedItem (ent);
- }
- //======================================================================
- qboolean Pickup_Adrenaline (edict_t *ent, edict_t *other)
- {
- if (!deathmatch->value)
- other->max_health += 1;
- if (other->health < other->max_health)
- other->health = other->max_health;
- if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
- SetRespawn (ent, ent->item->quantity);
- return true;
- }
- qboolean Pickup_AncientHead (edict_t *ent, edict_t *other)
- {
- other->max_health += 2;
- if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
- SetRespawn (ent, ent->item->quantity);
- return true;
- }
- qboolean Pickup_Bandolier (edict_t *ent, edict_t *other)
- {
- gitem_t *item;
- int index;
- if (other->client->pers.max_bullets < 250)
- other->client->pers.max_bullets = 250;
- if (other->client->pers.max_shells < 150)
- other->client->pers.max_shells = 150;
- if (other->client->pers.max_cells < 250)
- other->client->pers.max_cells = 250;
- if (other->client->pers.max_slugs < 75)
- other->client->pers.max_slugs = 75;
- item = FindItem("Bullets");
- if (item)
- {
- index = ITEM_INDEX(item);
- other->client->pers.inventory[index] += item->quantity;
- if (other->client->pers.inventory[index] > other->client->pers.max_bullets)
- other->client->pers.inventory[index] = other->client->pers.max_bullets;
- }
- item = FindItem("Shells");
- if (item)
- {
- index = ITEM_INDEX(item);
- other->client->pers.inventory[index] += item->quantity;
- if (other->client->pers.inventory[index] > other->client->pers.max_shells)
- other->client->pers.inventory[index] = other->client->pers.max_shells;
- }
- if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
- SetRespawn (ent, ent->item->quantity);
- return true;
- }
- qboolean Pickup_Pack (edict_t *ent, edict_t *other)
- {
- gitem_t *item;
- int index;
- if (other->client->pers.max_bullets < 300)
- other->client->pers.max_bullets = 300;
- if (other->client->pers.max_shells < 200)
- other->client->pers.max_shells = 200;
- if (other->client->pers.max_rockets < 100)
- other->client->pers.max_rockets = 100;
- if (other->client->pers.max_grenades < 100)
- other->client->pers.max_grenades = 100;
- if (other->client->pers.max_cells < 300)
- other->client->pers.max_cells = 300;
- if (other->client->pers.max_slugs < 100)
- other->client->pers.max_slugs = 100;
- item = FindItem("Bullets");
- if (item)
- {
- index = ITEM_INDEX(item);
- other->client->pers.inventory[index] += item->quantity;
- if (other->client->pers.inventory[index] > other->client->pers.max_bullets)
- other->client->pers.inventory[index] = other->client->pers.max_bullets;
- }
- item = FindItem("Shells");
- if (item)
- {
- index = ITEM_INDEX(item);
- other->client->pers.inventory[index] += item->quantity;
- if (other->client->pers.inventory[index] > other->client->pers.max_shells)
- other->client->pers.inventory[index] = other->client->pers.max_shells;
- }
- item = FindItem("Cells");
- if (item)
- {
- index = ITEM_INDEX(item);
- other->client->pers.inventory[index] += item->quantity;
- if (other->client->pers.inventory[index] > other->client->pers.max_cells)
- other->client->pers.inventory[index] = other->client->pers.max_cells;
- }
- item = FindItem("Grenades");
- if (item)
- {
- index = ITEM_INDEX(item);
- other->client->pers.inventory[index] += item->quantity;
- if (other->client->pers.inventory[index] > other->client->pers.max_grenades)
- other->client->pers.inventory[index] = other->client->pers.max_grenades;
- }
- item = FindItem("Rockets");
- if (item)
- {
- index = ITEM_INDEX(item);
- other->client->pers.inventory[index] += item->quantity;
- if (other->client->pers.inventory[index] > other->client->pers.max_rockets)
- other->client->pers.inventory[index] = other->client->pers.max_rockets;
- }
- item = FindItem("Slugs");
- if (item)
- {
- index = ITEM_INDEX(item);
- other->client->pers.inventory[index] += item->quantity;
- if (other->client->pers.inventory[index] > other->client->pers.max_slugs)
- other->client->pers.inventory[index] = other->client->pers.max_slugs;
- }
- if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
- SetRespawn (ent, ent->item->quantity);
- return true;
- }
- //======================================================================
- void Use_Quad (edict_t *ent, gitem_t *item)
- {
- int timeout;
- ent->client->pers.inventory[ITEM_INDEX(item)]--;
- ValidateSelectedItem (ent);
- if (quad_drop_timeout_hack)
- {
- timeout = quad_drop_timeout_hack;
- quad_drop_timeout_hack = 0;
- }
- else
- {
- timeout = 300;
- }
- if (ent->client->quad_framenum > level.framenum)
- ent->client->quad_framenum += timeout;
- else
- ent->client->quad_framenum = level.framenum + timeout;
- gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
- }
- //======================================================================
- void Use_Breather (edict_t *ent, gitem_t *item)
- {
- ent->client->pers.inventory[ITEM_INDEX(item)]--;
- ValidateSelectedItem (ent);
- if (ent->client->breather_framenum > level.framenum)
- ent->client->breather_framenum += 300;
- else
- ent->client->breather_framenum = level.framenum + 300;
- // gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
- }
- //======================================================================
- void Use_Envirosuit (edict_t *ent, gitem_t *item)
- {
- ent->client->pers.inventory[ITEM_INDEX(item)]--;
- ValidateSelectedItem (ent);
- if (ent->client->enviro_framenum > level.framenum)
- ent->client->enviro_framenum += 300;
- else
- ent->client->enviro_framenum = level.framenum + 300;
- // gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
- }
- //======================================================================
- void Use_Invulnerability (edict_t *ent, gitem_t *item)
- {
- ent->client->pers.inventory[ITEM_INDEX(item)]--;
- ValidateSelectedItem (ent);
- if (ent->client->invincible_framenum > level.framenum)
- ent->client->invincible_framenum += 300;
- else
- ent->client->invincible_framenum = level.framenum + 300;
- gi.sound(ent, CHAN_ITEM, gi.soundindex("items/protect.wav"), 1, ATTN_NORM, 0);
- }
- //======================================================================
- void Use_Silencer (edict_t *ent, gitem_t *item)
- {
- ent->client->pers.inventory[ITEM_INDEX(item)]--;
- ValidateSelectedItem (ent);
- ent->client->silencer_shots += 30;
- // gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
- }
- //======================================================================
- qboolean Pickup_Key (edict_t *ent, edict_t *other)
- {
- if (coop->value)
- {
- if (strcmp(ent->classname, "key_power_cube") == 0)
- {
- if (other->client->pers.power_cubes & ((ent->spawnflags & 0x0000ff00)>> 8))
- return false;
- other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
- other->client->pers.power_cubes |= ((ent->spawnflags & 0x0000ff00) >> 8);
- }
- else
- {
- if (other->client->pers.inventory[ITEM_INDEX(ent->item)])
- return false;
- other->client->pers.inventory[ITEM_INDEX(ent->item)] = 1;
- }
- return true;
- }
- other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
- return true;
- }
- //======================================================================
- qboolean Add_Ammo (edict_t *ent, gitem_t *item, int count)
- {
- int index;
- int max;
- if (!ent->client)
- return false;
- if (item->tag == AMMO_BULLETS)
- max = ent->client->pers.max_bullets;
- else if (item->tag == AMMO_SHELLS)
- max = ent->client->pers.max_shells;
- else if (item->tag == AMMO_ROCKETS)
- max = ent->client->pers.max_rockets;
- else if (item->tag == AMMO_GRENADES)
- max = ent->client->pers.max_grenades;
- else if (item->tag == AMMO_CELLS)
- max = ent->client->pers.max_cells;
- else if (item->tag == AMMO_SLUGS)
- max = ent->client->pers.max_slugs;
- else
- return false;
- index = ITEM_INDEX(item);
- if (ent->client->pers.inventory[index] == max)
- return false;
- ent->client->pers.inventory[index] += count;
- if (ent->client->pers.inventory[index] > max)
- ent->client->pers.inventory[index] = max;
- return true;
- }
- qboolean Pickup_Ammo (edict_t *ent, edict_t *other)
- {
- int oldcount;
- int count;
- qboolean weapon;
- weapon = (ent->item->flags & IT_WEAPON);
- if ( (weapon) && ( (int)dmflags->value & DF_INFINITE_AMMO ) )
- count = 1000;
- else if (ent->count)
- count = ent->count;
- else
- count = ent->item->quantity;
- oldcount = other->client->pers.inventory[ITEM_INDEX(ent->item)];
- if (!Add_Ammo (other, ent->item, count))
- return false;
- if (weapon && !oldcount)
- {
- if (other->client->pers.weapon != ent->item && ( !deathmatch->value || other->client->pers.weapon == FindItem("blaster") ) )
- other->client->newweapon = ent->item;
- }
- if (!(ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM)) && (deathmatch->value))
- SetRespawn (ent, 30);
- return true;
- }
- void Drop_Ammo (edict_t *ent, gitem_t *item)
- {
- edict_t *dropped;
- int index;
- index = ITEM_INDEX(item);
- dropped = Drop_Item (ent, item);
- if (ent->client->pers.inventory[index] >= item->quantity)
- dropped->count = item->quantity;
- else
- dropped->count = ent->client->pers.inventory[index];
- if (ent->client->pers.weapon &&
- ent->client->pers.weapon->tag == AMMO_GRENADES &&
- item->tag == AMMO_GRENADES &&
- ent->client->pers.inventory[index] - dropped->count <= 0) {
- gi.cprintf (ent, PRINT_HIGH, "Can't drop current weapon\n");
- G_FreeEdict(dropped);
- return;
- }
- ent->client->pers.inventory[index] -= dropped->count;
- ValidateSelectedItem (ent);
- }
- //======================================================================
- void MegaHealth_think (edict_t *self)
- {
- if (self->owner->health > self->owner->max_health)
- {
- self->nextthink = level.time + 1;
- self->owner->health -= 1;
- return;
- }
- if (!(self->spawnflags & DROPPED_ITEM) && (deathmatch->value))
- SetRespawn (self, 20);
- else
- G_FreeEdict (self);
- }
- qboolean Pickup_Health (edict_t *ent, edict_t *other)
- {
- if (!(ent->style & HEALTH_IGNORE_MAX))
- if (other->health >= other->max_health)
- return false;
- other->health += ent->count;
- if (!(ent->style & HEALTH_IGNORE_MAX))
- {
- if (other->health > other->max_health)
- other->health = other->max_health;
- }
- if (ent->style & HEALTH_TIMED)
- {
- ent->think = MegaHealth_think;
- ent->nextthink = level.time + 5;
- ent->owner = other;
- ent->flags |= FL_RESPAWN;
- ent->svflags |= SVF_NOCLIENT;
- ent->solid = SOLID_NOT;
- }
- else
- {
- if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
- SetRespawn (ent, 30);
- }
- return true;
- }
- //======================================================================
- int ArmorIndex (edict_t *ent)
- {
- if (!ent->client)
- return 0;
- if (ent->client->pers.inventory[jacket_armor_index] > 0)
- return jacket_armor_index;
- if (ent->client->pers.inventory[combat_armor_index] > 0)
- return combat_armor_index;
- if (ent->client->pers.inventory[body_armor_index] > 0)
- return body_armor_index;
- return 0;
- }
- qboolean Pickup_Armor (edict_t *ent, edict_t *other)
- {
- int old_armor_index;
- gitem_armor_t *oldinfo;
- gitem_armor_t *newinfo;
- int newcount;
- float salvage;
- int salvagecount;
- // get info on new armor
- newinfo = (gitem_armor_t *)ent->item->info;
- old_armor_index = ArmorIndex (other);
- // handle armor shards specially
- if (ent->item->tag == ARMOR_SHARD)
- {
- if (!old_armor_index)
- other->client->pers.inventory[jacket_armor_index] = 2;
- else
- other->client->pers.inventory[old_armor_index] += 2;
- }
- // if player has no armor, just use it
- else if (!old_armor_index)
- {
- other->client->pers.inventory[ITEM_INDEX(ent->item)] = newinfo->base_count;
- }
- // use the better armor
- else
- {
- // get info on old armor
- if (old_armor_index == jacket_armor_index)
- oldinfo = &jacketarmor_info;
- else if (old_armor_index == combat_armor_index)
- oldinfo = &combatarmor_info;
- else // (old_armor_index == body_armor_index)
- oldinfo = &bodyarmor_info;
- if (newinfo->normal_protection > oldinfo->normal_protection)
- {
- // calc new armor values
- salvage = oldinfo->normal_protection / newinfo->normal_protection;
- salvagecount = salvage * other->client->pers.inventory[old_armor_index];
- newcount = newinfo->base_count + salvagecount;
- if (newcount > newinfo->max_count)
- newcount = newinfo->max_count;
- // zero count of old armor so it goes away
- other->client->pers.inventory[old_armor_index] = 0;
- // change armor to new item with computed value
- other->client->pers.inventory[ITEM_INDEX(ent->item)] = newcount;
- }
- else
- {
- // calc new armor values
- salvage = newinfo->normal_protection / oldinfo->normal_protection;
- salvagecount = salvage * newinfo->base_count;
- newcount = other->client->pers.inventory[old_armor_index] + salvagecount;
- if (newcount > oldinfo->max_count)
- newcount = oldinfo->max_count;
- // if we're already maxed out then we don't need the new armor
- if (other->client->pers.inventory[old_armor_index] >= newcount)
- return false;
- // update current armor value
- other->client->pers.inventory[old_armor_index] = newcount;
- }
- }
- if (!(ent->spawnflags & DROPPED_ITEM) && (deathmatch->value))
- SetRespawn (ent, 20);
- return true;
- }
- //======================================================================
- int PowerArmorType (edict_t *ent)
- {
- if (!ent->client)
- return POWER_ARMOR_NONE;
- if (!(ent->flags & FL_POWER_ARMOR))
- return POWER_ARMOR_NONE;
- if (ent->client->pers.inventory[power_shield_index] > 0)
- return POWER_ARMOR_SHIELD;
- if (ent->client->pers.inventory[power_screen_index] > 0)
- return POWER_ARMOR_SCREEN;
- return POWER_ARMOR_NONE;
- }
- void Use_PowerArmor (edict_t *ent, gitem_t *item)
- {
- int index;
- if (ent->flags & FL_POWER_ARMOR)
- {
- ent->flags &= ~FL_POWER_ARMOR;
- gi.sound(ent, CHAN_AUTO, gi.soundindex("misc/power2.wav"), 1, ATTN_NORM, 0);
- }
- else
- {
- index = ITEM_INDEX(FindItem("cells"));
- if (!ent->client->pers.inventory[index])
- {
- gi.cprintf (ent, PRINT_HIGH, "No cells for power armor.\n");
- return;
- }
- ent->flags |= FL_POWER_ARMOR;
- gi.sound(ent, CHAN_AUTO, gi.soundindex("misc/power1.wav"), 1, ATTN_NORM, 0);
- }
- }
- qboolean Pickup_PowerArmor (edict_t *ent, edict_t *other)
- {
- int quantity;
- quantity = other->client->pers.inventory[ITEM_INDEX(ent->item)];
- other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
- if (deathmatch->value)
- {
- if (!(ent->spawnflags & DROPPED_ITEM) )
- SetRespawn (ent, ent->item->quantity);
- // auto-use for DM only if we didn't already have one
- if (!quantity)
- ent->item->use (other, ent->item);
- }
- return true;
- }
- void Drop_PowerArmor (edict_t *ent, gitem_t *item)
- {
- if ((ent->flags & FL_POWER_ARMOR) && (ent->client->pers.inventory[ITEM_INDEX(item)] == 1))
- Use_PowerArmor (ent, item);
- Drop_General (ent, item);
- }
- //======================================================================
- /*
- ===============
- Touch_Item
- ===============
- */
- void Touch_Item (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
- {
- qboolean taken;
- if (!other->client)
- return;
- if (other->health < 1)
- return; // dead people can't pickup
- if (!ent->item->pickup)
- return; // not a grabbable item?
- taken = ent->item->pickup(ent, other);
- if (taken)
- {
- // flash the screen
- other->client->bonus_alpha = 0.25;
- // show icon and name on status bar
- other->client->ps.stats[STAT_PICKUP_ICON] = gi.imageindex(ent->item->icon);
- other->client->ps.stats[STAT_PICKUP_STRING] = CS_ITEMS+ITEM_INDEX(ent->item);
- other->client->pickup_msg_time = level.time + 3.0;
- // change selected item
- if (ent->item->use)
- other->client->pers.selected_item = other->client->ps.stats[STAT_SELECTED_ITEM] = ITEM_INDEX(ent->item);
- if (ent->item->pickup == Pickup_Health)
- {
- if (ent->count == 2)
- gi.sound(other, CHAN_ITEM, gi.soundindex("items/s_health.wav"), 1, ATTN_NORM, 0);
- else if (ent->count == 10)
- gi.sound(other, CHAN_ITEM, gi.soundindex("items/n_health.wav"), 1, ATTN_NORM, 0);
- else if (ent->count == 25)
- gi.sound(other, CHAN_ITEM, gi.soundindex("items/l_health.wav"), 1, ATTN_NORM, 0);
- else // (ent->count == 100)
- gi.sound(other, CHAN_ITEM, gi.soundindex("items/m_health.wav"), 1, ATTN_NORM, 0);
- }
- else if (ent->item->pickup_sound)
- {
- gi.sound(other, CHAN_ITEM, gi.soundindex(ent->item->pickup_sound), 1, ATTN_NORM, 0);
- }
- }
- if (!(ent->spawnflags & ITEM_TARGETS_USED))
- {
- G_UseTargets (ent, other);
- ent->spawnflags |= ITEM_TARGETS_USED;
- }
- if (!taken)
- return;
- if (!((coop->value) && (ent->item->flags & IT_STAY_COOP)) || (ent->spawnflags & (DROPPED_ITEM | DROPPED_PLAYER_ITEM)))
- {
- if (ent->flags & FL_RESPAWN)
- ent->flags &= ~FL_RESPAWN;
- else
- G_FreeEdict (ent);
- }
- }
- //======================================================================
- static void drop_temp_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
- {
- if (other == ent->owner)
- return;
- Touch_Item (ent, other, plane, surf);
- }
- static void drop_make_touchable (edict_t *ent)
- {
- ent->touch = Touch_Item;
- if (deathmatch->value)
- {
- ent->nextthink = level.time + 29;
- ent->think = G_FreeEdict;
- }
- }
- edict_t *Drop_Item (edict_t *ent, gitem_t *item)
- {
- edict_t *dropped;
- vec3_t forward, right;
- vec3_t offset;
- dropped = G_Spawn();
- dropped->classname = item->classname;
- dropped->item = item;
- dropped->spawnflags = DROPPED_ITEM;
- dropped->s.effects = item->world_model_flags;
- dropped->s.renderfx = RF_GLOW;
- VectorSet (dropped->mins, -15, -15, -15);
- VectorSet (dropped->maxs, 15, 15, 15);
- gi.setmodel (dropped, dropped->item->world_model);
- dropped->solid = SOLID_TRIGGER;
- dropped->movetype = MOVETYPE_TOSS;
- dropped->touch = drop_temp_touch;
- dropped->owner = ent;
- if (ent->client)
- {
- trace_t trace;
- AngleVectors (ent->client->v_angle, forward, right, NULL);
- VectorSet(offset, 24, 0, -16);
- G_ProjectSource (ent->s.origin, offset, forward, right, dropped->s.origin);
- trace = gi.trace (ent->s.origin, dropped->mins, dropped->maxs,
- dropped->s.origin, ent, CONTENTS_SOLID);
- VectorCopy (trace.endpos, dropped->s.origin);
- }
- else
- {
- AngleVectors (ent->s.angles, forward, right, NULL);
- VectorCopy (ent->s.origin, dropped->s.origin);
- }
- VectorScale (forward, 100, dropped->velocity);
- dropped->velocity[2] = 300;
- dropped->think = drop_make_touchable;
- dropped->nextthink = level.time + 1;
- gi.linkentity (dropped);
- return dropped;
- }
- void Use_Item (edict_t *ent, edict_t *other, edict_t *activator)
- {
- ent->svflags &= ~SVF_NOCLIENT;
- ent->use = NULL;
- if (ent->spawnflags & ITEM_NO_TOUCH)
- {
- ent->solid = SOLID_BBOX;
- ent->touch = NULL;
- }
- else
- {
- ent->solid = SOLID_TRIGGER;
- ent->touch = Touch_Item;
- }
- gi.linkentity (ent);
- }
- //======================================================================
- /*
- ================
- droptofloor
- ================
- */
- void droptofloor (edict_t *ent)
- {
- trace_t tr;
- vec3_t dest;
- float *v;
- v = tv(-15,-15,-15);
- VectorCopy (v, ent->mins);
- v = tv(15,15,15);
- VectorCopy (v, ent->maxs);
- if (ent->model)
- gi.setmodel (ent, ent->model);
- else
- gi.setmodel (ent, ent->item->world_model);
- ent->solid = SOLID_TRIGGER;
- ent->movetype = MOVETYPE_TOSS;
- ent->touch = Touch_Item;
- v = tv(0,0,-128);
- VectorAdd (ent->s.origin, v, dest);
- tr = gi.trace (ent->s.origin, ent->mins, ent->maxs, dest, ent, MASK_SOLID);
- if (tr.startsolid)
- {
- gi.dprintf ("droptofloor: %s startsolid at %s\n", ent->classname, vtos(ent->s.origin));
- G_FreeEdict (ent);
- return;
- }
- VectorCopy (tr.endpos, ent->s.origin);
- if (ent->team)
- {
- ent->flags &= ~FL_TEAMSLAVE;
- ent->chain = ent->teamchain;
- ent->teamchain = NULL;
- ent->svflags |= SVF_NOCLIENT;
- ent->solid = SOLID_NOT;
- if (ent == ent->teammaster)
- {
- ent->nextthink = level.time + FRAMETIME;
- ent->think = DoRespawn;
- }
- }
- if (ent->spawnflags & ITEM_NO_TOUCH)
- {
- ent->solid = SOLID_BBOX;
- ent->touch = NULL;
- ent->s.effects &= ~EF_ROTATE;
- ent->s.renderfx &= ~RF_GLOW;
- }
- if (ent->spawnflags & ITEM_TRIGGER_SPAWN)
- {
- ent->svflags |= SVF_NOCLIENT;
- ent->solid = SOLID_NOT;
- ent->use = Use_Item;
- }
- gi.linkentity (ent);
- }
- /*
- ===============
- PrecacheItem
- Precaches all data needed for a given item.
- This will be called for each item spawned in a level,
- and for each item in each client's inventory.
- ===============
- */
- void PrecacheItem (gitem_t *it)
- {
- char *s, *start;
- char data[MAX_QPATH];
- int len;
- gitem_t *ammo;
- if (!it)
- return;
- if (it->pickup_sound)
- gi.soundindex (it->pickup_sound);
- if (it->world_model)
- gi.modelindex (it->world_model);
- if (it->view_model)
- gi.modelindex (it->view_model);
- if (it->icon)
- gi.imageindex (it->icon);
- // parse everything for its ammo
- if (it->ammo && it->ammo[0])
- {
- ammo = FindItem (it->ammo);
- if (ammo != it)
- PrecacheItem (ammo);
- }
- // parse the space seperated precache string for other items
- s = it->precaches;
- if (!s || !s[0])
- return;
- while (*s)
- {
- start = s;
- while (*s && *s != ' ')
- s++;
- len = s-start;
- if (len >= MAX_QPATH || len < 5)
- gi.error ("PrecacheItem: %s has bad precache string", it->classname);
- memcpy (data, start, len);
- data[len] = 0;
- if (*s)
- s++;
- // determine type based on extension
- if (!strcmp(data+len-3, "md2"))
- gi.modelindex (data);
- else if (!strcmp(data+len-3, "sp2"))
- gi.modelindex (data);
- else if (!strcmp(data+len-3, "wav"))
- gi.soundindex (data);
- if (!strcmp(data+len-3, "pcx"))
- gi.imageindex (data);
- }
- }
- /*
- ============
- SpawnItem
- Sets the clipping size and plants the object on the floor.
- Items can't be immediately dropped to floor, because they might
- be on an entity that hasn't spawned yet.
- ============
- */
- void SpawnItem (edict_t *ent, gitem_t *item)
- {
- PrecacheItem (item);
- if (ent->spawnflags)
- {
- if (strcmp(ent->classname, "key_power_cube") != 0)
- {
- ent->spawnflags = 0;
- gi.dprintf("%s at %s has invalid spawnflags set\n", ent->classname, vtos(ent->s.origin));
- }
- }
- // some items will be prevented in deathmatch
- if (deathmatch->value)
- {
- if ( (int)dmflags->value & DF_NO_ARMOR )
- {
- if (item->pickup == Pickup_Armor || item->pickup == Pickup_PowerArmor)
- {
- G_FreeEdict (ent);
- return;
- }
- }
- if ( (int)dmflags->value & DF_NO_ITEMS )
- {
- if (item->pickup == Pickup_Powerup)
- {
- G_FreeEdict (ent);
- return;
- }
- }
- if ( (int)dmflags->value & DF_NO_HEALTH )
- {
- if (item->pickup == Pickup_Health || item->pickup == Pickup_Adrenaline || item->pickup == Pickup_AncientHead)
- {
- G_FreeEdict (ent);
- return;
- }
- }
- if ( (int)dmflags->value & DF_INFINITE_AMMO )
- {
- if ( (item->flags == IT_AMMO) || (strcmp(ent->classname, "weapon_bfg") == 0) )
- {
- G_FreeEdict (ent);
- return;
- }
- }
- }
- if (coop->value && (strcmp(ent->classname, "key_power_cube") == 0))
- {
- ent->spawnflags |= (1 << (8 + level.power_cubes));
- level.power_cubes++;
- }
- // don't let them drop items that stay in a coop game
- if ((coop->value) && (item->flags & IT_STAY_COOP))
- {
- item->drop = NULL;
- }
- ent->item = item;
- ent->nextthink = level.time + 2 * FRAMETIME; // items start after other solids
- ent->think = droptofloor;
- ent->s.effects = item->world_model_flags;
- ent->s.renderfx = RF_GLOW;
- if (ent->model)
- gi.modelindex (ent->model);
- }
- //======================================================================
- gitem_t itemlist[] =
- {
- {
- NULL
- }, // leave index 0 alone
- //
- // ARMOR
- //
- /*QUAKED item_armor_body (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "item_armor_body",
- Pickup_Armor,
- NULL,
- NULL,
- NULL,
- "misc/ar1_pkup.wav",
- "models/items/armor/body/tris.md2", EF_ROTATE,
- NULL,
- /* icon */ "i_bodyarmor",
- /* pickup */ "Body Armor",
- /* width */ 3,
- 0,
- NULL,
- IT_ARMOR,
- 0,
- &bodyarmor_info,
- ARMOR_BODY,
- /* precache */ ""
- },
- /*QUAKED item_armor_combat (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "item_armor_combat",
- Pickup_Armor,
- NULL,
- NULL,
- NULL,
- "misc/ar1_pkup.wav",
- "models/items/armor/combat/tris.md2", EF_ROTATE,
- NULL,
- /* icon */ "i_combatarmor",
- /* pickup */ "Combat Armor",
- /* width */ 3,
- 0,
- NULL,
- IT_ARMOR,
- 0,
- &combatarmor_info,
- ARMOR_COMBAT,
- /* precache */ ""
- },
- /*QUAKED item_armor_jacket (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "item_armor_jacket",
- Pickup_Armor,
- NULL,
- NULL,
- NULL,
- "misc/ar1_pkup.wav",
- "models/items/armor/jacket/tris.md2", EF_ROTATE,
- NULL,
- /* icon */ "i_jacketarmor",
- /* pickup */ "Jacket Armor",
- /* width */ 3,
- 0,
- NULL,
- IT_ARMOR,
- 0,
- &jacketarmor_info,
- ARMOR_JACKET,
- /* precache */ ""
- },
- /*QUAKED item_armor_shard (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "item_armor_shard",
- Pickup_Armor,
- NULL,
- NULL,
- NULL,
- "misc/ar2_pkup.wav",
- "models/items/armor/shard/tris.md2", EF_ROTATE,
- NULL,
- /* icon */ "i_jacketarmor",
- /* pickup */ "Armor Shard",
- /* width */ 3,
- 0,
- NULL,
- IT_ARMOR,
- 0,
- NULL,
- ARMOR_SHARD,
- /* precache */ ""
- },
- /*QUAKED item_power_screen (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "item_power_screen",
- Pickup_PowerArmor,
- Use_PowerArmor,
- Drop_PowerArmor,
- NULL,
- "misc/ar3_pkup.wav",
- "models/items/armor/screen/tris.md2", EF_ROTATE,
- NULL,
- /* icon */ "i_powerscreen",
- /* pickup */ "Power Screen",
- /* width */ 0,
- 60,
- NULL,
- IT_ARMOR,
- 0,
- NULL,
- 0,
- /* precache */ ""
- },
- /*QUAKED item_power_shield (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "item_power_shield",
- Pickup_PowerArmor,
- Use_PowerArmor,
- Drop_PowerArmor,
- NULL,
- "misc/ar3_pkup.wav",
- "models/items/armor/shield/tris.md2", EF_ROTATE,
- NULL,
- /* icon */ "i_powershield",
- /* pickup */ "Power Shield",
- /* width */ 0,
- 60,
- NULL,
- IT_ARMOR,
- 0,
- NULL,
- 0,
- /* precache */ "misc/power2.wav misc/power1.wav"
- },
- //
- // WEAPONS
- //
- /* weapon_blaster (.3 .3 1) (-16 -16 -16) (16 16 16)
- always owned, never in the world
- */
- {
- "weapon_blaster",
- NULL,
- Use_Weapon,
- NULL,
- Weapon_Blaster,
- "misc/w_pkup.wav",
- NULL, 0,
- "models/weapons/v_blast/tris.md2",
- /* icon */ "w_blaster",
- /* pickup */ "Blaster",
- 0,
- 0,
- NULL,
- IT_WEAPON|IT_STAY_COOP,
- WEAP_BLASTER,
- NULL,
- 0,
- /* precache */ "weapons/blastf1a.wav misc/lasfly.wav"
- },
- /*QUAKED weapon_shotgun (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "weapon_shotgun",
- Pickup_Weapon,
- Use_Weapon,
- Drop_Weapon,
- Weapon_Shotgun,
- "misc/w_pkup.wav",
- "models/weapons/g_shotg/tris.md2", EF_ROTATE,
- "models/weapons/v_shotg/tris.md2",
- /* icon */ "w_shotgun",
- /* pickup */ "Shotgun",
- 0,
- 1,
- "Shells",
- IT_WEAPON|IT_STAY_COOP,
- WEAP_SHOTGUN,
- NULL,
- 0,
- /* precache */ "weapons/shotgf1b.wav weapons/shotgr1b.wav"
- },
- /*QUAKED weapon_supershotgun (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "weapon_supershotgun",
- Pickup_Weapon,
- Use_Weapon,
- Drop_Weapon,
- Weapon_SuperShotgun,
- "misc/w_pkup.wav",
- "models/weapons/g_shotg2/tris.md2", EF_ROTATE,
- "models/weapons/v_shotg2/tris.md2",
- /* icon */ "w_sshotgun",
- /* pickup */ "Super Shotgun",
- 0,
- 2,
- "Shells",
- IT_WEAPON|IT_STAY_COOP,
- WEAP_SUPERSHOTGUN,
- NULL,
- 0,
- /* precache */ "weapons/sshotf1b.wav"
- },
- /*QUAKED weapon_machinegun (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "weapon_machinegun",
- Pickup_Weapon,
- Use_Weapon,
- Drop_Weapon,
- Weapon_Machinegun,
- "misc/w_pkup.wav",
- "models/weapons/g_machn/tris.md2", EF_ROTATE,
- "models/weapons/v_machn/tris.md2",
- /* icon */ "w_machinegun",
- /* pickup */ "Machinegun",
- 0,
- 1,
- "Bullets",
- IT_WEAPON|IT_STAY_COOP,
- WEAP_MACHINEGUN,
- NULL,
- 0,
- /* precache */ "weapons/machgf1b.wav weapons/machgf2b.wav weapons/machgf3b.wav weapons/machgf4b.wav weapons/machgf5b.wav"
- },
- /*QUAKED weapon_chaingun (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "weapon_chaingun",
- Pickup_Weapon,
- Use_Weapon,
- Drop_Weapon,
- Weapon_Chaingun,
- "misc/w_pkup.wav",
- "models/weapons/g_chain/tris.md2", EF_ROTATE,
- "models/weapons/v_chain/tris.md2",
- /* icon */ "w_chaingun",
- /* pickup */ "Chaingun",
- 0,
- 1,
- "Bullets",
- IT_WEAPON|IT_STAY_COOP,
- WEAP_CHAINGUN,
- NULL,
- 0,
- /* precache */ "weapons/chngnu1a.wav weapons/chngnl1a.wav weapons/machgf3b.wav` weapons/chngnd1a.wav"
- },
- /*QUAKED ammo_grenades (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "ammo_grenades",
- Pickup_Ammo,
- Use_Weapon,
- Drop_Ammo,
- Weapon_Grenade,
- "misc/am_pkup.wav",
- "models/items/ammo/grenades/medium/tris.md2", 0,
- "models/weapons/v_handgr/tris.md2",
- /* icon */ "a_grenades",
- /* pickup */ "Grenades",
- /* width */ 3,
- 5,
- "grenades",
- IT_AMMO|IT_WEAPON,
- WEAP_GRENADES,
- NULL,
- AMMO_GRENADES,
- /* precache */ "weapons/hgrent1a.wav weapons/hgrena1b.wav weapons/hgrenc1b.wav weapons/hgrenb1a.wav weapons/hgrenb2a.wav "
- },
- /*QUAKED weapon_grenadelauncher (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "weapon_grenadelauncher",
- Pickup_Weapon,
- Use_Weapon,
- Drop_Weapon,
- Weapon_GrenadeLauncher,
- "misc/w_pkup.wav",
- "models/weapons/g_launch/tris.md2", EF_ROTATE,
- "models/weapons/v_launch/tris.md2",
- /* icon */ "w_glauncher",
- /* pickup */ "Grenade Launcher",
- 0,
- 1,
- "Grenades",
- IT_WEAPON|IT_STAY_COOP,
- WEAP_GRENADELAUNCHER,
- NULL,
- 0,
- /* precache */ "models/objects/grenade/tris.md2 weapons/grenlf1a.wav weapons/grenlr1b.wav weapons/grenlb1b.wav"
- },
- /*QUAKED weapon_rocketlauncher (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "weapon_rocketlauncher",
- Pickup_Weapon,
- Use_Weapon,
- Drop_Weapon,
- Weapon_RocketLauncher,
- "misc/w_pkup.wav",
- "models/weapons/g_rocket/tris.md2", EF_ROTATE,
- "models/weapons/v_rocket/tris.md2",
- /* icon */ "w_rlauncher",
- /* pickup */ "Rocket Launcher",
- 0,
- 1,
- "Rockets",
- IT_WEAPON|IT_STAY_COOP,
- WEAP_ROCKETLAUNCHER,
- NULL,
- 0,
- /* precache */ "models/objects/rocket/tris.md2 weapons/rockfly.wav weapons/rocklf1a.wav weapons/rocklr1b.wav models/objects/debris2/tris.md2"
- },
- /*QUAKED weapon_hyperblaster (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "weapon_hyperblaster",
- Pickup_Weapon,
- Use_Weapon,
- Drop_Weapon,
- Weapon_HyperBlaster,
- "misc/w_pkup.wav",
- "models/weapons/g_hyperb/tris.md2", EF_ROTATE,
- "models/weapons/v_hyperb/tris.md2",
- /* icon */ "w_hyperblaster",
- /* pickup */ "HyperBlaster",
- 0,
- 1,
- "Cells",
- IT_WEAPON|IT_STAY_COOP,
- WEAP_HYPERBLASTER,
- NULL,
- 0,
- /* precache */ "weapons/hyprbu1a.wav weapons/hyprbl1a.wav weapons/hyprbf1a.wav weapons/hyprbd1a.wav misc/lasfly.wav"
- },
- /*QUAKED weapon_railgun (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "weapon_railgun",
- Pickup_Weapon,
- Use_Weapon,
- Drop_Weapon,
- Weapon_Railgun,
- "misc/w_pkup.wav",
- "models/weapons/g_rail/tris.md2", EF_ROTATE,
- "models/weapons/v_rail/tris.md2",
- /* icon */ "w_railgun",
- /* pickup */ "Railgun",
- 0,
- 1,
- "Slugs",
- IT_WEAPON|IT_STAY_COOP,
- WEAP_RAILGUN,
- NULL,
- 0,
- /* precache */ "weapons/rg_hum.wav"
- },
- /*QUAKED weapon_bfg (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "weapon_bfg",
- Pickup_Weapon,
- Use_Weapon,
- Drop_Weapon,
- Weapon_BFG,
- "misc/w_pkup.wav",
- "models/weapons/g_bfg/tris.md2", EF_ROTATE,
- "models/weapons/v_bfg/tris.md2",
- /* icon */ "w_bfg",
- /* pickup */ "BFG10K",
- 0,
- 50,
- "Cells",
- IT_WEAPON|IT_STAY_COOP,
- WEAP_BFG,
- NULL,
- 0,
- /* precache */ "sprites/s_bfg1.sp2 sprites/s_bfg2.sp2 sprites/s_bfg3.sp2 weapons/bfg__f1y.wav weapons/bfg__l1a.wav weapons/bfg__x1b.wav weapons/bfg_hum.wav"
- },
- //
- // AMMO ITEMS
- //
- /*QUAKED ammo_shells (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "ammo_shells",
- Pickup_Ammo,
- NULL,
- Drop_Ammo,
- NULL,
- "misc/am_pkup.wav",
- "models/items/ammo/shells/medium/tris.md2", 0,
- NULL,
- /* icon */ "a_shells",
- /* pickup */ "Shells",
- /* width */ 3,
- 10,
- NULL,
- IT_AMMO,
- 0,
- NULL,
- AMMO_SHELLS,
- /* precache */ ""
- },
- /*QUAKED ammo_bullets (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "ammo_bullets",
- Pickup_Ammo,
- NULL,
- Drop_Ammo,
- NULL,
- "misc/am_pkup.wav",
- "models/items/ammo/bullets/medium/tris.md2", 0,
- NULL,
- /* icon */ "a_bullets",
- /* pickup */ "Bullets",
- /* width */ 3,
- 50,
- NULL,
- IT_AMMO,
- 0,
- NULL,
- AMMO_BULLETS,
- /* precache */ ""
- },
- /*QUAKED ammo_cells (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "ammo_cells",
- Pickup_Ammo,
- NULL,
- Drop_Ammo,
- NULL,
- "misc/am_pkup.wav",
- "models/items/ammo/cells/medium/tris.md2", 0,
- NULL,
- /* icon */ "a_cells",
- /* pickup */ "Cells",
- /* width */ 3,
- 50,
- NULL,
- IT_AMMO,
- 0,
- NULL,
- AMMO_CELLS,
- /* precache */ ""
- },
- /*QUAKED ammo_rockets (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "ammo_rockets",
- Pickup_Ammo,
- NULL,
- Drop_Ammo,
- NULL,
- "misc/am_pkup.wav",
- "models/items/ammo/rockets/medium/tris.md2", 0,
- NULL,
- /* icon */ "a_rockets",
- /* pickup */ "Rockets",
- /* width */ 3,
- 5,
- NULL,
- IT_AMMO,
- 0,
- NULL,
- AMMO_ROCKETS,
- /* precache */ ""
- },
- /*QUAKED ammo_slugs (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "ammo_slugs",
- Pickup_Ammo,
- NULL,
- Drop_Ammo,
- NULL,
- "misc/am_pkup.wav",
- "models/items/ammo/slugs/medium/tris.md2", 0,
- NULL,
- /* icon */ "a_slugs",
- /* pickup */ "Slugs",
- /* width */ 3,
- 10,
- NULL,
- IT_AMMO,
- 0,
- NULL,
- AMMO_SLUGS,
- /* precache */ ""
- },
- //
- // POWERUP ITEMS
- //
- /*QUAKED item_quad (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "item_quad",
- Pickup_Powerup,
- Use_Quad,
- Drop_General,
- NULL,
- "items/pkup.wav",
- "models/items/quaddama/tris.md2", EF_ROTATE,
- NULL,
- /* icon */ "p_quad",
- /* pickup */ "Quad Damage",
- /* width */ 2,
- 60,
- NULL,
- IT_POWERUP,
- 0,
- NULL,
- 0,
- /* precache */ "items/damage.wav items/damage2.wav items/damage3.wav"
- },
- /*QUAKED item_invulnerability (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "item_invulnerability",
- Pickup_Powerup,
- Use_Invulnerability,
- Drop_General,
- NULL,
- "items/pkup.wav",
- "models/items/invulner/tris.md2", EF_ROTATE,
- NULL,
- /* icon */ "p_invulnerability",
- /* pickup */ "Invulnerability",
- /* width */ 2,
- 300,
- NULL,
- IT_POWERUP,
- 0,
- NULL,
- 0,
- /* precache */ "items/protect.wav items/protect2.wav items/protect4.wav"
- },
- /*QUAKED item_silencer (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "item_silencer",
- Pickup_Powerup,
- Use_Silencer,
- Drop_General,
- NULL,
- "items/pkup.wav",
- "models/items/silencer/tris.md2", EF_ROTATE,
- NULL,
- /* icon */ "p_silencer",
- /* pickup */ "Silencer",
- /* width */ 2,
- 60,
- NULL,
- IT_POWERUP,
- 0,
- NULL,
- 0,
- /* precache */ ""
- },
- /*QUAKED item_breather (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "item_breather",
- Pickup_Powerup,
- Use_Breather,
- Drop_General,
- NULL,
- "items/pkup.wav",
- "models/items/breather/tris.md2", EF_ROTATE,
- NULL,
- /* icon */ "p_rebreather",
- /* pickup */ "Rebreather",
- /* width */ 2,
- 60,
- NULL,
- IT_STAY_COOP|IT_POWERUP,
- 0,
- NULL,
- 0,
- /* precache */ "items/airout.wav"
- },
- /*QUAKED item_enviro (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "item_enviro",
- Pickup_Powerup,
- Use_Envirosuit,
- Drop_General,
- NULL,
- "items/pkup.wav",
- "models/items/enviro/tris.md2", EF_ROTATE,
- NULL,
- /* icon */ "p_envirosuit",
- /* pickup */ "Environment Suit",
- /* width */ 2,
- 60,
- NULL,
- IT_STAY_COOP|IT_POWERUP,
- 0,
- NULL,
- 0,
- /* precache */ "items/airout.wav"
- },
- /*QUAKED item_ancient_head (.3 .3 1) (-16 -16 -16) (16 16 16)
- Special item that gives +2 to maximum health
- */
- {
- "item_ancient_head",
- Pickup_AncientHead,
- NULL,
- NULL,
- NULL,
- "items/pkup.wav",
- "models/items/c_head/tris.md2", EF_ROTATE,
- NULL,
- /* icon */ "i_fixme",
- /* pickup */ "Ancient Head",
- /* width */ 2,
- 60,
- NULL,
- 0,
- 0,
- NULL,
- 0,
- /* precache */ ""
- },
- /*QUAKED item_adrenaline (.3 .3 1) (-16 -16 -16) (16 16 16)
- gives +1 to maximum health
- */
- {
- "item_adrenaline",
- Pickup_Adrenaline,
- NULL,
- NULL,
- NULL,
- "items/pkup.wav",
- "models/items/adrenal/tris.md2", EF_ROTATE,
- NULL,
- /* icon */ "p_adrenaline",
- /* pickup */ "Adrenaline",
- /* width */ 2,
- 60,
- NULL,
- 0,
- 0,
- NULL,
- 0,
- /* precache */ ""
- },
- /*QUAKED item_bandolier (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "item_bandolier",
- Pickup_Bandolier,
- NULL,
- NULL,
- NULL,
- "items/pkup.wav",
- "models/items/band/tris.md2", EF_ROTATE,
- NULL,
- /* icon */ "p_bandolier",
- /* pickup */ "Bandolier",
- /* width */ 2,
- 60,
- NULL,
- 0,
- 0,
- NULL,
- 0,
- /* precache */ ""
- },
- /*QUAKED item_pack (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- {
- "item_pack",
- Pickup_Pack,
- NULL,
- NULL,
- NULL,
- "items/pkup.wav",
- "models/items/pack/tris.md2", EF_ROTATE,
- NULL,
- /* icon */ "i_pack",
- /* pickup */ "Ammo Pack",
- /* width */ 2,
- 180,
- NULL,
- 0,
- 0,
- NULL,
- 0,
- /* precache */ ""
- },
- //
- // KEYS
- //
- /*QUAKED key_data_cd (0 .5 .8) (-16 -16 -16) (16 16 16)
- key for computer centers
- */
- {
- "key_data_cd",
- Pickup_Key,
- NULL,
- Drop_General,
- NULL,
- "items/pkup.wav",
- "models/items/keys/data_cd/tris.md2", EF_ROTATE,
- NULL,
- "k_datacd",
- "Data CD",
- 2,
- 0,
- NULL,
- IT_STAY_COOP|IT_KEY,
- 0,
- NULL,
- 0,
- /* precache */ ""
- },
- /*QUAKED key_power_cube (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN NO_TOUCH
- warehouse circuits
- */
- {
- "key_power_cube",
- Pickup_Key,
- NULL,
- Drop_General,
- NULL,
- "items/pkup.wav",
- "models/items/keys/power/tris.md2", EF_ROTATE,
- NULL,
- "k_powercube",
- "Power Cube",
- 2,
- 0,
- NULL,
- IT_STAY_COOP|IT_KEY,
- 0,
- NULL,
- 0,
- /* precache */ ""
- },
- /*QUAKED key_pyramid (0 .5 .8) (-16 -16 -16) (16 16 16)
- key for the entrance of jail3
- */
- {
- "key_pyramid",
- Pickup_Key,
- NULL,
- Drop_General,
- NULL,
- "items/pkup.wav",
- "models/items/keys/pyramid/tris.md2", EF_ROTATE,
- NULL,
- "k_pyramid",
- "Pyramid Key",
- 2,
- 0,
- NULL,
- IT_STAY_COOP|IT_KEY,
- 0,
- NULL,
- 0,
- /* precache */ ""
- },
- /*QUAKED key_data_spinner (0 .5 .8) (-16 -16 -16) (16 16 16)
- key for the city computer
- */
- {
- "key_data_spinner",
- Pickup_Key,
- NULL,
- Drop_General,
- NULL,
- "items/pkup.wav",
- "models/items/keys/spinner/tris.md2", EF_ROTATE,
- NULL,
- "k_dataspin",
- "Data Spinner",
- 2,
- 0,
- NULL,
- IT_STAY_COOP|IT_KEY,
- 0,
- NULL,
- 0,
- /* precache */ ""
- },
- /*QUAKED key_pass (0 .5 .8) (-16 -16 -16) (16 16 16)
- security pass for the security level
- */
- {
- "key_pass",
- Pickup_Key,
- NULL,
- Drop_General,
- NULL,
- "items/pkup.wav",
- "models/items/keys/pass/tris.md2", EF_ROTATE,
- NULL,
- "k_security",
- "Security Pass",
- 2,
- 0,
- NULL,
- IT_STAY_COOP|IT_KEY,
- 0,
- NULL,
- 0,
- /* precache */ ""
- },
- /*QUAKED key_blue_key (0 .5 .8) (-16 -16 -16) (16 16 16)
- normal door key - blue
- */
- {
- "key_blue_key",
- Pickup_Key,
- NULL,
- Drop_General,
- NULL,
- "items/pkup.wav",
- "models/items/keys/key/tris.md2", EF_ROTATE,
- NULL,
- "k_bluekey",
- "Blue Key",
- 2,
- 0,
- NULL,
- IT_STAY_COOP|IT_KEY,
- 0,
- NULL,
- 0,
- /* precache */ ""
- },
- /*QUAKED key_red_key (0 .5 .8) (-16 -16 -16) (16 16 16)
- normal door key - red
- */
- {
- "key_red_key",
- Pickup_Key,
- NULL,
- Drop_General,
- NULL,
- "items/pkup.wav",
- "models/items/keys/red_key/tris.md2", EF_ROTATE,
- NULL,
- "k_redkey",
- "Red Key",
- 2,
- 0,
- NULL,
- IT_STAY_COOP|IT_KEY,
- 0,
- NULL,
- 0,
- /* precache */ ""
- },
- /*QUAKED key_commander_head (0 .5 .8) (-16 -16 -16) (16 16 16)
- tank commander's head
- */
- {
- "key_commander_head",
- Pickup_Key,
- NULL,
- Drop_General,
- NULL,
- "items/pkup.wav",
- "models/monsters/commandr/head/tris.md2", EF_GIB,
- NULL,
- /* icon */ "k_comhead",
- /* pickup */ "Commander's Head",
- /* width */ 2,
- 0,
- NULL,
- IT_STAY_COOP|IT_KEY,
- 0,
- NULL,
- 0,
- /* precache */ ""
- },
- /*QUAKED key_airstrike_target (0 .5 .8) (-16 -16 -16) (16 16 16)
- tank commander's head
- */
- {
- "key_airstrike_target",
- Pickup_Key,
- NULL,
- Drop_General,
- NULL,
- "items/pkup.wav",
- "models/items/keys/target/tris.md2", EF_ROTATE,
- NULL,
- /* icon */ "i_airstrike",
- /* pickup */ "Airstrike Marker",
- /* width */ 2,
- 0,
- NULL,
- IT_STAY_COOP|IT_KEY,
- 0,
- NULL,
- 0,
- /* precache */ ""
- },
- {
- NULL,
- Pickup_Health,
- NULL,
- NULL,
- NULL,
- "items/pkup.wav",
- NULL, 0,
- NULL,
- /* icon */ "i_health",
- /* pickup */ "Health",
- /* width */ 3,
- 0,
- NULL,
- 0,
- 0,
- NULL,
- 0,
- /* precache */ "items/s_health.wav items/n_health.wav items/l_health.wav items/m_health.wav"
- },
- // end of list marker
- {NULL}
- };
- /*QUAKED item_health (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- void SP_item_health (edict_t *self)
- {
- if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
- {
- G_FreeEdict (self);
- return;
- }
- self->model = "models/items/healing/medium/tris.md2";
- self->count = 10;
- SpawnItem (self, FindItem ("Health"));
- gi.soundindex ("items/n_health.wav");
- }
- /*QUAKED item_health_small (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- void SP_item_health_small (edict_t *self)
- {
- if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
- {
- G_FreeEdict (self);
- return;
- }
- self->model = "models/items/healing/stimpack/tris.md2";
- self->count = 2;
- SpawnItem (self, FindItem ("Health"));
- self->style = HEALTH_IGNORE_MAX;
- gi.soundindex ("items/s_health.wav");
- }
- /*QUAKED item_health_large (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- void SP_item_health_large (edict_t *self)
- {
- if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
- {
- G_FreeEdict (self);
- return;
- }
- self->model = "models/items/healing/large/tris.md2";
- self->count = 25;
- SpawnItem (self, FindItem ("Health"));
- gi.soundindex ("items/l_health.wav");
- }
- /*QUAKED item_health_mega (.3 .3 1) (-16 -16 -16) (16 16 16)
- */
- void SP_item_health_mega (edict_t *self)
- {
- if ( deathmatch->value && ((int)dmflags->value & DF_NO_HEALTH) )
- {
- G_FreeEdict (self);
- return;
- }
- self->model = "models/items/mega_h/tris.md2";
- self->count = 100;
- SpawnItem (self, FindItem ("Health"));
- gi.soundindex ("items/m_health.wav");
- self->style = HEALTH_IGNORE_MAX|HEALTH_TIMED;
- }
- void InitItems (void)
- {
- game.num_items = sizeof(itemlist)/sizeof(itemlist[0]) - 1;
- }
- /*
- ===============
- SetItemNames
- Called by worldspawn
- ===============
- */
- void SetItemNames (void)
- {
- int i;
- gitem_t *it;
- for (i=0 ; i<game.num_items ; i++)
- {
- it = &itemlist[i];
- gi.configstring (CS_ITEMS+i, it->pickup_name);
- }
- jacket_armor_index = ITEM_INDEX(FindItem("Jacket Armor"));
- combat_armor_index = ITEM_INDEX(FindItem("Combat Armor"));
- body_armor_index = ITEM_INDEX(FindItem("Body Armor"));
- power_screen_index = ITEM_INDEX(FindItem("Power Screen"));
- power_shield_index = ITEM_INDEX(FindItem("Power Shield"));
- }
|