- Fixed: A_PainDie and A_DualPainAttack could fail to spawn the correct actor
if the first spawned one died and executed some code in its death state. - Added Karate Chris's submission for 'allowrespawn' MAPINFO option. - Added Karate Chris's submission for customizable skill confirmation text. - Fixed: Doom's statusbar only checked for primary attacks, not secondary ones when setting Doomguy's face. (Thanks to Karate Chris for the fix.) - added Skulltag's FORCEYBILLBOARD and FORCEXYBILLBOARD flags to the DECORATE parser. Even though the software renderer has no use for them it is necessary to support them so that mods can use these flags without becoming incompatible with ZDoom. SVN r576 (trunk)
This commit is contained in:
parent
2e56925c36
commit
47dafa3824
14 changed files with 63 additions and 23 deletions
|
|
@ -322,6 +322,9 @@ enum
|
|||
RF_VOXELSPRITE = 0x3000, // Voxel object
|
||||
RF_INVISIBLE = 0x8000, // Don't bother drawing this actor
|
||||
|
||||
RF_FORCEYBILLBOARD = 0x10000, // [BB] OpenGL only: draw with y axis billboard, i.e. anchored to the floor (overrides gl_billboard_mode setting)
|
||||
RF_FORCEXYBILLBOARD = 0x20000, // [BB] OpenGL only: draw with xy axis billboard, i.e. unanchored (overrides gl_billboard_mode setting)
|
||||
|
||||
// --- dummies for unknown/unimplemented Strife flags ---
|
||||
|
||||
MF_STRIFEx8000000 = 0, // seems related to MF_SHADOW
|
||||
|
|
|
|||
|
|
@ -11,11 +11,23 @@ void A_PainDie (AActor *);
|
|||
|
||||
void A_SkullAttack (AActor *self);
|
||||
|
||||
static const PClass *GetSpawnType()
|
||||
{
|
||||
const PClass *spawntype = NULL;
|
||||
int index=CheckIndex(1, NULL);
|
||||
if (index>=0)
|
||||
{
|
||||
spawntype = PClass::FindClass((ENamedName)StateParameters[index]);
|
||||
}
|
||||
if (spawntype == NULL) spawntype = PClass::FindClass("LostSoul");
|
||||
return spawntype;
|
||||
}
|
||||
|
||||
//
|
||||
// A_PainShootSkull
|
||||
// Spawn a lost soul and launch it at the target
|
||||
//
|
||||
void A_PainShootSkull (AActor *self, angle_t angle)
|
||||
void A_PainShootSkull (AActor *self, angle_t angle, const PClass *spawntype)
|
||||
{
|
||||
fixed_t x, y, z;
|
||||
|
||||
|
|
@ -23,17 +35,8 @@ void A_PainShootSkull (AActor *self, angle_t angle)
|
|||
angle_t an;
|
||||
int prestep;
|
||||
|
||||
const PClass *spawntype = NULL;
|
||||
|
||||
if (self->DamageType==NAME_Massacre) return;
|
||||
|
||||
int index=CheckIndex(1, NULL);
|
||||
if (index>=0)
|
||||
{
|
||||
spawntype = PClass::FindClass((ENamedName)StateParameters[index]);
|
||||
}
|
||||
if (spawntype == NULL) spawntype = PClass::FindClass("LostSoul");
|
||||
|
||||
// [RH] check to make sure it's not too close to the ceiling
|
||||
if (self->z + self->height + 8*FRACUNIT > self->ceilingz)
|
||||
{
|
||||
|
|
@ -121,8 +124,9 @@ void A_PainAttack (AActor *self)
|
|||
if (!self->target)
|
||||
return;
|
||||
|
||||
const PClass *spawntype = GetSpawnType();
|
||||
A_FaceTarget (self);
|
||||
A_PainShootSkull (self, self->angle);
|
||||
A_PainShootSkull (self, self->angle, spawntype);
|
||||
}
|
||||
|
||||
void A_DualPainAttack (AActor *self)
|
||||
|
|
@ -130,9 +134,10 @@ void A_DualPainAttack (AActor *self)
|
|||
if (!self->target)
|
||||
return;
|
||||
|
||||
const PClass *spawntype = GetSpawnType();
|
||||
A_FaceTarget (self);
|
||||
A_PainShootSkull (self, self->angle + ANG45);
|
||||
A_PainShootSkull (self, self->angle - ANG45);
|
||||
A_PainShootSkull (self, self->angle + ANG45, spawntype);
|
||||
A_PainShootSkull (self, self->angle - ANG45, spawntype);
|
||||
}
|
||||
|
||||
void A_PainDie (AActor *self)
|
||||
|
|
@ -141,8 +146,9 @@ void A_PainDie (AActor *self)
|
|||
{ // And I thought you were my friend!
|
||||
self->flags &= ~MF_FRIENDLY;
|
||||
}
|
||||
const PClass *spawntype = GetSpawnType();
|
||||
A_NoBlocking (self);
|
||||
A_PainShootSkull (self, self->angle + ANG90);
|
||||
A_PainShootSkull (self, self->angle + ANG180);
|
||||
A_PainShootSkull (self, self->angle + ANG270);
|
||||
A_PainShootSkull (self, self->angle + ANG90, spawntype);
|
||||
A_PainShootSkull (self, self->angle + ANG180, spawntype);
|
||||
A_PainShootSkull (self, self->angle + ANG270, spawntype);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -916,7 +916,7 @@ private:
|
|||
if (FacePriority < 6)
|
||||
{
|
||||
// rapid firing
|
||||
if ((CPlayer->cmd.ucmd.buttons & BT_ATTACK) && !(CPlayer->cheats & (CF_FROZEN | CF_TOTALLYFROZEN)))
|
||||
if ((CPlayer->cmd.ucmd.buttons & (BT_ATTACK|BT_ALTATTACK)) && !(CPlayer->cheats & (CF_FROZEN | CF_TOTALLYFROZEN)))
|
||||
{
|
||||
if (FaceLastAttackDown == -1)
|
||||
FaceLastAttackDown = ST_RAMPAGEDELAY;
|
||||
|
|
|
|||
|
|
@ -1405,7 +1405,7 @@ static void G_QueueBody (AActor *body)
|
|||
//
|
||||
void G_DoReborn (int playernum, bool freshbot)
|
||||
{
|
||||
if (!multiplayer)
|
||||
if (!multiplayer && !(level.flags & LEVEL_ALLOWRESPAWN))
|
||||
{
|
||||
if (BackupSaveName.Len() > 0 && FileExists (BackupSaveName.GetChars()))
|
||||
{ // Load game from the last point it was saved
|
||||
|
|
|
|||
|
|
@ -297,6 +297,7 @@ static const char *MapInfoMapLevel[] =
|
|||
"totalinfighting",
|
||||
"infiniteflightpowerup",
|
||||
"noinfiniteflightpowerup",
|
||||
"allowrespawn",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -437,6 +438,7 @@ MapHandlers[] =
|
|||
{ MITYPE_SCFLAGS, LEVEL_TOTALINFIGHTING, ~LEVEL_NOINFIGHTING },
|
||||
{ MITYPE_SETFLAG, LEVEL_INFINITE_FLIGHT, 0 },
|
||||
{ MITYPE_CLRFLAG, LEVEL_INFINITE_FLIGHT, 0 },
|
||||
{ MITYPE_SETFLAG, LEVEL_ALLOWRESPAWN, 0 },
|
||||
};
|
||||
|
||||
static const char *MapInfoClusterLevel[] =
|
||||
|
|
@ -3142,6 +3144,10 @@ static void ParseSkill ()
|
|||
else if (SC_Compare("MustConfirm"))
|
||||
{
|
||||
skill.MustConfirm = true;
|
||||
if (SC_CheckToken(TK_String))
|
||||
{
|
||||
skill.MustConfirmText = sc_String;
|
||||
}
|
||||
}
|
||||
else if (SC_Compare("Key"))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -113,6 +113,8 @@
|
|||
#define LEVEL_NOMONSTERS UCONST64(0x1000000000000)
|
||||
#define LEVEL_INFINITE_FLIGHT UCONST64(0x2000000000000)
|
||||
|
||||
#define LEVEL_ALLOWRESPAWN UCONST64(0x4000000000000)
|
||||
|
||||
struct acsdefered_s;
|
||||
|
||||
struct FSpecialAction
|
||||
|
|
@ -392,6 +394,7 @@ struct FSkillInfo
|
|||
SkillMenuNames MenuNamesForPlayerClass;
|
||||
bool MenuNameIsLump;
|
||||
bool MustConfirm;
|
||||
FString MustConfirmText;
|
||||
char shortcut;
|
||||
int textcolor;
|
||||
|
||||
|
|
@ -417,6 +420,7 @@ struct FSkillInfo
|
|||
MenuNamesForPlayerClass = other.MenuNamesForPlayerClass;
|
||||
MenuNameIsLump = other.MenuNameIsLump;
|
||||
MustConfirm = other.MustConfirm;
|
||||
MustConfirmText = other.MustConfirmText;
|
||||
shortcut = other.shortcut;
|
||||
textcolor = other.textcolor;
|
||||
return *this;
|
||||
|
|
|
|||
|
|
@ -1741,7 +1741,10 @@ void M_ChooseSkill (int choice)
|
|||
{
|
||||
if (gameinfo.gametype == GAME_Doom && AllSkills[choice].MustConfirm)
|
||||
{
|
||||
M_StartMessage (GStrings("NIGHTMARE"), M_VerifyNightmare, true);
|
||||
const char *msg = AllSkills[choice].MustConfirmText;
|
||||
if (*msg==0) msg = GStrings("NIGHTMARE");
|
||||
if (*msg=='$') msg = GStrings(msg+1);
|
||||
M_StartMessage (msg, M_VerifyNightmare, true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -226,6 +226,8 @@ static flagdef ActorFlags[]=
|
|||
DEFINE_FLAG2(FX_ROCKET, ROCKETTRAIL, AActor, effects),
|
||||
DEFINE_FLAG2(FX_GRENADE, GRENADETRAIL, AActor, effects),
|
||||
DEFINE_FLAG(RF, INVISIBLE, AActor, renderflags),
|
||||
DEFINE_FLAG(RF, FORCEYBILLBOARD, AActor, renderflags),
|
||||
DEFINE_FLAG(RF, FORCEXYBILLBOARD, AActor, renderflags),
|
||||
|
||||
// Deprecated flags. Handling must be performed in HandleDeprecatedFlags
|
||||
DEFINE_DEPRECATED_FLAG(FIREDAMAGE, AActor, 0),
|
||||
|
|
|
|||
|
|
@ -2041,6 +2041,7 @@ void A_Respawn (AActor *actor)
|
|||
{
|
||||
Spawn<ATeleportFog> (x, y, actor->z + TELEFOGHEIGHT, ALLOW_REPLACE);
|
||||
}
|
||||
if (actor->CountsAsKill()) level.total_monsters++;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue