mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-27 14:22:13 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
4d34e0f548
10 changed files with 190 additions and 69 deletions
|
@ -985,6 +985,9 @@ public:
|
|||
FNameNoInit DeathType;
|
||||
const PClass *TeleFogSourceType;
|
||||
const PClass *TeleFogDestType;
|
||||
int RipperLevel;
|
||||
int RipLevelMin;
|
||||
int RipLevelMax;
|
||||
|
||||
FState *SpawnState;
|
||||
FState *SeeState;
|
||||
|
|
|
@ -529,24 +529,26 @@ bool P_MorphedDeath(AActor *actor, AActor **morphed, int *morphedstyle, int *mor
|
|||
{
|
||||
AMorphedMonster *fakeme = static_cast<AMorphedMonster *>(actor);
|
||||
AActor *realme = fakeme->UnmorphedMe;
|
||||
if ((fakeme->UnmorphTime) &&
|
||||
(fakeme->MorphStyle & MORPH_UNDOBYDEATH) &&
|
||||
(realme))
|
||||
if (realme != NULL)
|
||||
{
|
||||
int realstyle = fakeme->MorphStyle;
|
||||
int realhealth = fakeme->health;
|
||||
if (P_UndoMonsterMorph(fakeme, !!(fakeme->MorphStyle & MORPH_UNDOBYDEATHFORCED)))
|
||||
if ((fakeme->UnmorphTime) &&
|
||||
(fakeme->MorphStyle & MORPH_UNDOBYDEATH))
|
||||
{
|
||||
*morphed = realme;
|
||||
*morphedstyle = realstyle;
|
||||
*morphedhealth = realhealth;
|
||||
return true;
|
||||
int realstyle = fakeme->MorphStyle;
|
||||
int realhealth = fakeme->health;
|
||||
if (P_UndoMonsterMorph(fakeme, !!(fakeme->MorphStyle & MORPH_UNDOBYDEATHFORCED)))
|
||||
{
|
||||
*morphed = realme;
|
||||
*morphedstyle = realstyle;
|
||||
*morphedhealth = realhealth;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (realme->flags4 & MF4_BOSSDEATH)
|
||||
{
|
||||
realme->health = 0; // make sure that A_BossDeath considers it dead.
|
||||
CALL_ACTION(A_BossDeath, realme);
|
||||
}
|
||||
}
|
||||
if (realme->flags4 & MF4_BOSSDEATH)
|
||||
{
|
||||
realme->health = 0; // make sure that A_BossDeath considers it dead.
|
||||
CALL_ACTION(A_BossDeath, realme);
|
||||
}
|
||||
fakeme->flags3 |= MF3_STAYMORPHED; // moved here from AMorphedMonster::Die()
|
||||
return false;
|
||||
|
|
|
@ -133,7 +133,7 @@ enum EPuffFlags
|
|||
PF_NORANDOMZ = 16
|
||||
};
|
||||
|
||||
AActor *P_SpawnPuff (AActor *source, const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags = 0);
|
||||
AActor *P_SpawnPuff (AActor *source, const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags = 0, AActor *vict = NULL);
|
||||
void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator);
|
||||
void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator);
|
||||
void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator);
|
||||
|
|
|
@ -887,6 +887,20 @@ bool PIT_CheckLine(line_t *ld, const FBoundingBox &box, FCheckPosition &tm)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Isolated to keep the code readable and fix the logic
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static bool CheckRipLevel(AActor *victim, AActor *projectile)
|
||||
{
|
||||
if (victim->RipLevelMin > 0 && projectile->RipperLevel < victim->RipLevelMin) return false;
|
||||
if (victim->RipLevelMax > 0 && projectile->RipperLevel > victim->RipLevelMax) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PIT_CheckThing
|
||||
|
@ -1207,7 +1221,8 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
|
|||
{
|
||||
return true;
|
||||
}
|
||||
if (tm.DoRipping && !(thing->flags5 & MF5_DONTRIP))
|
||||
|
||||
if ((tm.DoRipping && !(thing->flags5 & MF5_DONTRIP)) && CheckRipLevel(thing, tm.thing))
|
||||
{
|
||||
if (!(tm.thing->flags6 & MF6_NOBOSSRIP) || !(thing->flags2 & MF2_BOSS))
|
||||
{
|
||||
|
@ -3761,14 +3776,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
|
|||
puffFlags |= PF_HITTHINGBLEED;
|
||||
|
||||
// We must pass the unreplaced puff type here
|
||||
puff = P_SpawnPuff(t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags | PF_HITTHING);
|
||||
}
|
||||
|
||||
if (puffDefaults != NULL && trace.Actor != NULL && puff != NULL)
|
||||
{
|
||||
if (puffDefaults->flags7 && MF7_HITTARGET) puff->target = trace.Actor;
|
||||
if (puffDefaults->flags7 && MF7_HITMASTER) puff->master = trace.Actor;
|
||||
if (puffDefaults->flags7 && MF7_HITTRACER) puff->tracer = trace.Actor;
|
||||
puff = P_SpawnPuff(t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags | PF_HITTHING, trace.Actor);
|
||||
}
|
||||
|
||||
// Allow puffs to inflict poison damage, so that hitscans can poison, too.
|
||||
|
@ -4211,14 +4219,9 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
|
|||
}
|
||||
if (spawnpuff)
|
||||
{
|
||||
P_SpawnPuff(source, puffclass, x, y, z, (source->angle + angleoffset) - ANG90, 1, puffflags);
|
||||
}
|
||||
if (hitactor != NULL && puffDefaults != NULL && thepuff != NULL)
|
||||
{
|
||||
if (puffDefaults->flags7 & MF7_HITTARGET) thepuff->target = hitactor;
|
||||
if (puffDefaults->flags7 & MF7_HITMASTER) thepuff->master = hitactor;
|
||||
if (puffDefaults->flags7 & MF7_HITTRACER) thepuff->tracer = hitactor;
|
||||
P_SpawnPuff(source, puffclass, x, y, z, (source->angle + angleoffset) - ANG90, 1, puffflags, hitactor);
|
||||
}
|
||||
|
||||
if (puffDefaults && puffDefaults->PoisonDamage > 0 && puffDefaults->PoisonDuration != INT_MIN)
|
||||
{
|
||||
P_PoisonMobj(hitactor, thepuff ? thepuff : source, source, puffDefaults->PoisonDamage, puffDefaults->PoisonDuration, puffDefaults->PoisonPeriod, puffDefaults->PoisonDamageType);
|
||||
|
|
|
@ -338,6 +338,13 @@ void AActor::Serialize (FArchive &arc)
|
|||
arc << TeleFogSourceType
|
||||
<< TeleFogDestType;
|
||||
}
|
||||
if (SaveVersion >= 4518)
|
||||
{
|
||||
arc << RipperLevel
|
||||
<< RipLevelMin
|
||||
<< RipLevelMax;
|
||||
}
|
||||
|
||||
{
|
||||
FString tagstr;
|
||||
if (arc.IsStoring() && Tag != NULL && Tag->Len() > 0) tagstr = *Tag;
|
||||
|
@ -1961,48 +1968,50 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
|
|||
// Don't change the angle if there's THRUREFLECT on the monster.
|
||||
if (!(BlockingMobj->flags7 & MF7_THRUREFLECT))
|
||||
{
|
||||
int dir;
|
||||
angle_t delta;
|
||||
|
||||
if (BlockingMobj->flags7 & MF7_MIRRORREFLECT)
|
||||
angle = mo->angle + ANG180;
|
||||
else
|
||||
angle = R_PointToAngle2(BlockingMobj->x, BlockingMobj->y, mo->x, mo->y);
|
||||
|
||||
//int dir;
|
||||
//angle_t delta;
|
||||
bool dontReflect = (mo->AdjustReflectionAngle(BlockingMobj, angle));
|
||||
// Change angle for deflection/reflection
|
||||
// AIMREFLECT calls precedence so make sure not to bother with adjusting here if declared.
|
||||
if (!(BlockingMobj->flags7 & MF7_AIMREFLECT) && (mo->AdjustReflectionAngle(BlockingMobj, angle)))
|
||||
{
|
||||
goto explode;
|
||||
}
|
||||
|
||||
// Reflect the missile along angle
|
||||
if (BlockingMobj->flags7 & MF7_AIMREFLECT)
|
||||
if (!dontReflect)
|
||||
{
|
||||
dir = P_FaceMobj(mo, mo->target, &delta);
|
||||
if (dir)
|
||||
{ // Turn clockwise
|
||||
mo->angle += delta;
|
||||
bool tg = (mo->target != NULL);
|
||||
bool blockingtg = (BlockingMobj->target != NULL);
|
||||
if (BlockingMobj->flags7 & MF7_AIMREFLECT && (tg || blockingtg))
|
||||
{
|
||||
AActor *origin;
|
||||
if (tg)
|
||||
origin = mo->target;
|
||||
else if (blockingtg)
|
||||
origin = BlockingMobj->target;
|
||||
|
||||
float speed = (float)(mo->Speed);
|
||||
//dest->x - source->x
|
||||
FVector3 velocity(origin->x - mo->x, origin->y - mo->y, (origin->z + (origin->height/2)) - mo->z);
|
||||
velocity.Resize(speed);
|
||||
angle = mo->angle >> ANGLETOFINESHIFT;
|
||||
mo->velx = (fixed_t)(velocity.X);
|
||||
mo->vely = (fixed_t)(velocity.Y);
|
||||
mo->velz = (fixed_t)(velocity.Z);
|
||||
/*
|
||||
mo->velx = FixedMul(mo->Speed, finecosine[angle]);
|
||||
mo->vely = FixedMul(mo->Speed, finesine[angle]);
|
||||
mo->velz = -mo->velz;
|
||||
*/
|
||||
}
|
||||
else
|
||||
{ // Turn counter clockwise
|
||||
mo->angle -= delta;
|
||||
{
|
||||
mo->angle = angle;
|
||||
angle >>= ANGLETOFINESHIFT;
|
||||
mo->velx = FixedMul(mo->Speed >> 1, finecosine[angle]);
|
||||
mo->vely = FixedMul(mo->Speed >> 1, finesine[angle]);
|
||||
mo->velz = -mo->velz / 2;
|
||||
}
|
||||
angle = mo->angle >> ANGLETOFINESHIFT;
|
||||
mo->velx = FixedMul(mo->Speed, finecosine[angle]);
|
||||
mo->vely = FixedMul(mo->Speed, finesine[angle]);
|
||||
mo->velz = -mo->velz;
|
||||
}
|
||||
else
|
||||
{
|
||||
mo->angle = angle;
|
||||
angle >>= ANGLETOFINESHIFT;
|
||||
mo->velx = FixedMul(mo->Speed >> 1, finecosine[angle]);
|
||||
mo->vely = FixedMul(mo->Speed >> 1, finesine[angle]);
|
||||
mo->velz = -mo->velz / 2;
|
||||
}
|
||||
|
||||
|
||||
goto explode;
|
||||
}
|
||||
}
|
||||
if (mo->flags2 & MF2_SEEKERMISSILE)
|
||||
{
|
||||
|
@ -2928,8 +2937,10 @@ bool AActor::AdjustReflectionAngle (AActor *thing, angle_t &angle)
|
|||
if (flags2 & MF2_DONTREFLECT) return true;
|
||||
if (thing->flags7 & MF7_THRUREFLECT) return false;
|
||||
|
||||
if (thing->flags7 & MF7_MIRRORREFLECT)
|
||||
angle += ANGLE_180;
|
||||
// Change angle for reflection
|
||||
if (thing->flags4&MF4_SHIELDREFLECT)
|
||||
else if (thing->flags4&MF4_SHIELDREFLECT)
|
||||
{
|
||||
// Shield reflection (from the Centaur
|
||||
if (abs (angle - thing->angle)>>24 > 45)
|
||||
|
@ -2952,6 +2963,13 @@ bool AActor::AdjustReflectionAngle (AActor *thing, angle_t &angle)
|
|||
else
|
||||
angle -= ANG45;
|
||||
}
|
||||
else if (thing->flags7 & MF7_AIMREFLECT)
|
||||
{
|
||||
if (this->target != NULL)
|
||||
A_Face(this, this->target);
|
||||
else if (thing->target != NULL)
|
||||
A_Face(this, thing->target);
|
||||
}
|
||||
else
|
||||
angle += ANGLE_1 * ((pr_reflect()%16)-8);
|
||||
return false;
|
||||
|
@ -4919,7 +4937,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
|
|||
// P_SpawnPuff
|
||||
//
|
||||
|
||||
AActor *P_SpawnPuff (AActor *source, const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags)
|
||||
AActor *P_SpawnPuff (AActor *source, const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags, AActor *vict)
|
||||
{
|
||||
AActor *puff;
|
||||
|
||||
|
@ -4929,9 +4947,17 @@ AActor *P_SpawnPuff (AActor *source, const PClass *pufftype, fixed_t x, fixed_t
|
|||
puff = Spawn (pufftype, x, y, z, ALLOW_REPLACE);
|
||||
if (puff == NULL) return NULL;
|
||||
|
||||
//Moved puff creation and target/master/tracer setting to here.
|
||||
if (puff && vict)
|
||||
{
|
||||
if (puff->flags7 & MF7_HITTARGET) puff->target = vict;
|
||||
if (puff->flags7 & MF7_HITMASTER) puff->master = vict;
|
||||
if (puff->flags7 & MF7_HITTRACER) puff->tracer = vict;
|
||||
}
|
||||
// [BB] If the puff came from a player, set the target of the puff to this player.
|
||||
if ( puff && (puff->flags5 & MF5_PUFFGETSOWNER))
|
||||
puff->target = source;
|
||||
|
||||
|
||||
if (source != NULL) puff->angle = R_PointToAngle2(x, y, source->x, source->y);
|
||||
|
||||
|
|
|
@ -1365,7 +1365,7 @@ void APlayerPawn::Die (AActor *source, AActor *inflictor, int dmgflags)
|
|||
weap->SpawnState != ::GetDefault<AActor>()->SpawnState)
|
||||
{
|
||||
item = P_DropItem (this, weap->GetClass(), -1, 256);
|
||||
if (item != NULL)
|
||||
if (item != NULL && item->IsKindOf(RUNTIME_CLASS(AWeapon)))
|
||||
{
|
||||
if (weap->AmmoGive1 && weap->Ammo1)
|
||||
{
|
||||
|
|
|
@ -5613,3 +5613,45 @@ DEFINE_ACTION_FUNCTION(AActor, A_SwapTeleFog)
|
|||
self->TeleFogDestType = temp;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_SetRipperLevel(int level)
|
||||
//
|
||||
// Sets the ripper level/requirement of the calling actor.
|
||||
// Also sets the minimum and maximum levels to rip through.
|
||||
//===========================================================================
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetRipperLevel)
|
||||
{
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_INT(level, 0);
|
||||
self->RipperLevel = level;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_SetRipMin(int min)
|
||||
//
|
||||
// Sets the ripper level/requirement of the calling actor.
|
||||
// Also sets the minimum and maximum levels to rip through.
|
||||
//===========================================================================
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetRipMin)
|
||||
{
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_INT(min, 1);
|
||||
self->RipLevelMin = min;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_SetRipMin(int min)
|
||||
//
|
||||
// Sets the ripper level/requirement of the calling actor.
|
||||
// Also sets the minimum and maximum levels to rip through.
|
||||
//===========================================================================
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetRipMax)
|
||||
{
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_INT(max, 1);
|
||||
self->RipLevelMax = max;
|
||||
}
|
|
@ -1436,6 +1436,45 @@ DEFINE_PROPERTY(telefogdesttype, S, Actor)
|
|||
else defaults->TeleFogDestType = FindClassTentative(str, "TeleportFog");
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(ripperlevel, I, Actor)
|
||||
{
|
||||
PROP_INT_PARM(id, 0);
|
||||
if (id < 0)
|
||||
{
|
||||
I_Error ("RipperLevel must not be negative");
|
||||
}
|
||||
defaults->RipperLevel = id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(riplevelmin, I, Actor)
|
||||
{
|
||||
PROP_INT_PARM(id, 0);
|
||||
if (id < 0)
|
||||
{
|
||||
I_Error ("RipLevelMin must not be negative");
|
||||
}
|
||||
defaults->RipLevelMin = id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(riplevelmax, I, Actor)
|
||||
{
|
||||
PROP_INT_PARM(id, 0);
|
||||
if (id < 0)
|
||||
{
|
||||
I_Error ("RipLevelMax must not be negative");
|
||||
}
|
||||
defaults->RipLevelMax = id;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Special inventory properties
|
||||
|
|
|
@ -76,7 +76,7 @@ const char *GetVersionString();
|
|||
|
||||
// Use 4500 as the base git save version, since it's higher than the
|
||||
// SVN revision ever got.
|
||||
#define SAVEVER 4517
|
||||
#define SAVEVER 4518
|
||||
|
||||
#define SAVEVERSTRINGIFY2(x) #x
|
||||
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)
|
||||
|
|
|
@ -28,6 +28,9 @@ ACTOR Actor native //: Thinker
|
|||
DeathType Normal
|
||||
TeleFogSourceType "TeleportFog"
|
||||
TeleFogDestType "TeleportFog"
|
||||
RipperLevel 0
|
||||
RipLevelMin 0
|
||||
RipLevelMax 0
|
||||
|
||||
// Variables for the expression evaluator
|
||||
// NOTE: fixed_t and angle_t are only used here to ensure proper conversion
|
||||
|
@ -321,6 +324,9 @@ ACTOR Actor native //: Thinker
|
|||
action native A_TakeFromSiblings(class<Inventory> itemtype, int amount = 0);
|
||||
action native A_SetTeleFog(name oldpos, name newpos);
|
||||
action native A_SwapTeleFog();
|
||||
action native A_SetRipperLevel(int level);
|
||||
action native A_SetRipMin(int min);
|
||||
action native A_SetRipMax(int max);
|
||||
|
||||
action native A_CheckSightOrRange(float distance, state label);
|
||||
action native A_CheckRange(float distance, state label);
|
||||
|
|
Loading…
Reference in a new issue