- scriptified the bridge things, except the Destroy method which still requires work to allow virtually calling this.

This commit is contained in:
Christoph Oelckers 2017-01-12 19:54:25 +01:00
parent de6a66851e
commit 0b94d4e0a3
3 changed files with 103 additions and 146 deletions

View file

@ -100,8 +100,6 @@ enum
CLASSREG_PClassPlayerPawn, CLASSREG_PClassPlayerPawn,
CLASSREG_PClassType, CLASSREG_PClassType,
CLASSREG_PClassClass, CLASSREG_PClassClass,
CLASSREG_PClassWeaponPiece,
CLASSREG_PClassPowerupGiver
}; };
struct ClassReg struct ClassReg

View file

@ -1,63 +1,18 @@
#include "actor.h" #include "actor.h"
#include "info.h" #include "info.h"
#include "gi.h" #include "gi.h"
#include "m_random.h"
static FRandom pr_orbit ("Orbit");
// Custom bridge -------------------------------------------------------- // Custom bridge --------------------------------------------------------
/*
args[0]: Bridge radius, in mapunits
args[1]: Bridge height, in mapunits
args[2]: Amount of bridge balls (if 0: Doom bridge)
args[3]: Rotation speed of bridge balls, in byte angle per seconds, sorta:
Since an arg is only a byte, it can only go from 0 to 255, while ZDoom's
BAM go from 0 to 65535. Plus, it needs to be able to go either way. So,
up to 128, it goes counterclockwise; 129-255 is clockwise, substracting
256 from it to get the angle. A few example values:
0: Hexen default
11: 15° / seconds
21: 30° / seconds
32: 45° / seconds
64: 90° / seconds
128: 180° / seconds
192: -90° / seconds
223: -45° / seconds
233: -30° / seconds
244: -15° / seconds
This value only matters if args[2] is not zero.
args[4]: Rotation radius of bridge balls, in bridge radius %.
If 0, use Hexen default: ORBIT_RADIUS, regardless of bridge radius.
This value only matters if args[2] is not zero.
*/
class ACustomBridge : public AActor class ACustomBridge : public AActor
{ {
DECLARE_CLASS (ACustomBridge, AActor) DECLARE_CLASS (ACustomBridge, AActor)
public: public:
void BeginPlay ();
void Destroy() override; void Destroy() override;
}; };
IMPLEMENT_CLASS(ACustomBridge, false, false) IMPLEMENT_CLASS(ACustomBridge, false, false)
void ACustomBridge::BeginPlay ()
{
if (args[2]) // Hexen bridge if there are balls
{
SetState(SeeState);
radius = args[0] ? args[0] : 32;
Height = args[1] ? args[1] : 2;
}
else // No balls? Then a Doom bridge.
{
radius = args[0] ? args[0] : 36;
Height = args[1] ? args[1] : 4;
RenderStyle = STYLE_Normal;
}
}
void ACustomBridge::Destroy() void ACustomBridge::Destroy()
{ {
// Hexen originally just set a flag to make the bridge balls remove themselves in A_BridgeOrbit. // Hexen originally just set a flag to make the bridge balls remove themselves in A_BridgeOrbit.
@ -76,97 +31,3 @@ void ACustomBridge::Destroy()
} }
Super::Destroy(); Super::Destroy();
} }
// Action functions for the non-Doom bridge --------------------------------
#define ORBIT_RADIUS 15
// New bridge stuff
// Parent
// special1 true == removing from world
//
// Child
// target pointer to center mobj
// angle angle of ball
static void BridgeOrbit(AActor *self)
{
if (self->target == NULL)
{ // Don't crash if somebody spawned this into the world
// independantly of a Bridge actor.
return;
}
// Set default values
// Every five tics, Hexen moved the ball 3/256th of a revolution.
DAngle rotationspeed = 45. / 32 * 3 / 5;
double rotationradius = ORBIT_RADIUS;
// If the bridge is custom, set non-default values if any.
// Set angular speed; 1--128: counterclockwise rotation ~=1--180°; 129--255: clockwise rotation ~= 180--1°
if (self->target->args[3] > 128) rotationspeed = 45. / 32 * (self->target->args[3] - 256) / TICRATE;
else if (self->target->args[3] > 0) rotationspeed = 45. / 32 * (self->target->args[3]) / TICRATE;
// Set rotation radius
if (self->target->args[4]) rotationradius = ((self->target->args[4] * self->target->radius) / 100);
self->Angles.Yaw += rotationspeed;
self->SetOrigin(self->target->Vec3Angle(rotationradius, self->Angles.Yaw, 0), true);
self->floorz = self->target->floorz;
self->ceilingz = self->target->ceilingz;
}
DEFINE_ACTION_FUNCTION(ABridgeBall, A_BridgeOrbit)
{
PARAM_SELF_PROLOGUE(AActor);
BridgeOrbit(self);
return 0;
}
DEFINE_ACTION_FUNCTION(ACustomBridge, A_BridgeInit)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_CLASS_DEF(balltype, AActor);
AActor *ball;
if (balltype == NULL)
{
balltype = PClass::FindActor("BridgeBall");
}
DAngle startangle = pr_orbit() * (360./256.);
// Spawn triad into world -- may be more than a triad now.
int ballcount = self->args[2]==0 ? 3 : self->args[2];
for (int i = 0; i < ballcount; i++)
{
ball = Spawn(balltype, self->Pos(), ALLOW_REPLACE);
ball->Angles.Yaw = startangle + (45./32) * (256/ballcount) * i;
ball->target = self;
BridgeOrbit(ball);
}
return 0;
}
// Invisible bridge --------------------------------------------------------
class AInvisibleBridge : public AActor
{
DECLARE_CLASS (AInvisibleBridge, AActor)
public:
void BeginPlay ();
};
IMPLEMENT_CLASS(AInvisibleBridge, false, false)
void AInvisibleBridge::BeginPlay ()
{
Super::BeginPlay ();
if (args[0])
radius = args[0];
if (args[1])
Height = args[1];
}

View file

@ -1,3 +1,28 @@
/*
args[0]: Bridge radius, in mapunits
args[1]: Bridge height, in mapunits
args[2]: Amount of bridge balls (if 0: Doom bridge)
args[3]: Rotation speed of bridge balls, in byte angle per seconds, sorta:
Since an arg is only a byte, it can only go from 0 to 255, while ZDoom's
BAM go from 0 to 65535. Plus, it needs to be able to go either way. So,
up to 128, it goes counterclockwise; 129-255 is clockwise, substracting
256 from it to get the angle. A few example values:
0: Hexen default
11: 15° / seconds
21: 30° / seconds
32: 45° / seconds
64: 90° / seconds
128: 180° / seconds
192: -90° / seconds
223: -45° / seconds
233: -30° / seconds
244: -15° / seconds
This value only matters if args[2] is not zero.
args[4]: Rotation radius of bridge balls, in bridge radius %.
If 0, use Hexen default: ORBIT_RADIUS, regardless of bridge radius.
This value only matters if args[2] is not zero.
*/
// Bridge ball ------------------------------------------------------------- // Bridge ball -------------------------------------------------------------
class BridgeBall : Actor class BridgeBall : Actor
@ -9,8 +34,6 @@ class BridgeBall : Actor
+NOGRAVITY +NOGRAVITY
} }
native void A_BridgeOrbit();
States States
{ {
Spawn: Spawn:
@ -19,12 +42,38 @@ class BridgeBall : Actor
Wait; Wait;
} }
void A_BridgeOrbit()
{
if (target == NULL)
{ // Don't crash if somebody spawned this into the world
// independantly of a Bridge actor.
return;
}
// Set default values
// Every five tics, Hexen moved the ball 3/256th of a revolution.
double rotationspeed = 45. / 32 * 3 / 5;
double rotationradius = CustomBridge.ORBIT_RADIUS;
// If the bridge is custom, set non-default values if any.
// Set angular speed; 1--128: counterclockwise rotation ~=1--180°; 129--255: clockwise rotation ~= 180--1°
if (target.args[3] > 128) rotationspeed = 45. / 32 * (target.args[3] - 256) / TICRATE;
else if (target.args[3] > 0) rotationspeed = 45. / 32 * (target.args[3]) / TICRATE;
// Set rotation radius
if (target.args[4]) rotationradius = ((target.args[4] * target.radius) / 100);
Angle += rotationspeed;
SetOrigin(target.Vec3Angle(rotationradius, Angle, 0), true);
floorz = target.floorz;
ceilingz = target.ceilingz;
}
} }
// The bridge itself ------------------------------------------------------- // The bridge itself -------------------------------------------------------
class CustomBridge : Actor native class CustomBridge : Actor native
{ {
const ORBIT_RADIUS = 15;
default default
{ {
+SOLID +SOLID
@ -36,8 +85,6 @@ class CustomBridge : Actor native
RenderStyle "None"; RenderStyle "None";
} }
native void A_BridgeInit(class<Actor> balltype = "BridgeBall");
states states
{ {
Spawn: Spawn:
@ -53,6 +100,47 @@ class CustomBridge : Actor native
TLGL A 300; TLGL A 300;
Stop; Stop;
} }
override void BeginPlay ()
{
if (args[2]) // Hexen bridge if there are balls
{
SetState(SeeState);
A_SetSize(args[0] ? args[0] : 32, args[1] ? args[1] : 2);
}
else // No balls? Then a Doom bridge.
{
A_SetSize(args[0] ? args[0] : 36, args[1] ? args[1] : 4);
A_SetRenderStyle(1., STYLE_Normal);
}
}
void A_BridgeInit(class<Actor> balltype = "BridgeBall")
{
if (balltype == NULL)
{
balltype = "BridgeBall";
}
double startangle = random[orbit]() * (360./256.);
// Spawn triad into world -- may be more than a triad now.
int ballcount = args[2]==0 ? 3 : args[2];
for (int i = 0; i < ballcount; i++)
{
Actor ball = Spawn(balltype, Pos, ALLOW_REPLACE);
ball.Angle = startangle + (45./32) * (256/ballcount) * i;
ball.target = self;
double rotationradius = ORBIT_RADIUS;
if (args[4]) rotationradius = (args[4] * radius) / 100;
ball.SetOrigin(Vec3Angle(rotationradius, ball.Angle, 0), true);
ball.floorz = floorz;
ball.ceilingz = ceilingz;
}
}
} }
// The Hexen bridge ------------------------------------------------------- // The Hexen bridge -------------------------------------------------------
@ -79,7 +167,7 @@ class ZBridge : CustomBridge
// Invisible bridge -------------------------------------------------------- // Invisible bridge --------------------------------------------------------
class InvisibleBridge : Actor native class InvisibleBridge : Actor
{ {
default default
{ {
@ -98,6 +186,16 @@ class InvisibleBridge : Actor native
TNT1 A -1; TNT1 A -1;
Stop; Stop;
} }
override void BeginPlay ()
{
Super.BeginPlay ();
if (args[0] || args[1])
{
A_SetSize(args[0]? args[0] : radius, args[1]? args[1] : height);
}
}
} }
// And some invisible bridges from Skull Tag ------------------------------- // And some invisible bridges from Skull Tag -------------------------------