Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

bg_misc.c (36059B)


      1 /*
      2 ===========================================================================
      3 Copyright (C) 1999-2005 Id Software, Inc.
      4 
      5 This file is part of Quake III Arena source code.
      6 
      7 Quake III Arena source code is free software; you can redistribute it
      8 and/or modify it under the terms of the GNU General Public License as
      9 published by the Free Software Foundation; either version 2 of the License,
     10 or (at your option) any later version.
     11 
     12 Quake III Arena source code is distributed in the hope that it will be
     13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 GNU General Public License for more details.
     16 
     17 You should have received a copy of the GNU General Public License
     18 along with Foobar; if not, write to the Free Software
     19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     20 ===========================================================================
     21 */
     22 //
     23 // bg_misc.c -- both games misc functions, all completely stateless
     24 
     25 #include "q_shared.h"
     26 #include "bg_public.h"
     27 
     28 /*QUAKED item_***** ( 0 0 0 ) (-16 -16 -16) (16 16 16) suspended
     29 DO NOT USE THIS CLASS, IT JUST HOLDS GENERAL INFORMATION.
     30 The suspended flag will allow items to hang in the air, otherwise they are dropped to the next surface.
     31 
     32 If an item is the target of another entity, it will not spawn in until fired.
     33 
     34 An item fires all of its targets when it is picked up.  If the toucher can't carry it, the targets won't be fired.
     35 
     36 "notfree" if set to 1, don't spawn in free for all games
     37 "notteam" if set to 1, don't spawn in team games
     38 "notsingle" if set to 1, don't spawn in single player games
     39 "wait"	override the default wait before respawning.  -1 = never respawn automatically, which can be used with targeted spawning.
     40 "random" random number of plus or minus seconds varied from the respawn time
     41 "count" override quantity or duration on most items.
     42 */
     43 
     44 gitem_t	bg_itemlist[] = 
     45 {
     46 	{
     47 		NULL,
     48 		NULL,
     49 		{ NULL,
     50 		NULL,
     51 		0, 0} ,
     52 /* icon */		NULL,
     53 /* pickup */	NULL,
     54 		0,
     55 		0,
     56 		0,
     57 /* precache */ "",
     58 /* sounds */ ""
     59 	},	// leave index 0 alone
     60 
     61 	//
     62 	// ARMOR
     63 	//
     64 
     65 /*QUAKED item_armor_shard (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
     66 */
     67 	{
     68 		"item_armor_shard", 
     69 		"sound/misc/ar1_pkup.wav",
     70 		{ "models/powerups/armor/shard.md3", 
     71 		"models/powerups/armor/shard_sphere.md3",
     72 		0, 0} ,
     73 /* icon */		"icons/iconr_shard",
     74 /* pickup */	"Armor Shard",
     75 		5,
     76 		IT_ARMOR,
     77 		0,
     78 /* precache */ "",
     79 /* sounds */ ""
     80 	},
     81 
     82 /*QUAKED item_armor_combat (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
     83 */
     84 	{
     85 		"item_armor_combat", 
     86 		"sound/misc/ar2_pkup.wav",
     87         { "models/powerups/armor/armor_yel.md3",
     88 		0, 0, 0},
     89 /* icon */		"icons/iconr_yellow",
     90 /* pickup */	"Armor",
     91 		50,
     92 		IT_ARMOR,
     93 		0,
     94 /* precache */ "",
     95 /* sounds */ ""
     96 	},
     97 
     98 /*QUAKED item_armor_body (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
     99 */
    100 	{
    101 		"item_armor_body", 
    102 		"sound/misc/ar2_pkup.wav",
    103         { "models/powerups/armor/armor_red.md3",
    104 		0, 0, 0},
    105 /* icon */		"icons/iconr_red",
    106 /* pickup */	"Heavy Armor",
    107 		100,
    108 		IT_ARMOR,
    109 		0,
    110 /* precache */ "",
    111 /* sounds */ ""
    112 	},
    113 
    114 	//
    115 	// health
    116 	//
    117 /*QUAKED item_health_small (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    118 */
    119 	{
    120 		"item_health_small",
    121 		"sound/items/s_health.wav",
    122         { "models/powerups/health/small_cross.md3", 
    123 		"models/powerups/health/small_sphere.md3", 
    124 		0, 0 },
    125 /* icon */		"icons/iconh_green",
    126 /* pickup */	"5 Health",
    127 		5,
    128 		IT_HEALTH,
    129 		0,
    130 /* precache */ "",
    131 /* sounds */ ""
    132 	},
    133 
    134 /*QUAKED item_health (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    135 */
    136 	{
    137 		"item_health",
    138 		"sound/items/n_health.wav",
    139         { "models/powerups/health/medium_cross.md3", 
    140 		"models/powerups/health/medium_sphere.md3", 
    141 		0, 0 },
    142 /* icon */		"icons/iconh_yellow",
    143 /* pickup */	"25 Health",
    144 		25,
    145 		IT_HEALTH,
    146 		0,
    147 /* precache */ "",
    148 /* sounds */ ""
    149 	},
    150 
    151 /*QUAKED item_health_large (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    152 */
    153 	{
    154 		"item_health_large",
    155 		"sound/items/l_health.wav",
    156         { "models/powerups/health/large_cross.md3", 
    157 		"models/powerups/health/large_sphere.md3", 
    158 		0, 0 },
    159 /* icon */		"icons/iconh_red",
    160 /* pickup */	"50 Health",
    161 		50,
    162 		IT_HEALTH,
    163 		0,
    164 /* precache */ "",
    165 /* sounds */ ""
    166 	},
    167 
    168 /*QUAKED item_health_mega (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    169 */
    170 	{
    171 		"item_health_mega",
    172 		"sound/items/m_health.wav",
    173         { "models/powerups/health/mega_cross.md3", 
    174 		"models/powerups/health/mega_sphere.md3", 
    175 		0, 0 },
    176 /* icon */		"icons/iconh_mega",
    177 /* pickup */	"Mega Health",
    178 		100,
    179 		IT_HEALTH,
    180 		0,
    181 /* precache */ "",
    182 /* sounds */ ""
    183 	},
    184 
    185 
    186 	//
    187 	// WEAPONS 
    188 	//
    189 
    190 /*QUAKED weapon_gauntlet (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    191 */
    192 	{
    193 		"weapon_gauntlet", 
    194 		"sound/misc/w_pkup.wav",
    195         { "models/weapons2/gauntlet/gauntlet.md3",
    196 		0, 0, 0},
    197 /* icon */		"icons/iconw_gauntlet",
    198 /* pickup */	"Gauntlet",
    199 		0,
    200 		IT_WEAPON,
    201 		WP_GAUNTLET,
    202 /* precache */ "",
    203 /* sounds */ ""
    204 	},
    205 
    206 /*QUAKED weapon_shotgun (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    207 */
    208 	{
    209 		"weapon_shotgun", 
    210 		"sound/misc/w_pkup.wav",
    211         { "models/weapons2/shotgun/shotgun.md3", 
    212 		0, 0, 0},
    213 /* icon */		"icons/iconw_shotgun",
    214 /* pickup */	"Shotgun",
    215 		10,
    216 		IT_WEAPON,
    217 		WP_SHOTGUN,
    218 /* precache */ "",
    219 /* sounds */ ""
    220 	},
    221 
    222 /*QUAKED weapon_machinegun (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    223 */
    224 	{
    225 		"weapon_machinegun", 
    226 		"sound/misc/w_pkup.wav",
    227         { "models/weapons2/machinegun/machinegun.md3", 
    228 		0, 0, 0},
    229 /* icon */		"icons/iconw_machinegun",
    230 /* pickup */	"Machinegun",
    231 		40,
    232 		IT_WEAPON,
    233 		WP_MACHINEGUN,
    234 /* precache */ "",
    235 /* sounds */ ""
    236 	},
    237 
    238 /*QUAKED weapon_grenadelauncher (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    239 */
    240 	{
    241 		"weapon_grenadelauncher",
    242 		"sound/misc/w_pkup.wav",
    243         { "models/weapons2/grenadel/grenadel.md3", 
    244 		0, 0, 0},
    245 /* icon */		"icons/iconw_grenade",
    246 /* pickup */	"Grenade Launcher",
    247 		10,
    248 		IT_WEAPON,
    249 		WP_GRENADE_LAUNCHER,
    250 /* precache */ "",
    251 /* sounds */ "sound/weapons/grenade/hgrenb1a.wav sound/weapons/grenade/hgrenb2a.wav"
    252 	},
    253 
    254 /*QUAKED weapon_rocketlauncher (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    255 */
    256 	{
    257 		"weapon_rocketlauncher",
    258 		"sound/misc/w_pkup.wav",
    259         { "models/weapons2/rocketl/rocketl.md3", 
    260 		0, 0, 0},
    261 /* icon */		"icons/iconw_rocket",
    262 /* pickup */	"Rocket Launcher",
    263 		10,
    264 		IT_WEAPON,
    265 		WP_ROCKET_LAUNCHER,
    266 /* precache */ "",
    267 /* sounds */ ""
    268 	},
    269 
    270 /*QUAKED weapon_lightning (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    271 */
    272 	{
    273 		"weapon_lightning", 
    274 		"sound/misc/w_pkup.wav",
    275         { "models/weapons2/lightning/lightning.md3", 
    276 		0, 0, 0},
    277 /* icon */		"icons/iconw_lightning",
    278 /* pickup */	"Lightning Gun",
    279 		100,
    280 		IT_WEAPON,
    281 		WP_LIGHTNING,
    282 /* precache */ "",
    283 /* sounds */ ""
    284 	},
    285 
    286 /*QUAKED weapon_railgun (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    287 */
    288 	{
    289 		"weapon_railgun", 
    290 		"sound/misc/w_pkup.wav",
    291         { "models/weapons2/railgun/railgun.md3", 
    292 		0, 0, 0},
    293 /* icon */		"icons/iconw_railgun",
    294 /* pickup */	"Railgun",
    295 		10,
    296 		IT_WEAPON,
    297 		WP_RAILGUN,
    298 /* precache */ "",
    299 /* sounds */ ""
    300 	},
    301 
    302 /*QUAKED weapon_plasmagun (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    303 */
    304 	{
    305 		"weapon_plasmagun", 
    306 		"sound/misc/w_pkup.wav",
    307         { "models/weapons2/plasma/plasma.md3", 
    308 		0, 0, 0},
    309 /* icon */		"icons/iconw_plasma",
    310 /* pickup */	"Plasma Gun",
    311 		50,
    312 		IT_WEAPON,
    313 		WP_PLASMAGUN,
    314 /* precache */ "",
    315 /* sounds */ ""
    316 	},
    317 
    318 /*QUAKED weapon_bfg (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    319 */
    320 	{
    321 		"weapon_bfg",
    322 		"sound/misc/w_pkup.wav",
    323         { "models/weapons2/bfg/bfg.md3", 
    324 		0, 0, 0},
    325 /* icon */		"icons/iconw_bfg",
    326 /* pickup */	"BFG10K",
    327 		20,
    328 		IT_WEAPON,
    329 		WP_BFG,
    330 /* precache */ "",
    331 /* sounds */ ""
    332 	},
    333 
    334 /*QUAKED weapon_grapplinghook (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    335 */
    336 	{
    337 		"weapon_grapplinghook",
    338 		"sound/misc/w_pkup.wav",
    339         { "models/weapons2/grapple/grapple.md3", 
    340 		0, 0, 0},
    341 /* icon */		"icons/iconw_grapple",
    342 /* pickup */	"Grappling Hook",
    343 		0,
    344 		IT_WEAPON,
    345 		WP_GRAPPLING_HOOK,
    346 /* precache */ "",
    347 /* sounds */ ""
    348 	},
    349 
    350 	//
    351 	// AMMO ITEMS
    352 	//
    353 
    354 /*QUAKED ammo_shells (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    355 */
    356 	{
    357 		"ammo_shells",
    358 		"sound/misc/am_pkup.wav",
    359         { "models/powerups/ammo/shotgunam.md3", 
    360 		0, 0, 0},
    361 /* icon */		"icons/icona_shotgun",
    362 /* pickup */	"Shells",
    363 		10,
    364 		IT_AMMO,
    365 		WP_SHOTGUN,
    366 /* precache */ "",
    367 /* sounds */ ""
    368 	},
    369 
    370 /*QUAKED ammo_bullets (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    371 */
    372 	{
    373 		"ammo_bullets",
    374 		"sound/misc/am_pkup.wav",
    375         { "models/powerups/ammo/machinegunam.md3", 
    376 		0, 0, 0},
    377 /* icon */		"icons/icona_machinegun",
    378 /* pickup */	"Bullets",
    379 		50,
    380 		IT_AMMO,
    381 		WP_MACHINEGUN,
    382 /* precache */ "",
    383 /* sounds */ ""
    384 	},
    385 
    386 /*QUAKED ammo_grenades (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    387 */
    388 	{
    389 		"ammo_grenades",
    390 		"sound/misc/am_pkup.wav",
    391         { "models/powerups/ammo/grenadeam.md3", 
    392 		0, 0, 0},
    393 /* icon */		"icons/icona_grenade",
    394 /* pickup */	"Grenades",
    395 		5,
    396 		IT_AMMO,
    397 		WP_GRENADE_LAUNCHER,
    398 /* precache */ "",
    399 /* sounds */ ""
    400 	},
    401 
    402 /*QUAKED ammo_cells (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    403 */
    404 	{
    405 		"ammo_cells",
    406 		"sound/misc/am_pkup.wav",
    407         { "models/powerups/ammo/plasmaam.md3", 
    408 		0, 0, 0},
    409 /* icon */		"icons/icona_plasma",
    410 /* pickup */	"Cells",
    411 		30,
    412 		IT_AMMO,
    413 		WP_PLASMAGUN,
    414 /* precache */ "",
    415 /* sounds */ ""
    416 	},
    417 
    418 /*QUAKED ammo_lightning (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    419 */
    420 	{
    421 		"ammo_lightning",
    422 		"sound/misc/am_pkup.wav",
    423         { "models/powerups/ammo/lightningam.md3", 
    424 		0, 0, 0},
    425 /* icon */		"icons/icona_lightning",
    426 /* pickup */	"Lightning",
    427 		60,
    428 		IT_AMMO,
    429 		WP_LIGHTNING,
    430 /* precache */ "",
    431 /* sounds */ ""
    432 	},
    433 
    434 /*QUAKED ammo_rockets (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    435 */
    436 	{
    437 		"ammo_rockets",
    438 		"sound/misc/am_pkup.wav",
    439         { "models/powerups/ammo/rocketam.md3", 
    440 		0, 0, 0},
    441 /* icon */		"icons/icona_rocket",
    442 /* pickup */	"Rockets",
    443 		5,
    444 		IT_AMMO,
    445 		WP_ROCKET_LAUNCHER,
    446 /* precache */ "",
    447 /* sounds */ ""
    448 	},
    449 
    450 /*QUAKED ammo_slugs (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    451 */
    452 	{
    453 		"ammo_slugs",
    454 		"sound/misc/am_pkup.wav",
    455         { "models/powerups/ammo/railgunam.md3", 
    456 		0, 0, 0},
    457 /* icon */		"icons/icona_railgun",
    458 /* pickup */	"Slugs",
    459 		10,
    460 		IT_AMMO,
    461 		WP_RAILGUN,
    462 /* precache */ "",
    463 /* sounds */ ""
    464 	},
    465 
    466 /*QUAKED ammo_bfg (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    467 */
    468 	{
    469 		"ammo_bfg",
    470 		"sound/misc/am_pkup.wav",
    471         { "models/powerups/ammo/bfgam.md3", 
    472 		0, 0, 0},
    473 /* icon */		"icons/icona_bfg",
    474 /* pickup */	"Bfg Ammo",
    475 		15,
    476 		IT_AMMO,
    477 		WP_BFG,
    478 /* precache */ "",
    479 /* sounds */ ""
    480 	},
    481 
    482 	//
    483 	// HOLDABLE ITEMS
    484 	//
    485 /*QUAKED holdable_teleporter (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    486 */
    487 	{
    488 		"holdable_teleporter", 
    489 		"sound/items/holdable.wav",
    490         { "models/powerups/holdable/teleporter.md3", 
    491 		0, 0, 0},
    492 /* icon */		"icons/teleporter",
    493 /* pickup */	"Personal Teleporter",
    494 		60,
    495 		IT_HOLDABLE,
    496 		HI_TELEPORTER,
    497 /* precache */ "",
    498 /* sounds */ ""
    499 	},
    500 /*QUAKED holdable_medkit (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    501 */
    502 	{
    503 		"holdable_medkit", 
    504 		"sound/items/holdable.wav",
    505         { 
    506 		"models/powerups/holdable/medkit.md3", 
    507 		"models/powerups/holdable/medkit_sphere.md3",
    508 		0, 0},
    509 /* icon */		"icons/medkit",
    510 /* pickup */	"Medkit",
    511 		60,
    512 		IT_HOLDABLE,
    513 		HI_MEDKIT,
    514 /* precache */ "",
    515 /* sounds */ "sound/items/use_medkit.wav"
    516 	},
    517 
    518 	//
    519 	// POWERUP ITEMS
    520 	//
    521 /*QUAKED item_quad (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    522 */
    523 	{
    524 		"item_quad", 
    525 		"sound/items/quaddamage.wav",
    526         { "models/powerups/instant/quad.md3", 
    527         "models/powerups/instant/quad_ring.md3",
    528 		0, 0 },
    529 /* icon */		"icons/quad",
    530 /* pickup */	"Quad Damage",
    531 		30,
    532 		IT_POWERUP,
    533 		PW_QUAD,
    534 /* precache */ "",
    535 /* sounds */ "sound/items/damage2.wav sound/items/damage3.wav"
    536 	},
    537 
    538 /*QUAKED item_enviro (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    539 */
    540 	{
    541 		"item_enviro",
    542 		"sound/items/protect.wav",
    543         { "models/powerups/instant/enviro.md3", 
    544 		"models/powerups/instant/enviro_ring.md3", 
    545 		0, 0 },
    546 /* icon */		"icons/envirosuit",
    547 /* pickup */	"Battle Suit",
    548 		30,
    549 		IT_POWERUP,
    550 		PW_BATTLESUIT,
    551 /* precache */ "",
    552 /* sounds */ "sound/items/airout.wav sound/items/protect3.wav"
    553 	},
    554 
    555 /*QUAKED item_haste (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    556 */
    557 	{
    558 		"item_haste",
    559 		"sound/items/haste.wav",
    560         { "models/powerups/instant/haste.md3", 
    561 		"models/powerups/instant/haste_ring.md3", 
    562 		0, 0 },
    563 /* icon */		"icons/haste",
    564 /* pickup */	"Speed",
    565 		30,
    566 		IT_POWERUP,
    567 		PW_HASTE,
    568 /* precache */ "",
    569 /* sounds */ ""
    570 	},
    571 
    572 /*QUAKED item_invis (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    573 */
    574 	{
    575 		"item_invis",
    576 		"sound/items/invisibility.wav",
    577         { "models/powerups/instant/invis.md3", 
    578 		"models/powerups/instant/invis_ring.md3", 
    579 		0, 0 },
    580 /* icon */		"icons/invis",
    581 /* pickup */	"Invisibility",
    582 		30,
    583 		IT_POWERUP,
    584 		PW_INVIS,
    585 /* precache */ "",
    586 /* sounds */ ""
    587 	},
    588 
    589 /*QUAKED item_regen (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    590 */
    591 	{
    592 		"item_regen",
    593 		"sound/items/regeneration.wav",
    594         { "models/powerups/instant/regen.md3", 
    595 		"models/powerups/instant/regen_ring.md3", 
    596 		0, 0 },
    597 /* icon */		"icons/regen",
    598 /* pickup */	"Regeneration",
    599 		30,
    600 		IT_POWERUP,
    601 		PW_REGEN,
    602 /* precache */ "",
    603 /* sounds */ "sound/items/regen.wav"
    604 	},
    605 
    606 /*QUAKED item_flight (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    607 */
    608 	{
    609 		"item_flight",
    610 		"sound/items/flight.wav",
    611         { "models/powerups/instant/flight.md3", 
    612 		"models/powerups/instant/flight_ring.md3", 
    613 		0, 0 },
    614 /* icon */		"icons/flight",
    615 /* pickup */	"Flight",
    616 		60,
    617 		IT_POWERUP,
    618 		PW_FLIGHT,
    619 /* precache */ "",
    620 /* sounds */ "sound/items/flight.wav"
    621 	},
    622 
    623 /*QUAKED team_CTF_redflag (1 0 0) (-16 -16 -16) (16 16 16)
    624 Only in CTF games
    625 */
    626 	{
    627 		"team_CTF_redflag",
    628 		NULL,
    629         { "models/flags/r_flag.md3",
    630 		0, 0, 0 },
    631 /* icon */		"icons/iconf_red1",
    632 /* pickup */	"Red Flag",
    633 		0,
    634 		IT_TEAM,
    635 		PW_REDFLAG,
    636 /* precache */ "",
    637 /* sounds */ ""
    638 	},
    639 
    640 /*QUAKED team_CTF_blueflag (0 0 1) (-16 -16 -16) (16 16 16)
    641 Only in CTF games
    642 */
    643 	{
    644 		"team_CTF_blueflag",
    645 		NULL,
    646         { "models/flags/b_flag.md3",
    647 		0, 0, 0 },
    648 /* icon */		"icons/iconf_blu1",
    649 /* pickup */	"Blue Flag",
    650 		0,
    651 		IT_TEAM,
    652 		PW_BLUEFLAG,
    653 /* precache */ "",
    654 /* sounds */ ""
    655 	},
    656 
    657 #ifdef MISSIONPACK
    658 /*QUAKED holdable_kamikaze (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    659 */
    660 	{
    661 		"holdable_kamikaze", 
    662 		"sound/items/holdable.wav",
    663         { "models/powerups/kamikazi.md3", 
    664 		0, 0, 0},
    665 /* icon */		"icons/kamikaze",
    666 /* pickup */	"Kamikaze",
    667 		60,
    668 		IT_HOLDABLE,
    669 		HI_KAMIKAZE,
    670 /* precache */ "",
    671 /* sounds */ "sound/items/kamikazerespawn.wav"
    672 	},
    673 
    674 /*QUAKED holdable_portal (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    675 */
    676 	{
    677 		"holdable_portal", 
    678 		"sound/items/holdable.wav",
    679         { "models/powerups/holdable/porter.md3",
    680 		0, 0, 0},
    681 /* icon */		"icons/portal",
    682 /* pickup */	"Portal",
    683 		60,
    684 		IT_HOLDABLE,
    685 		HI_PORTAL,
    686 /* precache */ "",
    687 /* sounds */ ""
    688 	},
    689 
    690 /*QUAKED holdable_invulnerability (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    691 */
    692 	{
    693 		"holdable_invulnerability", 
    694 		"sound/items/holdable.wav",
    695         { "models/powerups/holdable/invulnerability.md3", 
    696 		0, 0, 0},
    697 /* icon */		"icons/invulnerability",
    698 /* pickup */	"Invulnerability",
    699 		60,
    700 		IT_HOLDABLE,
    701 		HI_INVULNERABILITY,
    702 /* precache */ "",
    703 /* sounds */ ""
    704 	},
    705 
    706 /*QUAKED ammo_nails (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    707 */
    708 	{
    709 		"ammo_nails",
    710 		"sound/misc/am_pkup.wav",
    711         { "models/powerups/ammo/nailgunam.md3", 
    712 		0, 0, 0},
    713 /* icon */		"icons/icona_nailgun",
    714 /* pickup */	"Nails",
    715 		20,
    716 		IT_AMMO,
    717 		WP_NAILGUN,
    718 /* precache */ "",
    719 /* sounds */ ""
    720 	},
    721 
    722 /*QUAKED ammo_mines (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    723 */
    724 	{
    725 		"ammo_mines",
    726 		"sound/misc/am_pkup.wav",
    727         { "models/powerups/ammo/proxmineam.md3", 
    728 		0, 0, 0},
    729 /* icon */		"icons/icona_proxlauncher",
    730 /* pickup */	"Proximity Mines",
    731 		10,
    732 		IT_AMMO,
    733 		WP_PROX_LAUNCHER,
    734 /* precache */ "",
    735 /* sounds */ ""
    736 	},
    737 
    738 /*QUAKED ammo_belt (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    739 */
    740 	{
    741 		"ammo_belt",
    742 		"sound/misc/am_pkup.wav",
    743         { "models/powerups/ammo/chaingunam.md3", 
    744 		0, 0, 0},
    745 /* icon */		"icons/icona_chaingun",
    746 /* pickup */	"Chaingun Belt",
    747 		100,
    748 		IT_AMMO,
    749 		WP_CHAINGUN,
    750 /* precache */ "",
    751 /* sounds */ ""
    752 	},
    753 
    754 	//
    755 	// PERSISTANT POWERUP ITEMS
    756 	//
    757 /*QUAKED item_scout (.3 .3 1) (-16 -16 -16) (16 16 16) suspended redTeam blueTeam
    758 */
    759 	{
    760 		"item_scout",
    761 		"sound/items/scout.wav",
    762         { "models/powerups/scout.md3", 
    763 		0, 0, 0 },
    764 /* icon */		"icons/scout",
    765 /* pickup */	"Scout",
    766 		30,
    767 		IT_PERSISTANT_POWERUP,
    768 		PW_SCOUT,
    769 /* precache */ "",
    770 /* sounds */ ""
    771 	},
    772 
    773 /*QUAKED item_guard (.3 .3 1) (-16 -16 -16) (16 16 16) suspended redTeam blueTeam
    774 */
    775 	{
    776 		"item_guard",
    777 		"sound/items/guard.wav",
    778         { "models/powerups/guard.md3", 
    779 		0, 0, 0 },
    780 /* icon */		"icons/guard",
    781 /* pickup */	"Guard",
    782 		30,
    783 		IT_PERSISTANT_POWERUP,
    784 		PW_GUARD,
    785 /* precache */ "",
    786 /* sounds */ ""
    787 	},
    788 
    789 /*QUAKED item_doubler (.3 .3 1) (-16 -16 -16) (16 16 16) suspended redTeam blueTeam
    790 */
    791 	{
    792 		"item_doubler",
    793 		"sound/items/doubler.wav",
    794         { "models/powerups/doubler.md3", 
    795 		0, 0, 0 },
    796 /* icon */		"icons/doubler",
    797 /* pickup */	"Doubler",
    798 		30,
    799 		IT_PERSISTANT_POWERUP,
    800 		PW_DOUBLER,
    801 /* precache */ "",
    802 /* sounds */ ""
    803 	},
    804 
    805 /*QUAKED item_doubler (.3 .3 1) (-16 -16 -16) (16 16 16) suspended redTeam blueTeam
    806 */
    807 	{
    808 		"item_ammoregen",
    809 		"sound/items/ammoregen.wav",
    810         { "models/powerups/ammo.md3",
    811 		0, 0, 0 },
    812 /* icon */		"icons/ammo_regen",
    813 /* pickup */	"Ammo Regen",
    814 		30,
    815 		IT_PERSISTANT_POWERUP,
    816 		PW_AMMOREGEN,
    817 /* precache */ "",
    818 /* sounds */ ""
    819 	},
    820 
    821 	/*QUAKED team_CTF_neutralflag (0 0 1) (-16 -16 -16) (16 16 16)
    822 Only in One Flag CTF games
    823 */
    824 	{
    825 		"team_CTF_neutralflag",
    826 		NULL,
    827         { "models/flags/n_flag.md3",
    828 		0, 0, 0 },
    829 /* icon */		"icons/iconf_neutral1",
    830 /* pickup */	"Neutral Flag",
    831 		0,
    832 		IT_TEAM,
    833 		PW_NEUTRALFLAG,
    834 /* precache */ "",
    835 /* sounds */ ""
    836 	},
    837 
    838 	{
    839 		"item_redcube",
    840 		"sound/misc/am_pkup.wav",
    841         { "models/powerups/orb/r_orb.md3",
    842 		0, 0, 0 },
    843 /* icon */		"icons/iconh_rorb",
    844 /* pickup */	"Red Cube",
    845 		0,
    846 		IT_TEAM,
    847 		0,
    848 /* precache */ "",
    849 /* sounds */ ""
    850 	},
    851 
    852 	{
    853 		"item_bluecube",
    854 		"sound/misc/am_pkup.wav",
    855         { "models/powerups/orb/b_orb.md3",
    856 		0, 0, 0 },
    857 /* icon */		"icons/iconh_borb",
    858 /* pickup */	"Blue Cube",
    859 		0,
    860 		IT_TEAM,
    861 		0,
    862 /* precache */ "",
    863 /* sounds */ ""
    864 	},
    865 /*QUAKED weapon_nailgun (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    866 */
    867 	{
    868 		"weapon_nailgun", 
    869 		"sound/misc/w_pkup.wav",
    870         { "models/weapons/nailgun/nailgun.md3", 
    871 		0, 0, 0},
    872 /* icon */		"icons/iconw_nailgun",
    873 /* pickup */	"Nailgun",
    874 		10,
    875 		IT_WEAPON,
    876 		WP_NAILGUN,
    877 /* precache */ "",
    878 /* sounds */ ""
    879 	},
    880 
    881 /*QUAKED weapon_prox_launcher (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    882 */
    883 	{
    884 		"weapon_prox_launcher", 
    885 		"sound/misc/w_pkup.wav",
    886         { "models/weapons/proxmine/proxmine.md3", 
    887 		0, 0, 0},
    888 /* icon */		"icons/iconw_proxlauncher",
    889 /* pickup */	"Prox Launcher",
    890 		5,
    891 		IT_WEAPON,
    892 		WP_PROX_LAUNCHER,
    893 /* precache */ "",
    894 /* sounds */ "sound/weapons/proxmine/wstbtick.wav "
    895 			"sound/weapons/proxmine/wstbactv.wav "
    896 			"sound/weapons/proxmine/wstbimpl.wav "
    897 			"sound/weapons/proxmine/wstbimpm.wav "
    898 			"sound/weapons/proxmine/wstbimpd.wav "
    899 			"sound/weapons/proxmine/wstbactv.wav"
    900 	},
    901 
    902 /*QUAKED weapon_chaingun (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
    903 */
    904 	{
    905 		"weapon_chaingun", 
    906 		"sound/misc/w_pkup.wav",
    907         { "models/weapons/vulcan/vulcan.md3", 
    908 		0, 0, 0},
    909 /* icon */		"icons/iconw_chaingun",
    910 /* pickup */	"Chaingun",
    911 		80,
    912 		IT_WEAPON,
    913 		WP_CHAINGUN,
    914 /* precache */ "",
    915 /* sounds */ "sound/weapons/vulcan/wvulwind.wav"
    916 	},
    917 #endif
    918 
    919 	// end of list marker
    920 	{NULL}
    921 };
    922 
    923 int		bg_numItems = sizeof(bg_itemlist) / sizeof(bg_itemlist[0]) - 1;
    924 
    925 
    926 /*
    927 ==============
    928 BG_FindItemForPowerup
    929 ==============
    930 */
    931 gitem_t	*BG_FindItemForPowerup( powerup_t pw ) {
    932 	int		i;
    933 
    934 	for ( i = 0 ; i < bg_numItems ; i++ ) {
    935 		if ( (bg_itemlist[i].giType == IT_POWERUP || 
    936 					bg_itemlist[i].giType == IT_TEAM ||
    937 					bg_itemlist[i].giType == IT_PERSISTANT_POWERUP) && 
    938 			bg_itemlist[i].giTag == pw ) {
    939 			return &bg_itemlist[i];
    940 		}
    941 	}
    942 
    943 	return NULL;
    944 }
    945 
    946 
    947 /*
    948 ==============
    949 BG_FindItemForHoldable
    950 ==============
    951 */
    952 gitem_t	*BG_FindItemForHoldable( holdable_t pw ) {
    953 	int		i;
    954 
    955 	for ( i = 0 ; i < bg_numItems ; i++ ) {
    956 		if ( bg_itemlist[i].giType == IT_HOLDABLE && bg_itemlist[i].giTag == pw ) {
    957 			return &bg_itemlist[i];
    958 		}
    959 	}
    960 
    961 	Com_Error( ERR_DROP, "HoldableItem not found" );
    962 
    963 	return NULL;
    964 }
    965 
    966 
    967 /*
    968 ===============
    969 BG_FindItemForWeapon
    970 
    971 ===============
    972 */
    973 gitem_t	*BG_FindItemForWeapon( weapon_t weapon ) {
    974 	gitem_t	*it;
    975 	
    976 	for ( it = bg_itemlist + 1 ; it->classname ; it++) {
    977 		if ( it->giType == IT_WEAPON && it->giTag == weapon ) {
    978 			return it;
    979 		}
    980 	}
    981 
    982 	Com_Error( ERR_DROP, "Couldn't find item for weapon %i", weapon);
    983 	return NULL;
    984 }
    985 
    986 /*
    987 ===============
    988 BG_FindItem
    989 
    990 ===============
    991 */
    992 gitem_t	*BG_FindItem( const char *pickupName ) {
    993 	gitem_t	*it;
    994 	
    995 	for ( it = bg_itemlist + 1 ; it->classname ; it++ ) {
    996 		if ( !Q_stricmp( it->pickup_name, pickupName ) )
    997 			return it;
    998 	}
    999 
   1000 	return NULL;
   1001 }
   1002 
   1003 /*
   1004 ============
   1005 BG_PlayerTouchesItem
   1006 
   1007 Items can be picked up without actually touching their physical bounds to make
   1008 grabbing them easier
   1009 ============
   1010 */
   1011 qboolean	BG_PlayerTouchesItem( playerState_t *ps, entityState_t *item, int atTime ) {
   1012 	vec3_t		origin;
   1013 
   1014 	BG_EvaluateTrajectory( &item->pos, atTime, origin );
   1015 
   1016 	// we are ignoring ducked differences here
   1017 	if ( ps->origin[0] - origin[0] > 44
   1018 		|| ps->origin[0] - origin[0] < -50
   1019 		|| ps->origin[1] - origin[1] > 36
   1020 		|| ps->origin[1] - origin[1] < -36
   1021 		|| ps->origin[2] - origin[2] > 36
   1022 		|| ps->origin[2] - origin[2] < -36 ) {
   1023 		return qfalse;
   1024 	}
   1025 
   1026 	return qtrue;
   1027 }
   1028 
   1029 
   1030 
   1031 /*
   1032 ================
   1033 BG_CanItemBeGrabbed
   1034 
   1035 Returns false if the item should not be picked up.
   1036 This needs to be the same for client side prediction and server use.
   1037 ================
   1038 */
   1039 qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const playerState_t *ps ) {
   1040 	gitem_t	*item;
   1041 #ifdef MISSIONPACK
   1042 	int		upperBound;
   1043 #endif
   1044 
   1045 	if ( ent->modelindex < 1 || ent->modelindex >= bg_numItems ) {
   1046 		Com_Error( ERR_DROP, "BG_CanItemBeGrabbed: index out of range" );
   1047 	}
   1048 
   1049 	item = &bg_itemlist[ent->modelindex];
   1050 
   1051 	switch( item->giType ) {
   1052 	case IT_WEAPON:
   1053 		return qtrue;	// weapons are always picked up
   1054 
   1055 	case IT_AMMO:
   1056 		if ( ps->ammo[ item->giTag ] >= 200 ) {
   1057 			return qfalse;		// can't hold any more
   1058 		}
   1059 		return qtrue;
   1060 
   1061 	case IT_ARMOR:
   1062 #ifdef MISSIONPACK
   1063 		if( bg_itemlist[ps->stats[STAT_PERSISTANT_POWERUP]].giTag == PW_SCOUT ) {
   1064 			return qfalse;
   1065 		}
   1066 
   1067 		// we also clamp armor to the maxhealth for handicapping
   1068 		if( bg_itemlist[ps->stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
   1069 			upperBound = ps->stats[STAT_MAX_HEALTH];
   1070 		}
   1071 		else {
   1072 			upperBound = ps->stats[STAT_MAX_HEALTH] * 2;
   1073 		}
   1074 
   1075 		if ( ps->stats[STAT_ARMOR] >= upperBound ) {
   1076 			return qfalse;
   1077 		}
   1078 #else
   1079 		if ( ps->stats[STAT_ARMOR] >= ps->stats[STAT_MAX_HEALTH] * 2 ) {
   1080 			return qfalse;
   1081 		}
   1082 #endif
   1083 		return qtrue;
   1084 
   1085 	case IT_HEALTH:
   1086 		// small and mega healths will go over the max, otherwise
   1087 		// don't pick up if already at max
   1088 #ifdef MISSIONPACK
   1089 		if( bg_itemlist[ps->stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
   1090 			upperBound = ps->stats[STAT_MAX_HEALTH];
   1091 		}
   1092 		else
   1093 #endif
   1094 		if ( item->quantity == 5 || item->quantity == 100 ) {
   1095 			if ( ps->stats[STAT_HEALTH] >= ps->stats[STAT_MAX_HEALTH] * 2 ) {
   1096 				return qfalse;
   1097 			}
   1098 			return qtrue;
   1099 		}
   1100 
   1101 		if ( ps->stats[STAT_HEALTH] >= ps->stats[STAT_MAX_HEALTH] ) {
   1102 			return qfalse;
   1103 		}
   1104 		return qtrue;
   1105 
   1106 	case IT_POWERUP:
   1107 		return qtrue;	// powerups are always picked up
   1108 
   1109 #ifdef MISSIONPACK
   1110 	case IT_PERSISTANT_POWERUP:
   1111 		// can only hold one item at a time
   1112 		if ( ps->stats[STAT_PERSISTANT_POWERUP] ) {
   1113 			return qfalse;
   1114 		}
   1115 
   1116 		// check team only
   1117 		if( ( ent->generic1 & 2 ) && ( ps->persistant[PERS_TEAM] != TEAM_RED ) ) {
   1118 			return qfalse;
   1119 		}
   1120 		if( ( ent->generic1 & 4 ) && ( ps->persistant[PERS_TEAM] != TEAM_BLUE ) ) {
   1121 			return qfalse;
   1122 		}
   1123 
   1124 		return qtrue;
   1125 #endif
   1126 
   1127 	case IT_TEAM: // team items, such as flags
   1128 #ifdef MISSIONPACK		
   1129 		if( gametype == GT_1FCTF ) {
   1130 			// neutral flag can always be picked up
   1131 			if( item->giTag == PW_NEUTRALFLAG ) {
   1132 				return qtrue;
   1133 			}
   1134 			if (ps->persistant[PERS_TEAM] == TEAM_RED) {
   1135 				if (item->giTag == PW_BLUEFLAG  && ps->powerups[PW_NEUTRALFLAG] ) {
   1136 					return qtrue;
   1137 				}
   1138 			} else if (ps->persistant[PERS_TEAM] == TEAM_BLUE) {
   1139 				if (item->giTag == PW_REDFLAG  && ps->powerups[PW_NEUTRALFLAG] ) {
   1140 					return qtrue;
   1141 				}
   1142 			}
   1143 		}
   1144 #endif
   1145 		if( gametype == GT_CTF ) {
   1146 			// ent->modelindex2 is non-zero on items if they are dropped
   1147 			// we need to know this because we can pick up our dropped flag (and return it)
   1148 			// but we can't pick up our flag at base
   1149 			if (ps->persistant[PERS_TEAM] == TEAM_RED) {
   1150 				if (item->giTag == PW_BLUEFLAG ||
   1151 					(item->giTag == PW_REDFLAG && ent->modelindex2) ||
   1152 					(item->giTag == PW_REDFLAG && ps->powerups[PW_BLUEFLAG]) )
   1153 					return qtrue;
   1154 			} else if (ps->persistant[PERS_TEAM] == TEAM_BLUE) {
   1155 				if (item->giTag == PW_REDFLAG ||
   1156 					(item->giTag == PW_BLUEFLAG && ent->modelindex2) ||
   1157 					(item->giTag == PW_BLUEFLAG && ps->powerups[PW_REDFLAG]) )
   1158 					return qtrue;
   1159 			}
   1160 		}
   1161 
   1162 #ifdef MISSIONPACK
   1163 		if( gametype == GT_HARVESTER ) {
   1164 			return qtrue;
   1165 		}
   1166 #endif
   1167 		return qfalse;
   1168 
   1169 	case IT_HOLDABLE:
   1170 		// can only hold one item at a time
   1171 		if ( ps->stats[STAT_HOLDABLE_ITEM] ) {
   1172 			return qfalse;
   1173 		}
   1174 		return qtrue;
   1175 
   1176         case IT_BAD:
   1177             Com_Error( ERR_DROP, "BG_CanItemBeGrabbed: IT_BAD" );
   1178         default:
   1179 #ifndef Q3_VM
   1180 #ifndef NDEBUG // bk0001204
   1181           Com_Printf("BG_CanItemBeGrabbed: unknown enum %d\n", item->giType );
   1182 #endif
   1183 #endif
   1184          break;
   1185 	}
   1186 
   1187 	return qfalse;
   1188 }
   1189 
   1190 //======================================================================
   1191 
   1192 /*
   1193 ================
   1194 BG_EvaluateTrajectory
   1195 
   1196 ================
   1197 */
   1198 void BG_EvaluateTrajectory( const trajectory_t *tr, int atTime, vec3_t result ) {
   1199 	float		deltaTime;
   1200 	float		phase;
   1201 
   1202 	switch( tr->trType ) {
   1203 	case TR_STATIONARY:
   1204 	case TR_INTERPOLATE:
   1205 		VectorCopy( tr->trBase, result );
   1206 		break;
   1207 	case TR_LINEAR:
   1208 		deltaTime = ( atTime - tr->trTime ) * 0.001;	// milliseconds to seconds
   1209 		VectorMA( tr->trBase, deltaTime, tr->trDelta, result );
   1210 		break;
   1211 	case TR_SINE:
   1212 		deltaTime = ( atTime - tr->trTime ) / (float) tr->trDuration;
   1213 		phase = sin( deltaTime * M_PI * 2 );
   1214 		VectorMA( tr->trBase, phase, tr->trDelta, result );
   1215 		break;
   1216 	case TR_LINEAR_STOP:
   1217 		if ( atTime > tr->trTime + tr->trDuration ) {
   1218 			atTime = tr->trTime + tr->trDuration;
   1219 		}
   1220 		deltaTime = ( atTime - tr->trTime ) * 0.001;	// milliseconds to seconds
   1221 		if ( deltaTime < 0 ) {
   1222 			deltaTime = 0;
   1223 		}
   1224 		VectorMA( tr->trBase, deltaTime, tr->trDelta, result );
   1225 		break;
   1226 	case TR_GRAVITY:
   1227 		deltaTime = ( atTime - tr->trTime ) * 0.001;	// milliseconds to seconds
   1228 		VectorMA( tr->trBase, deltaTime, tr->trDelta, result );
   1229 		result[2] -= 0.5 * DEFAULT_GRAVITY * deltaTime * deltaTime;		// FIXME: local gravity...
   1230 		break;
   1231 	default:
   1232 		Com_Error( ERR_DROP, "BG_EvaluateTrajectory: unknown trType: %i", tr->trTime );
   1233 		break;
   1234 	}
   1235 }
   1236 
   1237 /*
   1238 ================
   1239 BG_EvaluateTrajectoryDelta
   1240 
   1241 For determining velocity at a given time
   1242 ================
   1243 */
   1244 void BG_EvaluateTrajectoryDelta( const trajectory_t *tr, int atTime, vec3_t result ) {
   1245 	float	deltaTime;
   1246 	float	phase;
   1247 
   1248 	switch( tr->trType ) {
   1249 	case TR_STATIONARY:
   1250 	case TR_INTERPOLATE:
   1251 		VectorClear( result );
   1252 		break;
   1253 	case TR_LINEAR:
   1254 		VectorCopy( tr->trDelta, result );
   1255 		break;
   1256 	case TR_SINE:
   1257 		deltaTime = ( atTime - tr->trTime ) / (float) tr->trDuration;
   1258 		phase = cos( deltaTime * M_PI * 2 );	// derivative of sin = cos
   1259 		phase *= 0.5;
   1260 		VectorScale( tr->trDelta, phase, result );
   1261 		break;
   1262 	case TR_LINEAR_STOP:
   1263 		if ( atTime > tr->trTime + tr->trDuration ) {
   1264 			VectorClear( result );
   1265 			return;
   1266 		}
   1267 		VectorCopy( tr->trDelta, result );
   1268 		break;
   1269 	case TR_GRAVITY:
   1270 		deltaTime = ( atTime - tr->trTime ) * 0.001;	// milliseconds to seconds
   1271 		VectorCopy( tr->trDelta, result );
   1272 		result[2] -= DEFAULT_GRAVITY * deltaTime;		// FIXME: local gravity...
   1273 		break;
   1274 	default:
   1275 		Com_Error( ERR_DROP, "BG_EvaluateTrajectoryDelta: unknown trType: %i", tr->trTime );
   1276 		break;
   1277 	}
   1278 }
   1279 
   1280 char *eventnames[] = {
   1281 	"EV_NONE",
   1282 
   1283 	"EV_FOOTSTEP",
   1284 	"EV_FOOTSTEP_METAL",
   1285 	"EV_FOOTSPLASH",
   1286 	"EV_FOOTWADE",
   1287 	"EV_SWIM",
   1288 
   1289 	"EV_STEP_4",
   1290 	"EV_STEP_8",
   1291 	"EV_STEP_12",
   1292 	"EV_STEP_16",
   1293 
   1294 	"EV_FALL_SHORT",
   1295 	"EV_FALL_MEDIUM",
   1296 	"EV_FALL_FAR",
   1297 
   1298 	"EV_JUMP_PAD",			// boing sound at origin", jump sound on player
   1299 
   1300 	"EV_JUMP",
   1301 	"EV_WATER_TOUCH",	// foot touches
   1302 	"EV_WATER_LEAVE",	// foot leaves
   1303 	"EV_WATER_UNDER",	// head touches
   1304 	"EV_WATER_CLEAR",	// head leaves
   1305 
   1306 	"EV_ITEM_PICKUP",			// normal item pickups are predictable
   1307 	"EV_GLOBAL_ITEM_PICKUP",	// powerup / team sounds are broadcast to everyone
   1308 
   1309 	"EV_NOAMMO",
   1310 	"EV_CHANGE_WEAPON",
   1311 	"EV_FIRE_WEAPON",
   1312 
   1313 	"EV_USE_ITEM0",
   1314 	"EV_USE_ITEM1",
   1315 	"EV_USE_ITEM2",
   1316 	"EV_USE_ITEM3",
   1317 	"EV_USE_ITEM4",
   1318 	"EV_USE_ITEM5",
   1319 	"EV_USE_ITEM6",
   1320 	"EV_USE_ITEM7",
   1321 	"EV_USE_ITEM8",
   1322 	"EV_USE_ITEM9",
   1323 	"EV_USE_ITEM10",
   1324 	"EV_USE_ITEM11",
   1325 	"EV_USE_ITEM12",
   1326 	"EV_USE_ITEM13",
   1327 	"EV_USE_ITEM14",
   1328 	"EV_USE_ITEM15",
   1329 
   1330 	"EV_ITEM_RESPAWN",
   1331 	"EV_ITEM_POP",
   1332 	"EV_PLAYER_TELEPORT_IN",
   1333 	"EV_PLAYER_TELEPORT_OUT",
   1334 
   1335 	"EV_GRENADE_BOUNCE",		// eventParm will be the soundindex
   1336 
   1337 	"EV_GENERAL_SOUND",
   1338 	"EV_GLOBAL_SOUND",		// no attenuation
   1339 	"EV_GLOBAL_TEAM_SOUND",
   1340 
   1341 	"EV_BULLET_HIT_FLESH",
   1342 	"EV_BULLET_HIT_WALL",
   1343 
   1344 	"EV_MISSILE_HIT",
   1345 	"EV_MISSILE_MISS",
   1346 	"EV_MISSILE_MISS_METAL",
   1347 	"EV_RAILTRAIL",
   1348 	"EV_SHOTGUN",
   1349 	"EV_BULLET",				// otherEntity is the shooter
   1350 
   1351 	"EV_PAIN",
   1352 	"EV_DEATH1",
   1353 	"EV_DEATH2",
   1354 	"EV_DEATH3",
   1355 	"EV_OBITUARY",
   1356 
   1357 	"EV_POWERUP_QUAD",
   1358 	"EV_POWERUP_BATTLESUIT",
   1359 	"EV_POWERUP_REGEN",
   1360 
   1361 	"EV_GIB_PLAYER",			// gib a previously living player
   1362 	"EV_SCOREPLUM",			// score plum
   1363 
   1364 //#ifdef MISSIONPACK
   1365 	"EV_PROXIMITY_MINE_STICK",
   1366 	"EV_PROXIMITY_MINE_TRIGGER",
   1367 	"EV_KAMIKAZE",			// kamikaze explodes
   1368 	"EV_OBELISKEXPLODE",		// obelisk explodes
   1369 	"EV_INVUL_IMPACT",		// invulnerability sphere impact
   1370 	"EV_JUICED",				// invulnerability juiced effect
   1371 	"EV_LIGHTNINGBOLT",		// lightning bolt bounced of invulnerability sphere
   1372 //#endif
   1373 
   1374 	"EV_DEBUG_LINE",
   1375 	"EV_STOPLOOPINGSOUND",
   1376 	"EV_TAUNT"
   1377 
   1378 };
   1379 
   1380 /*
   1381 ===============
   1382 BG_AddPredictableEventToPlayerstate
   1383 
   1384 Handles the sequence numbers
   1385 ===============
   1386 */
   1387 
   1388 void	trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize );
   1389 
   1390 void BG_AddPredictableEventToPlayerstate( int newEvent, int eventParm, playerState_t *ps ) {
   1391 
   1392 #ifdef _DEBUG
   1393 	{
   1394 		char buf[256];
   1395 		trap_Cvar_VariableStringBuffer("showevents", buf, sizeof(buf));
   1396 		if ( atof(buf) != 0 ) {
   1397 #ifdef QAGAME
   1398 			Com_Printf(" game event svt %5d -> %5d: num = %20s parm %d\n", ps->pmove_framecount/*ps->commandTime*/, ps->eventSequence, eventnames[newEvent], eventParm);
   1399 #else
   1400 			Com_Printf("Cgame event svt %5d -> %5d: num = %20s parm %d\n", ps->pmove_framecount/*ps->commandTime*/, ps->eventSequence, eventnames[newEvent], eventParm);
   1401 #endif
   1402 		}
   1403 	}
   1404 #endif
   1405 	ps->events[ps->eventSequence & (MAX_PS_EVENTS-1)] = newEvent;
   1406 	ps->eventParms[ps->eventSequence & (MAX_PS_EVENTS-1)] = eventParm;
   1407 	ps->eventSequence++;
   1408 }
   1409 
   1410 /*
   1411 ========================
   1412 BG_TouchJumpPad
   1413 ========================
   1414 */
   1415 void BG_TouchJumpPad( playerState_t *ps, entityState_t *jumppad ) {
   1416 	vec3_t	angles;
   1417 	float p;
   1418 	int effectNum;
   1419 
   1420 	// spectators don't use jump pads
   1421 	if ( ps->pm_type != PM_NORMAL ) {
   1422 		return;
   1423 	}
   1424 
   1425 	// flying characters don't hit bounce pads
   1426 	if ( ps->powerups[PW_FLIGHT] ) {
   1427 		return;
   1428 	}
   1429 
   1430 	// if we didn't hit this same jumppad the previous frame
   1431 	// then don't play the event sound again if we are in a fat trigger
   1432 	if ( ps->jumppad_ent != jumppad->number ) {
   1433 
   1434 		vectoangles( jumppad->origin2, angles);
   1435 		p = fabs( AngleNormalize180( angles[PITCH] ) );
   1436 		if( p < 45 ) {
   1437 			effectNum = 0;
   1438 		} else {
   1439 			effectNum = 1;
   1440 		}
   1441 		BG_AddPredictableEventToPlayerstate( EV_JUMP_PAD, effectNum, ps );
   1442 	}
   1443 	// remember hitting this jumppad this frame
   1444 	ps->jumppad_ent = jumppad->number;
   1445 	ps->jumppad_frame = ps->pmove_framecount;
   1446 	// give the player the velocity from the jumppad
   1447 	VectorCopy( jumppad->origin2, ps->velocity );
   1448 }
   1449 
   1450 /*
   1451 ========================
   1452 BG_PlayerStateToEntityState
   1453 
   1454 This is done after each set of usercmd_t on the server,
   1455 and after local prediction on the client
   1456 ========================
   1457 */
   1458 void BG_PlayerStateToEntityState( playerState_t *ps, entityState_t *s, qboolean snap ) {
   1459 	int		i;
   1460 
   1461 	if ( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPECTATOR ) {
   1462 		s->eType = ET_INVISIBLE;
   1463 	} else if ( ps->stats[STAT_HEALTH] <= GIB_HEALTH ) {
   1464 		s->eType = ET_INVISIBLE;
   1465 	} else {
   1466 		s->eType = ET_PLAYER;
   1467 	}
   1468 
   1469 	s->number = ps->clientNum;
   1470 
   1471 	s->pos.trType = TR_INTERPOLATE;
   1472 	VectorCopy( ps->origin, s->pos.trBase );
   1473 	if ( snap ) {
   1474 		SnapVector( s->pos.trBase );
   1475 	}
   1476 	// set the trDelta for flag direction
   1477 	VectorCopy( ps->velocity, s->pos.trDelta );
   1478 
   1479 	s->apos.trType = TR_INTERPOLATE;
   1480 	VectorCopy( ps->viewangles, s->apos.trBase );
   1481 	if ( snap ) {
   1482 		SnapVector( s->apos.trBase );
   1483 	}
   1484 
   1485 	s->angles2[YAW] = ps->movementDir;
   1486 	s->legsAnim = ps->legsAnim;
   1487 	s->torsoAnim = ps->torsoAnim;
   1488 	s->clientNum = ps->clientNum;		// ET_PLAYER looks here instead of at number
   1489 										// so corpses can also reference the proper config
   1490 	s->eFlags = ps->eFlags;
   1491 	if ( ps->stats[STAT_HEALTH] <= 0 ) {
   1492 		s->eFlags |= EF_DEAD;
   1493 	} else {
   1494 		s->eFlags &= ~EF_DEAD;
   1495 	}
   1496 
   1497 	if ( ps->externalEvent ) {
   1498 		s->event = ps->externalEvent;
   1499 		s->eventParm = ps->externalEventParm;
   1500 	} else if ( ps->entityEventSequence < ps->eventSequence ) {
   1501 		int		seq;
   1502 
   1503 		if ( ps->entityEventSequence < ps->eventSequence - MAX_PS_EVENTS) {
   1504 			ps->entityEventSequence = ps->eventSequence - MAX_PS_EVENTS;
   1505 		}
   1506 		seq = ps->entityEventSequence & (MAX_PS_EVENTS-1);
   1507 		s->event = ps->events[ seq ] | ( ( ps->entityEventSequence & 3 ) << 8 );
   1508 		s->eventParm = ps->eventParms[ seq ];
   1509 		ps->entityEventSequence++;
   1510 	}
   1511 
   1512 	s->weapon = ps->weapon;
   1513 	s->groundEntityNum = ps->groundEntityNum;
   1514 
   1515 	s->powerups = 0;
   1516 	for ( i = 0 ; i < MAX_POWERUPS ; i++ ) {
   1517 		if ( ps->powerups[ i ] ) {
   1518 			s->powerups |= 1 << i;
   1519 		}
   1520 	}
   1521 
   1522 	s->loopSound = ps->loopSound;
   1523 	s->generic1 = ps->generic1;
   1524 }
   1525 
   1526 /*
   1527 ========================
   1528 BG_PlayerStateToEntityStateExtraPolate
   1529 
   1530 This is done after each set of usercmd_t on the server,
   1531 and after local prediction on the client
   1532 ========================
   1533 */
   1534 void BG_PlayerStateToEntityStateExtraPolate( playerState_t *ps, entityState_t *s, int time, qboolean snap ) {
   1535 	int		i;
   1536 
   1537 	if ( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPECTATOR ) {
   1538 		s->eType = ET_INVISIBLE;
   1539 	} else if ( ps->stats[STAT_HEALTH] <= GIB_HEALTH ) {
   1540 		s->eType = ET_INVISIBLE;
   1541 	} else {
   1542 		s->eType = ET_PLAYER;
   1543 	}
   1544 
   1545 	s->number = ps->clientNum;
   1546 
   1547 	s->pos.trType = TR_LINEAR_STOP;
   1548 	VectorCopy( ps->origin, s->pos.trBase );
   1549 	if ( snap ) {
   1550 		SnapVector( s->pos.trBase );
   1551 	}
   1552 	// set the trDelta for flag direction and linear prediction
   1553 	VectorCopy( ps->velocity, s->pos.trDelta );
   1554 	// set the time for linear prediction
   1555 	s->pos.trTime = time;
   1556 	// set maximum extra polation time
   1557 	s->pos.trDuration = 50; // 1000 / sv_fps (default = 20)
   1558 
   1559 	s->apos.trType = TR_INTERPOLATE;
   1560 	VectorCopy( ps->viewangles, s->apos.trBase );
   1561 	if ( snap ) {
   1562 		SnapVector( s->apos.trBase );
   1563 	}
   1564 
   1565 	s->angles2[YAW] = ps->movementDir;
   1566 	s->legsAnim = ps->legsAnim;
   1567 	s->torsoAnim = ps->torsoAnim;
   1568 	s->clientNum = ps->clientNum;		// ET_PLAYER looks here instead of at number
   1569 										// so corpses can also reference the proper config
   1570 	s->eFlags = ps->eFlags;
   1571 	if ( ps->stats[STAT_HEALTH] <= 0 ) {
   1572 		s->eFlags |= EF_DEAD;
   1573 	} else {
   1574 		s->eFlags &= ~EF_DEAD;
   1575 	}
   1576 
   1577 	if ( ps->externalEvent ) {
   1578 		s->event = ps->externalEvent;
   1579 		s->eventParm = ps->externalEventParm;
   1580 	} else if ( ps->entityEventSequence < ps->eventSequence ) {
   1581 		int		seq;
   1582 
   1583 		if ( ps->entityEventSequence < ps->eventSequence - MAX_PS_EVENTS) {
   1584 			ps->entityEventSequence = ps->eventSequence - MAX_PS_EVENTS;
   1585 		}
   1586 		seq = ps->entityEventSequence & (MAX_PS_EVENTS-1);
   1587 		s->event = ps->events[ seq ] | ( ( ps->entityEventSequence & 3 ) << 8 );
   1588 		s->eventParm = ps->eventParms[ seq ];
   1589 		ps->entityEventSequence++;
   1590 	}
   1591 
   1592 	s->weapon = ps->weapon;
   1593 	s->groundEntityNum = ps->groundEntityNum;
   1594 
   1595 	s->powerups = 0;
   1596 	for ( i = 0 ; i < MAX_POWERUPS ; i++ ) {
   1597 		if ( ps->powerups[ i ] ) {
   1598 			s->powerups |= 1 << i;
   1599 		}
   1600 	}
   1601 
   1602 	s->loopSound = ps->loopSound;
   1603 	s->generic1 = ps->generic1;
   1604 }