|
|
1.1 ! root 1: // g_sphere.c ! 2: // pmack ! 3: // april 1998 ! 4: ! 5: // defender - actively finds and shoots at enemies ! 6: // hunter - waits until < 25% health and vore ball tracks person who hurt you ! 7: // vengeance - kills person who killed you. ! 8: ! 9: #include "g_local.h" ! 10: ! 11: #define DEFENDER_LIFESPAN 30 ! 12: #define HUNTER_LIFESPAN 30 ! 13: #define VENGEANCE_LIFESPAN 30 ! 14: #define MINIMUM_FLY_TIME 15 ! 15: //#define MINIMUM_FLY_TIME 30 ! 16: ! 17: // FIXME - do we need to be calling ED_NewString at all? ! 18: extern char *ED_NewString (char *string); ! 19: void LookAtKiller (edict_t *self, edict_t *inflictor, edict_t *attacker); ! 20: ! 21: ! 22: void defender_think (edict_t *self); ! 23: void hunter_think (edict_t *self); ! 24: void vengeance_think (edict_t *self); ! 25: void vengeance_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf); ! 26: void hunter_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf); ! 27: ! 28: // ************************* ! 29: // General Sphere Code ! 30: // ************************* ! 31: ! 32: // ================= ! 33: // ================= ! 34: void sphere_think_explode (edict_t *self) ! 35: { ! 36: if(self->owner && self->owner->client) ! 37: { ! 38: self->owner->client->owned_sphere = NULL; ! 39: } ! 40: BecomeExplosion1 (self); ! 41: } ! 42: ! 43: // ================= ! 44: // sphere_explode ! 45: // ================= ! 46: void sphere_explode (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) ! 47: { ! 48: // if(self->owner && self->owner->client) ! 49: // gi.cprintf(self->owner, PRINT_HIGH, "Sphere timed out\n"); ! 50: // gi.dprintf("player died, blowing up\n"); ! 51: sphere_think_explode (self); ! 52: } ! 53: ! 54: // ================= ! 55: // sphere_if_idle_die - if the sphere is not currently attacking, blow up. ! 56: // ================= ! 57: void sphere_if_idle_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) ! 58: { ! 59: if(!self->enemy) ! 60: { ! 61: // gi.dprintf("player died, blowing up\n"); ! 62: sphere_think_explode(self); ! 63: } ! 64: } ! 65: ! 66: // ************************* ! 67: // Sphere Movement ! 68: // ************************* ! 69: ! 70: // ================= ! 71: // ================= ! 72: void sphere_fly (edict_t *self) ! 73: { ! 74: vec3_t dest; ! 75: vec3_t dir; ! 76: ! 77: if(level.time >= self->wait) ! 78: { ! 79: // gi.dprintf("fly: timed out\n"); ! 80: sphere_think_explode(self); ! 81: return; ! 82: } ! 83: ! 84: VectorCopy (self->owner->s.origin, dest); ! 85: dest[2] = self->owner->absmax[2] + 4; ! 86: ! 87: if(level.time == (float)(int)level.time) ! 88: { ! 89: if(!visible(self, self->owner)) ! 90: { ! 91: VectorCopy(dest, self->s.origin); ! 92: gi.linkentity(self); ! 93: return; ! 94: } ! 95: } ! 96: ! 97: VectorSubtract (dest, self->s.origin, dir); ! 98: VectorScale (dir, 5, self->velocity); ! 99: } ! 100: ! 101: // ================= ! 102: // ================= ! 103: void sphere_chase (edict_t *self, int stupidChase) ! 104: { ! 105: vec3_t dest; ! 106: vec3_t dir; ! 107: float dist; ! 108: ! 109: if(level.time >= self->wait || (self->enemy && self->enemy->health < 1)) ! 110: { ! 111: sphere_think_explode(self); ! 112: return; ! 113: } ! 114: ! 115: VectorCopy (self->enemy->s.origin, dest); ! 116: if(self->enemy->client) ! 117: dest[2] += self->enemy->viewheight; ! 118: ! 119: if(visible(self, self->enemy) || stupidChase) ! 120: { ! 121: VectorSubtract (dest, self->s.origin, dir); ! 122: VectorNormalize (dir); ! 123: vectoangles2(dir, self->s.angles); ! 124: VectorScale (dir, 500, self->velocity); ! 125: VectorCopy(dest, self->monsterinfo.saved_goal); ! 126: } ! 127: else if (VectorCompare (self->monsterinfo.saved_goal, vec3_origin)) ! 128: { ! 129: VectorClear (self->velocity); ! 130: } ! 131: else ! 132: { ! 133: VectorSubtract(self->monsterinfo.saved_goal, self->s.origin, dir); ! 134: dist = VectorNormalize(dir); ! 135: vectoangles2(dir, self->s.angles); ! 136: if(dist) ! 137: { ! 138: if(dist > 500) ! 139: VectorScale(dir, 500, self->velocity); ! 140: else ! 141: VectorScale(dir, dist, self->velocity); ! 142: } ! 143: else ! 144: VectorClear(self->velocity); ! 145: } ! 146: } ! 147: ! 148: // ************************* ! 149: // Attack related stuff ! 150: // ************************* ! 151: ! 152: // ================= ! 153: // ================= ! 154: void sphere_fire (edict_t *self, edict_t *enemy) ! 155: { ! 156: vec3_t dest; ! 157: vec3_t dir; ! 158: ! 159: if(level.time >= self->wait || !enemy) ! 160: { ! 161: sphere_think_explode(self); ! 162: return; ! 163: } ! 164: ! 165: VectorCopy (enemy->s.origin, dest); ! 166: self->s.effects |= EF_ROCKET; ! 167: ! 168: VectorSubtract (dest, self->s.origin, dir); ! 169: VectorNormalize (dir); ! 170: vectoangles2 ( dir, self->s.angles ); ! 171: VectorScale (dir, 1000, self->velocity); ! 172: ! 173: self->touch = vengeance_touch; ! 174: self->think = sphere_think_explode; ! 175: self->nextthink = self->wait; ! 176: } ! 177: ! 178: // ================= ! 179: // ================= ! 180: void sphere_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf, int mod) ! 181: { ! 182: if(self->spawnflags & SPHERE_DOPPLEGANGER) ! 183: { ! 184: if (other == self->teammaster) ! 185: return; ! 186: ! 187: self->takedamage = DAMAGE_NO; ! 188: self->owner = self->teammaster; ! 189: self->teammaster = NULL; ! 190: } ! 191: else ! 192: { ! 193: if (other == self->owner) ! 194: return; ! 195: // PMM - don't blow up on bodies ! 196: if (!strcmp(other->classname, "bodyque")) ! 197: return; ! 198: } ! 199: ! 200: if (surf && (surf->flags & SURF_SKY)) ! 201: { ! 202: G_FreeEdict (self); ! 203: return; ! 204: } ! 205: ! 206: if (other->takedamage) ! 207: { ! 208: T_Damage (other, self, self->owner, self->velocity, self->s.origin, plane->normal, ! 209: 10000, 1, DAMAGE_DESTROY_ARMOR, mod); ! 210: } ! 211: else ! 212: { ! 213: T_RadiusDamage (self, self->owner, 512, self->owner, 256, mod); ! 214: } ! 215: ! 216: sphere_think_explode (self); ! 217: } ! 218: ! 219: // ================= ! 220: // ================= ! 221: void vengeance_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) ! 222: { ! 223: if(self->spawnflags & SPHERE_DOPPLEGANGER) ! 224: sphere_touch (self, other, plane, surf, MOD_DOPPLE_VENGEANCE); ! 225: else ! 226: sphere_touch (self, other, plane, surf, MOD_VENGEANCE_SPHERE); ! 227: } ! 228: ! 229: // ================= ! 230: // ================= ! 231: void hunter_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) ! 232: { ! 233: edict_t *owner; ! 234: ! 235: // don't blow up if you hit the world.... sheesh. ! 236: if(other==world) ! 237: return; ! 238: ! 239: if(self->owner) ! 240: { ! 241: // if owner is flying with us, make sure they stop too. ! 242: owner=self->owner; ! 243: if(owner->flags & FL_SAM_RAIMI) ! 244: { ! 245: VectorClear(owner->velocity); ! 246: owner->movetype = MOVETYPE_NONE; ! 247: gi.linkentity(owner); ! 248: } ! 249: } ! 250: ! 251: if(self->spawnflags & SPHERE_DOPPLEGANGER) ! 252: sphere_touch (self, other, plane, surf, MOD_DOPPLE_HUNTER); ! 253: else ! 254: sphere_touch (self, other, plane, surf, MOD_HUNTER_SPHERE); ! 255: } ! 256: ! 257: // ================= ! 258: // ================= ! 259: void defender_shoot (edict_t *self, edict_t *enemy) ! 260: { ! 261: vec3_t dir; ! 262: vec3_t start; ! 263: ! 264: if(!(enemy->inuse) || enemy->health <= 0) ! 265: return; ! 266: ! 267: if(enemy == self->owner) ! 268: return; ! 269: ! 270: VectorSubtract (enemy->s.origin, self->s.origin, dir); ! 271: VectorNormalize (dir); ! 272: ! 273: if(self->monsterinfo.attack_finished > level.time) ! 274: return; ! 275: ! 276: if(!visible(self, self->enemy)) ! 277: return; ! 278: ! 279: VectorCopy(self->s.origin, start); ! 280: start[2] += 2; ! 281: fire_blaster2 (self->owner, start, dir, 10, 1000, EF_BLASTER, 0); ! 282: ! 283: self->monsterinfo.attack_finished = level.time + 0.4; ! 284: } ! 285: ! 286: // ************************* ! 287: // Activation Related Stuff ! 288: // ************************* ! 289: ! 290: // ================= ! 291: // ================= ! 292: void body_gib (edict_t *self) ! 293: { ! 294: int n; ! 295: ! 296: gi.sound (self, CHAN_BODY, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0); ! 297: for (n= 0; n < 4; n++) ! 298: ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", 50, GIB_ORGANIC); ! 299: ThrowGib (self, "models/objects/gibs/skull/tris.md2", 50, GIB_ORGANIC); ! 300: } ! 301: ! 302: // ================= ! 303: // ================= ! 304: void hunter_pain (edict_t *self, edict_t *other, float kick, int damage) ! 305: { ! 306: edict_t *owner; ! 307: float dist; ! 308: vec3_t dir; ! 309: ! 310: if(self->enemy) ! 311: return; ! 312: ! 313: owner = self->owner; ! 314: ! 315: if(!(self->spawnflags & SPHERE_DOPPLEGANGER)) ! 316: { ! 317: if(owner && (owner->health > 0)) ! 318: return; ! 319: ! 320: //PMM ! 321: if(other == owner) ! 322: { ! 323: // if ((g_showlogic) && (g_showlogic->value)) ! 324: // gi.dprintf ("hunter: won't get mad at my owner!\n"); ! 325: return; ! 326: } ! 327: //pmm ! 328: } ! 329: else ! 330: { ! 331: // if fired by a doppleganger, set it to 10 second timeout ! 332: self->wait = level.time + MINIMUM_FLY_TIME; ! 333: } ! 334: ! 335: if((self->wait - level.time) < MINIMUM_FLY_TIME) ! 336: self->wait = level.time + MINIMUM_FLY_TIME; ! 337: self->s.effects |= EF_BLASTER | EF_TRACKER; ! 338: self->touch = hunter_touch; ! 339: self->enemy = other; ! 340: ! 341: if(g_showlogic && g_showlogic->value) ! 342: gi.dprintf("hunter_pain: mad at %s\n", other->classname); ! 343: ! 344: // if we're not owned by a player, no sam raimi ! 345: // if we're spawned by a doppleganger, no sam raimi ! 346: if((self->spawnflags & SPHERE_DOPPLEGANGER) || !(owner && owner->client)) ! 347: return; ! 348: ! 349: // sam raimi cam is disabled if FORCE_RESPAWN is set. ! 350: // sam raimi cam is also disabled if huntercam->value is 0. ! 351: if(!((int)dmflags->value & DF_FORCE_RESPAWN) && (huntercam && (huntercam->value))) ! 352: { ! 353: VectorSubtract(other->s.origin, self->s.origin, dir); ! 354: dist=VectorLength(dir); ! 355: ! 356: if(owner && (dist >= 192)) ! 357: { ! 358: // detach owner from body and send him flying ! 359: owner->movetype = MOVETYPE_FLYMISSILE; ! 360: ! 361: // gib like we just died, even though we didn't, really. ! 362: body_gib(owner); ! 363: ! 364: // move the sphere to the owner's current viewpoint. ! 365: // we know it's a valid spot (or will be momentarily) ! 366: VectorCopy(owner->s.origin, self->s.origin); ! 367: self->s.origin[2] += owner->viewheight; ! 368: ! 369: // move the player's origin to the sphere's new origin ! 370: VectorCopy(self->s.origin, owner->s.origin); ! 371: VectorCopy(self->s.angles, owner->s.angles); ! 372: VectorCopy(self->s.angles, owner->client->v_angle); ! 373: VectorClear(owner->mins); ! 374: VectorClear(owner->maxs); ! 375: VectorSet(owner->mins, -5, -5, -5); ! 376: VectorSet(owner->maxs, 5, 5, 5); ! 377: owner->client->ps.fov = 140; ! 378: owner->s.modelindex = 0; ! 379: owner->s.modelindex2 = 0; ! 380: owner->viewheight = 8; ! 381: owner->solid = SOLID_NOT; ! 382: owner->flags |= FL_SAM_RAIMI; ! 383: gi.linkentity(owner); ! 384: ! 385: // PMM - set bounding box so we don't clip out of world ! 386: // VectorSet(self->mins, -5, -5, -5); ! 387: // VectorSet(self->maxs, 5, 5, 5); ! 388: self->solid = SOLID_BBOX; ! 389: gi.linkentity (self); ! 390: } ! 391: // else ! 392: // gi.dprintf("too close for sam raimi cam\n"); ! 393: } ! 394: } ! 395: ! 396: // ================= ! 397: // ================= ! 398: void defender_pain (edict_t *self, edict_t *other, float kick, int damage) ! 399: { ! 400: //PMM ! 401: if(other == self->owner) ! 402: { ! 403: // if ((g_showlogic) && (g_showlogic->value)) ! 404: // gi.dprintf ("defender: won't get mad at my owner!\n"); ! 405: return; ! 406: } ! 407: //pmm ! 408: self->enemy = other; ! 409: } ! 410: ! 411: // ================= ! 412: // ================= ! 413: void vengeance_pain (edict_t *self, edict_t *other, float kick, int damage) ! 414: { ! 415: if(self->enemy) ! 416: return; ! 417: ! 418: if(!(self->spawnflags & SPHERE_DOPPLEGANGER)) ! 419: { ! 420: if(self->owner->health >= 25) ! 421: return; ! 422: ! 423: //PMM ! 424: if(other == self->owner) ! 425: { ! 426: // if ((g_showlogic) && (g_showlogic->value)) ! 427: // gi.dprintf ("vengeance: won't get mad at my owner!\n"); ! 428: return; ! 429: } ! 430: //pmm ! 431: } ! 432: else ! 433: { ! 434: self->wait = level.time + MINIMUM_FLY_TIME; ! 435: } ! 436: ! 437: if((self->wait - level.time) < MINIMUM_FLY_TIME) ! 438: self->wait = level.time + MINIMUM_FLY_TIME; ! 439: self->s.effects |= EF_ROCKET; ! 440: self->touch = vengeance_touch; ! 441: self->enemy = other; ! 442: } ! 443: ! 444: // ************************* ! 445: // Think Functions ! 446: // ************************* ! 447: ! 448: // =================== ! 449: // =================== ! 450: void defender_think (edict_t *self) ! 451: { ! 452: if(!self->owner) ! 453: { ! 454: // gi.dprintf("think: no owner\n"); ! 455: G_FreeEdict(self); ! 456: return; ! 457: } ! 458: ! 459: if(self->owner->health <=0) ! 460: { ! 461: sphere_think_explode(self); ! 462: return; ! 463: } ! 464: ! 465: if(level.time - self->timestamp > 1) ! 466: { ! 467: gi.sound (self, CHAN_VOICE, gi.soundindex ("powerup/dsphere.wav"), 0.6, ATTN_NORM, 0); ! 468: self->timestamp = level.time; ! 469: } ! 470: ! 471: self->s.frame++; ! 472: if(self->s.frame>19) ! 473: self->s.frame = 0; ! 474: ! 475: if(self->enemy) ! 476: { ! 477: if(self->enemy->health > 0) ! 478: { ! 479: // gi.dprintf( "shooting at %s\n", self->enemy->classname); ! 480: defender_shoot (self, self->enemy); ! 481: } ! 482: else ! 483: self->enemy = NULL; ! 484: } ! 485: // else ! 486: // { ! 487: // self->ideal_yaw+=3; ! 488: // M_ChangeYaw (self); ! 489: // } ! 490: ! 491: sphere_fly (self); ! 492: ! 493: if(self->inuse) ! 494: self->nextthink = level.time + 0.1; ! 495: } ! 496: ! 497: // ================= ! 498: // ================= ! 499: void hunter_think (edict_t *self) ! 500: { ! 501: edict_t *owner; ! 502: vec3_t dir, ang; ! 503: ! 504: ! 505: owner = self->owner; ! 506: if(!owner && !(self->spawnflags & SPHERE_DOPPLEGANGER)) ! 507: { ! 508: // gi.dprintf("think: no owner\n"); ! 509: G_FreeEdict(self); ! 510: return; ! 511: } ! 512: ! 513: if(owner) ! 514: self->ideal_yaw = owner->s.angles[YAW]; ! 515: else if(self->enemy) // fired by doppleganger ! 516: { ! 517: VectorSubtract(self->enemy->s.origin, self->s.origin, dir); ! 518: vectoangles2(dir, ang); ! 519: self->ideal_yaw = ang[YAW]; ! 520: } ! 521: ! 522: M_ChangeYaw(self); ! 523: ! 524: if(level.time - self->timestamp > 1) ! 525: { ! 526: gi.sound (self, CHAN_VOICE, gi.soundindex ("powerup/hsphere.wav"), 0.5, ATTN_NORM, 0); ! 527: self->timestamp = level.time; ! 528: } ! 529: ! 530: if(self->enemy) ! 531: { ! 532: sphere_chase (self, 0); ! 533: ! 534: // deal with sam raimi cam ! 535: if(owner && (owner->flags & FL_SAM_RAIMI)) ! 536: { ! 537: if(self->inuse) ! 538: { ! 539: owner->movetype = MOVETYPE_FLYMISSILE; ! 540: // VectorCopy(self->s.angles, owner->s.angles); ! 541: // VectorCopy(self->s.angles, owner->client->v_angle); ! 542: LookAtKiller (owner, self, self->enemy); ! 543: // owner->viewheight = 22; ! 544: ! 545: // owner->client->v_angle[YAW]+=5; ! 546: // owner is flying with us, move him too ! 547: owner->movetype = MOVETYPE_FLYMISSILE; ! 548: owner->viewheight = self->s.origin[2] - owner->s.origin[2]; ! 549: // VectorCopy(self->s.angles, owner->s.angles); ! 550: // VectorCopy(self->s.angles, owner->client->v_angle); ! 551: VectorCopy(self->s.origin, owner->s.origin); ! 552: VectorCopy(self->velocity, owner->velocity); ! 553: VectorClear(owner->mins); ! 554: VectorClear(owner->maxs); ! 555: gi.linkentity(owner); ! 556: } ! 557: else // sphere timed out ! 558: { ! 559: VectorClear(owner->velocity); ! 560: owner->movetype = MOVETYPE_NONE; ! 561: gi.linkentity(owner); ! 562: } ! 563: } ! 564: } ! 565: else ! 566: { ! 567: // self->ideal_yaw+=3; ! 568: // M_ChangeYaw (self); ! 569: sphere_fly (self); ! 570: } ! 571: ! 572: if(self->inuse) ! 573: self->nextthink = level.time + 0.1; ! 574: } ! 575: ! 576: // ================= ! 577: // ================= ! 578: void vengeance_think (edict_t *self) ! 579: { ! 580: if(!(self->owner) && !(self->spawnflags & SPHERE_DOPPLEGANGER)) ! 581: { ! 582: // gi.dprintf("think: no owner\n"); ! 583: G_FreeEdict(self); ! 584: return; ! 585: } ! 586: ! 587: if(level.time - self->timestamp > 1) ! 588: { ! 589: gi.sound (self, CHAN_VOICE, gi.soundindex ("powerup/vsphere.wav"), 0.5, ATTN_NORM, 0); ! 590: self->timestamp = level.time; ! 591: } ! 592: ! 593: if(self->enemy) ! 594: { ! 595: // sphere_fire (self, self->owner->enemy); ! 596: sphere_chase (self, 1); ! 597: } ! 598: else ! 599: sphere_fly (self); ! 600: ! 601: if(self->inuse) ! 602: self->nextthink = level.time + 0.1; ! 603: } ! 604: ! 605: // ************************* ! 606: // Spawning / Creation ! 607: // ************************* ! 608: ! 609: // monsterinfo_t ! 610: // ================= ! 611: // ================= ! 612: edict_t *Sphere_Spawn (edict_t *owner, int spawnflags) ! 613: { ! 614: edict_t *sphere; ! 615: ! 616: sphere = G_Spawn(); ! 617: VectorCopy(owner->s.origin, sphere->s.origin); ! 618: sphere->s.origin[2] = owner->absmax[2]; ! 619: sphere->s.angles[YAW] = owner->s.angles[YAW]; ! 620: sphere->solid = SOLID_BBOX; ! 621: sphere->clipmask = MASK_SHOT; ! 622: sphere->s.renderfx = RF_FULLBRIGHT | RF_IR_VISIBLE; ! 623: sphere->movetype = MOVETYPE_FLYMISSILE; ! 624: ! 625: if(spawnflags & SPHERE_DOPPLEGANGER) ! 626: sphere->teammaster = owner->teammaster; ! 627: else ! 628: sphere->owner = owner; ! 629: ! 630: sphere->classname = "sphere"; ! 631: sphere->yaw_speed = 40; ! 632: sphere->monsterinfo.attack_finished = 0; ! 633: sphere->spawnflags = spawnflags; // need this for the HUD to recognize sphere ! 634: //PMM ! 635: sphere->takedamage = DAMAGE_NO; ! 636: ! 637: switch(spawnflags & SPHERE_TYPE) ! 638: { ! 639: case SPHERE_DEFENDER: ! 640: sphere->s.modelindex = gi.modelindex("models/items/defender/tris.md2"); ! 641: sphere->s.modelindex2 = gi.modelindex("models/items/shell/tris.md2") | 0x80; ! 642: sphere->pain = defender_pain; ! 643: sphere->wait = level.time + DEFENDER_LIFESPAN; ! 644: sphere->die = sphere_explode; ! 645: sphere->think = defender_think; ! 646: break; ! 647: case SPHERE_HUNTER: ! 648: sphere->s.modelindex = gi.modelindex("models/items/hunter/tris.md2"); ! 649: sphere->wait = level.time + HUNTER_LIFESPAN; ! 650: sphere->pain = hunter_pain; ! 651: sphere->die = sphere_if_idle_die; ! 652: sphere->think = hunter_think; ! 653: break; ! 654: case SPHERE_VENGEANCE: ! 655: sphere->s.modelindex = gi.modelindex("models/items/vengnce/tris.md2"); ! 656: sphere->wait = level.time + VENGEANCE_LIFESPAN; ! 657: sphere->pain = vengeance_pain; ! 658: sphere->die = sphere_if_idle_die; ! 659: sphere->think = vengeance_think; ! 660: VectorSet (sphere->avelocity, 30, 30, 0); ! 661: break; ! 662: default: ! 663: gi.dprintf("Tried to create an invalid sphere\n"); ! 664: G_FreeEdict(sphere); ! 665: return NULL; ! 666: } ! 667: ! 668: sphere->nextthink = level.time + 0.1; ! 669: ! 670: gi.linkentity (sphere); ! 671: ! 672: return sphere; ! 673: } ! 674: ! 675: // ================= ! 676: // Own_Sphere - attach the sphere to the client so we can ! 677: // directly access it later ! 678: // ================= ! 679: void Own_Sphere (edict_t *self, edict_t *sphere) ! 680: { ! 681: if(!sphere) ! 682: return; ! 683: ! 684: // ownership only for players ! 685: if(self->client) ! 686: { ! 687: // if they don't have one ! 688: if(!(self->client->owned_sphere)) ! 689: { ! 690: self->client->owned_sphere = sphere; ! 691: } ! 692: // they already have one, take care of the old one ! 693: else ! 694: { ! 695: if(self->client->owned_sphere->inuse) ! 696: { ! 697: G_FreeEdict(self->client->owned_sphere); ! 698: self->client->owned_sphere = sphere; ! 699: } ! 700: else ! 701: { ! 702: self->client->owned_sphere = sphere; ! 703: } ! 704: } ! 705: } ! 706: } ! 707: ! 708: // ================= ! 709: // ================= ! 710: void Defender_Launch (edict_t *self) ! 711: { ! 712: edict_t *sphere; ! 713: ! 714: sphere = Sphere_Spawn (self, SPHERE_DEFENDER); ! 715: Own_Sphere (self, sphere); ! 716: } ! 717: ! 718: // ================= ! 719: // ================= ! 720: void Hunter_Launch (edict_t *self) ! 721: { ! 722: edict_t *sphere; ! 723: ! 724: sphere = Sphere_Spawn (self, SPHERE_HUNTER); ! 725: Own_Sphere (self, sphere); ! 726: } ! 727: ! 728: // ================= ! 729: // ================= ! 730: void Vengeance_Launch (edict_t *self) ! 731: { ! 732: edict_t *sphere; ! 733: ! 734: sphere = Sphere_Spawn (self, SPHERE_VENGEANCE); ! 735: Own_Sphere (self, sphere); ! 736: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.