diff --git a/src/p_acs.cpp b/src/p_acs.cpp index e63cfb087..1f56607e5 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -132,28 +132,6 @@ enum ARMORINFO_ACTUALSAVEAMOUNT, }; -// [ZK] Warp -enum -{ - WARPF_ABSOLUTEOFFSET = 0x1, - WARPF_ABSOLUTEANGLE = 0x2, - WARPF_USECALLERANGLE = 0x4, - - WARPF_NOCHECKPOSITION = 0x8, - - WARPF_INTERPOLATE = 0x10, - WARPF_WARPINTERPOLATION = 0x20, - WARPF_COPYINTERPOLATION = 0x40, - - WARPF_STOP = 0x80, - WARPF_TOFLOOR = 0x100, - WARPF_TESTONLY = 0x200, - WARPF_ABSOLUTEPOSITION = 0x400, - WARPF_BOB = 0x800, - WARPF_MOVEPTR = 0x1000, - WARPF_USEPTR = 0x2000, -}; - struct CallReturn { CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, ACSLocalArrays *arrays, bool discard, unsigned int runaway) @@ -5902,136 +5880,15 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) if (!reference) return false; - AActor *caller = activator; - - if (flags & WARPF_MOVEPTR) + if (P_Thing_Warp(activator, reference, xofs, yofs, zofs, angle, flags)) { - AActor *temp = reference; - reference = caller; - caller = temp; - } - - fixed_t oldx = caller->x; - fixed_t oldy = caller->y; - fixed_t oldz = caller->z; - - if (!(flags & WARPF_ABSOLUTEANGLE)) - { - angle += (flags & WARPF_USECALLERANGLE) ? caller->angle : reference->angle; - } - if (!(flags & WARPF_ABSOLUTEPOSITION)) - { - if (!(flags & WARPF_ABSOLUTEOFFSET)) - { - angle_t fineangle = angle >> ANGLETOFINESHIFT; - fixed_t xofs1 = xofs; - - // (borrowed from A_SpawnItemEx, assumed workable) - // in relative mode negative y values mean 'left' and positive ones mean 'right' - // This is the inverse orientation of the absolute mode! - - xofs = FixedMul(xofs1, finecosine[fineangle]) + FixedMul(yofs, finesine[fineangle]); - yofs = FixedMul(xofs1, finesine[fineangle]) - FixedMul(yofs, finecosine[fineangle]); - } - - if (flags & WARPF_TOFLOOR) - { - // set correct xy - - caller->SetOrigin( - reference->x + xofs, - reference->y + yofs, - reference->z); - - // now the caller's floorz should be appropriate for the assigned xy-position - // assigning position again with - - if (zofs) - { - // extra unlink, link and environment calculation - caller->SetOrigin( - caller->x, - caller->y, - caller->floorz + zofs); - } - else - { - // if there is no offset, there should be no ill effect from moving down to the already defined floor - - // A_Teleport does the same thing anyway - caller->z = caller->floorz; - } - } - else - { - caller->SetOrigin( - reference->x + xofs, - reference->y + yofs, - reference->z + zofs); - } - } - else // [MC] The idea behind "absolute" is meant to be "absolute". Override everything, just like A_SpawnItemEx's. - { - if (flags & WARPF_TOFLOOR) - { - caller->SetOrigin(xofs, yofs, caller->floorz + zofs); - } - else - { - caller->SetOrigin(xofs, yofs, zofs); - } - } - - if ((flags & WARPF_NOCHECKPOSITION) || P_TestMobjLocation(caller)) - { - if (flags & WARPF_TESTONLY) - { - caller->SetOrigin(oldx, oldy, oldz); - } - else - { - caller->angle = angle; - - if (flags & WARPF_STOP) - { - caller->velx = 0; - caller->vely = 0; - caller->velz = 0; - } - - if (flags & WARPF_WARPINTERPOLATION) - { - caller->PrevX += caller->x - oldx; - caller->PrevY += caller->y - oldy; - caller->PrevZ += caller->z - oldz; - } - else if (flags & WARPF_COPYINTERPOLATION) - { - caller->PrevX = caller->x + reference->PrevX - reference->x; - caller->PrevY = caller->y + reference->PrevY - reference->y; - caller->PrevZ = caller->z + reference->PrevZ - reference->z; - } - else if (flags & WARPF_INTERPOLATE) - { - caller->PrevX = caller->x; - caller->PrevY = caller->y; - caller->PrevZ = caller->z; - } - } - - if (state && argCount > 7) + if (state && argCount > 6) { activator->SetState(state); } - return true; } - else - { - caller->SetOrigin(oldx, oldy, oldz); - return false; - } - break; + return false; } default: diff --git a/src/p_local.h b/src/p_local.h index 686e0ee13..691d66245 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -176,6 +176,30 @@ bool P_Thing_Raise(AActor *thing, AActor *raiser); bool P_Thing_CanRaise(AActor *thing); const PClass *P_GetSpawnableType(int spawnnum); void InitSpawnablesFromMapinfo(); +int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags); + +enum WARPF +{ + WARPF_ABSOLUTEOFFSET = 0x1, + WARPF_ABSOLUTEANGLE = 0x2, + WARPF_USECALLERANGLE = 0x4, + + WARPF_NOCHECKPOSITION = 0x8, + + WARPF_INTERPOLATE = 0x10, + WARPF_WARPINTERPOLATION = 0x20, + WARPF_COPYINTERPOLATION = 0x40, + + WARPF_STOP = 0x80, + WARPF_TOFLOOR = 0x100, + WARPF_TESTONLY = 0x200, + WARPF_ABSOLUTEPOSITION = 0x400, + WARPF_BOB = 0x800, + WARPF_MOVEPTR = 0x1000, + WARPF_USEPTR = 0x2000, +}; + + // // P_MAPUTL diff --git a/src/p_things.cpp b/src/p_things.cpp index 632f53bc3..799e72893 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -678,3 +678,130 @@ void InitSpawnablesFromMapinfo() InitClassMap(SpawnableThings, SpawnablesFromMapinfo); InitClassMap(StrifeTypes, ConversationIDsFromMapinfo); } + + +int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags) +{ + if (flags & WARPF_MOVEPTR) + { + AActor *temp = reference; + reference = caller; + caller = temp; + } + + fixed_t oldx = caller->x; + fixed_t oldy = caller->y; + fixed_t oldz = caller->z; + + if (!(flags & WARPF_ABSOLUTEANGLE)) + { + angle += (flags & WARPF_USECALLERANGLE) ? caller->angle : reference->angle; + } + if (!(flags & WARPF_ABSOLUTEPOSITION)) + { + if (!(flags & WARPF_ABSOLUTEOFFSET)) + { + angle_t fineangle = angle >> ANGLETOFINESHIFT; + fixed_t xofs1 = xofs; + + // (borrowed from A_SpawnItemEx, assumed workable) + // in relative mode negative y values mean 'left' and positive ones mean 'right' + // This is the inverse orientation of the absolute mode! + + xofs = FixedMul(xofs1, finecosine[fineangle]) + FixedMul(yofs, finesine[fineangle]); + yofs = FixedMul(xofs1, finesine[fineangle]) - FixedMul(yofs, finecosine[fineangle]); + } + + if (flags & WARPF_TOFLOOR) + { + // set correct xy + + caller->SetOrigin( + reference->x + xofs, + reference->y + yofs, + reference->z); + + // now the caller's floorz should be appropriate for the assigned xy-position + // assigning position again with + + if (zofs) + { + // extra unlink, link and environment calculation + caller->SetOrigin( + caller->x, + caller->y, + caller->floorz + zofs); + } + else + { + // if there is no offset, there should be no ill effect from moving down to the already defined floor + + // A_Teleport does the same thing anyway + caller->z = caller->floorz; + } + } + else + { + caller->SetOrigin( + reference->x + xofs, + reference->y + yofs, + reference->z + zofs); + } + } + else // [MC] The idea behind "absolute" is meant to be "absolute". Override everything, just like A_SpawnItemEx's. + { + if (flags & WARPF_TOFLOOR) + { + caller->SetOrigin(xofs, yofs, caller->floorz + zofs); + } + else + { + caller->SetOrigin(xofs, yofs, zofs); + } + } + + if ((flags & WARPF_NOCHECKPOSITION) || P_TestMobjLocation(caller)) + { + if (flags & WARPF_TESTONLY) + { + caller->SetOrigin(oldx, oldy, oldz); + } + else + { + caller->angle = angle; + + if (flags & WARPF_STOP) + { + caller->velx = 0; + caller->vely = 0; + caller->velz = 0; + } + + if (flags & WARPF_WARPINTERPOLATION) + { + caller->PrevX += caller->x - oldx; + caller->PrevY += caller->y - oldy; + caller->PrevZ += caller->z - oldz; + } + else if (flags & WARPF_COPYINTERPOLATION) + { + caller->PrevX = caller->x + reference->PrevX - reference->x; + caller->PrevY = caller->y + reference->PrevY - reference->y; + caller->PrevZ = caller->z + reference->PrevZ - reference->z; + } + else if (!(flags & WARPF_INTERPOLATE)) + { + caller->PrevX = caller->x; + caller->PrevY = caller->y; + caller->PrevZ = caller->z; + } + if ((flags & WARPF_BOB) && (reference->flags2 & MF2_FLOATBOB)) + { + caller->z += reference->GetBobOffset(); + } + } + return true; + } + caller->SetOrigin(oldx, oldy, oldz); + return false; +} \ No newline at end of file diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 7435bc6fe..733572a04 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -4653,26 +4653,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) // //========================================================================== -enum WARPF -{ - WARPF_ABSOLUTEOFFSET = 0x1, - WARPF_ABSOLUTEANGLE = 0x2, - WARPF_USECALLERANGLE = 0x4, - - WARPF_NOCHECKPOSITION = 0x8, - - WARPF_INTERPOLATE = 0x10, - WARPF_WARPINTERPOLATION = 0x20, - WARPF_COPYINTERPOLATION = 0x40, - - WARPF_STOP = 0x80, - WARPF_TOFLOOR = 0x100, - WARPF_TESTONLY = 0x200, - WARPF_ABSOLUTEPOSITION = 0x400, - WARPF_BOB = 0x800, - WARPF_MOVEPTR = 0x1000, -}; - DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) { ACTION_PARAM_START(7); @@ -4694,130 +4674,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) return; } - AActor *caller = self; - - if (flags & WARPF_MOVEPTR) + if (P_Thing_Warp(self, reference, xofs, yofs, zofs, angle, flags)) { - AActor *temp = reference; - reference = caller; - caller = temp; - } - - fixed_t oldx = caller->x; - fixed_t oldy = caller->y; - fixed_t oldz = caller->z; - - if (!(flags & WARPF_ABSOLUTEANGLE)) - { - angle += (flags & WARPF_USECALLERANGLE) ? caller->angle : reference->angle; - } - if (!(flags & WARPF_ABSOLUTEPOSITION)) - { - if (!(flags & WARPF_ABSOLUTEOFFSET)) - { - angle_t fineangle = angle >> ANGLETOFINESHIFT; - fixed_t xofs1 = xofs; - - // (borrowed from A_SpawnItemEx, assumed workable) - // in relative mode negative y values mean 'left' and positive ones mean 'right' - // This is the inverse orientation of the absolute mode! - - xofs = FixedMul(xofs1, finecosine[fineangle]) + FixedMul(yofs, finesine[fineangle]); - yofs = FixedMul(xofs1, finesine[fineangle]) - FixedMul(yofs, finecosine[fineangle]); - } - - if (flags & WARPF_TOFLOOR) - { - // set correct xy - - caller->SetOrigin( - reference->x + xofs, - reference->y + yofs, - reference->z); - - // now the caller's floorz should be appropriate for the assigned xy-position - // assigning position again with - - if (zofs) - { - // extra unlink, link and environment calculation - caller->SetOrigin( - caller->x, - caller->y, - caller->floorz + zofs); - } - else - { - // if there is no offset, there should be no ill effect from moving down to the - // already identified floor - - // A_Teleport does the same thing anyway - caller->z = caller->floorz; - } - } - else - { - caller->SetOrigin( - reference->x + xofs, - reference->y + yofs, - reference->z + zofs); - } - } - else //[MC] The idea behind "absolute" is meant to be "absolute". Override everything, just like A_SpawnItemEx's. - { - if (flags & WARPF_TOFLOOR) - { - caller->SetOrigin(xofs, yofs, caller->floorz + zofs); - } - else - { - caller->SetOrigin(xofs, yofs, zofs); - } - } - - if ((flags & WARPF_NOCHECKPOSITION) || P_TestMobjLocation(caller)) - { - if (flags & WARPF_TESTONLY) - { - caller->SetOrigin(oldx, oldy, oldz); - } - else - { - caller->angle = angle; - - if (flags & WARPF_STOP) - { - caller->velx = 0; - caller->vely = 0; - caller->velz = 0; - } - - if (flags & WARPF_WARPINTERPOLATION) - { - caller->PrevX += caller->x - oldx; - caller->PrevY += caller->y - oldy; - caller->PrevZ += caller->z - oldz; - } - else if (flags & WARPF_COPYINTERPOLATION) - { - caller->PrevX = caller->x + reference->PrevX - reference->x; - caller->PrevY = caller->y + reference->PrevY - reference->y; - caller->PrevZ = caller->z + reference->PrevZ - reference->z; - } - else if (!(flags & WARPF_INTERPOLATE)) - { - caller->PrevX = caller->x; - caller->PrevY = caller->y; - caller->PrevZ = caller->z; - } - - if ((flags & WARPF_BOB) && (reference->flags2 & MF2_FLOATBOB)) - { - caller->z += reference->GetBobOffset(); - } - } - - if (success_state) { ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains! @@ -4830,7 +4688,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) } else { - caller->SetOrigin(oldx, oldy, oldz); ACTION_SET_RESULT(false); }