|
This article or section is incomplete. It doesn't have all of the necessary core information on this topic. Please help the SRB2 Wiki by finishing this article.
|
A_Custom3DRotate is an action that rotates the actor around its target in 3 dimensions. If the target is removed, so is the actor. Var1 lower 16 bits determine the radius, measured in fracunits. Var1 upper 16 bits determine the vertical offset from the target. The vertical rotation speed is determined by Var2 lower 16 bits, the horizontal rotation by Var2 upper 16 bits. Both are measured in one fracunit per 10 tics. This action has to be looped infinitely and has to last 1 tic.
This action originates from the v2.0 modification SRB2Morphed and was added to SRB2 itself in v2.1.
Code – A_Custom3DRotate
|
|
// Function: A_Custom3DRotate
//
// Description: Rotates the actor around its target in 3 dimensions.
//
// var1:
// lower 16 bits = radius in fracunits
// upper 16 bits = vertical offset
// var2:
// lower 16 bits = vertical rotation speed in 1/10 fracunits per tic
// upper 16 bits = horizontal rotation speed in 1/10 fracunits per tic
//
void A_Custom3DRotate(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
const UINT16 loc1lw = (UINT16)(locvar1 & 65535);
const UINT16 loc1up = (UINT16)(locvar1 >> 16);
const UINT16 loc2lw = (UINT16)(locvar2 & 65535);
const UINT16 loc2up = (UINT16)(locvar2 >> 16);
const fixed_t radius = FixedMul(loc1lw*FRACUNIT, actor->scale);
const fixed_t hOff = FixedMul(loc1up*FRACUNIT, actor->scale);
const fixed_t hspeed = FixedMul(loc2up*FRACUNIT/10, actor->scale);
const fixed_t vspeed = FixedMul(loc2lw*FRACUNIT/10, actor->scale);
#ifdef HAVE_BLUA
if (LUA_CallAction("A_Custom3DRotate", actor))
return;
#endif
if (actor->target->health == 0)
{
P_RemoveMobj(actor);
return;
}
if (!actor->target) // This should NEVER happen.
{
if (cv_debug)
CONS_Printf("Error: Object has no target\n");
P_RemoveMobj(actor);
return;
}
if (hspeed==0 && vspeed==0)
{
CONS_Printf("Error: A_Custom3DRotate: Object has no speed.\n");
return;
}
actor->angle += FixedAngle(hspeed);
actor->movedir += FixedAngle(vspeed);
P_UnsetThingPosition(actor);
{
const angle_t fa = actor->angle>>ANGLETOFINESHIFT;
if (vspeed == 0 && hspeed != 0)
{
actor->x = actor->target->x + FixedMul(FINECOSINE(fa),radius);
actor->y = actor->target->y + FixedMul(FINESINE(fa),radius);
actor->z = actor->target->z + actor->target->height/2 - actor->height/2 + hOff;
}
else
{
const angle_t md = actor->movedir>>ANGLETOFINESHIFT;
actor->x = actor->target->x + FixedMul(FixedMul(FINESINE(md),FINECOSINE(fa)),radius);
actor->y = actor->target->y + FixedMul(FixedMul(FINESINE(md),FINESINE(fa)),radius);
actor->z = actor->target->z + FixedMul(FINECOSINE(md),radius) + actor->target->height/2 - actor->height/2 + hOff;
}
}
P_SetThingPosition(actor);
}
|
|