mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 05:51:20 +00:00
- Added Gez's Skulltag feature patch, including:
* BUMPSPECIAL flag: actors with this flag will run their special if collided on by a player * WEAPON.NOAUTOAIM flag, though it is restricted to attacks that spawn a missile (it will not affect autoaim settings for a hitscan or railgun, and that's deliberate) * A_FireSTGrenade codepointer, extended to be parameterizable * The grenade (as the default actor for A_FireSTGrenade) * Protective armors à la RedArmor: they work with a DamageFactor; for example to recreate the RedArmor from Skulltag, copy its code from skulltag.pk3 but remove the "native" keyword and add DamageFactor "Fire" 0.1 to its properties. SVN r1661 (trunk)
This commit is contained in:
parent
4fcd64d2c1
commit
523cf6acb2
17 changed files with 154 additions and 23 deletions
|
@ -1,4 +1,13 @@
|
|||
June 9, 2009 (Changes by Graf Zahl)
|
||||
- Added Gez's Skulltag feature patch, including:
|
||||
* BUMPSPECIAL flag: actors with this flag will run their special if collided on by a player
|
||||
* WEAPON.NOAUTOAIM flag, though it is restricted to attacks that spawn a missile (it will
|
||||
not affect autoaim settings for a hitscan or railgun, and that's deliberate)
|
||||
* A_FireSTGrenade codepointer, extended to be parameterizable
|
||||
* The grenade (as the default actor for A_FireSTGrenade)
|
||||
* Protective armors à la RedArmor: they work with a DamageFactor; for example to
|
||||
recreate the RedArmor from Skulltag, copy its code from skulltag.pk3 but remove
|
||||
the "native" keyword and add DamageFactor "Fire" 0.1 to its properties.
|
||||
- Fixed: I_ShutdownInput must NULL all pointers because it can be called twice
|
||||
if an ENDOOM screen is displayed.
|
||||
- Fixed: R_DrawSkyStriped used frontyScale without initializing it first.
|
||||
|
|
|
@ -309,6 +309,7 @@ enum
|
|||
MF6_MTHRUSPECIES = 0x00000004, // Missile passes through actors of its shooter's species.
|
||||
MF6_FORCEPAIN = 0x00000008, // forces target into painstate (unless it has the NOPAIN flag)
|
||||
MF6_NOFEAR = 0x00000010, // Not scared of frightening players
|
||||
MF6_BUMPSPECIAL = 0x00000020, // Actor executes its special when being collided (as the ST flag)
|
||||
|
||||
|
||||
// --- mobj.renderflags ---
|
||||
|
|
|
@ -361,6 +361,34 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMissile)
|
|||
P_SpawnPlayerMissile (self, PClass::FindClass("Rocket"));
|
||||
}
|
||||
|
||||
//
|
||||
// A_FireSTGrenade: not exactly backported from ST, but should work the same
|
||||
//
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireSTGrenade)
|
||||
{
|
||||
player_t *player;
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_CLASS(grenade, 0);
|
||||
if (grenade == NULL) return;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
}
|
||||
|
||||
// Temporarily raise the pitch to send the grenade slightly upwards
|
||||
fixed_t SavedPlayerPitch = self->pitch;
|
||||
self->pitch -= (1152 << FRACBITS);
|
||||
P_SpawnPlayerMissile(self, grenade);
|
||||
self->pitch = SavedPlayerPitch;
|
||||
}
|
||||
|
||||
//
|
||||
// A_FirePlasma
|
||||
//
|
||||
|
|
|
@ -139,6 +139,7 @@ void ABasicArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
|||
{
|
||||
// The armor has become useless
|
||||
SavePercent = 0;
|
||||
ArmorType = NAME_None; // Not NAME_BasicArmor.
|
||||
// Now see if the player has some more armor in their inventory
|
||||
// and use it if so. As in Strife, the best armor is used up first.
|
||||
ABasicArmorPickup *best = NULL;
|
||||
|
@ -162,6 +163,24 @@ void ABasicArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
|
|||
}
|
||||
damage = newdamage;
|
||||
}
|
||||
|
||||
// Once the armor has absorbed its part of the damage, then apply its damage factor, if any, to the player
|
||||
if ((damage > 0) && (ArmorType != NAME_None)) // BasicArmor is not going to have any damage factor, so skip it.
|
||||
{
|
||||
// This code is taken and adapted from APowerProtection::ModifyDamage().
|
||||
// The differences include not checking for the NAME_None key (doesn't seem appropriate here),
|
||||
// not using a default value, and of course the way the damage factor info is obtained.
|
||||
const fixed_t *pdf = NULL;
|
||||
DmgFactors *df = PClass::FindClass(ArmorType)->ActorInfo->DamageFactors;
|
||||
if (df != NULL && df->CountUsed() != 0)
|
||||
{
|
||||
pdf = df->CheckKey(damageType);
|
||||
if (pdf != NULL)
|
||||
{
|
||||
damage = newdamage = FixedMul(damage, *pdf);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Inventory != NULL)
|
||||
{
|
||||
Inventory->AbsorbDamage (damage, damageType, newdamage);
|
||||
|
|
|
@ -1387,7 +1387,7 @@ IMPLEMENT_CLASS (AHealth)
|
|||
|
||||
//===========================================================================
|
||||
//
|
||||
// AHealth :: TryPickup
|
||||
// AHealth :: PickupMessage
|
||||
//
|
||||
//===========================================================================
|
||||
const char *AHealth::PickupMessage ()
|
||||
|
|
|
@ -317,9 +317,10 @@ enum
|
|||
WIF_POWERED_UP = 0x00000400, // this is a tome-of-power'ed version of its sister
|
||||
WIF_AMMO_CHECKBOTH = 0x00000800, // check for both primary and secondary fire before switching it off
|
||||
WIF_NO_AUTO_SWITCH = 0x00001000, // never switch to this weapon when it's picked up
|
||||
WIF_STAFF2_KICKBACK = 0x00002000, // the powered-up Heretic staff has special kickba
|
||||
WIF_STAFF2_KICKBACK = 0x00002000, // the powered-up Heretic staff has special kickback
|
||||
WIF_NOAUTOAIM = 0x00004000, // this weapon never uses autoaim (useful for ballistic projectiles)
|
||||
|
||||
WIF_CHEATNOTWEAPON = 1<<27, // Give cheat considers this not a weapon (used by Sigil)
|
||||
WIF_CHEATNOTWEAPON = 0x08000000, // Give cheat considers this not a weapon (used by Sigil)
|
||||
|
||||
// Flags used only by bot AI:
|
||||
|
||||
|
|
|
@ -2957,7 +2957,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
|
|||
{
|
||||
FName p(FBehavior::StaticLookupString(args[0]));
|
||||
ABasicArmor * armor = (ABasicArmor *) players[args[1]].mo->FindInventory(NAME_BasicArmor);
|
||||
if (armor->ArmorType == p) return 1;
|
||||
if (armor && armor->ArmorType == p) return armor->Amount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -826,6 +826,13 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
// Check for players touching a thing with MF6_BUMPSPECIAL
|
||||
// A blind recreation of what the Skulltag code is probably like.
|
||||
if (tm.thing->player && (thing->flags6 & MF6_BUMPSPECIAL) && thing->special)
|
||||
{
|
||||
LineSpecials[thing->special] (NULL, tm.thing, false, thing->args[0],
|
||||
thing->args[1], thing->args[2], thing->args[3], thing->args[4]);
|
||||
}
|
||||
// Check for missile
|
||||
if (tm.thing->flags & MF_MISSILE)
|
||||
{
|
||||
|
|
|
@ -4999,21 +4999,30 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z,
|
|||
AActor *linetarget;
|
||||
int vrange = nofreeaim? ANGLE_1*35 : 0;
|
||||
|
||||
// see which target is to be aimed at
|
||||
i = 2;
|
||||
do
|
||||
// Note: NOAUTOAIM is implemented only here, and not in the hitscan or rail attack functions.
|
||||
// That is because it is only justified for projectiles affected by gravity, not for other attacks.
|
||||
if (source && source->player && source->player->ReadyWeapon && (source->player->ReadyWeapon->WeaponFlags & WIF_NOAUTOAIM))
|
||||
{
|
||||
an = angle + angdiff[i];
|
||||
pitch = P_AimLineAttack (source, an, 16*64*FRACUNIT, &linetarget, vrange);
|
||||
|
||||
if (source->player != NULL &&
|
||||
!nofreeaim &&
|
||||
level.IsFreelookAllowed() &&
|
||||
source->player->userinfo.GetAimDist() <= ANGLE_1/2)
|
||||
// Keep exactly the same angle and pitch as the player's own aim
|
||||
pitch = source->pitch; linetarget = NULL;
|
||||
}
|
||||
else // see which target is to be aimed at
|
||||
{
|
||||
i = 2;
|
||||
do
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (linetarget == NULL && --i >= 0);
|
||||
an = angle + angdiff[i];
|
||||
pitch = P_AimLineAttack (source, an, 16*64*FRACUNIT, &linetarget, vrange);
|
||||
|
||||
if (source->player != NULL &&
|
||||
!nofreeaim &&
|
||||
level.IsFreelookAllowed() &&
|
||||
source->player->userinfo.GetAimDist() <= ANGLE_1/2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (linetarget == NULL && --i >= 0);
|
||||
}
|
||||
|
||||
if (linetarget == NULL)
|
||||
{
|
||||
|
|
|
@ -535,12 +535,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfArmorType)
|
|||
ACTION_PARAM_START(3);
|
||||
ACTION_PARAM_NAME(Type, 0);
|
||||
ACTION_PARAM_STATE(JumpOffset, 1);
|
||||
ACTION_PARAM_INT(amount, 1);
|
||||
|
||||
ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains!
|
||||
|
||||
ABasicArmor * armor = (ABasicArmor *) self->FindInventory(NAME_BasicArmor);
|
||||
|
||||
if (armor && armor->ArmorType == Type)
|
||||
if (armor && armor->ArmorType == Type && armor->Amount >= amount)
|
||||
ACTION_JUMP(JumpOffset);
|
||||
}
|
||||
|
||||
|
|
|
@ -214,6 +214,7 @@ static FFlagDef ActorFlags[]=
|
|||
DEFINE_FLAG(MF6, MTHRUSPECIES, AActor, flags6),
|
||||
DEFINE_FLAG(MF6, FORCEPAIN, AActor, flags6),
|
||||
DEFINE_FLAG(MF6, NOFEAR, AActor, flags6),
|
||||
DEFINE_FLAG(MF6, BUMPSPECIAL, AActor, flags6),
|
||||
|
||||
// Effect flags
|
||||
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
|
||||
|
@ -234,9 +235,12 @@ static FFlagDef ActorFlags[]=
|
|||
DEFINE_DEPRECATED_FLAG(HERETICBOUNCE),
|
||||
DEFINE_DEPRECATED_FLAG(HEXENBOUNCE),
|
||||
DEFINE_DEPRECATED_FLAG(DOOMBOUNCE),
|
||||
DEFINE_DUMMY_FLAG(NONETID),
|
||||
DEFINE_DUMMY_FLAG(ALLOWCLIENTSPAWN),
|
||||
DEFINE_DUMMY_FLAG(CLIENTSIDEONLY),
|
||||
|
||||
// Various Skulltag flags that are quite irrelevant to ZDoom
|
||||
DEFINE_DUMMY_FLAG(NONETID), // netcode-based
|
||||
DEFINE_DUMMY_FLAG(ALLOWCLIENTSPAWN), // netcode-based
|
||||
DEFINE_DUMMY_FLAG(CLIENTSIDEONLY), // netcode-based
|
||||
DEFINE_DUMMY_FLAG(EXPLODEONDEATH), // seems useless
|
||||
};
|
||||
|
||||
static FFlagDef InventoryFlags[] =
|
||||
|
@ -281,6 +285,7 @@ static FFlagDef WeaponFlags[] =
|
|||
DEFINE_FLAG(WIF, CHEATNOTWEAPON, AWeapon, WeaponFlags),
|
||||
DEFINE_FLAG(WIF, NO_AUTO_SWITCH, AWeapon, WeaponFlags),
|
||||
DEFINE_FLAG(WIF, AMMO_CHECKBOTH, AWeapon, WeaponFlags),
|
||||
DEFINE_FLAG(WIF, NOAUTOAIM, AWeapon, WeaponFlags),
|
||||
|
||||
DEFINE_DUMMY_FLAG(NOLMS),
|
||||
};
|
||||
|
|
|
@ -60,7 +60,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def);
|
|||
//
|
||||
// ParseParameter
|
||||
//
|
||||
// Parses aparameter - either a default in a function declaration
|
||||
// Parses a parameter - either a default in a function declaration
|
||||
// or an argument in a function call.
|
||||
//
|
||||
//==========================================================================
|
||||
|
|
|
@ -1262,6 +1262,14 @@ DEFINE_CLASS_PROPERTY(pickupsound, S, Inventory)
|
|||
defaults->PickupSound = str;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
// Dummy for Skulltag compatibility...
|
||||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY(pickupannouncerentry, S, Inventory)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
|
|
@ -176,7 +176,7 @@ ACTOR Actor native //: Thinker
|
|||
action native A_JumpIfHealthLower(int health, state label);
|
||||
action native A_JumpIfCloser(float distance, state label);
|
||||
action native A_JumpIfInventory(class<Inventory> itemtype, int itemamount, state label);
|
||||
action native A_JumpIfArmorType(string Type, state label);
|
||||
action native A_JumpIfArmorType(string Type, state label, int amount = 1);
|
||||
action native A_GiveInventory(class<Inventory> itemtype, int amount = 0);
|
||||
action native A_TakeInventory(class<Inventory> itemtype, int amount = 0);
|
||||
action native A_SpawnItem(class<Actor> itemtype, float distance = 0, float zheight = 0, bool useammo = true, bool transfer_translation = false);
|
||||
|
|
|
@ -340,6 +340,45 @@ ACTOR Rocket
|
|||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
//
|
||||
// Grenade -- Taken and adapted from Skulltag
|
||||
//
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
ACTOR Grenade
|
||||
{
|
||||
SpawnID 216
|
||||
Radius 8
|
||||
Height 8
|
||||
Speed 25
|
||||
Damage 20
|
||||
Projectile
|
||||
-NOGRAVITY
|
||||
+RANDOMIZE
|
||||
+DEHEXPLOSION
|
||||
+GRENADETRAIL
|
||||
BounceType "Doom"
|
||||
Gravity 0.25
|
||||
SeeSound "weapons/grenlf"
|
||||
DeathSound "weapons/grenlx"
|
||||
BounceSound "weapons/grbnce"
|
||||
Obituary "$OB_GRENADE"
|
||||
DamageType Grenade
|
||||
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
SGRN A 1 Bright
|
||||
Loop
|
||||
Death:
|
||||
MISL B 8 Bright A_Explode
|
||||
MISL C 6 Bright
|
||||
MISL D 4 Bright
|
||||
Stop
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
//
|
||||
// Plasma rifle
|
||||
|
|
|
@ -25,6 +25,7 @@ ACTOR Inventory native
|
|||
action native A_LoadShotgun2();
|
||||
action native A_CloseShotgun2();
|
||||
action native A_FireCGun();
|
||||
action native A_FireSTGrenade(class<Actor> grenadetype = "Grenade");
|
||||
action native A_FireMissile();
|
||||
action native A_FirePlasma();
|
||||
action native A_FireRailgun();
|
||||
|
|
|
@ -201,6 +201,9 @@ weapons/plasmax dsfirxpl
|
|||
weapons/bfgf dsbfg
|
||||
weapons/bfgx dsrxplod
|
||||
weapons/railgf railgf1
|
||||
weapons/grbnce dsbounce
|
||||
weapons/grenlx dsgrnexp
|
||||
weapons/grenlf dsglaunc
|
||||
|
||||
// Problem: weapons/rocklx needs to be unlimited but
|
||||
// is also used for the MAP30 brain explosion.
|
||||
|
|
Loading…
Reference in a new issue