Annotation of doom/a_action.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.