diff --git a/src/keysections.cpp b/src/keysections.cpp index 8d23c9582..1ae87958c 100644 --- a/src/keysections.cpp +++ b/src/keysections.cpp @@ -177,6 +177,11 @@ void D_LoadWadSettings () { cmd[i] = conf[i]; } + if (i == 0) + { + conf++; + continue; + } cmd[i] = 0; conf += i; if (*conf == '\n') diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 170c65021..ab9c0aee7 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -149,7 +149,8 @@ void cht_DoCheat (player_t *player, int cheat) case CHT_FLY: if (player->mo != NULL) { - if ((player->mo->flags7 ^= MF7_FLYCHEAT) != 0) + player->mo->flags7 ^= MF7_FLYCHEAT; + if (player->mo->flags7 & MF7_FLYCHEAT) { player->mo->flags |= MF_NOGRAVITY; player->mo->flags2 |= MF2_FLY; diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 2cc9f958f..750b8f09d 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -4422,6 +4422,8 @@ enum EACSFunctions ACSF_ChangeActorRoll, ACSF_GetActorRoll, ACSF_QuakeEx, + ACSF_Warp, // 92 + /* Zandronum's - these must be skipped when we reach 99! -100:ResetMap(0), -101 : PlayerIsSpectator(1), @@ -5848,6 +5850,45 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) case ACSF_GetActorRoll: actor = SingleActorFromTID(args[0], activator); return actor != NULL? actor->roll >> 16 : 0; + + // [ZK] A_Warp in ACS + case ACSF_Warp: + { + int tid_dest = args[0]; + fixed_t xofs = args[1]; + fixed_t yofs = args[2]; + fixed_t zofs = args[3]; + angle_t angle = args[4]; + int flags = args[5]; + const char *statename = argCount > 6 ? FBehavior::StaticLookupString(args[6]) : ""; + bool exact = argCount > 7 ? !!args[7] : false; + + FState *state = argCount > 6 ? activator->GetClass()->ActorInfo->FindStateByString(statename, exact) : 0; + + AActor *reference; + if((flags & WARPF_USEPTR) && tid_dest != AAPTR_DEFAULT) + { + reference = COPY_AAPTR(activator, tid_dest); + } + else + { + reference = SingleActorFromTID(tid_dest, activator); + } + + // If there is no actor to warp to, fail. + if (!reference) + return false; + + if (P_Thing_Warp(activator, reference, xofs, yofs, zofs, angle, flags)) + { + if (state && argCount > 6) + { + activator->SetState(state); + } + return true; + } + return false; + } default: break; diff --git a/src/p_floor.cpp b/src/p_floor.cpp index 97e23571b..9e7806039 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -727,6 +727,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, floor->m_Type = DFloor::buildStair; //jff 3/31/98 do not leave uninited //jff 2/27/98 fix uninitialized crush field floor->m_Crush = (!usespecials && speed == 4*FRACUNIT) ? 10 : -1; + floor->m_Hexencrush = false; floor->m_ResetCount = reset; // [RH] Tics until reset (0 if never) floor->m_OrgDist = sec->floorplane.d; // [RH] Height to reset to } diff --git a/src/p_local.h b/src/p_local.h index 686e0ee13..0b1c9c7a8 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -176,6 +176,31 @@ 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, + WARPF_USETID = 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 54bbe68d3..e47f4148f 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -4039,7 +4039,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ScaleVelocity) return; } - INTBOOL was_moving = self->velx | self->vely | self->velz; + INTBOOL was_moving = ref->velx | ref->vely | ref->velz; ref->velx = FixedMul(ref->velx, scale); ref->vely = FixedMul(ref->vely, scale); @@ -4061,7 +4061,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ScaleVelocity) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeVelocity) { - ACTION_PARAM_START(4); + ACTION_PARAM_START(5); ACTION_PARAM_FIXED(x, 0); ACTION_PARAM_FIXED(y, 1); ACTION_PARAM_FIXED(z, 2); @@ -4102,7 +4102,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeVelocity) if (was_moving) { - CheckStopped(self); + CheckStopped(ref); } } @@ -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); @@ -4684,8 +4664,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) ACTION_PARAM_ANGLE(angle, 4); ACTION_PARAM_INT(flags, 5); ACTION_PARAM_STATE(success_state, 6); - - AActor *reference = COPY_AAPTR(self, destination_selector); + + AActor *reference; + + if((flags & WARPF_USETID)) + { + reference = SingleActorFromTID(destination_selector, self); + } + else + { + reference = COPY_AAPTR(self, destination_selector); + } //If there is no actor to warp to, fail. if (!reference) @@ -4694,130 +4683,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 +4697,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) } else { - caller->SetOrigin(oldx, oldy, oldz); ACTION_SET_RESULT(false); } @@ -4948,12 +4814,25 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, ACS_NamedTerminate) } +static bool DoCheckSpecies(AActor *mo, FName filterSpecies, bool exclude) +{ + FName actorSpecies = mo->GetSpecies(); + if (filterSpecies == NAME_None) return true; + return exclude ? (actorSpecies != filterSpecies) : (actorSpecies == filterSpecies); +} + +static bool DoCheckClass(AActor *mo, const PClass *filterClass, bool exclude) +{ + const PClass *actorClass = mo->GetClass(); + if (filterClass == NULL) return true; + return exclude ? (actorClass != filterClass) : (actorClass == filterClass); +} //========================================================================== // -// A_RadiusGive +// A_RadiusGive(item, distance, flags, amount, filter, species) // // Uses code roughly similar to A_Explode (but without all the compatibility -// baggage and damage computation code to give an item to all eligible mobjs +// baggage and damage computation code) to give an item to all eligible mobjs // in range. // //========================================================================== @@ -4972,21 +4851,30 @@ enum RadiusGiveFlags RGF_CUBE = 1 << 9, RGF_NOSIGHT = 1 << 10, RGF_MISSILES = 1 << 11, + RGF_INCLUSIVE = 1 << 12, + RGF_ITEMS = 1 << 13, + RGF_KILLED = 1 << 14, + RGF_EXFILTER = 1 << 15, + RGF_EXSPECIES = 1 << 16, + RGF_EITHER = 1 << 17, }; DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive) { - ACTION_PARAM_START(7); + ACTION_PARAM_START(6); ACTION_PARAM_CLASS(item, 0); ACTION_PARAM_FIXED(distance, 1); ACTION_PARAM_INT(flags, 2); ACTION_PARAM_INT(amount, 3); + ACTION_PARAM_CLASS(filter, 4); + ACTION_PARAM_NAME(species, 5); // We need a valid item, valid targets, and a valid range - if (item == NULL || (flags & RGF_MASK) == 0 || distance <= 0) + if (item == NULL || (flags & RGF_MASK) == 0 || !flags || distance <= 0) { return; } + if (amount == 0) { amount = 1; @@ -4997,108 +4885,107 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive) AActor *thing; while ((thing = it.Next())) { - // Don't give to inventory items - if (thing->flags & MF_SPECIAL) + //[MC] Check for a filter, species, and the related exfilter/expecies/either flag(s). + bool filterpass = DoCheckClass(thing, filter, !!(flags & RGF_EXFILTER)), + speciespass = DoCheckSpecies(thing, species, !!(flags & RGF_EXSPECIES)); + + if ((flags & RGF_EITHER) ? (!(filterpass || speciespass)) : (!(filterpass && speciespass))) { - continue; - } - // Avoid giving to self unless requested - if (thing == self && !(flags & RGF_GIVESELF)) - { - continue; - } - // Avoiding special pointers if requested - if (((thing == self->target) && (flags & RGF_NOTARGET)) || - ((thing == self->tracer) && (flags & RGF_NOTRACER)) || - ((thing == self->master) && (flags & RGF_NOMASTER))) - { - continue; - } - // Don't give to dead thing unless requested - if (thing->flags & MF_CORPSE) - { - if (!(flags & RGF_CORPSES)) - { + if (thing != self) //Don't let filter and species obstruct RGF_GIVESELF. continue; - } - } - else if (thing->health <= 0 || thing->flags6 & MF6_KILLED) - { - continue; - } - // Players, monsters, and other shootable objects - if (thing->player) - { - if ((thing->player->mo == thing) && !(flags & RGF_PLAYERS)) - { - continue; - } - if ((thing->player->mo != thing) && !(flags & RGF_VOODOO)) - { - continue; - } - } - else if (thing->flags3 & MF3_ISMONSTER) - { - if (!(flags & RGF_MONSTERS)) - { - continue; - } - } - else if (thing->flags & MF_SHOOTABLE || thing->flags6 & MF6_VULNERABLE) - { - if (!(flags & RGF_OBJECTS)) - { - continue; - } - } - else if (thing->flags & MF_MISSILE) - { - if (!(flags & RGF_MISSILES)) - { - continue; - } - } - else - { - continue; } - if (flags & RGF_CUBE) - { // check if inside a cube - if (fabs((double)thing->x - self->x) > (double)distance || - fabs((double)thing->y - self->y) > (double)distance || - fabs((double)(thing->z + thing->height/2) - (self->z + self->height/2)) > (double)distance) - { + if (thing == self) + { + if (!(flags & RGF_GIVESELF)) continue; - } } - else - { // check if inside a sphere - TVector3 tpos(thing->x, thing->y, thing->z + thing->height/2); - TVector3 spos(self->x, self->y, self->z + self->height/2); - if ((tpos - spos).LengthSquared() > distsquared) - { + + //Check for target, master, and tracer flagging. + bool targetPass = true; + bool masterPass = true; + bool tracerPass = true; + bool ptrPass = false; + if ((thing != self) && (flags & (RGF_NOTARGET | RGF_NOMASTER | RGF_NOTRACER))) + { + if ((thing == self->target) && (flags & RGF_NOTARGET)) + targetPass = false; + if ((thing == self->master) && (flags & RGF_NOMASTER)) + masterPass = false; + if ((thing == self->tracer) && (flags & RGF_NOTRACER)) + tracerPass = false; + + ptrPass = (flags & RGF_INCLUSIVE) ? (targetPass || masterPass || tracerPass) : (targetPass && masterPass && tracerPass); + + //We should not care about what the actor is here. It's safe to abort this actor. + if (!ptrPass) continue; + } + + //Next, actor flag checking. + bool selfPass = !!((flags & RGF_GIVESELF) && thing == self); + bool corpsePass = !!((flags & RGF_CORPSES) && thing->flags & MF_CORPSE); + bool killedPass = !!((flags & RGF_KILLED) && thing->flags6 & MF6_KILLED); + bool monsterPass = !!((flags & RGF_MONSTERS) && thing->flags3 & MF3_ISMONSTER); + bool objectPass = !!((flags & RGF_OBJECTS) && ((thing->flags & MF_SHOOTABLE) || (thing->flags6 & MF6_VULNERABLE))); + bool playerPass = !!((flags & RGF_PLAYERS) && (thing->player != NULL) && (thing->player->mo == thing)); + bool voodooPass = !!((flags & RGF_VOODOO) && (thing->player != NULL) && (thing->player->mo != thing)); + //Self calls priority over the rest of this. + if (!selfPass) + { + //If it's specifically a monster/object/player/voodoo... Can be either or... + if (monsterPass || objectPass || playerPass || voodooPass) + { + //...and is dead, without desire to give to the dead... + if (((thing->health <= 0) && !(corpsePass || killedPass))) + { + //Skip! + continue; + } } } - if ((flags & RGF_NOSIGHT) || P_CheckSight (thing, self, SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY)) - { // OK to give; target is in direct path, or the monster doesn't care about it being in line of sight. - AInventory *gift = static_cast(Spawn (item, 0, 0, 0, NO_REPLACE)); - if (gift->IsKindOf(RUNTIME_CLASS(AHealth))) - { - gift->Amount *= amount; + bool itemPass = !!((flags & RGF_ITEMS) && thing->IsKindOf(RUNTIME_CLASS(AInventory))); + bool missilePass = !!((flags & RGF_MISSILES) && thing->flags & MF_MISSILE); + + if (selfPass || monsterPass || corpsePass || killedPass || itemPass || objectPass || missilePass || playerPass || voodooPass) + { + if (flags & RGF_CUBE) + { // check if inside a cube + if (fabs((double)thing->x - self->x) > (double)distance || + fabs((double)thing->y - self->y) > (double)distance || + fabs((double)(thing->z + thing->height / 2) - (self->z + self->height / 2)) > (double)distance) + { + continue; + } } else - { - gift->Amount = amount; + { // check if inside a sphere + TVector3 tpos(thing->x, thing->y, thing->z + thing->height / 2); + TVector3 spos(self->x, self->y, self->z + self->height / 2); + if ((tpos - spos).LengthSquared() > distsquared) + { + continue; + } } - gift->flags |= MF_DROPPED; - gift->ClearCounters(); - if (!gift->CallTryPickup (thing)) - { - gift->Destroy (); + + if ((flags & RGF_NOSIGHT) || P_CheckSight(thing, self, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)) + { // OK to give; target is in direct path, or the monster doesn't care about it being in line of sight. + AInventory *gift = static_cast(Spawn(item, 0, 0, 0, NO_REPLACE)); + if (gift->IsKindOf(RUNTIME_CLASS(AHealth))) + { + gift->Amount *= amount; + } + else + { + gift->Amount = amount; + } + gift->flags |= MF_DROPPED; + gift->ClearCounters(); + if (!gift->CallTryPickup(thing)) + { + gift->Destroy(); + } } } } @@ -5184,20 +5071,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpeed) ref->Speed = speed; } -static bool DoCheckSpecies(AActor *mo, FName filterSpecies, bool exclude) -{ - FName actorSpecies = mo->GetSpecies(); - if (filterSpecies == NAME_None) return true; - return exclude ? (actorSpecies != filterSpecies) : (actorSpecies == filterSpecies); -} - -static bool DoCheckClass(AActor *mo, const PClass *filterClass, bool exclude) -{ - const PClass *actorClass = mo->GetClass(); - if (filterClass == NULL) return true; - return exclude ? (actorClass != filterClass) : (actorClass == filterClass); -} - //=========================================================================== // // Common A_Damage handler diff --git a/src/win32/i_input.cpp b/src/win32/i_input.cpp index a26ff320e..941fc15de 100644 --- a/src/win32/i_input.cpp +++ b/src/win32/i_input.cpp @@ -110,6 +110,11 @@ #include "rawinput.h" +// Compensate for w32api's lack +#ifndef GET_XBUTTON_WPARAM +#define GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam)) +#endif + #ifdef _DEBUG #define INGAME_PRIORITY_CLASS NORMAL_PRIORITY_CLASS diff --git a/src/win32/i_input.h b/src/win32/i_input.h index b0d409844..c0de97e63 100644 --- a/src/win32/i_input.h +++ b/src/win32/i_input.h @@ -47,6 +47,15 @@ FString I_GetFromClipboard (bool windows_has_no_selection_clipboard); void I_GetEvent(); +enum +{ + INPUT_DIJoy, + INPUT_XInput, + INPUT_RawPS2, + NUM_JOYDEVICES +}; + + #ifdef USE_WINDOWS_DWORD #include "m_joy.h" @@ -121,14 +130,6 @@ public: virtual IJoystickConfig *Rescan() = 0; }; -enum -{ - INPUT_DIJoy, - INPUT_XInput, - INPUT_RawPS2, - NUM_JOYDEVICES -}; - extern FJoystickCollection *JoyDevices[NUM_JOYDEVICES]; void I_StartupMouse(); diff --git a/src/win32/i_xinput.cpp b/src/win32/i_xinput.cpp index 5a02d7af4..3d85f48a0 100644 --- a/src/win32/i_xinput.cpp +++ b/src/win32/i_xinput.cpp @@ -789,6 +789,8 @@ void I_StartupXInput() #else // NO_XINPUT +#include "i_input.h" + void I_StartupXInput() { JoyDevices[INPUT_XInput] = NULL; diff --git a/src/xs_Float.h b/src/xs_Float.h index 19300b2fc..1f57f9205 100644 --- a/src/xs_Float.h +++ b/src/xs_Float.h @@ -209,7 +209,7 @@ finline static uint32 xs_FloorToUInt(real64 val) finline static uint32 xs_CeilToUInt(real64 val) { - return (uint32)xs_CeilToUInt(val); + return (uint32)xs_CeilToInt(val); } finline static uint32 xs_RoundToUInt(real64 val) diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index b7fea4189..6885ad2d6 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -257,7 +257,7 @@ ACTOR Actor native //: Thinker action native A_JumpIfInTargetInventory(class itemtype, int amount, state label, int forward_ptr = AAPTR_DEFAULT); action native A_GiveToTarget(class itemtype, int amount = 0, int forward_ptr = AAPTR_DEFAULT); action native A_TakeFromTarget(class itemtype, int amount = 0, int flags = 0, int forward_ptr = AAPTR_DEFAULT); - action native A_RadiusGive(class itemtype, int distance, int flags, int amount = 0); + action native A_RadiusGive(class itemtype, int distance, int flags, int amount = 0, class filter = "None", name species = "None"); action native A_CountdownArg(int argnum, state targstate = ""); action native A_CustomMeleeAttack(int damage = 0, sound meleesound = "", sound misssound = "", name damagetype = "none", bool bleed = true); action native A_CustomComboAttack(class missiletype, float spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 6612dd9f8..1ee6c96c9 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -224,6 +224,12 @@ enum RGF_CUBE = 1 << 9, RGF_NOSIGHT = 1 << 10, RGF_MISSILES = 1 << 11, + RGF_INCLUSIVE = 1 << 12, + RGF_ITEMS = 1 << 13, + RGF_KILLED = 1 << 14, + RGF_EXFILTER = 1 << 15, + RGF_EXSPECIES = 1 << 16, + RGF_EITHER = 1 << 17, }; // Activation flags @@ -351,6 +357,7 @@ Const Int WAPRF_ABSOLUTEPOSITION = 0x400; Const Int WARPF_ABSOLUTEPOSITION = 0x400; Const Int WARPF_BOB = 0x800; Const Int WARPF_MOVEPTR = 0x1000; +Const Int WARPF_USETID = 0x2000; // flags for A_SetPitch/SetAngle/SetRoll const int SPF_FORCECLAMP = 1;