|
|
1.1 ! root 1: ! 2: //************************************************************************** ! 3: //** ! 4: //** a_action.c : Heretic 2 : Raven Software, Corp. ! 5: //** ! 6: //** $RCSfile: a_action.c,v $ ! 7: //** $Revision: 1.86 $ ! 8: //** $Date: 96/03/22 13:15:33 $ ! 9: //** $Author: bgokey $ ! 10: //** ! 11: //************************************************************************** ! 12: ! 13: // HEADER FILES ------------------------------------------------------------ ! 14: ! 15: #include "h2def.h" ! 16: #include "p_local.h" ! 17: #include "soundst.h" ! 18: ! 19: // MACROS ------------------------------------------------------------------ ! 20: ! 21: // TYPES ------------------------------------------------------------------- ! 22: ! 23: // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- ! 24: ! 25: // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- ! 26: ! 27: // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- ! 28: ! 29: // EXTERNAL DATA DECLARATIONS ---------------------------------------------- ! 30: extern fixed_t FloatBobOffsets[64]; ! 31: ! 32: // PUBLIC DATA DEFINITIONS ------------------------------------------------- ! 33: int orbitTableX[256]= ! 34: { ! 35: 983025, 982725, 981825, 980340, 978255, 975600, 972330, 968490, ! 36: 964065, 959070, 953475, 947325, 940590, 933300, 925440, 917025, ! 37: 908055, 898545, 888495, 877905, 866775, 855135, 842985, 830310, ! 38: 817155, 803490, 789360, 774735, 759660, 744120, 728130, 711690, ! 39: 694845, 677565, 659880, 641805, 623340, 604500, 585285, 565725, ! 40: 545820, 525600, 505050, 484200, 463065, 441645, 419955, 398010, ! 41: 375840, 353430, 330810, 307995, 285000, 261825, 238485, 215010, ! 42: 191400, 167685, 143865, 119955, 95970, 71940, 47850, 23745, ! 43: -375, -24495, -48600, -72690, -96720, -120705, -144600, -168420, ! 44: -192150, -215745, -239220, -262545, -285720, -308715, -331530, -354135, ! 45: -376530, -398700, -420630, -442320, -463725, -484860, -505695, -526230, ! 46: -546450, -566340, -585885, -605085, -623925, -642375, -660435, -678105, ! 47: -695370, -712215, -728625, -744600, -760125, -775200, -789795, -803925, ! 48: -817575, -830715, -843375, -855510, -867135, -878235, -888810, -898845, ! 49: -908340, -917295, -925695, -933540, -940815, -947520, -953670, -959235, ! 50: -964215, -968625, -972450, -975690, -978330, -980400, -981870, -982740, ! 51: -983025, -982725, -981825, -980340, -978255, -975600, -972330, -968490, ! 52: -964065, -959070, -953475, -947325, -940590, -933300, -925440, -917025, ! 53: -908055, -898545, -888495, -877905, -866775, -855135, -842985, -830310, ! 54: -817155, -803490, -789360, -774735, -759660, -744120, -728130, -711690, ! 55: -694845, -677565, -659880, -641805, -623340, -604485, -585285, -565725, ! 56: -545820, -525600, -505050, -484200, -463065, -441645, -419955, -398010, ! 57: -375840, -353430, -330810, -307995, -285000, -261825, -238485, -215010, ! 58: -191400, -167685, -143865, -119955, -95970, -71940, -47850, -23745, ! 59: 375, 24495, 48600, 72690, 96720, 120705, 144600, 168420, ! 60: 192150, 215745, 239220, 262545, 285720, 308715, 331530, 354135, ! 61: 376530, 398700, 420630, 442320, 463725, 484860, 505695, 526230, ! 62: 546450, 566340, 585885, 605085, 623925, 642375, 660435, 678105, ! 63: 695370, 712215, 728625, 744600, 760125, 775200, 789795, 803925, ! 64: 817575, 830715, 843375, 855510, 867135, 878235, 888810, 898845, ! 65: 908340, 917295, 925695, 933540, 940815, 947520, 953670, 959235, ! 66: 964215, 968625, 972450, 975690, 978330, 980400, 981870, 982740 ! 67: }; ! 68: ! 69: int orbitTableY[256]= ! 70: { ! 71: 375, 24495, 48600, 72690, 96720, 120705, 144600, 168420, ! 72: 192150, 215745, 239220, 262545, 285720, 308715, 331530, 354135, ! 73: 376530, 398700, 420630, 442320, 463725, 484860, 505695, 526230, ! 74: 546450, 566340, 585885, 605085, 623925, 642375, 660435, 678105, ! 75: 695370, 712215, 728625, 744600, 760125, 775200, 789795, 803925, ! 76: 817575, 830715, 843375, 855510, 867135, 878235, 888810, 898845, ! 77: 908340, 917295, 925695, 933540, 940815, 947520, 953670, 959235, ! 78: 964215, 968625, 972450, 975690, 978330, 980400, 981870, 982740, ! 79: 983025, 982725, 981825, 980340, 978255, 975600, 972330, 968490, ! 80: 964065, 959070, 953475, 947325, 940590, 933300, 925440, 917025, ! 81: 908055, 898545, 888495, 877905, 866775, 855135, 842985, 830310, ! 82: 817155, 803490, 789360, 774735, 759660, 744120, 728130, 711690, ! 83: 694845, 677565, 659880, 641805, 623340, 604500, 585285, 565725, ! 84: 545820, 525600, 505050, 484200, 463065, 441645, 419955, 398010, ! 85: 375840, 353430, 330810, 307995, 285000, 261825, 238485, 215010, ! 86: 191400, 167685, 143865, 119955, 95970, 71940, 47850, 23745, ! 87: -375, -24495, -48600, -72690, -96720, -120705, -144600, -168420, ! 88: -192150, -215745, -239220, -262545, -285720, -308715, -331530, -354135, ! 89: -376530, -398700, -420630, -442320, -463725, -484860, -505695, -526230, ! 90: -546450, -566340, -585885, -605085, -623925, -642375, -660435, -678105, ! 91: -695370, -712215, -728625, -744600, -760125, -775200, -789795, -803925, ! 92: -817575, -830715, -843375, -855510, -867135, -878235, -888810, -898845, ! 93: -908340, -917295, -925695, -933540, -940815, -947520, -953670, -959235, ! 94: -964215, -968625, -972450, -975690, -978330, -980400, -981870, -982740, ! 95: -983025, -982725, -981825, -980340, -978255, -975600, -972330, -968490, ! 96: -964065, -959070, -953475, -947325, -940590, -933300, -925440, -917025, ! 97: -908055, -898545, -888495, -877905, -866775, -855135, -842985, -830310, ! 98: -817155, -803490, -789360, -774735, -759660, -744120, -728130, -711690, ! 99: -694845, -677565, -659880, -641805, -623340, -604485, -585285, -565725, ! 100: -545820, -525600, -505050, -484200, -463065, -441645, -419955, -398010, ! 101: -375840, -353430, -330810, -307995, -285000, -261825, -238485, -215010, ! 102: -191400, -167685, -143865, -119955, -95970, -71940, -47850, -23745 ! 103: }; ! 104: ! 105: // PRIVATE DATA DEFINITIONS ------------------------------------------------ ! 106: ! 107: // CODE -------------------------------------------------------------------- ! 108: ! 109: //-------------------------------------------------------------------------- ! 110: // ! 111: // Environmental Action routines ! 112: // ! 113: //-------------------------------------------------------------------------- ! 114: ! 115: //========================================================================== ! 116: // ! 117: // A_DripBlood ! 118: // ! 119: //========================================================================== ! 120: ! 121: /* ! 122: void A_DripBlood(mobj_t *actor) ! 123: { ! 124: mobj_t *mo; ! 125: ! 126: mo = P_SpawnMobj(actor->x+((P_Random()-P_Random())<<11), ! 127: actor->y+((P_Random()-P_Random())<<11), actor->z, MT_BLOOD); ! 128: mo->momx = (P_Random()-P_Random())<<10; ! 129: mo->momy = (P_Random()-P_Random())<<10; ! 130: mo->flags2 |= MF2_LOGRAV; ! 131: } ! 132: */ ! 133: ! 134: //============================================================================ ! 135: // ! 136: // A_PotteryExplode ! 137: // ! 138: //============================================================================ ! 139: ! 140: void A_PotteryExplode(mobj_t *actor) ! 141: { ! 142: mobj_t *mo=NULL; ! 143: int i; ! 144: ! 145: for(i = (P_Random()&3)+3; i; i--) ! 146: { ! 147: mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_POTTERYBIT1); ! 148: P_SetMobjState(mo, mo->info->spawnstate+(P_Random()%5)); ! 149: if(mo) ! 150: { ! 151: mo->momz = ((P_Random()&7)+5)*(3*FRACUNIT/4); ! 152: mo->momx = (P_Random()-P_Random())<<(FRACBITS-6); ! 153: mo->momy = (P_Random()-P_Random())<<(FRACBITS-6); ! 154: } ! 155: } ! 156: S_StartSound(mo, SFX_POTTERY_EXPLODE); ! 157: if(actor->args[0]) ! 158: { // Spawn an item ! 159: if(!nomonsters ! 160: || !(mobjinfo[TranslateThingType[actor->args[0]]].flags&MF_COUNTKILL)) ! 161: { // Only spawn monsters if not -nomonsters ! 162: P_SpawnMobj(actor->x, actor->y, actor->z, ! 163: TranslateThingType[actor->args[0]]); ! 164: } ! 165: } ! 166: P_RemoveMobj(actor); ! 167: } ! 168: ! 169: //============================================================================ ! 170: // ! 171: // A_PotteryChooseBit ! 172: // ! 173: //============================================================================ ! 174: ! 175: void A_PotteryChooseBit(mobj_t *actor) ! 176: { ! 177: P_SetMobjState(actor, actor->info->deathstate+(P_Random()%5)+1); ! 178: actor->tics = 256+(P_Random()<<1); ! 179: } ! 180: ! 181: //============================================================================ ! 182: // ! 183: // A_PotteryCheck ! 184: // ! 185: //============================================================================ ! 186: ! 187: void A_PotteryCheck(mobj_t *actor) ! 188: { ! 189: int i; ! 190: mobj_t *pmo; ! 191: ! 192: if(!netgame) ! 193: { ! 194: pmo = players[consoleplayer].mo; ! 195: if(P_CheckSight(actor, pmo) && (abs(R_PointToAngle2(pmo->x, ! 196: pmo->y, actor->x, actor->y)-pmo->angle) <= ANGLE_45)) ! 197: { // Previous state (pottery bit waiting state) ! 198: P_SetMobjState(actor, actor->state-&states[0]-1); ! 199: } ! 200: else ! 201: { ! 202: return; ! 203: } ! 204: } ! 205: else ! 206: { ! 207: for(i = 0; i < MAXPLAYERS; i++) ! 208: { ! 209: if(!playeringame[i]) ! 210: { ! 211: continue; ! 212: } ! 213: pmo = players[i].mo; ! 214: if(P_CheckSight(actor, pmo) && (abs(R_PointToAngle2(pmo->x, ! 215: pmo->y, actor->x, actor->y)-pmo->angle) <= ANGLE_45)) ! 216: { // Previous state (pottery bit waiting state) ! 217: P_SetMobjState(actor, actor->state-&states[0]-1); ! 218: return; ! 219: } ! 220: } ! 221: } ! 222: } ! 223: ! 224: //============================================================================ ! 225: // ! 226: // A_CorpseBloodDrip ! 227: // ! 228: //============================================================================ ! 229: ! 230: void A_CorpseBloodDrip(mobj_t *actor) ! 231: { ! 232: if(P_Random() > 128) ! 233: { ! 234: return; ! 235: } ! 236: P_SpawnMobj(actor->x, actor->y, actor->z+actor->height/2, ! 237: MT_CORPSEBLOODDRIP); ! 238: } ! 239: ! 240: //============================================================================ ! 241: // ! 242: // A_CorpseExplode ! 243: // ! 244: //============================================================================ ! 245: ! 246: void A_CorpseExplode(mobj_t *actor) ! 247: { ! 248: mobj_t *mo; ! 249: int i; ! 250: ! 251: for(i = (P_Random()&3)+3; i; i--) ! 252: { ! 253: mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_CORPSEBIT); ! 254: P_SetMobjState(mo, mo->info->spawnstate+(P_Random()%3)); ! 255: if(mo) ! 256: { ! 257: mo->momz = ((P_Random()&7)+5)*(3*FRACUNIT/4); ! 258: mo->momx = (P_Random()-P_Random())<<(FRACBITS-6); ! 259: mo->momy = (P_Random()-P_Random())<<(FRACBITS-6); ! 260: } ! 261: } ! 262: // Spawn a skull ! 263: mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_CORPSEBIT); ! 264: P_SetMobjState(mo, S_CORPSEBIT_4); ! 265: if(mo) ! 266: { ! 267: mo->momz = ((P_Random()&7)+5)*(3*FRACUNIT/4); ! 268: mo->momx = (P_Random()-P_Random())<<(FRACBITS-6); ! 269: mo->momy = (P_Random()-P_Random())<<(FRACBITS-6); ! 270: S_StartSound(mo, SFX_FIRED_DEATH); ! 271: } ! 272: P_RemoveMobj(actor); ! 273: } ! 274: ! 275: //============================================================================ ! 276: // ! 277: // A_LeafSpawn ! 278: // ! 279: //============================================================================ ! 280: ! 281: void A_LeafSpawn(mobj_t *actor) ! 282: { ! 283: mobj_t *mo; ! 284: int i; ! 285: ! 286: for(i = (P_Random()&3)+1; i; i--) ! 287: { ! 288: mo = P_SpawnMobj(actor->x+((P_Random()-P_Random())<<14), actor->y+ ! 289: ((P_Random()-P_Random())<<14), actor->z+(P_Random()<<14), ! 290: MT_LEAF1+(P_Random()&1)); ! 291: if(mo) ! 292: { ! 293: P_ThrustMobj(mo, actor->angle, (P_Random()<<9)+3*FRACUNIT); ! 294: mo->target = actor; ! 295: mo->special1 = 0; ! 296: } ! 297: } ! 298: } ! 299: ! 300: //============================================================================ ! 301: // ! 302: // A_LeafThrust ! 303: // ! 304: //============================================================================ ! 305: ! 306: void A_LeafThrust(mobj_t *actor) ! 307: { ! 308: if(P_Random() > 96) ! 309: { ! 310: return; ! 311: } ! 312: actor->momz += (P_Random()<<9)+FRACUNIT; ! 313: } ! 314: ! 315: //============================================================================ ! 316: // ! 317: // A_LeafCheck ! 318: // ! 319: //============================================================================ ! 320: ! 321: void A_LeafCheck(mobj_t *actor) ! 322: { ! 323: actor->special1++; ! 324: if(actor->special1 >= 20) ! 325: { ! 326: P_SetMobjState(actor, S_NULL); ! 327: return; ! 328: } ! 329: if(P_Random() > 64) ! 330: { ! 331: if(!actor->momx && !actor->momy) ! 332: { ! 333: P_ThrustMobj(actor, actor->target->angle, ! 334: (P_Random()<<9)+FRACUNIT); ! 335: } ! 336: return; ! 337: } ! 338: P_SetMobjState(actor, S_LEAF1_8); ! 339: actor->momz = (P_Random()<<9)+FRACUNIT; ! 340: P_ThrustMobj(actor, actor->target->angle, (P_Random()<<9)+2*FRACUNIT); ! 341: actor->flags |= MF_MISSILE; ! 342: } ! 343: ! 344: /* ! 345: #define ORBIT_RADIUS (15*FRACUNIT) ! 346: void GenerateOrbitTable(void) ! 347: { ! 348: int angle; ! 349: ! 350: for (angle=0; angle<256; angle++) ! 351: { ! 352: orbitTableX[angle] = FixedMul(ORBIT_RADIUS, finecosine[angle<<5]); ! 353: orbitTableY[angle] = FixedMul(ORBIT_RADIUS, finesine[angle<<5]); ! 354: } ! 355: ! 356: printf("int orbitTableX[256]=\n{\n"); ! 357: for (angle=0; angle<256; angle+=8) ! 358: { ! 359: printf("%d, %d, %d, %d, %d, %d, %d, %d,\n", ! 360: orbitTableX[angle], ! 361: orbitTableX[angle+1], ! 362: orbitTableX[angle+2], ! 363: orbitTableX[angle+3], ! 364: orbitTableX[angle+4], ! 365: orbitTableX[angle+5], ! 366: orbitTableX[angle+6], ! 367: orbitTableX[angle+7]); ! 368: } ! 369: printf("};\n\n"); ! 370: ! 371: printf("int orbitTableY[256]=\n{\n"); ! 372: for (angle=0; angle<256; angle+=8) ! 373: { ! 374: printf("%d, %d, %d, %d, %d, %d, %d, %d,\n", ! 375: orbitTableY[angle], ! 376: orbitTableY[angle+1], ! 377: orbitTableY[angle+2], ! 378: orbitTableY[angle+3], ! 379: orbitTableY[angle+4], ! 380: orbitTableY[angle+5], ! 381: orbitTableY[angle+6], ! 382: orbitTableY[angle+7]); ! 383: } ! 384: printf("};\n"); ! 385: } ! 386: */ ! 387: ! 388: // New bridge stuff ! 389: // Parent ! 390: // special1 true == removing from world ! 391: // ! 392: // Child ! 393: // target pointer to center mobj ! 394: // args[0] angle of ball ! 395: ! 396: void A_BridgeOrbit(mobj_t *actor) ! 397: { ! 398: if (actor->target->special1) ! 399: { ! 400: P_SetMobjState(actor, S_NULL); ! 401: } ! 402: actor->args[0]+=3; ! 403: actor->x = actor->target->x + orbitTableX[actor->args[0]]; ! 404: actor->y = actor->target->y + orbitTableY[actor->args[0]]; ! 405: actor->z = actor->target->z; ! 406: } ! 407: ! 408: ! 409: void A_BridgeInit(mobj_t *actor) ! 410: { ! 411: byte startangle; ! 412: mobj_t *ball1, *ball2, *ball3; ! 413: fixed_t cx,cy,cz; ! 414: ! 415: // GenerateOrbitTable(); ! 416: ! 417: cx = actor->x; ! 418: cy = actor->y; ! 419: cz = actor->z; ! 420: startangle = P_Random(); ! 421: actor->special1 = 0; ! 422: ! 423: // Spawn triad into world ! 424: ball1 = P_SpawnMobj(cx, cy, cz, MT_BRIDGEBALL); ! 425: ball1->args[0] = startangle; ! 426: ball1->target = actor; ! 427: ! 428: ball2 = P_SpawnMobj(cx, cy, cz, MT_BRIDGEBALL); ! 429: ball2->args[0] = (startangle+85)&255; ! 430: ball2->target = actor; ! 431: ! 432: ball3 = P_SpawnMobj(cx, cy, cz, MT_BRIDGEBALL); ! 433: ball3->args[0] = (startangle+170)&255; ! 434: ball3->target = actor; ! 435: ! 436: A_BridgeOrbit(ball1); ! 437: A_BridgeOrbit(ball2); ! 438: A_BridgeOrbit(ball3); ! 439: } ! 440: ! 441: void A_BridgeRemove(mobj_t *actor) ! 442: { ! 443: actor->special1 = true; // Removing the bridge ! 444: actor->flags &= ~MF_SOLID; ! 445: P_SetMobjState(actor, S_FREE_BRIDGE1); ! 446: } ! 447: ! 448: ! 449: //========================================================================== ! 450: // ! 451: // A_GhostOn ! 452: // ! 453: //========================================================================== ! 454: ! 455: /* ! 456: void A_GhostOn(mobj_t *actor) ! 457: { ! 458: actor->flags |= MF_SHADOW; ! 459: } ! 460: */ ! 461: ! 462: //========================================================================== ! 463: // ! 464: // A_GhostOff ! 465: // ! 466: //========================================================================== ! 467: ! 468: /* ! 469: void A_GhostOff(mobj_t *actor) ! 470: { ! 471: actor->flags &= ~MF_SHADOW; ! 472: } ! 473: */ ! 474: ! 475: //========================================================================== ! 476: // ! 477: // A_HideThing ! 478: // ! 479: //========================================================================== ! 480: ! 481: void A_HideThing(mobj_t *actor) ! 482: { ! 483: actor->flags2 |= MF2_DONTDRAW; ! 484: } ! 485: ! 486: //========================================================================== ! 487: // ! 488: // A_UnHideThing ! 489: // ! 490: //========================================================================== ! 491: ! 492: void A_UnHideThing(mobj_t *actor) ! 493: { ! 494: actor->flags2 &= ~MF2_DONTDRAW; ! 495: } ! 496: ! 497: //========================================================================== ! 498: // ! 499: // A_SetShootable ! 500: // ! 501: //========================================================================== ! 502: ! 503: void A_SetShootable(mobj_t *actor) ! 504: { ! 505: actor->flags2 &= ~MF2_NONSHOOTABLE; ! 506: actor->flags |= MF_SHOOTABLE; ! 507: } ! 508: ! 509: //========================================================================== ! 510: // ! 511: // A_UnSetShootable ! 512: // ! 513: //========================================================================== ! 514: ! 515: void A_UnSetShootable(mobj_t *actor) ! 516: { ! 517: actor->flags2 |= MF2_NONSHOOTABLE; ! 518: actor->flags &= ~MF_SHOOTABLE; ! 519: } ! 520: ! 521: //========================================================================== ! 522: // ! 523: // A_SetAltShadow ! 524: // ! 525: //========================================================================== ! 526: ! 527: void A_SetAltShadow(mobj_t *actor) ! 528: { ! 529: actor->flags &= ~MF_SHADOW; ! 530: actor->flags |= MF_ALTSHADOW; ! 531: } ! 532: ! 533: //========================================================================== ! 534: // ! 535: // A_UnSetAltShadow ! 536: // ! 537: //========================================================================== ! 538: ! 539: /* ! 540: void A_UnSetAltShadow(mobj_t *actor) ! 541: { ! 542: actor->flags &= ~MF_ALTSHADOW; ! 543: } ! 544: */ ! 545: ! 546: //-------------------------------------------------------------------------- ! 547: // ! 548: // Sound Action Routines ! 549: // ! 550: //-------------------------------------------------------------------------- ! 551: ! 552: //========================================================================== ! 553: // ! 554: // A_ContMobjSound ! 555: // ! 556: //========================================================================== ! 557: ! 558: void A_ContMobjSound(mobj_t *actor) ! 559: { ! 560: switch(actor->type) ! 561: { ! 562: case MT_SERPENTFX: ! 563: S_StartSound(actor, SFX_SERPENTFX_CONTINUOUS); ! 564: break; ! 565: case MT_HAMMER_MISSILE: ! 566: S_StartSound(actor, SFX_FIGHTER_HAMMER_CONTINUOUS); ! 567: break; ! 568: case MT_QUAKE_FOCUS: ! 569: S_StartSound(actor, SFX_EARTHQUAKE); ! 570: break; ! 571: default: ! 572: break; ! 573: } ! 574: } ! 575: ! 576: //========================================================================== ! 577: // ! 578: // PROC A_ESound ! 579: // ! 580: //========================================================================== ! 581: ! 582: void A_ESound(mobj_t *mo) ! 583: { ! 584: int sound; ! 585: ! 586: switch(mo->type) ! 587: { ! 588: case MT_SOUNDWIND: ! 589: sound = SFX_WIND; ! 590: break; ! 591: default: ! 592: sound = SFX_NONE; ! 593: break; ! 594: } ! 595: S_StartSound(mo, sound); ! 596: } ! 597: ! 598: ! 599: ! 600: //========================================================================== ! 601: // Summon Minotaur -- see p_enemy for variable descriptions ! 602: //========================================================================== ! 603: ! 604: ! 605: void A_Summon(mobj_t *actor) ! 606: { ! 607: mobj_t *mo; ! 608: mobj_t *master; ! 609: ! 610: mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_MINOTAUR); ! 611: if (mo) ! 612: { ! 613: if(P_TestMobjLocation(mo) == false || !actor->special1) ! 614: { // Didn't fit - change back to artifact ! 615: P_SetMobjState(mo, S_NULL); ! 616: mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SUMMONMAULATOR); ! 617: if (mo) mo->flags2 |= MF2_DROPPED; ! 618: return; ! 619: } ! 620: ! 621: memcpy((void *)mo->args, &leveltime, sizeof(leveltime)); ! 622: master = (mobj_t *)actor->special1; ! 623: if (master->flags&MF_CORPSE) ! 624: { // Master dead ! 625: mo->special1 = 0; // No master ! 626: } ! 627: else ! 628: { ! 629: mo->special1 = actor->special1; // Pointer to master (mobj_t *) ! 630: P_GivePower(master->player, pw_minotaur); ! 631: } ! 632: ! 633: // Make smoke puff ! 634: P_SpawnMobj(actor->x, actor->y, actor->z, MT_MNTRSMOKE); ! 635: S_StartSound(actor, SFX_MAULATOR_ACTIVE); ! 636: } ! 637: } ! 638: ! 639: ! 640: ! 641: //========================================================================== ! 642: // Fog Variables: ! 643: // ! 644: // args[0] Speed (0..10) of fog ! 645: // args[1] Angle of spread (0..128) ! 646: // args[2] Frequency of spawn (1..10) ! 647: // args[3] Lifetime countdown ! 648: // args[4] Boolean: fog moving? ! 649: // special1 Internal: Counter for spawn frequency ! 650: // special2 Internal: Index into floatbob table ! 651: // ! 652: //========================================================================== ! 653: ! 654: void A_FogSpawn(mobj_t *actor) ! 655: { ! 656: mobj_t *mo=NULL; ! 657: angle_t delta; ! 658: ! 659: if (actor->special1-- > 0) return; ! 660: ! 661: actor->special1 = actor->args[2]; // Reset frequency count ! 662: ! 663: switch(P_Random()%3) ! 664: { ! 665: case 0: ! 666: mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_FOGPATCHS); ! 667: break; ! 668: case 1: ! 669: mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_FOGPATCHM); ! 670: break; ! 671: case 2: ! 672: mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_FOGPATCHL); ! 673: break; ! 674: } ! 675: ! 676: if (mo) ! 677: { ! 678: delta = actor->args[1]; ! 679: if (delta==0) delta=1; ! 680: mo->angle = actor->angle + (((P_Random()%delta)-(delta>>1))<<24); ! 681: mo->target = actor; ! 682: if (actor->args[0] < 1) actor->args[0] = 1; ! 683: mo->args[0] = (P_Random() % (actor->args[0]))+1; // Random speed ! 684: mo->args[3] = actor->args[3]; // Set lifetime ! 685: mo->args[4] = 1; // Set to moving ! 686: mo->special2 = P_Random()&63; ! 687: } ! 688: } ! 689: ! 690: ! 691: void A_FogMove(mobj_t *actor) ! 692: { ! 693: int speed = actor->args[0]<<FRACBITS; ! 694: angle_t angle; ! 695: int weaveindex; ! 696: ! 697: if (!(actor->args[4])) return; ! 698: ! 699: if (actor->args[3]-- <= 0) ! 700: { ! 701: P_SetMobjStateNF(actor, actor->info->deathstate); ! 702: return; ! 703: } ! 704: ! 705: if ((actor->args[3] % 4) == 0) ! 706: { ! 707: weaveindex = actor->special2; ! 708: actor->z += FloatBobOffsets[weaveindex]>>1; ! 709: actor->special2 = (weaveindex+1)&63; ! 710: } ! 711: ! 712: angle = actor->angle>>ANGLETOFINESHIFT; ! 713: actor->momx = FixedMul(speed, finecosine[angle]); ! 714: actor->momy = FixedMul(speed, finesine[angle]); ! 715: } ! 716: ! 717: //=========================================================================== ! 718: // ! 719: // A_PoisonBagInit ! 720: // ! 721: //=========================================================================== ! 722: ! 723: void A_PoisonBagInit(mobj_t *actor) ! 724: { ! 725: mobj_t *mo; ! 726: ! 727: mo = P_SpawnMobj(actor->x, actor->y, actor->z+28*FRACUNIT, ! 728: MT_POISONCLOUD); ! 729: if(!mo) ! 730: { ! 731: return; ! 732: } ! 733: mo->momx = 1; // missile objects must move to impact other objects ! 734: mo->special1 = 24+(P_Random()&7); ! 735: mo->special2 = 0; ! 736: mo->target = actor->target; ! 737: mo->radius = 20*FRACUNIT; ! 738: mo->height = 30*FRACUNIT; ! 739: mo->flags &= ~MF_NOCLIP; ! 740: } ! 741: ! 742: //=========================================================================== ! 743: // ! 744: // A_PoisonBagCheck ! 745: // ! 746: //=========================================================================== ! 747: ! 748: void A_PoisonBagCheck(mobj_t *actor) ! 749: { ! 750: if(!--actor->special1) ! 751: { ! 752: P_SetMobjState(actor, S_POISONCLOUD_X1); ! 753: } ! 754: else ! 755: { ! 756: return; ! 757: } ! 758: } ! 759: ! 760: //=========================================================================== ! 761: // ! 762: // A_PoisonBagDamage ! 763: // ! 764: //=========================================================================== ! 765: ! 766: void A_PoisonBagDamage(mobj_t *actor) ! 767: { ! 768: int bobIndex; ! 769: ! 770: extern void A_Explode(mobj_t *actor); ! 771: ! 772: A_Explode(actor); ! 773: ! 774: bobIndex = actor->special2; ! 775: actor->z += FloatBobOffsets[bobIndex]>>4; ! 776: actor->special2 = (bobIndex+1)&63; ! 777: } ! 778: ! 779: //=========================================================================== ! 780: // ! 781: // A_PoisonShroom ! 782: // ! 783: //=========================================================================== ! 784: ! 785: void A_PoisonShroom(mobj_t *actor) ! 786: { ! 787: actor->tics = 128+(P_Random()<<1); ! 788: } ! 789: ! 790: //=========================================================================== ! 791: // ! 792: // A_CheckThrowBomb ! 793: // ! 794: //=========================================================================== ! 795: ! 796: void A_CheckThrowBomb(mobj_t *actor) ! 797: { ! 798: if(abs(actor->momx) < 1.5*FRACUNIT && abs(actor->momy) < 1.5*FRACUNIT ! 799: && actor->momz < 2*FRACUNIT ! 800: && actor->state == &states[S_THROWINGBOMB6]) ! 801: { ! 802: P_SetMobjState(actor, S_THROWINGBOMB7); ! 803: actor->z = actor->floorz; ! 804: actor->momz = 0; ! 805: actor->flags2 &= ~MF2_FLOORBOUNCE; ! 806: actor->flags &= ~MF_MISSILE; ! 807: } ! 808: if(!--actor->health) ! 809: { ! 810: P_SetMobjState(actor, actor->info->deathstate); ! 811: } ! 812: } ! 813: ! 814: //=========================================================================== ! 815: // Quake variables ! 816: // ! 817: // args[0] Intensity on richter scale (2..9) ! 818: // args[1] Duration in tics ! 819: // args[2] Radius for damage ! 820: // args[3] Radius for tremor ! 821: // args[4] TID of map thing for focus of quake ! 822: // ! 823: //=========================================================================== ! 824: ! 825: //=========================================================================== ! 826: // ! 827: // A_LocalQuake ! 828: // ! 829: //=========================================================================== ! 830: ! 831: boolean A_LocalQuake(byte *args, mobj_t *actor) ! 832: { ! 833: mobj_t *focus, *target; ! 834: int lastfound=0; ! 835: int success=false; ! 836: ! 837: actor=actor; // suppress warning ! 838: ! 839: // Find all quake foci ! 840: do ! 841: { ! 842: target = P_FindMobjFromTID(args[4], &lastfound); ! 843: if (target) ! 844: { ! 845: focus = P_SpawnMobj(target->x, ! 846: target->y, ! 847: target->z, MT_QUAKE_FOCUS); ! 848: if (focus) ! 849: { ! 850: focus->args[0] = args[0]; ! 851: focus->args[1] = args[1]>>1; // decremented every 2 tics ! 852: focus->args[2] = args[2]; ! 853: focus->args[3] = args[3]; ! 854: focus->args[4] = args[4]; ! 855: success = true; ! 856: } ! 857: } ! 858: }while(target != NULL); ! 859: ! 860: return(success); ! 861: } ! 862: ! 863: ! 864: //=========================================================================== ! 865: // ! 866: // A_Quake ! 867: // ! 868: //=========================================================================== ! 869: int localQuakeHappening[MAXPLAYERS]; ! 870: ! 871: void A_Quake(mobj_t *actor) ! 872: { ! 873: angle_t an; ! 874: player_t *player; ! 875: mobj_t *victim; ! 876: int richters = actor->args[0]; ! 877: int playnum; ! 878: fixed_t dist; ! 879: ! 880: if (actor->args[1]-- > 0) ! 881: { ! 882: for (playnum=0; playnum < MAXPLAYERS; playnum++) ! 883: { ! 884: player = &players[playnum]; ! 885: if (!playeringame[playnum]) continue; ! 886: ! 887: victim = player->mo; ! 888: dist = P_AproxDistance(actor->x - victim->x, ! 889: actor->y - victim->y) >> (FRACBITS+6); ! 890: // Tested in tile units (64 pixels) ! 891: if (dist < actor->args[3]) // In tremor radius ! 892: { ! 893: localQuakeHappening[playnum] = richters; ! 894: } ! 895: // Check if in damage radius ! 896: if ((dist < actor->args[2]) && ! 897: (victim->z <= victim->floorz)) ! 898: { ! 899: if (P_Random() < 50) ! 900: { ! 901: P_DamageMobj(victim, NULL, NULL, HITDICE(1)); ! 902: } ! 903: // Thrust player around ! 904: an = victim->angle + ANGLE_1*P_Random(); ! 905: P_ThrustMobj(victim,an,richters<<(FRACBITS-1)); ! 906: } ! 907: } ! 908: } ! 909: else ! 910: { ! 911: for (playnum=0; playnum < MAXPLAYERS; playnum++) ! 912: { ! 913: localQuakeHappening[playnum] = false; ! 914: } ! 915: P_SetMobjState(actor, S_NULL); ! 916: } ! 917: } ! 918: ! 919: ! 920: ! 921: ! 922: //=========================================================================== ! 923: // ! 924: // Teleport other stuff ! 925: // ! 926: //=========================================================================== ! 927: ! 928: #define TELEPORT_LIFE 1 ! 929: ! 930: void A_TeloSpawnA(mobj_t *actor) ! 931: { ! 932: mobj_t *mo; ! 933: ! 934: mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_TELOTHER_FX2); ! 935: if (mo) ! 936: { ! 937: mo->special1 = TELEPORT_LIFE; // Lifetime countdown ! 938: mo->angle = actor->angle; ! 939: mo->target = actor->target; ! 940: mo->momx = actor->momx>>1; ! 941: mo->momy = actor->momy>>1; ! 942: mo->momz = actor->momz>>1; ! 943: } ! 944: } ! 945: ! 946: void A_TeloSpawnB(mobj_t *actor) ! 947: { ! 948: mobj_t *mo; ! 949: ! 950: mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_TELOTHER_FX3); ! 951: if (mo) ! 952: { ! 953: mo->special1 = TELEPORT_LIFE; // Lifetime countdown ! 954: mo->angle = actor->angle; ! 955: mo->target = actor->target; ! 956: mo->momx = actor->momx>>1; ! 957: mo->momy = actor->momy>>1; ! 958: mo->momz = actor->momz>>1; ! 959: } ! 960: } ! 961: ! 962: void A_TeloSpawnC(mobj_t *actor) ! 963: { ! 964: mobj_t *mo; ! 965: ! 966: mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_TELOTHER_FX4); ! 967: if (mo) ! 968: { ! 969: mo->special1 = TELEPORT_LIFE; // Lifetime countdown ! 970: mo->angle = actor->angle; ! 971: mo->target = actor->target; ! 972: mo->momx = actor->momx>>1; ! 973: mo->momy = actor->momy>>1; ! 974: mo->momz = actor->momz>>1; ! 975: } ! 976: } ! 977: ! 978: void A_TeloSpawnD(mobj_t *actor) ! 979: { ! 980: mobj_t *mo; ! 981: ! 982: mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_TELOTHER_FX5); ! 983: if (mo) ! 984: { ! 985: mo->special1 = TELEPORT_LIFE; // Lifetime countdown ! 986: mo->angle = actor->angle; ! 987: mo->target = actor->target; ! 988: mo->momx = actor->momx>>1; ! 989: mo->momy = actor->momy>>1; ! 990: mo->momz = actor->momz>>1; ! 991: } ! 992: } ! 993: ! 994: void A_CheckTeleRing(mobj_t *actor) ! 995: { ! 996: if (actor->special1-- <= 0) ! 997: { ! 998: P_SetMobjState(actor, actor->info->deathstate); ! 999: } ! 1000: } ! 1001: ! 1002: ! 1003: ! 1004: ! 1005: // Dirt stuff ! 1006: ! 1007: void P_SpawnDirt(mobj_t *actor, fixed_t radius) ! 1008: { ! 1009: fixed_t x,y,z; ! 1010: int dtype=0; ! 1011: mobj_t *mo; ! 1012: angle_t angle; ! 1013: ! 1014: angle = P_Random()<<5; // <<24 >>19 ! 1015: x = actor->x + FixedMul(radius,finecosine[angle]); ! 1016: y = actor->y + FixedMul(radius,finesine[angle]); ! 1017: // x = actor->x + ((P_Random()-P_Random())%radius)<<FRACBITS; ! 1018: // y = actor->y + ((P_Random()-P_Random()<<FRACBITS)%radius); ! 1019: z = actor->z + (P_Random()<<9) + FRACUNIT; ! 1020: switch(P_Random()%6) ! 1021: { ! 1022: case 0: ! 1023: dtype = MT_DIRT1; ! 1024: break; ! 1025: case 1: ! 1026: dtype = MT_DIRT2; ! 1027: break; ! 1028: case 2: ! 1029: dtype = MT_DIRT3; ! 1030: break; ! 1031: case 3: ! 1032: dtype = MT_DIRT4; ! 1033: break; ! 1034: case 4: ! 1035: dtype = MT_DIRT5; ! 1036: break; ! 1037: case 5: ! 1038: dtype = MT_DIRT6; ! 1039: break; ! 1040: } ! 1041: mo = P_SpawnMobj(x,y,z,dtype); ! 1042: if (mo) ! 1043: { ! 1044: mo->momz = P_Random()<<10; ! 1045: } ! 1046: } ! 1047: ! 1048: ! 1049: ! 1050: ! 1051: //=========================================================================== ! 1052: // ! 1053: // Thrust floor stuff ! 1054: // ! 1055: // Thrust Spike Variables ! 1056: // special1 pointer to dirt clump mobj ! 1057: // special2 speed of raise ! 1058: // args[0] 0 = lowered, 1 = raised ! 1059: // args[1] 0 = normal, 1 = bloody ! 1060: //=========================================================================== ! 1061: ! 1062: void A_ThrustInitUp(mobj_t *actor) ! 1063: { ! 1064: actor->special2 = 5; // Raise speed ! 1065: actor->args[0] = 1; // Mark as up ! 1066: actor->floorclip = 0; ! 1067: actor->flags = MF_SOLID; ! 1068: actor->flags2 = MF2_NOTELEPORT|MF2_FLOORCLIP; ! 1069: actor->special1 = 0L; ! 1070: } ! 1071: ! 1072: void A_ThrustInitDn(mobj_t *actor) ! 1073: { ! 1074: mobj_t *mo; ! 1075: actor->special2 = 5; // Raise speed ! 1076: actor->args[0] = 0; // Mark as down ! 1077: actor->floorclip = actor->info->height; ! 1078: actor->flags = 0; ! 1079: actor->flags2 = MF2_NOTELEPORT|MF2_FLOORCLIP|MF2_DONTDRAW; ! 1080: mo = P_SpawnMobj(actor->x, actor->y, actor->z, MT_DIRTCLUMP); ! 1081: actor->special1 = (int)mo; ! 1082: } ! 1083: ! 1084: ! 1085: void A_ThrustRaise(mobj_t *actor) ! 1086: { ! 1087: if (A_RaiseMobj(actor)) ! 1088: { // Reached it's target height ! 1089: actor->args[0] = 1; ! 1090: if (actor->args[1]) ! 1091: P_SetMobjStateNF(actor, S_BTHRUSTINIT2_1); ! 1092: else ! 1093: P_SetMobjStateNF(actor, S_THRUSTINIT2_1); ! 1094: } ! 1095: ! 1096: // Lose the dirt clump ! 1097: if ((actor->floorclip < actor->height) && actor->special1) ! 1098: { ! 1099: P_RemoveMobj( (mobj_t *)actor->special1 ); ! 1100: actor->special1 = 0; ! 1101: } ! 1102: ! 1103: // Spawn some dirt ! 1104: if (P_Random()<40) ! 1105: P_SpawnDirt(actor, actor->radius); ! 1106: actor->special2++; // Increase raise speed ! 1107: } ! 1108: ! 1109: void A_ThrustLower(mobj_t *actor) ! 1110: { ! 1111: if (A_SinkMobj(actor)) ! 1112: { ! 1113: actor->args[0] = 0; ! 1114: if (actor->args[1]) ! 1115: P_SetMobjStateNF(actor, S_BTHRUSTINIT1_1); ! 1116: else ! 1117: P_SetMobjStateNF(actor, S_THRUSTINIT1_1); ! 1118: } ! 1119: } ! 1120: ! 1121: void A_ThrustBlock(mobj_t *actor) ! 1122: { ! 1123: actor->flags |= MF_SOLID; ! 1124: } ! 1125: ! 1126: void A_ThrustImpale(mobj_t *actor) ! 1127: { ! 1128: // Impale all shootables in radius ! 1129: PIT_ThrustSpike(actor); ! 1130: } ! 1131: ! 1132: //=========================================================================== ! 1133: // ! 1134: // A_SoAExplode - Suit of Armor Explode ! 1135: // ! 1136: //=========================================================================== ! 1137: ! 1138: void A_SoAExplode(mobj_t *actor) ! 1139: { ! 1140: mobj_t *mo; ! 1141: int i; ! 1142: ! 1143: for(i = 0; i < 10; i++) ! 1144: { ! 1145: mo = P_SpawnMobj(actor->x+((P_Random()-128)<<12), ! 1146: actor->y+((P_Random()-128)<<12), ! 1147: actor->z+(P_Random()*actor->height/256), MT_ZARMORCHUNK); ! 1148: P_SetMobjState(mo, mo->info->spawnstate+i); ! 1149: if(mo) ! 1150: { ! 1151: mo->momz = ((P_Random()&7)+5)*FRACUNIT; ! 1152: mo->momx = (P_Random()-P_Random())<<(FRACBITS-6); ! 1153: mo->momy = (P_Random()-P_Random())<<(FRACBITS-6); ! 1154: } ! 1155: } ! 1156: if(actor->args[0]) ! 1157: { // Spawn an item ! 1158: if(!nomonsters ! 1159: || !(mobjinfo[TranslateThingType[actor->args[0]]].flags&MF_COUNTKILL)) ! 1160: { // Only spawn monsters if not -nomonsters ! 1161: P_SpawnMobj(actor->x, actor->y, actor->z, ! 1162: TranslateThingType[actor->args[0]]); ! 1163: } ! 1164: } ! 1165: S_StartSound(mo, SFX_SUITOFARMOR_BREAK); ! 1166: P_RemoveMobj(actor); ! 1167: } ! 1168: ! 1169: //=========================================================================== ! 1170: // ! 1171: // A_BellReset1 ! 1172: // ! 1173: //=========================================================================== ! 1174: ! 1175: void A_BellReset1(mobj_t *actor) ! 1176: { ! 1177: actor->flags |= MF_NOGRAVITY; ! 1178: actor->height <<= 2; ! 1179: } ! 1180: ! 1181: //=========================================================================== ! 1182: // ! 1183: // A_BellReset2 ! 1184: // ! 1185: //=========================================================================== ! 1186: ! 1187: void A_BellReset2(mobj_t *actor) ! 1188: { ! 1189: actor->flags |= MF_SHOOTABLE; ! 1190: actor->flags &= ~MF_CORPSE; ! 1191: actor->health = 5; ! 1192: } ! 1193: ! 1194: ! 1195: //=========================================================================== ! 1196: // ! 1197: // A_FlameCheck ! 1198: // ! 1199: //=========================================================================== ! 1200: ! 1201: void A_FlameCheck(mobj_t *actor) ! 1202: { ! 1203: if(!actor->args[0]--) // Called every 8 tics ! 1204: { ! 1205: P_SetMobjState(actor, S_NULL); ! 1206: } ! 1207: } ! 1208: ! 1209: ! 1210: //=========================================================================== ! 1211: // Bat Spawner Variables ! 1212: // special1 frequency counter ! 1213: // special2 ! 1214: // args[0] frequency of spawn (1=fastest, 10=slowest) ! 1215: // args[1] spread angle (0..255) ! 1216: // args[2] ! 1217: // args[3] duration of bats (in octics) ! 1218: // args[4] turn amount per move (in degrees) ! 1219: // ! 1220: // Bat Variables ! 1221: // special2 lifetime counter ! 1222: // args[4] turn amount per move (in degrees) ! 1223: //=========================================================================== ! 1224: ! 1225: void A_BatSpawnInit(mobj_t *actor) ! 1226: { ! 1227: actor->special1 = 0; // Frequency count ! 1228: } ! 1229: ! 1230: void A_BatSpawn(mobj_t *actor) ! 1231: { ! 1232: mobj_t *mo; ! 1233: int delta; ! 1234: angle_t angle; ! 1235: ! 1236: // Countdown until next spawn ! 1237: if (actor->special1-- > 0) return; ! 1238: actor->special1 = actor->args[0]; // Reset frequency count ! 1239: ! 1240: delta = actor->args[1]; ! 1241: if (delta==0) delta=1; ! 1242: angle = actor->angle + (((P_Random()%delta)-(delta>>1))<<24); ! 1243: mo = P_SpawnMissileAngle(actor, MT_BAT, angle, 0); ! 1244: if (mo) ! 1245: { ! 1246: mo->args[0] = P_Random()&63; // floatbob index ! 1247: mo->args[4] = actor->args[4]; // turn degrees ! 1248: mo->special2 = actor->args[3]<<3; // Set lifetime ! 1249: mo->target = actor; ! 1250: } ! 1251: } ! 1252: ! 1253: ! 1254: void A_BatMove(mobj_t *actor) ! 1255: { ! 1256: angle_t newangle; ! 1257: fixed_t speed; ! 1258: ! 1259: if (actor->special2 < 0) ! 1260: { ! 1261: P_SetMobjState(actor, actor->info->deathstate); ! 1262: } ! 1263: actor->special2 -= 2; // Called every 2 tics ! 1264: ! 1265: if (P_Random()<128) ! 1266: { ! 1267: newangle = actor->angle + ANGLE_1*actor->args[4]; ! 1268: } ! 1269: else ! 1270: { ! 1271: newangle = actor->angle - ANGLE_1*actor->args[4]; ! 1272: } ! 1273: ! 1274: // Adjust momentum vector to new direction ! 1275: newangle >>= ANGLETOFINESHIFT; ! 1276: speed = FixedMul(actor->info->speed, P_Random()<<10); ! 1277: actor->momx = FixedMul(speed, finecosine[newangle]); ! 1278: actor->momy = FixedMul(speed, finesine[newangle]); ! 1279: ! 1280: if (P_Random()<15) ! 1281: S_StartSound(actor, SFX_BAT_SCREAM); ! 1282: ! 1283: // Handle Z movement ! 1284: actor->z = actor->target->z + 2*FloatBobOffsets[actor->args[0]]; ! 1285: actor->args[0] = (actor->args[0]+3)&63; ! 1286: } ! 1287: ! 1288: //=========================================================================== ! 1289: // ! 1290: // A_TreeDeath ! 1291: // ! 1292: //=========================================================================== ! 1293: ! 1294: void A_TreeDeath(mobj_t *actor) ! 1295: { ! 1296: if(!(actor->flags2&MF2_FIREDAMAGE)) ! 1297: { ! 1298: actor->height <<= 2; ! 1299: actor->flags |= MF_SHOOTABLE; ! 1300: actor->flags &= ~(MF_CORPSE+MF_DROPOFF); ! 1301: actor->health = 35; ! 1302: return; ! 1303: } ! 1304: else ! 1305: { ! 1306: P_SetMobjState(actor, actor->info->meleestate); ! 1307: } ! 1308: } ! 1309: ! 1310: //=========================================================================== ! 1311: // ! 1312: // A_NoGravity ! 1313: // ! 1314: //=========================================================================== ! 1315: ! 1316: void A_NoGravity(mobj_t *actor) ! 1317: { ! 1318: actor->flags |= MF_NOGRAVITY; ! 1319: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.