I've been working with and learning ZScript for about two or three years now and have built a fairly reasonable foundation with it, so I know how to go about adding these additional features to A_SpawnItemEx in theory. The problem is my math skills. I never finished high school because of real life reasons I won't discuss here, nonetheless, it left some real holes in my education related to Trig, Algebra, and Calculus which have caused me no end of grief in my modding career for various games, Doom being no exception. I've managed to add the ability to set the spawned actor's pitch and roll but I lack the necessary math skills to figure out how to set an actor's velocity if pitch should be taken into account for said velocity. I've attempted to figure it out myself and sometimes it seems to work right and other times the spawned actor's velocity is completely out of whack. The last feature I want is for the spawned actor's positional offsets to take the actor's pitch into account if a flag is passed. For example, if the actor is spawned pitching up at 45 degrees, the X offset should raise the actor as well as move it forward by the appropriate amount. I have absolutely no idea how to implement this so I haven't even tried.

Here is what I've got so far, if anyone can help me figure out what I've done wrong with the velocity calculations, I would greatly appreciate it. Extra kudos if someone can show me how to have the spawned offsets take into account the actor's pitch.

- Code: Select all • Expand view
`Enum ESpawnItemExtendedFlags`

{

SXF_ABSOLUTEPITCH = 1 << 29,

SXF_ABSOLUTEROLL = 1 << 30,

SXF_VELOCITYFROMPITCH = 1 << 31,

SXF_OFFSETFROMPITCH = 1 << 32,

};

Bool, Actor A_SpawnItemExtended(Class<Actor> Actr, Double XOfs = 0.0, Double YOfs = 0.0, Double ZOfs = 0.0, Double XVel = 0.0, Double YVel = 0.0, Double ZVel = 0.0, Double Angle = 0.0, Double Pitch = 0.0, Double Roll = 0.0, Int Flags = 0, Int FailChance = 0, Int TID = 0)

{

Vector2 Pos;

Double S;

Double C;

Double NewXVel;

Bool Res;

Vector3 PitchSpeed;

If (!Actr)

{

Return False, Null;

}

If (FailChance > 0 && Random[SpawnItemEx]() < FailChance)

{

Return True, Null;

}

If (DamageType == 'Massacre' && GetDefaultByType(Actr).bIsMonster)

{

Return True, Null;

}

If (!(Flags & SXF_ABSOLUTEANGLE))

{

Angle += Self.Angle;

}

If (!(Flags & SXF_ABSOLUTEPITCH))

{

Pitch += Clamp(Self.Pitch,-90.0,90.0);

}

If (!(Flags & SXF_ABSOLUTEROLL))

{

Roll += Self.Roll;

}

S = Sin(Angle);

C = Cos(Angle);

If (Flags & SXF_ABSOLUTEPOSITION)

{

Pos = Vec2Offset(XOfs,YOfs);

}

Else

{

If (Flags & SXF_OFFSETFROMPITCH)

{

//No idea how to implement this

}

Else

{

Pos = Vec2Offset(XOfs * C + YOfs * S,XOfs * S - YOfs * C);

}

}

If (!(Flags & SXF_ABSOLUTEVELOCITY))

{

NewXVel = XVel * C + YVel * S;

YVel = XVel * S - YVel * C;

XVel = NewXVel;

ZVel = Self.Vel.Z + ZVel;

}

Let MO = Spawn(Actr,(Pos,Self.Pos.Z - Floorclip + GetBobOffset() + ZOfs),ALLOW_REPLACE);

Res = InitSpawnedItem(MO,Flags);

If (Res)

{

If (TID != 0)

{

MO.ChangeTid(TID);

}

MO.Vel = (XVel, YVel, ZVel);

Pitch = Clamp(Pitch,-90.0,90.0);

MO.Angle = Angle;

MO.Pitch = Pitch;

MO.Roll = Roll;

If (Flags & SXF_VELOCITYFROMPITCH)

{

PitchSpeed = (Cos(MO.Pitch) * XVel,YVel,(-Sin(MO.Pitch) * XVel) + ZVel);

MO.Vel = PitchSpeed;

}

If (Flags & SXF_MULTIPLYSPEED)

{

MO.Vel *= MO.Speed;

}

}

Return Res, MO;

}