Update to ZDoom r2047:

- Fixed: Decals could spread to walls which had a decal-less texture or
  were flagged not to have decals.
- Fixed: DBaseDecal/DImpactDecal::CloneSelf never checked the return value
  from their StickToWall call and left unplaced decals behind if that happened.
- Reintroduced Doom.exe's player_t::usedown variable so that respawning a
  player does not immediately activate switches. oldbuttons was not usable
  for this. This also required that CopyPlayer preserves this info.
- Fixed: When restarting the music there was a NULL pointer check missing
  so it crashed when the game was started wi
- Fixed: If the Use key is used to respawn the player it must be cleared
  so that it doesn't trigger any subsequent actions after respawning.
- Fixed: Resurrecting a monster did not restore flags5 and flags6.
- Fixed: Projectiles which killed a non-monster were unable to determine
  what precisely they hit because MF_CORPSE is only valid for monsters.
  A new flag, MF6_KILLED that gets set for all objects that die, was added
  for this case.
- Added a generic A_Weave function that exposes all possible options of
  A_BishopMissileWeave and A_CStaffMissileSlither. These 2 functions are
  no longer needed from DECORATE and therefore deprecated.
- The options menu no longer scales up so quickly, so it can fit wider text
  onscreen. In addition, it now uses the whole height available to it. Also,
  at lower resolutions, items on the compatibility options menu now cut off
  the beginning of the option label rather than the option setting, making
  this menu useable where previously it was not.
- Added a channel parameter to the sector overload of SN_StopSequence() so
  it can be properly paired with calls to SN_StartSequence().
- Fixed: P_CheckPlayerSprites() ignored the MF4_NOSKIN flag.  It now also sets
  the X scale, so switching skins while morphed does not produce weird
  stretching upon unmorphing.
- Fixed: Calling S_ChangeMusic() with the same song but a different looping
  flag now restarts the song so that the new looping setting can be applied.
  (This was easier than modifying every music handler to support modifying
  loop changes on the fly, which seems like overkill.)
- Fixed: savepatchsize was declared incorrectly in d_dehacked.cpp:DoInclude().
- Changed AFastProjectile::Effect() so that it sets the spawned trail to face
  same direction as the projectile.

git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@672 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
Christoph Oelckers 2009-12-25 12:10:12 +00:00
parent 8653592339
commit 7d5c48606b
35 changed files with 437 additions and 177 deletions

View file

@ -1,3 +1,67 @@
December 25, 2009 (Changes by Graf Zahl)
- Fixed: Decals could spread to walls which had a decal-less texture or
were flagged not to have decals.
- Fixed: DBaseDecal/DImpactDecal::CloneSelf never checked the return value
from their StickToWall call and left unplaced decals behind if that happened.
- Reintroduced Doom.exe's player_t::usedown variable so that respawning a
player does not immediately activate switches. oldbuttons was not usable
for this. This also required that CopyPlayer preserves this info.
- Fixed: When restarting the music there was a NULL pointer check missing
so it crashed when the game was started wi
- Fixed: If the Use key is used to respawn the player it must be cleared
so that it doesn't trigger any subsequent actions after respawning.
- Fixed: Resurrecting a monster did not restore flags5 and flags6.
- Fixed: Projectiles which killed a non-monster were unable to determine
what precisely they hit because MF_CORPSE is only valid for monsters.
A new flag, MF6_KILLED that gets set for all objects that die, was added
for this case.
- Added a generic A_Weave function that exposes all possible options of
A_BishopMissileWeave and A_CStaffMissileSlither. These 2 functions are
no longer needed from DECORATE and therefore deprecated.
December 24, 2009
- The options menu no longer scales up so quickly, so it can fit wider text
onscreen. In addition, it now uses the whole height available to it. Also,
at lower resolutions, items on the compatibility options menu now cut off
the beginning of the option label rather than the option setting, making
this menu useable where previously it was not.
- Added a channel parameter to the sector overload of SN_StopSequence() so
it can be properly paired with calls to SN_StartSequence().
- Fixed: P_CheckPlayerSprites() ignored the MF4_NOSKIN flag. It now also sets
the X scale, so switching skins while morphed does not produce weird
stretching upon unmorphing.
- Fixed: Calling S_ChangeMusic() with the same song but a different looping
flag now restarts the song so that the new looping setting can be applied.
(This was easier than modifying every music handler to support modifying
loop changes on the fly, which seems like overkill.)
- Fixed: savepatchsize was declared incorrectly in d_dehacked.cpp:DoInclude().
- Changed AFastProjectile::Effect() so that it sets the spawned trail to face
same direction as the projectile.
December 24, 2009 (Changes by Graf Zahl)
- fixed: The UDMF blockfloaters flag was misnamed. Changed to match the spec.
December 23, 2009 (Changes by Graf Zahl)
- made the initial weave index for A_BishopMissileWeave and A_CStaffMissileSlither
a configurable actor property.
- added a menu item for snd_channels.
December 20, 2009 (Changes by Graf Zahl)
- Fixed: The Dehacked parser could read past the end of the file if the last
element was improperly defined.
December 19, 2009
- Extended MF3_SKYEXPLODE to apply to horizon walls as well.
December 19, 2009 (Changes by Graf Zahl)
- Fixed: It was not possible to set the ammo type of a weapon explicitly to
'none'.
December 18, 2009
- A_FreezeDeath() now removes fuzz effects.
- In mus2midi.cpp, added range checking to MUS_SYSEVENT and MUS_CTRLCHANGE,
and masking for note-off keys, note-on velocities, and program changes.
December 18, 2009 (Changes by Graf Zahl)
- added all known maps requiring inverted sprite sorting to compatibility.txt.
- added compatibility option to invert sprite sorting. Apparently Doom.exe

View file

@ -319,6 +319,7 @@ enum
MF6_LINEDONE = 0x00008000, // From MBF: Object has already run a line effect
MF6_NOTRIGGER = 0x00010000, // actor cannot trigger any line actions
MF6_SHATTERING = 0x00020000, // marks an ice corpse for forced shattering
MF6_KILLED = 0x00040000, // Something that was killed (but not necessarily a corpse)
// --- mobj.renderflags ---
@ -765,7 +766,6 @@ public:
DWORD flags6; // Shit! Where did all the flags go?
int special1; // Special info
int special2; // Special info
int weaveindex; // Separated from special2 because it's used by globally accessible functions.
int health;
BYTE movedir; // 0-7
SBYTE visdir;
@ -783,6 +783,8 @@ public:
TObjPtr<AActor> LastLookActor; // Actor last looked for (if TIDtoHate != 0)
fixed_t SpawnPoint[3]; // For nightmare respawn
WORD SpawnAngle;
BYTE WeaveIndexXY; // Separated from special2 because it's used by globally accessible functions.
BYTE WeaveIndexZ;
int skillrespawncount;
int TIDtoHate; // TID of things to hate (0 if none)
FNameNoInit Species; // For monster families

View file

@ -2205,8 +2205,8 @@ static int PatchStrings (int dummy)
static int DoInclude (int dummy)
{
char *data;
int savedversion, savepversion;
char *savepatchfile, *savepatchpt, *savepatchname, savepatchsize;
int savedversion, savepversion, savepatchsize;
char *savepatchfile, *savepatchpt, *savepatchname;
if (including)
{

View file

@ -276,6 +276,7 @@ public:
bool centering;
BYTE turnticks;
bool attackdown;
bool usedown;
DWORD oldbuttons;
int health; // only used between levels, mo->health
// is used during levels

View file

@ -1316,7 +1316,7 @@ void G_PlayerReborn (int player)
p->skill = b_skill; //Added by MC:
p->oldbuttons = ~0, p->attackdown = true; // don't do anything immediately
p->oldbuttons = ~0, p->attackdown = true; p->usedown = true; // don't do anything immediately
p->original_oldbuttons = ~0;
p->playerstate = PST_LIVE;

View file

@ -72,27 +72,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopAttack2)
DEFINE_ACTION_FUNCTION(AActor, A_BishopMissileWeave)
{
fixed_t newX, newY;
int weaveXY, weaveZ;
int angle;
// for compatibility this needs to set the value itself if it was never done by the projectile itself
if (self->weaveindex == -1) self->weaveindex = 16;
// since these values are now user configurable we have to do a proper range check to avoid array overflows.
weaveXY = (self->weaveindex >> 16) & 63;
weaveZ = (self->weaveindex & 63);
angle = (self->angle + ANG90) >> ANGLETOFINESHIFT;
newX = self->x - FixedMul (finecosine[angle], FloatBobOffsets[weaveXY]<<1);
newY = self->y - FixedMul (finesine[angle], FloatBobOffsets[weaveXY]<<1);
weaveXY = (weaveXY + 2) & 63;
newX += FixedMul (finecosine[angle], FloatBobOffsets[weaveXY]<<1);
newY += FixedMul (finesine[angle], FloatBobOffsets[weaveXY]<<1);
P_TryMove (self, newX, newY, true);
self->z -= FloatBobOffsets[weaveZ];
weaveZ = (weaveZ + 2) & 63;
self->z += FloatBobOffsets[weaveZ];
self->weaveindex = weaveZ + (weaveXY<<16);
A_Weave(self, 2, 2, 2*FRACUNIT, FRACUNIT);
}
//============================================================================

View file

@ -135,12 +135,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffAttack)
mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->angle-(ANG45/15));
if (mo)
{
mo->weaveindex = 32;
mo->WeaveIndexXY = 32;
}
mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->angle+(ANG45/15));
if (mo)
{
mo->weaveindex = 0;
mo->WeaveIndexXY = 0;
}
S_Sound (self, CHAN_WEAPON, "ClericCStaffFire", 1, ATTN_NORM);
}
@ -153,22 +153,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffAttack)
DEFINE_ACTION_FUNCTION(AActor, A_CStaffMissileSlither)
{
fixed_t newX, newY;
int weaveXY;
int angle;
if (self->weaveindex == -1) self->weaveindex = 0;
// since these values are now user configurable we have to do a proper range check to avoid array overflows.
weaveXY = self->weaveindex & 63;
angle = (self->angle+ANG90)>>ANGLETOFINESHIFT;
newX = self->x-FixedMul(finecosine[angle], FloatBobOffsets[weaveXY]);
newY = self->y-FixedMul(finesine[angle], FloatBobOffsets[weaveXY]);
weaveXY = (weaveXY+3)&63;
newX += FixedMul(finecosine[angle], FloatBobOffsets[weaveXY]);
newY += FixedMul(finesine[angle], FloatBobOffsets[weaveXY]);
P_TryMove (self, newX, newY, true);
self->weaveindex = weaveXY;
A_Weave(self, 3, 0, FRACUNIT, 0);
}
//============================================================================

View file

@ -348,6 +348,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BellReset2)
{
self->flags |= MF_SHOOTABLE;
self->flags &= ~MF_CORPSE;
self->flags6 &= ~MF6_KILLED;
self->health = 5;
}

View file

@ -298,6 +298,13 @@ FTextureID DBaseDecal::StickToWall (side_t *wall, fixed_t x, fixed_t y, F3DFloor
else return FNullTextureID();
CalcFracPos (wall, x, y);
FTexture *texture = TexMan[tex];
if (texture == NULL || texture->bNoDecals)
{
return FNullTextureID();
}
return tex;
}
@ -546,11 +553,18 @@ DBaseDecal *DBaseDecal::CloneSelf (const FDecalTemplate *tpl, fixed_t ix, fixed_
DBaseDecal *decal = new DBaseDecal(iz);
if (decal != NULL)
{
decal->StickToWall (wall, ix, iy, ffloor);
tpl->ApplyToDecal (decal, wall);
decal->AlphaColor = AlphaColor;
decal->RenderFlags = (decal->RenderFlags & RF_DECALMASK) |
(this->RenderFlags & ~RF_DECALMASK);
if (decal->StickToWall (wall, ix, iy, ffloor).isValid())
{
tpl->ApplyToDecal (decal, wall);
decal->AlphaColor = AlphaColor;
decal->RenderFlags = (decal->RenderFlags & RF_DECALMASK) |
(this->RenderFlags & ~RF_DECALMASK);
}
else
{
decal->Destroy();
return NULL;
}
}
return decal;
}
@ -652,16 +666,12 @@ DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, fixed_t x,
}
DImpactDecal::CheckMax();
decal = new DImpactDecal (z);
FTextureID stickypic = decal->StickToWall (wall, x, y, ffloor);
FTexture *tex = TexMan[stickypic];
if (tex != NULL && tex->bNoDecals)
if (decal == NULL)
{
return NULL;
}
if (decal == NULL)
if (!decal->StickToWall (wall, x, y, ffloor).isValid())
{
return NULL;
}
@ -685,15 +695,27 @@ DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, fixed_t x,
DBaseDecal *DImpactDecal::CloneSelf (const FDecalTemplate *tpl, fixed_t ix, fixed_t iy, fixed_t iz, side_t *wall, F3DFloor * ffloor) const
{
if (wall->Flags & WALLF_NOAUTODECALS)
{
return NULL;
}
DImpactDecal::CheckMax();
DImpactDecal *decal = new DImpactDecal(iz);
if (decal != NULL)
{
decal->StickToWall (wall, ix, iy, ffloor);
tpl->ApplyToDecal (decal, wall);
decal->AlphaColor = AlphaColor;
decal->RenderFlags = (decal->RenderFlags & RF_DECALMASK) |
(this->RenderFlags & ~RF_DECALMASK);
if (decal->StickToWall (wall, ix, iy, ffloor).isValid())
{
tpl->ApplyToDecal (decal, wall);
decal->AlphaColor = AlphaColor;
decal->RenderFlags = (decal->RenderFlags & RF_DECALMASK) |
(this->RenderFlags & ~RF_DECALMASK);
}
else
{
decal->Destroy();
return NULL;
}
}
return decal;
}

View file

@ -125,7 +125,14 @@ void AFastProjectile::Effect()
}
const PClass *trail = PClass::FindClass(name);
Spawn (trail, x, y, hitz, ALLOW_REPLACE);
if (trail != NULL)
{
AActor *act = Spawn (trail, x, y, hitz, ALLOW_REPLACE);
if (act != NULL)
{
act->angle = this->angle;
}
}
}
}
}

View file

@ -2120,6 +2120,26 @@ static void M_PlayerSetupTicker (void)
}
}
static void M_DrawPlayerSlider (int x, int y, int cur)
{
const int range = 255;
x = (x - 160) * CleanXfac + screen->GetWidth() / 2;
y = (y - 100) * CleanYfac + screen->GetHeight() / 2;
screen->DrawText (ConFont, CR_WHITE, x, y,
"\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12",
DTA_CellX, 8 * CleanXfac,
DTA_CellY, 8 * CleanYfac,
TAG_DONE);
screen->DrawText (ConFont, CR_ORANGE, x + (5 + (int)((cur * 78) / range)) * CleanXfac, y,
"\x13",
DTA_CellX, 8 * CleanXfac,
DTA_CellY, 8 * CleanYfac,
TAG_DONE);
}
static void M_PlayerSetupDrawer ()
{
int x, xo, yo;
@ -2251,9 +2271,9 @@ static void M_PlayerSetupDrawer ()
x = SmallFont->StringWidth ("Green") + 8 + PSetupDef.x;
color = players[consoleplayer].userinfo.color;
M_DrawSlider (x, PSetupDef.y + LINEHEIGHT*2+yo, 0.0f, 255.0f, float(RPART(color)), -1);
M_DrawSlider (x, PSetupDef.y + LINEHEIGHT*3+yo, 0.0f, 255.0f, float(GPART(color)), -1);
M_DrawSlider (x, PSetupDef.y + LINEHEIGHT*4+yo, 0.0f, 255.0f, float(BPART(color)), -1);
M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*2+yo, RPART(color));
M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*3+yo, GPART(color));
M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*4+yo, BPART(color));
// [GRB] Draw class setting
int pclass = players[consoleplayer].userinfo.PlayerClass;
@ -3443,7 +3463,13 @@ void M_Drawer ()
screen->DrawText(SmallFont, CR_UNTRANSLATED, 160, y + fontheight + 1, GStrings["TXT_NO"], DTA_Clean, true, TAG_DONE);
if (skullAnimCounter < 6)
{
M_DrawConText(CR_RED, 150, y + (fontheight + 1) * messageSelection, "\xd");
screen->DrawText(ConFont, CR_RED,
(150 - 160) * CleanXfac + screen->GetWidth() / 2,
(y + (fontheight + 1) * messageSelection - 100) * CleanYfac + screen->GetHeight() / 2,
"\xd",
DTA_CellX, 8 * CleanXfac,
DTA_CellY, 8 * CleanYfac,
TAG_DONE);
}
}
}

View file

@ -84,9 +84,6 @@ void M_DeactivateMenuInput ();
void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave);
// Draw a slider. Set fracdigits negative to not display the current value numerically.
void M_DrawSlider (int x, int y, double min, double max, double cur, int fracdigits=1);
//
// MENU TYPEDEFS
//

View file

@ -87,15 +87,17 @@
#include "m_menu.h"
extern FButtonStatus MenuButtons[NUM_MKEYS];
void StartGLMenu (void);
EXTERN_CVAR(Int, vid_renderer)
EXTERN_CVAR(Bool, nomonsterinterpolation)
EXTERN_CVAR(Int, showendoom)
EXTERN_CVAR(Bool, hud_althud)
EXTERN_CVAR(Int, compatmode)
EXTERN_CVAR (Bool, vid_vsync)
EXTERN_CVAR(Bool, displaynametags)
EXTERN_CVAR (Int, snd_channels)
void StartGLMenu (void);
EXTERN_CVAR(Int, vid_renderer)
static value_t Renderers[] = {
{ 0.0, "Software" },
{ 1.0, "OpenGL" },
@ -104,7 +106,6 @@ EXTERN_CVAR (Float, vid_brightness)
EXTERN_CVAR (Float, vid_contrast)
extern bool gl_disabled;
//
// defaulted values
//
@ -1266,6 +1267,7 @@ static menuitem_t SoundItems[] =
{ discrete, "Underwater reverb", {&snd_waterreverb}, {2.0}, {0.0}, {0.0}, {OnOff} },
{ slider, "Underwater cutoff", {&snd_waterlp}, {0.0}, {2000.0},{50.0}, {NULL} },
{ discrete, "Randomize pitches", {&snd_pitched}, {2.0}, {0.0}, {0.0}, {OnOff} },
{ slider, "Sound channels", {&snd_channels}, {8.0}, {256.0}, {8.0}, {NULL} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ more, "Restart sound", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)MakeSoundChanges} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
@ -1513,11 +1515,9 @@ void M_DrawConText (int color, int x, int y, const char *str)
{
int len = (int)strlen(str);
x = (x - 160) * CleanXfac + screen->GetWidth() / 2;
y = (y - 100) * CleanYfac + screen->GetHeight() / 2;
screen->DrawText (ConFont, color, x, y, str,
DTA_CellX, 8 * CleanXfac,
DTA_CellY, 8 * CleanYfac,
DTA_CellX, 8 * CleanXfac_1,
DTA_CellY, 8 * CleanYfac_1,
TAG_DONE);
}
@ -1577,7 +1577,8 @@ bool M_StartOptionsMenu (void)
return true;
}
void M_DrawSlider (int x, int y, double min, double max, double cur,int fracdigits)
// Draw a slider. Set fracdigits negative to not display the current value numerically.
static void M_DrawSlider (int x, int y, double min, double max, double cur,int fracdigits)
{
double range;
@ -1591,7 +1592,7 @@ void M_DrawSlider (int x, int y, double min, double max, double cur,int fracdigi
{
char textbuf[16];
mysnprintf(textbuf, countof(textbuf), "%.*f", fracdigits, cur);
screen->DrawText(SmallFont, CR_DARKGRAY, x + 12*8 + 4, y, textbuf, DTA_Clean, true, TAG_DONE);
screen->DrawText(SmallFont, CR_DARKGRAY, x + (12*8 + 4) * CleanXfac_1, y, textbuf, DTA_CleanNoMove_1, true, TAG_DONE);
}
}
@ -1662,6 +1663,7 @@ void M_OptDrawer ()
DWORD overlay;
int labelofs;
int indent;
int cursorspace;
if (!CurrentMenu->DontDim)
{
@ -1682,9 +1684,9 @@ void M_OptDrawer ()
if (BigFont && CurrentMenu->texttitle)
{
screen->DrawText (BigFont, gameinfo.gametype & GAME_DoomChex ? CR_RED : CR_UNTRANSLATED,
160-BigFont->StringWidth (CurrentMenu->texttitle)/2, 10,
CurrentMenu->texttitle, DTA_Clean, true, TAG_DONE);
y = 15 + BigFont->GetHeight ();
(screen->GetWidth() - BigFont->StringWidth(CurrentMenu->texttitle) * CleanXfac_1) / 2, 10*CleanYfac_1,
CurrentMenu->texttitle, DTA_CleanNoMove_1, true, TAG_DONE);
y = 15 + BigFont->GetHeight();
}
else
{
@ -1693,7 +1695,7 @@ void M_OptDrawer ()
}
if (gameinfo.gametype & GAME_Raven)
{
labelofs = 2;
labelofs = 2 * CleanXfac_1;
y -= 2;
fontheight = 9;
}
@ -1702,9 +1704,13 @@ void M_OptDrawer ()
labelofs = 0;
fontheight = 8;
}
ytop = y + CurrentMenu->scrolltop * 8;
cursorspace = 14 * CleanXfac_1;
y *= CleanYfac_1;
fontheight *= CleanYfac_1;
ytop = y + CurrentMenu->scrolltop * 8 * CleanYfac_1;
int lastrow = screen->GetHeight() - SmallFont->GetHeight() * CleanYfac_1;
for (i = 0; i < CurrentMenu->numitems && y <= 200 - SmallFont->GetHeight(); i++, y += fontheight)
for (i = 0; i < CurrentMenu->numitems && y <= lastrow; i++, y += fontheight)
{
if (i == CurrentMenu->scrolltop)
{
@ -1715,15 +1721,30 @@ void M_OptDrawer ()
overlay = 0;
if (item->type == discrete && item->c.discretecenter == 1)
{
indent = 160;
indent = screen->GetWidth() / 2;
}
else if (item->type == joymore)
{
indent = 4;
indent = 4 * CleanXfac_1;
}
else
{
indent = CurrentMenu->indent;
if (indent > 280)
{ // kludge for the compatibility options with their extremely long labels
if (indent + 40 <= CleanWidth_1)
{
indent = (screen->GetWidth() - ((indent + 40) * CleanXfac_1)) / 2 + indent * CleanXfac_1;
}
else
{
indent = screen->GetWidth() - 40 * CleanXfac_1;
}
}
else
{
indent = (indent - 160) * CleanXfac_1 + screen->GetWidth() / 2;
}
}
if (item->type != screenres)
@ -1746,7 +1767,7 @@ void M_OptDrawer ()
label = somestring;
}
}
width = SmallFont->StringWidth(label);
width = SmallFont->StringWidth(label) * CleanXfac_1;
switch (item->type)
{
case more:
@ -1756,34 +1777,34 @@ void M_OptDrawer ()
break;
case joymore:
x = 20;
x = 20 * CleanXfac_1;
color = MoreColor;
break;
case numberedmore:
case rsafemore:
case rightmore:
x = indent + 14;
x = indent + cursorspace;
color = item->type != rightmore ? CR_GREEN : MoreColor;
break;
case redtext:
x = 160 - width / 2;
x = screen->GetWidth() / 2 - width / 2;
color = LabelColor;
break;
case whitetext:
x = 160 - width / 2;
x = screen->GetWidth() / 2 - width / 2;
color = CR_GOLD;//ValueColor;
break;
case listelement:
x = indent + 14;
x = indent + cursorspace;
color = LabelColor;
break;
case colorpicker:
x = indent + 14;
x = indent + cursorspace;
color = MoreColor;
break;
@ -1800,7 +1821,7 @@ void M_OptDrawer ()
? CR_YELLOW : LabelColor;
break;
}
screen->DrawText (SmallFont, color, x, y, label, DTA_Clean, true, DTA_ColorOverlay, overlay, TAG_DONE);
screen->DrawText (SmallFont, color, x, y, label, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE);
switch (item->type)
{
@ -1810,8 +1831,8 @@ void M_OptDrawer ()
char tbuf[16];
mysnprintf (tbuf, countof(tbuf), "%d.", item->b.position);
x = indent - SmallFont->StringWidth (tbuf);
screen->DrawText (SmallFont, CR_GREY, x, y, tbuf, DTA_Clean, true, TAG_DONE);
x = indent - SmallFont->StringWidth (tbuf) * CleanXfac_1;
screen->DrawText (SmallFont, CR_GREY, x, y, tbuf, DTA_CleanNoMove_1, true, TAG_DONE);
}
break;
@ -1827,14 +1848,14 @@ void M_OptDrawer ()
if (v == vals)
{
screen->DrawText (SmallFont, ValueColor, indent + 14, y, "Unknown",
DTA_Clean, true, TAG_DONE);
screen->DrawText (SmallFont, ValueColor, indent + cursorspace, y, "Unknown",
DTA_CleanNoMove_1, true, TAG_DONE);
}
else
{
screen->DrawText (SmallFont, item->type == cdiscrete ? v : ValueColor,
indent + 14, y, item->e.values[v].name,
DTA_Clean, true, TAG_DONE);
indent + cursorspace, y, item->e.values[v].name,
DTA_CleanNoMove_1, true, TAG_DONE);
}
}
@ -1884,15 +1905,15 @@ void M_OptDrawer ()
if (v == vals)
{
screen->DrawText (SmallFont, ValueColor, indent + 14, y, "Unknown",
DTA_Clean, true, DTA_ColorOverlay, overlay, TAG_DONE);
screen->DrawText (SmallFont, ValueColor, indent + cursorspace, y, "Unknown",
DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE);
}
else
{
screen->DrawText (SmallFont, item->type == cdiscrete ? v : ValueColor,
indent + 14, y,
indent + cursorspace, y,
item->type != discretes ? item->e.values[v].name : item->e.valuestrings[v].name.GetChars(),
DTA_Clean, true, DTA_ColorOverlay, overlay, TAG_DONE);
DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE);
}
}
@ -1904,18 +1925,18 @@ void M_OptDrawer ()
value = item->a.cvar->GetGenericRep (CVAR_String);
v = M_FindCurVal(value.String, item->e.enumvalues, (int)item->b.numvalues);
screen->DrawText(SmallFont, ValueColor, indent + 14, y, v, DTA_Clean, true, TAG_DONE);
screen->DrawText(SmallFont, ValueColor, indent + cursorspace, y, v, DTA_CleanNoMove_1, true, TAG_DONE);
}
break;
case nochoice:
screen->DrawText (SmallFont, CR_GOLD, indent + 14, y,
(item->e.values[(int)item->b.min]).name, DTA_Clean, true, TAG_DONE);
screen->DrawText (SmallFont, CR_GOLD, indent + cursorspace, y,
(item->e.values[(int)item->b.min]).name, DTA_CleanNoMove_1, true, TAG_DONE);
break;
case joy_sens:
value.Float = SELECTED_JOYSTICK->GetSensitivity();
M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, value.Float, 1);
M_DrawSlider (indent + cursorspace, y + labelofs, item->b.min, item->c.max, value.Float, 1);
break;
case joy_slider:
@ -1928,29 +1949,29 @@ void M_OptDrawer ()
assert(item->e.joyslidernum == 1);
value.Float = SELECTED_JOYSTICK->GetAxisDeadZone(item->a.joyselection);
}
M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, fabs(value.Float), 3);
M_DrawSlider (indent + cursorspace, y + labelofs, item->b.min, item->c.max, fabs(value.Float), 3);
break;
case joy_inverter:
assert(item->e.joyslidernum == 0);
value.Float = SELECTED_JOYSTICK->GetAxisScale(item->a.joyselection);
screen->DrawText(SmallFont, ValueColor, indent + 14, y,
screen->DrawText(SmallFont, ValueColor, indent + cursorspace, y,
(value.Float < 0) ? "Yes" : "No",
DTA_Clean, true, TAG_DONE);
DTA_CleanNoMove_1, true, TAG_DONE);
break;
case slider:
value = item->a.cvar->GetGenericRep (CVAR_Float);
M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, value.Float, 1);
M_DrawSlider (indent + cursorspace, y + labelofs, item->b.min, item->c.max, value.Float, 1);
break;
case absslider:
value = item->a.cvar->GetGenericRep (CVAR_Float);
M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, fabs(value.Float), 1);
M_DrawSlider (indent + cursorspace, y + labelofs, item->b.min, item->c.max, fabs(value.Float), 1);
break;
case intslider:
M_DrawSlider (indent + 14, y + labelofs, item->b.min, item->c.max, item->a.fval, 0);
M_DrawSlider (indent + cursorspace, y + labelofs, item->b.min, item->c.max, item->a.fval, 0);
break;
case control:
@ -1960,12 +1981,12 @@ void M_OptDrawer ()
C_NameKeys (description, item->b.key1, item->c.key2);
if (description[0])
{
M_DrawConText(CR_WHITE, indent + 14, y-1+labelofs, description);
M_DrawConText(CR_WHITE, indent + cursorspace, y-1+labelofs, description);
}
else
{
screen->DrawText(SmallFont, CR_BLACK, indent + 14, y + labelofs, "---",
DTA_Clean, true, TAG_DONE);
screen->DrawText(SmallFont, CR_BLACK, indent + cursorspace, y + labelofs, "---",
DTA_CleanNoMove_1, true, TAG_DONE);
}
}
break;
@ -1973,9 +1994,9 @@ void M_OptDrawer ()
case colorpicker:
{
int box_x, box_y;
box_x = (indent - 35 - 160) * CleanXfac + screen->GetWidth()/2;
box_y = (y - ((gameinfo.gametype & GAME_Raven) ? 99 : 100)) * CleanYfac + screen->GetHeight()/2;
screen->Clear (box_x, box_y, box_x + 32*CleanXfac, box_y + (fontheight-1)*CleanYfac,
box_x = indent - 35 * CleanXfac_1;
box_y = (gameinfo.gametype & GAME_Raven) ? y - CleanYfac_1 : y;
screen->Clear (box_x, box_y, box_x + 32*CleanXfac_1, box_y + fontheight-CleanYfac_1,
item->a.colorcvar->GetIndex(), 0);
}
break;
@ -1984,12 +2005,12 @@ void M_OptDrawer ()
{
int box_x, box_y;
int x1, p;
const int w = fontheight*CleanXfac;
const int h = fontheight*CleanYfac;
const int w = fontheight;
const int h = fontheight;
box_y = (y - 98) * CleanYfac + screen->GetHeight()/2;
box_y = y - 2 * CleanYfac_1;
p = 0;
box_x = (indent - 32 - 160) * CleanXfac + screen->GetWidth()/2;
box_x = indent - 32 * CleanXfac_1;
for (x1 = 0, p = int(item->b.min * 16); x1 < 16; ++p, ++x1)
{
screen->Clear (box_x, box_y, box_x + w, box_y + h, p, 0);
@ -2044,7 +2065,7 @@ void M_OptDrawer ()
}
screen->DrawText (SmallFont, ValueColor,
indent + 14, y, str, DTA_Clean, true, TAG_DONE);
indent + cursorspace, y, str, DTA_CleanNoMove_1, true, TAG_DONE);
}
break;
@ -2056,12 +2077,13 @@ void M_OptDrawer ()
i == CurrentItem &&
(skullAnimCounter < 6 || menuactive == MENU_WaitKey))
{
M_DrawConText(CR_RED, indent + 3, y-1+labelofs, "\xd");
M_DrawConText(CR_RED, indent + 3 * CleanXfac_1, y-CleanYfac_1+labelofs, "\xd");
}
}
else
{
char *str = NULL;
int colwidth = screen->GetWidth() / 3;
for (x = 0; x < 3; x++)
{
@ -2078,13 +2100,13 @@ void M_OptDrawer ()
else
color = CR_BRICK; //LabelColor;
screen->DrawText (SmallFont, color, 104 * x + 20, y, str, DTA_Clean, true, TAG_DONE);
screen->DrawText (SmallFont, color, colwidth * x + 20 * CleanXfac_1, y, str, DTA_CleanNoMove_1, true, TAG_DONE);
}
}
if (i == CurrentItem && ((item->a.selmode != -1 && (skullAnimCounter < 6 || menuactive == MENU_WaitKey)) || testingmode))
{
M_DrawConText(CR_RED, item->a.selmode * 104 + 8, y-1 + labelofs, "\xd");
M_DrawConText(CR_RED, item->a.selmode * colwidth + 8 * CleanXfac_1, y - CleanYfac_1 + labelofs, "\xd");
}
}
}
@ -2095,11 +2117,11 @@ void M_OptDrawer ()
if (CanScrollUp)
{
M_DrawConText(CR_ORANGE, 3, ytop + labelofs, "\x1a");
M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, ytop + labelofs, "\x1a");
}
if (CanScrollDown)
{
M_DrawConText(CR_ORANGE, 3, y - 8 + labelofs, "\x1b");
M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, y - 8*CleanYfac_1 + labelofs, "\x1b");
}
if (flagsvar)
@ -2122,8 +2144,8 @@ void M_OptDrawer ()
}
}
screen->DrawText (SmallFont, ValueColor,
160 - (SmallFont->StringWidth (flagsblah) >> 1), 0, flagsblah,
DTA_Clean, true, TAG_DONE);
(screen->GetWidth() - SmallFont->StringWidth (flagsblah) * CleanXfac_1) / 2, 0, flagsblah,
DTA_CleanNoMove_1, true, TAG_DONE);
}
}
@ -2276,31 +2298,33 @@ void M_OptButtonHandler(EMenuKey key, bool repeat)
}
if (CurrentItem < 0)
{
int maxitems, rowheight;
int ytop, maxitems, rowheight;
// Figure out how many lines of text fit on the menu
if (CurrentMenu->y != 0)
{
maxitems = CurrentMenu->y;
ytop = CurrentMenu->y;
}
else if (BigFont && CurrentMenu->texttitle)
{
maxitems = 15 + BigFont->GetHeight ();
ytop = 15 + BigFont->GetHeight ();
}
else
{
maxitems = 15;
ytop = 15;
}
if (!(gameinfo.gametype & GAME_DoomChex))
{
maxitems -= 2;
ytop -= 2;
rowheight = 9;
}
else
{
rowheight = 8;
}
maxitems = (200 - SmallFont->GetHeight () - maxitems) / rowheight + 1;
ytop *= CleanYfac_1;
rowheight *= CleanYfac_1;
maxitems = (screen->GetHeight() - SmallFont->GetHeight() - ytop) / rowheight + 1;
CurrentMenu->scrollpos = MAX (0,CurrentMenu->numitems - maxitems + CurrentMenu->scrolltop);
CurrentItem = CurrentMenu->numitems - 1;
@ -3008,16 +3032,16 @@ static void ColorPickerDrawer ()
DWORD oldColor = DWORD(*ColorPickerItems[0].a.colorcvar) | 0xFF000000;
int x = screen->GetWidth()*2/3;
int y = (15 + BigFont->GetHeight() + SmallFont->GetHeight()*5 - 90) * CleanYfac + screen->GetHeight()/2;
int y = (15 + BigFont->GetHeight() + SmallFont->GetHeight()*5 - 10) * CleanYfac_1;
screen->Clear (x, y, x + 48*CleanXfac, y + 48*CleanYfac, -1, oldColor);
screen->Clear (x + 48*CleanXfac, y, x + 48*2*CleanXfac, y + 48*CleanYfac, -1, newColor);
screen->Clear (x, y, x + 48*CleanXfac_1, y + 48*CleanYfac_1, -1, oldColor);
screen->Clear (x + 48*CleanXfac_1, y, x + 48*2*CleanXfac_1, y + 48*CleanYfac_1, -1, newColor);
y += 49*CleanYfac;
screen->DrawText (SmallFont, CR_GRAY, x+(24-SmallFont->StringWidth("Old")/2)*CleanXfac, y,
"Old", DTA_CleanNoMove, true, TAG_DONE);
screen->DrawText (SmallFont, CR_WHITE, x+(48+24-SmallFont->StringWidth("New")/2)*CleanXfac, y,
"New", DTA_CleanNoMove, true, TAG_DONE);
y += 49*CleanYfac_1;
screen->DrawText (SmallFont, CR_GRAY, x+(24-SmallFont->StringWidth("Old")/2)*CleanXfac_1, y,
"Old", DTA_CleanNoMove_1, true, TAG_DONE);
screen->DrawText (SmallFont, CR_WHITE, x+(48+24-SmallFont->StringWidth("New")/2)*CleanXfac_1, y,
"New", DTA_CleanNoMove_1, true, TAG_DONE);
}
static void SetColorPickerSliders ()
@ -3118,11 +3142,12 @@ static void DrawJoystickConfigMenuHeader()
{
FString joyname = SELECTED_JOYSTICK->GetName();
screen->DrawText(BigFont, gameinfo.gametype & GAME_DoomChex ? CR_RED : CR_UNTRANSLATED,
160-BigFont->StringWidth(CurrentMenu->texttitle)/2, 5,
CurrentMenu->texttitle, DTA_Clean, true, TAG_DONE);
(screen->GetWidth() - BigFont->StringWidth(CurrentMenu->texttitle) * CleanXfac_1) / 2,
5 * CleanYfac_1,
CurrentMenu->texttitle, DTA_CleanNoMove_1, true, TAG_DONE);
screen->DrawText(SmallFont, gameinfo.gametype & GAME_DoomChex ? CR_RED : CR_UNTRANSLATED,
160-SmallFont->StringWidth(joyname)/2, 8 + BigFont->GetHeight(),
joyname, DTA_Clean, true, TAG_DONE);
(screen->GetWidth() - SmallFont->StringWidth(joyname) * CleanXfac_1) / 2, (8 + BigFont->GetHeight()) * CleanYfac_1,
joyname, DTA_CleanNoMove_1, true, TAG_DONE);
}
static void UpdateJoystickConfigMenu(IJoystickConfig *joy)

View file

@ -112,7 +112,7 @@ void DCeiling::Tick ()
m_Sector->SetTexture(sector_t::ceiling, m_Texture);
// fall through
default:
SN_StopSequence (m_Sector);
SN_StopSequence (m_Sector, CHAN_CEILING);
Destroy ();
break;
}
@ -145,7 +145,7 @@ void DCeiling::Tick ()
m_Sector->SetTexture(sector_t::ceiling, m_Texture);
// fall through
default:
SN_StopSequence (m_Sector);
SN_StopSequence (m_Sector, CHAN_CEILING);
Destroy ();
break;
}
@ -500,7 +500,7 @@ bool EV_CeilingCrushStop (int tag)
{
if (scan->m_Tag == tag && scan->m_Direction != 0)
{
SN_StopSequence (scan->m_Sector);
SN_StopSequence (scan->m_Sector, CHAN_CEILING);
scan->m_OldDirection = scan->m_Direction;
scan->m_Direction = 0; // in-stasis;
rtn = true;

View file

@ -133,7 +133,7 @@ void DDoor::Tick ()
if (res == pastdest)
{
SN_StopSequence (m_Sector);
SN_StopSequence (m_Sector, CHAN_CEILING);
switch (m_Type)
{
case doorRaise:
@ -179,7 +179,7 @@ void DDoor::Tick ()
if (res == pastdest)
{
SN_StopSequence (m_Sector);
SN_StopSequence (m_Sector, CHAN_CEILING);
switch (m_Type)
{
case doorRaise:

View file

@ -54,6 +54,7 @@ void P_NewChaseDir (AActor *actor);
AInventory *P_DropItem (AActor *source, const PClass *type, int special, int chance);
void P_TossItem (AActor *item);
bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params);
void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdist);
DECLARE_ACTION(A_Look)
DECLARE_ACTION(A_Wander)

View file

@ -126,7 +126,7 @@ void DFloor::Tick ()
if (res == pastdest)
{
SN_StopSequence (m_Sector);
SN_StopSequence (m_Sector, CHAN_FLOOR);
if (m_Type == buildStair)
m_Type = waitStair;
@ -530,7 +530,7 @@ bool EV_FloorCrushStop (int tag)
if (sec->floordata && sec->floordata->IsKindOf (RUNTIME_CLASS(DFloor)) &&
barrier_cast<DFloor *>(sec->floordata)->m_Type == DFloor::floorRaiseAndCrush)
{
SN_StopSequence (sec);
SN_StopSequence (sec, CHAN_FLOOR);
sec->floordata->Destroy ();
sec->floordata = NULL;
}
@ -959,7 +959,7 @@ void DElevator::Tick ()
if (res == pastdest) // if destination height acheived
{
// make floor stop sound
SN_StopSequence (m_Sector);
SN_StopSequence (m_Sector, CHAN_FLOOR);
m_Sector->floordata = NULL; //jff 2/22/98
m_Sector->ceilingdata = NULL; //jff 2/22/98

View file

@ -396,6 +396,8 @@ void AActor::Die (AActor *source, AActor *inflictor)
// be revived by an Arch-Vile. Batman Doom needs this.
flags |= MF_CORPSE;
}
flags6 |= MF6_KILLED;
// [RH] Allow the death height to be overridden using metadata.
fixed_t metaheight = 0;
if (DamageType == NAME_Fire)

View file

@ -312,13 +312,34 @@ void AActor::Serialize (FArchive &arc)
{
arc << DamageFactor;
}
if (SaveVersion >= 2036)
if (SaveVersion > 2036)
{
arc << weaveindex;
arc << WeaveIndexXY << WeaveIndexZ;
}
else
{
weaveindex = special2;
int index;
if (SaveVersion < 2036)
{
index = special2;
}
else
{
arc << index;
}
// A_BishopMissileWeave and A_CStaffMissileSlither stored the weaveXY
// value in different parts of the index.
if (this->IsKindOf(PClass::FindClass("BishopFX")))
{
WeaveIndexXY = index >> 16;
WeaveIndexZ = index;
}
else
{
WeaveIndexXY = index;
WeaveIndexZ = 0;
}
}
// Skip past uservar array in old savegames

View file

@ -98,7 +98,7 @@ void DPillar::Tick ()
if (r == pastdest && s == pastdest)
{
SN_StopSequence (m_Sector);
SN_StopSequence (m_Sector, CHAN_FLOOR);
Destroy ();
}
else

View file

@ -82,7 +82,7 @@ void DPlat::Tick ()
}
else if (res == pastdest)
{
SN_StopSequence (m_Sector);
SN_StopSequence (m_Sector, CHAN_FLOOR);
if (m_Type != platToggle)
{
m_Count = m_Wait;
@ -121,7 +121,7 @@ void DPlat::Tick ()
if (res == pastdest)
{
SN_StopSequence (m_Sector);
SN_StopSequence (m_Sector, CHAN_FLOOR);
// if not an instant toggle, start waiting
if (m_Type != platToggle) //jff 3/14/98 toggle up down
{ // is silent, instant, no waiting

View file

@ -244,6 +244,8 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name)
// needs to come from the save for bots.
userinfo_t uibackup = dst->userinfo;
int chasecam = dst->cheats & CF_CHASECAM; // Remember the chasecam setting
bool attackdown = dst->attackdown;
bool usedown = dst->usedown;
*dst = *src;
dst->cheats |= chasecam;
@ -270,6 +272,9 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name)
{
dst->mo->player = dst;
}
// These 2 variables may not be overwritten.
dst->attackdown = attackdown;
dst->usedown = usedown;
}
static void SpawnExtraPlayers ()

View file

@ -466,6 +466,8 @@ bool P_Thing_Raise(AActor *thing)
thing->flags2 = info->flags2;
thing->flags3 = info->flags3;
thing->flags4 = info->flags4;
thing->flags5 = info->flags5;
thing->flags6 = info->flags6;
thing->health = info->health;
thing->target = NULL;
thing->lastenemy = NULL;

View file

@ -222,6 +222,7 @@ player_t::player_t()
centering(0),
turnticks(0),
attackdown(0),
usedown(0),
oldbuttons(0),
health(0),
inventorytics(0),
@ -1399,10 +1400,12 @@ void P_CheckPlayerSprites()
{
int crouchspriteno;
fixed_t defscaleY = mo->GetDefault()->scaleY;
fixed_t defscaleX = mo->GetDefault()->scaleX;
if (player->userinfo.skin != 0)
if (player->userinfo.skin != 0 && !(player->mo->flags4 & MF4_NOSKIN))
{
defscaleY = skins[player->userinfo.skin].ScaleY;
defscaleX = skins[player->userinfo.skin].ScaleX;
}
// Set the crouch sprite
@ -1413,8 +1416,9 @@ void P_CheckPlayerSprites()
{
crouchspriteno = mo->crouchsprite;
}
else if (mo->sprite == skins[player->userinfo.skin].sprite ||
mo->sprite == skins[player->userinfo.skin].crouchsprite)
else if (!(player->mo->flags4 & MF4_NOSKIN) &&
(mo->sprite == skins[player->userinfo.skin].sprite ||
mo->sprite == skins[player->userinfo.skin].crouchsprite))
{
crouchspriteno = skins[player->userinfo.skin].crouchsprite;
}
@ -1446,6 +1450,7 @@ void P_CheckPlayerSprites()
}
mo->scaleY = defscaleY;
}
mo->scaleX = defscaleX;
}
}
}
@ -2283,10 +2288,15 @@ void P_PlayerThink (player_t *player)
}
}
// check for use
if ((cmd->ucmd.buttons & BT_USE) && !(player->oldbuttons & BT_USE))
if ((cmd->ucmd.buttons & BT_USE) && !player->usedown)
{
player->usedown = true;
P_UseLines (player);
}
else
{
player->usedown = false;
}
// Morph counter
if (player->morphTics)
{

View file

@ -849,7 +849,7 @@ DSeqNode *SN_StartSequence (sector_t *sector, int chan, int sequence, seqtype_t
{
if (!nostop)
{
SN_StopSequence (sector);
SN_StopSequence (sector, chan);
}
if (TwiddleSeqNum (sequence, type))
{
@ -963,9 +963,23 @@ void SN_StopSequence (AActor *actor)
SN_DoStop (actor);
}
void SN_StopSequence (sector_t *sector)
void SN_StopSequence (sector_t *sector, int chan)
{
SN_DoStop (sector);
DSeqNode *node;
for (node = DSeqNode::FirstSequence(); node; )
{
DSeqNode *next = node->NextSequence();
if (node->Source() == sector)
{
assert(node->IsKindOf(RUNTIME_CLASS(DSeqSectorNode)));
if ((static_cast<DSeqSectorNode *>(node)->Channel & 7) == chan)
{
node->StopAndDestroy ();
}
}
node = next;
}
}
void SN_StopSequence (FPolyObj *poly)

View file

@ -86,7 +86,7 @@ DSeqNode *SN_StartSequence (sector_t *sec, int chan, FName seqname, int modenum)
DSeqNode *SN_StartSequence (FPolyObj *poly, int sequence, seqtype_t type, int modenum, bool nostop=false);
DSeqNode *SN_StartSequence (FPolyObj *poly, const char *name, int modenum);
void SN_StopSequence (AActor *mobj);
void SN_StopSequence (sector_t *sector);
void SN_StopSequence (sector_t *sector, int chan);
void SN_StopSequence (FPolyObj *poly);
void SN_UpdateActiveSequences (void);
ptrdiff_t SN_GetSequenceOffset (int sequence, SDWORD *sequencePtr);

View file

@ -2306,7 +2306,10 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
}
}
if (!mus_playing.name.IsEmpty() && stricmp (mus_playing.name, musicname) == 0)
if (!mus_playing.name.IsEmpty() &&
mus_playing.handle != NULL &&
stricmp (mus_playing.name, musicname) == 0 &&
mus_playing.handle->m_Looping == looping)
{
if (order != mus_playing.baseorder)
{

View file

@ -3,5 +3,5 @@
// This file was automatically generated by the
// updaterevision tool. Do not edit by hand.
#define ZD_SVN_REVISION_STRING "2037"
#define ZD_SVN_REVISION_NUMBER 2037
#define ZD_SVN_REVISION_STRING "2047"
#define ZD_SVN_REVISION_NUMBER 2047

View file

@ -3019,6 +3019,58 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Quake)
P_StartQuake(self, 0, intensity, duration, damrad, tremrad, sound);
}
//===========================================================================
//
// A_Weave
//
//===========================================================================
void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdist)
{
fixed_t newX, newY;
int weaveXY, weaveZ;
int angle;
fixed_t dist;
weaveXY = self->WeaveIndexXY & 63;
weaveZ = self->WeaveIndexZ & 63;
angle = (self->angle + ANG90) >> ANGLETOFINESHIFT;
if (xydist != 0 && xyspeed != 0)
{
dist = FixedMul(FloatBobOffsets[weaveXY], xydist);
newX = self->x - FixedMul (finecosine[angle], dist);
newY = self->y - FixedMul (finesine[angle], dist);
weaveXY = (weaveXY + xyspeed) & 63;
dist = FixedMul(FloatBobOffsets[weaveXY], xydist);
newX += FixedMul (finecosine[angle], dist);
newY += FixedMul (finesine[angle], dist);
P_TryMove (self, newX, newY, true);
self->WeaveIndexXY = weaveXY;
}
if (zdist != 0 && zspeed != 0)
{
self->z -= FixedMul(FloatBobOffsets[weaveZ], zdist);
weaveZ = (weaveZ + zspeed) & 63;
self->z += FixedMul(FloatBobOffsets[weaveZ], zdist);
self->WeaveIndexZ = weaveZ;
}
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Weave)
{
ACTION_PARAM_START(4);
ACTION_PARAM_INT(xspeed, 0);
ACTION_PARAM_INT(yspeed, 1);
ACTION_PARAM_FIXED(xdist, 2);
ACTION_PARAM_FIXED(ydist, 3);
A_Weave(self, xspeed, yspeed, xdist, ydist);
}
//===========================================================================
//
// A_LineEffect

View file

@ -905,10 +905,19 @@ DEFINE_PROPERTY(bouncecount, I, Actor)
//==========================================================================
//
//==========================================================================
DEFINE_PROPERTY(weaveindex, I, Actor)
DEFINE_PROPERTY(weaveindexXY, I, Actor)
{
PROP_INT_PARM(id, 0);
defaults->weaveindex = id;
defaults->WeaveIndexXY = id;
}
//==========================================================================
//
//==========================================================================
DEFINE_PROPERTY(weaveindexZ, I, Actor)
{
PROP_INT_PARM(id, 0);
defaults->WeaveIndexZ = id;
}
//==========================================================================

View file

@ -59,6 +59,9 @@ int CleanXfac, CleanYfac;
// [RH] Effective screen sizes that the above scale values give you
int CleanWidth, CleanHeight;
// Above minus 1 (or 1, if they are already 1)
int CleanXfac_1, CleanYfac_1, CleanWidth_1, CleanHeight_1;
CVAR (Bool, hud_scale, false, CVAR_ARCHIVE);
// For routines that take RGB colors, cache the previous lookup in case there
@ -425,6 +428,15 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
}
break;
case DTA_CleanNoMove_1:
boolval = va_arg(tags, INTBOOL);
if (boolval)
{
parms->destwidth = parms->texwidth * CleanXfac_1;
parms->destheight = parms->texheight * CleanYfac_1;
}
break;
case DTA_320x200:
boolval = va_arg(tags, INTBOOL);
if (boolval)

View file

@ -156,13 +156,23 @@ void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, c
ptrval = va_arg (tags, void*);
break;
case DTA_CleanNoMove_1:
boolval = va_arg (tags, INTBOOL);
if (boolval)
{
scalex = CleanXfac_1;
scaley = CleanYfac_1;
maxwidth = Width - (Width % scalex);
}
break;
case DTA_CleanNoMove:
boolval = va_arg (tags, INTBOOL);
if (boolval)
{
scalex = CleanXfac;
scaley = CleanYfac;
maxwidth = Width - (Width % CleanYfac);
maxwidth = Width - (Width % scalex);
}
break;

View file

@ -1398,6 +1398,11 @@ bool V_DoModeSetup (int width, int height, int bits)
assert(CleanWidth >= 320);
assert(CleanHeight >= 200);
CleanXfac_1 = MAX(CleanXfac - 1, 1);
CleanYfac_1 = MAX(CleanYfac - 1, 1);
CleanWidth_1 = width / CleanXfac_1;
CleanHeight_1 = height / CleanYfac_1;
DisplayWidth = width;
DisplayHeight = height;
DisplayBits = bits;

View file

@ -42,6 +42,7 @@
#include "c_cvars.h"
extern int CleanWidth, CleanHeight, CleanXfac, CleanYfac;
extern int CleanWidth_1, CleanHeight_1, CleanXfac_1, CleanYfac_1;
extern int DisplayWidth, DisplayHeight, DisplayBits;
bool V_DoModeSetup (int width, int height, int bits);
@ -79,6 +80,7 @@ enum
DTA_320x200, // bool: scale texture size and position to fit on a virtual 320x200 screen
DTA_Bottom320x200, // bool: same as DTA_320x200 but centers virtual screen on bottom for 1280x1024 targets
DTA_CleanNoMove, // bool: like DTA_Clean but does not reposition output position
DTA_CleanNoMove_1, // bool: like DTA_CleanNoMove, but uses Clean[XY]fac_1 instead
DTA_FlipX, // bool: flip image horizontally //FIXME: Does not work with DTA_Window(Left|Right)
DTA_ShadowColor, // color of shadow
DTA_ShadowAlpha, // alpha of shadow

View file

@ -19,7 +19,8 @@ ACTOR Actor native //: Thinker
Gravity 1
DamageFactor 1.0
PushFactor 0.25
WeaveIndex -1
WeaveIndexXY 0
WeaveIndexZ 16
// Variables for the expression evaluator
// NOTE: fixed_t and angle_t are only used here to ensure proper conversion
@ -221,6 +222,7 @@ ACTOR Actor native //: Thinker
action native A_PlayerSkinCheck(state label);
action native A_BasicAttack(int meleedamage, sound meleesound, class<actor> missiletype, float missileheight);
action native 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);
action native A_Recoil(float xyvel);
action native A_JumpIfInTargetInventory(class<Inventory> itemtype, int amount, state label);