- 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.


SVN r1578 (trunk)
This commit is contained in:
Christoph Oelckers 2009-05-11 22:16:41 +00:00
parent 571d28281b
commit 912abc144e
5 changed files with 104 additions and 24 deletions

View file

@ -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 - Added Species property for actors and separated Hexen's Demon1 and Demon2
into different species. into different species.

View file

@ -1,6 +1,7 @@
#include "a_sharedglobal.h" #include "a_sharedglobal.h"
#include "p_local.h" #include "p_local.h"
#include "g_level.h"
IMPLEMENT_CLASS(AFastProjectile) IMPLEMENT_CLASS(AFastProjectile)
@ -26,6 +27,16 @@ void AFastProjectile::Tick ()
PrevY = y; PrevY = y;
PrevZ = z; 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 // [RH] Ripping is a little different than it was in Hexen
FCheckPosition tm(!!(flags2 & MF2_RIP)); FCheckPosition tm(!!(flags2 & MF2_RIP));

View file

@ -2781,14 +2781,20 @@ int DLevelScript::DoClassifyActor(int tid)
enum EACSFunctions enum EACSFunctions
{ {
GetLineUDMFInt=1, ACSF_GetLineUDMFInt=1,
GetLineUDMFFixed, ACSF_GetLineUDMFFixed,
GetThingUDMFInt, ACSF_GetThingUDMFInt,
GetThingUDMFFixed, ACSF_GetThingUDMFFixed,
GetSectorUDMFInt, ACSF_GetSectorUDMFInt,
GetSectorUDMFFixed, ACSF_GetSectorUDMFFixed,
GetSideUDMFInt, ACSF_GetSideUDMFInt,
GetSideUDMFFixed, ACSF_GetSideUDMFFixed,
ACSF_GetActorMomX,
ACSF_GetActorMomY,
ACSF_GetActorMomZ,
ACSF_SetActivator,
ACSF_SetActivatorToTarget,
ACSF_GetActorViewHeight,
}; };
int DLevelScript::SideFromID(int id, int side) 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) int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
{ {
AActor *actor;
switch(funcIndex) switch(funcIndex)
{ {
case GetLineUDMFInt: case ACSF_GetLineUDMFInt:
return GetUDMFInt(UDMF_Line, LineFromID(args[0]), FBehavior::StaticLookupString(args[1])); 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])); 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 return 0; // Not implemented yet
case GetSectorUDMFInt:
case ACSF_GetSectorUDMFInt:
return GetUDMFInt(UDMF_Sector, P_FindSectorFromTag(args[0], -1), FBehavior::StaticLookupString(args[1])); 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])); 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])); 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])); 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: default:
break; break;
} }

View file

@ -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) static AActor * SpawnMissile (const PClass *type, fixed_t x, fixed_t y, fixed_t z)
{ {
AActor *th = Spawn (type, x, y, z, ALLOW_REPLACE); 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) angle_t angle, fixed_t momz)
{ {
return P_SpawnMissileAngleZSpeed (source, source->z + 32*FRACUNIT, 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, AActor *P_SpawnMissileAngleZ (AActor *source, fixed_t z,
const PClass *type, angle_t angle, fixed_t momz) const PClass *type, angle_t angle, fixed_t momz)
{ {
return P_SpawnMissileAngleZSpeed (source, z, type, angle, 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) 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; an += pr_spawnmissile.Random2() << 20;
} }
dist = P_AproxDistance (dest->x - source->x, dest->y - source->y); dist = P_AproxDistance (dest->x - source->x, dest->y - source->y);
speed = GetDefaultByType (type)->Speed; speed = GetDefaultSpeed (type);
dist /= speed; dist /= speed;
momz = dist != 0 ? (dest->z - source->z)/dist : speed; momz = dist != 0 ? (dest->z - source->z)/dist : speed;
return P_SpawnMissileAngleZSpeed (source, z, type, an, momz, speed); return P_SpawnMissileAngleZSpeed (source, z, type, an, momz, speed);

View file

@ -464,13 +464,13 @@ static int TryFindSwitch (side_t *side, int Where)
// //
bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno) 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 checktop;
fixed_t checkbot; fixed_t checkbot;
side_t *side = &sides[line->sidenum[sideno]]; side_t *side = &sides[line->sidenum[sideno]];
sector_t *front = sides[line->sidenum[sideno]].sector; sector_t *front = sides[line->sidenum[sideno]].sector;
sector_t *back = sides[line->sidenum[1-sideno]].sector;
FLineOpening open; FLineOpening open;
// 3DMIDTEX forces CHECKSWITCHRANGE because otherwise it might cause problems. // 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) if (line->sidenum[1] == NO_SIDE)
{ {
onesided: onesided:
fixed_t sectorc = line->frontsector->ceilingplane.ZatPoint(checkx, checky); fixed_t sectorc = front->ceilingplane.ZatPoint(checkx, checky);
fixed_t sectorf = line->frontsector->floorplane.ZatPoint(checkx, checky); fixed_t sectorf = front->floorplane.ZatPoint(checkx, checky);
return (user->z + user->height >= sectorf && user->z <= sectorc); return (user->z + user->height >= sectorf && user->z <= sectorc);
} }