- scriptified a_thingstoblowup.cpp.

- changed the power crystal floor movement to use DFloor instead of an incomplete in-place hack to ensure that everything is processed properly.
This commit is contained in:
Christoph Oelckers 2016-11-28 21:33:14 +01:00
parent dd5494d848
commit caef5344b0
9 changed files with 194 additions and 174 deletions

View file

@ -863,7 +863,6 @@ set( NOT_COMPILED_SOURCE_FILES
g_hexen/a_spike.cpp
g_strife/a_strifeitems.cpp
g_strife/a_strifeweapons.cpp
g_strife/a_thingstoblowup.cpp
g_shared/sbarinfo_commands.cpp
xlat/xlat_parser.y
xlat_parser.c

View file

@ -26,7 +26,6 @@
// Include all the other Strife stuff here to reduce compile time
#include "a_strifeitems.cpp"
#include "a_strifeweapons.cpp"
#include "a_thingstoblowup.cpp"
// Notes so I don't forget them:
// Strife does some extra stuff in A_Explode if a player caused the explosion. (probably NoiseAlert)
@ -67,47 +66,6 @@ int AForceFieldGuard::TakeSpecialDamage (AActor *inflictor, AActor *source, int
return health;
}
// Kneeling Guy -------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_SetShadow)
{
PARAM_SELF_PROLOGUE(AActor);
self->flags |= MF_STRIFEx8000000|MF_SHADOW;
self->RenderStyle = STYLE_Translucent;
self->Alpha = HR_SHADOW;
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_ClearShadow)
{
PARAM_SELF_PROLOGUE(AActor);
self->flags &= ~(MF_STRIFEx8000000|MF_SHADOW);
self->RenderStyle = STYLE_Normal;
self->Alpha = 1.;
return 0;
}
static FRandom pr_gethurt ("HurtMe!");
DEFINE_ACTION_FUNCTION(AActor, A_GetHurt)
{
PARAM_SELF_PROLOGUE(AActor);
self->flags4 |= MF4_INCOMBAT;
if ((pr_gethurt() % 5) == 0)
{
S_Sound (self, CHAN_VOICE, self->PainSound, 1, ATTN_NORM);
self->health--;
}
if (self->health <= 0)
{
self->CallDie (self->target, self->target);
}
return 0;
}
// Klaxon Warning Light -----------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_TurretLook)

View file

@ -1,121 +0,0 @@
/*
#include "actor.h"
#include "m_random.h"
#include "p_local.h"
#include "c_console.h"
#include "p_enemy.h"
#include "a_action.h"
#include "gstrings.h"
#include "vm.h"
#include "vm.h"
#include "doomstat.h"
*/
static FRandom pr_bang4cloud ("Bang4Cloud");
static FRandom pr_lightout ("LightOut");
DEFINE_ACTION_FUNCTION(AActor, A_Bang4Cloud)
{
PARAM_SELF_PROLOGUE(AActor);
double xo = (pr_bang4cloud.Random2() & 3) * (10. / 64);
double yo = (pr_bang4cloud.Random2() & 3) * (10. / 64);
Spawn("Bang4Cloud", self->Vec3Offset(xo, yo, 0.), ALLOW_REPLACE);
return 0;
}
// -------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_GiveQuestItem)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(questitem);
// Give one of these quest items to every player in the game
if (questitem >= 0 && questitem < (int)countof(QuestItemClasses))
{
for (int i = 0; i < MAXPLAYERS; ++i)
{
if (playeringame[i])
{
AInventory *item = static_cast<AInventory *>(Spawn (QuestItemClasses[questitem - 1]));
if (!item->CallTryPickup (players[i].mo))
{
item->Destroy ();
}
}
}
}
char messageid[64];
mysnprintf(messageid, countof(messageid), "TXT_QUEST_%d", questitem);
const char * name = GStrings[messageid];
if (name != NULL)
{
C_MidPrint (SmallFont, name);
}
return 0;
}
// PowerCrystal -------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AActor, A_ExtraLightOff)
{
PARAM_SELF_PROLOGUE(AActor);
if (self->target != NULL && self->target->player != NULL)
{
self->target->player->extralight = 0;
}
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_Explode512)
{
PARAM_SELF_PROLOGUE(AActor);
P_RadiusAttack (self, self->target, 512, 512, NAME_None, RADF_HURTSOURCE);
if (self->target != NULL && self->target->player != NULL)
{
self->target->player->extralight = 5;
}
P_CheckSplash(self, 512);
// Strife didn't do this next part, but it looks good
self->RenderStyle = STYLE_Add;
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_LightGoesOut)
{
PARAM_SELF_PROLOGUE(AActor);
AActor *foo;
sector_t *sec = self->Sector;
vertex_t *spot;
double newheight;
sec->SetLightLevel(0);
double oldtheight = sec->floorplane.fD();
newheight = sec->FindLowestFloorSurrounding(&spot);
sec->floorplane.setD(sec->floorplane.PointToDist (spot, newheight));
double newtheight = sec->floorplane.fD();
sec->ChangePlaneTexZ(sector_t::floor, newtheight - oldtheight);
sec->CheckPortalPlane(sector_t::floor);
for (int i = 0; i < 8; ++i)
{
foo = Spawn("Rubble1", self->Pos(), ALLOW_REPLACE);
if (foo != NULL)
{
int t = pr_lightout() & 15;
foo->Vel.X = t - (pr_lightout() & 7);
foo->Vel.Y = pr_lightout.Random2() & 7;
foo->Vel.Z = 7 + (pr_lightout() & 3);
}
}
return 0;
}

View file

@ -492,6 +492,21 @@ bool P_CreateFloor(sector_t *sec, DFloor::EFloor floortype, line_t *line,
return true;
}
DEFINE_ACTION_FUNCTION(DFloor, CreateFloor)
{
PARAM_PROLOGUE;
PARAM_POINTER(sec, sector_t);
PARAM_INT(floortype);
PARAM_POINTER(ln, line_t);
PARAM_FLOAT(speed);
PARAM_FLOAT_DEF(height);
PARAM_INT_DEF(crush);
PARAM_INT_DEF(change);
PARAM_BOOL_DEF(hereticlower);
PARAM_BOOL_DEF(hexencrush);
ACTION_RETURN_BOOL(P_CreateFloor(sec, (DFloor::EFloor)floortype, ln, speed, height, crush, change, hexencrush, hereticlower));
}
//==========================================================================
//
// HANDLE FLOOR TYPES

View file

@ -9512,7 +9512,8 @@ int BuiltinNameToClass(VMFrameStack *stack, VMValue *param, TArray<VMValue> &def
if (!cls->IsDescendantOf(desttype))
{
Printf("class '%s' is not compatible with '%s'\n", clsname.GetChars(), desttype->TypeName.GetChars());
// Let the caller check this. The message can be enabled for diagnostic purposes.
DPrintf(DMSG_SPAMMY, "class '%s' is not compatible with '%s'\n", clsname.GetChars(), desttype->TypeName.GetChars());
cls = nullptr;
}
ret->SetPointer(const_cast<PClass *>(cls), ATAG_OBJECT);

View file

@ -619,9 +619,6 @@ class Actor : Thinker native
native void A_Wander(int flags = 0);
native void A_Look2();
native void A_TossGib();
native void A_SetShadow();
native void A_ClearShadow();
native void A_GetHurt();
native void A_TurretLook();
native void A_KlaxonBlare();
native void A_Countdown();
@ -701,9 +698,7 @@ class Actor : Thinker native
native bool A_SelectWeapon(class<Weapon> whichweapon, int flags = 0);
native void A_ClassBossHealth();
native void A_RocketInFlight();
native void A_Bang4Cloud();
native void A_DropFire();
native void A_GiveQuestItem(int itemno);
native void A_RemoveForcefield();
native void A_SetAngle(double angle = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
native void A_SetPitch(double pitch, int flags = 0, int ptr = AAPTR_DEFAULT);

View file

@ -212,6 +212,28 @@ struct Sector native
native uint16 ZoneNumber;
native uint16 MoreFlags;
enum ESectorFlags
{
SECF_SILENT = 1, // actors in sector make no noise
SECF_NOFALLINGDAMAGE= 2, // No falling damage in this sector
SECF_FLOORDROP = 4, // all actors standing on this floor will remain on it when it lowers very fast.
SECF_NORESPAWN = 8, // players can not respawn in this sector
SECF_FRICTION = 16, // sector has friction enabled
SECF_PUSH = 32, // pushers enabled
SECF_SILENTMOVE = 64, // Sector movement makes mo sound (Eternity got this so this may be useful for an extended cross-port standard.)
SECF_DMGTERRAINFX = 128, // spawns terrain splash when inflicting damage
SECF_ENDGODMODE = 256, // getting damaged by this sector ends god mode
SECF_ENDLEVEL = 512, // ends level when health goes below 10
SECF_HAZARD = 1024, // Change to Strife's delayed damage handling.
SECF_WASSECRET = 1 << 30, // a secret that was discovered
SECF_SECRET = 1 << 31, // a secret sector
SECF_DAMAGEFLAGS = SECF_ENDGODMODE|SECF_ENDLEVEL|SECF_DMGTERRAINFX|SECF_HAZARD,
SECF_NOMODIFY = SECF_SECRET|SECF_WASSECRET, // not modifiable by Sector_ChangeFlags
SECF_SPECIALFLAGS = SECF_DAMAGEFLAGS|SECF_FRICTION|SECF_PUSH, // these flags originate from 'special and must be transferrable by floor thinkers
}
native uint Flags;
native SectorAction SecActTarget;
@ -286,3 +308,49 @@ struct String native
{
native void Replace(String pattern, String replacement);
}
class Floor : Thinker native
{
// only here so that some constants and functions can be added. Not directly usable yet.
enum EFloor
{
floorLowerToLowest,
floorLowerToNearest,
floorLowerToHighest,
floorLowerByValue,
floorRaiseByValue,
floorRaiseToHighest,
floorRaiseToNearest,
floorRaiseAndCrush,
floorRaiseAndCrushDoom,
floorCrushStop,
floorLowerInstant,
floorRaiseInstant,
floorMoveToValue,
floorRaiseToLowestCeiling,
floorRaiseByTexture,
floorLowerAndChange,
floorRaiseAndChange,
floorRaiseToLowest,
floorRaiseToCeiling,
floorLowerToLowestCeiling,
floorLowerByTexture,
floorLowerToCeiling,
donutRaise,
buildStair,
waitStair,
resetStair,
// Not to be used as parameters to EV_DoFloor()
genFloorChg0,
genFloorChgT,
genFloorChg
};
native static bool CreateFloor(sector sec, EFloor floortype, line ln, double speed, double height = 0, int crush = -1, int change = 0, bool hexencrush = false, bool hereticlower = false);
}

View file

@ -72,5 +72,32 @@ extend class Actor
double pitch = AimLineAttack (angle, MISSILERANGE);
LineAttack (Angle + Random2[ShootGun]() * (11.25 / 256), MISSILERANGE, pitch, 3*(random[ShootGun]() % 5 + 1), 'Hitscan', "StrifePuff");
}
// Kneeling Guy -------------------------------------------------------------
void A_SetShadow()
{
bShadow = true;
A_SetRenderStyle(HR_SHADOW, STYLE_Translucent);
}
void A_ClearShadow()
{
bShadow = false;
A_SetRenderStyle(1, STYLE_Normal);
}
void A_GetHurt()
{
bInCombat = true;
if ((random[HurtMe]() % 5) == 0)
{
A_PlaySound (PainSound, CHAN_VOICE);
health--;
}
if (health <= 0)
{
Die (target, target);
}
}
}

View file

@ -1,4 +1,42 @@
extend class Actor
{
void A_Bang4Cloud()
{
double xo = (random[Bang4Cloud]() & 3) * (10. / 64);
double yo = (random[Bang4Cloud]() & 3) * (10. / 64);
Spawn("Bang4Cloud", Vec3Offset(xo, yo, 0.), ALLOW_REPLACE);
}
void A_GiveQuestItem(int questitem)
{
// Give one of these quest items to every player in the game
if (questitem >= 0)
{
String itemname = "QuestItem" .. questitem;
class<Inventory> item = itemname;
if (item != null)
{
for (int i = 0; i < MAXPLAYERS; ++i)
{
if (playeringame[i])
{
players[i].mo.GiveInventoryType(item);
}
}
}
}
String msgid = "TXT_QUEST_" .. questitem;
String msg = StringTable.Localize(msgid);
if (msg != msgid) // if both are identical there was no message of this name in the stringtable.
{
C_MidPrint ("SmallFont", msg);
}
}
}
// A Cloud used for varius explosions ---------------------------------------
// This actor has no direct equivalent in strife. To create this, Strife
@ -121,10 +159,6 @@ class PowerCrystal : Actor
ActiveSound "misc/reactor";
}
native void A_ExtraLightOff ();
native void A_Explode512 ();
native void A_LightGoesOut ();
States
{
Spawn:
@ -150,4 +184,48 @@ class PowerCrystal : Actor
BOOM VWXY 3 Bright;
Stop;
}
// PowerCrystal -------------------------------------------------------------------
void A_ExtraLightOff()
{
if (target != NULL && target.player != NULL)
{
target.player.extralight = 0;
}
}
void A_Explode512()
{
A_Explode(512, 512);
if (target != NULL && target.player != NULL)
{
target.player.extralight = 5;
}
A_SetRenderStyle(1, STYLE_Add);
}
void A_LightGoesOut()
{
sector sec = CurSector;
sec.Flags |= Sector.SECF_SILENTMOVE;
sec.lightlevel = 0;
// Do this right with proper checks instead of just hacking the floor height.
Floor.CreateFloor(sec, Floor.floorLowerToLowest, null, 65536.);
for (int i = 0; i < 8; ++i)
{
Actor foo = Spawn("Rubble1", Pos, ALLOW_REPLACE);
if (foo != NULL)
{
int t = random[LightOut]() & 15;
foo.Vel.X = t - (random[LightOut]() & 7);
foo.Vel.Y = random2[LightOut]() & 7;
foo.Vel.Z = 7 + (random[LightOut]() & 3);
}
}
}
}