1998-11-24 00:00:00 +00:00
|
|
|
//
|
|
|
|
// g_items.c
|
|
|
|
//
|
|
|
|
// Heretic II
|
|
|
|
// Copyright 1998 Raven Software
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "g_local.h"
|
|
|
|
#include "p_item.h"
|
|
|
|
#include "g_items.h"
|
1999-03-18 00:00:00 +00:00
|
|
|
//#include "p_types.h"
|
|
|
|
#include "player.h"
|
1998-11-24 00:00:00 +00:00
|
|
|
#include "p_weapon.h"
|
1999-03-18 00:00:00 +00:00
|
|
|
#include "g_weapon.h"
|
|
|
|
#include "p_anims.h"
|
|
|
|
#include "p_anim_data.h"
|
1998-11-24 00:00:00 +00:00
|
|
|
#include "fx.h"
|
|
|
|
#include "random.h"
|
|
|
|
#include "vector.h"
|
|
|
|
#include "g_itemstats.h"
|
|
|
|
|
|
|
|
#define HEALTH_IGNORE_MAX 1
|
|
|
|
#define HEALTH_TIMED 2
|
|
|
|
|
|
|
|
#define ITEM_COOP_ONLY 1
|
|
|
|
#define ITEM_NO_DROP 2
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
extern player_export_t playerExport; // interface to player DLL.
|
|
|
|
|
1998-11-24 00:00:00 +00:00
|
|
|
// ************************************************************************************************
|
|
|
|
// RespawnedThink
|
|
|
|
// --------------
|
|
|
|
// ************************************************************************************************
|
|
|
|
|
|
|
|
void RespawnedThink(edict_t *ent)
|
|
|
|
{
|
|
|
|
ent->think = NULL;
|
|
|
|
// ent->svflags |= SVF_NOCLIENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ************************************************************************************************
|
|
|
|
// DoRespawn
|
|
|
|
// ---------
|
|
|
|
// ************************************************************************************************
|
|
|
|
|
|
|
|
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=irand(0, Count - 1);
|
|
|
|
|
|
|
|
for(Count=0,ent=Master;Count<Choice;ent=ent->chain,Count++)
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
ent->solid=SOLID_TRIGGER;
|
|
|
|
|
|
|
|
gi.linkentity(ent);
|
|
|
|
|
|
|
|
// Create a respawn client-effect (this isn't currenlty doing anything on the client).
|
|
|
|
|
|
|
|
//gi.CreateEffect(&ent->s,FX_ITEM_RESPAWN,CEF_OWNERS_ORIGIN,ent->s.origin,NULL);
|
|
|
|
|
|
|
|
// So it'll get sent to the client again.
|
|
|
|
|
|
|
|
// ent->svflags &= ~SVF_NOCLIENT;
|
|
|
|
|
|
|
|
// Re-enable the persistent effect.
|
|
|
|
|
|
|
|
ent->s.effects &= ~EF_DISABLE_ALL_CFX;
|
|
|
|
|
|
|
|
// So it'll get displayed again.
|
|
|
|
|
|
|
|
ent->s.effects |= EF_ALWAYS_ADD_EFFECTS;
|
|
|
|
|
|
|
|
// And the rest.
|
|
|
|
|
|
|
|
ent->think = RespawnedThink;
|
|
|
|
ent->nextthink = level.time + FRAMETIME;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ************************************************************************************************
|
|
|
|
// PreRespawnThink
|
|
|
|
// ---------------
|
|
|
|
// ************************************************************************************************
|
|
|
|
|
|
|
|
void PreRespawnThink(edict_t *ent)
|
|
|
|
{
|
|
|
|
int delay;
|
|
|
|
float clients;
|
|
|
|
|
|
|
|
// The equation for respawn:
|
|
|
|
// --The respawn times should be normal for 8 players.
|
|
|
|
// --For 32 players the respawn should be halved
|
|
|
|
// --For 2 players the respawn should be doubled.
|
|
|
|
if (deathmatch->value)
|
|
|
|
{
|
|
|
|
/* // You know what? I thought I was being clever here, but I just screwed up the eq and made the game not respawn enough.
|
|
|
|
delay = ent->delay * sqrt((float)game.num_clients/8.0); // This makes it a nice curve. Clever, no?
|
|
|
|
// Lemme see here: sqrt(2/8) = sqrt(1/4) = 1/2
|
|
|
|
// sqrt(8/8) = sqrt(1) = 1
|
|
|
|
// sqrt(32/8) = sqrt(4) = 2
|
|
|
|
*/
|
|
|
|
clients=(float)game.num_clients;
|
|
|
|
if (clients<2.0)
|
|
|
|
clients=2.0;
|
|
|
|
delay = ent->delay * sqrt(2.0/clients); // Spawn more frequently when more players.
|
|
|
|
// Lemme see here: sqrt(2/2) = sqrt(1) = 1
|
|
|
|
// sqrt(2/8) = sqrt(1/4) = 1/2
|
|
|
|
// sqrt(2/32) = sqrt(1/16) = 1/4
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
delay = ent->delay;
|
|
|
|
}
|
|
|
|
ent->nextthink = level.time + delay - FRAMETIME;
|
|
|
|
ent->think = DoRespawn;
|
|
|
|
// ent->svflags |= SVF_NOCLIENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ************************************************************************************************
|
|
|
|
// SetRespawn
|
|
|
|
// ----------
|
|
|
|
// ************************************************************************************************
|
|
|
|
|
|
|
|
void SetRespawn(edict_t *ent)
|
|
|
|
{
|
|
|
|
// So it'll get sent to the client again.
|
|
|
|
|
|
|
|
// ent->svflags &= ~SVF_NOCLIENT;
|
|
|
|
|
|
|
|
// Disables all the effects on the entity.
|
|
|
|
|
|
|
|
ent->s.effects |= EF_DISABLE_ALL_CFX;
|
|
|
|
|
|
|
|
// Take off the EF_ALWAYS_ADD_EFFECTS or EF_DISABLE_ALL_CFX wont have an effect.
|
|
|
|
|
|
|
|
ent->s.effects &= ~EF_ALWAYS_ADD_EFFECTS;
|
|
|
|
|
|
|
|
// And the rest.
|
|
|
|
|
|
|
|
ent->solid = SOLID_NOT;
|
|
|
|
|
|
|
|
if(deathmatch->value && game.num_clients > 8)
|
|
|
|
{
|
|
|
|
// No less than 1/4th the delay.
|
|
|
|
|
|
|
|
ent->nextthink = level.time + (ent->delay) / 4;
|
|
|
|
}
|
|
|
|
if(deathmatch->value && game.num_clients > 2)
|
|
|
|
{
|
|
|
|
// So things respawn faster with a lot of players.
|
|
|
|
|
|
|
|
ent->nextthink = level.time + (ent->delay) / (game.num_clients/2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ent->nextthink = level.time + ent->delay;
|
|
|
|
}
|
|
|
|
|
|
|
|
ent->think = PreRespawnThink;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ************************************************************************************************
|
|
|
|
// Pickup_Puzzle
|
|
|
|
// -------------
|
|
|
|
// ************************************************************************************************
|
|
|
|
|
|
|
|
qboolean Pickup_Puzzle(edict_t *ent, edict_t *other)
|
|
|
|
{
|
|
|
|
gitem_t *item;
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
if (other->flags & FL_CHICKEN)
|
|
|
|
{
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
item = P_FindItemByClassname(ent->classname);
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
if (!other->client->playerinfo.pers.inventory.Items[ITEM_INDEX(ent->item)])
|
|
|
|
{
|
|
|
|
other->client->playerinfo.pers.inventory.Items[ITEM_INDEX(ent->item)] = 1;
|
|
|
|
|
|
|
|
gi.gamemsg_centerprintf(other, ent->item->msg_pickup);
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ************************************************************************************************
|
|
|
|
// AddWeaponToInventory
|
|
|
|
// --------------------
|
|
|
|
// ************************************************************************************************
|
|
|
|
|
|
|
|
qboolean AddWeaponToInventory(gitem_t *item,edict_t *player)
|
|
|
|
{
|
|
|
|
gitem_t *newitem;
|
|
|
|
int count;
|
|
|
|
|
|
|
|
// Do we already have this weapon?
|
|
|
|
|
|
|
|
if(!player->client->playerinfo.pers.inventory.Items[ITEM_INDEX(item)])
|
|
|
|
{
|
|
|
|
// We don't already have it, so get the weapon and some ammo.
|
|
|
|
|
|
|
|
if (item->tag == ITEM_WEAPON_SWORDSTAFF)
|
|
|
|
count= 0;
|
|
|
|
else if (item->tag == ITEM_WEAPON_HELLSTAFF)
|
|
|
|
count = AMMO_COUNT_HELLSTAFF;
|
|
|
|
else if (item->tag == ITEM_WEAPON_REDRAINBOW)
|
|
|
|
{
|
|
|
|
// give us the bowtype
|
|
|
|
player->client->playerinfo.pers.bowtype = BOW_TYPE_REDRAIN;
|
|
|
|
count = AMMO_COUNT_REDRAINBOW;
|
|
|
|
}
|
|
|
|
else if (item->tag == ITEM_WEAPON_PHOENIXBOW)
|
|
|
|
{
|
|
|
|
// give us the bowtype
|
|
|
|
player->client->playerinfo.pers.bowtype = BOW_TYPE_PHOENIX;
|
|
|
|
count = AMMO_COUNT_PHOENIXBOW;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
count = AMMO_COUNT_MOST;
|
|
|
|
|
|
|
|
player->client->playerinfo.pers.inventory.Items[ITEM_INDEX(item)] = 1;
|
|
|
|
|
|
|
|
if(count)
|
|
|
|
{
|
1999-03-18 00:00:00 +00:00
|
|
|
newitem = P_FindItem(item->ammo);
|
1998-11-24 00:00:00 +00:00
|
|
|
Add_Ammo(player, newitem,count);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now decide if we want to swap weapons or not.
|
|
|
|
|
|
|
|
if (player->client->playerinfo.pers.autoweapon)
|
|
|
|
{
|
|
|
|
// If this new weapon is a higher value than the one we currently have, swap the current
|
|
|
|
// weapon for the new one.
|
|
|
|
|
|
|
|
if (ITEM_INDEX(item) > ITEM_INDEX(player->client->playerinfo.pers.weapon))
|
|
|
|
{
|
|
|
|
item->use(&player->client->playerinfo,item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// We already have it...
|
|
|
|
|
|
|
|
if(!((deathmatch->value&&((int)dmflags->value&DF_WEAPONS_STAY))||coop->value))
|
|
|
|
{
|
|
|
|
// ...and DF_WEPONS_STAY is off and we're not in coop, so just try to up the ammo counts.
|
|
|
|
|
|
|
|
if (item->tag == ITEM_WEAPON_HELLSTAFF)
|
|
|
|
{
|
1999-03-18 00:00:00 +00:00
|
|
|
newitem = P_FindItemByClassname("item_ammo_hellstaff");
|
1998-11-24 00:00:00 +00:00
|
|
|
count = AMMO_COUNT_HELLSTAFF;
|
|
|
|
}
|
|
|
|
else if (item->tag == ITEM_WEAPON_REDRAINBOW)
|
|
|
|
{
|
1999-03-18 00:00:00 +00:00
|
|
|
newitem = P_FindItemByClassname("item_ammo_redrain");
|
1998-11-24 00:00:00 +00:00
|
|
|
count = AMMO_COUNT_REDRAINBOW;
|
|
|
|
}
|
|
|
|
else if (item->tag == ITEM_WEAPON_PHOENIXBOW)
|
|
|
|
{
|
1999-03-18 00:00:00 +00:00
|
|
|
newitem = P_FindItemByClassname("item_ammo_phoenix");
|
1998-11-24 00:00:00 +00:00
|
|
|
count = AMMO_COUNT_PHOENIXBOW;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-03-18 00:00:00 +00:00
|
|
|
newitem = P_FindItemByClassname("item_mana_offensive_half");
|
1998-11-24 00:00:00 +00:00
|
|
|
count = AMMO_COUNT_MOST;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(Add_Ammo(player, newitem,count))
|
|
|
|
{
|
|
|
|
// Have space in our inventory, so add ammo.
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// No space in inventory to add the ammo.
|
|
|
|
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// ...but we're not able to pick it up.
|
|
|
|
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ************************************************************************************************
|
|
|
|
// Pickup_Weapon
|
|
|
|
// -------------
|
|
|
|
// ************************************************************************************************
|
|
|
|
|
|
|
|
qboolean Pickup_Weapon(edict_t *ent,edict_t *other)
|
|
|
|
{
|
1999-03-18 00:00:00 +00:00
|
|
|
if (other->flags & FL_CHICKEN)
|
|
|
|
{
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
1998-11-24 00:00:00 +00:00
|
|
|
if(AddWeaponToInventory(ent->item,other))
|
|
|
|
{
|
|
|
|
gi.gamemsg_centerprintf(other, ent->item->msg_pickup);
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// We already have it.
|
|
|
|
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ************************************************************************************************
|
|
|
|
// AddDefenseToInventory
|
|
|
|
// ---------------------
|
|
|
|
// ************************************************************************************************
|
|
|
|
|
|
|
|
qboolean AddDefenseToInventory(gitem_t *item,edict_t *player)
|
|
|
|
{
|
|
|
|
if(!player->client->playerinfo.pers.inventory.Items[ITEM_INDEX(item)])
|
|
|
|
{
|
|
|
|
player->client->playerinfo.pers.inventory.Items[ITEM_INDEX(item)]=1;
|
|
|
|
|
|
|
|
// Now decide if we want to swap defenses or not.
|
|
|
|
|
|
|
|
// if(player->client->playerinfo.pers.autoweapon || !player->client->playerinfo.pers.defence)
|
|
|
|
if(player->client->playerinfo.pers.autoweapon )
|
|
|
|
{
|
|
|
|
item->use(&player->client->playerinfo,item);
|
|
|
|
}
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// We already have it...
|
|
|
|
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ************************************************************************************************
|
|
|
|
// Pickup_Defense
|
|
|
|
// --------------
|
|
|
|
// ************************************************************************************************
|
|
|
|
|
|
|
|
qboolean Pickup_Defense (edict_t *ent, edict_t *other)
|
|
|
|
{
|
1999-03-18 00:00:00 +00:00
|
|
|
if (other->flags & FL_CHICKEN)
|
|
|
|
{
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
1998-11-24 00:00:00 +00:00
|
|
|
if(AddDefenseToInventory(ent->item,other))
|
|
|
|
{
|
|
|
|
gi.gamemsg_centerprintf(other, ent->item->msg_pickup);
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ************************************************************************************************
|
|
|
|
// Add_AmmoToInventory
|
|
|
|
// -------------------
|
|
|
|
// ************************************************************************************************
|
|
|
|
|
|
|
|
qboolean Add_AmmoToInventory (edict_t *ent, gitem_t *item, int count,int max)
|
|
|
|
{
|
|
|
|
int index;
|
|
|
|
|
|
|
|
index = ITEM_INDEX(item);
|
|
|
|
|
|
|
|
if (ent->client->playerinfo.pers.inventory.Items[index] == max)
|
|
|
|
return(false);
|
|
|
|
|
|
|
|
ent->client->playerinfo.pers.inventory.Items[index] += count;
|
|
|
|
|
|
|
|
if (ent->client->playerinfo.pers.inventory.Items[index] > max)
|
|
|
|
ent->client->playerinfo.pers.inventory.Items[index] = max;
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============
|
|
|
|
Add_Ammo
|
|
|
|
===============
|
|
|
|
*/
|
|
|
|
|
|
|
|
qboolean Add_Ammo (edict_t *ent, gitem_t *item, int count)
|
|
|
|
{
|
|
|
|
int bo;
|
|
|
|
int max;
|
|
|
|
|
|
|
|
if (!ent->client)
|
|
|
|
return(false);
|
|
|
|
|
|
|
|
if ((item->tag == ITEM_AMMO_MANA_OFFENSIVE_HALF) || (item->tag == ITEM_AMMO_MANA_OFFENSIVE_FULL))
|
|
|
|
{
|
1999-03-18 00:00:00 +00:00
|
|
|
item = P_FindItemByClassname("item_mana_offensive_half");
|
1998-11-24 00:00:00 +00:00
|
|
|
max = ent->client->playerinfo.pers.max_offmana;
|
|
|
|
return(Add_AmmoToInventory (ent,item,count,max));
|
|
|
|
}
|
|
|
|
else if ((item->tag == ITEM_AMMO_MANA_DEFENSIVE_HALF) || (item->tag == ITEM_AMMO_MANA_DEFENSIVE_FULL))
|
|
|
|
{
|
1999-03-18 00:00:00 +00:00
|
|
|
item = P_FindItemByClassname("item_mana_defensive_half");
|
1998-11-24 00:00:00 +00:00
|
|
|
max = ent->client->playerinfo.pers.max_defmana;
|
|
|
|
return(Add_AmmoToInventory (ent,item,count,max));
|
|
|
|
}
|
|
|
|
else if ((item->tag == ITEM_AMMO_MANA_COMBO_QUARTER) || (item->tag == ITEM_AMMO_MANA_COMBO_HALF))
|
|
|
|
{
|
1999-03-18 00:00:00 +00:00
|
|
|
item = P_FindItemByClassname("item_mana_offensive_half");
|
1998-11-24 00:00:00 +00:00
|
|
|
max = ent->client->playerinfo.pers.max_offmana;
|
|
|
|
|
|
|
|
bo = Add_AmmoToInventory (ent,item,count,max);
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
item = P_FindItemByClassname("item_mana_defensive_half");
|
1998-11-24 00:00:00 +00:00
|
|
|
max = ent->client->playerinfo.pers.max_defmana;
|
|
|
|
bo |= Add_AmmoToInventory (ent,item,count,max);
|
|
|
|
|
|
|
|
return(bo);
|
|
|
|
}
|
|
|
|
else if (item->tag == ITEM_AMMO_REDRAIN)
|
|
|
|
{
|
|
|
|
max = ent->client->playerinfo.pers.max_redarrow;
|
|
|
|
return(Add_AmmoToInventory (ent,item,count,max));
|
|
|
|
}
|
|
|
|
else if (item->tag == ITEM_AMMO_PHOENIX)
|
|
|
|
{
|
|
|
|
max = ent->client->playerinfo.pers.max_phoenarr;
|
|
|
|
return(Add_AmmoToInventory (ent,item,count,max));
|
|
|
|
}
|
|
|
|
else if (item->tag == ITEM_AMMO_HELLSTAFF)
|
|
|
|
{
|
|
|
|
max = ent->client->playerinfo.pers.max_hellstaff;
|
|
|
|
return(Add_AmmoToInventory (ent,item,count,max));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============
|
|
|
|
Pickup_Ammo
|
|
|
|
===============
|
|
|
|
*/
|
|
|
|
|
|
|
|
qboolean Pickup_Ammo (edict_t *ent, edict_t *other)
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
if (other->flags & FL_CHICKEN)
|
|
|
|
{
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
1998-11-24 00:00:00 +00:00
|
|
|
if (ent->count)
|
|
|
|
count = ent->count;
|
|
|
|
else
|
|
|
|
count = ent->item->quantity;
|
|
|
|
|
|
|
|
if (!Add_Ammo (other, ent->item, count))
|
|
|
|
return(false);
|
|
|
|
|
|
|
|
gi.gamemsg_centerprintf(other, ent->item->msg_pickup);
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============
|
|
|
|
Pickup_Manna
|
|
|
|
|
|
|
|
Separate routine so we can distinguish between ammo and mana.
|
|
|
|
===============
|
|
|
|
*/
|
|
|
|
|
|
|
|
qboolean Pickup_Mana (edict_t *ent, edict_t *other)
|
|
|
|
{
|
|
|
|
return(Pickup_Ammo(ent, other));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============
|
|
|
|
Drop_Ammo
|
|
|
|
===============
|
|
|
|
*/
|
|
|
|
|
|
|
|
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->playerinfo.pers.inventory.Items[index] >= item->quantity)
|
|
|
|
dropped->count = item->quantity;
|
|
|
|
else
|
|
|
|
dropped->count = ent->client->playerinfo.pers.inventory.Items[index];
|
|
|
|
ent->client->playerinfo.pers.inventory.Items[index] -= dropped->count;
|
|
|
|
|
|
|
|
ValidateSelectedItem (ent);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============
|
|
|
|
Pickup_Health
|
|
|
|
===============
|
|
|
|
*/
|
|
|
|
|
|
|
|
qboolean Pickup_Health (edict_t *ent, edict_t *other)
|
|
|
|
{
|
1999-03-18 00:00:00 +00:00
|
|
|
if (other->flags & FL_CHICKEN)
|
|
|
|
{
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
1998-11-24 00:00:00 +00:00
|
|
|
if (!(ent->style & HEALTH_IGNORE_MAX))
|
|
|
|
{
|
|
|
|
if (other->health >= other->max_health)
|
|
|
|
{
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
other->health += ent->item->quantity;
|
|
|
|
|
|
|
|
if(other->fire_damage_time>level.time)
|
|
|
|
{
|
|
|
|
other->fire_damage_time -= ent->item->quantity/10;
|
|
|
|
if(other->fire_damage_time<=0)
|
|
|
|
{
|
|
|
|
other->fire_damage_time = 0;
|
|
|
|
// gi.RemoveEffects(&other->s, FX_FIRE_ON_ENTITY);//turn off CFX too
|
|
|
|
other->s.effects |= EF_MARCUS_FLAG1; // Notify the effect to turn itself off.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(ent->style & HEALTH_IGNORE_MAX))
|
|
|
|
{
|
|
|
|
if (other->health > other->max_health)
|
|
|
|
{
|
|
|
|
other->health = other->max_health;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(other->client)
|
|
|
|
player_repair_skin(other);
|
|
|
|
|
|
|
|
gi.gamemsg_centerprintf(other, ent->item->msg_pickup);
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============
|
|
|
|
Touch_Item
|
|
|
|
===============
|
|
|
|
*/
|
|
|
|
|
|
|
|
void Touch_Item (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
|
|
|
|
{
|
|
|
|
if(strcmp(other->classname,"player"))
|
|
|
|
{
|
|
|
|
// Only players can touch items.
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(other->health <= 0)
|
|
|
|
{
|
|
|
|
// Dead players can't pickup.
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(!ent->item->pickup)
|
|
|
|
{
|
|
|
|
// Not a grabbable item.
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(ent->item->pickup);
|
|
|
|
|
|
|
|
if((other->client->playerinfo.edictflags & FL_CHICKEN) && (ent->item->pickup == Pickup_Health))
|
|
|
|
{
|
|
|
|
// chickens can't pickup health
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!ent->item->pickup(ent, other))
|
|
|
|
{
|
|
|
|
// Player can't hold it.
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gi.sound(other, CHAN_ITEM, gi.soundindex(ent->item->pickup_sound), 1, ATTN_NORM, 0);
|
|
|
|
|
|
|
|
gi.CreateEffect(NULL, FX_PICKUP, 0, ent->s.origin, "");
|
|
|
|
|
|
|
|
G_UseTargets (ent, other);
|
|
|
|
|
|
|
|
// Handle respawn / removal of the item.
|
|
|
|
|
|
|
|
if(((ent->item->pickup==Pickup_Weapon)||(ent->item->pickup==Pickup_Defense)||(ent->item->pickup==Pickup_Puzzle))&&
|
|
|
|
((deathmatch->value&&((int)dmflags->value&DF_WEAPONS_STAY))||coop->value))
|
|
|
|
{
|
|
|
|
// The item is a weapon or a defence or a puzzle piece AND (deathmatch rule DF_WEAPONS_STAY
|
|
|
|
// is on OR we are playing coop), so just return right now, as we don't care about respawn
|
|
|
|
// or removal.
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ent->flags&FL_RESPAWN)
|
|
|
|
{
|
|
|
|
// The item should respawn.
|
|
|
|
|
|
|
|
SetRespawn(ent);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Going away for good, so make it noclipping.
|
|
|
|
|
|
|
|
ent->solid = SOLID_NOT;
|
|
|
|
|
|
|
|
// Once picked up, the item is gone forever, so remove it's client effect(s).
|
|
|
|
|
|
|
|
gi.RemoveEffects(&ent->s,0);
|
|
|
|
|
|
|
|
// The persistent part is removed from the server here.
|
|
|
|
|
|
|
|
G_SetToFree(ent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
drop_temp_touch
|
|
|
|
================
|
|
|
|
*/
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
drop_make_touchable
|
|
|
|
================
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void drop_make_touchable (edict_t *ent)
|
|
|
|
{
|
|
|
|
ent->touch = Touch_Item;
|
|
|
|
|
|
|
|
if (deathmatch->value)
|
|
|
|
{
|
|
|
|
ent->nextthink = level.time + 29;
|
|
|
|
ent->think = G_FreeEdict;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
Drop_Item
|
|
|
|
================
|
|
|
|
*/
|
|
|
|
|
|
|
|
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 = PHYSICSTYPE_NONE;
|
|
|
|
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);
|
|
|
|
gi.trace (ent->s.origin, dropped->mins, dropped->maxs,
|
|
|
|
dropped->s.origin, ent, CONTENTS_SOLID,&trace);
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
Use_Item
|
|
|
|
================
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
void Use_Item (edict_t *ent, edict_t *other, edict_t *activator)
|
|
|
|
{
|
|
|
|
// ent->svflags &= ~SVF_NOCLIENT;
|
|
|
|
ent->use = NULL;
|
|
|
|
|
|
|
|
if (ent->spawnflags & 2) // NO_TOUCH
|
|
|
|
{
|
|
|
|
ent->solid = SOLID_BBOX;
|
|
|
|
ent->touch = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ent->solid = SOLID_TRIGGER;
|
|
|
|
ent->touch = Touch_Item;
|
|
|
|
}
|
|
|
|
|
|
|
|
gi.linkentity (ent);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
// ************************************************************************************************
|
|
|
|
// ValidItem
|
|
|
|
// ---------
|
|
|
|
// ************************************************************************************************
|
|
|
|
|
|
|
|
qboolean ValidItem(gitem_t *item)
|
|
|
|
{
|
|
|
|
// Some items will be prevented in deathmatch.
|
|
|
|
|
|
|
|
if(deathmatch->value)
|
|
|
|
{
|
|
|
|
if ( (int)dmflags->value & DF_NO_DEFENSIVE_SPELL )
|
|
|
|
{
|
1999-03-18 00:00:00 +00:00
|
|
|
if (item->flags & IT_DEFENSE)
|
1998-11-24 00:00:00 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( (int)dmflags->value & DF_NO_OFFENSIVE_SPELL )
|
|
|
|
{
|
1999-03-18 00:00:00 +00:00
|
|
|
if (item->flags & IT_OFFENSE)
|
1998-11-24 00:00:00 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( (int)dmflags->value & DF_NO_HEALTH )
|
|
|
|
{
|
1999-03-18 00:00:00 +00:00
|
|
|
if (item->flags & IT_HEALTH)
|
1998-11-24 00:00:00 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-04-30 00:00:00 +00:00
|
|
|
if ((item->flags & IT_DEFENSE) && (item->tag == ITEM_DEFENSE_TORNADO) && (no_tornado->value))
|
1999-03-18 00:00:00 +00:00
|
|
|
return false;
|
1999-04-30 00:00:00 +00:00
|
|
|
else if ((item->flags & IT_DEFENSE) && (item->tag == ITEM_DEFENSE_POLYMORPH) && (no_morph->value))
|
1999-03-18 00:00:00 +00:00
|
|
|
return false;
|
1999-04-30 00:00:00 +00:00
|
|
|
else if ((item->flags & IT_DEFENSE) && (item->tag == ITEM_DEFENSE_SHIELD) && (no_shield->value))
|
1999-03-18 00:00:00 +00:00
|
|
|
return false;
|
1999-04-30 00:00:00 +00:00
|
|
|
else if ((item->flags & IT_DEFENSE) && (item->tag == ITEM_DEFENSE_TELEPORT) && (no_teleport->value))
|
1999-03-18 00:00:00 +00:00
|
|
|
return false;
|
1999-04-30 00:00:00 +00:00
|
|
|
else if ((item->flags & IT_OFFENSE) && (item->tag == ITEM_WEAPON_PHOENIXBOW) && (no_phoenix->value))
|
1999-03-18 00:00:00 +00:00
|
|
|
return false;
|
1999-04-30 00:00:00 +00:00
|
|
|
else if ((item->flags & IT_OFFENSE) && (item->tag == ITEM_WEAPON_MACEBALLS) && (no_irondoom->value))
|
1999-03-18 00:00:00 +00:00
|
|
|
return false;
|
1999-04-30 00:00:00 +00:00
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
}
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
#if DEMO_CODE
|
|
|
|
// don't spawn this item in Demo game
|
|
|
|
if ((int)item->info)
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ************************************************************************************************
|
|
|
|
// SpawnItemEffect
|
|
|
|
// ---------------
|
|
|
|
// ************************************************************************************************
|
|
|
|
|
|
|
|
void SpawnItemEffect(edict_t *ent, gitem_t *item)
|
|
|
|
{
|
|
|
|
|
|
|
|
if(!ValidItem(item))
|
|
|
|
{
|
|
|
|
G_FreeEdict (ent);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(!ent->PersistantCFX);
|
|
|
|
|
|
|
|
if ((ent->spawnflags & ITEM_COOP_ONLY) && (!coop->value))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(ent->item->flags & IT_PUZZLE)
|
|
|
|
{
|
|
|
|
ent->PersistantCFX = gi.CreatePersistantEffect(&ent->s, FX_PICKUP_PUZZLE, CEF_BROADCAST, ent->s.origin, "bv", ent->item->tag,ent->s.angles);
|
|
|
|
}
|
|
|
|
else if(ent->item->flags & IT_WEAPON)
|
|
|
|
{
|
|
|
|
ent->PersistantCFX = gi.CreatePersistantEffect(&ent->s, FX_PICKUP_WEAPON, CEF_BROADCAST, ent->s.origin, "b", ent->item->tag);
|
|
|
|
}
|
|
|
|
else if(ent->item->flags & IT_AMMO)
|
|
|
|
{
|
|
|
|
ent->PersistantCFX = gi.CreatePersistantEffect(&ent->s, FX_PICKUP_AMMO, CEF_BROADCAST, ent->s.origin, "b", ent->item->tag);
|
|
|
|
}
|
1999-03-18 00:00:00 +00:00
|
|
|
else if(ent->item->flags & IT_DEFENSE)
|
|
|
|
{
|
|
|
|
ent->PersistantCFX = gi.CreatePersistantEffect(&ent->s, FX_PICKUP_DEFENSE, CEF_BROADCAST, ent->s.origin, "b", ent->item->tag);
|
|
|
|
}
|
1998-11-24 00:00:00 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (ent->item->tag)
|
|
|
|
ent->PersistantCFX = gi.CreatePersistantEffect(&ent->s, FX_PICKUP_HEALTH, CEF_FLAG6|CEF_BROADCAST, ent->s.origin, "");
|
|
|
|
else
|
|
|
|
ent->PersistantCFX = gi.CreatePersistantEffect(&ent->s, FX_PICKUP_HEALTH, CEF_BROADCAST, ent->s.origin, "");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
droptofloor
|
|
|
|
================
|
|
|
|
*/
|
|
|
|
|
|
|
|
void itemsdroptofloor (edict_t *ent)
|
|
|
|
{
|
|
|
|
trace_t tr;
|
|
|
|
vec3_t dest;
|
|
|
|
|
|
|
|
ent->movetype = PHYSICSTYPE_STATIC;
|
|
|
|
ent->solid = SOLID_TRIGGER;
|
|
|
|
ent->touch = Touch_Item;
|
|
|
|
ent->think = NULL;
|
|
|
|
|
|
|
|
if (!(ent->spawnflags & ITEM_NO_DROP))
|
|
|
|
{
|
|
|
|
VectorSet(dest, 0.0, 0.0, -128.0);
|
|
|
|
Vec3AddAssign (ent->s.origin, dest);
|
|
|
|
|
|
|
|
gi.linkentity (ent);
|
|
|
|
|
|
|
|
gi.trace (ent->s.origin, ent->mins, ent->maxs, dest, ent, MASK_SOLID, &tr);
|
|
|
|
if (tr.startsolid)
|
|
|
|
{
|
|
|
|
gi.dprintf ("droptofloor: %s startsolid at %s (inhibited)\n", ent->classname, vtos(ent->s.origin));
|
|
|
|
G_FreeEdict (ent);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
tr.endpos[2] += 24;
|
|
|
|
VectorCopy(tr.endpos,ent->s.origin);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
gi.linkentity (ent);
|
|
|
|
|
|
|
|
// if we loading a saved game - the objects will already be out there
|
|
|
|
if (!ent->PersistantCFX)
|
|
|
|
SpawnItemEffect(ent, ent->item);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
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->icon)
|
|
|
|
gi.imageindex (it->icon);
|
|
|
|
|
|
|
|
// parse everything for its ammo
|
|
|
|
if (it->ammo && it->ammo[0])
|
|
|
|
{
|
1999-03-18 00:00:00 +00:00
|
|
|
ammo = P_FindItem (it->ammo);
|
1998-11-24 00:00:00 +00:00
|
|
|
if (ammo != it)
|
|
|
|
PrecacheItem (ammo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// ************************************************************************************************
|
|
|
|
// SpawnItem
|
|
|
|
// ---------
|
|
|
|
// Sets the clipping size and plants the object on the floor. Items can't be immediately dropped to
|
|
|
|
// the floor because they might be on an entity that hasn't spawned yet.
|
|
|
|
// ************************************************************************************************
|
|
|
|
|
|
|
|
void SpawnItem (edict_t *ent, gitem_t *item)
|
|
|
|
{
|
|
|
|
if ((ent->spawnflags & ITEM_COOP_ONLY) && (!coop->value))
|
|
|
|
return;
|
|
|
|
|
|
|
|
PrecacheItem(item);
|
|
|
|
|
|
|
|
if(!ValidItem(item))
|
|
|
|
{
|
|
|
|
G_FreeEdict (ent);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ent->item = item;
|
|
|
|
ent->nextthink = level.time + (2 * FRAMETIME); // items start after other solids
|
|
|
|
ent->think = itemsdroptofloor;
|
|
|
|
|
|
|
|
ent->s.effects = item->world_model_flags;
|
|
|
|
ent->s.renderfx = RF_GLOW;
|
|
|
|
// ent->svflags |= SVF_ALWAYS_SEND; // make sure SVF_NOCLIENT gets set in think
|
|
|
|
ent->s.effects |= EF_ALWAYS_ADD_EFFECTS;
|
|
|
|
|
|
|
|
if (item->flags & IT_WEAPON)
|
|
|
|
{
|
|
|
|
if (item->tag == ITEM_WEAPON_MACEBALLS)
|
|
|
|
ent->delay = RESPAWN_TIME_MACEBALL; // Maceballs shouldn't come back as fast...
|
|
|
|
else
|
|
|
|
ent->delay = RESPAWN_TIME_WEAPON;
|
|
|
|
}
|
|
|
|
else if (item->flags & IT_DEFENSE)
|
|
|
|
{
|
|
|
|
if (item->tag == ITEM_DEFENSE_REPULSION)
|
|
|
|
ent->delay = RESPAWN_TIME_RING;
|
|
|
|
else if (item->tag == ITEM_DEFENSE_TELEPORT)
|
|
|
|
ent->delay = RESPAWN_TIME_TELEPORT;
|
|
|
|
else if (item->tag == ITEM_DEFENSE_POLYMORPH)
|
|
|
|
ent->delay = RESPAWN_TIME_MORPH;
|
|
|
|
else
|
|
|
|
ent->delay = RESPAWN_TIME_DEFENSE;
|
|
|
|
}
|
|
|
|
else if (item->flags & IT_AMMO)
|
|
|
|
{
|
|
|
|
if (item->tag == ITEM_AMMO_REDRAIN || item->tag == ITEM_AMMO_PHOENIX)
|
|
|
|
ent->delay = RESPAWN_TIME_ARROWS;
|
|
|
|
else
|
|
|
|
ent->delay = RESPAWN_TIME_AMMO;
|
|
|
|
}
|
|
|
|
else // Health and anything else
|
|
|
|
{
|
|
|
|
ent->delay = RESPAWN_TIME_MISC;
|
|
|
|
}
|
|
|
|
|
|
|
|
ent->flags = item->flags;
|
|
|
|
ent->clipmask = MASK_MONSTERSOLID;
|
|
|
|
|
|
|
|
if (item->flags == IT_PUZZLE)
|
|
|
|
{
|
|
|
|
VectorCopy(ent->item->mins, ent->mins);
|
|
|
|
VectorCopy(ent->item->maxs, ent->maxs);
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: Until all objects have bounding boxes, default to these vals.
|
|
|
|
if (Vec3IsZero(ent->mins))
|
|
|
|
{
|
|
|
|
VectorSet (ent->mins, -10.0, -10.0, -10.0);
|
|
|
|
VectorSet (ent->maxs, 10.0, 10.0, 10.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
ent->classname = item->classname;
|
|
|
|
if(deathmatch->value)
|
|
|
|
{
|
|
|
|
ent->flags |= FL_RESPAWN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// ************************************************************************************************
|
|
|
|
// IsItem
|
|
|
|
// ------
|
|
|
|
// ************************************************************************************************
|
|
|
|
|
|
|
|
gitem_t *IsItem(edict_t *ent)
|
|
|
|
{
|
|
|
|
gitem_t *item;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if(!ent->classname)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
for(i = 0, item = playerExport.p_itemlist; i < game.num_items; ++i, ++item)
|
1998-11-24 00:00:00 +00:00
|
|
|
{
|
|
|
|
if(!item->classname)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!strcmp(item->classname, ent->classname))
|
|
|
|
{
|
|
|
|
// Found it.
|
|
|
|
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ************************************************************************************************
|
|
|
|
// G_InitItems
|
|
|
|
// -----------
|
|
|
|
// ************************************************************************************************
|
|
|
|
|
|
|
|
void G_InitItems(void)
|
|
|
|
{
|
|
|
|
// ********************************************************************************************
|
|
|
|
// Setup item function pointers which yield pick-up, use, drop and weaponthink functionality.
|
|
|
|
// ********************************************************************************************
|
|
|
|
|
|
|
|
// Leave index 0 empty.
|
|
|
|
|
|
|
|
// weapon_swordstaff
|
|
|
|
// This can't be placed in the editor
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[1].pickup=Pickup_Weapon;
|
|
|
|
playerExport.p_itemlist[1].use=P_Weapon_EquipSwordStaff;
|
|
|
|
playerExport.p_itemlist[1].weaponthink=WeaponThink_SwordStaff;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// weapon_flyingfist
|
|
|
|
// This can't be placed in the editor
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[2].pickup=Pickup_Weapon;
|
|
|
|
playerExport.p_itemlist[2].use=P_Weapon_EquipSpell;
|
|
|
|
playerExport.p_itemlist[2].weaponthink=WeaponThink_FlyingFist;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_weapon_hellstaff
|
|
|
|
/*QUAKED item_weapon_hellstaff (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for the hellstaff weapon.
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[3].pickup=Pickup_Weapon;
|
|
|
|
playerExport.p_itemlist[3].use=P_Weapon_EquipHellStaff;
|
|
|
|
playerExport.p_itemlist[3].weaponthink=WeaponThink_HellStaff;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_weapon_magicmissile
|
|
|
|
/*QUAKED item_weapon_magicmissile (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for the Magic Missile weapon.
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[4].pickup=Pickup_Weapon;
|
|
|
|
playerExport.p_itemlist[4].use=P_Weapon_EquipSpell;
|
|
|
|
playerExport.p_itemlist[4].weaponthink=WeaponThink_MagicMissileSpread;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_weapon_redrain_bow
|
|
|
|
/*QUAKED item_weapon_redrain_bow (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for the Red Rain Bow weapon.
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[5].pickup=Pickup_Weapon;
|
|
|
|
playerExport.p_itemlist[5].use=P_Weapon_EquipBow;
|
|
|
|
playerExport.p_itemlist[5].weaponthink=WeaponThink_RedRainBow;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_weapon_firewall
|
|
|
|
/*QUAKED item_weapon_firewall (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for the Fire Wall weapon.
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[6].pickup=Pickup_Weapon;
|
|
|
|
playerExport.p_itemlist[6].use=P_Weapon_EquipSpell;
|
|
|
|
playerExport.p_itemlist[6].weaponthink=WeaponThink_Firewall;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_weapon_phoenixbow
|
|
|
|
/*QUAKED item_weapon_phoenixbow (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for the Phoenix Bow weapon.
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[7].pickup=Pickup_Weapon;
|
|
|
|
playerExport.p_itemlist[7].use=P_Weapon_EquipBow;
|
|
|
|
playerExport.p_itemlist[7].weaponthink=WeaponThink_PhoenixBow;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_weapon_sphereofannihilation
|
|
|
|
/*QUAKED item_weapon_sphereofannihilation (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for the Sphere Annihilation weapon.
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[8].pickup=Pickup_Weapon;
|
|
|
|
playerExport.p_itemlist[8].use=P_Weapon_EquipSpell;
|
|
|
|
playerExport.p_itemlist[8].weaponthink=WeaponThink_SphereOfAnnihilation;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_weapon_maceballs
|
|
|
|
/*QUAKED item_weapon_maceballs (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for the Mace Balls weapon.
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[9].pickup=Pickup_Weapon;
|
|
|
|
playerExport.p_itemlist[9].use=P_Weapon_EquipSpell;
|
|
|
|
playerExport.p_itemlist[9].weaponthink=WeaponThink_Maceballs;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_defense_powerup
|
|
|
|
// This can't be placed in the editor
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[10].pickup=Pickup_Defense;
|
|
|
|
playerExport.p_itemlist[10].use=Use_Defence;
|
|
|
|
playerExport.p_itemlist[10].weaponthink=DefenceThink_Powerup;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_defense_ringofrepulsion
|
|
|
|
/*QUAKED item_defense_ringofrepulsion (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for the Ring of Repulsion defensive spell.
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[11].pickup=Pickup_Defense;
|
|
|
|
playerExport.p_itemlist[11].use=Use_Defence;
|
|
|
|
playerExport.p_itemlist[11].weaponthink=DefenceThink_RingOfRepulsion;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_defense_shield
|
|
|
|
/*QUAKED item_defense_shield (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for the Shield defensive spell.
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[12].pickup=Pickup_Defense;
|
|
|
|
playerExport.p_itemlist[12].use=Use_Defence;
|
|
|
|
playerExport.p_itemlist[12].weaponthink=DefenceThink_Shield;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_defense_teleport
|
|
|
|
/*QUAKED item_defense_teleport (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for the Teleport defensive spell.
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[13].pickup=Pickup_Defense;
|
|
|
|
playerExport.p_itemlist[13].use=Use_Defence;
|
|
|
|
playerExport.p_itemlist[13].weaponthink=DefenceThink_Teleport;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_defense_polymorph
|
|
|
|
/*QUAKED item_defense_polymorph (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for the Polymorph Barrier defensive spell.
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[14].pickup=Pickup_Defense;
|
|
|
|
playerExport.p_itemlist[14].use=Use_Defence;
|
|
|
|
playerExport.p_itemlist[14].weaponthink=DefenceThink_Morph;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_defense_meteorbarrier
|
|
|
|
/*QUAKED item_defense_meteorbarrier (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for the Meteor Barrier defensive spell.
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[15].pickup=Pickup_Defense;
|
|
|
|
playerExport.p_itemlist[15].use=Use_Defence;
|
|
|
|
playerExport.p_itemlist[15].weaponthink=DefenceThink_MeteorBarrier;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_mana_offensive_half
|
|
|
|
/*QUAKED item_mana_offensive_half (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for the offensive mana (50 points).
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[16].pickup=Pickup_Mana;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_mana_offensive_full
|
|
|
|
/*QUAKED item_mana_offensive_full (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for the offensive mana (100 points).
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[17].pickup=Pickup_Mana;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_mana_defensive_half
|
|
|
|
/*QUAKED item_mana_defensive_half (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for the defensive mana (50 points).
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[18].pickup=Pickup_Mana;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_mana_defensive_full
|
|
|
|
/*QUAKED item_mana_defensive_full (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for the defensive mana (100 points).
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[19].pickup=Pickup_Mana;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_mana_combo_quarter
|
|
|
|
/*QUAK-ED item_mana_combo_quarter (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for both defensive & offensive mana (25 points).
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[20].pickup=Pickup_Mana;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_mana_combo_half
|
|
|
|
/*QUAKED item_mana_combo_half (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for both defensive & offensive mana (50 points).
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[21].pickup=Pickup_Mana;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_ammo_redrain
|
|
|
|
/*QUAKED item_ammo_redrain (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup ammo for the Red Rain Bow
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[22].pickup=Pickup_Ammo;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_ammo_phoenix
|
|
|
|
/*QUAKED item_ammo_phoenix (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup ammo for the Phoenix Bow
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[23].pickup=Pickup_Ammo;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_ammo_hellstaff
|
|
|
|
/*QUAKED item_ammo_hellstaff (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup ammo for the Hellstaff
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[24].pickup=Pickup_Ammo;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_health_half
|
|
|
|
/*QUAKED item_health_half (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup health (10 points)
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[25].pickup=Pickup_Health;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// item_health_full
|
|
|
|
/*QUAKED item_health_full (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup health (30 points)
|
|
|
|
*/
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[26].pickup=Pickup_Health;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_townkey (.3 .3 1) (-8 -8 -4) (8 8 4) x NO_DROP
|
|
|
|
Key puzzle piece
|
|
|
|
Town Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[27].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_cog (.3 .3 1) (-10 -10 -24) (10 10 20) x NO_DROP
|
|
|
|
Cog puzzle piece
|
|
|
|
Palace level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[28].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_shield (.3 .3 1) (-2 -6 -12) (2 6 12) x NO_DROP
|
|
|
|
Sithra Shield puzzle item
|
|
|
|
Healer Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[29].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_potion (.3 .3 1) (-3 -3 -10) (3 3 10) x NO_DROP
|
|
|
|
Potion puzzle item
|
|
|
|
Healer Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[30].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_plazacontainer (.3 .3 1) (-6 -6 -8) (6 6 6) x NO_DROP
|
|
|
|
Container puzzle item
|
|
|
|
Plaza Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[31].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_slumcontainer (.3 .3 1) (-6 -6 -8) (6 6 6) x NO_DROP
|
|
|
|
Full Container puzzle item
|
|
|
|
Slum Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[32].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_crystal (.3 .3 1) (-16 -16 -16) (16 16 16) x NO_DROP
|
|
|
|
Crystal puzzle item
|
|
|
|
Academic Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[33].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_canyonkey (.3 .3 1) (-16 -16 -16) (16 16 16) x NO_DROP
|
|
|
|
Key puzzle item
|
|
|
|
Canyon Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[34].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_hive2amulet (.3 .3 1) (-16 -16 -16) (16 16 16) x NO_DROP
|
|
|
|
Amulet puzzle item
|
|
|
|
Hive 2 Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[35].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_hive2spear (.3 .3 1) (-16 -16 -16) (16 16 16) x NO_DROP
|
|
|
|
Spear puzzle item
|
|
|
|
Hive 2 Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[36].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_hive2gem (.3 .3 1) (-16 -16 -16) (16 16 16) x NO_DROP
|
|
|
|
Gem puzzle item
|
|
|
|
Hive 2 Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[37].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_minecartwheel (.3 .3 1) (-1 -6 -6) (1 6 6) x NO_DROP
|
|
|
|
Mine Cart Wheel puzzle item
|
|
|
|
Mine 1 Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[38].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_ore (.3 .3 1) (-10 -10 -8) (10 10 8) x NO_DROP
|
|
|
|
Unrefined Ore puzzle item
|
|
|
|
Mine 2 Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[39].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_refinedore (.3 .3 1) (-3 -12 -2) (3 12 2) x NO_DROP
|
|
|
|
Refined Ore puzzle item
|
|
|
|
Mine 2 Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[40].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_dungeonkey (.3 .3 1) (-1 -18 -9) (1 18 9) x NO_DROP
|
|
|
|
Amulet puzzle item
|
|
|
|
Dungeon Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[41].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_cloudkey (.3 .3 1) (-8 -8 -3) (8 8 6) x NO_DROP
|
|
|
|
Key puzzle item
|
|
|
|
Cloud Quarters 2 Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[42].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_highpriestesskey (.3 .3 1) (-12 -12 -6) (12 12 6) x NO_DROP
|
|
|
|
Key puzzle item
|
|
|
|
High Priestess Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[43].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_highpriestesssymbol (.3 .3 1) (-12 -12 -4) (12 12 4) x NO_DROP
|
|
|
|
Key puzzle item
|
|
|
|
High Priestess Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[44].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_tome (.3 .3 1) (-12 -12 -4) (12 12 4) x NO_DROP
|
|
|
|
Tome puzzle piece
|
|
|
|
2 Cloud Levels
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[45].pickup = Pickup_Puzzle;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
/*QUAKED item_puzzle_tavernkey (.3 .3 1) (-8 -8 -4) (8 8 4) x NO_DROP
|
|
|
|
Key puzzle piece
|
|
|
|
Ssdocks Level
|
|
|
|
NO_DROP - won't drop to ground
|
|
|
|
*/
|
1999-03-18 00:00:00 +00:00
|
|
|
playerExport.p_itemlist[46].pickup = Pickup_Puzzle;
|
|
|
|
|
|
|
|
// item_defense_tornado
|
|
|
|
/*QUAKED item_defense_tornado (.3 .3 1) (-16 -16 -16) (16 16 16) COOP_ONLY
|
|
|
|
Pickup for the Tornado defensive spell.
|
|
|
|
*/
|
|
|
|
playerExport.p_itemlist[47].pickup=Pickup_Defense;
|
|
|
|
playerExport.p_itemlist[47].use=Use_Defence;
|
|
|
|
playerExport.p_itemlist[47].weaponthink=DefenceThink_Tornado;
|
1998-11-24 00:00:00 +00:00
|
|
|
|
|
|
|
// ********************************************************************************************
|
|
|
|
// Initialise game variables.
|
|
|
|
// ********************************************************************************************
|
|
|
|
|
1999-03-18 00:00:00 +00:00
|
|
|
game.num_items=playerExport.p_num_items;
|
1998-11-24 00:00:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============
|
|
|
|
SetItemNames - called by worldspawn.
|
|
|
|
===============
|
|
|
|
*/
|
|
|
|
|
|
|
|
void SetItemNames(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
gitem_t *it;
|
|
|
|
|
|
|
|
for (i=0 ; i<game.num_items ; i++)
|
|
|
|
{
|
1999-03-18 00:00:00 +00:00
|
|
|
it = &playerExport.p_itemlist[i];
|
1998-11-24 00:00:00 +00:00
|
|
|
gi.configstring (CS_ITEMS+i, it->pickup_name);
|
|
|
|
}
|
|
|
|
}
|