diff --git a/src/p_enemy.c b/src/p_enemy.c index 6c87ebb23..716b1a5ca 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5188,6 +5188,7 @@ void A_MaceRotate(mobj_t *actor) TVector v; TVector *res; fixed_t radius; + INT32 prevswing; #ifdef HAVE_BLUA if (LUA_CallAction("A_MaceRotate", actor)) return; @@ -5238,10 +5239,16 @@ void A_MaceRotate(mobj_t *actor) // Swinging Chain. if (actor->target->type == MT_HANGMACEPOINT || actor->target->type == MT_SWINGMACEPOINT) { - actor->movecount += actor->target->lastlook; - actor->movecount &= FINEMASK; + actor->threshold += actor->target->lastlook; + actor->threshold &= FINEMASK; - actor->threshold = FixedMul(FINECOSINE(actor->movecount), actor->target->lastlook << FRACBITS); + prevswing = actor->movecount; + actor->movecount = FixedMul(FINECOSINE(actor->threshold), actor->target->lastlook << FRACBITS); + + if ((actor->flags2 & MF2_AMBUSH) // at the end of the chain + && !(actor->target->flags2 & MF2_BOSSNOTRAP) // flag that makes 'em shut up on request + && ((prevswing > 0) != (actor->movecount > 0))) // just passed its lowest point + S_StartSound(actor, actor->info->activesound); v[0] = FRACUNIT; v[1] = 0; @@ -5249,7 +5256,7 @@ void A_MaceRotate(mobj_t *actor) v[3] = FRACUNIT; // Calculate the angle matrixes for the link. - res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(actor->threshold))); + res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(actor->movecount))); M_Memcpy(&v, res, sizeof(v)); res = VectorMatrixMultiply(v, *RotateZMatrix(actor->target->health << ANGLETOFINESHIFT)); M_Memcpy(&v, res, sizeof(v)); @@ -5257,15 +5264,18 @@ void A_MaceRotate(mobj_t *actor) // Rotating Chain. else { - angle_t fa; - + prevswing = actor->threshold; actor->threshold += actor->target->lastlook; actor->threshold &= FINEMASK; - fa = actor->threshold; - v[0] = FixedMul(FINECOSINE(fa), radius); + if ((actor->flags2 & MF2_AMBUSH) // at the end of the chain + && !(actor->target->flags2 & MF2_BOSSNOTRAP) // flag that makes 'em shut up on request + && (!(prevswing > (FINEMASK/2)) && (actor->threshold > (FINEMASK/2)))) // completed a full swing + S_StartSound(actor, actor->info->activesound); + + v[0] = FixedMul(FINECOSINE((angle_t)actor->threshold), radius); v[1] = 0; - v[2] = FixedMul(FINESINE(fa), radius); + v[2] = FixedMul(FINESINE((angle_t)actor->threshold), radius); v[3] = FRACUNIT; // Calculate the angle matrixes for the link. @@ -5281,10 +5291,6 @@ void A_MaceRotate(mobj_t *actor) actor->z += v[2]; P_SetThingPosition(actor); - - if (!(actor->target->flags2 & MF2_BOSSNOTRAP) // flag that makes maces shut up on request - && !(leveltime & 63) && (actor->type == MT_BIGMACE || actor->type == MT_SMALLMACE) && actor->target->type == MT_MACEPOINT) - S_StartSound(actor, actor->info->activesound); } // Function: A_SetFuse diff --git a/src/p_mobj.c b/src/p_mobj.c index e3feef294..3ff5bfab5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9775,9 +9775,10 @@ void P_SpawnMapThing(mapthing_t *mthing) case MT_HANGMACEPOINT: case MT_SPINMACEPOINT: { - fixed_t mlength, mspeed, mxspeed, mzspeed, mstartangle, mmaxspeed, movecountset, thresholdset, radiusfactor = 1; + fixed_t mlength, mspeed, mxspeed, mzspeed, mstartangle, mmaxspeed, thresholdset, radiusfactor = 1; mobjtype_t chainlink = MT_SMALLMACECHAIN; mobjtype_t macetype = MT_SMALLMACE; + mobjtype_t firsttype; const boolean hazard = (mobj->type == MT_MACEPOINT || mobj->type == MT_SWINGMACEPOINT); mobj_t *spawnee; INT32 line; @@ -9793,10 +9794,12 @@ void P_SpawnMapThing(mapthing_t *mthing) return; } /* -No deaf - small mace -Deaf - big mace +No deaf - small +Deaf - big -ML_NOCLIMB : Direction not controllable +ML_NOCLIMB : +SPINMACEPOINT - Direction not controllable +MACEPOINT, SWINGMACEPOINT - Chain links are replaced with maces */ mlength = abs(lines[line].dx >> FRACBITS); mspeed = abs(lines[line].dy >> FRACBITS); @@ -9809,18 +9812,18 @@ ML_NOCLIMB : Direction not controllable mxspeed %= 360; mzspeed %= 360; - CONS_Debug(DBG_GAMELOGIC, "Mace Chain (mapthing #%s):\n" + CONS_Debug(DBG_GAMELOGIC, "Mace/Chain (mapthing #%s):\n" "Length is %d\n" "Speed is %d\n" - "Xspeed is %d\n" - "Zspeed is %d\n" - "startangle is %d\n" - "maxspeed is %d\n", + "Phase is %d\n" + "Angle is %d\n" + "Tilt is %d\n" + "Max. speed is %d\n", sizeu1(mthingi), mlength, mspeed, mxspeed, mzspeed, mstartangle, mmaxspeed); mobj->lastlook = mspeed << 4; mobj->movecount = mobj->lastlook; - mobj->health = (FixedAngle(((mzspeed+mstartangle)%360)*FRACUNIT)>>ANGLETOFINESHIFT); + mobj->health = (FixedAngle(mzspeed*FRACUNIT)>>ANGLETOFINESHIFT); mobj->threshold = (FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT); mobj->movefactor = mobj->threshold; mobj->friction = mmaxspeed; @@ -9844,31 +9847,24 @@ ML_NOCLIMB : Direction not controllable mobj->reactiontime = 0; - if (mthing->options & MTF_OBJECTSPECIAL) + if (!mspeed || mthing->options & MTF_OBJECTSPECIAL) mobj->flags2 |= MF2_BOSSNOTRAP; // shut up maces. - if (mobj->type == MT_HANGMACEPOINT || mobj->type == MT_SWINGMACEPOINT) - movecountset = FixedAngle(mstartangle*FRACUNIT)>>ANGLETOFINESHIFT; - else - movecountset = 0; - - thresholdset = FixedAngle(((mxspeed + mstartangle)%360)*FRACUNIT)>>ANGLETOFINESHIFT; + thresholdset = FixedAngle(mxspeed*FRACUNIT)>>ANGLETOFINESHIFT; if (hazard) // outermost mace { - spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, macetype); - P_SetTarget(&spawnee->target, mobj); - - spawnee->movecount = movecountset; - spawnee->threshold = thresholdset; - spawnee->reactiontime = radiusfactor*(mlength+1); + firsttype = macetype; + mlength++; } - else if (mlength) // outermost link + else + firsttype = chainlink; + + if (mlength) // outermost mace/link { - spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, chainlink); + spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, firsttype); P_SetTarget(&spawnee->target, mobj); - spawnee->movecount = movecountset; spawnee->threshold = thresholdset; spawnee->reactiontime = radiusfactor*(mlength--); @@ -9880,7 +9876,6 @@ ML_NOCLIMB : Direction not controllable spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, chainlink); P_SetTarget(&spawnee->target, mobj); - spawnee->movecount = movecountset; spawnee->threshold = thresholdset; spawnee->reactiontime = radiusfactor*(mlength--); }