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 }