mirror of
https://github.com/ZDoom/gzdoom-last-svn.git
synced 2025-06-04 03:00:47 +00:00
* Updated to ZDoom r3360:
- Added ability to use a constant for the maximum comparator for health and armor drawbars. - Added support for loading named ACS scripts. You can't run them directly at the moment, but you can still use them for automatically executed script types (like open and enter). - Change the DACSThinker::RunningScripts array into a TMap so that it can catalog the new range of ACS scripts (up to 32767). - Removed snd_3dspread, because it totally does not do what I want. I was using it to preserve some of the stereoness of stereo sounds played in 3D. My testing was done only with stereo speakers, however, and I did not realize that it was moving the perceived physical location of the sound itself (because it sounded fine with my two speakers). So when 3D spread started working with mono sounds as well in FMOD 4.28, sound positioning was completely broken for everything when outputting to more than two speakers, because sounds were being spread across a 180 degree arc. Whoops! Stereo sounds are now completely mono when not played by you, the listener. - Added keys on the automap for Heretic in easy mode. - Fixed: Sound limiting applied even to sounds that were already playing on the same actor+channel. Since in this case, it's really just restarting the sound, it shouldn't limit it. (Since it's already playing, we know the limit wasn't exceeded when it started playing, so it shouldn't be exceeded if we restart it now.) - Fixed: C_DoKey() must disable all doublebind processing if it isn't passed any doublebindings. This is because the automap calls it with its own bindings, which effectively cancelled all doublebindings while the automap was open. - Fixed: CheckMobjBlocking() did not consider one-sided lines without the ML_BLOCKING flag to be blocking. - Fixed: Forgot to divide the length of the SVCT chunks in ACS objects by 4 to get the actual number of scripts to set VarCount for. - Fixed: DCanvas::DrawTextV needs to accept the entire tag list in one parameter. Otherwise, it can't pass it to DrawTexture with a simple TAG_MORE. (Not sure why I thought the initial tag needed to be separate, though it did catch one case where it wasn't provided.) git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1284 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
parent
e6e6f45a91
commit
d95f3ca348
15 changed files with 329 additions and 133 deletions
|
@ -308,6 +308,7 @@ struct islope_t
|
||||||
static TArray<mline_t> MapArrow;
|
static TArray<mline_t> MapArrow;
|
||||||
static TArray<mline_t> CheatMapArrow;
|
static TArray<mline_t> CheatMapArrow;
|
||||||
static TArray<mline_t> CheatKey;
|
static TArray<mline_t> CheatKey;
|
||||||
|
static TArray<mline_t> EasyKey;
|
||||||
|
|
||||||
#define R (MAPUNIT)
|
#define R (MAPUNIT)
|
||||||
// [RH] Avoid lots of warnings without compiler-specific #pragmas
|
// [RH] Avoid lots of warnings without compiler-specific #pragmas
|
||||||
|
@ -536,10 +537,12 @@ void AM_StaticInit()
|
||||||
MapArrow.Clear();
|
MapArrow.Clear();
|
||||||
CheatMapArrow.Clear();
|
CheatMapArrow.Clear();
|
||||||
CheatKey.Clear();
|
CheatKey.Clear();
|
||||||
|
EasyKey.Clear();
|
||||||
|
|
||||||
if (gameinfo.mMapArrow.IsNotEmpty()) AM_ParseArrow(MapArrow, gameinfo.mMapArrow);
|
if (gameinfo.mMapArrow.IsNotEmpty()) AM_ParseArrow(MapArrow, gameinfo.mMapArrow);
|
||||||
if (gameinfo.mCheatMapArrow.IsNotEmpty()) AM_ParseArrow(CheatMapArrow, gameinfo.mCheatMapArrow);
|
if (gameinfo.mCheatMapArrow.IsNotEmpty()) AM_ParseArrow(CheatMapArrow, gameinfo.mCheatMapArrow);
|
||||||
AM_ParseArrow(CheatKey, "maparrows/key.txt");
|
AM_ParseArrow(CheatKey, "maparrows/key.txt");
|
||||||
|
AM_ParseArrow(EasyKey, "maparrows/ravenkey.txt");
|
||||||
if (MapArrow.Size() == 0) I_FatalError("No automap arrow defined");
|
if (MapArrow.Size() == 0) I_FatalError("No automap arrow defined");
|
||||||
|
|
||||||
char namebuf[9];
|
char namebuf[9];
|
||||||
|
@ -2261,6 +2264,49 @@ void AM_drawPlayers ()
|
||||||
//
|
//
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
|
void AM_drawKeys ()
|
||||||
|
{
|
||||||
|
AMColor color;
|
||||||
|
mpoint_t p;
|
||||||
|
angle_t angle;
|
||||||
|
|
||||||
|
TThinkerIterator<AKey> it;
|
||||||
|
AKey *key;
|
||||||
|
|
||||||
|
while ((key = it.Next()) != NULL)
|
||||||
|
{
|
||||||
|
p.x = key->x >> FRACTOMAPBITS;
|
||||||
|
p.y = key->y >> FRACTOMAPBITS;
|
||||||
|
angle = key->angle;
|
||||||
|
|
||||||
|
if (am_rotate == 1 || (am_rotate == 2 && viewactive))
|
||||||
|
{
|
||||||
|
AM_rotatePoint (&p.x, &p.y);
|
||||||
|
angle += ANG90 - players[consoleplayer].camera->angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
color = ThingColor;
|
||||||
|
if (key->flags & MF_SPECIAL)
|
||||||
|
{
|
||||||
|
// Find the key's own color.
|
||||||
|
// Only works correctly if single-key locks have lower numbers than any-key locks.
|
||||||
|
// That is the case for all default keys, however.
|
||||||
|
int P_GetMapColorForKey (AInventory * key);
|
||||||
|
int c = P_GetMapColorForKey(key);
|
||||||
|
|
||||||
|
if (c >= 0) color.FromRGB(RPART(c), GPART(c), BPART(c));
|
||||||
|
else color = ThingColor_CountItem;
|
||||||
|
AM_drawLineCharacter(&EasyKey[0], EasyKey.Size(), 0, 0, color, p.x, p.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
void AM_drawThings ()
|
void AM_drawThings ()
|
||||||
{
|
{
|
||||||
AMColor color;
|
AMColor color;
|
||||||
|
@ -2299,7 +2345,12 @@ void AM_drawThings ()
|
||||||
// That is the case for all default keys, however.
|
// That is the case for all default keys, however.
|
||||||
if (t->IsKindOf(RUNTIME_CLASS(AKey)))
|
if (t->IsKindOf(RUNTIME_CLASS(AKey)))
|
||||||
{
|
{
|
||||||
if (am_showkeys)
|
if (G_SkillProperty(SKILLP_EasyKey))
|
||||||
|
{
|
||||||
|
// Already drawn by AM_drawKeys(), so don't draw again
|
||||||
|
color.Index = -1;
|
||||||
|
}
|
||||||
|
else if (am_showkeys)
|
||||||
{
|
{
|
||||||
int P_GetMapColorForKey (AInventory * key);
|
int P_GetMapColorForKey (AInventory * key);
|
||||||
int c = P_GetMapColorForKey(static_cast<AKey *>(t));
|
int c = P_GetMapColorForKey(static_cast<AKey *>(t));
|
||||||
|
@ -2521,6 +2572,8 @@ void AM_Drawer ()
|
||||||
|
|
||||||
AM_drawWalls(allmap);
|
AM_drawWalls(allmap);
|
||||||
AM_drawPlayers();
|
AM_drawPlayers();
|
||||||
|
if (G_SkillProperty(SKILLP_EasyKey))
|
||||||
|
AM_drawKeys();
|
||||||
if (am_cheat >= 2 || allthings)
|
if (am_cheat >= 2 || allthings)
|
||||||
AM_drawThings();
|
AM_drawThings();
|
||||||
|
|
||||||
|
|
|
@ -829,6 +829,7 @@ bool C_DoKey (event_t *ev, FKeyBindings *binds, FKeyBindings *doublebinds)
|
||||||
bool dclick;
|
bool dclick;
|
||||||
int dclickspot;
|
int dclickspot;
|
||||||
BYTE dclickmask;
|
BYTE dclickmask;
|
||||||
|
unsigned int nowtime;
|
||||||
|
|
||||||
if (ev->type != EV_KeyDown && ev->type != EV_KeyUp)
|
if (ev->type != EV_KeyDown && ev->type != EV_KeyUp)
|
||||||
return false;
|
return false;
|
||||||
|
@ -841,10 +842,11 @@ bool C_DoKey (event_t *ev, FKeyBindings *binds, FKeyBindings *doublebinds)
|
||||||
dclick = false;
|
dclick = false;
|
||||||
|
|
||||||
// This used level.time which didn't work outside a level.
|
// This used level.time which didn't work outside a level.
|
||||||
if (DClickTime[ev->data1] > I_MSTime() && ev->type == EV_KeyDown)
|
nowtime = I_MSTime();
|
||||||
|
if (doublebinds != NULL && DClickTime[ev->data1] > nowtime && ev->type == EV_KeyDown)
|
||||||
{
|
{
|
||||||
// Key pressed for a double click
|
// Key pressed for a double click
|
||||||
if (doublebinds != NULL) binding = doublebinds->GetBinding(ev->data1);
|
binding = doublebinds->GetBinding(ev->data1);
|
||||||
DClicked[dclickspot] |= dclickmask;
|
DClicked[dclickspot] |= dclickmask;
|
||||||
dclick = true;
|
dclick = true;
|
||||||
}
|
}
|
||||||
|
@ -853,11 +855,11 @@ bool C_DoKey (event_t *ev, FKeyBindings *binds, FKeyBindings *doublebinds)
|
||||||
if (ev->type == EV_KeyDown)
|
if (ev->type == EV_KeyDown)
|
||||||
{ // Key pressed for a normal press
|
{ // Key pressed for a normal press
|
||||||
binding = binds->GetBinding(ev->data1);
|
binding = binds->GetBinding(ev->data1);
|
||||||
DClickTime[ev->data1] = I_MSTime() + 571;
|
DClickTime[ev->data1] = nowtime + 571;
|
||||||
}
|
}
|
||||||
else if (DClicked[dclickspot] & dclickmask)
|
else if (doublebinds != NULL && DClicked[dclickspot] & dclickmask)
|
||||||
{ // Key released from a double click
|
{ // Key released from a double click
|
||||||
if (doublebinds != NULL) binding = doublebinds->GetBinding(ev->data1);
|
binding = doublebinds->GetBinding(ev->data1);
|
||||||
DClicked[dclickspot] &= ~dclickmask;
|
DClicked[dclickspot] &= ~dclickmask;
|
||||||
DClickTime[ev->data1] = 0;
|
DClickTime[ev->data1] = 0;
|
||||||
dclick = true;
|
dclick = true;
|
||||||
|
|
|
@ -545,7 +545,8 @@ enum ESkillProperty
|
||||||
SKILLP_MonsterHealth,
|
SKILLP_MonsterHealth,
|
||||||
SKILLP_FriendlyHealth,
|
SKILLP_FriendlyHealth,
|
||||||
SKILLP_NoPain,
|
SKILLP_NoPain,
|
||||||
SKILLP_ArmorFactor
|
SKILLP_ArmorFactor,
|
||||||
|
SKILLP_EasyKey,
|
||||||
};
|
};
|
||||||
int G_SkillProperty(ESkillProperty prop);
|
int G_SkillProperty(ESkillProperty prop);
|
||||||
const char * G_SkillName();
|
const char * G_SkillName();
|
||||||
|
@ -564,6 +565,7 @@ struct FSkillInfo
|
||||||
bool AutoUseHealth;
|
bool AutoUseHealth;
|
||||||
|
|
||||||
bool EasyBossBrain;
|
bool EasyBossBrain;
|
||||||
|
bool EasyKey;
|
||||||
int RespawnCounter;
|
int RespawnCounter;
|
||||||
int RespawnLimit;
|
int RespawnLimit;
|
||||||
fixed_t Aggressiveness;
|
fixed_t Aggressiveness;
|
||||||
|
|
|
@ -2235,8 +2235,8 @@ class CommandDrawBar : public SBarInfoCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CommandDrawBar(SBarInfo *script) : SBarInfoCommand(script),
|
CommandDrawBar(SBarInfo *script) : SBarInfoCommand(script),
|
||||||
border(0), horizontal(false), reverse(false), foreground(-1), background(-1),
|
border(0), horizontal(false), reverse(false), foreground(-1),
|
||||||
type(HEALTH), inventoryItem(NULL), interpolationSpeed(0), drawValue(0)
|
background(-1), type(HEALTH), interpolationSpeed(0), drawValue(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2297,28 +2297,12 @@ class CommandDrawBar : public SBarInfoCommand
|
||||||
if(sc.Compare("health"))
|
if(sc.Compare("health"))
|
||||||
{
|
{
|
||||||
type = HEALTH;
|
type = HEALTH;
|
||||||
if(sc.CheckToken(TK_Identifier)) //comparing reference
|
ParseComparator(sc);
|
||||||
{
|
|
||||||
inventoryItem = PClass::FindClass(sc.String);
|
|
||||||
if(inventoryItem == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(inventoryItem)) //must be a kind of inventory
|
|
||||||
{
|
|
||||||
sc.ScriptMessage("'%s' is not a type of inventory item.", sc.String);
|
|
||||||
inventoryItem = RUNTIME_CLASS(AInventory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if(sc.Compare("armor"))
|
else if(sc.Compare("armor"))
|
||||||
{
|
{
|
||||||
type = ARMOR;
|
type = ARMOR;
|
||||||
if(sc.CheckToken(TK_Identifier))
|
ParseComparator(sc);
|
||||||
{
|
|
||||||
inventoryItem = PClass::FindClass(sc.String);
|
|
||||||
if(inventoryItem == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(inventoryItem)) //must be a kind of inventory
|
|
||||||
{
|
|
||||||
sc.ScriptMessage("'%s' is not a type of inventory item.", sc.String);
|
|
||||||
inventoryItem = RUNTIME_CLASS(AInventory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if(sc.Compare("ammo1"))
|
else if(sc.Compare("ammo1"))
|
||||||
type = AMMO1;
|
type = AMMO1;
|
||||||
|
@ -2328,11 +2312,11 @@ class CommandDrawBar : public SBarInfoCommand
|
||||||
{
|
{
|
||||||
sc.MustGetToken(TK_Identifier);
|
sc.MustGetToken(TK_Identifier);
|
||||||
type = AMMO;
|
type = AMMO;
|
||||||
inventoryItem = PClass::FindClass(sc.String);
|
data.inventoryItem = PClass::FindClass(sc.String);
|
||||||
if(inventoryItem == NULL || !RUNTIME_CLASS(AAmmo)->IsAncestorOf(inventoryItem)) //must be a kind of ammo
|
if(data.inventoryItem == NULL || !RUNTIME_CLASS(AAmmo)->IsAncestorOf(data.inventoryItem)) //must be a kind of ammo
|
||||||
{
|
{
|
||||||
sc.ScriptMessage("'%s' is not a type of ammo.", sc.String);
|
sc.ScriptMessage("'%s' is not a type of ammo.", sc.String);
|
||||||
inventoryItem = RUNTIME_CLASS(AAmmo);
|
data.inventoryItem = RUNTIME_CLASS(AAmmo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(sc.Compare("frags"))
|
else if(sc.Compare("frags"))
|
||||||
|
@ -2351,21 +2335,21 @@ class CommandDrawBar : public SBarInfoCommand
|
||||||
{
|
{
|
||||||
type = POWERUPTIME;
|
type = POWERUPTIME;
|
||||||
sc.MustGetToken(TK_Identifier);
|
sc.MustGetToken(TK_Identifier);
|
||||||
inventoryItem = PClass::FindClass(sc.String);
|
data.inventoryItem = PClass::FindClass(sc.String);
|
||||||
if(inventoryItem == NULL || !RUNTIME_CLASS(APowerupGiver)->IsAncestorOf(inventoryItem))
|
if(data.inventoryItem == NULL || !RUNTIME_CLASS(APowerupGiver)->IsAncestorOf(data.inventoryItem))
|
||||||
{
|
{
|
||||||
sc.ScriptMessage("'%s' is not a type of PowerupGiver.", sc.String);
|
sc.ScriptMessage("'%s' is not a type of PowerupGiver.", sc.String);
|
||||||
inventoryItem = RUNTIME_CLASS(APowerupGiver);
|
data.inventoryItem = RUNTIME_CLASS(APowerupGiver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
type = INVENTORY;
|
type = INVENTORY;
|
||||||
inventoryItem = PClass::FindClass(sc.String);
|
data.inventoryItem = PClass::FindClass(sc.String);
|
||||||
if(inventoryItem == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(inventoryItem))
|
if(data.inventoryItem == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(data.inventoryItem))
|
||||||
{
|
{
|
||||||
sc.ScriptMessage("'%s' is not a type of inventory item.", sc.String);
|
sc.ScriptMessage("'%s' is not a type of inventory item.", sc.String);
|
||||||
inventoryItem = RUNTIME_CLASS(AInventory);
|
data.inventoryItem = RUNTIME_CLASS(AInventory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sc.MustGetToken(',');
|
sc.MustGetToken(',');
|
||||||
|
@ -2423,9 +2407,11 @@ class CommandDrawBar : public SBarInfoCommand
|
||||||
if(value < 0) //health shouldn't display negatives
|
if(value < 0) //health shouldn't display negatives
|
||||||
value = 0;
|
value = 0;
|
||||||
|
|
||||||
if(inventoryItem != NULL)
|
if(data.useMaximumConstant)
|
||||||
|
max = data.value;
|
||||||
|
else if(data.inventoryItem != NULL)
|
||||||
{
|
{
|
||||||
AInventory *item = statusBar->CPlayer->mo->FindInventory(inventoryItem); //max comparer
|
AInventory *item = statusBar->CPlayer->mo->FindInventory(data.inventoryItem); //max comparer
|
||||||
if(item != NULL)
|
if(item != NULL)
|
||||||
max = item->Amount;
|
max = item->Amount;
|
||||||
else
|
else
|
||||||
|
@ -2436,9 +2422,11 @@ class CommandDrawBar : public SBarInfoCommand
|
||||||
break;
|
break;
|
||||||
case ARMOR:
|
case ARMOR:
|
||||||
value = statusBar->armor != NULL ? statusBar->armor->Amount : 0;
|
value = statusBar->armor != NULL ? statusBar->armor->Amount : 0;
|
||||||
if(inventoryItem != NULL)
|
if(data.useMaximumConstant)
|
||||||
|
max = data.value;
|
||||||
|
else if(data.inventoryItem != NULL)
|
||||||
{
|
{
|
||||||
AInventory *item = statusBar->CPlayer->mo->FindInventory(inventoryItem);
|
AInventory *item = statusBar->CPlayer->mo->FindInventory(data.inventoryItem);
|
||||||
if(item != NULL)
|
if(item != NULL)
|
||||||
max = item->Amount;
|
max = item->Amount;
|
||||||
else
|
else
|
||||||
|
@ -2469,7 +2457,7 @@ class CommandDrawBar : public SBarInfoCommand
|
||||||
break;
|
break;
|
||||||
case AMMO:
|
case AMMO:
|
||||||
{
|
{
|
||||||
AInventory *item = statusBar->CPlayer->mo->FindInventory(inventoryItem);
|
AInventory *item = statusBar->CPlayer->mo->FindInventory(data.inventoryItem);
|
||||||
if(item != NULL)
|
if(item != NULL)
|
||||||
{
|
{
|
||||||
value = item->Amount;
|
value = item->Amount;
|
||||||
|
@ -2497,7 +2485,7 @@ class CommandDrawBar : public SBarInfoCommand
|
||||||
break;
|
break;
|
||||||
case INVENTORY:
|
case INVENTORY:
|
||||||
{
|
{
|
||||||
AInventory *item = statusBar->CPlayer->mo->FindInventory(inventoryItem);
|
AInventory *item = statusBar->CPlayer->mo->FindInventory(data.inventoryItem);
|
||||||
if(item != NULL)
|
if(item != NULL)
|
||||||
{
|
{
|
||||||
value = item->Amount;
|
value = item->Amount;
|
||||||
|
@ -2514,7 +2502,7 @@ class CommandDrawBar : public SBarInfoCommand
|
||||||
case POWERUPTIME:
|
case POWERUPTIME:
|
||||||
{
|
{
|
||||||
//Get the PowerupType and check to see if the player has any in inventory.
|
//Get the PowerupType and check to see if the player has any in inventory.
|
||||||
APowerupGiver *powerupGiver = (APowerupGiver*) GetDefaultByType(inventoryItem);
|
APowerupGiver *powerupGiver = (APowerupGiver*) GetDefaultByType(data.inventoryItem);
|
||||||
const PClass *powerupType = powerupGiver->PowerupType;
|
const PClass *powerupType = powerupGiver->PowerupType;
|
||||||
APowerup *powerup = (APowerup*) statusBar->CPlayer->mo->FindInventory(powerupType);
|
APowerup *powerup = (APowerup*) statusBar->CPlayer->mo->FindInventory(powerupType);
|
||||||
if(powerup != NULL && powerupType != NULL && powerupGiver != NULL)
|
if(powerup != NULL && powerupType != NULL && powerupGiver != NULL)
|
||||||
|
@ -2566,6 +2554,29 @@ class CommandDrawBar : public SBarInfoCommand
|
||||||
drawValue = value;
|
drawValue = value;
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
|
void ParseComparator(FScanner &sc)
|
||||||
|
{
|
||||||
|
bool extendedSyntax = sc.CheckToken('(');
|
||||||
|
|
||||||
|
if(sc.CheckToken(TK_Identifier)) //comparing reference
|
||||||
|
{
|
||||||
|
data.inventoryItem = PClass::FindClass(sc.String);
|
||||||
|
if(data.inventoryItem == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(data.inventoryItem)) //must be a kind of inventory
|
||||||
|
{
|
||||||
|
sc.ScriptMessage("'%s' is not a type of inventory item.", sc.String);
|
||||||
|
data.inventoryItem = RUNTIME_CLASS(AInventory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(extendedSyntax && sc.CheckToken(TK_IntConst))
|
||||||
|
{
|
||||||
|
data.useMaximumConstant = true;
|
||||||
|
data.value = sc.Number;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(extendedSyntax)
|
||||||
|
sc.MustGetToken(')');
|
||||||
|
}
|
||||||
|
|
||||||
enum ValueType
|
enum ValueType
|
||||||
{
|
{
|
||||||
HEALTH,
|
HEALTH,
|
||||||
|
@ -2584,13 +2595,28 @@ class CommandDrawBar : public SBarInfoCommand
|
||||||
SAVEPERCENT
|
SAVEPERCENT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AdditionalData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AdditionalData() : useMaximumConstant(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool useMaximumConstant;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
const PClass *inventoryItem;
|
||||||
|
int value;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
unsigned int border;
|
unsigned int border;
|
||||||
bool horizontal;
|
bool horizontal;
|
||||||
bool reverse;
|
bool reverse;
|
||||||
int foreground;
|
int foreground;
|
||||||
int background;
|
int background;
|
||||||
ValueType type;
|
ValueType type;
|
||||||
const PClass *inventoryItem;
|
AdditionalData data;
|
||||||
SBarInfoCoordinate x;
|
SBarInfoCoordinate x;
|
||||||
SBarInfoCoordinate y;
|
SBarInfoCoordinate y;
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ void FMapInfoParser::ParseSkill ()
|
||||||
skill.FastMonsters = false;
|
skill.FastMonsters = false;
|
||||||
skill.DisableCheats = false;
|
skill.DisableCheats = false;
|
||||||
skill.EasyBossBrain = false;
|
skill.EasyBossBrain = false;
|
||||||
|
skill.EasyKey = false;
|
||||||
skill.AutoUseHealth = false;
|
skill.AutoUseHealth = false;
|
||||||
skill.RespawnCounter = 0;
|
skill.RespawnCounter = 0;
|
||||||
skill.RespawnLimit = 0;
|
skill.RespawnLimit = 0;
|
||||||
|
@ -125,6 +126,10 @@ void FMapInfoParser::ParseSkill ()
|
||||||
{
|
{
|
||||||
skill.EasyBossBrain = true;
|
skill.EasyBossBrain = true;
|
||||||
}
|
}
|
||||||
|
else if (sc.Compare ("easykey"))
|
||||||
|
{
|
||||||
|
skill.EasyKey = true;
|
||||||
|
}
|
||||||
else if (sc.Compare("autousehealth"))
|
else if (sc.Compare("autousehealth"))
|
||||||
{
|
{
|
||||||
skill.AutoUseHealth = true;
|
skill.AutoUseHealth = true;
|
||||||
|
@ -351,6 +356,9 @@ int G_SkillProperty(ESkillProperty prop)
|
||||||
case SKILLP_EasyBossBrain:
|
case SKILLP_EasyBossBrain:
|
||||||
return AllSkills[gameskill].EasyBossBrain;
|
return AllSkills[gameskill].EasyBossBrain;
|
||||||
|
|
||||||
|
case SKILLP_EasyKey:
|
||||||
|
return AllSkills[gameskill].EasyKey;
|
||||||
|
|
||||||
case SKILLP_SpawnFilter:
|
case SKILLP_SpawnFilter:
|
||||||
return AllSkills[gameskill].SpawnFilter;
|
return AllSkills[gameskill].SpawnFilter;
|
||||||
|
|
||||||
|
@ -428,6 +436,7 @@ FSkillInfo &FSkillInfo::operator=(const FSkillInfo &other)
|
||||||
DisableCheats = other.DisableCheats;
|
DisableCheats = other.DisableCheats;
|
||||||
AutoUseHealth = other.AutoUseHealth;
|
AutoUseHealth = other.AutoUseHealth;
|
||||||
EasyBossBrain = other.EasyBossBrain;
|
EasyBossBrain = other.EasyBossBrain;
|
||||||
|
EasyKey = other.EasyKey;
|
||||||
RespawnCounter= other.RespawnCounter;
|
RespawnCounter= other.RespawnCounter;
|
||||||
RespawnLimit= other.RespawnLimit;
|
RespawnLimit= other.RespawnLimit;
|
||||||
Aggressiveness= other.Aggressiveness;
|
Aggressiveness= other.Aggressiveness;
|
||||||
|
|
133
src/p_acs.cpp
133
src/p_acs.cpp
|
@ -1529,11 +1529,11 @@ void FBehavior::LoadScriptsDirectory ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load script var counts
|
// Load script var counts. (Only recorded for scripts that use more than LOCAL_SIZE variables.)
|
||||||
scripts.b = FindChunk (MAKE_ID('S','V','C','T'));
|
scripts.b = FindChunk (MAKE_ID('S','V','C','T'));
|
||||||
if (scripts.dw != NULL)
|
if (scripts.dw != NULL)
|
||||||
{
|
{
|
||||||
max = scripts.dw[1];
|
max = scripts.dw[1] / 4;
|
||||||
scripts.dw += 2;
|
scripts.dw += 2;
|
||||||
for (i = max; i > 0; --i, scripts.w += 2)
|
for (i = max; i > 0; --i, scripts.w += 2)
|
||||||
{
|
{
|
||||||
|
@ -1544,6 +1544,27 @@ void FBehavior::LoadScriptsDirectory ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load script names (if any)
|
||||||
|
scripts.b = FindChunk(MAKE_ID('S','N','A','M'));
|
||||||
|
if (scripts.dw != NULL)
|
||||||
|
{
|
||||||
|
for (i = 0; i < NumScripts; ++i)
|
||||||
|
{
|
||||||
|
// ACC stores script names as an index into the SNAM chunk, with the first index as
|
||||||
|
// -1 and counting down from there. We convert this from an index into SNAM into
|
||||||
|
// a negative index into the global name table.
|
||||||
|
if (Scripts[i].Number < 0)
|
||||||
|
{
|
||||||
|
const char *str = (const char *)(scripts.b + 8 + scripts.dw[3 + (-Scripts[i].Number - 1)]);
|
||||||
|
FName name(str);
|
||||||
|
Scripts[i].Number = -name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// We need to resort scripts, because the new numbers for named scripts likely
|
||||||
|
// do not match the order they were originally in.
|
||||||
|
qsort (Scripts, NumScripts, sizeof(ScriptPtr), SortScripts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int STACK_ARGS FBehavior::SortScripts (const void *a, const void *b)
|
int STACK_ARGS FBehavior::SortScripts (const void *a, const void *b)
|
||||||
|
@ -1621,8 +1642,8 @@ bool FBehavior::IsGood ()
|
||||||
|
|
||||||
const ScriptPtr *FBehavior::FindScript (int script) const
|
const ScriptPtr *FBehavior::FindScript (int script) const
|
||||||
{
|
{
|
||||||
const ScriptPtr *ptr = BinarySearch<ScriptPtr, WORD>
|
const ScriptPtr *ptr = BinarySearch<ScriptPtr, int>
|
||||||
((ScriptPtr *)Scripts, NumScripts, &ScriptPtr::Number, (WORD)script);
|
((ScriptPtr *)Scripts, NumScripts, &ScriptPtr::Number, script);
|
||||||
|
|
||||||
// If the preceding script has the same number, return it instead.
|
// If the preceding script has the same number, return it instead.
|
||||||
// See the note by the script sorting above for why.
|
// See the note by the script sorting above for why.
|
||||||
|
@ -1859,6 +1880,50 @@ void FBehavior::StaticStopMyScripts (AActor *actor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// SerializeScriptNumber
|
||||||
|
//
|
||||||
|
// Serializes a script number. If it's negative, it's really a name, so
|
||||||
|
// that will get serialized after it.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static void SerializeScriptNumber(FArchive &arc, int &scriptnum, bool was2byte)
|
||||||
|
{
|
||||||
|
if (SaveVersion < 3359)
|
||||||
|
{
|
||||||
|
if (was2byte)
|
||||||
|
{
|
||||||
|
WORD oldver;
|
||||||
|
arc << oldver;
|
||||||
|
scriptnum = oldver;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arc << scriptnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arc << scriptnum;
|
||||||
|
// If the script number is negative, then it's really a name.
|
||||||
|
// So read/store the name after it.
|
||||||
|
if (scriptnum < 0)
|
||||||
|
{
|
||||||
|
if (arc.IsStoring())
|
||||||
|
{
|
||||||
|
arc.WriteName(FName(ENamedName(-scriptnum)).GetChars());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char *nam = arc.ReadName();
|
||||||
|
scriptnum = -FName(nam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//---- The ACS Interpreter ----//
|
//---- The ACS Interpreter ----//
|
||||||
|
|
||||||
IMPLEMENT_POINTY_CLASS (DACSThinker)
|
IMPLEMENT_POINTY_CLASS (DACSThinker)
|
||||||
|
@ -1880,8 +1945,7 @@ DACSThinker::DACSThinker ()
|
||||||
ActiveThinker = this;
|
ActiveThinker = this;
|
||||||
Scripts = NULL;
|
Scripts = NULL;
|
||||||
LastScript = NULL;
|
LastScript = NULL;
|
||||||
for (int i = 0; i < 1000; i++)
|
RunningScripts.Clear();
|
||||||
RunningScripts[i] = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1893,27 +1957,34 @@ DACSThinker::~DACSThinker ()
|
||||||
|
|
||||||
void DACSThinker::Serialize (FArchive &arc)
|
void DACSThinker::Serialize (FArchive &arc)
|
||||||
{
|
{
|
||||||
|
int scriptnum;
|
||||||
|
|
||||||
Super::Serialize (arc);
|
Super::Serialize (arc);
|
||||||
arc << Scripts << LastScript;
|
arc << Scripts << LastScript;
|
||||||
if (arc.IsStoring ())
|
if (arc.IsStoring ())
|
||||||
{
|
{
|
||||||
WORD i;
|
ScriptMap::Iterator it(RunningScripts);
|
||||||
for (i = 0; i < 1000; i++)
|
ScriptMap::Pair *pair;
|
||||||
|
|
||||||
|
while (it.NextPair(pair))
|
||||||
{
|
{
|
||||||
if (RunningScripts[i])
|
assert(pair->Value != NULL);
|
||||||
arc << RunningScripts[i] << i;
|
arc << pair->Value;
|
||||||
|
scriptnum = pair->Key;
|
||||||
|
SerializeScriptNumber(arc, scriptnum, true);
|
||||||
}
|
}
|
||||||
DLevelScript *nilptr = NULL;
|
DLevelScript *nilptr = NULL;
|
||||||
arc << nilptr;
|
arc << nilptr;
|
||||||
}
|
}
|
||||||
else
|
else // Loading
|
||||||
{
|
{
|
||||||
WORD scriptnum;
|
|
||||||
DLevelScript *script = NULL;
|
DLevelScript *script = NULL;
|
||||||
|
RunningScripts.Clear();
|
||||||
|
|
||||||
arc << script;
|
arc << script;
|
||||||
while (script)
|
while (script)
|
||||||
{
|
{
|
||||||
arc << scriptnum;
|
SerializeScriptNumber(arc, scriptnum, true);
|
||||||
RunningScripts[scriptnum] = script;
|
RunningScripts[scriptnum] = script;
|
||||||
arc << script;
|
arc << script;
|
||||||
}
|
}
|
||||||
|
@ -1975,8 +2046,9 @@ void DLevelScript::Serialize (FArchive &arc)
|
||||||
DWORD i;
|
DWORD i;
|
||||||
|
|
||||||
Super::Serialize (arc);
|
Super::Serialize (arc);
|
||||||
arc << next << prev
|
arc << next << prev;
|
||||||
<< script;
|
|
||||||
|
SerializeScriptNumber(arc, script, false);
|
||||||
|
|
||||||
arc << state
|
arc << state
|
||||||
<< statedata
|
<< statedata
|
||||||
|
@ -3713,13 +3785,13 @@ int DLevelScript::RunScript ()
|
||||||
|
|
||||||
case SCRIPT_ScriptWaitPre:
|
case SCRIPT_ScriptWaitPre:
|
||||||
// Wait for a script to start running, then enter state scriptwait
|
// Wait for a script to start running, then enter state scriptwait
|
||||||
if (controller->RunningScripts[statedata])
|
if (controller->RunningScripts.CheckKey(statedata) != NULL)
|
||||||
state = SCRIPT_ScriptWait;
|
state = SCRIPT_ScriptWait;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCRIPT_ScriptWait:
|
case SCRIPT_ScriptWait:
|
||||||
// Wait for a script to stop running, then enter state running
|
// Wait for a script to stop running, then enter state running
|
||||||
if (controller->RunningScripts[statedata])
|
if (controller->RunningScripts.CheckKey(statedata) != NULL)
|
||||||
return resultValue;
|
return resultValue;
|
||||||
|
|
||||||
state = SCRIPT_Running;
|
state = SCRIPT_Running;
|
||||||
|
@ -5016,7 +5088,7 @@ int DLevelScript::RunScript ()
|
||||||
|
|
||||||
case PCD_SCRIPTWAIT:
|
case PCD_SCRIPTWAIT:
|
||||||
statedata = STACK(1);
|
statedata = STACK(1);
|
||||||
if (controller->RunningScripts[statedata])
|
if (controller->RunningScripts.CheckKey(statedata) != NULL)
|
||||||
state = SCRIPT_ScriptWait;
|
state = SCRIPT_ScriptWait;
|
||||||
else
|
else
|
||||||
state = SCRIPT_ScriptWaitPre;
|
state = SCRIPT_ScriptWaitPre;
|
||||||
|
@ -6960,8 +7032,12 @@ int DLevelScript::RunScript ()
|
||||||
if (state == SCRIPT_PleaseRemove)
|
if (state == SCRIPT_PleaseRemove)
|
||||||
{
|
{
|
||||||
Unlink ();
|
Unlink ();
|
||||||
if (controller->RunningScripts[script] == this)
|
DLevelScript **running;
|
||||||
controller->RunningScripts[script] = NULL;
|
if ((running = controller->RunningScripts.CheckKey(script)) != NULL &&
|
||||||
|
*running == this)
|
||||||
|
{
|
||||||
|
controller->RunningScripts.Remove(script);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -6977,13 +7053,14 @@ static DLevelScript *P_GetScriptGoing (AActor *who, line_t *where, int num, cons
|
||||||
bool backSide, int arg0, int arg1, int arg2, int always)
|
bool backSide, int arg0, int arg1, int arg2, int always)
|
||||||
{
|
{
|
||||||
DACSThinker *controller = DACSThinker::ActiveThinker;
|
DACSThinker *controller = DACSThinker::ActiveThinker;
|
||||||
|
DLevelScript **running;
|
||||||
|
|
||||||
if (controller && !always && controller->RunningScripts[num])
|
if (controller && !always && (running = controller->RunningScripts.CheckKey(num)) != NULL)
|
||||||
{
|
{
|
||||||
if (controller->RunningScripts[num]->GetState () == DLevelScript::SCRIPT_Suspended)
|
if ((*running)->GetState() == DLevelScript::SCRIPT_Suspended)
|
||||||
{
|
{
|
||||||
controller->RunningScripts[num]->SetState (DLevelScript::SCRIPT_Running);
|
(*running)->SetState(DLevelScript::SCRIPT_Running);
|
||||||
return controller->RunningScripts[num];
|
return *running;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -6999,6 +7076,7 @@ DLevelScript::DLevelScript (AActor *who, line_t *where, int num, const ScriptPtr
|
||||||
new DACSThinker;
|
new DACSThinker;
|
||||||
|
|
||||||
script = num;
|
script = num;
|
||||||
|
assert(code->VarCount >= code->ArgCount);
|
||||||
numlocalvars = code->VarCount;
|
numlocalvars = code->VarCount;
|
||||||
localvars = new SDWORD[code->VarCount];
|
localvars = new SDWORD[code->VarCount];
|
||||||
if (code->VarCount > 0)
|
if (code->VarCount > 0)
|
||||||
|
@ -7043,9 +7121,12 @@ DLevelScript::DLevelScript (AActor *who, line_t *where, int num, const ScriptPtr
|
||||||
static void SetScriptState (int script, DLevelScript::EScriptState state)
|
static void SetScriptState (int script, DLevelScript::EScriptState state)
|
||||||
{
|
{
|
||||||
DACSThinker *controller = DACSThinker::ActiveThinker;
|
DACSThinker *controller = DACSThinker::ActiveThinker;
|
||||||
|
DLevelScript **running;
|
||||||
|
|
||||||
if (controller != NULL && controller->RunningScripts[script])
|
if (controller != NULL && (running = controller->RunningScripts.CheckKey(script)) != NULL)
|
||||||
controller->RunningScripts[script]->SetState (state);
|
{
|
||||||
|
(*running)->SetState (state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void P_DoDeferedScripts ()
|
void P_DoDeferedScripts ()
|
||||||
|
|
|
@ -76,18 +76,18 @@ void P_ClearACSVars(bool);
|
||||||
// The in-memory version
|
// The in-memory version
|
||||||
struct ScriptPtr
|
struct ScriptPtr
|
||||||
{
|
{
|
||||||
WORD Number;
|
int Number;
|
||||||
|
DWORD Address;
|
||||||
BYTE Type;
|
BYTE Type;
|
||||||
BYTE ArgCount;
|
BYTE ArgCount;
|
||||||
WORD VarCount;
|
WORD VarCount;
|
||||||
WORD Flags;
|
WORD Flags;
|
||||||
DWORD Address;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// The present ZDoom version
|
// The present ZDoom version
|
||||||
struct ScriptPtr3
|
struct ScriptPtr3
|
||||||
{
|
{
|
||||||
WORD Number;
|
SWORD Number;
|
||||||
BYTE Type;
|
BYTE Type;
|
||||||
BYTE ArgCount;
|
BYTE ArgCount;
|
||||||
DWORD Address;
|
DWORD Address;
|
||||||
|
@ -747,7 +747,8 @@ public:
|
||||||
void Serialize (FArchive &arc);
|
void Serialize (FArchive &arc);
|
||||||
void Tick ();
|
void Tick ();
|
||||||
|
|
||||||
DLevelScript *RunningScripts[1000]; // Array of all synchronous scripts
|
typedef TMap<int, DLevelScript *> ScriptMap;
|
||||||
|
ScriptMap RunningScripts; // Array of all synchronous scripts
|
||||||
static TObjPtr<DACSThinker> ActiveThinker;
|
static TObjPtr<DACSThinker> ActiveThinker;
|
||||||
|
|
||||||
void DumpScriptStatus();
|
void DumpScriptStatus();
|
||||||
|
|
|
@ -1295,7 +1295,8 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd)
|
||||||
fixed_t top = -INT_MAX, bottom = INT_MAX;
|
fixed_t top = -INT_MAX, bottom = INT_MAX;
|
||||||
bool above;
|
bool above;
|
||||||
// [TN] Check wether this actor gets blocked by the line.
|
// [TN] Check wether this actor gets blocked by the line.
|
||||||
if(!(ld->flags & (ML_BLOCKING|ML_BLOCKEVERYTHING))
|
if (ld->backsector != NULL &&
|
||||||
|
!(ld->flags & (ML_BLOCKING|ML_BLOCKEVERYTHING))
|
||||||
&& !(ld->flags & ML_BLOCK_PLAYERS && mobj->player)
|
&& !(ld->flags & ML_BLOCK_PLAYERS && mobj->player)
|
||||||
&& !(ld->flags & ML_BLOCKMONSTERS && mobj->flags3 & MF3_ISMONSTER)
|
&& !(ld->flags & ML_BLOCKMONSTERS && mobj->flags3 & MF3_ISMONSTER)
|
||||||
&& !((mobj->flags & MF_FLOAT) && (ld->flags & ML_BLOCK_FLOATERS))
|
&& !((mobj->flags & MF_FLOAT) && (ld->flags & ML_BLOCK_FLOATERS))
|
||||||
|
|
|
@ -101,7 +101,7 @@ extern float S_GetMusicVolume (const char *music);
|
||||||
|
|
||||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||||
|
|
||||||
static bool S_CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_limit, float limit_range);
|
static bool S_CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_limit, float limit_range, AActor *actor, int channel);
|
||||||
static bool S_IsChannelUsed(AActor *actor, int channel, int *seen);
|
static bool S_IsChannelUsed(AActor *actor, int channel, int *seen);
|
||||||
static void S_ActivatePlayList(bool goBack);
|
static void S_ActivatePlayList(bool goBack);
|
||||||
static void CalcPosVel(FSoundChan *chan, FVector3 *pos, FVector3 *vel);
|
static void CalcPosVel(FSoundChan *chan, FVector3 *pos, FVector3 *vel);
|
||||||
|
@ -952,7 +952,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
|
||||||
|
|
||||||
// If this sound doesn't like playing near itself, don't play it if
|
// If this sound doesn't like playing near itself, don't play it if
|
||||||
// that's what would happen.
|
// that's what would happen.
|
||||||
if (near_limit > 0 && S_CheckSoundLimit(sfx, pos, near_limit, limit_range))
|
if (near_limit > 0 && S_CheckSoundLimit(sfx, pos, near_limit, limit_range, actor, channel))
|
||||||
{
|
{
|
||||||
chanflags |= CHAN_EVICTED;
|
chanflags |= CHAN_EVICTED;
|
||||||
}
|
}
|
||||||
|
@ -1157,7 +1157,7 @@ void S_RestartSound(FSoundChan *chan)
|
||||||
|
|
||||||
// If this sound doesn't like playing near itself, don't play it if
|
// If this sound doesn't like playing near itself, don't play it if
|
||||||
// that's what would happen.
|
// that's what would happen.
|
||||||
if (chan->NearLimit > 0 && S_CheckSoundLimit(&S_sfx[chan->SoundID], pos, chan->NearLimit, chan->LimitRange))
|
if (chan->NearLimit > 0 && S_CheckSoundLimit(&S_sfx[chan->SoundID], pos, chan->NearLimit, chan->LimitRange, NULL, 0))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1389,12 +1389,19 @@ bool S_CheckSingular(int sound_id)
|
||||||
//
|
//
|
||||||
// Limits the number of nearby copies of a sound that can play near
|
// Limits the number of nearby copies of a sound that can play near
|
||||||
// each other. If there are NearLimit instances of this sound already
|
// each other. If there are NearLimit instances of this sound already
|
||||||
// playing within 256 units of the new sound, the new sound will not
|
// playing within sqrt(limit_range) (typically 256 units) of the new sound, the
|
||||||
// start.
|
// new sound will not start.
|
||||||
|
//
|
||||||
|
// If an actor is specified, and it is already playing the same sound on
|
||||||
|
// the same channel, this sound will not be limited. In this case, we're
|
||||||
|
// restarting an already playing sound, so there's no need to limit it.
|
||||||
|
//
|
||||||
|
// Returns true if the sound should not play.
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
bool S_CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_limit, float limit_range)
|
bool S_CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_limit, float limit_range,
|
||||||
|
AActor *actor, int channel)
|
||||||
{
|
{
|
||||||
FSoundChan *chan;
|
FSoundChan *chan;
|
||||||
int count;
|
int count;
|
||||||
|
@ -1405,6 +1412,12 @@ bool S_CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_limit, floa
|
||||||
{
|
{
|
||||||
FVector3 chanorigin;
|
FVector3 chanorigin;
|
||||||
|
|
||||||
|
if (actor != NULL && chan->EntChannel == channel &&
|
||||||
|
chan->SourceType == SOURCE_Actor && chan->Actor == actor)
|
||||||
|
{ // We are restarting a playing sound. Always let it play.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
CalcPosVel(chan, &chanorigin, NULL);
|
CalcPosVel(chan, &chanorigin, NULL);
|
||||||
if ((chanorigin - pos).LengthSquared() <= limit_range)
|
if ((chanorigin - pos).LengthSquared() <= limit_range)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1725,8 +1725,6 @@ FISoundChannel *FMODSoundRenderer::StartSound(SoundHandle sfx, float vol, int pi
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
CVAR(Float, snd_3dspread, 180, 0)
|
|
||||||
|
|
||||||
FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener *listener, float vol,
|
FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener *listener, float vol,
|
||||||
FRolloffInfo *rolloff, float distscale,
|
FRolloffInfo *rolloff, float distscale,
|
||||||
int pitch, int priority, const FVector3 &pos, const FVector3 &vel,
|
int pitch, int priority, const FVector3 &pos, const FVector3 &vel,
|
||||||
|
@ -1811,7 +1809,6 @@ FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener *
|
||||||
if (mode & FMOD_3D)
|
if (mode & FMOD_3D)
|
||||||
{
|
{
|
||||||
chan->set3DAttributes((FMOD_VECTOR *)&pos[0], (FMOD_VECTOR *)&vel[0]);
|
chan->set3DAttributes((FMOD_VECTOR *)&pos[0], (FMOD_VECTOR *)&vel[0]);
|
||||||
chan->set3DSpread(snd_3dspread);
|
|
||||||
}
|
}
|
||||||
if (!HandleChannelDelay(chan, reuse_chan, flags & (SNDF_ABSTIME | SNDF_LOOP), freq))
|
if (!HandleChannelDelay(chan, reuse_chan, flags & (SNDF_ABSTIME | SNDF_LOOP), freq))
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,5 +3,5 @@
|
||||||
// This file was automatically generated by the
|
// This file was automatically generated by the
|
||||||
// updaterevision tool. Do not edit by hand.
|
// updaterevision tool. Do not edit by hand.
|
||||||
|
|
||||||
#define ZD_SVN_REVISION_STRING "3350"
|
#define ZD_SVN_REVISION_STRING "3360"
|
||||||
#define ZD_SVN_REVISION_NUMBER 3350
|
#define ZD_SVN_REVISION_NUMBER 3360
|
||||||
|
|
|
@ -78,7 +78,7 @@ void STACK_ARGS DCanvas::DrawChar (FFont *font, int normalcolor, int x, int y, B
|
||||||
//
|
//
|
||||||
// Write a string using the given font
|
// Write a string using the given font
|
||||||
//
|
//
|
||||||
void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag1, va_list taglist)
|
void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char *string, va_list taglist)
|
||||||
{
|
{
|
||||||
INTBOOL boolval;
|
INTBOOL boolval;
|
||||||
va_list tags;
|
va_list tags;
|
||||||
|
@ -122,7 +122,7 @@ void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char *
|
||||||
#else
|
#else
|
||||||
tags = taglist;
|
tags = taglist;
|
||||||
#endif
|
#endif
|
||||||
tag = tag1;
|
tag = va_arg(tags, uint32);
|
||||||
|
|
||||||
while (tag != TAG_DONE)
|
while (tag != TAG_DONE)
|
||||||
{
|
{
|
||||||
|
@ -209,6 +209,7 @@ void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char *
|
||||||
}
|
}
|
||||||
tag = va_arg (tags, uint32);
|
tag = va_arg (tags, uint32);
|
||||||
}
|
}
|
||||||
|
va_end(tags);
|
||||||
|
|
||||||
height *= scaley;
|
height *= scaley;
|
||||||
|
|
||||||
|
@ -242,7 +243,6 @@ void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char *
|
||||||
#else
|
#else
|
||||||
tags = taglist;
|
tags = taglist;
|
||||||
#endif
|
#endif
|
||||||
tag = tag1;
|
|
||||||
if (forcedwidth)
|
if (forcedwidth)
|
||||||
{
|
{
|
||||||
w = forcedwidth;
|
w = forcedwidth;
|
||||||
|
@ -262,21 +262,22 @@ void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char *
|
||||||
}
|
}
|
||||||
cx += (w + kerning) * scalex;
|
cx += (w + kerning) * scalex;
|
||||||
}
|
}
|
||||||
|
va_end(taglist);
|
||||||
}
|
}
|
||||||
|
|
||||||
void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, ...)
|
void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, const char *string, ...)
|
||||||
{
|
{
|
||||||
va_list tags;
|
va_list tags;
|
||||||
va_start(tags, tag);
|
va_start(tags, string);
|
||||||
DrawTextV(font, normalcolor, x, y, string, tag, tags);
|
DrawTextV(font, normalcolor, x, y, string, tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A synonym so that this can still be used in files that #include Windows headers
|
// A synonym so that this can still be used in files that #include Windows headers
|
||||||
void STACK_ARGS DCanvas::DrawTextA (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, ...)
|
void STACK_ARGS DCanvas::DrawTextA (FFont *font, int normalcolor, int x, int y, const char *string, ...)
|
||||||
{
|
{
|
||||||
va_list tags;
|
va_list tags;
|
||||||
va_start(tags, tag);
|
va_start(tags, string);
|
||||||
DrawTextV(font, normalcolor, x, y, string, tag, tags);
|
DrawTextV(font, normalcolor, x, y, string, tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -214,11 +214,11 @@ public:
|
||||||
void VirtualToRealCoordsInt(int &x, int &y, int &w, int &h, int vwidth, int vheight, bool vbottom=false, bool handleaspect=true) const;
|
void VirtualToRealCoordsInt(int &x, int &y, int &w, int &h, int vwidth, int vheight, bool vbottom=false, bool handleaspect=true) const;
|
||||||
|
|
||||||
// 2D Text drawing
|
// 2D Text drawing
|
||||||
void STACK_ARGS DrawText (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, ...);
|
void STACK_ARGS DrawText (FFont *font, int normalcolor, int x, int y, const char *string, ...);
|
||||||
#ifndef DrawText // See WinUser.h for the definition of DrawText as a macro
|
#ifndef DrawText // See WinUser.h for the definition of DrawText as a macro
|
||||||
void STACK_ARGS DrawTextA (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, ...);
|
void STACK_ARGS DrawTextA (FFont *font, int normalcolor, int x, int y, const char *string, ...);
|
||||||
#endif
|
#endif
|
||||||
void DrawTextV (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, va_list tags);
|
void DrawTextV (FFont *font, int normalcolor, int x, int y, const char *string, va_list tags);
|
||||||
void STACK_ARGS DrawChar (FFont *font, int normalcolor, int x, int y, BYTE character, ...);
|
void STACK_ARGS DrawChar (FFont *font, int normalcolor, int x, int y, BYTE character, ...);
|
||||||
|
|
||||||
struct DrawParms
|
struct DrawParms
|
||||||
|
|
9
wadsrc/static/maparrows/ravenkey.txt
Normal file
9
wadsrc/static/maparrows/ravenkey.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
( 0, 0 ), ( 0.25, -0.5 )
|
||||||
|
( 0.25, -0.5 ), ( 0.5, -0.5 )
|
||||||
|
( 0.5, -0.5 ), ( 0.5, 0.5 )
|
||||||
|
( 0.5, 0.5 ), ( 0.25, 0.5 )
|
||||||
|
( 0.25, 0.5 ), ( 0, 0 ) // handle part type thing
|
||||||
|
( 0, 0 ), ( -1, 0 ) // stem
|
||||||
|
( -1, 0 ), ( -1, -0.5 ) // end lockpick part
|
||||||
|
( -0.75, 0 ), ( -0.75, -0.25 )
|
||||||
|
|
|
@ -75,6 +75,7 @@ skill baby
|
||||||
EasyBossBrain
|
EasyBossBrain
|
||||||
SpawnFilter = Baby
|
SpawnFilter = Baby
|
||||||
Name = "$MNU_WETNURSE"
|
Name = "$MNU_WETNURSE"
|
||||||
|
EasyKey
|
||||||
}
|
}
|
||||||
|
|
||||||
skill easy
|
skill easy
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue