diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 4233bb38f..d41ecf3a9 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,12 @@ -May 11, 2009 +May 11, 2009 (Changes by Graf Zahl) +- Fixed: Some missile spawning functions ignored the FastSpeed setting. +- Fixed: P_CheckSwitchRange tried to access a line's backsector without + checking if it is valid. +- Fixed: Fast projectile could not be frozen by the Time freezer. +- Added several new ACS functions: GetActorMomX/Y/Z, GetActorViewHeight, + SetActivator, SetActivatorToTarget. + +May 11, 2009 - Added Species property for actors and separated Hexen's Demon1 and Demon2 into different species. diff --git a/src/g_shared/a_fastprojectile.cpp b/src/g_shared/a_fastprojectile.cpp index ec92a1eeb..fecf0c2f0 100644 --- a/src/g_shared/a_fastprojectile.cpp +++ b/src/g_shared/a_fastprojectile.cpp @@ -1,6 +1,7 @@ #include "a_sharedglobal.h" #include "p_local.h" +#include "g_level.h" IMPLEMENT_CLASS(AFastProjectile) @@ -26,6 +27,16 @@ void AFastProjectile::Tick () PrevY = y; PrevZ = z; + if (!(flags5 & MF5_NOTIMEFREEZE)) + { + //Added by MC: Freeze mode. + if (bglobal.freeze || level.flags2 & LEVEL2_FROZEN) + { + return; + } + } + + // [RH] Ripping is a little different than it was in Hexen FCheckPosition tm(!!(flags2 & MF2_RIP)); diff --git a/src/p_acs.cpp b/src/p_acs.cpp index edd90bf17..a8fcbd9b2 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -2781,14 +2781,20 @@ int DLevelScript::DoClassifyActor(int tid) enum EACSFunctions { - GetLineUDMFInt=1, - GetLineUDMFFixed, - GetThingUDMFInt, - GetThingUDMFFixed, - GetSectorUDMFInt, - GetSectorUDMFFixed, - GetSideUDMFInt, - GetSideUDMFFixed, + ACSF_GetLineUDMFInt=1, + ACSF_GetLineUDMFFixed, + ACSF_GetThingUDMFInt, + ACSF_GetThingUDMFFixed, + ACSF_GetSectorUDMFInt, + ACSF_GetSectorUDMFFixed, + ACSF_GetSideUDMFInt, + ACSF_GetSideUDMFFixed, + ACSF_GetActorMomX, + ACSF_GetActorMomY, + ACSF_GetActorMomZ, + ACSF_SetActivator, + ACSF_SetActivatorToTarget, + ACSF_GetActorViewHeight, }; int DLevelScript::SideFromID(int id, int side) @@ -2825,23 +2831,69 @@ int DLevelScript::LineFromID(int id) int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) { + AActor *actor; switch(funcIndex) { - case GetLineUDMFInt: + case ACSF_GetLineUDMFInt: return GetUDMFInt(UDMF_Line, LineFromID(args[0]), FBehavior::StaticLookupString(args[1])); - case GetLineUDMFFixed: + + case ACSF_GetLineUDMFFixed: return GetUDMFFixed(UDMF_Line, LineFromID(args[0]), FBehavior::StaticLookupString(args[1])); - case GetThingUDMFInt: - case GetThingUDMFFixed: + + case ACSF_GetThingUDMFInt: + case ACSF_GetThingUDMFFixed: return 0; // Not implemented yet - case GetSectorUDMFInt: + + case ACSF_GetSectorUDMFInt: return GetUDMFInt(UDMF_Sector, P_FindSectorFromTag(args[0], -1), FBehavior::StaticLookupString(args[1])); - case GetSectorUDMFFixed: + + case ACSF_GetSectorUDMFFixed: return GetUDMFFixed(UDMF_Sector, P_FindSectorFromTag(args[0], -1), FBehavior::StaticLookupString(args[1])); - case GetSideUDMFInt: + + case ACSF_GetSideUDMFInt: return GetUDMFInt(UDMF_Side, SideFromID(args[0], args[1]), FBehavior::StaticLookupString(args[2])); - case GetSideUDMFFixed: + + case ACSF_GetSideUDMFFixed: return GetUDMFFixed(UDMF_Side, SideFromID(args[0], args[1]), FBehavior::StaticLookupString(args[2])); + + case ACSF_GetActorMomX: + actor = SingleActorFromTID(args[0], activator); + return actor != NULL? actor->momx : 0; + + case ACSF_GetActorMomY: + actor = SingleActorFromTID(args[0], activator); + return actor != NULL? actor->momy : 0; + + case ACSF_GetActorMomZ: + actor = SingleActorFromTID(args[0], activator); + return actor != NULL? actor->momz : 0; + + case ACSF_SetActivator: + activator = SingleActorFromTID(args[0], NULL); + return activator != NULL; + + case ACSF_SetActivatorToTarget: + actor = SingleActorFromTID(args[0], NULL); + if (actor != NULL) actor = actor->target; + if (actor != NULL) activator = actor; + return activator != NULL; + + case ACSF_GetActorViewHeight: + actor = SingleActorFromTID(args[0], NULL); + if (actor != NULL) + { + if (actor->player != NULL) + { + return actor->player->mo->ViewHeight + actor->player->crouchviewdelta; + } + else + { + return actor->GetClass()->Meta.GetMetaFixed(AMETA_CameraHeight, actor->height/2); + } + } + else return 0; + + default: break; } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 2a9d9c802..50368f48c 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4636,6 +4636,15 @@ void P_PlaySpawnSound(AActor *missile, AActor *spawner) } } +static fixed_t GetDefaultSpeed(const PClass *type) +{ + if (type == NULL) return 0; + else if (G_SkillProperty(SKILLP_FastMonsters)) + return type->Meta.GetMetaFixed(AMETA_FastSpeed, GetDefaultByType(type)->Speed); + else + return GetDefaultByType(type)->Speed; +} + static AActor * SpawnMissile (const PClass *type, fixed_t x, fixed_t y, fixed_t z) { AActor *th = Spawn (type, x, y, z, ALLOW_REPLACE); @@ -4750,14 +4759,14 @@ AActor *P_SpawnMissileAngle (AActor *source, const PClass *type, angle_t angle, fixed_t momz) { return P_SpawnMissileAngleZSpeed (source, source->z + 32*FRACUNIT, - type, angle, momz, GetDefaultByType (type)->Speed); + type, angle, momz, GetDefaultSpeed (type)); } AActor *P_SpawnMissileAngleZ (AActor *source, fixed_t z, const PClass *type, angle_t angle, fixed_t momz) { return P_SpawnMissileAngleZSpeed (source, z, type, angle, momz, - GetDefaultByType (type)->Speed); + GetDefaultSpeed (type)); } AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, const PClass *type) @@ -4774,7 +4783,7 @@ AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, const PCl an += pr_spawnmissile.Random2() << 20; } dist = P_AproxDistance (dest->x - source->x, dest->y - source->y); - speed = GetDefaultByType (type)->Speed; + speed = GetDefaultSpeed (type); dist /= speed; momz = dist != 0 ? (dest->z - source->z)/dist : speed; return P_SpawnMissileAngleZSpeed (source, z, type, an, momz, speed); diff --git a/src/p_switch.cpp b/src/p_switch.cpp index 1d31e8c38..a011df11e 100644 --- a/src/p_switch.cpp +++ b/src/p_switch.cpp @@ -464,13 +464,13 @@ static int TryFindSwitch (side_t *side, int Where) // bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno) { - if (line->sidenum[0] == NO_SIDE) return true; + // Activated from an empty side -> always succeed + if (line->sidenum[sideno] == NO_SIDE) return true; fixed_t checktop; fixed_t checkbot; side_t *side = &sides[line->sidenum[sideno]]; sector_t *front = sides[line->sidenum[sideno]].sector; - sector_t *back = sides[line->sidenum[1-sideno]].sector; FLineOpening open; // 3DMIDTEX forces CHECKSWITCHRANGE because otherwise it might cause problems. @@ -495,8 +495,8 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno) if (line->sidenum[1] == NO_SIDE) { onesided: - fixed_t sectorc = line->frontsector->ceilingplane.ZatPoint(checkx, checky); - fixed_t sectorf = line->frontsector->floorplane.ZatPoint(checkx, checky); + fixed_t sectorc = front->ceilingplane.ZatPoint(checkx, checky); + fixed_t sectorf = front->floorplane.ZatPoint(checkx, checky); return (user->z + user->height >= sectorf && user->z <= sectorc); }