mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-23 20:43:15 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
b0a0fb5ff0
25 changed files with 499 additions and 354 deletions
|
@ -26,7 +26,7 @@ static FRandom pr_fswordflame ("FSwordFlame");
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropWeaponPieces)
|
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropWeaponPieces)
|
||||||
{
|
{
|
||||||
PARAM_ACTION_PROLOGUE;
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
PARAM_CLASS(p1, AActor);
|
PARAM_CLASS(p1, AActor);
|
||||||
PARAM_CLASS(p2, AActor);
|
PARAM_CLASS(p2, AActor);
|
||||||
PARAM_CLASS(p3, AActor);
|
PARAM_CLASS(p3, AActor);
|
||||||
|
|
|
@ -28,7 +28,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Bang4Cloud)
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GiveQuestItem)
|
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GiveQuestItem)
|
||||||
{
|
{
|
||||||
PARAM_ACTION_PROLOGUE;
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
PARAM_INT(questitem);
|
PARAM_INT(questitem);
|
||||||
|
|
||||||
// Give one of these quest items to every player in the game
|
// Give one of these quest items to every player in the game
|
||||||
|
|
|
@ -345,4 +345,8 @@ void AddStateLight(FState *state, const char *lname);
|
||||||
// Number of action paramaters
|
// Number of action paramaters
|
||||||
#define NAP 3
|
#define NAP 3
|
||||||
|
|
||||||
|
#define PARAM_SELF_PROLOGUE(type) \
|
||||||
|
PARAM_PROLOGUE; \
|
||||||
|
PARAM_OBJECT(self, type);
|
||||||
|
|
||||||
#endif // __INFO_H__
|
#endif // __INFO_H__
|
||||||
|
|
|
@ -296,6 +296,8 @@ xx(Tan)
|
||||||
xx(CosH)
|
xx(CosH)
|
||||||
xx(SinH)
|
xx(SinH)
|
||||||
xx(TanH)
|
xx(TanH)
|
||||||
|
xx(ATan2)
|
||||||
|
xx(VectorAngle)
|
||||||
xx(Alpha)
|
xx(Alpha)
|
||||||
xx(Angle)
|
xx(Angle)
|
||||||
xx(Args)
|
xx(Args)
|
||||||
|
|
|
@ -287,22 +287,21 @@ void P_ThinkParticles ()
|
||||||
particle->Pos.Z += particle->Vel.Z;
|
particle->Pos.Z += particle->Vel.Z;
|
||||||
particle->Vel += particle->Acc;
|
particle->Vel += particle->Acc;
|
||||||
particle->subsector = R_PointInSubsector(particle->Pos);
|
particle->subsector = R_PointInSubsector(particle->Pos);
|
||||||
|
sector_t *s = particle->subsector->sector;
|
||||||
// Handle crossing a sector portal.
|
// Handle crossing a sector portal.
|
||||||
if (!particle->subsector->sector->PortalBlocksMovement(sector_t::ceiling))
|
if (!s->PortalBlocksMovement(sector_t::ceiling))
|
||||||
{
|
{
|
||||||
AActor *skybox = particle->subsector->sector->SkyBoxes[sector_t::ceiling];
|
if (particle->Pos.Z > s->GetPortalPlaneZ(sector_t::ceiling))
|
||||||
if (particle->Pos.Z > skybox->specialf1)
|
|
||||||
{
|
{
|
||||||
particle->Pos += skybox->Scale;
|
particle->Pos += s->GetPortalDisplacement(sector_t::ceiling);
|
||||||
particle->subsector = NULL;
|
particle->subsector = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!particle->subsector->sector->PortalBlocksMovement(sector_t::floor))
|
else if (!s->PortalBlocksMovement(sector_t::floor))
|
||||||
{
|
{
|
||||||
AActor *skybox = particle->subsector->sector->SkyBoxes[sector_t::floor];
|
if (particle->Pos.Z < s->GetPortalPlaneZ(sector_t::floor))
|
||||||
if (particle->Pos.Z < skybox->specialf1)
|
|
||||||
{
|
{
|
||||||
particle->Pos += skybox->Scale;
|
particle->Pos += s->GetPortalDisplacement(sector_t::floor);
|
||||||
particle->subsector = NULL;
|
particle->subsector = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,12 +162,12 @@ void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soun
|
||||||
// I wish there was a better method to do this than randomly looking through the portal at a few places...
|
// I wish there was a better method to do this than randomly looking through the portal at a few places...
|
||||||
if (checkabove)
|
if (checkabove)
|
||||||
{
|
{
|
||||||
sector_t *upper = P_PointInSector(check->v1->fPos() + check->Delta() / 2 + sec->SkyBoxes[sector_t::ceiling]->Scale);
|
sector_t *upper = P_PointInSector(check->v1->fPos() + check->Delta() / 2 + sec->GetPortalDisplacement(sector_t::ceiling));
|
||||||
P_RecursiveSound(upper, soundtarget, splash, soundblocks, emitter, maxdist);
|
P_RecursiveSound(upper, soundtarget, splash, soundblocks, emitter, maxdist);
|
||||||
}
|
}
|
||||||
if (checkbelow)
|
if (checkbelow)
|
||||||
{
|
{
|
||||||
sector_t *lower = P_PointInSector(check->v1->fPos() + check->Delta() / 2 + sec->SkyBoxes[sector_t::floor]->Scale);
|
sector_t *lower = P_PointInSector(check->v1->fPos() + check->Delta() / 2 + sec->GetPortalDisplacement(sector_t::floor));
|
||||||
P_RecursiveSound(lower, soundtarget, splash, soundblocks, emitter, maxdist);
|
P_RecursiveSound(lower, soundtarget, splash, soundblocks, emitter, maxdist);
|
||||||
}
|
}
|
||||||
FLinePortal *port = check->getPortal();
|
FLinePortal *port = check->getPortal();
|
||||||
|
@ -2773,7 +2773,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_VileChase)
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ExtChase)
|
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ExtChase)
|
||||||
{
|
{
|
||||||
PARAM_ACTION_PROLOGUE;
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
PARAM_BOOL (domelee);
|
PARAM_BOOL (domelee);
|
||||||
PARAM_BOOL (domissile);
|
PARAM_BOOL (domissile);
|
||||||
PARAM_BOOL_OPT (playactive) { playactive = true; }
|
PARAM_BOOL_OPT (playactive) { playactive = true; }
|
||||||
|
|
|
@ -656,20 +656,21 @@ double P_GetMoveFactor(const AActor *mo, double *frictionp)
|
||||||
// - 0 when intersecting
|
// - 0 when intersecting
|
||||||
// - -1 when outside the portal
|
// - -1 when outside the portal
|
||||||
//
|
//
|
||||||
|
// Note that this check is done from the 'other' side of the portal
|
||||||
|
// so plane names seem to be inverted.
|
||||||
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
static int LineIsAbove(line_t *line, AActor *actor)
|
static int LineIsAbove(line_t *line, AActor *actor)
|
||||||
{
|
{
|
||||||
AActor *point = line->frontsector->SkyBoxes[sector_t::floor];
|
if (line->frontsector->PortalBlocksMovement(sector_t::floor)) return -1;
|
||||||
if (point == NULL) return -1;
|
return line->frontsector->GetPortalPlaneZ(sector_t::floor) >= actor->Top();
|
||||||
return point->specialf1 >= actor->Top();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int LineIsBelow(line_t *line, AActor *actor)
|
static int LineIsBelow(line_t *line, AActor *actor)
|
||||||
{
|
{
|
||||||
AActor *point = line->frontsector->SkyBoxes[sector_t::ceiling];
|
if (line->frontsector->PortalBlocksMovement(sector_t::ceiling)) return -1;
|
||||||
if (point == NULL) return -1;
|
return line->frontsector->GetPortalPlaneZ(sector_t::ceiling) <= actor->Z();
|
||||||
return point->specialf1 <= actor->Z();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -762,7 +763,7 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
|
||||||
if (state == 1)
|
if (state == 1)
|
||||||
{
|
{
|
||||||
// the line should not block but we should set the ceilingz to the portal boundary so that we can't float up into that line.
|
// the line should not block but we should set the ceilingz to the portal boundary so that we can't float up into that line.
|
||||||
double portalz = cres.line->frontsector->SkyBoxes[sector_t::floor]->specialf1;
|
double portalz = cres.line->frontsector->GetPortalPlaneZ(sector_t::floor);
|
||||||
if (portalz < tm.ceilingz)
|
if (portalz < tm.ceilingz)
|
||||||
{
|
{
|
||||||
tm.ceilingz = portalz;
|
tm.ceilingz = portalz;
|
||||||
|
@ -778,7 +779,7 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
|
||||||
if (state == -1) return true;
|
if (state == -1) return true;
|
||||||
if (state == 1)
|
if (state == 1)
|
||||||
{
|
{
|
||||||
double portalz = cres.line->frontsector->SkyBoxes[sector_t::ceiling]->specialf1;
|
double portalz = cres.line->frontsector->GetPortalPlaneZ(sector_t::ceiling);
|
||||||
if (portalz > tm.floorz)
|
if (portalz > tm.floorz)
|
||||||
{
|
{
|
||||||
tm.floorz = portalz;
|
tm.floorz = portalz;
|
||||||
|
@ -3529,20 +3530,20 @@ struct aim_t
|
||||||
|
|
||||||
void EnterSectorPortal(int position, double frac, sector_t *entersec, DAngle newtoppitch, DAngle newbottompitch)
|
void EnterSectorPortal(int position, double frac, sector_t *entersec, DAngle newtoppitch, DAngle newbottompitch)
|
||||||
{
|
{
|
||||||
AActor *portal = entersec->SkyBoxes[position];
|
double portalz = entersec->GetPortalPlaneZ(position);
|
||||||
|
|
||||||
if (position == sector_t::ceiling && portal->specialf1 < limitz) return;
|
if (position == sector_t::ceiling && portalz < limitz) return;
|
||||||
else if (position == sector_t::floor && portal->specialf1 > limitz) return;
|
else if (position == sector_t::floor && portalz > limitz) return;
|
||||||
aim_t newtrace = Clone();
|
aim_t newtrace = Clone();
|
||||||
|
|
||||||
|
|
||||||
newtrace.toppitch = newtoppitch;
|
newtrace.toppitch = newtoppitch;
|
||||||
newtrace.bottompitch = newbottompitch;
|
newtrace.bottompitch = newbottompitch;
|
||||||
newtrace.aimdir = position == sector_t::ceiling? aim_t::aim_up : aim_t::aim_down;
|
newtrace.aimdir = position == sector_t::ceiling? aim_t::aim_up : aim_t::aim_down;
|
||||||
newtrace.startpos = startpos + portal->Scale;
|
newtrace.startpos = startpos + entersec->GetPortalDisplacement(position);
|
||||||
newtrace.startfrac = frac + 1. / attackrange; // this is to skip the transition line to the portal which would produce a bogus opening
|
newtrace.startfrac = frac + 1. / attackrange; // this is to skip the transition line to the portal which would produce a bogus opening
|
||||||
newtrace.lastsector = P_PointInSector(newtrace.startpos + aimtrace * newtrace.startfrac);
|
newtrace.lastsector = P_PointInSector(newtrace.startpos + aimtrace * newtrace.startfrac);
|
||||||
newtrace.limitz = portal->specialf1;
|
newtrace.limitz = portalz;
|
||||||
if (aimdebug)
|
if (aimdebug)
|
||||||
Printf("-----Entering %s portal from sector %d to sector %d\n", position ? "ceiling" : "floor", lastsector->sectornum, newtrace.lastsector->sectornum);
|
Printf("-----Entering %s portal from sector %d to sector %d\n", position ? "ceiling" : "floor", lastsector->sectornum, newtrace.lastsector->sectornum);
|
||||||
newtrace.AimTraverse();
|
newtrace.AimTraverse();
|
||||||
|
@ -6253,22 +6254,22 @@ void AActor::UpdateRenderSectorList()
|
||||||
ClearRenderSectorList();
|
ClearRenderSectorList();
|
||||||
while (!sec->PortalBlocksMovement(sector_t::ceiling))
|
while (!sec->PortalBlocksMovement(sector_t::ceiling))
|
||||||
{
|
{
|
||||||
double planeh = sec->SkyBoxes[sector_t::ceiling]->specialf1;
|
double planeh = sec->GetPortalPlaneZ(sector_t::ceiling);
|
||||||
if (planeh < lasth) break; // broken setup.
|
if (planeh < lasth) break; // broken setup.
|
||||||
if (Top() + SPRITE_SPACE < planeh) break;
|
if (Top() + SPRITE_SPACE < planeh) break;
|
||||||
lasth = planeh;
|
lasth = planeh;
|
||||||
DVector2 newpos = Pos() + sec->SkyBoxes[sector_t::ceiling]->Scale;
|
DVector2 newpos = Pos() + sec->GetPortalDisplacement(sector_t::ceiling);
|
||||||
sec = P_PointInSector(newpos);
|
sec = P_PointInSector(newpos);
|
||||||
render_sectorlist = P_AddSecnode(sec, this, render_sectorlist, sec->render_thinglist);
|
render_sectorlist = P_AddSecnode(sec, this, render_sectorlist, sec->render_thinglist);
|
||||||
}
|
}
|
||||||
lasth = FLT_MAX;
|
lasth = FLT_MAX;
|
||||||
while (!sec->PortalBlocksMovement(sector_t::floor))
|
while (!sec->PortalBlocksMovement(sector_t::floor))
|
||||||
{
|
{
|
||||||
double planeh = sec->SkyBoxes[sector_t::floor]->specialf1;
|
double planeh = sec->GetPortalPlaneZ(sector_t::floor);
|
||||||
if (planeh > lasth) break; // broken setup.
|
if (planeh > lasth) break; // broken setup.
|
||||||
if (Z() - SPRITE_SPACE > planeh) break;
|
if (Z() - SPRITE_SPACE > planeh) break;
|
||||||
lasth = planeh;
|
lasth = planeh;
|
||||||
DVector2 newpos = Pos() + sec->SkyBoxes[sector_t::floor]->Scale;
|
DVector2 newpos = Pos() + sec->GetPortalDisplacement(sector_t::floor);
|
||||||
sec = P_PointInSector(newpos);
|
sec = P_PointInSector(newpos);
|
||||||
render_sectorlist = P_AddSecnode(sec, this, render_sectorlist, sec->render_thinglist);
|
render_sectorlist = P_AddSecnode(sec, this, render_sectorlist, sec->render_thinglist);
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,7 +174,7 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, co
|
||||||
{
|
{
|
||||||
// We must check through the portal for the actual dropoff.
|
// We must check through the portal for the actual dropoff.
|
||||||
// If there's no lines in the lower sections we'd never get a usable value otherwise.
|
// If there's no lines in the lower sections we'd never get a usable value otherwise.
|
||||||
open.lowfloor = back->NextLowestFloorAt(pos.X, pos.Y, back->SkyBoxes[sector_t::floor]->specialf1-1);
|
open.lowfloor = back->NextLowestFloorAt(pos.X, pos.Y, back->GetPortalPlaneZ(sector_t::floor) - EQUAL_EPSILON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -188,7 +188,7 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, co
|
||||||
{
|
{
|
||||||
// We must check through the portal for the actual dropoff.
|
// We must check through the portal for the actual dropoff.
|
||||||
// If there's no lines in the lower sections we'd never get a usable value otherwise.
|
// If there's no lines in the lower sections we'd never get a usable value otherwise.
|
||||||
open.lowfloor = front->NextLowestFloorAt(pos.X, pos.Y, front->SkyBoxes[sector_t::floor]->specialf1 - 1);
|
open.lowfloor = front->NextLowestFloorAt(pos.X, pos.Y, front->GetPortalPlaneZ(sector_t::floor) - EQUAL_EPSILON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
open.frontfloorplane = front->floorplane;
|
open.frontfloorplane = front->floorplane;
|
||||||
|
@ -735,7 +735,7 @@ bool FMultiBlockLinesIterator::GoUp(double x, double y)
|
||||||
{
|
{
|
||||||
if (!cursector->PortalBlocksMovement(sector_t::ceiling))
|
if (!cursector->PortalBlocksMovement(sector_t::ceiling))
|
||||||
{
|
{
|
||||||
startIteratorForGroup(cursector->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup);
|
startIteratorForGroup(cursector->GetOppositePortalGroup(sector_t::ceiling));
|
||||||
portalflags = FFCF_NOFLOOR;
|
portalflags = FFCF_NOFLOOR;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -756,7 +756,7 @@ bool FMultiBlockLinesIterator::GoDown(double x, double y)
|
||||||
{
|
{
|
||||||
if (!cursector->PortalBlocksMovement(sector_t::floor))
|
if (!cursector->PortalBlocksMovement(sector_t::floor))
|
||||||
{
|
{
|
||||||
startIteratorForGroup(cursector->SkyBoxes[sector_t::floor]->Sector->PortalGroup);
|
startIteratorForGroup(cursector->GetOppositePortalGroup(sector_t::floor));
|
||||||
portalflags = FFCF_NOCEILING;
|
portalflags = FFCF_NOCEILING;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3169,10 +3169,9 @@ DVector3 AActor::GetPortalTransition(double byoffset, sector_t **pSec)
|
||||||
|
|
||||||
while (!sec->PortalBlocksMovement(sector_t::ceiling))
|
while (!sec->PortalBlocksMovement(sector_t::ceiling))
|
||||||
{
|
{
|
||||||
AActor *port = sec->SkyBoxes[sector_t::ceiling];
|
if (testz > sec->GetPortalPlaneZ(sector_t::ceiling))
|
||||||
if (testz > port->specialf1)
|
|
||||||
{
|
{
|
||||||
pos = PosRelative(port->Sector);
|
pos = PosRelative(sec->GetOppositePortalGroup(sector_t::ceiling));
|
||||||
sec = P_PointInSector(pos);
|
sec = P_PointInSector(pos);
|
||||||
moved = true;
|
moved = true;
|
||||||
}
|
}
|
||||||
|
@ -3182,10 +3181,9 @@ DVector3 AActor::GetPortalTransition(double byoffset, sector_t **pSec)
|
||||||
{
|
{
|
||||||
while (!sec->PortalBlocksMovement(sector_t::floor))
|
while (!sec->PortalBlocksMovement(sector_t::floor))
|
||||||
{
|
{
|
||||||
AActor *port = sec->SkyBoxes[sector_t::floor];
|
if (testz <= sec->GetPortalPlaneZ(sector_t::floor))
|
||||||
if (testz <= port->specialf1)
|
|
||||||
{
|
{
|
||||||
pos = PosRelative(port->Sector);
|
pos = PosRelative(sec->GetOppositePortalGroup(sector_t::floor));
|
||||||
sec = P_PointInSector(pos);
|
sec = P_PointInSector(pos);
|
||||||
}
|
}
|
||||||
else break;
|
else break;
|
||||||
|
@ -3202,12 +3200,11 @@ void AActor::CheckPortalTransition(bool islinked)
|
||||||
bool moved = false;
|
bool moved = false;
|
||||||
while (!Sector->PortalBlocksMovement(sector_t::ceiling))
|
while (!Sector->PortalBlocksMovement(sector_t::ceiling))
|
||||||
{
|
{
|
||||||
AActor *port = Sector->SkyBoxes[sector_t::ceiling];
|
if (Z() > Sector->GetPortalPlaneZ(sector_t::ceiling))
|
||||||
if (Z() > port->specialf1)
|
|
||||||
{
|
{
|
||||||
DVector3 oldpos = Pos();
|
DVector3 oldpos = Pos();
|
||||||
if (islinked && !moved) UnlinkFromWorld();
|
if (islinked && !moved) UnlinkFromWorld();
|
||||||
SetXYZ(PosRelative(port->Sector));
|
SetXYZ(PosRelative(Sector->GetOppositePortalGroup(sector_t::ceiling)));
|
||||||
Prev = Pos() - oldpos;
|
Prev = Pos() - oldpos;
|
||||||
Sector = P_PointInSector(Pos());
|
Sector = P_PointInSector(Pos());
|
||||||
PrevPortalGroup = Sector->PortalGroup;
|
PrevPortalGroup = Sector->PortalGroup;
|
||||||
|
@ -3219,12 +3216,12 @@ void AActor::CheckPortalTransition(bool islinked)
|
||||||
{
|
{
|
||||||
while (!Sector->PortalBlocksMovement(sector_t::floor))
|
while (!Sector->PortalBlocksMovement(sector_t::floor))
|
||||||
{
|
{
|
||||||
AActor *port = Sector->SkyBoxes[sector_t::floor];
|
double portalz = Sector->GetPortalPlaneZ(sector_t::floor);
|
||||||
if (Z() < port->specialf1 && floorz < port->specialf1)
|
if (Z() < portalz && floorz < portalz)
|
||||||
{
|
{
|
||||||
DVector3 oldpos = Pos();
|
DVector3 oldpos = Pos();
|
||||||
if (islinked && !moved) UnlinkFromWorld();
|
if (islinked && !moved) UnlinkFromWorld();
|
||||||
SetXYZ(PosRelative(port->Sector));
|
SetXYZ(PosRelative(Sector->GetOppositePortalGroup(sector_t::floor)));
|
||||||
Prev = Pos() - oldpos;
|
Prev = Pos() - oldpos;
|
||||||
Sector = P_PointInSector(Pos());
|
Sector = P_PointInSector(Pos());
|
||||||
PrevPortalGroup = Sector->PortalGroup;
|
PrevPortalGroup = Sector->PortalGroup;
|
||||||
|
|
|
@ -895,10 +895,10 @@ double sector_t::HighestCeilingAt(const DVector2 &p, sector_t **resultsec)
|
||||||
DVector2 pos = p;
|
DVector2 pos = p;
|
||||||
|
|
||||||
// Continue until we find a blocking portal or a portal below where we actually are.
|
// Continue until we find a blocking portal or a portal below where we actually are.
|
||||||
while (!check->PortalBlocksMovement(ceiling) && planeheight < check->SkyBoxes[ceiling]->specialf1)
|
while (!check->PortalBlocksMovement(ceiling) && planeheight < check->GetPortalPlaneZ(ceiling))
|
||||||
{
|
{
|
||||||
pos += check->SkyBoxes[ceiling]->Scale;
|
pos += check->GetPortalDisplacement(ceiling);
|
||||||
planeheight = check->SkyBoxes[ceiling]->specialf1;
|
planeheight = check->GetPortalPlaneZ(ceiling);
|
||||||
check = P_PointInSector(pos);
|
check = P_PointInSector(pos);
|
||||||
}
|
}
|
||||||
if (resultsec) *resultsec = check;
|
if (resultsec) *resultsec = check;
|
||||||
|
@ -918,10 +918,10 @@ double sector_t::LowestFloorAt(const DVector2 &p, sector_t **resultsec)
|
||||||
DVector2 pos = p;
|
DVector2 pos = p;
|
||||||
|
|
||||||
// Continue until we find a blocking portal or a portal above where we actually are.
|
// Continue until we find a blocking portal or a portal above where we actually are.
|
||||||
while (!check->PortalBlocksMovement(floor) && planeheight > check->SkyBoxes[floor]->specialf1)
|
while (!check->PortalBlocksMovement(floor) && planeheight > check->GetPortalPlaneZ(floor))
|
||||||
{
|
{
|
||||||
pos += check->SkyBoxes[floor]->Scale;
|
pos += check->GetPortalDisplacement(floor);
|
||||||
planeheight = check->SkyBoxes[floor]->specialf1;
|
planeheight = check->GetPortalPlaneZ(ceiling);
|
||||||
check = P_PointInSector(pos);
|
check = P_PointInSector(pos);
|
||||||
}
|
}
|
||||||
if (resultsec) *resultsec = check;
|
if (resultsec) *resultsec = check;
|
||||||
|
@ -956,7 +956,7 @@ double sector_t::NextHighestCeilingAt(double x, double y, double bottomz, double
|
||||||
return ff_bottom;
|
return ff_bottom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((flags & FFCF_NOPORTALS) || sec->PortalBlocksMovement(ceiling) || planeheight >= sec->SkyBoxes[ceiling]->specialf1)
|
if ((flags & FFCF_NOPORTALS) || sec->PortalBlocksMovement(ceiling) || planeheight >= sec->GetPortalPlaneZ(ceiling))
|
||||||
{ // Use sector's floor
|
{ // Use sector's floor
|
||||||
if (resultffloor) *resultffloor = NULL;
|
if (resultffloor) *resultffloor = NULL;
|
||||||
if (resultsec) *resultsec = sec;
|
if (resultsec) *resultsec = sec;
|
||||||
|
@ -964,10 +964,10 @@ double sector_t::NextHighestCeilingAt(double x, double y, double bottomz, double
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DVector2 pos = sec->SkyBoxes[ceiling]->Scale;
|
DVector2 pos = sec->GetPortalDisplacement(ceiling);
|
||||||
x += pos.X;
|
x += pos.X;
|
||||||
y += pos.Y;
|
y += pos.Y;
|
||||||
planeheight = sec->SkyBoxes[ceiling]->specialf1;
|
planeheight = sec->GetPortalPlaneZ(ceiling);
|
||||||
sec = P_PointInSector(x, y);
|
sec = P_PointInSector(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1001,7 +1001,7 @@ double sector_t::NextLowestFloorAt(double x, double y, double z, int flags, doub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((flags & FFCF_NOPORTALS) || sec->PortalBlocksMovement(sector_t::floor) || planeheight <= sec->SkyBoxes[floor]->specialf1)
|
if ((flags & FFCF_NOPORTALS) || sec->PortalBlocksMovement(sector_t::floor) || planeheight <= sec->GetPortalPlaneZ(floor))
|
||||||
{ // Use sector's floor
|
{ // Use sector's floor
|
||||||
if (resultffloor) *resultffloor = NULL;
|
if (resultffloor) *resultffloor = NULL;
|
||||||
if (resultsec) *resultsec = sec;
|
if (resultsec) *resultsec = sec;
|
||||||
|
@ -1009,10 +1009,10 @@ double sector_t::NextLowestFloorAt(double x, double y, double z, int flags, doub
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DVector2 pos = sec->SkyBoxes[floor]->Scale;
|
DVector2 pos = sec->GetPortalDisplacement(floor);
|
||||||
x += pos.X;
|
x += pos.X;
|
||||||
y += pos.Y;
|
y += pos.Y;
|
||||||
planeheight = sec->SkyBoxes[floor]->specialf1;
|
planeheight = sec->GetPortalPlaneZ(floor);
|
||||||
sec = P_PointInSector(x, y);
|
sec = P_PointInSector(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -254,11 +254,11 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
|
||||||
|
|
||||||
if (portaldir != sector_t::floor && (open.portalflags & SO_TOPBACK) && !(open.portalflags & SO_TOPFRONT))
|
if (portaldir != sector_t::floor && (open.portalflags & SO_TOPBACK) && !(open.portalflags & SO_TOPFRONT))
|
||||||
{
|
{
|
||||||
portals.Push({ in->frac, topslope, bottomslope, sector_t::ceiling, backsec->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup });
|
portals.Push({ in->frac, topslope, bottomslope, sector_t::ceiling, backsec->GetOppositePortalGroup(sector_t::ceiling) });
|
||||||
}
|
}
|
||||||
if (portaldir != sector_t::ceiling && (open.portalflags & SO_BOTTOMBACK) && !(open.portalflags & SO_BOTTOMFRONT))
|
if (portaldir != sector_t::ceiling && (open.portalflags & SO_BOTTOMBACK) && !(open.portalflags & SO_BOTTOMFRONT))
|
||||||
{
|
{
|
||||||
portals.Push({ in->frac, topslope, bottomslope, sector_t::floor, backsec->SkyBoxes[sector_t::floor]->Sector->PortalGroup });
|
portals.Push({ in->frac, topslope, bottomslope, sector_t::floor, backsec->GetOppositePortalGroup(sector_t::floor) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lport)
|
if (lport)
|
||||||
|
@ -628,11 +628,11 @@ bool SightCheck::P_SightPathTraverse ()
|
||||||
// We also must check if the starting sector contains portals, and start sight checks in those as well.
|
// We also must check if the starting sector contains portals, and start sight checks in those as well.
|
||||||
if (portaldir != sector_t::floor && checkceiling && !lastsector->PortalBlocksSight(sector_t::ceiling))
|
if (portaldir != sector_t::floor && checkceiling && !lastsector->PortalBlocksSight(sector_t::ceiling))
|
||||||
{
|
{
|
||||||
portals.Push({ 0, topslope, bottomslope, sector_t::ceiling, lastsector->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup });
|
portals.Push({ 0, topslope, bottomslope, sector_t::ceiling, lastsector->GetOppositePortalGroup(sector_t::ceiling) });
|
||||||
}
|
}
|
||||||
if (portaldir != sector_t::ceiling && checkfloor && !lastsector->PortalBlocksSight(sector_t::floor))
|
if (portaldir != sector_t::ceiling && checkfloor && !lastsector->PortalBlocksSight(sector_t::floor))
|
||||||
{
|
{
|
||||||
portals.Push({ 0, topslope, bottomslope, sector_t::floor, lastsector->SkyBoxes[sector_t::floor]->Sector->PortalGroup });
|
portals.Push({ 0, topslope, bottomslope, sector_t::floor, lastsector->GetOppositePortalGroup(sector_t::floor) });
|
||||||
}
|
}
|
||||||
|
|
||||||
x1 -= bmaporgx;
|
x1 -= bmaporgx;
|
||||||
|
|
|
@ -112,10 +112,9 @@ static void GetPortalTransition(DVector3 &pos, sector_t *&sec)
|
||||||
|
|
||||||
while (!sec->PortalBlocksMovement(sector_t::ceiling))
|
while (!sec->PortalBlocksMovement(sector_t::ceiling))
|
||||||
{
|
{
|
||||||
AActor *port = sec->SkyBoxes[sector_t::ceiling];
|
if (pos.Z > sec->GetPortalPlaneZ(sector_t::ceiling))
|
||||||
if (pos.Z > port->specialf1)
|
|
||||||
{
|
{
|
||||||
pos += port->Scale;
|
pos += sec->GetPortalDisplacement(sector_t::ceiling);
|
||||||
sec = P_PointInSector(pos);
|
sec = P_PointInSector(pos);
|
||||||
moved = true;
|
moved = true;
|
||||||
}
|
}
|
||||||
|
@ -125,10 +124,9 @@ static void GetPortalTransition(DVector3 &pos, sector_t *&sec)
|
||||||
{
|
{
|
||||||
while (!sec->PortalBlocksMovement(sector_t::floor))
|
while (!sec->PortalBlocksMovement(sector_t::floor))
|
||||||
{
|
{
|
||||||
AActor *port = sec->SkyBoxes[sector_t::floor];
|
if (pos.Z <= sec->GetPortalPlaneZ(sector_t::floor))
|
||||||
if (pos.Z <= port->specialf1)
|
|
||||||
{
|
{
|
||||||
pos += port->Scale;
|
pos += sec->GetPortalDisplacement(sector_t::floor);
|
||||||
sec = P_PointInSector(pos);
|
sec = P_PointInSector(pos);
|
||||||
}
|
}
|
||||||
else break;
|
else break;
|
||||||
|
@ -208,18 +206,17 @@ bool Trace(const DVector3 &start, sector_t *sector, const DVector3 &direction, d
|
||||||
|
|
||||||
void FTraceInfo::EnterSectorPortal(FPathTraverse &pt, int position, double frac, sector_t *entersec)
|
void FTraceInfo::EnterSectorPortal(FPathTraverse &pt, int position, double frac, sector_t *entersec)
|
||||||
{
|
{
|
||||||
AActor *portal = entersec->SkyBoxes[position];
|
DVector2 displacement = entersec->GetPortalDisplacement(position);;
|
||||||
|
|
||||||
double enterdist = MaxDist * frac;
|
double enterdist = MaxDist * frac;
|
||||||
DVector3 exit = Start + enterdist * Vec;
|
DVector3 exit = Start + enterdist * Vec;
|
||||||
DVector3 enter = exit + portal->Scale;
|
DVector3 enter = exit + displacement;
|
||||||
|
|
||||||
Start += portal->Scale;
|
Start += displacement;
|
||||||
CurSector = P_PointInSector(enter);
|
CurSector = P_PointInSector(enter);
|
||||||
inshootthrough = true;
|
inshootthrough = true;
|
||||||
startfrac = frac;
|
startfrac = frac;
|
||||||
EnterDist = enterdist;
|
EnterDist = enterdist;
|
||||||
pt.PortalRelocate(portal, ptflags, frac);
|
pt.PortalRelocate(entersec->SkyBoxes[position], ptflags, frac);
|
||||||
|
|
||||||
if ((TraceFlags & TRACE_ReportPortals) && TraceCallback != NULL)
|
if ((TraceFlags & TRACE_ReportPortals) && TraceCallback != NULL)
|
||||||
{
|
{
|
||||||
|
@ -763,7 +760,7 @@ bool FTraceInfo::TraceTraverse (int ptflags)
|
||||||
if (Vec.Z < 0 && !CurSector->PortalBlocksMovement(sector_t::floor))
|
if (Vec.Z < 0 && !CurSector->PortalBlocksMovement(sector_t::floor))
|
||||||
{
|
{
|
||||||
// calculate position where the portal is crossed
|
// calculate position where the portal is crossed
|
||||||
double portz = CurSector->SkyBoxes[sector_t::floor]->specialf1;
|
double portz = CurSector->GetPortalPlaneZ(sector_t::floor);
|
||||||
if (hit.Z < portz && limitz > portz)
|
if (hit.Z < portz && limitz > portz)
|
||||||
{
|
{
|
||||||
limitz = portz;
|
limitz = portz;
|
||||||
|
@ -775,7 +772,7 @@ bool FTraceInfo::TraceTraverse (int ptflags)
|
||||||
else if (Vec.Z > 0 && !CurSector->PortalBlocksMovement(sector_t::ceiling))
|
else if (Vec.Z > 0 && !CurSector->PortalBlocksMovement(sector_t::ceiling))
|
||||||
{
|
{
|
||||||
// calculate position where the portal is crossed
|
// calculate position where the portal is crossed
|
||||||
double portz = CurSector->SkyBoxes[sector_t::ceiling]->specialf1;
|
double portz = CurSector->GetPortalPlaneZ(sector_t::ceiling);
|
||||||
if (hit.Z > portz && limitz < portz)
|
if (hit.Z > portz && limitz < portz)
|
||||||
{
|
{
|
||||||
limitz = portz;
|
limitz = portz;
|
||||||
|
|
|
@ -1050,8 +1050,8 @@ void P_CreateLinkedPortals()
|
||||||
}
|
}
|
||||||
if (sectors[i].PortalIsLinked(sector_t::ceiling) && sectors[i].PortalIsLinked(sector_t::floor))
|
if (sectors[i].PortalIsLinked(sector_t::ceiling) && sectors[i].PortalIsLinked(sector_t::floor))
|
||||||
{
|
{
|
||||||
double cz = sectors[i].SkyBoxes[sector_t::ceiling]->specialf1;
|
double cz = sectors[i].GetPortalPlaneZ(sector_t::ceiling);
|
||||||
double fz = sectors[i].SkyBoxes[sector_t::floor]->specialf1;
|
double fz = sectors[i].GetPortalPlaneZ(sector_t::floor);
|
||||||
if (cz < fz)
|
if (cz < fz)
|
||||||
{
|
{
|
||||||
// This is a fatal condition. We have to remove one of the two portals. Choose the one that doesn't match the current plane
|
// This is a fatal condition. We have to remove one of the two portals. Choose the one that doesn't match the current plane
|
||||||
|
@ -1162,22 +1162,22 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u
|
||||||
{
|
{
|
||||||
sector_t *sec = P_PointInSector(position);
|
sector_t *sec = P_PointInSector(position);
|
||||||
sector_t *wsec = sec;
|
sector_t *wsec = sec;
|
||||||
while (!wsec->PortalBlocksMovement(sector_t::ceiling) && upperz > wsec->SkyBoxes[sector_t::ceiling]->specialf1)
|
while (!wsec->PortalBlocksMovement(sector_t::ceiling) && upperz > wsec->GetPortalPlaneZ(sector_t::ceiling))
|
||||||
{
|
{
|
||||||
sector_t *othersec = wsec->SkyBoxes[sector_t::ceiling]->Sector;
|
int othergroup = wsec->GetOppositePortalGroup(sector_t::ceiling);
|
||||||
DVector2 pos = Displacements.getOffset(startgroup, othersec->PortalGroup) + position;
|
DVector2 pos = Displacements.getOffset(startgroup, othergroup) + position;
|
||||||
processMask.setBit(othersec->PortalGroup);
|
processMask.setBit(othergroup);
|
||||||
out.Add(othersec->PortalGroup | FPortalGroupArray::UPPER);
|
out.Add(othergroup | FPortalGroupArray::UPPER);
|
||||||
wsec = P_PointInSector(pos); // get upper sector at the exact spot we want to check and repeat
|
wsec = P_PointInSector(pos); // get upper sector at the exact spot we want to check and repeat
|
||||||
retval = true;
|
retval = true;
|
||||||
}
|
}
|
||||||
wsec = sec;
|
wsec = sec;
|
||||||
while (!wsec->PortalBlocksMovement(sector_t::floor) && position.Z < wsec->SkyBoxes[sector_t::floor]->specialf1)
|
while (!wsec->PortalBlocksMovement(sector_t::floor) && position.Z < wsec->GetPortalPlaneZ(sector_t::floor))
|
||||||
{
|
{
|
||||||
sector_t *othersec = wsec->SkyBoxes[sector_t::floor]->Sector;
|
int othergroup = wsec->GetOppositePortalGroup(sector_t::floor);
|
||||||
DVector2 pos = Displacements.getOffset(startgroup, othersec->PortalGroup) + position;
|
DVector2 pos = Displacements.getOffset(startgroup, othergroup) + position;
|
||||||
processMask.setBit(othersec->PortalGroup | FPortalGroupArray::LOWER);
|
processMask.setBit(othergroup | FPortalGroupArray::LOWER);
|
||||||
out.Add(othersec->PortalGroup);
|
out.Add(othergroup);
|
||||||
wsec = P_PointInSector(pos); // get lower sector at the exact spot we want to check and repeat
|
wsec = P_PointInSector(pos); // get lower sector at the exact spot we want to check and repeat
|
||||||
retval = true;
|
retval = true;
|
||||||
}
|
}
|
||||||
|
@ -1204,9 +1204,9 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u
|
||||||
sector_t *sec = s ? ld->backsector : ld->frontsector;
|
sector_t *sec = s ? ld->backsector : ld->frontsector;
|
||||||
if (sec && !(sec->PortalBlocksMovement(sector_t::ceiling)))
|
if (sec && !(sec->PortalBlocksMovement(sector_t::ceiling)))
|
||||||
{
|
{
|
||||||
if (sec->SkyBoxes[sector_t::ceiling]->specialf1 < upperz)
|
if (sec->GetPortalPlaneZ(sector_t::ceiling) < upperz)
|
||||||
{
|
{
|
||||||
int grp = sec->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup;
|
int grp = sec->GetOppositePortalGroup(sector_t::ceiling);
|
||||||
if (!(processMask.getBit(grp)))
|
if (!(processMask.getBit(grp)))
|
||||||
{
|
{
|
||||||
processMask.setBit(grp);
|
processMask.setBit(grp);
|
||||||
|
@ -1223,9 +1223,9 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u
|
||||||
sector_t *sec = s ? ld->backsector : ld->frontsector;
|
sector_t *sec = s ? ld->backsector : ld->frontsector;
|
||||||
if (sec && !(sec->PortalBlocksMovement(sector_t::floor)))
|
if (sec && !(sec->PortalBlocksMovement(sector_t::floor)))
|
||||||
{
|
{
|
||||||
if (sec->SkyBoxes[sector_t::floor]->specialf1 > position.Z)
|
if (sec->GetPortalPlaneZ(sector_t::floor) > position.Z)
|
||||||
{
|
{
|
||||||
int grp = sec->SkyBoxes[sector_t::floor]->Sector->PortalGroup;
|
int grp = sec->GetOppositePortalGroup(sector_t::floor);
|
||||||
if (!(processMask.getBit(grp)))
|
if (!(processMask.getBit(grp)))
|
||||||
{
|
{
|
||||||
processMask.setBit(grp);
|
processMask.setBit(grp);
|
||||||
|
|
25
src/r_defs.h
25
src/r_defs.h
|
@ -964,7 +964,7 @@ public:
|
||||||
bool PortalBlocksView(int plane)
|
bool PortalBlocksView(int plane)
|
||||||
{
|
{
|
||||||
if (SkyBoxes[plane] == NULL) return true;
|
if (SkyBoxes[plane] == NULL) return true;
|
||||||
if (SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return false;
|
if (GetPortalType(plane) != SKYBOX_LINKEDPORTAL) return false;
|
||||||
return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -985,7 +985,28 @@ public:
|
||||||
|
|
||||||
bool PortalIsLinked(int plane)
|
bool PortalIsLinked(int plane)
|
||||||
{
|
{
|
||||||
return (SkyBoxes[plane] != NULL && SkyBoxes[plane]->special1 == SKYBOX_LINKEDPORTAL);
|
return (SkyBoxes[plane] != NULL && GetPortalType(plane) == SKYBOX_LINKEDPORTAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// These intentionally do not validate the SkyBoxes pointers.
|
||||||
|
double GetPortalPlaneZ(int plane)
|
||||||
|
{
|
||||||
|
return SkyBoxes[plane]->specialf1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DVector2 GetPortalDisplacement(int plane)
|
||||||
|
{
|
||||||
|
return SkyBoxes[plane]->Scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetPortalType(int plane)
|
||||||
|
{
|
||||||
|
return SkyBoxes[plane]->special1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetOppositePortalGroup(int plane)
|
||||||
|
{
|
||||||
|
return SkyBoxes[plane]->Sector->PortalGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetVerticesDirty()
|
void SetVerticesDirty()
|
||||||
|
|
|
@ -694,10 +694,9 @@ void R_InterpolateView (player_t *player, double Frac, InterpolationViewer *ivie
|
||||||
bool moved = false;
|
bool moved = false;
|
||||||
while (!viewsector->PortalBlocksMovement(sector_t::ceiling))
|
while (!viewsector->PortalBlocksMovement(sector_t::ceiling))
|
||||||
{
|
{
|
||||||
AActor *point = viewsector->SkyBoxes[sector_t::ceiling];
|
if (ViewPos.Z > viewsector->GetPortalPlaneZ(sector_t::ceiling))
|
||||||
if (ViewPos.Z > point->specialf1)
|
|
||||||
{
|
{
|
||||||
ViewPos += point->Scale;
|
ViewPos += viewsector->GetPortalDisplacement(sector_t::ceiling);
|
||||||
viewsector = R_PointInSubsector(ViewPos)->sector;
|
viewsector = R_PointInSubsector(ViewPos)->sector;
|
||||||
moved = true;
|
moved = true;
|
||||||
}
|
}
|
||||||
|
@ -707,10 +706,9 @@ void R_InterpolateView (player_t *player, double Frac, InterpolationViewer *ivie
|
||||||
{
|
{
|
||||||
while (!viewsector->PortalBlocksMovement(sector_t::floor))
|
while (!viewsector->PortalBlocksMovement(sector_t::floor))
|
||||||
{
|
{
|
||||||
AActor *point = viewsector->SkyBoxes[sector_t::floor];
|
if (ViewPos.Z < viewsector->GetPortalPlaneZ(sector_t::floor))
|
||||||
if (ViewPos.Z < point->specialf1)
|
|
||||||
{
|
{
|
||||||
ViewPos += point->Scale;
|
ViewPos += viewsector->GetPortalDisplacement(sector_t::floor);
|
||||||
viewsector = R_PointInSubsector(ViewPos)->sector;
|
viewsector = R_PointInSubsector(ViewPos)->sector;
|
||||||
moved = true;
|
moved = true;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -56,6 +56,7 @@ static FxExpression *ParseRandom(FScanner &sc, FName identifier, PClassActor *cl
|
||||||
static FxExpression *ParseRandomPick(FScanner &sc, FName identifier, PClassActor *cls);
|
static FxExpression *ParseRandomPick(FScanner &sc, FName identifier, PClassActor *cls);
|
||||||
static FxExpression *ParseRandom2(FScanner &sc, PClassActor *cls);
|
static FxExpression *ParseRandom2(FScanner &sc, PClassActor *cls);
|
||||||
static FxExpression *ParseAbs(FScanner &sc, PClassActor *cls);
|
static FxExpression *ParseAbs(FScanner &sc, PClassActor *cls);
|
||||||
|
static FxExpression *ParseAtan2(FScanner &sc, FName identifier, PClassActor *cls);
|
||||||
static FxExpression *ParseMinMax(FScanner &sc, FName identifier, PClassActor *cls);
|
static FxExpression *ParseMinMax(FScanner &sc, FName identifier, PClassActor *cls);
|
||||||
static FxExpression *ParseClamp(FScanner &sc, PClassActor *cls);
|
static FxExpression *ParseClamp(FScanner &sc, PClassActor *cls);
|
||||||
|
|
||||||
|
@ -386,6 +387,9 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls)
|
||||||
return ParseClamp(sc, cls);
|
return ParseClamp(sc, cls);
|
||||||
case NAME_Abs:
|
case NAME_Abs:
|
||||||
return ParseAbs(sc, cls);
|
return ParseAbs(sc, cls);
|
||||||
|
case NAME_ATan2:
|
||||||
|
case NAME_VectorAngle:
|
||||||
|
return ParseAtan2(sc, identifier, cls);
|
||||||
default:
|
default:
|
||||||
args = new FArgumentList;
|
args = new FArgumentList;
|
||||||
func = dyn_cast<PFunction>(cls->Symbols.FindSymbol(identifier, true));
|
func = dyn_cast<PFunction>(cls->Symbols.FindSymbol(identifier, true));
|
||||||
|
@ -511,6 +515,15 @@ static FxExpression *ParseAbs(FScanner &sc, PClassActor *cls)
|
||||||
return new FxAbs(x);
|
return new FxAbs(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FxExpression *ParseAtan2(FScanner &sc, FName identifier, PClassActor *cls)
|
||||||
|
{
|
||||||
|
FxExpression *a = ParseExpressionM(sc, cls);
|
||||||
|
sc.MustGetToken(',');
|
||||||
|
FxExpression *b = ParseExpressionM(sc, cls);
|
||||||
|
sc.MustGetToken(')');
|
||||||
|
return identifier == NAME_ATan2 ? new FxATan2(a, b, sc) : new FxATan2(b, a, sc);
|
||||||
|
}
|
||||||
|
|
||||||
static FxExpression *ParseMinMax(FScanner &sc, FName identifier, PClassActor *cls)
|
static FxExpression *ParseMinMax(FScanner &sc, FName identifier, PClassActor *cls)
|
||||||
{
|
{
|
||||||
TArray<FxExpression*> list;
|
TArray<FxExpression*> list;
|
||||||
|
|
|
@ -623,6 +623,27 @@ public:
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
class FxATan2 : public FxExpression
|
||||||
|
{
|
||||||
|
FxExpression *yval, *xval;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FxATan2(FxExpression *y, FxExpression *x, const FScriptPosition &pos);
|
||||||
|
~FxATan2();
|
||||||
|
FxExpression *Resolve(FCompileContext&);
|
||||||
|
|
||||||
|
ExpEmit Emit(VMFunctionBuilder *build);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ExpEmit ToReg(VMFunctionBuilder *build, FxExpression *val);
|
||||||
|
};
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
class FxMinMax : public FxExpression
|
class FxMinMax : public FxExpression
|
||||||
{
|
{
|
||||||
TDeletingArray<FxExpression *> choices;
|
TDeletingArray<FxExpression *> choices;
|
||||||
|
@ -860,6 +881,7 @@ public:
|
||||||
ExpEmit Emit(VMFunctionBuilder *build, bool tailcall);
|
ExpEmit Emit(VMFunctionBuilder *build, bool tailcall);
|
||||||
bool CheckEmitCast(VMFunctionBuilder *build, bool returnit, ExpEmit ®);
|
bool CheckEmitCast(VMFunctionBuilder *build, bool returnit, ExpEmit ®);
|
||||||
unsigned GetArgCount() const { return ArgList == NULL ? 0 : ArgList->Size(); }
|
unsigned GetArgCount() const { return ArgList == NULL ? 0 : ArgList->Size(); }
|
||||||
|
PFunction *GetFunction() const { return Function; }
|
||||||
VMFunction *GetVMFunction() const { return Function->Variants[0].Implementation; }
|
VMFunction *GetVMFunction() const { return Function->Variants[0].Implementation; }
|
||||||
bool IsDirectFunction();
|
bool IsDirectFunction();
|
||||||
};
|
};
|
||||||
|
|
|
@ -1991,6 +1991,99 @@ ExpEmit FxAbs::Emit(VMFunctionBuilder *build)
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
FxATan2::FxATan2(FxExpression *y, FxExpression *x, const FScriptPosition &pos)
|
||||||
|
: FxExpression(pos)
|
||||||
|
{
|
||||||
|
yval = y;
|
||||||
|
xval = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
FxATan2::~FxATan2()
|
||||||
|
{
|
||||||
|
SAFE_DELETE(yval);
|
||||||
|
SAFE_DELETE(xval);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
FxExpression *FxATan2::Resolve(FCompileContext &ctx)
|
||||||
|
{
|
||||||
|
CHECKRESOLVED();
|
||||||
|
SAFE_RESOLVE(yval, ctx);
|
||||||
|
SAFE_RESOLVE(xval, ctx);
|
||||||
|
|
||||||
|
if (!yval->IsNumeric() || !xval->IsNumeric())
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_ERROR, "numeric value expected for parameter");
|
||||||
|
delete this;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (yval->isConstant() && xval->isConstant())
|
||||||
|
{
|
||||||
|
double y = static_cast<FxConstant *>(yval)->GetValue().GetFloat();
|
||||||
|
double x = static_cast<FxConstant *>(xval)->GetValue().GetFloat();
|
||||||
|
FxExpression *z = new FxConstant(g_atan2(y, x) * (180 / M_PI), ScriptPosition);
|
||||||
|
delete this;
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
if (yval->ValueType->GetRegType() != REGT_FLOAT && !yval->isConstant())
|
||||||
|
{
|
||||||
|
yval = new FxFloatCast(yval);
|
||||||
|
}
|
||||||
|
if (xval->ValueType->GetRegType() != REGT_FLOAT && !xval->isConstant())
|
||||||
|
{
|
||||||
|
xval = new FxFloatCast(xval);
|
||||||
|
}
|
||||||
|
ValueType = TypeFloat64;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
ExpEmit FxATan2::Emit(VMFunctionBuilder *build)
|
||||||
|
{
|
||||||
|
ExpEmit yreg = ToReg(build, yval);
|
||||||
|
ExpEmit xreg = ToReg(build, xval);
|
||||||
|
yreg.Free(build);
|
||||||
|
xreg.Free(build);
|
||||||
|
ExpEmit out(build, REGT_FLOAT);
|
||||||
|
build->Emit(OP_ATAN2, out.RegNum, yreg.RegNum, xreg.RegNum);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// The atan2 opcode only takes registers as parameters, so any constants
|
||||||
|
// must be loaded into registers first.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
ExpEmit FxATan2::ToReg(VMFunctionBuilder *build, FxExpression *val)
|
||||||
|
{
|
||||||
|
if (val->isConstant())
|
||||||
|
{
|
||||||
|
ExpEmit reg(build, REGT_FLOAT);
|
||||||
|
build->Emit(OP_LKF, reg.RegNum, build->GetConstantFloat(static_cast<FxConstant*>(val)->GetValue().GetFloat()));
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
|
return val->Emit(build);
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -3751,7 +3844,7 @@ VMFunction *FxReturnStatement::GetDirectFunction()
|
||||||
// then it can be a "direct" function. That is, the DECORATE
|
// then it can be a "direct" function. That is, the DECORATE
|
||||||
// definition can call that function directly without wrapping
|
// definition can call that function directly without wrapping
|
||||||
// it inside VM code.
|
// it inside VM code.
|
||||||
if (Call != NULL && Call->GetArgCount() == 0)
|
if (Call != NULL && Call->GetArgCount() == 0 && (Call->GetFunction()->Flags & VARF_Action))
|
||||||
{
|
{
|
||||||
return Call->GetVMFunction();
|
return Call->GetVMFunction();
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,7 +473,7 @@ static void ParseNativeFunction(FScanner &sc, PClassActor *cls)
|
||||||
FScriptPosition::ErrorCounter++;
|
FScriptPosition::ErrorCounter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the type and make sure it's int or float.
|
// Read the type and make sure it's acceptable.
|
||||||
sc.MustGetAnyToken();
|
sc.MustGetAnyToken();
|
||||||
switch (sc.TokenType)
|
switch (sc.TokenType)
|
||||||
{
|
{
|
||||||
|
@ -490,6 +490,9 @@ static void ParseNativeFunction(FScanner &sc, PClassActor *cls)
|
||||||
rets.Push(TypeState);
|
rets.Push(TypeState);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TK_Void:
|
||||||
|
break;
|
||||||
|
|
||||||
case TK_Identifier:
|
case TK_Identifier:
|
||||||
rets.Push(NewPointer(RUNTIME_CLASS(DObject)));
|
rets.Push(NewPointer(RUNTIME_CLASS(DObject)));
|
||||||
// Todo: Object type
|
// Todo: Object type
|
||||||
|
|
|
@ -476,7 +476,7 @@ static int print_reg(FILE *out, int col, int arg, int mode, int immshift, const
|
||||||
case MODE_KF:
|
case MODE_KF:
|
||||||
if (func != NULL)
|
if (func != NULL)
|
||||||
{
|
{
|
||||||
return col+printf_wrapper(out, "%g", func->KonstF[arg]);
|
return col+printf_wrapper(out, "%#g", func->KonstF[arg]);
|
||||||
}
|
}
|
||||||
return col+printf_wrapper(out, "kf%d", arg);
|
return col+printf_wrapper(out, "kf%d", arg);
|
||||||
case MODE_KS:
|
case MODE_KS:
|
||||||
|
|
|
@ -1039,6 +1039,11 @@ begin:
|
||||||
reg.f[a] = reg.f[B] > konstf[C] ? reg.f[B] : konstf[C];
|
reg.f[a] = reg.f[B] > konstf[C] ? reg.f[B] : konstf[C];
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
|
|
||||||
|
OP(ATAN2):
|
||||||
|
ASSERTF(a); ASSERTF(B); ASSERTF(C);
|
||||||
|
reg.f[a] = g_atan2(reg.f[B], reg.f[C]) * (180 / M_PI);
|
||||||
|
NEXTOP;
|
||||||
|
|
||||||
OP(FLOP):
|
OP(FLOP):
|
||||||
ASSERTF(a); ASSERTF(B);
|
ASSERTF(a); ASSERTF(B);
|
||||||
fb = reg.f[B];
|
fb = reg.f[B];
|
||||||
|
|
|
@ -174,6 +174,7 @@ xx(MINF_RR, min, RFRFRF), // fA = min(fB),fkC)
|
||||||
xx(MINF_RK, min, RFRFKF),
|
xx(MINF_RK, min, RFRFKF),
|
||||||
xx(MAXF_RR, max, RFRFRF), // fA = max(fB),fkC)
|
xx(MAXF_RR, max, RFRFRF), // fA = max(fB),fkC)
|
||||||
xx(MAXF_RK, max, RFRFKF),
|
xx(MAXF_RK, max, RFRFKF),
|
||||||
|
xx(ATAN2, atan2, RFRFRF), // fA = atan2(fB,fC), result is in degrees
|
||||||
xx(FLOP, flop, RFRFI8), // fA = f(fB), where function is selected by C
|
xx(FLOP, flop, RFRFI8), // fA = f(fB), where function is selected by C
|
||||||
xx(EQF_R, beq, CFRR), // if ((fB == fkC) != (A & 1)) then pc++
|
xx(EQF_R, beq, CFRR), // if ((fB == fkC) != (A & 1)) then pc++
|
||||||
xx(EQF_K, beq, CFRK),
|
xx(EQF_K, beq, CFRK),
|
||||||
|
|
|
@ -110,7 +110,7 @@ ACTOR Actor native //: Thinker
|
||||||
action native A_Die(name damagetype = "none");
|
action native A_Die(name damagetype = "none");
|
||||||
action native A_Detonate();
|
action native A_Detonate();
|
||||||
action native A_Mushroom(class<Actor> spawntype = "FatShot", int numspawns = 0, int flags = 0, float vrange = 4.0, float hrange = 0.5);
|
action native A_Mushroom(class<Actor> spawntype = "FatShot", int numspawns = 0, int flags = 0, float vrange = 4.0, float hrange = 0.5);
|
||||||
action native bool A_CallSpecial(int special, int arg1=0, int arg2=0, int arg3=0, int arg4=0, int arg5=0);
|
native bool A_CallSpecial(int special, int arg1=0, int arg2=0, int arg3=0, int arg4=0, int arg5=0);
|
||||||
|
|
||||||
action native A_SetFloorClip();
|
action native A_SetFloorClip();
|
||||||
action native A_UnSetFloorClip();
|
action native A_UnSetFloorClip();
|
||||||
|
@ -127,7 +127,7 @@ ACTOR Actor native //: Thinker
|
||||||
action native A_NoGravity();
|
action native A_NoGravity();
|
||||||
action native A_Gravity();
|
action native A_Gravity();
|
||||||
action native A_LowGravity();
|
action native A_LowGravity();
|
||||||
action native A_SetGravity(float gravity);
|
native void A_SetGravity(float gravity);
|
||||||
action native A_Fall();
|
action native A_Fall();
|
||||||
action native A_SetSolid();
|
action native A_SetSolid();
|
||||||
action native A_UnsetSolid();
|
action native A_UnsetSolid();
|
||||||
|
@ -168,7 +168,7 @@ ACTOR Actor native //: Thinker
|
||||||
action native A_ClearSoundTarget();
|
action native A_ClearSoundTarget();
|
||||||
action native A_FireAssaultGun();
|
action native A_FireAssaultGun();
|
||||||
action native A_CheckTerrain();
|
action native A_CheckTerrain();
|
||||||
action native A_FaceConsolePlayer(float MaxTurnAngle = 0); // [TP]
|
action native A_FaceConsolePlayer(float MaxTurnAngle = 0); // [TP] no-op
|
||||||
|
|
||||||
action native A_MissileAttack();
|
action native A_MissileAttack();
|
||||||
action native A_MeleeAttack();
|
action native A_MeleeAttack();
|
||||||
|
@ -176,71 +176,71 @@ ACTOR Actor native //: Thinker
|
||||||
action native A_BulletAttack();
|
action native A_BulletAttack();
|
||||||
action native A_WolfAttack(int flags = 0, sound whattoplay = "weapons/pistol", float snipe = 1.0, int maxdamage = 64, int blocksize = 128, int pointblank = 2, int longrange = 4, float runspeed = 160.0, class<Actor> pufftype = "BulletPuff");
|
action native A_WolfAttack(int flags = 0, sound whattoplay = "weapons/pistol", float snipe = 1.0, int maxdamage = 64, int blocksize = 128, int pointblank = 2, int longrange = 4, float runspeed = 160.0, class<Actor> pufftype = "BulletPuff");
|
||||||
action native A_PlaySound(sound whattoplay = "weapons/pistol", int slot = CHAN_BODY, float volume = 1.0, bool looping = false, float attenuation = ATTN_NORM);
|
action native A_PlaySound(sound whattoplay = "weapons/pistol", int slot = CHAN_BODY, float volume = 1.0, bool looping = false, float attenuation = ATTN_NORM);
|
||||||
action native A_PlayWeaponSound(sound whattoplay);
|
native void A_PlayWeaponSound(sound whattoplay);
|
||||||
action native A_FLoopActiveSound();
|
action native A_FLoopActiveSound();
|
||||||
action native A_LoopActiveSound();
|
action native A_LoopActiveSound();
|
||||||
action native A_StopSound(int slot = CHAN_VOICE); // Bad default but that's what is originally was...
|
action native A_StopSound(int slot = CHAN_VOICE); // Bad default but that's what is originally was...
|
||||||
action native A_PlaySoundEx(sound whattoplay, coerce name slot, bool looping = false, int attenuation = 0);
|
native void A_PlaySoundEx(sound whattoplay, coerce name slot, bool looping = false, int attenuation = 0);
|
||||||
action native A_StopSoundEx(coerce name slot);
|
native void A_StopSoundEx(coerce name slot);
|
||||||
action native A_SeekerMissile(int threshold, int turnmax, int flags = 0, int chance = 50, int distance = 10);
|
native void A_SeekerMissile(int threshold, int turnmax, int flags = 0, int chance = 50, int distance = 10);
|
||||||
action native state A_Jump(int chance = 256, state label, ...);
|
native state A_Jump(int chance = 256, state label, ...);
|
||||||
action native A_CustomMissile(class<Actor> missiletype, float spawnheight = 32, float spawnofs_xy = 0, float angle = 0, int flags = 0, float pitch = 0, int ptr = AAPTR_TARGET);
|
native void A_CustomMissile(class<Actor> missiletype, float spawnheight = 32, float spawnofs_xy = 0, float angle = 0, int flags = 0, float pitch = 0, int ptr = AAPTR_TARGET);
|
||||||
action native A_CustomBulletAttack(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", float range = 0, int flags = 0, int ptr = AAPTR_TARGET);
|
native void A_CustomBulletAttack(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", float range = 0, int flags = 0, int ptr = AAPTR_TARGET);
|
||||||
action native A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = "", color color2 = "", int flags = 0, int aim = 0, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float/*angle*/ spread_xy = 0, float/*angle*/ spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270);
|
native void A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = "", color color2 = "", int flags = 0, int aim = 0, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float/*angle*/ spread_xy = 0, float/*angle*/ spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270);
|
||||||
action native state A_JumpIfHealthLower(int health, state label, int ptr_selector = AAPTR_DEFAULT);
|
native state A_JumpIfHealthLower(int health, state label, int ptr_selector = AAPTR_DEFAULT);
|
||||||
action native state A_JumpIfCloser(float distance, state label, bool noz = false);
|
native state A_JumpIfCloser(float distance, state label, bool noz = false);
|
||||||
action native state A_JumpIfTracerCloser(float distance, state label, bool noz = false);
|
native state A_JumpIfTracerCloser(float distance, state label, bool noz = false);
|
||||||
action native state A_JumpIfMasterCloser(float distance, state label, bool noz = false);
|
native state A_JumpIfMasterCloser(float distance, state label, bool noz = false);
|
||||||
action native state A_JumpIfTargetOutsideMeleeRange(state label);
|
native state A_JumpIfTargetOutsideMeleeRange(state label);
|
||||||
action native state A_JumpIfTargetInsideMeleeRange(state label);
|
native state A_JumpIfTargetInsideMeleeRange(state label);
|
||||||
action native state A_JumpIfInventory(class<Inventory> itemtype, int itemamount, state label, int owner = AAPTR_DEFAULT);
|
native state A_JumpIfInventory(class<Inventory> itemtype, int itemamount, state label, int owner = AAPTR_DEFAULT);
|
||||||
action native state A_JumpIfArmorType(name Type, state label, int amount = 1);
|
native state A_JumpIfArmorType(name Type, state label, int amount = 1);
|
||||||
action native bool A_GiveInventory(class<Inventory> itemtype, int amount = 0, int giveto = AAPTR_DEFAULT);
|
native bool A_GiveInventory(class<Inventory> itemtype, int amount = 0, int giveto = AAPTR_DEFAULT);
|
||||||
action native bool A_TakeInventory(class<Inventory> itemtype, int amount = 0, int flags = 0, int giveto = AAPTR_DEFAULT);
|
native bool A_TakeInventory(class<Inventory> itemtype, int amount = 0, int flags = 0, int giveto = AAPTR_DEFAULT);
|
||||||
action native bool A_SpawnItem(class<Actor> itemtype = "Unknown", float distance = 0, float zheight = 0, bool useammo = true, bool transfer_translation = false);
|
action native bool A_SpawnItem(class<Actor> itemtype = "Unknown", float distance = 0, float zheight = 0, bool useammo = true, bool transfer_translation = false);
|
||||||
action native bool A_SpawnItemEx(class<Actor> itemtype, float xofs = 0, float yofs = 0, float zofs = 0, float xvel = 0, float yvel = 0, float zvel = 0, float angle = 0, int flags = 0, int failchance = 0, int tid=0);
|
native bool A_SpawnItemEx(class<Actor> itemtype, float xofs = 0, float yofs = 0, float zofs = 0, float xvel = 0, float yvel = 0, float zvel = 0, float angle = 0, int flags = 0, int failchance = 0, int tid=0);
|
||||||
action native A_Print(string whattoprint, float time = 0, name fontname = "");
|
native void A_Print(string whattoprint, float time = 0, name fontname = "");
|
||||||
action native A_PrintBold(string whattoprint, float time = 0, name fontname = "");
|
native void A_PrintBold(string whattoprint, float time = 0, name fontname = "");
|
||||||
action native A_Log(string whattoprint);
|
native void A_Log(string whattoprint);
|
||||||
action native A_LogInt(int whattoprint);
|
native void A_LogInt(int whattoprint);
|
||||||
action native A_LogFloat(float whattoprint);
|
native void A_LogFloat(float whattoprint);
|
||||||
action native A_SetTranslucent(float alpha, int style = 0);
|
native void A_SetTranslucent(float alpha, int style = 0);
|
||||||
action native A_FadeIn(float reduce = 0.1, int flags = 0);
|
action native A_FadeIn(float reduce = 0.1, int flags = 0);
|
||||||
action native A_FadeOut(float reduce = 0.1, int flags = 1); //bool remove == true
|
action native A_FadeOut(float reduce = 0.1, int flags = 1); //bool remove == true
|
||||||
action native A_FadeTo(float target, float amount = 0.1, int flags = 0);
|
native void A_FadeTo(float target, float amount = 0.1, int flags = 0);
|
||||||
action native A_SetScale(float scalex, float scaley = 0, int ptr = AAPTR_DEFAULT, bool usezero = false);
|
native void A_SetScale(float scalex, float scaley = 0, int ptr = AAPTR_DEFAULT, bool usezero = false);
|
||||||
action native A_SetMass(int mass);
|
native void A_SetMass(int mass);
|
||||||
action native A_SpawnDebris(class<Actor> spawntype, bool transfer_translation = false, float mult_h = 1, float mult_v = 1);
|
native void A_SpawnDebris(class<Actor> spawntype, bool transfer_translation = false, float mult_h = 1, float mult_v = 1);
|
||||||
action native A_SpawnParticle(color color1, int flags = 0, int lifetime = 35, int size = 1, float angle = 0, float xoff = 0, float yoff = 0, float zoff = 0, float velx = 0, float vely = 0, float velz = 0, float accelx = 0, float accely = 0, float accelz = 0, float startalphaf = 1, float fadestepf = -1);
|
native void A_SpawnParticle(color color1, int flags = 0, int lifetime = 35, int size = 1, float angle = 0, float xoff = 0, float yoff = 0, float zoff = 0, float velx = 0, float vely = 0, float velz = 0, float accelx = 0, float accely = 0, float accelz = 0, float startalphaf = 1, float fadestepf = -1);
|
||||||
action native state A_CheckSight(state label);
|
native state A_CheckSight(state label);
|
||||||
action native A_ExtChase(bool usemelee, bool usemissile, bool playactive = true, bool nightmarefast = false);
|
native void A_ExtChase(bool usemelee, bool usemissile, bool playactive = true, bool nightmarefast = false);
|
||||||
action native A_DropInventory(class<Inventory> itemtype);
|
native void A_DropInventory(class<Inventory> itemtype);
|
||||||
action native A_SetBlend(color color1, float alpha, int tics, color color2 = "");
|
native void A_SetBlend(color color1, float alpha, int tics, color color2 = "");
|
||||||
action native A_ChangeFlag(string flagname, bool value);
|
native void A_ChangeFlag(string flagname, bool value);
|
||||||
action native state A_CheckFlag(string flagname, state label, int check_pointer = AAPTR_DEFAULT);
|
native state A_CheckFlag(string flagname, state label, int check_pointer = AAPTR_DEFAULT);
|
||||||
action native state A_JumpIf(bool expression, state label);
|
native state A_JumpIf(bool expression, state label);
|
||||||
action native A_RaiseMaster(bool copy = 0);
|
action native A_RaiseMaster(bool copy = 0);
|
||||||
action native A_RaiseChildren(bool copy = 0);
|
action native A_RaiseChildren(bool copy = 0);
|
||||||
action native A_RaiseSiblings(bool copy = 0);
|
action native A_RaiseSiblings(bool copy = 0);
|
||||||
action native state A_CheckFloor(state label);
|
native state A_CheckFloor(state label);
|
||||||
action native state A_CheckCeiling(state label);
|
native state A_CheckCeiling(state label);
|
||||||
action native state A_PlayerSkinCheck(state label);
|
native state A_PlayerSkinCheck(state label);
|
||||||
action native A_BasicAttack(int meleedamage, sound meleesound, class<actor> missiletype, float missileheight);
|
native void A_BasicAttack(int meleedamage, sound meleesound, class<actor> missiletype, float missileheight);
|
||||||
action native state, bool A_Teleport(state teleportstate = "", class<SpecialSpot> targettype = "BossSpot", class<Actor> fogtype = "TeleportFog", int flags = 0, float mindist = 0, float maxdist = 0, int ptr = AAPTR_DEFAULT);
|
action native state, bool A_Teleport(state teleportstate = "", class<SpecialSpot> targettype = "BossSpot", class<Actor> fogtype = "TeleportFog", int flags = 0, float mindist = 0, float maxdist = 0, int ptr = AAPTR_DEFAULT);
|
||||||
action native state, bool A_Warp(int ptr_destination, float xofs = 0, float yofs = 0, float zofs = 0, float angle = 0, int flags = 0, state success_state = "", float heightoffset = 0, float radiusoffset = 0, float pitch = 0);
|
action native state, bool A_Warp(int ptr_destination, float xofs = 0, float yofs = 0, float zofs = 0, float angle = 0, int flags = 0, state success_state = "", float heightoffset = 0, float radiusoffset = 0, float pitch = 0);
|
||||||
action native bool A_ThrowGrenade(class<Actor> itemtype, float zheight = 0, float xyvel = 0, float zvel = 0, bool useammo = true);
|
action native bool A_ThrowGrenade(class<Actor> itemtype, float zheight = 0, float xyvel = 0, float zvel = 0, bool useammo = true);
|
||||||
action native A_Weave(int xspeed, int yspeed, float xdist, float ydist);
|
native void A_Weave(int xspeed, int yspeed, float xdist, float ydist);
|
||||||
|
|
||||||
action native A_Recoil(float xyvel);
|
native void A_Recoil(float xyvel);
|
||||||
action native state A_JumpIfInTargetInventory(class<Inventory> itemtype, int amount, state label, int forward_ptr = AAPTR_DEFAULT);
|
native state A_JumpIfInTargetInventory(class<Inventory> itemtype, int amount, state label, int forward_ptr = AAPTR_DEFAULT);
|
||||||
action native bool A_GiveToTarget(class<Inventory> itemtype, int amount = 0, int forward_ptr = AAPTR_DEFAULT);
|
native bool A_GiveToTarget(class<Inventory> itemtype, int amount = 0, int forward_ptr = AAPTR_DEFAULT);
|
||||||
action native bool A_TakeFromTarget(class<Inventory> itemtype, int amount = 0, int flags = 0, int forward_ptr = AAPTR_DEFAULT);
|
native bool A_TakeFromTarget(class<Inventory> itemtype, int amount = 0, int flags = 0, int forward_ptr = AAPTR_DEFAULT);
|
||||||
action native int A_RadiusGive(class<Inventory> itemtype, float distance, int flags, int amount = 0, class<Actor> filter = "None", name species = "None", int mindist = 0);
|
native int A_RadiusGive(class<Inventory> itemtype, float distance, int flags, int amount = 0, class<Actor> filter = "None", name species = "None", int mindist = 0);
|
||||||
action native state A_CheckSpecies(state jump, name species = "", int ptr = AAPTR_DEFAULT);
|
native state A_CheckSpecies(state jump, name species = "", int ptr = AAPTR_DEFAULT);
|
||||||
action native A_CountdownArg(int argnum, state targstate = "");
|
native void A_CountdownArg(int argnum, state targstate = "");
|
||||||
action native A_CustomMeleeAttack(int damage = 0, sound meleesound = "", sound misssound = "", name damagetype = "none", bool bleed = true);
|
action native A_CustomMeleeAttack(int damage = 0, sound meleesound = "", sound misssound = "", name damagetype = "none", bool bleed = true);
|
||||||
action native A_CustomComboAttack(class<Actor> missiletype, float spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true);
|
native void A_CustomComboAttack(class<Actor> missiletype, float spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true);
|
||||||
action native A_Burst(class<Actor> chunktype);
|
native void A_Burst(class<Actor> chunktype);
|
||||||
action native A_Blast(int flags = 0, float strength = 255, float radius = 255, float speed = 20, class<Actor> blasteffect = "BlastEffect", sound blastsound = "BlastRadius");
|
action native A_Blast(int flags = 0, float strength = 255, float radius = 255, float speed = 20, class<Actor> blasteffect = "BlastEffect", sound blastsound = "BlastRadius");
|
||||||
action native A_RadiusThrust(int force = 128, int distance = -1, int flags = RTF_AFFECTSOURCE, int fullthrustdistance = 0);
|
action native A_RadiusThrust(int force = 128, int distance = -1, int flags = RTF_AFFECTSOURCE, int fullthrustdistance = 0);
|
||||||
action native A_Explode(int damage = -1, int distance = -1, int flags = XF_HURTSOURCE, bool alert = false, int fulldamagedistance = 0, int nails = 0, int naildamage = 10, class<Actor> pufftype = "BulletPuff");
|
action native A_Explode(int damage = -1, int distance = -1, int flags = XF_HURTSOURCE, bool alert = false, int fulldamagedistance = 0, int nails = 0, int naildamage = 10, class<Actor> pufftype = "BulletPuff");
|
||||||
|
@ -252,10 +252,10 @@ ACTOR Actor native //: Thinker
|
||||||
action native A_LookEx(int flags = 0, float minseedist = 0, float maxseedist = 0, float maxheardist = 0, float fov = 0, state label = "");
|
action native A_LookEx(int flags = 0, float minseedist = 0, float maxseedist = 0, float maxheardist = 0, float fov = 0, state label = "");
|
||||||
action native A_ClearLastHeard();
|
action native A_ClearLastHeard();
|
||||||
action native A_ClearTarget();
|
action native A_ClearTarget();
|
||||||
action native state A_CheckLOF(state jump, int flags = 0, float range = 0, float minrange = 0, float angle = 0, float pitch = 0, float offsetheight = 0, float offsetwidth = 0, int ptr_target = AAPTR_DEFAULT, float offsetforward = 0);
|
native state A_CheckLOF(state jump, int flags = 0, float range = 0, float minrange = 0, float angle = 0, float pitch = 0, float offsetheight = 0, float offsetwidth = 0, int ptr_target = AAPTR_DEFAULT, float offsetforward = 0);
|
||||||
action native state A_JumpIfTargetInLOS (state label, float/*angle*/ fov = 0, int flags = 0, float dist_max = 0, float dist_close = 0);
|
native state A_JumpIfTargetInLOS (state label, float/*angle*/ fov = 0, int flags = 0, float dist_max = 0, float dist_close = 0);
|
||||||
action native state A_JumpIfInTargetLOS (state label, float/*angle*/ fov = 0, int flags = 0, float dist_max = 0, float dist_close = 0);
|
native state A_JumpIfInTargetLOS (state label, float/*angle*/ fov = 0, int flags = 0, float dist_max = 0, float dist_close = 0);
|
||||||
action native bool A_SelectWeapon(class<Weapon> whichweapon);
|
native bool A_SelectWeapon(class<Weapon> whichweapon);
|
||||||
action native A_Punch();
|
action native A_Punch();
|
||||||
action native A_Feathers();
|
action native A_Feathers();
|
||||||
action native A_ClassBossHealth();
|
action native A_ClassBossHealth();
|
||||||
|
@ -263,36 +263,36 @@ ACTOR Actor native //: Thinker
|
||||||
action native A_RocketInFlight();
|
action native A_RocketInFlight();
|
||||||
action native A_Bang4Cloud();
|
action native A_Bang4Cloud();
|
||||||
action native A_DropFire();
|
action native A_DropFire();
|
||||||
action native A_GiveQuestItem(int itemno);
|
native void A_GiveQuestItem(int itemno);
|
||||||
action native A_RemoveForcefield();
|
action native A_RemoveForcefield();
|
||||||
action native A_DropWeaponPieces(class<Actor> p1, class<Actor> p2, class<Actor> p3);
|
native void A_DropWeaponPieces(class<Actor> p1, class<Actor> p2, class<Actor> p3);
|
||||||
action native A_PigPain ();
|
action native A_PigPain ();
|
||||||
action native state A_MonsterRefire(int chance, state label);
|
native state A_MonsterRefire(int chance, state label);
|
||||||
action native A_SetAngle(float angle = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
|
native void A_SetAngle(float angle = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||||
action native A_SetPitch(float pitch, int flags = 0, int ptr = AAPTR_DEFAULT);
|
native void A_SetPitch(float pitch, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||||
action native A_SetRoll(float/*angle*/ roll, int flags = 0, int ptr = AAPTR_DEFAULT);
|
native void A_SetRoll(float/*angle*/ roll, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||||
action native A_ScaleVelocity(float scale, int ptr = AAPTR_DEFAULT);
|
native void A_ScaleVelocity(float scale, int ptr = AAPTR_DEFAULT);
|
||||||
action native A_ChangeVelocity(float x = 0, float y = 0, float z = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
|
action native A_ChangeVelocity(float x = 0, float y = 0, float z = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||||
action native A_SetArg(int pos, int value);
|
native void A_SetArg(int pos, int value);
|
||||||
action native A_SetUserVar(name varname, int value);
|
native void A_SetUserVar(name varname, int value);
|
||||||
action native A_SetUserArray(name varname, int index, int value);
|
native void A_SetUserArray(name varname, int index, int value);
|
||||||
action native A_SetUserVarFloat(name varname, float value);
|
native void A_SetUserVarFloat(name varname, float value);
|
||||||
action native A_SetUserArrayFloat(name varname, int index, float value);
|
native void A_SetUserArrayFloat(name varname, int index, float value);
|
||||||
action native A_SetSpecial(int spec, int arg0 = 0, int arg1 = 0, int arg2 = 0, int arg3 = 0, int arg4 = 0);
|
native void A_SetSpecial(int spec, int arg0 = 0, int arg1 = 0, int arg2 = 0, int arg3 = 0, int arg4 = 0);
|
||||||
action native A_Quake(int intensity, int duration, int damrad, int tremrad, sound sfx = "world/quake");
|
native void A_Quake(int intensity, int duration, int damrad, int tremrad, sound sfx = "world/quake");
|
||||||
action native A_QuakeEx(int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, sound sfx = "world/quake", int flags = 0, float mulWaveX = 1, float mulWaveY = 1, float mulWaveZ = 1, int falloff = 0, int highpoint = 0);
|
native void A_QuakeEx(int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, sound sfx = "world/quake", int flags = 0, float mulWaveX = 1, float mulWaveY = 1, float mulWaveZ = 1, int falloff = 0, int highpoint = 0);
|
||||||
action native A_SetTics(int tics);
|
action native A_SetTics(int tics);
|
||||||
action native A_SetDamageType(name damagetype);
|
native void A_SetDamageType(name damagetype);
|
||||||
action native A_DropItem(class<Actor> item, int dropamount = -1, int chance = 256);
|
native void A_DropItem(class<Actor> item, int dropamount = -1, int chance = 256);
|
||||||
action native A_SetSpeed(float speed, int ptr = AAPTR_DEFAULT);
|
native void A_SetSpeed(float speed, int ptr = AAPTR_DEFAULT);
|
||||||
action native A_SetFloatSpeed(float speed, int ptr = AAPTR_DEFAULT);
|
native void A_SetFloatSpeed(float speed, int ptr = AAPTR_DEFAULT);
|
||||||
action native A_SetPainThreshold(int threshold, int ptr = AAPTR_DEFAULT);
|
native void A_SetPainThreshold(int threshold, int ptr = AAPTR_DEFAULT);
|
||||||
action native A_DamageSelf(int amount, name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
native void A_DamageSelf(int amount, name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
||||||
action native A_DamageTarget(int amount, name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
native void A_DamageTarget(int amount, name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
||||||
action native A_DamageMaster(int amount, name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
native void A_DamageMaster(int amount, name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
||||||
action native A_DamageTracer(int amount, name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
native void A_DamageTracer(int amount, name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
||||||
action native A_DamageChildren(int amount, name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
native void A_DamageChildren(int amount, name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
||||||
action native A_DamageSiblings(int amount, name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
native void A_DamageSiblings(int amount, name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
||||||
action native A_KillTarget(name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
action native A_KillTarget(name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
||||||
action native A_KillMaster(name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
action native A_KillMaster(name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
||||||
action native A_KillTracer(name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
action native A_KillTracer(name damagetype = "none", int flags = 0, class<Actor> filter = "None", name species = "None");
|
||||||
|
@ -303,39 +303,39 @@ ACTOR Actor native //: Thinker
|
||||||
action native A_RemoveTracer(int flags = 0, class<Actor> filter = "None", name species = "None");
|
action native A_RemoveTracer(int flags = 0, class<Actor> filter = "None", name species = "None");
|
||||||
action native A_RemoveChildren(bool removeall = false, int flags = 0, class<Actor> filter = "None", name species = "None");
|
action native A_RemoveChildren(bool removeall = false, int flags = 0, class<Actor> filter = "None", name species = "None");
|
||||||
action native A_RemoveSiblings(bool removeall = false, int flags = 0, class<Actor> filter = "None", name species = "None");
|
action native A_RemoveSiblings(bool removeall = false, int flags = 0, class<Actor> filter = "None", name species = "None");
|
||||||
action native A_Remove(int removee, int flags = 0, class<Actor> filter = "None", name species = "None");
|
native void A_Remove(int removee, int flags = 0, class<Actor> filter = "None", name species = "None");
|
||||||
action native int A_GiveToChildren(class<Inventory> itemtype, int amount = 0);
|
native int A_GiveToChildren(class<Inventory> itemtype, int amount = 0);
|
||||||
action native int A_GiveToSiblings(class<Inventory> itemtype, int amount = 0);
|
native int A_GiveToSiblings(class<Inventory> itemtype, int amount = 0);
|
||||||
action native int A_TakeFromChildren(class<Inventory> itemtype, int amount = 0);
|
native int A_TakeFromChildren(class<Inventory> itemtype, int amount = 0);
|
||||||
action native int A_TakeFromSiblings(class<Inventory> itemtype, int amount = 0);
|
native int A_TakeFromSiblings(class<Inventory> itemtype, int amount = 0);
|
||||||
action native A_SetTeleFog(class<Actor> oldpos, class<Actor> newpos);
|
native void A_SetTeleFog(class<Actor> oldpos, class<Actor> newpos);
|
||||||
action native A_SwapTeleFog();
|
action native A_SwapTeleFog();
|
||||||
action native A_SetFloatBobPhase(int bob);
|
native void A_SetFloatBobPhase(int bob);
|
||||||
action native A_SetHealth(int health, int ptr = AAPTR_DEFAULT);
|
native void A_SetHealth(int health, int ptr = AAPTR_DEFAULT);
|
||||||
action native A_ResetHealth(int ptr = AAPTR_DEFAULT);
|
action native A_ResetHealth(int ptr = AAPTR_DEFAULT);
|
||||||
action native state A_JumpIfHigherOrLower(state high, state low, float offsethigh = 0, float offsetlow = 0, bool includeHeight = true, int ptr = AAPTR_TARGET);
|
native state A_JumpIfHigherOrLower(state high, state low, float offsethigh = 0, float offsetlow = 0, bool includeHeight = true, int ptr = AAPTR_TARGET);
|
||||||
action native A_SetSpecies(name species, int ptr = AAPTR_DEFAULT);
|
native void A_SetSpecies(name species, int ptr = AAPTR_DEFAULT);
|
||||||
action native A_SetRipperLevel(int level);
|
native void A_SetRipperLevel(int level);
|
||||||
action native A_SetRipMin(int mininum);
|
native void A_SetRipMin(int mininum);
|
||||||
action native A_SetRipMax(int maximum);
|
native void A_SetRipMax(int maximum);
|
||||||
action native A_SetChaseThreshold(int threshold, bool def = false, int ptr = AAPTR_DEFAULT);
|
native void A_SetChaseThreshold(int threshold, bool def = false, int ptr = AAPTR_DEFAULT);
|
||||||
action native state A_CheckProximity(state jump, class<Actor> classname, float distance, int count = 1, int flags = 0, int ptr = AAPTR_DEFAULT);
|
native state A_CheckProximity(state jump, class<Actor> classname, float distance, int count = 1, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||||
action native state A_CheckBlock(state block, int flags = 0, int ptr = AAPTR_DEFAULT, float xofs = 0, float yofs = 0, float zofs = 0, float angle = 0);
|
native state A_CheckBlock(state block, int flags = 0, int ptr = AAPTR_DEFAULT, float xofs = 0, float yofs = 0, float zofs = 0, float angle = 0);
|
||||||
action native state A_CheckSightOrRange(float distance, state label, bool two_dimension = false);
|
native state A_CheckSightOrRange(float distance, state label, bool two_dimension = false);
|
||||||
action native state A_CheckRange(float distance, state label, bool two_dimension = false);
|
native state A_CheckRange(float distance, state label, bool two_dimension = false);
|
||||||
action native bool A_FaceMovementDirection(float offset = 0, float anglelimit = 0, float pitchlimit = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
|
action native bool A_FaceMovementDirection(float offset = 0, float anglelimit = 0, float pitchlimit = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||||
|
|
||||||
action native A_RearrangePointers(int newtarget, int newmaster = AAPTR_DEFAULT, int newtracer = AAPTR_DEFAULT, int flags=0);
|
native void A_RearrangePointers(int newtarget, int newmaster = AAPTR_DEFAULT, int newtracer = AAPTR_DEFAULT, int flags=0);
|
||||||
action native A_TransferPointer(int ptr_source, int ptr_recepient, int sourcefield, int recepientfield=AAPTR_DEFAULT, int flags=0);
|
native void A_TransferPointer(int ptr_source, int ptr_recepient, int sourcefield, int recepientfield=AAPTR_DEFAULT, int flags=0);
|
||||||
action native A_CopyFriendliness(int ptr_source = AAPTR_MASTER);
|
action native A_CopyFriendliness(int ptr_source = AAPTR_MASTER);
|
||||||
|
|
||||||
action native int ACS_NamedExecute(name script, int mapnum=0, int arg1=0, int arg2=0, int arg3=0);
|
native int ACS_NamedExecute(name script, int mapnum=0, int arg1=0, int arg2=0, int arg3=0);
|
||||||
action native int ACS_NamedSuspend(name script, int mapnum=0);
|
native int ACS_NamedSuspend(name script, int mapnum=0);
|
||||||
action native int ACS_NamedTerminate(name script, int mapnum=0);
|
native int ACS_NamedTerminate(name script, int mapnum=0);
|
||||||
action native int ACS_NamedLockedExecute(name script, int mapnum=0, int arg1=0, int arg2=0, int lock=0);
|
native int ACS_NamedLockedExecute(name script, int mapnum=0, int arg1=0, int arg2=0, int lock=0);
|
||||||
action native int ACS_NamedLockedExecuteDoor(name script, int mapnum=0, int arg1=0, int arg2=0, int lock=0);
|
native int ACS_NamedLockedExecuteDoor(name script, int mapnum=0, int arg1=0, int arg2=0, int lock=0);
|
||||||
action native int ACS_NamedExecuteWithResult(name script, int arg1=0, int arg2=0, int arg3=0, int arg4=0);
|
native int ACS_NamedExecuteWithResult(name script, int arg1=0, int arg2=0, int arg3=0, int arg4=0);
|
||||||
action native ACS_NamedExecuteAlways(name script, int mapnum=0, int arg1=0, int arg2=0, int arg3=0);
|
native void ACS_NamedExecuteAlways(name script, int mapnum=0, int arg1=0, int arg2=0, int arg3=0);
|
||||||
|
|
||||||
States
|
States
|
||||||
{
|
{
|
||||||
|
|
|
@ -711,6 +711,7 @@ ACTOR BlasterPowered : Blaster
|
||||||
Weapon.AmmoUse 5
|
Weapon.AmmoUse 5
|
||||||
Weapon.AmmoGive 0
|
Weapon.AmmoGive 0
|
||||||
Weapon.SisterWeapon "Blaster"
|
Weapon.SisterWeapon "Blaster"
|
||||||
|
Tag "$TAG_BLASTERP"
|
||||||
States
|
States
|
||||||
{
|
{
|
||||||
Fire:
|
Fire:
|
||||||
|
@ -735,7 +736,6 @@ ACTOR BlasterFX1 : FastProjectile native
|
||||||
DeathSound "weapons/blasterhit"
|
DeathSound "weapons/blasterhit"
|
||||||
+SPAWNSOUNDSOURCE
|
+SPAWNSOUNDSOURCE
|
||||||
Obituary "$OB_MPPBLASTER"
|
Obituary "$OB_MPPBLASTER"
|
||||||
Tag "$TAG_BLASTERP"
|
|
||||||
|
|
||||||
action native A_SpawnRippers();
|
action native A_SpawnRippers();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue