// // ST_updateFaceWidget // // This is a not-very-pretty routine which handles // the face states and their timing. // the precedence of expressions is: // dead > evil grin > turned head > straight ahead // static void ST_updateFaceWidget() { int i; angle_t badguyangle; angle_t diffang; static int lastattackdown = -1; static int priority = ST_PRIORITY_NONE; bool doevilgrin; if(priority < ST_PRIORITY_MAX) { // dead if(!plyr->health) { priority = ST_PRIORITY_DEAD; st_faceindex = ST_DEADFACE; st_facecount = 1; } } // haleyjd 06/27/08: ouch face when player screams from falling if(priority < ST_PRIORITY_DEAD) { if(plyr->mo->intflags & MIF_SCREAMED) { priority = ST_PRIORITY_FALLING; st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET; st_facecount = 1; } } if(priority < ST_PRIORITY_FALLING) { if(plyr->bonuscount) { // picking up bonus doevilgrin = false; for(i = 0; i < NUMWEAPONS; i++) { if(oldweaponsowned[i] != weaponsowned[i]) { doevilgrin = true; oldweaponsowned[i] = weaponsowned[i]; } } if(doevilgrin) { // evil grin if just picked up weapon priority = ST_PRIORITY_EVILGRIN; st_facecount = ST_EVILGRINCOUNT; st_faceindex = ST_calcPainOffset() + ST_EVILGRINOFFSET; } } } if(priority < ST_PRIORITY_EVILGRIN) { if(plyr->damagecount && plyr->attacker && plyr->attacker != plyr->mo) { // being attacked priority = ST_PRIORITY_PAIN; // haleyjd 10/12/03: classic DOOM problem of missing OUCH face // was due to inversion of this test: // if(plyr->health - st_oldhealth > ST_MUCHPAIN) if(st_oldhealth - plyr->health > ST_MUCHPAIN) { priority = ST_PRIORITY_MUCHPAIN; st_facecount = ST_TURNCOUNT; st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET; } else { badguyangle = R_PointToAngle2(plyr->mo->x, plyr->mo->y, getThingX(plyr->mo, plyr->attacker), getThingY(plyr->mo, plyr->attacker)); if(badguyangle > plyr->mo->angle) { // whether right or left diffang = badguyangle - plyr->mo->angle; i = diffang > ANG180; } else { // whether left or right diffang = plyr->mo->angle - badguyangle; i = diffang <= ANG180; } // confusing, aint it? st_facecount = ST_TURNCOUNT; st_faceindex = ST_calcPainOffset(); if(diffang < ANG45) { // head-on st_faceindex += ST_RAMPAGEOFFSET; } else if(i) { // turn face right st_faceindex += ST_TURNOFFSET; } else { // turn face left st_faceindex += ST_TURNOFFSET+1; } } } } if(priority < ST_PRIORITY_PAIN) { // getting hurt because of your own damn stupidity if(plyr->damagecount) { // haleyjd 10/12/03: classic DOOM problem of missing OUCH face // was due to inversion of this test: // if(plyr->health - st_oldhealth > ST_MUCHPAIN) if(st_oldhealth - plyr->health > ST_MUCHPAIN) { priority = ST_PRIORITY_MUCHPAIN_SELF; st_facecount = ST_TURNCOUNT; st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET; } else { priority = ST_PRIORITY_PAIN_SELF; st_facecount = ST_TURNCOUNT; st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET; } } } if(priority < ST_PRIORITY_PAIN_SELF) { // rapid firing if(plyr->attackdown) { if(lastattackdown==-1) lastattackdown = ST_RAMPAGEDELAY; else if(!--lastattackdown) { priority = ST_PRIORITY_RAMPAGE; st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET; st_facecount = 1; lastattackdown = 1; } } else lastattackdown = -1; } if(priority < ST_PRIORITY_RAMPAGE) { // invulnerability if((plyr->cheats & CF_GODMODE) || plyr->powers[pw_invulnerability]) { priority = ST_PRIORITY_GODMODE; st_faceindex = ST_GODFACE; st_facecount = 1; } } // look left or look right if the facecount has timed out if(!st_facecount) { // sf: remove st_randomnumber st_faceindex = ST_calcPainOffset() + (M_Random() % 3); st_facecount = ST_STRAIGHTFACECOUNT; priority = ST_PRIORITY_NONE; } st_facecount--; }
// // A_Tracer // // (Accidentally?) randomized homing missile maintenance. // ioanch 20151230: fixed to be portal-aware // void A_Tracer(actionargs_t *actionargs) { angle_t exact; fixed_t dist; fixed_t slope; Mobj *actor = actionargs->actor; Mobj *dest; Mobj *th; // killough 1/18/98: this is why some missiles do not have smoke // and some do. Also, internal demos start at random gametics, // thus the bug in which revenants cause internal demos to go out // of sync. // // killough 3/6/98: fix revenant internal demo bug by subtracting // levelstarttic from gametic. // // killough 9/29/98: use new "basetic" so that demos stay in sync // during pauses and menu activations, while retaining old demo // sync. // // leveltime would have been better to use to start with in Doom, // but since old demos were recorded using gametic, we must stick // with it, and improvise around it (using leveltime causes desync // across levels). if((gametic-basetic) & 3) return; // spawn a puff of smoke behind the rocket P_SpawnPuff(actor->x, actor->y, actor->z, 0, 3, false); th = P_SpawnMobj(actor->x - actor->momx, actor->y - actor->momy, actor->z, E_SafeThingType(MT_SMOKE)); th->momz = FRACUNIT; th->tics -= P_Random(pr_tracer) & 3; if(th->tics < 1) th->tics = 1; // adjust direction dest = actor->tracer; if(!dest || dest->health <= 0) return; fixed_t dx = getThingX(actor, dest); fixed_t dy = getThingY(actor, dest); fixed_t dz = getThingZ(actor, dest); // change angle exact = P_PointToAngle(actor->x, actor->y, dx, dy); if(exact != actor->angle) { if(exact - actor->angle > 0x80000000) { actor->angle -= TRACEANGLE; if(exact - actor->angle < 0x80000000) actor->angle = exact; } else { actor->angle += TRACEANGLE; if(exact - actor->angle > 0x80000000) actor->angle = exact; } } exact = actor->angle>>ANGLETOFINESHIFT; actor->momx = FixedMul(actor->info->speed, finecosine[exact]); actor->momy = FixedMul(actor->info->speed, finesine[exact]); // change slope dist = P_AproxDistance(dx - actor->x, dy - actor->y); dist = dist / actor->info->speed; if(dist < 1) dist = 1; slope = (dz + 40*FRACUNIT - actor->z) / dist; if(slope < actor->momz) actor->momz -= FRACUNIT/8; else actor->momz += FRACUNIT/8; }