diff --git a/src/p_acs.cpp b/src/p_acs.cpp index bca6ac62be..83146b7437 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -5872,6 +5872,8 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) const char *statename = argCount > 6 ? FBehavior::StaticLookupString(args[6]) : ""; bool exact = argCount > 7 ? !!args[7] : false; fixed_t heightoffset = argCount > 8 ? args[8] : 0; + fixed_t radiusoffset = argCount > 9 ? args[9] : 0; + fixed_t pitch = argCount > 10 ? args[10] : 0; FState *state = argCount > 6 ? activator->GetClass()->ActorInfo->FindStateByString(statename, exact) : 0; @@ -5889,7 +5891,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) if (!reference) return false; - if (P_Thing_Warp(activator, reference, xofs, yofs, zofs, angle, flags, heightoffset)) + if (P_Thing_Warp(activator, reference, xofs, yofs, zofs, angle, flags, heightoffset, radiusoffset, pitch)) { if (state && argCount > 6) { diff --git a/src/p_local.h b/src/p_local.h index a3df41f219..11e6678c1a 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -176,7 +176,7 @@ 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, fixed_t heightoffset); +int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags, fixed_t heightoffset, fixed_t radiusoffset, angle_t pitch); enum WARPF { @@ -198,6 +198,8 @@ enum WARPF WARPF_MOVEPTR = 0x1000, WARPF_USEPTR = 0x2000, WARPF_USETID = 0x2000, + WARPF_COPYVELOCITY = 0x4000, + WARPF_COPYPITCH = 0x8000, }; diff --git a/src/p_things.cpp b/src/p_things.cpp index b7e3f058b8..7e38a3c68f 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -680,7 +680,7 @@ void InitSpawnablesFromMapinfo() } -int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags, fixed_t heightoffset) +int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t zofs, angle_t angle, int flags, fixed_t heightoffset, fixed_t radiusoffset, angle_t pitch) { if (flags & WARPF_MOVEPTR) { @@ -692,25 +692,27 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, fixed_t oldx = caller->x; fixed_t oldy = caller->y; fixed_t oldz = caller->z; - zofs += FixedMul(reference->height, heightoffset); - + if (!(flags & WARPF_ABSOLUTEANGLE)) { angle += (flags & WARPF_USECALLERANGLE) ? caller->angle : reference->angle; } + + const fixed_t rad = FixedMul(radiusoffset, reference->radius); + const angle_t fineangle = angle >> ANGLETOFINESHIFT; + 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]); } @@ -722,15 +724,16 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, // assigning position again with. // extra unlink, link and environment calculation caller->SetOrigin( - reference->x + xofs, - reference->y + yofs, - reference->floorz + zofs); + reference->x + xofs + FixedMul(rad, finecosine[fineangle]), + reference->y + yofs + FixedMul(rad, finesine[fineangle]), + reference->z); + caller->z = caller->floorz + zofs; } else { caller->SetOrigin( - reference->x + xofs, - reference->y + yofs, + reference->x + xofs + FixedMul(rad, finecosine[fineangle]), + reference->y + yofs + FixedMul(rad, finesine[fineangle]), reference->z + zofs); } } @@ -738,11 +741,12 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, { if (flags & WARPF_TOFLOOR) { - caller->SetOrigin(xofs, yofs, caller->floorz + zofs); + caller->SetOrigin(xofs + FixedMul(rad, finecosine[fineangle]), yofs + FixedMul(rad, finesine[fineangle]), zofs); + caller->z = caller->floorz + zofs; } else { - caller->SetOrigin(xofs, yofs, zofs); + caller->SetOrigin(xofs + FixedMul(rad, finecosine[fineangle]), yofs + FixedMul(rad, finesine[fineangle]), zofs); } } @@ -756,6 +760,18 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, { caller->angle = angle; + if (flags & WARPF_COPYPITCH) + caller->SetPitch(reference->pitch, false); + + if (pitch) + caller->SetPitch(caller->pitch + pitch, false); + + if (flags & WARPF_COPYVELOCITY) + { + caller->velx = reference->velx; + caller->vely = reference->vely; + caller->velz = reference->velz; + } if (flags & WARPF_STOP) { caller->velx = 0; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 9b451d40b9..60a2318b4e 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -4675,7 +4675,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) { - ACTION_PARAM_START(8); + ACTION_PARAM_START(10); ACTION_PARAM_INT(destination_selector, 0); ACTION_PARAM_FIXED(xofs, 1); @@ -4684,7 +4684,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) ACTION_PARAM_ANGLE(angle, 4); ACTION_PARAM_INT(flags, 5); ACTION_PARAM_STATE(success_state, 6); - ACTION_PARAM_FIXED(heightoffset,7) + ACTION_PARAM_FIXED(heightoffset, 7); + ACTION_PARAM_FIXED(radiusoffset, 8); + ACTION_PARAM_ANGLE(pitch, 9); AActor *reference; @@ -4704,7 +4706,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) return; } - if (P_Thing_Warp(self, reference, xofs, yofs, zofs, angle, flags, heightoffset)) + if (P_Thing_Warp(self, reference, xofs, yofs, zofs, angle, flags, heightoffset, radiusoffset, pitch)) { if (success_state) { diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index d44dd4627c..7dc89f2015 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -249,7 +249,7 @@ ACTOR Actor native //: Thinker action native A_PlayerSkinCheck(state label); action native A_BasicAttack(int meleedamage, sound meleesound, class missiletype, float missileheight); action native A_Teleport(state teleportstate = "", class targettype = "BossSpot", class fogtype = "TeleportFog", int flags = 0, float mindist = 0, float maxdist = 0, int ptr = AAPTR_DEFAULT); - action native A_Warp(int ptr_destination, float xofs = 0, float yofs = 0, float zofs = 0, float angle = 0, int flags = 0, state success_state = "", float heightoffset = 0); + action native A_Warp(int ptr_destination, float xofs = 0, float yofs = 0, float zofs = 0, float angle = 0, int flags = 0, state success_state = "", float heightoffset = 0, float radiusoffset = 0, float pitch = 0); action native A_ThrowGrenade(class itemtype, float zheight = 0, float xyvel = 0, float zvel = 0, bool useammo = true); action native A_Weave(int xspeed, int yspeed, float xdist, float ydist); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 31014eb1e0..7f8fbc09e2 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -362,6 +362,8 @@ Const Int WARPF_ABSOLUTEPOSITION = 0x400; Const Int WARPF_BOB = 0x800; Const Int WARPF_MOVEPTR = 0x1000; Const Int WARPF_USETID = 0x2000; +Const Int WARPF_COPYVELOCITY = 0x4000; +Const Int WARPF_COPYPITCH = 0x8000; // flags for A_SetPitch/SetAngle/SetRoll const int SPF_FORCECLAMP = 1;