mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-27 22:42:57 +00:00
- Added a StartConversation special that allows automatic activation of Strife
dialogs. - Added Thing_Raise special that allows Arch-Vile like resurrections from scripts or DECORATE states. - Added a RadiusDamageFactor property for actors. This replaces the hard coded factor of 0.25 for Hexen's players. - Added new SpawnProjectile function to ACS. It's the same as Thing_Projectile2 but the projectile is specified by name, not spawn ID. - Added MAPINFO option to set the compatibility flags. If this is done these explicit settings will take precedence over the compatflags CVAR. SVN r164 (trunk)
This commit is contained in:
parent
4325fb8993
commit
15681d0588
32 changed files with 472 additions and 260 deletions
|
@ -1,3 +1,15 @@
|
|||
June 3, 2006 (Changes by Graf Zahl)
|
||||
- Added a StartConversation special that allows automatic activation of Strife
|
||||
dialogs.
|
||||
- Added Thing_Raise special that allows Arch-Vile like resurrections from scripts
|
||||
or DECORATE states.
|
||||
- Added a RadiusDamageFactor property for actors. This replaces the hard coded
|
||||
factor of 0.25 for Hexen's players.
|
||||
- Added new SpawnProjectile function to ACS. It's the same as Thing_Projectile2
|
||||
but the projectile is specified by name, not spawn ID.
|
||||
- Added MAPINFO option to set the compatibility flags. If this is done these
|
||||
explicit settings will take precedence over the compatflags CVAR.
|
||||
|
||||
May 31, 2006
|
||||
- Merged in recent ZDBSP fixes:
|
||||
- Added code to explicitly handle outputting overlapping segs when
|
||||
|
@ -14,7 +26,6 @@ May 31, 2006
|
|||
- Enabled reference optimization and COMDAT folding in the linker for a slightly
|
||||
smaller executable.
|
||||
|
||||
|
||||
May 31, 2006 (Changes by Graf Zahl)
|
||||
- Fixed: Ammo items dropped by monsters that have a default amount of 1 didn't
|
||||
contain any ammo at all.
|
||||
|
|
|
@ -403,6 +403,7 @@ enum
|
|||
AMETA_WoundHealth, // health needed to enter wound state
|
||||
AMETA_PoisonDamage, // Amount of poison damage
|
||||
AMETA_FastSpeed, // Speed in fast mode
|
||||
AMETA_RDFactor, // Radius damage factor
|
||||
};
|
||||
|
||||
// Map Object definition.
|
||||
|
|
|
@ -372,7 +372,14 @@ CVAR (Flag, sv_barrelrespawn, dmflags2, DF2_BARRELS_RESPAWN);
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
CVAR (Int, compatflags, 0, CVAR_ARCHIVE|CVAR_SERVERINFO);
|
||||
int i_compatflags; // internal compatflags composed from the compatflags CVAR and MAPINFO settings
|
||||
|
||||
CUSTOM_CVAR (Int, compatflags, 0, CVAR_ARCHIVE|CVAR_SERVERINFO)
|
||||
{
|
||||
if (level.info == NULL) i_compatflags = self;
|
||||
else i_compatflags = (self & ~level.info->compatmask) | (level.info->compatflags & level.info->compatmask);
|
||||
}
|
||||
|
||||
CVAR (Flag, compat_shortTex, compatflags, COMPATF_SHORTTEX);
|
||||
CVAR (Flag, compat_stairs, compatflags, COMPATF_STAIRINDEX);
|
||||
CVAR (Flag, compat_limitpain, compatflags, COMPATF_LIMITPAIN);
|
||||
|
|
|
@ -309,5 +309,6 @@ EXTERN_CVAR (Int, dmflags);
|
|||
EXTERN_CVAR (Int, dmflags2); // [BC]
|
||||
|
||||
EXTERN_CVAR (Int, compatflags);
|
||||
extern int i_compatflags;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -132,7 +132,7 @@ void A_PainShootSkull (AActor *self, angle_t angle)
|
|||
}
|
||||
|
||||
// [RH] make this optional
|
||||
if (compatflags & COMPATF_LIMITPAIN)
|
||||
if (i_compatflags & COMPATF_LIMITPAIN)
|
||||
{
|
||||
// count total number of skulls currently on the level
|
||||
// if there are already 20 skulls on the level, don't spit another one
|
||||
|
|
|
@ -91,6 +91,7 @@ IMPLEMENT_ACTOR (AClericPlayer, Hexen, -1, 0)
|
|||
PROP_RadiusFixed (16)
|
||||
PROP_HeightFixed (64)
|
||||
PROP_SpeedFixed (1)
|
||||
PROP_RadiusdamageFactor(FRACUNIT/4)
|
||||
PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|MF_PICKUP|MF_NOTDMATCH|MF_FRIENDLY)
|
||||
PROP_Flags2 (MF2_WINDTHRUST|MF2_FLOORCLIP|MF2_SLIDE|MF2_PASSMOBJ|MF2_TELESTOMP|MF2_PUSHWALL)
|
||||
PROP_Flags3 (MF3_NOBLOCKMONST)
|
||||
|
|
|
@ -89,6 +89,7 @@ IMPLEMENT_ACTOR (AFighterPlayer, Hexen, -1, 0)
|
|||
PROP_Mass (100)
|
||||
PROP_PainChance (255)
|
||||
PROP_SpeedFixed (1)
|
||||
PROP_RadiusdamageFactor(FRACUNIT/4)
|
||||
PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|MF_PICKUP|MF_NOTDMATCH|MF_FRIENDLY)
|
||||
PROP_Flags2 (MF2_WINDTHRUST|MF2_FLOORCLIP|MF2_SLIDE|MF2_PASSMOBJ|MF2_TELESTOMP|MF2_PUSHWALL)
|
||||
PROP_Flags3 (MF3_NOBLOCKMONST)
|
||||
|
|
|
@ -88,6 +88,7 @@ IMPLEMENT_ACTOR (AMagePlayer, Hexen, -1, 0)
|
|||
PROP_RadiusFixed (16)
|
||||
PROP_HeightFixed (64)
|
||||
PROP_SpeedFixed (1)
|
||||
PROP_RadiusdamageFactor(FRACUNIT/4)
|
||||
PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|MF_PICKUP|MF_NOTDMATCH|MF_FRIENDLY)
|
||||
PROP_Flags2 (MF2_WINDTHRUST|MF2_FLOORCLIP|MF2_SLIDE|MF2_PASSMOBJ|MF2_TELESTOMP|MF2_PUSHWALL)
|
||||
PROP_Flags3 (MF3_NOBLOCKMONST)
|
||||
|
|
|
@ -247,6 +247,19 @@ static const char *MapInfoMapLevel[] =
|
|||
"allowcrouch",
|
||||
"nocrouch",
|
||||
"pausemusicinmenus",
|
||||
"compat_shorttex",
|
||||
"compat_stairs",
|
||||
"compat_limitpain",
|
||||
"compat_nopassover",
|
||||
"compat_notossdrops",
|
||||
"compat_useblocking",
|
||||
"compat_nodoorlight",
|
||||
"compat_ravenscroll",
|
||||
"compat_soundtarget",
|
||||
"compat_dehhealth",
|
||||
"compat_trace",
|
||||
"compat_dropoff",
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -270,7 +283,8 @@ enum EMIType
|
|||
MITYPE_RELLIGHT,
|
||||
MITYPE_CLRBYTES,
|
||||
MITYPE_REDIRECT,
|
||||
MITYPE_SPECIALACTION
|
||||
MITYPE_SPECIALACTION,
|
||||
MITYPE_COMPATFLAG,
|
||||
};
|
||||
|
||||
struct MapInfoHandler
|
||||
|
@ -363,6 +377,18 @@ MapHandlers[] =
|
|||
{ MITYPE_SCFLAGS, LEVEL_CROUCH_YES, ~LEVEL_CROUCH_NO },
|
||||
{ MITYPE_SCFLAGS, LEVEL_CROUCH_NO, ~LEVEL_CROUCH_YES },
|
||||
{ MITYPE_SCFLAGS, LEVEL_PAUSE_MUSIC_IN_MENUS, 0 },
|
||||
{ MITYPE_COMPATFLAG, COMPATF_SHORTTEX},
|
||||
{ MITYPE_COMPATFLAG, COMPATF_STAIRINDEX},
|
||||
{ MITYPE_COMPATFLAG, COMPATF_LIMITPAIN},
|
||||
{ MITYPE_COMPATFLAG, COMPATF_NO_PASSMOBJ},
|
||||
{ MITYPE_COMPATFLAG, COMPATF_NOTOSSDROPS},
|
||||
{ MITYPE_COMPATFLAG, COMPATF_USEBLOCKING},
|
||||
{ MITYPE_COMPATFLAG, COMPATF_NODOORLIGHT},
|
||||
{ MITYPE_COMPATFLAG, COMPATF_RAVENSCROLL},
|
||||
{ MITYPE_COMPATFLAG, COMPATF_SOUNDTARGET},
|
||||
{ MITYPE_COMPATFLAG, COMPATF_DEHHEALTH},
|
||||
{ MITYPE_COMPATFLAG, COMPATF_TRACE},
|
||||
{ MITYPE_COMPATFLAG, COMPATF_DROPOFF},
|
||||
};
|
||||
|
||||
static const char *MapInfoClusterLevel[] =
|
||||
|
@ -976,6 +1002,16 @@ static void ParseMapInfoLower (MapInfoHandler *handlers,
|
|||
SC_SetCMode(false);
|
||||
}
|
||||
break;
|
||||
|
||||
case MITYPE_COMPATFLAG:
|
||||
SC_MustGetNumber();
|
||||
if (levelinfo != NULL)
|
||||
{
|
||||
if (sc_Number) levelinfo->compatflags |= (DWORD)handler->data1;
|
||||
else levelinfo->compatflags &= ~ (DWORD)handler->data1;
|
||||
levelinfo->compatmask |= (DWORD)handler->data1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (levelinfo)
|
||||
|
@ -2157,6 +2193,8 @@ void G_InitLevelLocals ()
|
|||
|
||||
dmflags = (dmflags & ~clear) | set;
|
||||
|
||||
compatflags.Callback();
|
||||
|
||||
NormalLight.ChangeFade (level.fadeto);
|
||||
|
||||
if (level.Scrolls != NULL)
|
||||
|
|
|
@ -134,6 +134,7 @@ struct level_info_s
|
|||
char *level_name;
|
||||
char fadetable[9];
|
||||
SBYTE WallVertLight, WallHorizLight;
|
||||
// TheDefaultLevelInfo initializes everything above this line.
|
||||
int musicorder;
|
||||
FCompressedMemFile *snapshot;
|
||||
DWORD snapshotVer;
|
||||
|
@ -149,6 +150,8 @@ struct level_info_s
|
|||
float aircontrol;
|
||||
int WarpTrans;
|
||||
int airsupply;
|
||||
DWORD compatflags;
|
||||
DWORD compatmask;
|
||||
|
||||
// Redirection: If any player is carrying the specified item, then
|
||||
// you go to the RedirectMap instead of this one.
|
||||
|
|
|
@ -180,7 +180,7 @@ bool P_GiveBody (AActor *actor, int num)
|
|||
|
||||
if (player != NULL)
|
||||
{
|
||||
max = ((compatflags&COMPATF_DEHHEALTH)? 100 : deh.MaxHealth) + player->stamina;
|
||||
max = ((i_compatflags&COMPATF_DEHHEALTH)? 100 : deh.MaxHealth) + player->stamina;
|
||||
if (player->morphTics)
|
||||
{
|
||||
max = MAXMORPHHEALTH;
|
||||
|
@ -1768,7 +1768,7 @@ bool AHealth::TryPickup (AActor *other)
|
|||
{
|
||||
if (max == 0)
|
||||
{
|
||||
max = ((compatflags&COMPATF_DEHHEALTH)? 100 : deh.MaxHealth) + player->stamina;
|
||||
max = ((i_compatflags&COMPATF_DEHHEALTH)? 100 : deh.MaxHealth) + player->stamina;
|
||||
if (player->morphTics)
|
||||
{
|
||||
max = MAXMORPHHEALTH;
|
||||
|
|
|
@ -282,6 +282,7 @@ enum
|
|||
ADEF_BounceFactor,
|
||||
ADEF_BounceCount,
|
||||
ADEF_FloatSpeed,
|
||||
ADEF_RDFactor,
|
||||
|
||||
ADEF_SpawnState,
|
||||
ADEF_SeeState,
|
||||
|
|
|
@ -216,6 +216,7 @@ static void ApplyActorDefault (int defnum, const char *datastr, int dataint)
|
|||
case ADEF_MaxStepHeight: actor->MaxStepHeight = dataint; break;
|
||||
case ADEF_BounceFactor: actor->bouncefactor = dataint; break;
|
||||
case ADEF_BounceCount: actor->bouncecount = dataint; break;
|
||||
case ADEF_RDFactor: sgClass->Meta.SetMetaFixed (AMETA_RDFactor, dataint); break;
|
||||
|
||||
case ADEF_SpawnState: actor->SpawnState = datastate; break;
|
||||
case ADEF_SeeState: actor->SeeState = datastate; break;
|
||||
|
@ -273,7 +274,7 @@ static void ApplyActorDefault (int defnum, const char *datastr, int dataint)
|
|||
|
||||
case ADEF_Ammo_BackpackAmount: ammo->BackpackAmount = dataint; break;
|
||||
case ADEF_Ammo_BackpackMaxAmount:ammo->BackpackMaxAmount = dataint; break;
|
||||
case ADEF_Ammo_DropAmount: sgClass->Meta.SetMetaInt (AIMETA_DropAmount, dataint);
|
||||
case ADEF_Ammo_DropAmount: sgClass->Meta.SetMetaInt (AIMETA_DropAmount, dataint); break;
|
||||
|
||||
case ADEF_Weapon_Flags: weapon->WeaponFlags = dataint; break;
|
||||
case ADEF_Weapon_FlagsSet: weapon->WeaponFlags |= dataint; break;
|
||||
|
|
|
@ -252,6 +252,7 @@ public:
|
|||
#define PROP_MaxStepHeight(x) ADD_FIXD_PROP(ADEF_MaxStepHeight,x)
|
||||
#define PROP_BounceFactor(x) ADD_LONG_PROP(ADEF_BounceFactor,x)
|
||||
#define PROP_BounceCount(x) ADD_LONG_PROP(ADEF_BounceCount,x)
|
||||
#define PROP_RadiusdamageFactor(x) ADD_LONG_PROP(ADEF_RDFactor,x)
|
||||
|
||||
#define PROP_SpawnState(x) ADD_BYTE_PROP(ADEF_SpawnState,x)
|
||||
#define PROP_SeeState(x) ADD_BYTE_PROP(ADEF_SeeState,x)
|
||||
|
|
|
@ -4294,7 +4294,14 @@ int DLevelScript::RunScript ()
|
|||
// Like Thing_Projectile(Gravity) specials, but you can give the
|
||||
// projectile a TID.
|
||||
// Thing_Projectile2 (tid, type, angle, speed, vspeed, gravity, newtid);
|
||||
P_Thing_Projectile (STACK(7), STACK(6), ((angle_t)(STACK(5)<<24)),
|
||||
P_Thing_Projectile (STACK(7), STACK(6), NULL, ((angle_t)(STACK(5)<<24)),
|
||||
STACK(4)<<(FRACBITS-3), STACK(3)<<(FRACBITS-3), 0, NULL, STACK(2), STACK(1), false);
|
||||
sp -= 7;
|
||||
break;
|
||||
|
||||
case PCD_SPAWNPROJECTILE:
|
||||
// Same, but takes an actor name instead of a spawn ID.
|
||||
P_Thing_Projectile (STACK(7), 0, FBehavior::StaticLookupString (STACK(6)), ((angle_t)(STACK(5)<<24)),
|
||||
STACK(4)<<(FRACBITS-3), STACK(3)<<(FRACBITS-3), 0, NULL, STACK(2), STACK(1), false);
|
||||
sp -= 7;
|
||||
break;
|
||||
|
|
|
@ -478,6 +478,10 @@ public:
|
|||
PCD_PRINTWORLDCHARARRAY,
|
||||
PCD_PRINTGLOBALCHARARRAY, // [JB] end of new p-codes
|
||||
PCD_SETACTORANGLE, // [GRB]
|
||||
PCD_GRABINPUT, // Unused but acc defines them
|
||||
PCD_SETMOUSEPOINTER, // "
|
||||
PCD_MOVEMOUSEPOINTER, // "
|
||||
PCD_SPAWNPROJECTILE,
|
||||
|
||||
PCODE_COMMAND_COUNT
|
||||
};
|
||||
|
|
|
@ -84,6 +84,7 @@ static FStrifeDialogueNode *CurNode, *PrevNode;
|
|||
static brokenlines_t *DialogueLines;
|
||||
static AActor *ConversationNPC, *ConversationPC;
|
||||
static angle_t ConversationNPCAngle;
|
||||
static bool ConversationFaceTalker;
|
||||
|
||||
#define NUM_RANDOM_LINES 10
|
||||
#define NUM_RANDOM_GOODBYES 3
|
||||
|
@ -601,7 +602,7 @@ CUSTOM_CVAR(Float, dlg_musicvolume, 1.0f, CVAR_ARCHIVE)
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
void P_StartConversation (AActor *npc, AActor *pc)
|
||||
void P_StartConversation (AActor *npc, AActor *pc, bool facetalker)
|
||||
{
|
||||
FStrifeDialogueReply *reply;
|
||||
menuitem_t item;
|
||||
|
@ -629,9 +630,13 @@ void P_StartConversation (AActor *npc, AActor *pc)
|
|||
{
|
||||
npc->target = pc;
|
||||
}
|
||||
ConversationFaceTalker = facetalker;
|
||||
ConversationNPCAngle = npc->angle;
|
||||
if (facetalker)
|
||||
{
|
||||
A_FaceTarget (npc);
|
||||
pc->angle = R_PointToAngle2 (pc->x, pc->y, npc->x, npc->y);
|
||||
}
|
||||
|
||||
// Check if we should jump to another node
|
||||
while (CurNode->ItemCheck[0] != NULL)
|
||||
|
@ -742,7 +747,7 @@ void P_ResumeConversation ()
|
|||
{
|
||||
if (ConversationPC != NULL && ConversationNPC != NULL)
|
||||
{
|
||||
P_StartConversation (ConversationNPC, ConversationPC);
|
||||
P_StartConversation (ConversationNPC, ConversationPC, ConversationFaceTalker);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -962,7 +967,7 @@ static void PickConversationReply ()
|
|||
ConversationNPC->Conversation = StrifeDialogues[rootnode - reply->NextNode - 1];
|
||||
if (gameaction != ga_slideshow)
|
||||
{
|
||||
P_StartConversation (ConversationNPC, players[consoleplayer].mo);
|
||||
P_StartConversation (ConversationNPC, players[consoleplayer].mo, ConversationFaceTalker);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -59,7 +59,7 @@ extern const PClass *StrifeTypes[999];
|
|||
void P_LoadStrifeConversations (const char *mapname);
|
||||
void P_FreeStrifeConversations ();
|
||||
|
||||
void P_StartConversation (AActor *npc, AActor *pc);
|
||||
void P_StartConversation (AActor *npc, AActor *pc, bool facetalker);
|
||||
void P_ResumeConversation ();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -302,7 +302,7 @@ DDoor::DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTa
|
|||
vertex_t *spot;
|
||||
fixed_t height;
|
||||
|
||||
if (compatflags & COMPATF_NODOORLIGHT)
|
||||
if (i_compatflags & COMPATF_NODOORLIGHT)
|
||||
{
|
||||
m_LightTag = 0;
|
||||
}
|
||||
|
|
|
@ -775,7 +775,7 @@ void P_NewChaseDir(AActor * actor)
|
|||
if (actor->floorz - actor->dropoffz > actor->MaxDropOffHeight &&
|
||||
actor->z <= actor->floorz && !(actor->flags & MF_DROPOFF) &&
|
||||
!(actor->flags2 & MF2_ONMOBJ) &&
|
||||
!(actor->flags & MF_FLOAT) && !(compatflags & COMPATF_DROPOFF))
|
||||
!(actor->flags & MF_FLOAT) && !(i_compatflags & COMPATF_DROPOFF))
|
||||
{
|
||||
a.thing = actor;
|
||||
a.deltax = a.deltay = 0;
|
||||
|
@ -1537,7 +1537,7 @@ void A_Look (AActor *actor)
|
|||
}
|
||||
else
|
||||
{
|
||||
targ = (compatflags & COMPATF_SOUNDTARGET)? actor->Sector->SoundTarget : actor->LastHeard;
|
||||
targ = (i_compatflags & COMPATF_SOUNDTARGET)? actor->Sector->SoundTarget : actor->LastHeard;
|
||||
|
||||
// [RH] If the soundtarget is dead, don't chase it
|
||||
if (targ != NULL && targ->health <= 0)
|
||||
|
@ -2195,7 +2195,7 @@ AInventory *P_DropItem (AActor *source, const PClass *type, int special, int cha
|
|||
fixed_t spawnz;
|
||||
|
||||
spawnz = source->z;
|
||||
if (!(compatflags & COMPATF_NOTOSSDROPS))
|
||||
if (!(i_compatflags & COMPATF_NOTOSSDROPS))
|
||||
{
|
||||
int style = sv_dropstyle;
|
||||
if (style==0) style= (gameinfo.gametype == GAME_Strife)? 2:1;
|
||||
|
@ -2235,7 +2235,7 @@ AInventory *P_DropItem (AActor *source, const PClass *type, int special, int cha
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
if (!(compatflags & COMPATF_NOTOSSDROPS))
|
||||
if (!(i_compatflags & COMPATF_NOTOSSDROPS))
|
||||
{
|
||||
P_TossItem (mo);
|
||||
}
|
||||
|
|
|
@ -698,7 +698,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line,
|
|||
persteptime = FixedDiv (stairsize, speed) >> FRACBITS;
|
||||
|
||||
int (* FindSector) (int tag, int start) =
|
||||
(compatflags & COMPATF_STAIRINDEX)? P_FindSectorFromTagLinear : P_FindSectorFromTag;
|
||||
(i_compatflags & COMPATF_STAIRINDEX)? P_FindSectorFromTagLinear : P_FindSectorFromTag;
|
||||
|
||||
// check if a manual trigger, if so do just the sector on the backside
|
||||
if (tag == 0)
|
||||
|
@ -862,7 +862,7 @@ manual_stair:
|
|||
{
|
||||
return rtn;
|
||||
}
|
||||
if (!(compatflags & COMPATF_STAIRINDEX))
|
||||
if (!(i_compatflags & COMPATF_STAIRINDEX))
|
||||
{
|
||||
secnum = osecnum; //jff 3/4/98 restore loop index
|
||||
}
|
||||
|
|
122
src/p_lnspec.cpp
122
src/p_lnspec.cpp
|
@ -50,6 +50,7 @@
|
|||
#include "a_keys.h"
|
||||
#include "gi.h"
|
||||
#include "m_random.h"
|
||||
#include "p_conversation.h"
|
||||
#include "a_strifeglobal.h"
|
||||
|
||||
#define FUNC(a) static int a (line_t *ln, AActor *it, bool backSide, \
|
||||
|
@ -1107,14 +1108,14 @@ FUNC(LS_Thing_Damage)
|
|||
FUNC(LS_Thing_Projectile)
|
||||
// Thing_Projectile (tid, type, angle, speed, vspeed)
|
||||
{
|
||||
return P_Thing_Projectile (arg0, arg1, BYTEANGLE(arg2), arg3<<(FRACBITS-3),
|
||||
return P_Thing_Projectile (arg0, arg1, NULL, BYTEANGLE(arg2), arg3<<(FRACBITS-3),
|
||||
arg4<<(FRACBITS-3), 0, NULL, 0, 0, false);
|
||||
}
|
||||
|
||||
FUNC(LS_Thing_ProjectileGravity)
|
||||
// Thing_ProjectileGravity (tid, type, angle, speed, vspeed)
|
||||
{
|
||||
return P_Thing_Projectile (arg0, arg1, BYTEANGLE(arg2), arg3<<(FRACBITS-3),
|
||||
return P_Thing_Projectile (arg0, arg1, NULL, BYTEANGLE(arg2), arg3<<(FRACBITS-3),
|
||||
arg4<<(FRACBITS-3), 0, NULL, 1, 0, false);
|
||||
}
|
||||
|
||||
|
@ -1284,13 +1285,13 @@ FUNC(LS_Thing_Hate)
|
|||
FUNC(LS_Thing_ProjectileAimed)
|
||||
// Thing_ProjectileAimed (tid, type, speed, target, newtid)
|
||||
{
|
||||
return P_Thing_Projectile (arg0, arg1, 0, arg2<<(FRACBITS-3), 0, arg3, it, 0, arg4, false);
|
||||
return P_Thing_Projectile (arg0, arg1, NULL, 0, arg2<<(FRACBITS-3), 0, arg3, it, 0, arg4, false);
|
||||
}
|
||||
|
||||
FUNC(LS_Thing_ProjectileIntercept)
|
||||
// Thing_ProjectileIntercept (tid, type, speed, target, newtid)
|
||||
{
|
||||
return P_Thing_Projectile (arg0, arg1, 0, arg2<<(FRACBITS-3), 0, arg3, it, 0, arg4, true);
|
||||
return P_Thing_Projectile (arg0, arg1, NULL, 0, arg2<<(FRACBITS-3), 0, arg3, it, 0, arg4, true);
|
||||
}
|
||||
|
||||
// [BC] added newtid for next two
|
||||
|
@ -1312,6 +1313,81 @@ FUNC(LS_Thing_SpawnFacing)
|
|||
return P_Thing_Spawn (arg0, arg1, ANGLE_MAX, arg2 ? false : true, arg3);
|
||||
}
|
||||
|
||||
static bool DoThingRaise(AActor * thing)
|
||||
{
|
||||
if (thing == NULL)
|
||||
return false; // not valid
|
||||
|
||||
if (!(thing->flags & MF_CORPSE) )
|
||||
return true; // not a corpse
|
||||
|
||||
if (thing->tics != -1)
|
||||
return true; // not lying still yet
|
||||
|
||||
if (thing->RaiseState == NULL)
|
||||
return true; // monster doesn't have a raise state
|
||||
|
||||
AActor *info = thing->GetDefault ();
|
||||
|
||||
thing->momx = thing->momy = 0;
|
||||
|
||||
// [RH] Check against real height and radius
|
||||
fixed_t oldheight = thing->height;
|
||||
fixed_t oldradius = thing->radius;
|
||||
int oldflags = thing->flags;
|
||||
|
||||
thing->flags |= MF_SOLID;
|
||||
thing->height = info->height; // [RH] Use real height
|
||||
thing->radius = info->radius; // [RH] Use real radius
|
||||
if (!P_CheckPosition (thing, thing->x, thing->y))
|
||||
{
|
||||
thing->flags = oldflags;
|
||||
thing->radius = oldradius;
|
||||
thing->height = oldheight;
|
||||
return false;
|
||||
}
|
||||
|
||||
S_Sound (thing, CHAN_BODY, "vile/raise", 1, ATTN_IDLE);
|
||||
|
||||
thing->SetState (info->RaiseState);
|
||||
thing->flags = info->flags;
|
||||
thing->flags2 = info->flags2;
|
||||
thing->flags3 = info->flags3;
|
||||
thing->flags4 = info->flags4;
|
||||
thing->health = info->health;
|
||||
thing->target = NULL;
|
||||
thing->lastenemy = NULL;
|
||||
|
||||
// [RH] If it's a monster, it gets to count as another kill
|
||||
if (thing->CountsAsKill())
|
||||
{
|
||||
level.total_monsters++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FUNC(LS_Thing_Raise)
|
||||
// Thing_Raise(tid)
|
||||
{
|
||||
AActor * target;
|
||||
bool ok = false;
|
||||
|
||||
if (arg0==0)
|
||||
{
|
||||
ok = DoThingRaise (it);
|
||||
}
|
||||
else
|
||||
{
|
||||
TActorIterator<AActor> iterator (arg0);
|
||||
|
||||
while ( (target = iterator.Next ()) )
|
||||
{
|
||||
ok |= DoThingRaise(target);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
FUNC(LS_Thing_SetGoal)
|
||||
// Thing_SetGoal (tid, goal, delay, chasegoal)
|
||||
{
|
||||
|
@ -2555,6 +2631,40 @@ FUNC(LS_GlassBreak)
|
|||
return false;
|
||||
}
|
||||
|
||||
FUNC(LS_StartConversation)
|
||||
// StartConversation (tid, facetalker)
|
||||
{
|
||||
FActorIterator iterator (arg0);
|
||||
|
||||
AActor *target = iterator.Next();
|
||||
|
||||
// Only living players are allowed to start conversations
|
||||
if (it == NULL || it->player == NULL || it->player->mo != it || it->health<=0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Dead things can't talk.
|
||||
if (target->health <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Fighting things don't talk either.
|
||||
if (target->flags4 & MF4_INCOMBAT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (target->Conversation != NULL)
|
||||
{
|
||||
// Give the NPC a chance to play a brief animation
|
||||
target->ConversationAnimation (0);
|
||||
P_StartConversation (target, it, !!arg1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
lnSpecFunc LineSpecials[256] =
|
||||
{
|
||||
LS_NOP,
|
||||
|
@ -2574,8 +2684,8 @@ lnSpecFunc LineSpecials[256] =
|
|||
LS_Door_Animated,
|
||||
LS_Autosave,
|
||||
LS_NOP, // Transfer_WallLight
|
||||
LS_NOP, // 17
|
||||
LS_NOP, // 18
|
||||
LS_Thing_Raise,
|
||||
LS_StartConversation,
|
||||
LS_NOP, // 19
|
||||
LS_Floor_LowerByValue,
|
||||
LS_Floor_LowerToLowest,
|
||||
|
|
|
@ -57,6 +57,8 @@ typedef enum {
|
|||
|
||||
Autosave = 15, // [RH] Save the game *now*
|
||||
Transfer_WallLight = 16,
|
||||
Thing_Raise = 17,
|
||||
StartConversation = 18,
|
||||
|
||||
Floor_LowerByValue = 20,
|
||||
Floor_LowerToLowest = 21,
|
||||
|
|
|
@ -126,7 +126,7 @@ void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz);
|
|||
extern const PClass *SpawnableThings[MAX_SPAWNABLES];
|
||||
|
||||
bool P_Thing_Spawn (int tid, int type, angle_t angle, bool fog, int newtid);
|
||||
bool P_Thing_Projectile (int tid, int type, angle_t angle,
|
||||
bool P_Thing_Projectile (int tid, int type, const char * type_name, angle_t angle,
|
||||
fixed_t speed, fixed_t vspeed, int dest, AActor *forcedest, int gravity, int newtid,
|
||||
bool leadTarget);
|
||||
bool P_Thing_Move (int tid, int mapspot, bool fog);
|
||||
|
|
|
@ -834,7 +834,7 @@ BOOL PIT_CheckThing (AActor *thing)
|
|||
}
|
||||
BlockingMobj = thing;
|
||||
topz = thing->z + thing->height;
|
||||
if (!(compatflags & COMPATF_NO_PASSMOBJ) && !(tmthing->flags & (MF_FLOAT|MF_MISSILE|MF_SKULLFLY|MF_NOGRAVITY)) &&
|
||||
if (!(i_compatflags & COMPATF_NO_PASSMOBJ) && !(tmthing->flags & (MF_FLOAT|MF_MISSILE|MF_SKULLFLY|MF_NOGRAVITY)) &&
|
||||
(thing->flags & MF_SOLID) && (thing->flags4 & MF4_ACTLIKEBRIDGE))
|
||||
{
|
||||
// [RH] Let monsters walk on actors as well as floors
|
||||
|
@ -856,7 +856,7 @@ BOOL PIT_CheckThing (AActor *thing)
|
|||
}
|
||||
// [RH] If the other thing is a bridge, then treat the moving thing as if it had MF2_PASSMOBJ, so
|
||||
// you can use a scrolling floor to move scenery items underneath a bridge.
|
||||
if ((tmthing->flags2 & MF2_PASSMOBJ || thing->flags4 & MF4_ACTLIKEBRIDGE) && !(compatflags & COMPATF_NO_PASSMOBJ))
|
||||
if ((tmthing->flags2 & MF2_PASSMOBJ || thing->flags4 & MF4_ACTLIKEBRIDGE) && !(i_compatflags & COMPATF_NO_PASSMOBJ))
|
||||
{ // check if a mobj passed over/under another object
|
||||
if (tmthing->flags3 & thing->flags3 & MF3_DONTOVERLAP)
|
||||
{ // Some things prefer not to overlap each other, if possible
|
||||
|
@ -1329,7 +1329,7 @@ BOOL P_CheckPosition (AActor *thing, fixed_t x, fixed_t y)
|
|||
// other things in the blocks and see if we hit something that is
|
||||
// definitely blocking. Otherwise, we need to check the lines, or we
|
||||
// could end up stuck inside a wall.
|
||||
if (BlockingMobj == NULL || (compatflags & COMPATF_NO_PASSMOBJ))
|
||||
if (BlockingMobj == NULL || (i_compatflags & COMPATF_NO_PASSMOBJ))
|
||||
{ // Thing slammed into something; don't let it move now.
|
||||
thing->height = realheight;
|
||||
return false;
|
||||
|
@ -1593,7 +1593,7 @@ BOOL P_TryMove (AActor *thing, fixed_t x, fixed_t y,
|
|||
goto pushline;
|
||||
}
|
||||
}
|
||||
if (!(tmthing->flags2 & MF2_PASSMOBJ) || (compatflags & COMPATF_NO_PASSMOBJ))
|
||||
if (!(tmthing->flags2 & MF2_PASSMOBJ) || (i_compatflags & COMPATF_NO_PASSMOBJ))
|
||||
{
|
||||
thing->z = oldz;
|
||||
return false;
|
||||
|
@ -3159,7 +3159,7 @@ BOOL PTR_UseTraverse (intercept_t *in)
|
|||
{
|
||||
// Give the NPC a chance to play a brief animation
|
||||
in->d.thing->ConversationAnimation (0);
|
||||
P_StartConversation (in->d.thing, usething);
|
||||
P_StartConversation (in->d.thing, usething, true);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -3189,7 +3189,7 @@ blocked:
|
|||
trace.y + FixedMul (trace.dy, in->frac));
|
||||
}
|
||||
if (openrange <= 0 ||
|
||||
(in->d.line->special != 0 && (compatflags & COMPATF_USEBLOCKING)))
|
||||
(in->d.line->special != 0 && (i_compatflags & COMPATF_USEBLOCKING)))
|
||||
{
|
||||
// [RH] Give sector a chance to intercept the use
|
||||
|
||||
|
@ -3233,7 +3233,7 @@ blocked:
|
|||
//[RH] And now I've changed it again. If the line is of type
|
||||
// SPAC_USE, then it eats the use. Everything else passes
|
||||
// it through, including SPAC_USETHROUGH.
|
||||
if (compatflags & COMPATF_USEBLOCKING)
|
||||
if (i_compatflags & COMPATF_USEBLOCKING)
|
||||
{
|
||||
return GET_SPAC(in->d.line->flags) == SPAC_USETHROUGH;
|
||||
}
|
||||
|
@ -3508,10 +3508,8 @@ BOOL PIT_RadiusAttack (AActor *thing)
|
|||
{
|
||||
points = points * splashfactor;
|
||||
}
|
||||
if (thing->player && gameinfo.gametype == GAME_Hexen)
|
||||
{
|
||||
points = points * 0.25f;
|
||||
}
|
||||
points *= thing->GetClass()->Meta.GetMetaFixed(AMETA_RDFactor, FRACUNIT)/(float)FRACUNIT;
|
||||
|
||||
if (points > 0.f && P_CheckSight (thing, bombspot, 1))
|
||||
{ // OK to damage; target is in direct path
|
||||
float momz;
|
||||
|
@ -3569,14 +3567,15 @@ BOOL PIT_RadiusAttack (AActor *thing)
|
|||
{ // OK to damage; target is in direct path
|
||||
int damage = Scale (bombdamage, bombdistance-dist, bombdistance);
|
||||
damage = (int)((float)damage * splashfactor);
|
||||
if (thing->player && gameinfo.gametype == GAME_Hexen)
|
||||
|
||||
damage = Scale(damage, thing->GetClass()->Meta.GetMetaFixed(AMETA_RDFactor, FRACUNIT), FRACUNIT);
|
||||
if (damage > 0)
|
||||
{
|
||||
damage >>= 2;
|
||||
}
|
||||
P_DamageMobj (thing, bombspot, bombsource, damage, bombmod);
|
||||
P_TraceBleed (damage, thing, bombspot);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1313,7 +1313,7 @@ void P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
|
|||
// that large thrusts can't propel an actor through a wall, because wall
|
||||
// running depends on the player's original movement continuing even after
|
||||
// it gets blocked.
|
||||
if (mo->player != NULL && (compatflags & COMPATF_WALLRUN) || (mo->waterlevel >= 1) ||
|
||||
if (mo->player != NULL && (i_compatflags & COMPATF_WALLRUN) || (mo->waterlevel >= 1) ||
|
||||
(mo->player != NULL && mo->player->crouchfactor < FRACUNIT*3/4))
|
||||
{
|
||||
// preserve the direction instead of clamping x and y independently.
|
||||
|
@ -1456,7 +1456,7 @@ void P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
|
|||
{
|
||||
mo->momz = WATER_JUMP_SPEED;
|
||||
}
|
||||
if (player && (compatflags & COMPATF_WALLRUN))
|
||||
if (player && (i_compatflags & COMPATF_WALLRUN))
|
||||
{
|
||||
// [RH] Here is the key to wall running: The move is clipped using its full speed.
|
||||
// If the move is done a second time (because it was too fast for one move), it
|
||||
|
@ -1474,7 +1474,7 @@ void P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!player || !(compatflags & COMPATF_WALLRUN))
|
||||
if (!player || !(i_compatflags & COMPATF_WALLRUN))
|
||||
{
|
||||
xmove = mo->momx;
|
||||
ymove = mo->momy;
|
||||
|
@ -2595,7 +2595,7 @@ void AActor::Tick ()
|
|||
scrolltype <= Scroll_SouthWest_Fast)
|
||||
{ // Hexen scroll special
|
||||
scrolltype -= Scroll_North_Slow;
|
||||
if (compatflags&COMPATF_RAVENSCROLL)
|
||||
if (i_compatflags&COMPATF_RAVENSCROLL)
|
||||
{
|
||||
angle_t fineangle = HexenScrollDirs[scrolltype / 3] * 32;
|
||||
fixed_t carryspeed = DivScale32 (HexenSpeedMuls[scrolltype % 3], 32*CARRYFACTOR);
|
||||
|
@ -2615,7 +2615,7 @@ void AActor::Tick ()
|
|||
scrolltype -= Carry_East5;
|
||||
byte dir = HereticScrollDirs[scrolltype / 5];
|
||||
fixed_t carryspeed = DivScale32 (HereticSpeedMuls[scrolltype % 5], 32*CARRYFACTOR);
|
||||
if (scrolltype<=Carry_East35 && !(compatflags&COMPATF_RAVENSCROLL))
|
||||
if (scrolltype<=Carry_East35 && !(i_compatflags&COMPATF_RAVENSCROLL))
|
||||
{
|
||||
// Use speeds that actually match the scrolling textures!
|
||||
carryspeed = (1 << ((scrolltype%5) + FRACBITS-1));
|
||||
|
@ -2625,7 +2625,7 @@ void AActor::Tick ()
|
|||
}
|
||||
else if (scrolltype == dScroll_EastLavaDamage)
|
||||
{ // Special Heretic scroll special
|
||||
if (compatflags&COMPATF_RAVENSCROLL)
|
||||
if (i_compatflags&COMPATF_RAVENSCROLL)
|
||||
{
|
||||
scrollx += DivScale32 (28, 32*CARRYFACTOR);
|
||||
}
|
||||
|
@ -2762,7 +2762,7 @@ void AActor::Tick ()
|
|||
(z - FloatBobOffsets[(FloatBobPhase + level.maptime) & 63] != floorz)
|
||||
)))
|
||||
{ // Handle Z momentum and gravity
|
||||
if (((flags2 & MF2_PASSMOBJ) || (flags & MF_SPECIAL)) && !(compatflags & COMPATF_NO_PASSMOBJ))
|
||||
if (((flags2 & MF2_PASSMOBJ) || (flags & MF_SPECIAL)) && !(i_compatflags & COMPATF_NO_PASSMOBJ))
|
||||
{
|
||||
if (!(onmo = P_CheckOnmobj (this)))
|
||||
{
|
||||
|
|
|
@ -451,7 +451,7 @@ fixed_t sector_t::FindHighestCeilingSurrounding (vertex_t **v) const
|
|||
|
||||
static inline void CheckShortestTex (int texnum, fixed_t &minsize)
|
||||
{
|
||||
if (texnum > 0 || (texnum == 0 && (compatflags & COMPATF_SHORTTEX)))
|
||||
if (texnum > 0 || (texnum == 0 && (i_compatflags & COMPATF_SHORTTEX)))
|
||||
{
|
||||
FTexture *tex = TexMan[texnum];
|
||||
int yscale = tex->ScaleY ? tex->ScaleY : 8;
|
||||
|
|
|
@ -150,7 +150,7 @@ bool P_Thing_Move (int tid, int mapspot, bool fog)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool P_Thing_Projectile (int tid, int type, angle_t angle,
|
||||
bool P_Thing_Projectile (int tid, int type, const char * type_name, angle_t angle,
|
||||
fixed_t speed, fixed_t vspeed, int dest, AActor *forcedest, int gravity, int newtid,
|
||||
bool leadTarget)
|
||||
{
|
||||
|
@ -161,11 +161,19 @@ bool P_Thing_Projectile (int tid, int type, angle_t angle,
|
|||
float fspeed = float(speed);
|
||||
int defflags3;
|
||||
|
||||
if (type_name == NULL)
|
||||
{
|
||||
if (type >= MAX_SPAWNABLES)
|
||||
return false;
|
||||
|
||||
if ((kind = SpawnableThings[type]) == NULL)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((kind = PClass::FindClass(type_name)) == NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
defflags3 = GetDefaultByType (kind)->flags3;
|
||||
if ((defflags3 & MF3_ISMONSTER) && (dmflags & DF_NO_MONSTERS))
|
||||
|
|
|
@ -171,7 +171,7 @@ static BOOL PTR_TraceIterator (intercept_t *in)
|
|||
|
||||
// For backwards compatibility: Ignore lines with the same sector on both sides.
|
||||
// This is the way Doom.exe did it and some WADs (e.g. Alien Vendetta MAP15 needs it.
|
||||
if (compatflags & COMPATF_TRACE)
|
||||
if (i_compatflags & COMPATF_TRACE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -624,13 +624,13 @@ static void S_StartSound (fixed_t *pt, AActor *mover, int channel,
|
|||
{
|
||||
pt = NULL;
|
||||
}
|
||||
if (compatflags & COMPATF_MAGICSILENCE)
|
||||
if (i_compatflags & COMPATF_MAGICSILENCE)
|
||||
{ // For people who just can't play without a silent BFG.
|
||||
channel = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((channel & CHAN_MAYBE_LOCAL) && (compatflags & COMPATF_SILENTPICKUP))
|
||||
if ((channel & CHAN_MAYBE_LOCAL) && (i_compatflags & COMPATF_SILENTPICKUP))
|
||||
{
|
||||
if (mover != 0 && mover != players[consoleplayer].camera)
|
||||
{
|
||||
|
@ -1108,7 +1108,7 @@ void S_StopSound (fixed_t *pt, int channel)
|
|||
{
|
||||
if (Channel[i].sfxinfo &&
|
||||
((pt == NULL && Channel[i].pt == &Channel[i].x) || Channel[i].pt == pt) &&
|
||||
((compatflags & COMPATF_MAGICSILENCE) || Channel[i].entchannel == channel))
|
||||
((i_compatflags & COMPATF_MAGICSILENCE) || Channel[i].entchannel == channel))
|
||||
{
|
||||
S_StopChannel (i);
|
||||
}
|
||||
|
@ -1208,7 +1208,7 @@ bool S_IsActorPlayingSomething (AActor *actor, int channel)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (compatflags & COMPATF_MAGICSILENCE)
|
||||
if (i_compatflags & COMPATF_MAGICSILENCE)
|
||||
{
|
||||
channel = 0;
|
||||
}
|
||||
|
|
|
@ -2954,6 +2954,15 @@ static void ActorFastSpeed (AActor *defaults, Baggage &bag)
|
|||
bag.Info->Class->Meta.SetMetaFixed (AMETA_FastSpeed, fixed_t(sc_Float*FRACUNIT));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
static void ActorRadiusDamageFactor (AActor *defaults, Baggage &bag)
|
||||
{
|
||||
SC_MustGetFloat();
|
||||
bag.Info->Class->Meta.SetMetaFixed (AMETA_RDFactor, fixed_t(sc_Float*FRACUNIT));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
@ -3572,6 +3581,7 @@ static const ActorProps props[] =
|
|||
{ "projectile", ActorProjectile, RUNTIME_CLASS(AActor) },
|
||||
{ "puzzleitem.number", (apf)PuzzleitemNumber, RUNTIME_CLASS(APuzzleItem) },
|
||||
{ "radius", ActorRadius, RUNTIME_CLASS(AActor) },
|
||||
{ "radiusdamagefactor", ActorRadiusDamageFactor, RUNTIME_CLASS(AActor) },
|
||||
{ "raise", ActorRaiseState, RUNTIME_CLASS(AActor) },
|
||||
{ "reactiontime", ActorReactionTime, RUNTIME_CLASS(AActor) },
|
||||
{ "renderstyle", ActorRenderStyle, RUNTIME_CLASS(AActor) },
|
||||
|
|
Loading…
Reference in a new issue