mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
Merge remote-tracking branch 'upstream/master' into truecolor
This commit is contained in:
commit
9953d70eaa
39 changed files with 1129 additions and 141 deletions
|
@ -176,7 +176,7 @@ DEFINE_SPECIAL(Sector_SetCeilingScale, 188, 5, 5, 5)
|
|||
DEFINE_SPECIAL(Sector_SetFloorScale, 189, 5, 5, 5)
|
||||
DEFINE_SPECIAL(Static_Init, 190, -1, -1, 4)
|
||||
DEFINE_SPECIAL(SetPlayerProperty, 191, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_LowerToHighestFloor, 192, 2, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_LowerToHighestFloor, 192, 2, 4, 5)
|
||||
DEFINE_SPECIAL(Ceiling_LowerInstant, 193, 3, 5, 5)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseInstant, 194, 3, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_CrushRaiseAndStayA, 195, 4, 5, 5)
|
||||
|
@ -222,7 +222,7 @@ DEFINE_SPECIAL(Light_MaxNeighbor, 234, 1, 1, 1)
|
|||
DEFINE_SPECIAL(Floor_TransferTrigger, 235, 1, 1, 1)
|
||||
DEFINE_SPECIAL(Floor_TransferNumeric, 236, 1, 1, 1)
|
||||
DEFINE_SPECIAL(ChangeCamera, 237, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_RaiseToLowestCeiling, 238, 2, 4, 4)
|
||||
DEFINE_SPECIAL(Floor_RaiseToLowestCeiling, 238, 2, 4, 5)
|
||||
DEFINE_SPECIAL(Floor_RaiseByValueTxTy, 239, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_RaiseByTexture, 240, 2, 4, 4)
|
||||
DEFINE_SPECIAL(Floor_LowerToLowestTxTy, 241, 2, 2, 2)
|
||||
|
@ -238,21 +238,21 @@ DEFINE_SPECIAL(Floor_Donut, 250, 3, 3, 3)
|
|||
DEFINE_SPECIAL(FloorAndCeiling_LowerRaise, 251, 3, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseToNearest, 252, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_LowerToLowest, 253, 2, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_LowerToFloor, 254, 2, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_LowerToFloor, 254, 2, 4, 5)
|
||||
DEFINE_SPECIAL(Ceiling_CrushRaiseAndStaySilA, 255, 4, 5, 5)
|
||||
|
||||
DEFINE_SPECIAL(Floor_LowerToHighestEE, 256, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_RaiseToLowest, 257, 1, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_LowerToLowestCeiling, 258, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_RaiseToCeiling, 259, 2, 4, 4)
|
||||
DEFINE_SPECIAL(Floor_ToCeilingInstant, 260, 1, 3, 3)
|
||||
DEFINE_SPECIAL(Floor_RaiseToCeiling, 259, 2, 4, 5)
|
||||
DEFINE_SPECIAL(Floor_ToCeilingInstant, 260, 1, 3, 4)
|
||||
DEFINE_SPECIAL(Floor_LowerByTexture, 261, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseToHighest, 262, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_ToHighestInstant, 263, 1, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_LowerToNearest, 264, 2, 4, 4)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseToLowest, 265, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseToHighestFloor, 266, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_ToFloorInstant, 267, 1, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_ToFloorInstant, 267, 1, 3, 4)
|
||||
DEFINE_SPECIAL(Ceiling_RaiseByTexture, 268, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Ceiling_LowerByTexture, 269, 2, 4, 4)
|
||||
DEFINE_SPECIAL(Stairs_BuildDownDoom, 270, 5, 5, 5)
|
||||
|
|
|
@ -382,6 +382,7 @@ enum ActorFlag7
|
|||
MF7_ALLOWTHRUFLAGS = 0x00400000, // [MC] Allow THRUACTORS and the likes on puffs to prevent mod breakage.
|
||||
MF7_USEKILLSCRIPTS = 0x00800000, // [JM] Use "KILL" Script on death if not forced by GameInfo.
|
||||
MF7_NOKILLSCRIPTS = 0x01000000, // [JM] No "KILL" Script on death whatsoever, even if forced by GameInfo.
|
||||
MF7_SPRITEANGLE = 0x02000000, // [MC] Utilize the SpriteAngle property and lock the rotation to the degrees specified.
|
||||
};
|
||||
|
||||
// --- mobj.renderflags ---
|
||||
|
@ -978,6 +979,8 @@ public:
|
|||
DVector3 __Pos; // double underscores so that it won't get used by accident. Access to this should be exclusively through the designated access functions.
|
||||
DVector3 OldRenderPos;
|
||||
|
||||
DAngle SpriteAngle;
|
||||
DAngle SpriteRotation;
|
||||
DRotator Angles;
|
||||
DVector3 Vel;
|
||||
double Speed;
|
||||
|
|
|
@ -1897,6 +1897,7 @@ void AM_drawSubsectors()
|
|||
FDynamicColormap *colormap;
|
||||
mpoint_t originpt;
|
||||
|
||||
screen->StartSimplePolys();
|
||||
for (int i = 0; i < numsubsectors; ++i)
|
||||
{
|
||||
if (subsectors[i].flags & SSECF_POLYORG)
|
||||
|
@ -2049,6 +2050,7 @@ void AM_drawSubsectors()
|
|||
);
|
||||
}
|
||||
}
|
||||
screen->FinishSimplePolys();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
|
|
@ -162,7 +162,7 @@ CVAR (Bool, con_centernotify, false, CVAR_ARCHIVE)
|
|||
CUSTOM_CVAR (Int, con_scaletext, 0, CVAR_ARCHIVE) // Scale notify text at high resolutions?
|
||||
{
|
||||
if (self < 0) self = 0;
|
||||
if (self > 2) self = 2;
|
||||
if (self > 3) self = 3;
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Float, con_alpha, 0.75f, CVAR_ARCHIVE)
|
||||
|
@ -493,7 +493,14 @@ void C_AddNotifyString (int printlevel, const char *source)
|
|||
return;
|
||||
}
|
||||
|
||||
width = con_scaletext > 1 ? DisplayWidth/2 : con_scaletext == 1 ? DisplayWidth / CleanXfac : DisplayWidth;
|
||||
switch (con_scaletext)
|
||||
{
|
||||
default:
|
||||
case 0: width = DisplayWidth; break;
|
||||
case 1: width = DisplayWidth / CleanXfac; break;
|
||||
case 2: width = DisplayWidth / 2; break;
|
||||
case 3: width = DisplayWidth / 4; break;
|
||||
}
|
||||
|
||||
if (addtype == APPENDLINE && NotifyStrings[NUMNOTIFIES-1].PrintLevel == printlevel)
|
||||
{
|
||||
|
@ -770,6 +777,23 @@ static void C_DrawNotifyText ()
|
|||
line, NotifyStrings[i].Text,
|
||||
DTA_AlphaF, alpha, TAG_DONE);
|
||||
}
|
||||
else if (con_scaletext == 3)
|
||||
{
|
||||
if (!center)
|
||||
screen->DrawText (SmallFont, color, 0, line, NotifyStrings[i].Text,
|
||||
DTA_VirtualWidth, screen->GetWidth() / 4,
|
||||
DTA_VirtualHeight, screen->GetHeight() / 4,
|
||||
DTA_KeepRatio, true,
|
||||
DTA_AlphaF, alpha, TAG_DONE);
|
||||
else
|
||||
screen->DrawText (SmallFont, color, (screen->GetWidth() / 4 -
|
||||
SmallFont->StringWidth (NotifyStrings[i].Text))/4,
|
||||
line, NotifyStrings[i].Text,
|
||||
DTA_VirtualWidth, screen->GetWidth() / 4,
|
||||
DTA_VirtualHeight, screen->GetHeight() / 4,
|
||||
DTA_KeepRatio, true,
|
||||
DTA_AlphaF, alpha, TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!center)
|
||||
|
|
|
@ -234,9 +234,27 @@ void CT_Drawer (void)
|
|||
scalex = 1;
|
||||
}
|
||||
|
||||
int screen_width = con_scaletext > 1? SCREENWIDTH/2 : SCREENWIDTH;
|
||||
int screen_height = con_scaletext > 1? SCREENHEIGHT/2 : SCREENHEIGHT;
|
||||
int st_y = con_scaletext > 1? ST_Y/2 : ST_Y;
|
||||
int screen_width, screen_height, st_y;
|
||||
switch (con_scaletext)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
case 1:
|
||||
screen_width = SCREENWIDTH;
|
||||
screen_height = SCREENHEIGHT;
|
||||
st_y = ST_Y;
|
||||
break;
|
||||
case 2:
|
||||
screen_width = SCREENWIDTH / 2;
|
||||
screen_height = SCREENHEIGHT / 2;
|
||||
st_y = ST_Y / 2;
|
||||
break;
|
||||
case 3:
|
||||
screen_width = SCREENWIDTH / 4;
|
||||
screen_height = SCREENHEIGHT / 4;
|
||||
st_y = ST_Y / 4;
|
||||
break;
|
||||
}
|
||||
|
||||
y += ((SCREENHEIGHT == viewheight && viewactive) || gamestate != GS_LEVEL) ? screen_height : st_y;
|
||||
|
||||
|
|
|
@ -260,7 +260,14 @@ void DHUDMessage::ResetText (const char *text)
|
|||
}
|
||||
else
|
||||
{
|
||||
width = con_scaletext >= 2 ? SCREENWIDTH/2 : (con_scaletext ? SCREENWIDTH / CleanXfac : SCREENWIDTH);
|
||||
switch (con_scaletext)
|
||||
{
|
||||
default:
|
||||
case 0: width = SCREENWIDTH; break;
|
||||
case 1: width = SCREENWIDTH / CleanXfac; break;
|
||||
case 2: width = SCREENWIDTH / 2; break;
|
||||
case 3: width = SCREENWIDTH / 4; break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Lines != NULL)
|
||||
|
@ -334,12 +341,18 @@ void DHUDMessage::Draw (int bottom, int visibility)
|
|||
else
|
||||
{
|
||||
xscale = yscale = 1;
|
||||
if (HUDWidth==0 && con_scaletext>1)
|
||||
if (HUDWidth==0 && con_scaletext==2)
|
||||
{
|
||||
screen_width/=2;
|
||||
screen_height/=2;
|
||||
bottom/=2;
|
||||
}
|
||||
else if (HUDWidth==0 && con_scaletext==3)
|
||||
{
|
||||
screen_width/=4;
|
||||
screen_height/=4;
|
||||
bottom/=4;
|
||||
}
|
||||
}
|
||||
|
||||
if (HUDWidth == 0)
|
||||
|
@ -448,6 +461,16 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight)
|
|||
DTA_RenderStyle, Style,
|
||||
TAG_DONE);
|
||||
}
|
||||
else if (con_scaletext == 3)
|
||||
{
|
||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, SCREENWIDTH/4,
|
||||
DTA_VirtualHeight, SCREENHEIGHT/4,
|
||||
DTA_AlphaF, Alpha,
|
||||
DTA_RenderStyle, Style,
|
||||
DTA_KeepRatio, true,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
|
@ -551,6 +574,16 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh
|
|||
DTA_RenderStyle, Style,
|
||||
TAG_DONE);
|
||||
}
|
||||
else if (con_scaletext == 3)
|
||||
{
|
||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, SCREENWIDTH/4,
|
||||
DTA_VirtualHeight, SCREENHEIGHT/4,
|
||||
DTA_AlphaF, trans,
|
||||
DTA_RenderStyle, Style,
|
||||
DTA_KeepRatio, true,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
|
@ -651,6 +684,16 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu
|
|||
DTA_RenderStyle, Style,
|
||||
TAG_DONE);
|
||||
}
|
||||
else if (con_scaletext == 3)
|
||||
{
|
||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, SCREENWIDTH/4,
|
||||
DTA_VirtualHeight, SCREENHEIGHT/4,
|
||||
DTA_AlphaF, trans,
|
||||
DTA_RenderStyle, Style,
|
||||
DTA_KeepRatio, true,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
|
@ -830,6 +873,17 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in
|
|||
DTA_RenderStyle, Style,
|
||||
TAG_DONE);
|
||||
}
|
||||
else if (con_scaletext == 3)
|
||||
{
|
||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, SCREENWIDTH/4,
|
||||
DTA_VirtualHeight, SCREENHEIGHT/4,
|
||||
DTA_KeepRatio, true,
|
||||
DTA_TextLen, LineVisible,
|
||||
DTA_AlphaF, Alpha,
|
||||
DTA_RenderStyle, Style,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
|
|
|
@ -885,8 +885,25 @@ static void DrawCoordinates(player_t * CPlayer)
|
|||
pos = DVector3(apos, z);
|
||||
}
|
||||
|
||||
int vwidth = con_scaletext==0? SCREENWIDTH : SCREENWIDTH/2;
|
||||
int vheight = con_scaletext==0? SCREENHEIGHT : SCREENHEIGHT/2;
|
||||
int vwidth, vheight;
|
||||
switch (con_scaletext)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
vwidth = SCREENWIDTH;
|
||||
vheight = SCREENWIDTH;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
vwidth = SCREENWIDTH/2;
|
||||
vheight = SCREENWIDTH/2;
|
||||
break;
|
||||
case 3:
|
||||
vwidth = SCREENWIDTH/4;
|
||||
vheight = SCREENWIDTH/4;
|
||||
break;
|
||||
}
|
||||
|
||||
int xpos = vwidth - SmallFont->StringWidth("X: -00000")-6;
|
||||
int ypos = 18;
|
||||
|
||||
|
@ -1073,7 +1090,12 @@ void DrawHUD()
|
|||
if (hud_althudscale && SCREENWIDTH>640)
|
||||
{
|
||||
hudwidth=SCREENWIDTH/2;
|
||||
if (hud_althudscale == 2)
|
||||
if (hud_althudscale == 3)
|
||||
{
|
||||
hudwidth = SCREENWIDTH / 4;
|
||||
hudheight = SCREENHEIGHT / 4;
|
||||
}
|
||||
else if (hud_althudscale == 2)
|
||||
{
|
||||
// Optionally just double the pixels to reduce scaling artifacts.
|
||||
hudheight=SCREENHEIGHT/2;
|
||||
|
|
|
@ -108,7 +108,7 @@ CVAR (Int, crosshair, 0, CVAR_ARCHIVE)
|
|||
CVAR (Bool, crosshairforce, false, CVAR_ARCHIVE)
|
||||
CVAR (Color, crosshaircolor, 0xff0000, CVAR_ARCHIVE);
|
||||
CVAR (Bool, crosshairhealth, true, CVAR_ARCHIVE);
|
||||
CVAR (Bool, crosshairscale, false, CVAR_ARCHIVE);
|
||||
CVAR (Float, crosshairscale, 1.0, CVAR_ARCHIVE);
|
||||
CVAR (Bool, crosshairgrow, false, CVAR_ARCHIVE);
|
||||
CUSTOM_CVAR(Int, am_showmaplabel, 2, CVAR_ARCHIVE)
|
||||
{
|
||||
|
@ -1106,9 +1106,9 @@ void DBaseStatusBar::DrawCrosshair ()
|
|||
return;
|
||||
}
|
||||
|
||||
if (crosshairscale)
|
||||
if (crosshairscale > 0.0f)
|
||||
{
|
||||
size = SCREENHEIGHT / 200.;
|
||||
size = SCREENHEIGHT * crosshairscale / 200.;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1247,6 +1247,13 @@ void DBaseStatusBar::Draw (EHudState state)
|
|||
xpos = vwidth - 80;
|
||||
y = ::ST_Y - height;
|
||||
}
|
||||
else if (con_scaletext == 3)
|
||||
{
|
||||
vwidth = SCREENWIDTH/4;
|
||||
vheight = SCREENHEIGHT/4;
|
||||
xpos = vwidth - SmallFont->StringWidth("X: -00000")-6;
|
||||
y = ::ST_Y/4 - height;
|
||||
}
|
||||
else
|
||||
{
|
||||
vwidth = SCREENWIDTH/2;
|
||||
|
@ -1259,6 +1266,8 @@ void DBaseStatusBar::Draw (EHudState state)
|
|||
{
|
||||
if (con_scaletext == 0)
|
||||
y -= height * 4;
|
||||
else if (con_scaletext == 3)
|
||||
y -= height;
|
||||
else
|
||||
y -= height * 2;
|
||||
}
|
||||
|
@ -1407,6 +1416,11 @@ void DBaseStatusBar::DrawLog ()
|
|||
hudwidth = SCREENWIDTH / 2;
|
||||
hudheight = SCREENHEIGHT / 2;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
hudwidth = SCREENWIDTH / 4;
|
||||
hudheight = SCREENHEIGHT / 4;
|
||||
break;
|
||||
}
|
||||
|
||||
int linelen = hudwidth<640? Scale(hudwidth,9,10)-40 : 560;
|
||||
|
|
|
@ -214,6 +214,7 @@ xx(Brainexplode)
|
|||
// Weapon animator names.
|
||||
xx(Select)
|
||||
xx(Deselect)
|
||||
xx(DeadLowered)
|
||||
xx(Ready)
|
||||
xx(Fire)
|
||||
xx(Hold)
|
||||
|
|
|
@ -514,6 +514,17 @@ void P_Recalculate3DFloors(sector_t * sector)
|
|||
clipped_bottom = pick_bottom;
|
||||
}
|
||||
}
|
||||
else if (pick_bottom > height) // do not allow inverted planes
|
||||
{
|
||||
F3DFloor * dyn = new F3DFloor;
|
||||
*dyn = *pick;
|
||||
pick->flags |= FF_CLIPPED;
|
||||
pick->flags &= ~FF_EXISTS;
|
||||
dyn->flags |= FF_DYNAMIC;
|
||||
dyn->bottom.copyPlane(&pick->top);
|
||||
ffloors.Push(pick);
|
||||
ffloors.Push(dyn);
|
||||
}
|
||||
else
|
||||
{
|
||||
clipped = pick;
|
||||
|
|
|
@ -309,7 +309,7 @@ bool P_CreateCeiling(sector_t *sec, DCeiling::ECeiling type, line_t *line, int t
|
|||
break;
|
||||
|
||||
case DCeiling::ceilLowerToHighestFloor:
|
||||
targheight = sec->FindHighestFloorSurrounding (&spot);
|
||||
targheight = sec->FindHighestFloorSurrounding (&spot) + height;
|
||||
ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight);
|
||||
ceiling->m_Direction = -1;
|
||||
break;
|
||||
|
@ -359,13 +359,13 @@ bool P_CreateCeiling(sector_t *sec, DCeiling::ECeiling type, line_t *line, int t
|
|||
break;
|
||||
|
||||
case DCeiling::ceilLowerToFloor:
|
||||
targheight = sec->FindHighestFloorPoint (&spot);
|
||||
targheight = sec->FindHighestFloorPoint (&spot) + height;
|
||||
ceiling->m_BottomHeight = sec->ceilingplane.PointToDist (spot, targheight);
|
||||
ceiling->m_Direction = -1;
|
||||
break;
|
||||
|
||||
case DCeiling::ceilRaiseToFloor: // [RH] What's this for?
|
||||
targheight = sec->FindHighestFloorPoint (&spot);
|
||||
targheight = sec->FindHighestFloorPoint (&spot) + height;
|
||||
ceiling->m_TopHeight = sec->ceilingplane.PointToDist (spot, targheight);
|
||||
ceiling->m_Direction = 1;
|
||||
break;
|
||||
|
|
|
@ -349,16 +349,14 @@ bool P_CreateFloor(sector_t *sec, DFloor::EFloor floortype, line_t *line,
|
|||
break;
|
||||
|
||||
case DFloor::floorRaiseAndCrushDoom:
|
||||
height = 8;
|
||||
case DFloor::floorRaiseToLowestCeiling:
|
||||
floor->m_Direction = 1;
|
||||
newheight = sec->FindLowestCeilingSurrounding(&spot);
|
||||
if (floortype == DFloor::floorRaiseAndCrushDoom)
|
||||
newheight -= 8;
|
||||
newheight = sec->FindLowestCeilingSurrounding(&spot) - height;
|
||||
ceilingheight = sec->FindLowestCeilingPoint(&spot2);
|
||||
floor->m_FloorDestDist = sec->floorplane.PointToDist(spot, newheight);
|
||||
if (sec->floorplane.ZatPointDist(spot2, floor->m_FloorDestDist) > ceilingheight)
|
||||
floor->m_FloorDestDist = sec->floorplane.PointToDist(spot2,
|
||||
floortype == DFloor::floorRaiseAndCrushDoom ? ceilingheight - 8 : ceilingheight);
|
||||
floor->m_FloorDestDist = sec->floorplane.PointToDist(spot2, floortype == ceilingheight - height);
|
||||
break;
|
||||
|
||||
case DFloor::floorRaiseToHighest:
|
||||
|
@ -387,7 +385,7 @@ bool P_CreateFloor(sector_t *sec, DFloor::EFloor floortype, line_t *line,
|
|||
|
||||
case DFloor::floorRaiseToCeiling:
|
||||
floor->m_Direction = 1;
|
||||
newheight = sec->FindLowestCeilingPoint(&spot);
|
||||
newheight = sec->FindLowestCeilingPoint(&spot) - height;
|
||||
floor->m_FloorDestDist = sec->floorplane.PointToDist(spot, newheight);
|
||||
break;
|
||||
|
||||
|
@ -406,7 +404,7 @@ bool P_CreateFloor(sector_t *sec, DFloor::EFloor floortype, line_t *line,
|
|||
case DFloor::floorLowerToCeiling:
|
||||
// [RH] Essentially instantly raises the floor to the ceiling
|
||||
floor->m_Direction = -1;
|
||||
newheight = sec->FindLowestCeilingPoint(&spot);
|
||||
newheight = sec->FindLowestCeilingPoint(&spot) - height;
|
||||
floor->m_FloorDestDist = sec->floorplane.PointToDist(spot, newheight);
|
||||
break;
|
||||
|
||||
|
|
|
@ -260,7 +260,13 @@ FUNC(LS_Door_Raise)
|
|||
FUNC(LS_Door_LockedRaise)
|
||||
// Door_LockedRaise (tag, speed, delay, lock, lighttag)
|
||||
{
|
||||
#if 0
|
||||
// In Hexen this originally created a thinker running for nearly 4 years.
|
||||
// Let's not do this unless it becomes necessary because this can hang tagwait.
|
||||
return EV_DoDoor (arg2 || (level.flags2 & LEVEL2_HEXENHACK) ? DDoor::doorRaise : DDoor::doorOpen, ln, it,
|
||||
#else
|
||||
return EV_DoDoor (arg2 ? DDoor::doorRaise : DDoor::doorOpen, ln, it,
|
||||
#endif
|
||||
arg0, SPEED(arg1), TICS(arg2), arg3, arg4);
|
||||
}
|
||||
|
||||
|
@ -420,9 +426,9 @@ FUNC(LS_Floor_RaiseInstant)
|
|||
}
|
||||
|
||||
FUNC(LS_Floor_ToCeilingInstant)
|
||||
// Floor_ToCeilingInstant (tag, change, crush)
|
||||
// Floor_ToCeilingInstant (tag, change, crush, gap)
|
||||
{
|
||||
return EV_DoFloor (DFloor::floorLowerToCeiling, ln, arg0, 0, 0, CRUSH(arg2), CHANGE(arg1), true);
|
||||
return EV_DoFloor (DFloor::floorLowerToCeiling, ln, arg0, 0, arg3, CRUSH(arg2), CHANGE(arg1), true);
|
||||
}
|
||||
|
||||
FUNC(LS_Floor_MoveToValueTimes8)
|
||||
|
@ -448,7 +454,7 @@ FUNC(LS_Floor_RaiseToLowestCeiling)
|
|||
FUNC(LS_Floor_LowerToLowestCeiling)
|
||||
// Floor_LowerToLowestCeiling (tag, speed, change)
|
||||
{
|
||||
return EV_DoFloor (DFloor::floorLowerToLowestCeiling, ln, arg0, SPEED(arg1), 0, -1, CHANGE(arg2), true);
|
||||
return EV_DoFloor (DFloor::floorLowerToLowestCeiling, ln, arg0, SPEED(arg1), arg4, -1, CHANGE(arg2), true);
|
||||
}
|
||||
|
||||
FUNC(LS_Floor_RaiseByTexture)
|
||||
|
@ -464,9 +470,9 @@ FUNC(LS_Floor_LowerByTexture)
|
|||
}
|
||||
|
||||
FUNC(LS_Floor_RaiseToCeiling)
|
||||
// Floor_RaiseToCeiling (tag, speed, change, crush)
|
||||
// Floor_RaiseToCeiling (tag, speed, change, crush, gap)
|
||||
{
|
||||
return EV_DoFloor (DFloor::floorRaiseToCeiling, ln, arg0, SPEED(arg1), 0, CRUSH(arg3), CHANGE(arg2), true);
|
||||
return EV_DoFloor (DFloor::floorRaiseToCeiling, ln, arg0, SPEED(arg1), arg4, CRUSH(arg3), CHANGE(arg2), true);
|
||||
}
|
||||
|
||||
FUNC(LS_Floor_RaiseByValueTxTy)
|
||||
|
@ -706,9 +712,9 @@ FUNC(LS_Ceiling_MoveToValue)
|
|||
}
|
||||
|
||||
FUNC(LS_Ceiling_LowerToHighestFloor)
|
||||
// Ceiling_LowerToHighestFloor (tag, speed, change, crush)
|
||||
// Ceiling_LowerToHighestFloor (tag, speed, change, crush, gap)
|
||||
{
|
||||
return EV_DoCeiling (DCeiling::ceilLowerToHighestFloor, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg2));
|
||||
return EV_DoCeiling (DCeiling::ceilLowerToHighestFloor, ln, arg0, SPEED(arg1), 0, arg4, CRUSH(arg3), 0, CHANGE(arg2));
|
||||
}
|
||||
|
||||
FUNC(LS_Ceiling_LowerInstant)
|
||||
|
@ -808,15 +814,15 @@ FUNC(LS_Ceiling_ToHighestInstant)
|
|||
}
|
||||
|
||||
FUNC(LS_Ceiling_ToFloorInstant)
|
||||
// Ceiling_ToFloorInstant (tag, change, crush)
|
||||
// Ceiling_ToFloorInstant (tag, change, crush, gap)
|
||||
{
|
||||
return EV_DoCeiling (DCeiling::ceilRaiseToFloor, ln, arg0, 2, 0, 0, CRUSH(arg2), 0, CHANGE(arg1));
|
||||
return EV_DoCeiling (DCeiling::ceilRaiseToFloor, ln, arg0, 2, 0, arg3, CRUSH(arg2), 0, CHANGE(arg1));
|
||||
}
|
||||
|
||||
FUNC(LS_Ceiling_LowerToFloor)
|
||||
// Ceiling_LowerToFloor (tag, speed, change, crush)
|
||||
// Ceiling_LowerToFloor (tag, speed, change, crush, gap)
|
||||
{
|
||||
return EV_DoCeiling (DCeiling::ceilLowerToFloor, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg4));
|
||||
return EV_DoCeiling (DCeiling::ceilLowerToFloor, ln, arg0, SPEED(arg1), 0, arg4, CRUSH(arg3), 0, CHANGE(arg4));
|
||||
}
|
||||
|
||||
FUNC(LS_Ceiling_LowerByTexture)
|
||||
|
|
|
@ -161,7 +161,7 @@ PClassActor *P_GetSpawnableType(int spawnnum);
|
|||
void InitSpawnablesFromMapinfo();
|
||||
int P_Thing_CheckInputNum(player_t *p, int inputnum);
|
||||
int P_Thing_Warp(AActor *caller, AActor *reference, double xofs, double yofs, double zofs, DAngle angle, int flags, double heightoffset, double radiusoffset, DAngle pitch);
|
||||
bool P_Thing_CheckProximity(AActor *self, PClass *classname, double distance, int count, int flags, int ptr);
|
||||
int P_Thing_CheckProximity(AActor *self, PClass *classname, double distance, int count, int flags, int ptr, bool counting = false);
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -1566,7 +1566,7 @@ bool P_CheckPosition(AActor *thing, const DVector2 &pos, FCheckPosition &tm, boo
|
|||
tm.floorpic = *rover->top.texture;
|
||||
tm.floorterrain = rover->model->GetTerrain(rover->top.isceiling);
|
||||
}
|
||||
if (ff_bottom < tm.ceilingz && abs(delta1) >= abs(delta2))
|
||||
if (ff_bottom < tm.ceilingz && fabs(delta1) >= fabs(delta2))
|
||||
{
|
||||
tm.ceilingz = ff_bottom;
|
||||
tm.ceilingpic = *rover->bottom.texture;
|
||||
|
|
|
@ -383,6 +383,11 @@ void AActor::Serialize(FArchive &arc)
|
|||
<< RipLevelMin
|
||||
<< RipLevelMax;
|
||||
arc << DefThreshold;
|
||||
if (SaveVersion >= 4549)
|
||||
{
|
||||
arc << SpriteAngle;
|
||||
arc << SpriteRotation;
|
||||
}
|
||||
|
||||
{
|
||||
FString tagstr;
|
||||
|
@ -6399,6 +6404,7 @@ void AActor::Revive()
|
|||
flags5 = info->flags5;
|
||||
flags6 = info->flags6;
|
||||
flags7 = info->flags7;
|
||||
if (SpawnFlags & MTF_FRIENDLY) flags |= MF_FRIENDLY;
|
||||
DamageType = info->DamageType;
|
||||
health = SpawnHealth();
|
||||
target = NULL;
|
||||
|
|
|
@ -237,8 +237,7 @@ DPSprite *player_t::GetPSprite(PSPLayers layer)
|
|||
pspr->y = WEAPONTOP;
|
||||
}
|
||||
|
||||
pspr->oldx = pspr->x;
|
||||
pspr->oldy = pspr->y;
|
||||
pspr->firstTic = true;
|
||||
}
|
||||
|
||||
return pspr;
|
||||
|
@ -1087,7 +1086,7 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Lower)
|
|||
{ // Player is dead, so don't bring up a pending weapon
|
||||
// Player is dead, so keep the weapon off screen
|
||||
P_SetPsprite(player, PSP_FLASH, nullptr);
|
||||
psp->SetState(nullptr);
|
||||
psp->SetState(player->ReadyWeapon->FindState(NAME_DeadLowered));
|
||||
return 0;
|
||||
}
|
||||
// [RH] Clear the flash state. Only needed for Strife.
|
||||
|
|
|
@ -696,16 +696,16 @@ int P_Thing_CheckInputNum(player_t *p, int inputnum)
|
|||
}
|
||||
return renum;
|
||||
}
|
||||
bool P_Thing_CheckProximity(AActor *self, PClass *classname, double distance, int count, int flags, int ptr)
|
||||
int P_Thing_CheckProximity(AActor *self, PClass *classname, double distance, int count, int flags, int ptr, bool counting)
|
||||
{
|
||||
AActor *ref = COPY_AAPTR(self, ptr);
|
||||
|
||||
// We need these to check out.
|
||||
if (!ref || !classname || distance <= 0)
|
||||
return false;
|
||||
return 0;
|
||||
|
||||
int counter = 0;
|
||||
bool result = false;
|
||||
int result = 0;
|
||||
double closer = distance, farther = 0, current = distance;
|
||||
const bool ptrWillChange = !!(flags & (CPXF_SETTARGET | CPXF_SETMASTER | CPXF_SETTRACER));
|
||||
const bool ptrDistPref = !!(flags & (CPXF_CLOSEST | CPXF_FARTHEST));
|
||||
|
@ -740,7 +740,7 @@ bool P_Thing_CheckProximity(AActor *self, PClass *classname, double distance, in
|
|||
if ((ref->Distance2D(mo) < distance &&
|
||||
((flags & CPXF_NOZ) ||
|
||||
((ref->Z() > mo->Z() && ref->Z() - mo->Top() < distance) ||
|
||||
(ref->Z() <= mo->Z() && mo->Z() - ref->Top() < distance)))))
|
||||
(ref->Z() <= mo->Z() && mo->Z() - ref->Top() < distance)))))
|
||||
{
|
||||
if ((flags & CPXF_CHECKSIGHT) && !(P_CheckSight(mo, ref, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)))
|
||||
continue;
|
||||
|
@ -766,19 +766,19 @@ bool P_Thing_CheckProximity(AActor *self, PClass *classname, double distance, in
|
|||
{
|
||||
if (!(flags & (CPXF_COUNTDEAD | CPXF_DEADONLY)))
|
||||
continue;
|
||||
counter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flags & CPXF_DEADONLY)
|
||||
continue;
|
||||
counter++;
|
||||
}
|
||||
counter++;
|
||||
|
||||
// Abort if the number of matching classes nearby is greater, we have obviously succeeded in our goal.
|
||||
if (counter > count)
|
||||
{
|
||||
result = (flags & (CPXF_LESSOREQUAL | CPXF_EXACT)) ? false : true;
|
||||
// Don't abort if calling the counting version CheckProximity non-action function.
|
||||
if (!counting && counter > count)
|
||||
{
|
||||
result = (flags & (CPXF_LESSOREQUAL | CPXF_EXACT)) ? 0 : 1;
|
||||
|
||||
// However, if we have one SET* flag and either the closest or farthest flags, keep the function going.
|
||||
if (ptrWillChange && ptrDistPref)
|
||||
|
@ -805,12 +805,14 @@ bool P_Thing_CheckProximity(AActor *self, PClass *classname, double distance, in
|
|||
}
|
||||
}
|
||||
|
||||
if (counter == count)
|
||||
result = true;
|
||||
else if (counter < count)
|
||||
result = !!((flags & CPXF_LESSOREQUAL) && !(flags & CPXF_EXACT));
|
||||
|
||||
return result;
|
||||
if (!counting)
|
||||
{
|
||||
if (counter == count)
|
||||
result = 1;
|
||||
else if (counter < count)
|
||||
result = !!((flags & CPXF_LESSOREQUAL) && !(flags & CPXF_EXACT)) ? 1 : 0;
|
||||
}
|
||||
return counting ? counter : result;
|
||||
}
|
||||
|
||||
int P_Thing_Warp(AActor *caller, AActor *reference, double xofs, double yofs, double zofs, DAngle angle, int flags, double heightoffset, double radiusoffset, DAngle pitch)
|
||||
|
|
|
@ -248,9 +248,6 @@ void FConsoleWindow::AddText(const char* message)
|
|||
AddText(color, buffer);
|
||||
}
|
||||
|
||||
#define CHECK_BUFFER_SPACE \
|
||||
if (pos >= sizeof buffer - 3) { reset = true; continue; }
|
||||
|
||||
if (TEXTCOLOR_ESCAPE == *message)
|
||||
{
|
||||
const BYTE* colorID = reinterpret_cast<const BYTE*>(message) + 1;
|
||||
|
@ -268,42 +265,20 @@ void FConsoleWindow::AddText(const char* message)
|
|||
|
||||
message += 2;
|
||||
}
|
||||
else if (0x1d == *message) // Opening bar character
|
||||
else if (0x1d == *message || 0x1f == *message) // Opening and closing bar characters
|
||||
{
|
||||
CHECK_BUFFER_SPACE;
|
||||
|
||||
// Insert BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT
|
||||
buffer[pos++] = '\xe2';
|
||||
buffer[pos++] = '\x95';
|
||||
buffer[pos++] = '\xbc';
|
||||
buffer[pos++] = '-';
|
||||
++message;
|
||||
}
|
||||
else if (0x1e == *message) // Middle bar character
|
||||
{
|
||||
CHECK_BUFFER_SPACE;
|
||||
|
||||
// Insert BOX DRAWINGS HEAVY HORIZONTAL
|
||||
buffer[pos++] = '\xe2';
|
||||
buffer[pos++] = '\x94';
|
||||
buffer[pos++] = '\x81';
|
||||
++message;
|
||||
}
|
||||
else if (0x1f == *message) // Closing bar character
|
||||
{
|
||||
CHECK_BUFFER_SPACE;
|
||||
|
||||
// Insert BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT
|
||||
buffer[pos++] = '\xe2';
|
||||
buffer[pos++] = '\x95';
|
||||
buffer[pos++] = '\xbe';
|
||||
buffer[pos++] = '=';
|
||||
++message;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[pos++] = *message++;
|
||||
}
|
||||
|
||||
#undef CHECK_BUFFER_SPACE
|
||||
}
|
||||
|
||||
if (0 != pos)
|
||||
|
|
|
@ -809,11 +809,17 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
|
|||
angle_t rot;
|
||||
if (sprframe->Texture[0] == sprframe->Texture[1])
|
||||
{
|
||||
rot = (ang - thing->Angles.Yaw + 45.0/2*9).BAMs() >> 28;
|
||||
if (thing->flags7 & MF7_SPRITEANGLE)
|
||||
rot = (thing->SpriteAngle + 45.0 / 2 * 9).BAMs() >> 28;
|
||||
else
|
||||
rot = (ang - (thing->Angles.Yaw + thing->SpriteRotation) + 45.0 / 2 * 9).BAMs() >> 28;
|
||||
}
|
||||
else
|
||||
{
|
||||
rot = (ang - thing->Angles.Yaw + (45.0/2*9-180.0/16)).BAMs() >> 28;
|
||||
if (thing->flags7 & MF7_SPRITEANGLE)
|
||||
rot = (thing->SpriteAngle + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
|
||||
else
|
||||
rot = (ang - (thing->Angles.Yaw + thing->SpriteRotation) + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
|
||||
}
|
||||
picnum = sprframe->Texture[rot];
|
||||
if (sprframe->Flip & (1 << rot))
|
||||
|
@ -848,11 +854,17 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
|
|||
angle_t rot;
|
||||
if (sprframe->Texture[0] == sprframe->Texture[1])
|
||||
{
|
||||
rot = (ang - thing->Angles.Yaw + 45.0 / 2 * 9).BAMs() >> 28;
|
||||
if (thing->flags7 & MF7_SPRITEANGLE)
|
||||
rot = (thing->SpriteAngle + 45.0 / 2 * 9).BAMs() >> 28;
|
||||
else
|
||||
rot = (ang - (thing->Angles.Yaw + thing->SpriteRotation) + 45.0 / 2 * 9).BAMs() >> 28;
|
||||
}
|
||||
else
|
||||
{
|
||||
rot = (ang - thing->Angles.Yaw + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
|
||||
if (thing->flags7 & MF7_SPRITEANGLE)
|
||||
rot = (thing->SpriteAngle + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
|
||||
else
|
||||
rot = (ang - (thing->Angles.Yaw + thing->SpriteRotation) + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
|
||||
}
|
||||
picnum = sprframe->Texture[rot];
|
||||
if (sprframe->Flip & (1 << rot))
|
||||
|
@ -904,7 +916,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
|
|||
// too far off the side?
|
||||
// if it's a voxel, it can be further off the side
|
||||
if ((voxel == NULL && (fabs(tx / 64) > fabs(tz))) ||
|
||||
(voxel != NULL && (fabs(tx / 128) > abs(tz))))
|
||||
(voxel != NULL && (fabs(tx / 128) > fabs(tz))))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2805,6 +2817,11 @@ void R_DrawVoxel(const FVector3 &globalpos, FAngle viewangle,
|
|||
// Also do some magic voodoo scaling to make them the right size.
|
||||
daxscale = daxscale / (0xC000 >> 6);
|
||||
dayscale = dayscale / (0xC000 >> 6);
|
||||
if (daxscale <= 0 || dayscale <= 0)
|
||||
{
|
||||
// won't be visible.
|
||||
return;
|
||||
}
|
||||
|
||||
angle_t viewang = viewangle.BAMs();
|
||||
cosang = FLOAT2FIXED(viewangle.Cos()) >> 2;
|
||||
|
|
|
@ -361,16 +361,20 @@ static void FinishThingdef()
|
|||
if (sfunc == NULL)
|
||||
{
|
||||
FCompileContext ctx(ti);
|
||||
dmg->Resolve(ctx);
|
||||
VMFunctionBuilder buildit;
|
||||
buildit.Registers[REGT_POINTER].Get(1); // The self pointer
|
||||
dmg->Emit(&buildit);
|
||||
sfunc = buildit.MakeFunction();
|
||||
sfunc->NumArgs = 1;
|
||||
sfunc->Proto = NULL; ///FIXME: Need a proper prototype here
|
||||
// Save this function in case this damage value was reused
|
||||
// (which happens quite easily with inheritance).
|
||||
dmg->SetFunction(sfunc);
|
||||
dmg = static_cast<FxDamageValue *>(dmg->Resolve(ctx));
|
||||
|
||||
if (dmg != nullptr)
|
||||
{
|
||||
VMFunctionBuilder buildit;
|
||||
buildit.Registers[REGT_POINTER].Get(1); // The self pointer
|
||||
dmg->Emit(&buildit);
|
||||
sfunc = buildit.MakeFunction();
|
||||
sfunc->NumArgs = 1;
|
||||
sfunc->Proto = NULL; ///FIXME: Need a proper prototype here
|
||||
// Save this function in case this damage value was reused
|
||||
// (which happens quite easily with inheritance).
|
||||
dmg->SetFunction(sfunc);
|
||||
}
|
||||
}
|
||||
def->Damage = sfunc;
|
||||
|
||||
|
|
|
@ -395,6 +395,64 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetGibHealth)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetSpriteAngle
|
||||
//
|
||||
// NON-ACTION function returns the sprite angle of a pointer.
|
||||
//==========================================================================
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetSpriteAngle)
|
||||
{
|
||||
if (numret > 0)
|
||||
{
|
||||
assert(ret != NULL);
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; }
|
||||
|
||||
AActor *target = COPY_AAPTR(self, ptr);
|
||||
if (target == nullptr)
|
||||
{
|
||||
ret->SetFloat(0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
const double ang = target->SpriteAngle.Degrees;
|
||||
ret->SetFloat(ang);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetSpriteRotation
|
||||
//
|
||||
// NON-ACTION function returns the sprite rotation of a pointer.
|
||||
//==========================================================================
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetSpriteRotation)
|
||||
{
|
||||
if (numret > 0)
|
||||
{
|
||||
assert(ret != NULL);
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; }
|
||||
|
||||
AActor *target = COPY_AAPTR(self, ptr);
|
||||
if (target == nullptr)
|
||||
{
|
||||
ret->SetFloat(0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
const double ang = target->SpriteRotation.Degrees;
|
||||
ret->SetFloat(ang);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetZAt
|
||||
|
@ -585,6 +643,38 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetPlayerInput)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CountProximity
|
||||
//
|
||||
// NON-ACTION function of A_CheckProximity that returns how much it counts.
|
||||
// Takes a pointer as anyone may or may not be a player.
|
||||
//==========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, CountProximity)
|
||||
{
|
||||
if (numret > 0)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_CLASS(classname, AActor);
|
||||
PARAM_FLOAT(distance);
|
||||
PARAM_INT_OPT(flags) { flags = 0; }
|
||||
PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; }
|
||||
|
||||
AActor *mobj = COPY_AAPTR(self, ptr);
|
||||
if (mobj == nullptr)
|
||||
{
|
||||
ret->SetInt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret->SetInt(P_Thing_CheckProximity(self, classname, distance, 0, flags, ptr, true));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// __decorate_internal_state__
|
||||
|
@ -3013,12 +3103,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Recoil)
|
|||
// A_SelectWeapon
|
||||
//
|
||||
//===========================================================================
|
||||
enum SW_Flags
|
||||
{
|
||||
SWF_SELECTPRIORITY = 1,
|
||||
};
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SelectWeapon)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_CLASS(cls, AWeapon);
|
||||
PARAM_INT_OPT(flags) { flags = 0; }
|
||||
|
||||
if (cls == NULL || self->player == NULL)
|
||||
bool selectPriority = !!(flags & SWF_SELECTPRIORITY);
|
||||
|
||||
if ((!selectPriority && cls == NULL) || self->player == NULL)
|
||||
{
|
||||
ACTION_RETURN_BOOL(false);
|
||||
}
|
||||
|
@ -3033,6 +3130,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SelectWeapon)
|
|||
}
|
||||
ACTION_RETURN_BOOL(true);
|
||||
}
|
||||
else if (selectPriority)
|
||||
{
|
||||
// [XA] if the named weapon cannot be found (or is a dummy like 'None'),
|
||||
// select the next highest priority weapon. This is basically
|
||||
// the same as A_CheckReload minus the ammo check. Handy.
|
||||
self->player->mo->PickNewWeapon(NULL);
|
||||
ACTION_RETURN_BOOL(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ACTION_RETURN_BOOL(false);
|
||||
|
@ -7202,7 +7307,7 @@ enum CPSFFlags
|
|||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CopySpriteFrame)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_INT(from);
|
||||
PARAM_INT(to);
|
||||
PARAM_INT_OPT(flags) { flags = 0; }
|
||||
|
@ -7219,3 +7324,49 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CopySpriteFrame)
|
|||
if (!(flags & CPSF_NOFRAME)) copyto->frame = copyfrom->frame;
|
||||
ACTION_RETURN_BOOL(true);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// A_SetSpriteAngle(angle, ptr)
|
||||
//
|
||||
// Specifies which angle the actor must always draw its sprite from.
|
||||
//==========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpriteAngle)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_FLOAT_OPT(angle) { angle = 0.; }
|
||||
PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; }
|
||||
|
||||
AActor *mobj = COPY_AAPTR(self, ptr);
|
||||
|
||||
if (mobj == nullptr)
|
||||
{
|
||||
ACTION_RETURN_BOOL(false);
|
||||
}
|
||||
mobj->SpriteAngle = angle;
|
||||
ACTION_RETURN_BOOL(true);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// A_SetSpriteRotation(angle, ptr)
|
||||
//
|
||||
// Specifies how much to fake a sprite rotation.
|
||||
//==========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpriteRotation)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_ANGLE_OPT(angle) { angle = 0.; }
|
||||
PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; }
|
||||
|
||||
AActor *mobj = COPY_AAPTR(self, ptr);
|
||||
|
||||
if (mobj == nullptr)
|
||||
{
|
||||
ACTION_RETURN_BOOL(false);
|
||||
}
|
||||
mobj->SpriteRotation = angle;
|
||||
ACTION_RETURN_BOOL(true);
|
||||
}
|
||||
|
|
|
@ -259,6 +259,7 @@ static FFlagDef ActorFlagDefs[]=
|
|||
DEFINE_FLAG(MF7, ALLOWTHRUFLAGS, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, USEKILLSCRIPTS, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, NOKILLSCRIPTS, AActor, flags7),
|
||||
DEFINE_FLAG(MF7, SPRITEANGLE, AActor, flags7),
|
||||
|
||||
// Effect flags
|
||||
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
|
||||
|
|
|
@ -392,7 +392,7 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls)
|
|||
return ParseAtan2(sc, identifier, cls);
|
||||
default:
|
||||
args = new FArgumentList;
|
||||
func = dyn_cast<PFunction>(cls->Symbols.FindSymbol(identifier, true));
|
||||
func = (cls == nullptr) ? nullptr : dyn_cast<PFunction>(cls->Symbols.FindSymbol(identifier, true));
|
||||
try
|
||||
{
|
||||
// There is an action function ACS_NamedExecuteWithResult which must be ignored here for this to work.
|
||||
|
|
|
@ -48,8 +48,10 @@
|
|||
#define RESOLVE(p,c) if (p!=NULL) p = p->Resolve(c)
|
||||
#define ABORT(p) if (!(p)) { delete this; return NULL; }
|
||||
#define SAFE_RESOLVE(p,c) RESOLVE(p,c); ABORT(p)
|
||||
#define SAFE_RESOLVE_OPT(p,c) if (p!=NULL) { SAFE_RESOLVE(p,c) }
|
||||
|
||||
class VMFunctionBuilder;
|
||||
class FxJumpStatement;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -59,21 +61,15 @@ class VMFunctionBuilder;
|
|||
|
||||
struct FCompileContext
|
||||
{
|
||||
PClassActor *cls;
|
||||
TArray<FxJumpStatement *> Jumps;
|
||||
PClassActor *Class;
|
||||
|
||||
FCompileContext(PClassActor *_cls = NULL)
|
||||
{
|
||||
cls = _cls;
|
||||
}
|
||||
FCompileContext(PClassActor *cls = nullptr);
|
||||
|
||||
PSymbol *FindInClass(FName identifier)
|
||||
{
|
||||
return cls ? cls->Symbols.FindSymbol(identifier, true) : NULL;
|
||||
}
|
||||
PSymbol *FindGlobal(FName identifier)
|
||||
{
|
||||
return GlobalSymbols.FindSymbol(identifier, true);
|
||||
}
|
||||
PSymbol *FindInClass(FName identifier);
|
||||
PSymbol *FindGlobal(FName identifier);
|
||||
|
||||
void HandleJumps(int token, FxExpression *handler);
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
@ -212,6 +208,8 @@ public:
|
|||
|
||||
virtual ExpEmit Emit(VMFunctionBuilder *build);
|
||||
|
||||
TArray<FxJumpStatement *> JumpAddresses;
|
||||
|
||||
FScriptPosition ScriptPosition;
|
||||
PType *ValueType;
|
||||
|
||||
|
@ -930,6 +928,80 @@ public:
|
|||
ExpEmit Emit(VMFunctionBuilder *build);
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxWhileLoop
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FxWhileLoop : public FxExpression
|
||||
{
|
||||
FxExpression *Condition;
|
||||
FxExpression *Code;
|
||||
|
||||
public:
|
||||
FxWhileLoop(FxExpression *condition, FxExpression *code, const FScriptPosition &pos);
|
||||
~FxWhileLoop();
|
||||
FxExpression *Resolve(FCompileContext&);
|
||||
ExpEmit Emit(VMFunctionBuilder *build);
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxDoWhileLoop
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FxDoWhileLoop : public FxExpression
|
||||
{
|
||||
FxExpression *Condition;
|
||||
FxExpression *Code;
|
||||
|
||||
public:
|
||||
FxDoWhileLoop(FxExpression *condition, FxExpression *code, const FScriptPosition &pos);
|
||||
~FxDoWhileLoop();
|
||||
FxExpression *Resolve(FCompileContext&);
|
||||
ExpEmit Emit(VMFunctionBuilder *build);
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxForLoop
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FxForLoop : public FxExpression
|
||||
{
|
||||
FxExpression *Init;
|
||||
FxExpression *Condition;
|
||||
FxExpression *Iteration;
|
||||
FxExpression *Code;
|
||||
|
||||
public:
|
||||
FxForLoop(FxExpression *init, FxExpression *condition, FxExpression *iteration, FxExpression *code, const FScriptPosition &pos);
|
||||
~FxForLoop();
|
||||
FxExpression *Resolve(FCompileContext&);
|
||||
ExpEmit Emit(VMFunctionBuilder *build);
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxJumpStatement
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FxJumpStatement : public FxExpression
|
||||
{
|
||||
public:
|
||||
FxJumpStatement(int token, const FScriptPosition &pos);
|
||||
FxExpression *Resolve(FCompileContext&);
|
||||
ExpEmit Emit(VMFunctionBuilder *build);
|
||||
|
||||
int Token;
|
||||
size_t Address;
|
||||
FxExpression *AddressResolver;
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxReturnStatement
|
||||
|
|
|
@ -85,6 +85,45 @@ static const FLOP FxFlops[] =
|
|||
{ NAME_TanH, FLOP_TANH, [](double v) { return g_tanh(v); } },
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FCompileContext
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FCompileContext::FCompileContext(PClassActor *cls) : Class(cls)
|
||||
{
|
||||
}
|
||||
|
||||
PSymbol *FCompileContext::FindInClass(FName identifier)
|
||||
{
|
||||
return Class ? Class->Symbols.FindSymbol(identifier, true) : nullptr;
|
||||
}
|
||||
PSymbol *FCompileContext::FindGlobal(FName identifier)
|
||||
{
|
||||
return GlobalSymbols.FindSymbol(identifier, true);
|
||||
}
|
||||
|
||||
void FCompileContext::HandleJumps(int token, FxExpression *handler)
|
||||
{
|
||||
for (unsigned int i = 0; i < Jumps.Size(); i++)
|
||||
{
|
||||
if (Jumps[i]->Token == token)
|
||||
{
|
||||
Jumps[i]->AddressResolver = handler;
|
||||
handler->JumpAddresses.Push(Jumps[i]);
|
||||
Jumps.Delete(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ExpEmit
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
ExpEmit::ExpEmit(VMFunctionBuilder *build, int type)
|
||||
: RegNum(build->Registers[type].Get(1)), RegType(type), Konst(false), Fixed(false)
|
||||
{
|
||||
|
@ -375,7 +414,7 @@ ExpEmit FxBoolCast::Emit(VMFunctionBuilder *build)
|
|||
{
|
||||
build->Emit(OP_EQF_K, 1, from.RegNum, build->GetConstantFloat(0.));
|
||||
}
|
||||
else if (from.RegNum == REGT_POINTER)
|
||||
else if (from.RegType == REGT_POINTER)
|
||||
{
|
||||
build->Emit(OP_EQA_K, 1, from.RegNum, build->GetConstantAddress(nullptr, ATAG_GENERIC));
|
||||
}
|
||||
|
@ -2838,14 +2877,14 @@ FxSelf::FxSelf(const FScriptPosition &pos)
|
|||
FxExpression *FxSelf::Resolve(FCompileContext& ctx)
|
||||
{
|
||||
CHECKRESOLVED();
|
||||
if (!ctx.cls)
|
||||
if (!ctx.Class)
|
||||
{
|
||||
// can't really happen with DECORATE's expression evaluator.
|
||||
ScriptPosition.Message(MSG_ERROR, "self used outside of a member function");
|
||||
delete this;
|
||||
return NULL;
|
||||
}
|
||||
ValueType = ctx.cls;
|
||||
ValueType = ctx.Class;
|
||||
ValueType = NewPointer(RUNTIME_CLASS(DObject));
|
||||
return this;
|
||||
}
|
||||
|
@ -3818,6 +3857,369 @@ ExpEmit FxIfStatement::Emit(VMFunctionBuilder *build)
|
|||
return ExpEmit();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxWhileLoop
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxWhileLoop::FxWhileLoop(FxExpression *condition, FxExpression *code, const FScriptPosition &pos)
|
||||
: FxExpression(pos), Condition(condition), Code(code)
|
||||
{
|
||||
ValueType = TypeVoid;
|
||||
}
|
||||
|
||||
FxWhileLoop::~FxWhileLoop()
|
||||
{
|
||||
SAFE_DELETE(Condition);
|
||||
SAFE_DELETE(Code);
|
||||
}
|
||||
|
||||
FxExpression *FxWhileLoop::Resolve(FCompileContext &ctx)
|
||||
{
|
||||
CHECKRESOLVED();
|
||||
SAFE_RESOLVE(Condition, ctx);
|
||||
SAFE_RESOLVE_OPT(Code, ctx);
|
||||
|
||||
ctx.HandleJumps(TK_Break, this);
|
||||
ctx.HandleJumps(TK_Continue, this);
|
||||
|
||||
if (Condition->ValueType != TypeBool)
|
||||
{
|
||||
Condition = new FxBoolCast(Condition);
|
||||
SAFE_RESOLVE(Condition, ctx);
|
||||
}
|
||||
|
||||
if (Condition->isConstant())
|
||||
{
|
||||
if (static_cast<FxConstant *>(Condition)->GetValue().GetBool() == false)
|
||||
{ // Nothing happens
|
||||
FxExpression *nop = new FxNop(ScriptPosition);
|
||||
delete this;
|
||||
return nop;
|
||||
}
|
||||
else if (Code == nullptr)
|
||||
{ // "while (true) { }"
|
||||
// Someone could be using this for testing.
|
||||
ScriptPosition.Message(MSG_WARNING, "Infinite empty loop");
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
ExpEmit FxWhileLoop::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
assert(Condition->ValueType == TypeBool);
|
||||
|
||||
size_t loopstart, loopend;
|
||||
size_t jumpspot;
|
||||
|
||||
// Evaluate the condition and execute/break out of the loop.
|
||||
loopstart = build->GetAddress();
|
||||
if (!Condition->isConstant())
|
||||
{
|
||||
ExpEmit cond = Condition->Emit(build);
|
||||
build->Emit(OP_TEST, cond.RegNum, 0);
|
||||
jumpspot = build->Emit(OP_JMP, 0);
|
||||
cond.Free(build);
|
||||
}
|
||||
else assert(static_cast<FxConstant *>(Condition)->GetValue().GetBool() == true);
|
||||
|
||||
// Execute the loop's content.
|
||||
if (Code != nullptr)
|
||||
{
|
||||
ExpEmit code = Code->Emit(build);
|
||||
code.Free(build);
|
||||
}
|
||||
|
||||
// Loop back.
|
||||
build->Backpatch(build->Emit(OP_JMP, 0), loopstart);
|
||||
loopend = build->GetAddress();
|
||||
|
||||
if (!Condition->isConstant())
|
||||
{
|
||||
build->Backpatch(jumpspot, loopend);
|
||||
}
|
||||
|
||||
// Give a proper address to any break/continue statement within this loop.
|
||||
for (unsigned int i = 0; i < JumpAddresses.Size(); i++)
|
||||
{
|
||||
if (JumpAddresses[i]->Token == TK_Break)
|
||||
{
|
||||
build->Backpatch(JumpAddresses[i]->Address, loopend);
|
||||
}
|
||||
else
|
||||
{ // Continue statement.
|
||||
build->Backpatch(JumpAddresses[i]->Address, loopstart);
|
||||
}
|
||||
}
|
||||
|
||||
return ExpEmit();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxDoWhileLoop
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxDoWhileLoop::FxDoWhileLoop(FxExpression *condition, FxExpression *code, const FScriptPosition &pos)
|
||||
: FxExpression(pos), Condition(condition), Code(code)
|
||||
{
|
||||
ValueType = TypeVoid;
|
||||
}
|
||||
|
||||
FxDoWhileLoop::~FxDoWhileLoop()
|
||||
{
|
||||
SAFE_DELETE(Condition);
|
||||
SAFE_DELETE(Code);
|
||||
}
|
||||
|
||||
FxExpression *FxDoWhileLoop::Resolve(FCompileContext &ctx)
|
||||
{
|
||||
CHECKRESOLVED();
|
||||
SAFE_RESOLVE(Condition, ctx);
|
||||
SAFE_RESOLVE_OPT(Code, ctx);
|
||||
|
||||
ctx.HandleJumps(TK_Break, this);
|
||||
ctx.HandleJumps(TK_Continue, this);
|
||||
|
||||
if (Condition->ValueType != TypeBool)
|
||||
{
|
||||
Condition = new FxBoolCast(Condition);
|
||||
SAFE_RESOLVE(Condition, ctx);
|
||||
}
|
||||
|
||||
if (Condition->isConstant())
|
||||
{
|
||||
if (static_cast<FxConstant *>(Condition)->GetValue().GetBool() == false)
|
||||
{ // The code executes once, if any.
|
||||
if (JumpAddresses.Size() == 0)
|
||||
{ // We would still have to handle the jumps however.
|
||||
FxExpression *e = Code;
|
||||
if (e == nullptr) e = new FxNop(ScriptPosition);
|
||||
Code = nullptr;
|
||||
delete this;
|
||||
return e;
|
||||
}
|
||||
}
|
||||
else if (Code == nullptr)
|
||||
{ // "do { } while (true);"
|
||||
// Someone could be using this for testing.
|
||||
ScriptPosition.Message(MSG_WARNING, "Infinite empty loop");
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
ExpEmit FxDoWhileLoop::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
assert(Condition->ValueType == TypeBool);
|
||||
|
||||
size_t loopstart, loopend;
|
||||
size_t codestart;
|
||||
|
||||
// Execute the loop's content.
|
||||
codestart = build->GetAddress();
|
||||
if (Code != nullptr)
|
||||
{
|
||||
ExpEmit code = Code->Emit(build);
|
||||
code.Free(build);
|
||||
}
|
||||
|
||||
// Evaluate the condition and execute/break out of the loop.
|
||||
loopstart = build->GetAddress();
|
||||
if (!Condition->isConstant())
|
||||
{
|
||||
ExpEmit cond = Condition->Emit(build);
|
||||
build->Emit(OP_TEST, cond.RegNum, 1);
|
||||
cond.Free(build);
|
||||
build->Backpatch(build->Emit(OP_JMP, 0), codestart);
|
||||
}
|
||||
else if (static_cast<FxConstant *>(Condition)->GetValue().GetBool() == true)
|
||||
{ // Always looping
|
||||
build->Backpatch(build->Emit(OP_JMP, 0), codestart);
|
||||
}
|
||||
loopend = build->GetAddress();
|
||||
|
||||
// Give a proper address to any break/continue statement within this loop.
|
||||
for (unsigned int i = 0; i < JumpAddresses.Size(); i++)
|
||||
{
|
||||
if (JumpAddresses[i]->Token == TK_Break)
|
||||
{
|
||||
build->Backpatch(JumpAddresses[i]->Address, loopend);
|
||||
}
|
||||
else
|
||||
{ // Continue statement.
|
||||
build->Backpatch(JumpAddresses[i]->Address, loopstart);
|
||||
}
|
||||
}
|
||||
|
||||
return ExpEmit();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxForLoop
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxForLoop::FxForLoop(FxExpression *init, FxExpression *condition, FxExpression *iteration, FxExpression *code, const FScriptPosition &pos)
|
||||
: FxExpression(pos), Init(init), Condition(condition), Iteration(iteration), Code(code)
|
||||
{
|
||||
ValueType = TypeVoid;
|
||||
}
|
||||
|
||||
FxForLoop::~FxForLoop()
|
||||
{
|
||||
SAFE_DELETE(Init);
|
||||
SAFE_DELETE(Condition);
|
||||
SAFE_DELETE(Iteration);
|
||||
SAFE_DELETE(Code);
|
||||
}
|
||||
|
||||
FxExpression *FxForLoop::Resolve(FCompileContext &ctx)
|
||||
{
|
||||
CHECKRESOLVED();
|
||||
SAFE_RESOLVE_OPT(Init, ctx);
|
||||
SAFE_RESOLVE_OPT(Condition, ctx);
|
||||
SAFE_RESOLVE_OPT(Iteration, ctx);
|
||||
SAFE_RESOLVE_OPT(Code, ctx);
|
||||
|
||||
ctx.HandleJumps(TK_Break, this);
|
||||
ctx.HandleJumps(TK_Continue, this);
|
||||
|
||||
if (Condition != nullptr)
|
||||
{
|
||||
if (Condition->ValueType != TypeBool)
|
||||
{
|
||||
Condition = new FxBoolCast(Condition);
|
||||
SAFE_RESOLVE(Condition, ctx);
|
||||
}
|
||||
|
||||
if (Condition->isConstant())
|
||||
{
|
||||
if (static_cast<FxConstant *>(Condition)->GetValue().GetBool() == false)
|
||||
{ // Nothing happens
|
||||
FxExpression *nop = new FxNop(ScriptPosition);
|
||||
delete this;
|
||||
return nop;
|
||||
}
|
||||
else
|
||||
{ // "for (..; true; ..)"
|
||||
delete Condition;
|
||||
Condition = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Condition == nullptr && Code == nullptr)
|
||||
{ // "for (..; ; ..) { }"
|
||||
// Someone could be using this for testing.
|
||||
ScriptPosition.Message(MSG_WARNING, "Infinite empty loop");
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
ExpEmit FxForLoop::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
assert((Condition && Condition->ValueType == TypeBool && !Condition->isConstant()) || Condition == nullptr);
|
||||
|
||||
size_t loopstart, loopend;
|
||||
size_t codestart;
|
||||
size_t jumpspot;
|
||||
|
||||
// Init statement.
|
||||
if (Init != nullptr)
|
||||
{
|
||||
ExpEmit init = Init->Emit(build);
|
||||
init.Free(build);
|
||||
}
|
||||
|
||||
// Evaluate the condition and execute/break out of the loop.
|
||||
codestart = build->GetAddress();
|
||||
if (Condition != nullptr)
|
||||
{
|
||||
ExpEmit cond = Condition->Emit(build);
|
||||
build->Emit(OP_TEST, cond.RegNum, 0);
|
||||
cond.Free(build);
|
||||
jumpspot = build->Emit(OP_JMP, 0);
|
||||
}
|
||||
|
||||
// Execute the loop's content.
|
||||
if (Code != nullptr)
|
||||
{
|
||||
ExpEmit code = Code->Emit(build);
|
||||
code.Free(build);
|
||||
}
|
||||
|
||||
// Iteration statement.
|
||||
loopstart = build->GetAddress();
|
||||
if (Iteration != nullptr)
|
||||
{
|
||||
ExpEmit iter = Iteration->Emit(build);
|
||||
iter.Free(build);
|
||||
}
|
||||
build->Backpatch(build->Emit(OP_JMP, 0), codestart);
|
||||
|
||||
// End of loop.
|
||||
loopend = build->GetAddress();
|
||||
if (Condition != nullptr)
|
||||
{
|
||||
build->Backpatch(jumpspot, loopend);
|
||||
}
|
||||
|
||||
// Give a proper address to any break/continue statement within this loop.
|
||||
for (unsigned int i = 0; i < JumpAddresses.Size(); i++)
|
||||
{
|
||||
if (JumpAddresses[i]->Token == TK_Break)
|
||||
{
|
||||
build->Backpatch(JumpAddresses[i]->Address, loopend);
|
||||
}
|
||||
else
|
||||
{ // Continue statement.
|
||||
build->Backpatch(JumpAddresses[i]->Address, loopstart);
|
||||
}
|
||||
}
|
||||
|
||||
return ExpEmit();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxJumpStatement
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxJumpStatement::FxJumpStatement(int token, const FScriptPosition &pos)
|
||||
: FxExpression(pos), Token(token), AddressResolver(nullptr)
|
||||
{
|
||||
ValueType = TypeVoid;
|
||||
}
|
||||
|
||||
FxExpression *FxJumpStatement::Resolve(FCompileContext &ctx)
|
||||
{
|
||||
CHECKRESOLVED();
|
||||
|
||||
ctx.Jumps.Push(this);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
ExpEmit FxJumpStatement::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
if (AddressResolver == nullptr)
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Jump statement %s has nowhere to go!", FScanner::TokenName(Token).GetChars());
|
||||
}
|
||||
|
||||
Address = build->Emit(OP_JMP, 0);
|
||||
|
||||
return ExpEmit();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
@ -4008,19 +4410,21 @@ ExpEmit FxClassTypeCast::Emit(VMFunctionBuilder *build)
|
|||
FxExpression *FxStateByIndex::Resolve(FCompileContext &ctx)
|
||||
{
|
||||
CHECKRESOLVED();
|
||||
if (ctx.cls->NumOwnedStates == 0)
|
||||
ABORT(ctx.Class);
|
||||
|
||||
if (ctx.Class->NumOwnedStates == 0)
|
||||
{
|
||||
// This can't really happen
|
||||
assert(false);
|
||||
}
|
||||
if (ctx.cls->NumOwnedStates <= index)
|
||||
if (ctx.Class->NumOwnedStates <= index)
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "%s: Attempt to jump to non existing state index %d",
|
||||
ctx.cls->TypeName.GetChars(), index);
|
||||
ctx.Class->TypeName.GetChars(), index);
|
||||
delete this;
|
||||
return NULL;
|
||||
}
|
||||
FxExpression *x = new FxConstant(ctx.cls->OwnedStates + index, ScriptPosition);
|
||||
FxExpression *x = new FxConstant(ctx.Class->OwnedStates + index, ScriptPosition);
|
||||
delete this;
|
||||
return x;
|
||||
}
|
||||
|
@ -4062,13 +4466,15 @@ FxMultiNameState::FxMultiNameState(const char *_statestring, const FScriptPositi
|
|||
FxExpression *FxMultiNameState::Resolve(FCompileContext &ctx)
|
||||
{
|
||||
CHECKRESOLVED();
|
||||
ABORT(ctx.Class);
|
||||
|
||||
if (names[0] == NAME_None)
|
||||
{
|
||||
scope = NULL;
|
||||
}
|
||||
else if (names[0] == NAME_Super)
|
||||
{
|
||||
scope = dyn_cast<PClassActor>(ctx.cls->ParentClass);
|
||||
scope = dyn_cast<PClassActor>(ctx.Class->ParentClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4079,9 +4485,9 @@ FxExpression *FxMultiNameState::Resolve(FCompileContext &ctx)
|
|||
delete this;
|
||||
return NULL;
|
||||
}
|
||||
else if (!scope->IsDescendantOf(ctx.cls))
|
||||
else if (!scope->IsDescendantOf(ctx.Class))
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "'%s' is not an ancestor of '%s'", names[0].GetChars(),ctx.cls->TypeName.GetChars());
|
||||
ScriptPosition.Message(MSG_ERROR, "'%s' is not an ancestor of '%s'", names[0].GetChars(),ctx.Class->TypeName.GetChars());
|
||||
delete this;
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -191,7 +191,12 @@ static void ParseConstant (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
|
|||
FxExpression *expr = ParseExpression (sc, cls, true);
|
||||
sc.MustGetToken(';');
|
||||
|
||||
if (!expr->isConstant())
|
||||
if (expr == nullptr)
|
||||
{
|
||||
sc.ScriptMessage("Error while resolving constant definition");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
else if (!expr->isConstant())
|
||||
{
|
||||
sc.ScriptMessage("Constant definition is not a constant");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
|
@ -247,16 +252,24 @@ static void ParseEnum (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
|
|||
if (sc.CheckToken('='))
|
||||
{
|
||||
FxExpression *expr = ParseExpression (sc, cls, true);
|
||||
if (!expr->isConstant())
|
||||
if (expr != nullptr)
|
||||
{
|
||||
sc.ScriptMessage("'%s' must be constant", symname.GetChars());
|
||||
FScriptPosition::ErrorCounter++;
|
||||
if (!expr->isConstant())
|
||||
{
|
||||
sc.ScriptMessage("'%s' must be constant", symname.GetChars());
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
currvalue = static_cast<FxConstant *>(expr)->GetValue().GetInt();
|
||||
}
|
||||
delete expr;
|
||||
}
|
||||
else
|
||||
{
|
||||
currvalue = static_cast<FxConstant *>(expr)->GetValue().GetInt();
|
||||
sc.ScriptMessage("Error while resolving expression of '%s'", symname.GetChars());
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
delete expr;
|
||||
}
|
||||
PSymbolConstNumeric *sym = new PSymbolConstNumeric(symname, TypeSInt32);
|
||||
sym->Value = currvalue;
|
||||
|
@ -568,7 +581,13 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClassActor *cl
|
|||
if (sc.CheckToken('['))
|
||||
{
|
||||
FxExpression *expr = ParseExpression(sc, cls, true);
|
||||
if (!expr->isConstant())
|
||||
if (expr == nullptr)
|
||||
{
|
||||
sc.ScriptMessage("Error while resolving array size");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
maxelems = 1;
|
||||
}
|
||||
else if (!expr->isConstant())
|
||||
{
|
||||
sc.ScriptMessage("Array size must be a constant");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
|
|
|
@ -1345,6 +1345,24 @@ DEFINE_PROPERTY(gravity, F, Actor)
|
|||
defaults->Gravity = i;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(spriteangle, F, Actor)
|
||||
{
|
||||
PROP_DOUBLE_PARM(i, 0);
|
||||
defaults->SpriteAngle = i;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(spriterotation, F, Actor)
|
||||
{
|
||||
PROP_DOUBLE_PARM(i, 0);
|
||||
defaults->SpriteRotation = i;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
|
|
@ -480,6 +480,93 @@ static FxExpression *ParseIf(FScanner &sc, FState state, FString statestring, Ba
|
|||
return add;
|
||||
}
|
||||
|
||||
static FxExpression *ParseWhile(FScanner &sc, FState state, FString statestring, Baggage &bag,
|
||||
PPrototype *&retproto, bool &lastwasret)
|
||||
{
|
||||
FxExpression *cond, *code;
|
||||
PPrototype *proto;
|
||||
bool ret;
|
||||
|
||||
sc.MustGetStringName("(");
|
||||
cond = ParseExpression(sc, bag.Info);
|
||||
sc.MustGetStringName(")");
|
||||
sc.MustGetStringName("{"); // Enforce braces like for if statements.
|
||||
|
||||
code = ParseActions(sc, state, statestring, bag, proto, ret);
|
||||
sc.MustGetString();
|
||||
|
||||
retproto = ReturnCheck(retproto, proto, sc);
|
||||
lastwasret = false; // A while loop always jumps back.
|
||||
|
||||
return new FxWhileLoop(cond, code, sc);
|
||||
}
|
||||
|
||||
static FxExpression *ParseDoWhile(FScanner &sc, FState state, FString statestring, Baggage &bag,
|
||||
PPrototype *&retproto, bool &lastwasret)
|
||||
{
|
||||
FxExpression *cond, *code;
|
||||
PPrototype *proto;
|
||||
bool ret;
|
||||
|
||||
sc.MustGetStringName("{"); // Enforce braces like for if statements.
|
||||
code = ParseActions(sc, state, statestring, bag, proto, ret);
|
||||
|
||||
sc.MustGetStringName("while");
|
||||
sc.MustGetStringName("(");
|
||||
cond = ParseExpression(sc, bag.Info);
|
||||
sc.MustGetStringName(")");
|
||||
sc.MustGetStringName(";");
|
||||
sc.MustGetString();
|
||||
|
||||
retproto = ReturnCheck(retproto, proto, sc);
|
||||
lastwasret = false;
|
||||
|
||||
return new FxDoWhileLoop(cond, code, sc);
|
||||
}
|
||||
|
||||
static FxExpression *ParseFor(FScanner &sc, FState state, FString statestring, Baggage &bag,
|
||||
PPrototype *&retproto, bool &lastwasret)
|
||||
{
|
||||
FxExpression *init = nullptr;
|
||||
FxExpression *cond = nullptr;
|
||||
FxExpression *iter = nullptr;
|
||||
FxExpression *code = nullptr;
|
||||
PPrototype *proto;
|
||||
bool ret;
|
||||
|
||||
// Parse the statements.
|
||||
sc.MustGetStringName("(");
|
||||
sc.MustGetString();
|
||||
if (!sc.Compare(";"))
|
||||
{
|
||||
init = ParseAction(sc, state, statestring, bag); // That's all DECORATE can handle for now.
|
||||
sc.MustGetStringName(";");
|
||||
}
|
||||
sc.MustGetString();
|
||||
if (!sc.Compare(";"))
|
||||
{
|
||||
sc.UnGet();
|
||||
cond = ParseExpression(sc, bag.Info);
|
||||
sc.MustGetStringName(";");
|
||||
}
|
||||
sc.MustGetString();
|
||||
if (!sc.Compare(")"))
|
||||
{
|
||||
iter = ParseAction(sc, state, statestring, bag);
|
||||
sc.MustGetStringName(")");
|
||||
}
|
||||
|
||||
// Now parse the loop's content.
|
||||
sc.MustGetStringName("{"); // Enforce braces like for if statements.
|
||||
code = ParseActions(sc, state, statestring, bag, proto, ret);
|
||||
sc.MustGetString();
|
||||
|
||||
retproto = ReturnCheck(retproto, proto, sc);
|
||||
lastwasret = false;
|
||||
|
||||
return new FxForLoop(init, cond, iter, code, sc);
|
||||
}
|
||||
|
||||
FxExpression *ParseActions(FScanner &sc, FState state, FString statestring, Baggage &bag,
|
||||
PPrototype *&retproto, bool &endswithret)
|
||||
{
|
||||
|
@ -505,9 +592,21 @@ FxExpression *ParseActions(FScanner &sc, FState state, FString statestring, Bagg
|
|||
FxExpression *add;
|
||||
lastwasret = false;
|
||||
if (sc.Compare("if"))
|
||||
{ // Hangle an if statement
|
||||
{ // Handle an if statement
|
||||
add = ParseIf(sc, state, statestring, bag, proto, lastwasret);
|
||||
}
|
||||
else if (sc.Compare("while"))
|
||||
{ // Handle a while loop
|
||||
add = ParseWhile(sc, state, statestring, bag, proto, lastwasret);
|
||||
}
|
||||
else if (sc.Compare("do"))
|
||||
{ // Handle a do-while loop
|
||||
add = ParseDoWhile(sc, state, statestring, bag, proto, lastwasret);
|
||||
}
|
||||
else if (sc.Compare("for"))
|
||||
{ // Handle a for loop
|
||||
add = ParseFor(sc, state, statestring, bag, proto, lastwasret);
|
||||
}
|
||||
else if (sc.Compare("return"))
|
||||
{ // Handle a return statement
|
||||
lastwasret = true;
|
||||
|
@ -529,6 +628,18 @@ FxExpression *ParseActions(FScanner &sc, FState state, FString statestring, Bagg
|
|||
sc.MustGetString();
|
||||
add = new FxReturnStatement(retexp, sc);
|
||||
}
|
||||
else if (sc.Compare("break"))
|
||||
{
|
||||
add = new FxJumpStatement(TK_Break, sc);
|
||||
sc.MustGetStringName(";");
|
||||
sc.MustGetString();
|
||||
}
|
||||
else if (sc.Compare("continue"))
|
||||
{
|
||||
add = new FxJumpStatement(TK_Continue, sc);
|
||||
sc.MustGetStringName(";");
|
||||
sc.MustGetString();
|
||||
}
|
||||
else
|
||||
{ // Handle a regular action function call
|
||||
add = ParseAction(sc, state, statestring, bag);
|
||||
|
|
|
@ -1326,6 +1326,19 @@ void DCanvas::Clear (int left, int top, int right, int bottom, int palcolor, uin
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// no-ops. This is so that renderer backends can better manage the
|
||||
// processing of the subsector drawing in the automap
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void DCanvas::StartSimplePolys()
|
||||
{}
|
||||
|
||||
void DCanvas::FinishSimplePolys()
|
||||
{}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DCanvas :: FillSimplePoly
|
||||
|
|
|
@ -217,6 +217,9 @@ public:
|
|||
// Fill an area with a texture
|
||||
virtual void FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin=false);
|
||||
|
||||
virtual void StartSimplePolys();
|
||||
virtual void FinishSimplePolys();
|
||||
|
||||
// Fill a simple polygon with a texture
|
||||
virtual void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints,
|
||||
double originx, double originy, double scalex, double scaley, DAngle rotation,
|
||||
|
|
|
@ -76,7 +76,7 @@ const char *GetVersionString();
|
|||
|
||||
// Use 4500 as the base git save version, since it's higher than the
|
||||
// SVN revision ever got.
|
||||
#define SAVEVER 4548
|
||||
#define SAVEVER 4549
|
||||
|
||||
#define SAVEVERSTRINGIFY2(x) #x
|
||||
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)
|
||||
|
|
|
@ -436,6 +436,17 @@ bool VMFunctionBuilder::RegAvailability::Reuse(int reg)
|
|||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// VMFunctionBuilder :: GetAddress
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
size_t VMFunctionBuilder::GetAddress()
|
||||
{
|
||||
return Code.Size();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// VMFunctionBuilder :: Emit
|
||||
|
|
|
@ -34,6 +34,9 @@ public:
|
|||
int GetConstantAddress(void *ptr, VM_ATAG tag);
|
||||
int GetConstantString(FString str);
|
||||
|
||||
// Returns the address of the next instruction to be emitted.
|
||||
size_t GetAddress();
|
||||
|
||||
// Returns the address of the newly-emitted instruction.
|
||||
size_t Emit(int opcode, int opa, int opb, int opc);
|
||||
size_t Emit(int opcode, int opa, VM_SHALF opbc);
|
||||
|
|
|
@ -35,6 +35,8 @@ ACTOR Actor native //: Thinker
|
|||
BloodType "Blood", "BloodSplatter", "AxeBlood"
|
||||
ExplosionDamage 128
|
||||
MissileHeight 32
|
||||
SpriteAngle 0
|
||||
SpriteRotation 0
|
||||
|
||||
// Functions
|
||||
native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false);
|
||||
|
@ -48,6 +50,9 @@ ACTOR Actor native //: Thinker
|
|||
native float GetCrouchFactor(int ptr = AAPTR_PLAYER1);
|
||||
native float GetCVar(string cvar);
|
||||
native int GetPlayerInput(int inputnum, int ptr = AAPTR_DEFAULT);
|
||||
native int CountProximity(class<Actor> classname, float distance, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||
native float GetSpriteAngle(int ptr = AAPTR_DEFAULT);
|
||||
native float GetSpriteRotation(int ptr = AAPTR_DEFAULT);
|
||||
|
||||
// Action functions
|
||||
// Meh, MBF redundant functions. Only for DeHackEd support.
|
||||
|
@ -239,7 +244,7 @@ ACTOR Actor native //: Thinker
|
|||
native state A_JumpIfInTargetInventory(class<Inventory> itemtype, int amount, state label, int forward_ptr = AAPTR_DEFAULT);
|
||||
native bool A_GiveToTarget(class<Inventory> itemtype, int amount = 0, int forward_ptr = AAPTR_DEFAULT);
|
||||
native bool A_TakeFromTarget(class<Inventory> itemtype, int amount = 0, int flags = 0, int forward_ptr = AAPTR_DEFAULT);
|
||||
native int A_RadiusGive(class<Inventory> itemtype, float distance, int flags, int amount = 0, class<Actor> filter = "None", name species = "None", int mindist = 0, int limit = 0);
|
||||
native int A_RadiusGive(class<Inventory> itemtype, float distance, int flags, int amount = 0, class<Actor> filter = "None", name species = "None", float mindist = 0, int limit = 0);
|
||||
native state A_CheckSpecies(state jump, name species = "", int ptr = AAPTR_DEFAULT);
|
||||
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);
|
||||
|
@ -260,7 +265,7 @@ ACTOR Actor native //: Thinker
|
|||
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_JumpIfTargetInLOS (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);
|
||||
native bool A_SelectWeapon(class<Weapon> whichweapon);
|
||||
native bool A_SelectWeapon(class<Weapon> whichweapon, int flags = 0);
|
||||
action native A_Punch();
|
||||
action native A_Feathers();
|
||||
action native A_ClassBossHealth();
|
||||
|
@ -331,6 +336,8 @@ ACTOR Actor native //: Thinker
|
|||
action native bool A_FaceMovementDirection(float offset = 0, float anglelimit = 0, float pitchlimit = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||
action native int A_ClearOverlays(int sstart = 0, int sstop = 0, bool safety = true);
|
||||
action native bool A_CopySpriteFrame(int from, int to, int flags = 0);
|
||||
action native bool A_SetSpriteAngle(float angle = 0, int ptr = AAPTR_DEFAULT);
|
||||
action native bool A_SetSpriteRotation(float angle = 0, int ptr = AAPTR_DEFAULT);
|
||||
|
||||
native void A_RearrangePointers(int newtarget, int newmaster = AAPTR_DEFAULT, int newtracer = AAPTR_DEFAULT, int flags=0);
|
||||
native void A_TransferPointer(int ptr_source, int ptr_recepient, int sourcefield, int recepientfield=AAPTR_DEFAULT, int flags=0);
|
||||
|
|
|
@ -150,6 +150,9 @@ const int WRF_ALLOWUSER2 = 256;
|
|||
const int WRF_ALLOWUSER3 = 512;
|
||||
const int WRF_ALLOWUSER4 = 1024;
|
||||
|
||||
// Flags for A_SelectWeapon
|
||||
const int SWF_SELECTPRIORITY = 1;
|
||||
|
||||
// Morph constants
|
||||
const int MRF_ADDSTAMINA = 1;
|
||||
const int MRF_FULLHEALTH = 2;
|
||||
|
|
|
@ -2201,6 +2201,7 @@ OPTVAL_PLAYER = "Player";
|
|||
OPTVAL_MAP = "Map";
|
||||
OPTVAL_SCALETO640X400 = "Scale to 640x400";
|
||||
OPTVAL_PIXELDOUBLE = "Pixel double";
|
||||
OPTVAL_PIXELQUADRUPLE = "Pixel quadruple";
|
||||
OPTVAL_CURRENTWEAPON = "Current weapon";
|
||||
OPTVAL_AVAILABLEWEAPONS = "Available weapons";
|
||||
OPTVAL_ALLWEAPONS = "All weapons";
|
||||
|
@ -2235,6 +2236,7 @@ OPTVAL_ANIMATED = "Animated";
|
|||
OPTVAL_ROTATED = "Rotated";
|
||||
OPTVAL_MAPDEFINEDCOLORSONLY = "Map defined colors only";
|
||||
OPTVAL_DOUBLE = "Double";
|
||||
OPTVAL_QUADRUPLE = "Quadruple";
|
||||
OPTVAL_ITEMPICKUP = "Item Pickup";
|
||||
OPTVAL_OBITUARIES = "Obituaries";
|
||||
OPTVAL_CRITICALMESSAGES = "Critical Messages";
|
||||
|
|
|
@ -764,7 +764,7 @@ OptionMenu "HUDOptions"
|
|||
Option "$HUDMNU_GROWCROSSHAIR", "crosshairgrow", "OnOff"
|
||||
ColorPicker "$HUDMNU_CROSSHAIRCOLOR", "crosshaircolor"
|
||||
Option "$HUDMNU_CROSSHAIRHEALTH", "crosshairhealth", "OnOff"
|
||||
Option "$HUDMNU_CROSSHAIRSCALE", "crosshairscale", "OnOff"
|
||||
Slider "$HUDMNU_CROSSHAIRSCALE", "crosshairscale", 0.0, 2.0, 0.05, 2
|
||||
StaticText " "
|
||||
Option "$HUDMNU_NAMETAGS", "displaynametags", "DisplayTagsTypes"
|
||||
Option "$HUDMNU_NAMETAGCOLOR", "nametagcolor", "TextColors", "displaynametags"
|
||||
|
@ -795,6 +795,7 @@ OptionValue "AltHUDScale"
|
|||
0, "$OPTVAL_OFF"
|
||||
1, "$OPTVAL_SCALETO640X400"
|
||||
2, "$OPTVAL_PIXELDOUBLE"
|
||||
3, "$OPTVAL_PIXELQUADRUPLE"
|
||||
}
|
||||
|
||||
OptionValue "AltHUDAmmo"
|
||||
|
@ -1111,6 +1112,7 @@ OptionValue ScaleValues
|
|||
0, "$OPTVAL_OFF"
|
||||
1, "$OPTVAL_ON"
|
||||
2, "$OPTVAL_DOUBLE"
|
||||
3, "$OPTVAL_QUADRUPLE"
|
||||
}
|
||||
|
||||
OptionValue MessageLevels
|
||||
|
|
|
@ -251,3 +251,13 @@ enum
|
|||
466 = 0, Floor_TransferTrigger(0)
|
||||
467 = 0, Floor_TransferNumeric(0)
|
||||
468 = 0, FloorAndCeiling_LowerRaise(0)
|
||||
469 = 0, HealThing(0)
|
||||
470 = 0, Sector_SetRotation(0)
|
||||
471 = 0, Sector_SetFloorPanning(0)
|
||||
472 = 0, Sector_SetCeilingPanning(0)
|
||||
473 = 0, Light_MinNeighbor(0)
|
||||
474 = 0, Polyobj_Stop(0)
|
||||
475 = 0, Plat_RaiseAndStayTx0(0)
|
||||
476 = 0, Plat_UpByValueStayTx(0)
|
||||
477 = 0, ACS_ExecuteAlways(0)
|
||||
478 = 0, Thing_Remove(0)
|
||||
|
|
Loading…
Reference in a new issue