- Took MF2_WINDTHRUST off AMorphedMonster. This is something that should not

be a default setting.
- Moved a_artiegg.cpp to g_shared and renamed it to a_morph.cpp to better reflect
  its meaning.
- Fixed: AMorphProjectile's PlayerClass and MonsterClass members must be serialized
  as FNames. Serializing them as ints is not safe because name indices are not 
  guaranteed to be the same each time the game is started. Same for APlayerPawn's
  MorphWeapon member.
- Converted EggFX, ArtiEgg, PorkFX and ArtiPork to DECORATE. 
- Added a new parameter to A_FireCustomMissile. Previously it always aimed
  straight ahead and altered the projectile's angle according to the resulting
  direction. If the 6th parameter is 1 now it will aim at the specified angle
  directly.
- Changed custom morphing to be based on a new MorphProjectile class, not
  the Heretic specific EggFX. The EggFX properties are now prefixed with
  'MorphProjectile.'. 


SVN r297 (trunk)
This commit is contained in:
Christoph Oelckers 2006-08-17 09:54:42 +00:00
parent a6d656b108
commit f66b7de8c8
17 changed files with 846 additions and 885 deletions

View file

@ -1,3 +1,21 @@
August 17, 2006 (Changes by Graf Zahl)
- Took MF2_WINDTHRUST off AMorphedMonster. This is something that should not
be a default setting.
- Moved a_artiegg.cpp to g_shared and renamed it to a_morph.cpp to better reflect
its meaning.
- Fixed: AMorphProjectile's PlayerClass and MonsterClass members must be serialized
as FNames. Serializing them as ints is not safe because name indices are not
guaranteed to be the same each time the game is started. Same for APlayerPawn's
MorphWeapon member.
- Converted EggFX, ArtiEgg, PorkFX and ArtiPork to DECORATE.
- Added a new parameter to A_FireCustomMissile. Previously it always aimed
straight ahead and altered the projectile's angle according to the resulting
direction. If the 6th parameter is 1 now it will aim at the specified angle
directly.
- Changed custom morphing to be based on a new MorphProjectile class, not
the Heretic specific EggFX. The EggFX properties are now prefixed with
'MorphProjectile.'.
August 16, 2006 August 16, 2006
- Updated thingdef_specials.h for the new thingdef_specials.gperf file. - Updated thingdef_specials.h for the new thingdef_specials.gperf file.
- Created a new MorphedMonster class that Chicken and Pig now derive from. - Created a new MorphedMonster class that Chicken and Pig now derive from.

View file

@ -10,7 +10,6 @@
#include "a_sharedglobal.h" #include "a_sharedglobal.h"
#include "p_enemy.h" #include "p_enemy.h"
#include "d_event.h" #include "d_event.h"
#include "ravenshared.h"
#include "gstrings.h" #include "gstrings.h"
static FRandom pr_chickenplayerthink ("ChickenPlayerThink"); static FRandom pr_chickenplayerthink ("ChickenPlayerThink");

View file

@ -254,7 +254,6 @@ void A_MummyAttack2 (AActor *actor)
return; return;
} }
mo = P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(AMummyFX1)); mo = P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(AMummyFX1));
//mo = P_SpawnMissile(actor, actor->target, MT_EGGFX);
if (mo != NULL) if (mo != NULL)
{ {
mo->tracer = actor->target; mo->tracer = actor->target;

View file

@ -10,7 +10,6 @@
#include "a_sharedglobal.h" #include "a_sharedglobal.h"
#include "p_enemy.h" #include "p_enemy.h"
#include "d_event.h" #include "d_event.h"
#include "ravenshared.h"
#include "gstrings.h" #include "gstrings.h"
static FRandom pr_snoutattack ("SnoutAttack"); static FRandom pr_snoutattack ("SnoutAttack");

View file

@ -36,29 +36,4 @@ public:
void Serialize (FArchive &arc); void Serialize (FArchive &arc);
}; };
class AEggFX : public AActor
{
DECLARE_ACTOR (AEggFX, AActor)
public:
int DoSpecialDamage (AActor *target, int damage);
void Serialize (FArchive &arc);
int PlayerClass, MonsterClass; // actually names
};
class AMorphedMonster : public AActor
{
DECLARE_ACTOR (AMorphedMonster, AActor)
HAS_OBJECT_POINTERS
public:
void Tick ();
void Serialize (FArchive &arc);
void Die (AActor *source, AActor *inflictor);
void Destroy ();
AActor *UnmorphedMe;
int UnmorphTime;
DWORD FlagsSave;
};
#endif //__RAVENSHARED_H__ #endif //__RAVENSHARED_H__

View file

@ -8,7 +8,6 @@
#include "s_sound.h" #include "s_sound.h"
#include "m_random.h" #include "m_random.h"
#include "a_sharedglobal.h" #include "a_sharedglobal.h"
#include "ravenshared.h"
#define MORPHTICS (40*TICRATE) #define MORPHTICS (40*TICRATE)
@ -291,40 +290,15 @@ bool P_UpdateMorphedMonster (AMorphedMonster *beast)
return true; return true;
} }
// Egg ---------------------------------------------------------------------- // Base class for morphing projectiles --------------------------------------
FState AEggFX::States[] = IMPLEMENT_STATELESS_ACTOR(AMorphProjectile, Any, -1, 0)
{
#define S_EGGFX 0
S_NORMAL (EGGM, 'A', 4, NULL, &States[S_EGGFX+1]),
S_NORMAL (EGGM, 'B', 4, NULL, &States[S_EGGFX+2]),
S_NORMAL (EGGM, 'C', 4, NULL, &States[S_EGGFX+3]),
S_NORMAL (EGGM, 'D', 4, NULL, &States[S_EGGFX+4]),
S_NORMAL (EGGM, 'E', 4, NULL, &States[S_EGGFX+0]),
#define S_EGGFXI1 (S_EGGFX+5)
S_BRIGHT (FX01, 'E', 3, NULL, &States[S_EGGFXI1+1]),
S_BRIGHT (FX01, 'F', 3, NULL, &States[S_EGGFXI1+2]),
S_BRIGHT (FX01, 'G', 3, NULL, &States[S_EGGFXI1+3]),
S_BRIGHT (FX01, 'H', 3, NULL, NULL),
};
IMPLEMENT_ACTOR (AEggFX, Heretic, -1, 40)
PROP_RadiusFixed (8)
PROP_HeightFixed (8)
PROP_SpeedFixed (18)
PROP_Damage (1) PROP_Damage (1)
PROP_Flags (MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY) PROP_Flags (MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY)
PROP_Flags2 (MF2_NOTELEPORT) PROP_Flags2 (MF2_NOTELEPORT)
PROP_SpawnState (S_EGGFX)
PROP_DeathState (S_EGGFXI1)
PROP_EggFX_PlayerClass ("ChickenPlayer")
PROP_EggFX_MonsterClass ("Chicken")
END_DEFAULTS END_DEFAULTS
int AEggFX::DoSpecialDamage (AActor *target, int damage) int AMorphProjectile::DoSpecialDamage (AActor *target, int damage)
{ {
if (target->player) if (target->player)
{ {
@ -337,129 +311,23 @@ int AEggFX::DoSpecialDamage (AActor *target, int damage)
return -1; return -1;
} }
void AEggFX::Serialize (FArchive &arc) void AMorphProjectile::Serialize (FArchive &arc)
{ {
Super::Serialize (arc); Super::Serialize (arc);
arc << PlayerClass << MonsterClass;
// Hack alert: The classes have to be serialized as names.
// But due to the way an actor is constructed they cannot
// be declared as names.
FName PlayerClassName = ENamedName(PlayerClass);
FName MonsterClassName = ENamedName(MonsterClass);
arc << PlayerClassName << MonsterClassName;
PlayerClass = PlayerClassName;
MonsterClass = MonsterClassName;
} }
// Morph Ovum ----------------------------------------------------------------
class AArtiEgg : public AInventory
{
DECLARE_ACTOR (AArtiEgg, AInventory)
public:
bool Use (bool pickup);
};
FState AArtiEgg::States[] =
{
S_NORMAL (EGGC, 'A', 6, NULL, &States[1]),
S_NORMAL (EGGC, 'B', 6, NULL, &States[2]),
S_NORMAL (EGGC, 'C', 6, NULL, &States[3]),
S_NORMAL (EGGC, 'B', 6, NULL, &States[0]),
};
IMPLEMENT_ACTOR (AArtiEgg, Heretic, 30, 14)
PROP_Flags (MF_SPECIAL|MF_COUNTITEM)
PROP_Flags2 (MF2_FLOATBOB)
PROP_SpawnState (0)
PROP_Inventory_DefMaxAmount
PROP_Inventory_FlagsSet (IF_INVBAR|IF_PICKUPFLASH|IF_FANCYPICKUPSOUND)
PROP_Inventory_Icon ("ARTIEGGC")
PROP_Inventory_PickupSound ("misc/p_pkup")
PROP_Inventory_PickupMessage("$TXT_ARTIEGG")
END_DEFAULTS
bool AArtiEgg::Use (bool pickup)
{
P_SpawnPlayerMissile (Owner, RUNTIME_CLASS(AEggFX));
P_SpawnPlayerMissile (Owner, RUNTIME_CLASS(AEggFX), Owner->angle-(ANG45/6));
P_SpawnPlayerMissile (Owner, RUNTIME_CLASS(AEggFX), Owner->angle+(ANG45/6));
P_SpawnPlayerMissile (Owner, RUNTIME_CLASS(AEggFX), Owner->angle-(ANG45/3));
P_SpawnPlayerMissile (Owner, RUNTIME_CLASS(AEggFX), Owner->angle+(ANG45/3));
return true;
}
// Pork missile --------------------------------------------------------------
class APorkFX : public AEggFX
{
DECLARE_ACTOR (APorkFX, AEggFX)
};
FState APorkFX::States[] =
{
//#define S_EGGFX 0
S_NORMAL (PRKM, 'A', 4, NULL, &States[S_EGGFX+1]),
S_NORMAL (PRKM, 'B', 4, NULL, &States[S_EGGFX+2]),
S_NORMAL (PRKM, 'C', 4, NULL, &States[S_EGGFX+3]),
S_NORMAL (PRKM, 'D', 4, NULL, &States[S_EGGFX+4]),
S_NORMAL (PRKM, 'E', 4, NULL, &States[S_EGGFX+0]),
#define S_EGGFXI2 (S_EGGFX+5)
S_BRIGHT (FHFX, 'I', 3, NULL, &States[S_EGGFXI2+1]),
S_BRIGHT (FHFX, 'J', 3, NULL, &States[S_EGGFXI2+2]),
S_BRIGHT (FHFX, 'K', 3, NULL, &States[S_EGGFXI2+3]),
S_BRIGHT (FHFX, 'L', 3, NULL, NULL)
};
IMPLEMENT_ACTOR (APorkFX, Hexen, -1, 40)
PROP_RadiusFixed (8)
PROP_HeightFixed (8)
PROP_SpeedFixed (18)
PROP_Damage (1)
PROP_Flags (MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY)
PROP_Flags2 (MF2_NOTELEPORT)
PROP_SpawnState (S_EGGFX)
PROP_DeathState (S_EGGFXI2)
PROP_EggFX_PlayerClass ("PigPlayer")
PROP_EggFX_MonsterClass ("Pig")
END_DEFAULTS
// Porkalator ---------------------------------------------------------------
class AArtiPork : public AInventory
{
DECLARE_ACTOR (AArtiPork, AInventory)
public:
bool Use (bool pickup);
};
FState AArtiPork::States[] =
{
S_NORMAL (PORK, 'A', 5, NULL, &States[1]),
S_NORMAL (PORK, 'B', 5, NULL, &States[2]),
S_NORMAL (PORK, 'C', 5, NULL, &States[3]),
S_NORMAL (PORK, 'D', 5, NULL, &States[4]),
S_NORMAL (PORK, 'E', 5, NULL, &States[5]),
S_NORMAL (PORK, 'F', 5, NULL, &States[6]),
S_NORMAL (PORK, 'G', 5, NULL, &States[7]),
S_NORMAL (PORK, 'H', 5, NULL, &States[0])
};
IMPLEMENT_ACTOR (AArtiPork, Hexen, 30, 14)
PROP_Flags (MF_SPECIAL|MF_COUNTITEM)
PROP_Flags2 (MF2_FLOATBOB)
PROP_SpawnState (0)
PROP_Inventory_DefMaxAmount
PROP_Inventory_FlagsSet (IF_INVBAR|IF_PICKUPFLASH|IF_FANCYPICKUPSOUND)
PROP_Inventory_Icon ("ARTIPORK")
PROP_Inventory_PickupSound ("misc/p_pkup")
PROP_Inventory_PickupMessage("$TXT_ARTIEGG2")
END_DEFAULTS
bool AArtiPork::Use (bool pickup)
{
P_SpawnPlayerMissile (Owner, RUNTIME_CLASS(APorkFX));
P_SpawnPlayerMissile (Owner, RUNTIME_CLASS(APorkFX), Owner->angle-(ANG45/6));
P_SpawnPlayerMissile (Owner, RUNTIME_CLASS(APorkFX), Owner->angle+(ANG45/6));
P_SpawnPlayerMissile (Owner, RUNTIME_CLASS(APorkFX), Owner->angle-(ANG45/3));
P_SpawnPlayerMissile (Owner, RUNTIME_CLASS(APorkFX), Owner->angle+(ANG45/3));
return true;
}
// Morphed Monster (you must subclass this to do something useful) --------- // Morphed Monster (you must subclass this to do something useful) ---------
@ -469,7 +337,7 @@ END_POINTERS
BEGIN_STATELESS_DEFAULTS (AMorphedMonster, Any, -1, 0) BEGIN_STATELESS_DEFAULTS (AMorphedMonster, Any, -1, 0)
PROP_Flags (MF_SOLID|MF_SHOOTABLE) PROP_Flags (MF_SOLID|MF_SHOOTABLE)
PROP_Flags2 (MF2_MCROSS|MF2_WINDTHRUST|MF2_FLOORCLIP|MF2_PASSMOBJ|MF2_PUSHWALL) PROP_Flags2 (MF2_MCROSS|MF2_FLOORCLIP|MF2_PASSMOBJ|MF2_PUSHWALL)
PROP_Flags3 (MF3_DONTMORPH|MF3_ISMONSTER) PROP_Flags3 (MF3_DONTMORPH|MF3_ISMONSTER)
END_DEFAULTS END_DEFAULTS

View file

@ -204,4 +204,29 @@ private:
DEarthquake (); DEarthquake ();
}; };
class AMorphProjectile : public AActor
{
DECLARE_ACTOR (AMorphProjectile, AActor)
public:
int DoSpecialDamage (AActor *target, int damage);
void Serialize (FArchive &arc);
int PlayerClass, MonsterClass; // really FNames but they would be destroyed by the construction process
};
class AMorphedMonster : public AActor
{
DECLARE_ACTOR (AMorphedMonster, AActor)
HAS_OBJECT_POINTERS
public:
void Tick ();
void Serialize (FArchive &arc);
void Die (AActor *source, AActor *inflictor);
void Destroy ();
AActor *UnmorphedMe;
int UnmorphTime;
DWORD FlagsSave;
};
#endif //__A_SHAREDGLOBAL_H__ #endif //__A_SHAREDGLOBAL_H__

View file

@ -246,9 +246,7 @@ enum
ADEF_PlayerPawn_SoundClass, ADEF_PlayerPawn_SoundClass,
ADEF_PlayerPawn_ScoreIcon, ADEF_PlayerPawn_ScoreIcon,
ADEF_PlayerPawn_MorphWeapon, ADEF_PlayerPawn_MorphWeapon,
ADEF_EggFX_PlayerClass, ADEF_LastString = ADEF_PlayerPawn_MorphWeapon,
ADEF_EggFX_MonsterClass,
ADEF_LastString = ADEF_EggFX_MonsterClass,
// The rest of the properties use their type field (upper 2 bits) // The rest of the properties use their type field (upper 2 bits)
ADEF_XScale, ADEF_XScale,

View file

@ -46,7 +46,6 @@
#include "w_wad.h" #include "w_wad.h"
#include "a_strifeglobal.h" #include "a_strifeglobal.h"
#include "thingdef.h" #include "thingdef.h"
#include "ravenshared.h"
void FActorInfo::BuildDefaults () void FActorInfo::BuildDefaults ()
{ {
@ -130,7 +129,6 @@ static void ApplyActorDefault (int defnum, const char *datastr, int dataint)
ASigil *const sigil = (ASigil *)sgDefaults; ASigil *const sigil = (ASigil *)sgDefaults;
AAmmo *const ammo = (AAmmo *)sgDefaults; AAmmo *const ammo = (AAmmo *)sgDefaults;
APlayerPawn *const player = (APlayerPawn *)sgDefaults; APlayerPawn *const player = (APlayerPawn *)sgDefaults;
AEggFX *const eggfx = (AEggFX *)sgDefaults;
switch (defnum) switch (defnum)
{ {
@ -342,10 +340,6 @@ static void ApplyActorDefault (int defnum, const char *datastr, int dataint)
player->ScoreIcon = TexMan.AddPatch (datastr, ns_sprites); player->ScoreIcon = TexMan.AddPatch (datastr, ns_sprites);
} }
break; break;
case ADEF_EggFX_PlayerClass: eggfx->PlayerClass = FName(datastr); break;
case ADEF_EggFX_MonsterClass: eggfx->MonsterClass = FName(datastr); break;
} }
} }

View file

@ -216,8 +216,6 @@ public:
#define PROP_PlayerPawn_SoundClass(x) ADD_STRING_PROP(ADEF_PlayerPawn_SoundClass,"\26",x) #define PROP_PlayerPawn_SoundClass(x) ADD_STRING_PROP(ADEF_PlayerPawn_SoundClass,"\26",x)
#define PROP_PlayerPawn_ScoreIcon(x) ADD_STRING_PROP(ADEF_PlayerPawn_ScoreIcon,"\27",x) #define PROP_PlayerPawn_ScoreIcon(x) ADD_STRING_PROP(ADEF_PlayerPawn_ScoreIcon,"\27",x)
#define PROP_PlayerPawn_MorphWeapon(x) ADD_STRING_PROP(ADEF_PlayerPawn_MorphWeapon,"\30",x) #define PROP_PlayerPawn_MorphWeapon(x) ADD_STRING_PROP(ADEF_PlayerPawn_MorphWeapon,"\30",x)
#define PROP_EggFX_PlayerClass(x) ADD_STRING_PROP(ADEF_EggFX_PlayerClass,"\31",x)
#define PROP_EggFX_MonsterClass(x) ADD_STRING_PROP(ADEF_EggFX_MonsterClass,"\32",x)
#define PROP_XScale(x) ADD_BYTE_PROP(ADEF_XScale,x) #define PROP_XScale(x) ADD_BYTE_PROP(ADEF_XScale,x)
#define PROP_YScale(x) ADD_BYTE_PROP(ADEF_YScale,x) #define PROP_YScale(x) ADD_BYTE_PROP(ADEF_YScale,x)

View file

@ -400,8 +400,12 @@ void APlayerPawn::Serialize (FArchive &arc)
<< SideMove2 << SideMove2
<< ScoreIcon << ScoreIcon
<< InvFirst << InvFirst
<< InvSel << InvSel;
<< MorphWeapon;
// Serialize the name, not the index
FName MorphWeaponName = ENamedName(MorphWeapon);
arc << MorphWeaponName;
MorphWeapon = MorphWeaponName;
} }
//=========================================================================== //===========================================================================

View file

@ -67,7 +67,7 @@
#include "p_conversation.h" #include "p_conversation.h"
#include "v_text.h" #include "v_text.h"
#include "thingdef.h" #include "thingdef.h"
#include "ravenshared.h" #include "a_sharedglobal.h"
const PClass *QuestItemClasses[31]; const PClass *QuestItemClasses[31];
@ -701,7 +701,7 @@ AFuncDesc AFTable[]=
FUNC(A_JumpIfNoAmmo, "L" ) FUNC(A_JumpIfNoAmmo, "L" )
FUNC(A_CustomPunch, "Xxymx" ) FUNC(A_CustomPunch, "Xxymx" )
FUNC(A_FireBullets, "XXXXmyx" ) FUNC(A_FireBullets, "XXXXmyx" )
FUNC(A_FireCustomMissile, "Mxyxx" ) FUNC(A_FireCustomMissile, "Mxyxxx" )
FUNC(A_RailAttack, "Xxyccxx" ) FUNC(A_RailAttack, "Xxyccxx" )
FUNC(A_Recoil, "X") FUNC(A_Recoil, "X")
FUNC(A_JumpIfInTargetInventory, "MXL" ) FUNC(A_JumpIfInTargetInventory, "MXL" )
@ -3701,7 +3701,7 @@ static void PlayerStartItem (APlayerPawn *defaults, Baggage &bag)
//========================================================================== //==========================================================================
// //
//========================================================================== //==========================================================================
static void EggFXMonsterClass (AEggFX *defaults, Baggage &bag) static void EggFXMonsterClass (AMorphProjectile *defaults, Baggage &bag)
{ {
SC_MustGetString (); SC_MustGetString ();
defaults->MonsterClass = FName(sc_String); defaults->MonsterClass = FName(sc_String);
@ -3710,7 +3710,7 @@ static void EggFXMonsterClass (AEggFX *defaults, Baggage &bag)
//========================================================================== //==========================================================================
// //
//========================================================================== //==========================================================================
static void EggFXPlayerClass (AEggFX *defaults, Baggage &bag) static void EggFXPlayerClass (AMorphProjectile *defaults, Baggage &bag)
{ {
SC_MustGetString (); SC_MustGetString ();
defaults->PlayerClass = FName(sc_String); defaults->PlayerClass = FName(sc_String);
@ -3780,8 +3780,6 @@ static const ActorProps props[] =
{ "disintegrate", ActorDisintegrateState, RUNTIME_CLASS(AActor) }, { "disintegrate", ActorDisintegrateState, RUNTIME_CLASS(AActor) },
{ "donthurtshooter", ActorDontHurtShooter, RUNTIME_CLASS(AActor) }, { "donthurtshooter", ActorDontHurtShooter, RUNTIME_CLASS(AActor) },
{ "dropitem", ActorDropItem, RUNTIME_CLASS(AActor) }, { "dropitem", ActorDropItem, RUNTIME_CLASS(AActor) },
{ "eggfx.playerclass", (apf)EggFXPlayerClass, RUNTIME_CLASS(AEggFX) },
{ "eggfx.monsterclass", (apf)EggFXMonsterClass, RUNTIME_CLASS(AEggFX) },
{ "explosiondamage", ActorExplosionDamage, RUNTIME_CLASS(AActor) }, { "explosiondamage", ActorExplosionDamage, RUNTIME_CLASS(AActor) },
{ "explosionradius", ActorExplosionRadius, RUNTIME_CLASS(AActor) }, { "explosionradius", ActorExplosionRadius, RUNTIME_CLASS(AActor) },
{ "fastspeed", ActorFastSpeed, RUNTIME_CLASS(AActor) }, { "fastspeed", ActorFastSpeed, RUNTIME_CLASS(AActor) },
@ -3815,6 +3813,8 @@ static const ActorProps props[] =
{ "missileheight", ActorMissileHeight, RUNTIME_CLASS(AActor) }, { "missileheight", ActorMissileHeight, RUNTIME_CLASS(AActor) },
{ "missiletype", ActorMissileType, RUNTIME_CLASS(AActor) }, { "missiletype", ActorMissileType, RUNTIME_CLASS(AActor) },
{ "monster", ActorMonster, RUNTIME_CLASS(AActor) }, { "monster", ActorMonster, RUNTIME_CLASS(AActor) },
{ "morphprojectile.monsterclass",(apf)EggFXMonsterClass, RUNTIME_CLASS(AMorphProjectile) },
{ "morphprojectile.playerclass",(apf)EggFXPlayerClass, RUNTIME_CLASS(AMorphProjectile) },
{ "obituary", ActorObituary, RUNTIME_CLASS(AActor) }, { "obituary", ActorObituary, RUNTIME_CLASS(AActor) },
{ "pain", ActorPainState, RUNTIME_CLASS(AActor) }, { "pain", ActorPainState, RUNTIME_CLASS(AActor) },
{ "painchance", ActorPainChance, RUNTIME_CLASS(AActor) }, { "painchance", ActorPainChance, RUNTIME_CLASS(AActor) },

View file

@ -824,7 +824,7 @@ void A_FireBullets (AActor *self)
//========================================================================== //==========================================================================
void A_FireCustomMissile (AActor * self) void A_FireCustomMissile (AActor * self)
{ {
int index=CheckIndex(5); int index=CheckIndex(6);
if (index<0 || !self->player) return; if (index<0 || !self->player) return;
ENamedName MissileName=(ENamedName)StateParameters[index]; ENamedName MissileName=(ENamedName)StateParameters[index];
@ -832,6 +832,7 @@ void A_FireCustomMissile (AActor * self)
bool UseAmmo=EvalExpressionN (StateParameters[index+2], self); bool UseAmmo=EvalExpressionN (StateParameters[index+2], self);
int SpawnOfs_XY=EvalExpressionI (StateParameters[index+3], self); int SpawnOfs_XY=EvalExpressionI (StateParameters[index+3], self);
fixed_t SpawnHeight=fixed_t(EvalExpressionF (StateParameters[index+4], self) * FRACUNIT); fixed_t SpawnHeight=fixed_t(EvalExpressionF (StateParameters[index+4], self) * FRACUNIT);
BOOL AimAtAngle=EvalExpressionI (StateParameters[index+5], self);
player_t *player=self->player; player_t *player=self->player;
AWeapon * weapon=player->ReadyWeapon; AWeapon * weapon=player->ReadyWeapon;
@ -848,19 +849,26 @@ void A_FireCustomMissile (AActor * self)
fixed_t x = SpawnOfs_XY * finecosine[ang]; fixed_t x = SpawnOfs_XY * finecosine[ang];
fixed_t y = SpawnOfs_XY * finesine[ang]; fixed_t y = SpawnOfs_XY * finesine[ang];
fixed_t z = SpawnHeight; fixed_t z = SpawnHeight;
fixed_t shootangle = self->angle;
AActor * misl=P_SpawnPlayerMissile (self, self->x+x, self->y+y, self->z+z, ti, self->angle); if (AimAtAngle) shootangle+=Angle;
AActor * misl=P_SpawnPlayerMissile (self, self->x+x, self->y+y, self->z+z, ti, shootangle);
// automatic handling of seeker missiles // automatic handling of seeker missiles
if (misl) if (misl)
{ {
vec3_t velocity = { misl->momx, misl->momy, 0 };
fixed_t missilespeed=(fixed_t)VectorLength(velocity);
if (linetarget && misl->flags2&MF2_SEEKERMISSILE) misl->tracer=linetarget; if (linetarget && misl->flags2&MF2_SEEKERMISSILE) misl->tracer=linetarget;
misl->angle += Angle; if (!AimAtAngle)
angle_t an = misl->angle >> ANGLETOFINESHIFT; {
misl->momx = FixedMul (missilespeed, finecosine[an]); // This original implementation is to aim straight ahead and then offset
misl->momy = FixedMul (missilespeed, finesine[an]); // the angle from the resulting direction.
vec3_t velocity = { misl->momx, misl->momy, 0 };
fixed_t missilespeed=(fixed_t)VectorLength(velocity);
misl->angle += Angle;
angle_t an = misl->angle >> ANGLETOFINESHIFT;
misl->momx = FixedMul (missilespeed, finecosine[an]);
misl->momy = FixedMul (missilespeed, finesine[an]);
}
if (misl->flags4&MF4_SPECTRAL) misl->health=-1; if (misl->flags4&MF4_SPECTRAL) misl->health=-1;
} }
} }

View file

@ -11,6 +11,7 @@
#include "actors/doom/doomdecorations.txt" #include "actors/doom/doomdecorations.txt"
#include "actors/doom/stealthmonsters.txt" #include "actors/doom/stealthmonsters.txt"
#include "actors/raven/artiegg.txt"
#include "actors/raven/ravenartifacts.txt" #include "actors/raven/ravenartifacts.txt"
#include "actors/raven/ravenhealth.txt" #include "actors/raven/ravenhealth.txt"

View file

@ -0,0 +1,106 @@
// Egg missile --------------------------------------------------------------
ACTOR EggFX : MorphProjectile
{
Game Heretic
SpawnID 40
Radius 8
Height 8
Speed 18
MorphProjectile.PlayerClass "ChickenPlayer"
MorphProjectile.MonsterClass "Chicken"
States
{
Spawn:
EGGM ABCDE 4
Loop
Death:
FX01 FFGH 3 Bright
Stop
}
}
// Morph Ovum ----------------------------------------------------------------
ACTOR ArtiEgg : CustomInventory 30
{
Game Heretic
SpawnID 14
+COUNTITEM
+FLOATBOB
+INVENTORY.INVBAR
+INVENTORY.PICKUPFLASH
+INVENTORY.FANCYPICKUPSOUND
Inventory.Icon "ARTIEGGC"
Inventory.PickupSound "misc/p_pkup"
Inventory.PickupMessage "$TXT_ARTIEGG"
Inventory.DefMaxAmount
States
{
Spawn:
EGGC ABCB 6
Loop
Use:
TNT1 A 0 A_FireCustomMissile("EggFX", -15, 0, 0, 0, 1)
TNT1 A 0 A_FireCustomMissile("EggFX", -7.5, 0, 0, 0, 1)
TNT1 A 0 A_FireCustomMissile("EggFX", 0, 0, 0, 0, 1)
TNT1 A 0 A_FireCustomMissile("EggFX", 7.5, 0, 0, 0, 1)
TNT1 A 0 A_FireCustomMissile("EggFX", 15, 0, 0, 0, 1)
Stop
}
}
// Pork missile --------------------------------------------------------------
ACTOR PorkFX : MorphProjectile
{
Game Hexen
SpawnID 40
Radius 8
Height 8
Speed 18
MorphProjectile.PlayerClass "PigPlayer"
MorphProjectile.MonsterClass "Pig"
States
{
Spawn:
PRKM ABCDE 4
Loop
Death:
FHFX IJKL 3 Bright
Stop
}
}
// Porkalator ---------------------------------------------------------------
ACTOR ArtiPork : CustomInventory 30
{
Game Hexen
SpawnID 14
+COUNTITEM
+FLOATBOB
+INVENTORY.INVBAR
+INVENTORY.PICKUPFLASH
+INVENTORY.FANCYPICKUPSOUND
Inventory.Icon "ARTIPORK"
Inventory.PickupSound "misc/p_pkup"
Inventory.PickupMessage "$TXT_ARTIEGG2"
Inventory.DefMaxAmount
States
{
Spawn:
EGGC ABCB 6
Loop
Use:
TNT1 A 0 A_FireCustomMissile("PorkFX", -15, 0, 0, 0, 1)
TNT1 A 0 A_FireCustomMissile("PorkFX", -7.5, 0, 0, 0, 1)
TNT1 A 0 A_FireCustomMissile("PorkFX", 0, 0, 0, 0, 1)
TNT1 A 0 A_FireCustomMissile("PorkFX", 7.5, 0, 0, 0, 1)
TNT1 A 0 A_FireCustomMissile("PorkFX", 15, 0, 0, 0, 1)
Stop
}
}

View file

@ -249,6 +249,7 @@ actors/doom/doomkeys.txt decorate/doom/doomkeys.txt
actors/doom/doomdecorations.txt decorate/doom/doomdecorations.txt actors/doom/doomdecorations.txt decorate/doom/doomdecorations.txt
actors/doom/stealthmonsters.txt decorate/doom/stealthmonsters.txt actors/doom/stealthmonsters.txt decorate/doom/stealthmonsters.txt
actors/raven/artiegg.txt decorate/raven/artiegg.txt
actors/raven/ravenartifacts.txt decorate/raven/ravenartifacts.txt actors/raven/ravenartifacts.txt decorate/raven/ravenartifacts.txt
actors/raven/ravenhealth.txt decorate/raven/ravenhealth.txt actors/raven/ravenhealth.txt decorate/raven/ravenhealth.txt

File diff suppressed because it is too large Load diff