mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 15:02:01 +00:00
- scriptified the bridge things, except the Destroy method which still requires work to allow virtually calling this.
This commit is contained in:
parent
de6a66851e
commit
0b94d4e0a3
3 changed files with 103 additions and 146 deletions
|
@ -100,8 +100,6 @@ enum
|
|||
CLASSREG_PClassPlayerPawn,
|
||||
CLASSREG_PClassType,
|
||||
CLASSREG_PClassClass,
|
||||
CLASSREG_PClassWeaponPiece,
|
||||
CLASSREG_PClassPowerupGiver
|
||||
};
|
||||
|
||||
struct ClassReg
|
||||
|
|
|
@ -1,63 +1,18 @@
|
|||
#include "actor.h"
|
||||
#include "info.h"
|
||||
#include "gi.h"
|
||||
#include "m_random.h"
|
||||
|
||||
static FRandom pr_orbit ("Orbit");
|
||||
|
||||
|
||||
// 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
|
||||
{
|
||||
DECLARE_CLASS (ACustomBridge, AActor)
|
||||
public:
|
||||
void BeginPlay ();
|
||||
void Destroy() override;
|
||||
};
|
||||
|
||||
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()
|
||||
{
|
||||
// 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();
|
||||
}
|
||||
|
||||
// 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];
|
||||
}
|
||||
|
||||
|
|
|
@ -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 -------------------------------------------------------------
|
||||
|
||||
class BridgeBall : Actor
|
||||
|
@ -9,8 +34,6 @@ class BridgeBall : Actor
|
|||
+NOGRAVITY
|
||||
}
|
||||
|
||||
native void A_BridgeOrbit();
|
||||
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
@ -19,12 +42,38 @@ class BridgeBall : Actor
|
|||
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 -------------------------------------------------------
|
||||
|
||||
class CustomBridge : Actor native
|
||||
{
|
||||
const ORBIT_RADIUS = 15;
|
||||
|
||||
default
|
||||
{
|
||||
+SOLID
|
||||
|
@ -36,8 +85,6 @@ class CustomBridge : Actor native
|
|||
RenderStyle "None";
|
||||
}
|
||||
|
||||
native void A_BridgeInit(class<Actor> balltype = "BridgeBall");
|
||||
|
||||
states
|
||||
{
|
||||
Spawn:
|
||||
|
@ -53,6 +100,47 @@ class CustomBridge : Actor native
|
|||
TLGL A 300;
|
||||
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 -------------------------------------------------------
|
||||
|
@ -79,7 +167,7 @@ class ZBridge : CustomBridge
|
|||
|
||||
// Invisible bridge --------------------------------------------------------
|
||||
|
||||
class InvisibleBridge : Actor native
|
||||
class InvisibleBridge : Actor
|
||||
{
|
||||
default
|
||||
{
|
||||
|
@ -98,6 +186,16 @@ class InvisibleBridge : Actor native
|
|||
TNT1 A -1;
|
||||
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 -------------------------------
|
||||
|
|
Loading…
Reference in a new issue