diff --git a/docs/rh-log.txt b/docs/rh-log.txt
index 7c90be1d9b..fd79dfb3c4 100644
--- a/docs/rh-log.txt
+++ b/docs/rh-log.txt
@@ -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
- Updated thingdef_specials.h for the new thingdef_specials.gperf file.
- Created a new MorphedMonster class that Chicken and Pig now derive from.
diff --git a/src/g_heretic/a_chicken.cpp b/src/g_heretic/a_chicken.cpp
index 2616823736..4179531229 100644
--- a/src/g_heretic/a_chicken.cpp
+++ b/src/g_heretic/a_chicken.cpp
@@ -10,7 +10,6 @@
#include "a_sharedglobal.h"
#include "p_enemy.h"
#include "d_event.h"
-#include "ravenshared.h"
#include "gstrings.h"
static FRandom pr_chickenplayerthink ("ChickenPlayerThink");
diff --git a/src/g_heretic/a_mummy.cpp b/src/g_heretic/a_mummy.cpp
index f66854a91c..0418252f71 100644
--- a/src/g_heretic/a_mummy.cpp
+++ b/src/g_heretic/a_mummy.cpp
@@ -254,7 +254,6 @@ void A_MummyAttack2 (AActor *actor)
return;
}
mo = P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(AMummyFX1));
- //mo = P_SpawnMissile(actor, actor->target, MT_EGGFX);
if (mo != NULL)
{
mo->tracer = actor->target;
diff --git a/src/g_hexen/a_pig.cpp b/src/g_hexen/a_pig.cpp
index ec2e7b4b7d..d8d74cbb35 100644
--- a/src/g_hexen/a_pig.cpp
+++ b/src/g_hexen/a_pig.cpp
@@ -10,7 +10,6 @@
#include "a_sharedglobal.h"
#include "p_enemy.h"
#include "d_event.h"
-#include "ravenshared.h"
#include "gstrings.h"
static FRandom pr_snoutattack ("SnoutAttack");
diff --git a/src/g_raven/ravenshared.h b/src/g_raven/ravenshared.h
index 928301637b..1352676c8c 100644
--- a/src/g_raven/ravenshared.h
+++ b/src/g_raven/ravenshared.h
@@ -36,29 +36,4 @@ public:
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__
diff --git a/src/g_raven/a_artiegg.cpp b/src/g_shared/a_morph.cpp
similarity index 64%
rename from src/g_raven/a_artiegg.cpp
rename to src/g_shared/a_morph.cpp
index afdb998cda..0167694846 100644
--- a/src/g_raven/a_artiegg.cpp
+++ b/src/g_shared/a_morph.cpp
@@ -8,7 +8,6 @@
#include "s_sound.h"
#include "m_random.h"
#include "a_sharedglobal.h"
-#include "ravenshared.h"
#define MORPHTICS (40*TICRATE)
@@ -291,40 +290,15 @@ bool P_UpdateMorphedMonster (AMorphedMonster *beast)
return true;
}
-// Egg ----------------------------------------------------------------------
+// Base class for morphing projectiles --------------------------------------
-FState AEggFX::States[] =
-{
-#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)
+IMPLEMENT_STATELESS_ACTOR(AMorphProjectile, Any, -1, 0)
PROP_Damage (1)
PROP_Flags (MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY)
PROP_Flags2 (MF2_NOTELEPORT)
-
- PROP_SpawnState (S_EGGFX)
- PROP_DeathState (S_EGGFXI1)
-
- PROP_EggFX_PlayerClass ("ChickenPlayer")
- PROP_EggFX_MonsterClass ("Chicken")
END_DEFAULTS
-int AEggFX::DoSpecialDamage (AActor *target, int damage)
+int AMorphProjectile::DoSpecialDamage (AActor *target, int damage)
{
if (target->player)
{
@@ -337,129 +311,23 @@ int AEggFX::DoSpecialDamage (AActor *target, int damage)
return -1;
}
-void AEggFX::Serialize (FArchive &arc)
+void AMorphProjectile::Serialize (FArchive &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) ---------
@@ -469,7 +337,7 @@ END_POINTERS
BEGIN_STATELESS_DEFAULTS (AMorphedMonster, Any, -1, 0)
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)
END_DEFAULTS
diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h
index cd1064be93..5eaf78c81f 100644
--- a/src/g_shared/a_sharedglobal.h
+++ b/src/g_shared/a_sharedglobal.h
@@ -204,4 +204,29 @@ private:
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__
diff --git a/src/info.h b/src/info.h
index 915160cbdc..275a735e86 100644
--- a/src/info.h
+++ b/src/info.h
@@ -246,9 +246,7 @@ enum
ADEF_PlayerPawn_SoundClass,
ADEF_PlayerPawn_ScoreIcon,
ADEF_PlayerPawn_MorphWeapon,
- ADEF_EggFX_PlayerClass,
- ADEF_EggFX_MonsterClass,
- ADEF_LastString = ADEF_EggFX_MonsterClass,
+ ADEF_LastString = ADEF_PlayerPawn_MorphWeapon,
// The rest of the properties use their type field (upper 2 bits)
ADEF_XScale,
diff --git a/src/infodefaults.cpp b/src/infodefaults.cpp
index 3d6ddbc1a2..0166c519fd 100644
--- a/src/infodefaults.cpp
+++ b/src/infodefaults.cpp
@@ -46,7 +46,6 @@
#include "w_wad.h"
#include "a_strifeglobal.h"
#include "thingdef.h"
-#include "ravenshared.h"
void FActorInfo::BuildDefaults ()
{
@@ -130,7 +129,6 @@ static void ApplyActorDefault (int defnum, const char *datastr, int dataint)
ASigil *const sigil = (ASigil *)sgDefaults;
AAmmo *const ammo = (AAmmo *)sgDefaults;
APlayerPawn *const player = (APlayerPawn *)sgDefaults;
- AEggFX *const eggfx = (AEggFX *)sgDefaults;
switch (defnum)
{
@@ -342,10 +340,6 @@ static void ApplyActorDefault (int defnum, const char *datastr, int dataint)
player->ScoreIcon = TexMan.AddPatch (datastr, ns_sprites);
}
break;
-
- case ADEF_EggFX_PlayerClass: eggfx->PlayerClass = FName(datastr); break;
- case ADEF_EggFX_MonsterClass: eggfx->MonsterClass = FName(datastr); break;
-
}
}
diff --git a/src/infomacros.h b/src/infomacros.h
index be0ba1c803..56c191d33c 100644
--- a/src/infomacros.h
+++ b/src/infomacros.h
@@ -216,8 +216,6 @@ public:
#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_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_YScale(x) ADD_BYTE_PROP(ADEF_YScale,x)
diff --git a/src/p_user.cpp b/src/p_user.cpp
index dd10722c7b..112c7c5929 100644
--- a/src/p_user.cpp
+++ b/src/p_user.cpp
@@ -400,8 +400,12 @@ void APlayerPawn::Serialize (FArchive &arc)
<< SideMove2
<< ScoreIcon
<< InvFirst
- << InvSel
- << MorphWeapon;
+ << InvSel;
+
+ // Serialize the name, not the index
+ FName MorphWeaponName = ENamedName(MorphWeapon);
+ arc << MorphWeaponName;
+ MorphWeapon = MorphWeaponName;
}
//===========================================================================
diff --git a/src/thingdef.cpp b/src/thingdef.cpp
index ab0f78bd34..d568cec356 100644
--- a/src/thingdef.cpp
+++ b/src/thingdef.cpp
@@ -67,7 +67,7 @@
#include "p_conversation.h"
#include "v_text.h"
#include "thingdef.h"
-#include "ravenshared.h"
+#include "a_sharedglobal.h"
const PClass *QuestItemClasses[31];
@@ -701,7 +701,7 @@ AFuncDesc AFTable[]=
FUNC(A_JumpIfNoAmmo, "L" )
FUNC(A_CustomPunch, "Xxymx" )
FUNC(A_FireBullets, "XXXXmyx" )
- FUNC(A_FireCustomMissile, "Mxyxx" )
+ FUNC(A_FireCustomMissile, "Mxyxxx" )
FUNC(A_RailAttack, "Xxyccxx" )
FUNC(A_Recoil, "X")
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 ();
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 ();
defaults->PlayerClass = FName(sc_String);
@@ -3780,8 +3780,6 @@ static const ActorProps props[] =
{ "disintegrate", ActorDisintegrateState, RUNTIME_CLASS(AActor) },
{ "donthurtshooter", ActorDontHurtShooter, 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) },
{ "explosionradius", ActorExplosionRadius, RUNTIME_CLASS(AActor) },
{ "fastspeed", ActorFastSpeed, RUNTIME_CLASS(AActor) },
@@ -3815,6 +3813,8 @@ static const ActorProps props[] =
{ "missileheight", ActorMissileHeight, RUNTIME_CLASS(AActor) },
{ "missiletype", ActorMissileType, 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) },
{ "pain", ActorPainState, RUNTIME_CLASS(AActor) },
{ "painchance", ActorPainChance, RUNTIME_CLASS(AActor) },
diff --git a/src/thingdef_codeptr.cpp b/src/thingdef_codeptr.cpp
index 014c423333..cb24d2236c 100644
--- a/src/thingdef_codeptr.cpp
+++ b/src/thingdef_codeptr.cpp
@@ -824,7 +824,7 @@ void A_FireBullets (AActor *self)
//==========================================================================
void A_FireCustomMissile (AActor * self)
{
- int index=CheckIndex(5);
+ int index=CheckIndex(6);
if (index<0 || !self->player) return;
ENamedName MissileName=(ENamedName)StateParameters[index];
@@ -832,6 +832,7 @@ void A_FireCustomMissile (AActor * self)
bool UseAmmo=EvalExpressionN (StateParameters[index+2], self);
int SpawnOfs_XY=EvalExpressionI (StateParameters[index+3], self);
fixed_t SpawnHeight=fixed_t(EvalExpressionF (StateParameters[index+4], self) * FRACUNIT);
+ BOOL AimAtAngle=EvalExpressionI (StateParameters[index+5], self);
player_t *player=self->player;
AWeapon * weapon=player->ReadyWeapon;
@@ -848,19 +849,26 @@ void A_FireCustomMissile (AActor * self)
fixed_t x = SpawnOfs_XY * finecosine[ang];
fixed_t y = SpawnOfs_XY * finesine[ang];
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
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;
- misl->angle += Angle;
- angle_t an = misl->angle >> ANGLETOFINESHIFT;
- misl->momx = FixedMul (missilespeed, finecosine[an]);
- misl->momy = FixedMul (missilespeed, finesine[an]);
+ if (!AimAtAngle)
+ {
+ // This original implementation is to aim straight ahead and then offset
+ // 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;
}
}
diff --git a/wadsrc/decorate/decorate.txt b/wadsrc/decorate/decorate.txt
index 8c8e35f718..d70c2b73f9 100644
--- a/wadsrc/decorate/decorate.txt
+++ b/wadsrc/decorate/decorate.txt
@@ -11,6 +11,7 @@
#include "actors/doom/doomdecorations.txt"
#include "actors/doom/stealthmonsters.txt"
+#include "actors/raven/artiegg.txt"
#include "actors/raven/ravenartifacts.txt"
#include "actors/raven/ravenhealth.txt"
diff --git a/wadsrc/decorate/raven/artiegg.txt b/wadsrc/decorate/raven/artiegg.txt
new file mode 100644
index 0000000000..649eed9539
--- /dev/null
+++ b/wadsrc/decorate/raven/artiegg.txt
@@ -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
+ }
+}
+
diff --git a/wadsrc/zdoom.lst b/wadsrc/zdoom.lst
index 494f2020a5..ac3664c9bb 100644
--- a/wadsrc/zdoom.lst
+++ b/wadsrc/zdoom.lst
@@ -249,6 +249,7 @@ actors/doom/doomkeys.txt decorate/doom/doomkeys.txt
actors/doom/doomdecorations.txt decorate/doom/doomdecorations.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/ravenhealth.txt decorate/raven/ravenhealth.txt
diff --git a/zdoom.vcproj b/zdoom.vcproj
index 219ce8b720..c54d8a6651 100644
--- a/zdoom.vcproj
+++ b/zdoom.vcproj
@@ -1,7 +1,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -2724,6 +2716,14 @@
GeneratePreprocessedFile="0"
/>
+
+
+
@@ -2746,7 +2746,7 @@
/>
-
-
-
@@ -4813,6 +4803,16 @@
Outputs="$(IntDir)/$(InputName).obj"
/>
+
+
+
@@ -4837,16 +4837,6 @@
Outputs="$(IntDir)/$(InputName).obj"
/>
-
-
-
@@ -4857,6 +4847,16 @@
Outputs="$(IntDir)/$(InputName).obj"
/>
+
+
+
@@ -4881,16 +4881,6 @@
Outputs="$(IntDir)\$(InputName).obj"
/>
-
-
-
@@ -4901,6 +4891,16 @@
Outputs="$(IntDir)\$(InputName).obj"
/>
+
+
+
@@ -4925,16 +4925,6 @@
Outputs="$(IntDir)\$(InputName).obj"
/>
-
-
-
@@ -4945,6 +4935,16 @@
Outputs="$(IntDir)\$(InputName).obj"
/>
+
+
+
@@ -4969,16 +4969,6 @@
Outputs="$(IntDir)\$(InputName).obj"
/>
-
-
-
@@ -4989,6 +4979,16 @@
Outputs="$(IntDir)\$(InputName).obj"
/>
+
+
+
@@ -5060,7 +5060,7 @@
/>
-
-
-
@@ -5403,6 +5395,14 @@
Outputs="$(IntDir)\$(InputName).obj"
/>
+
+
+
+
+
+
@@ -5625,14 +5633,6 @@
GeneratePreprocessedFile="0"
/>
-
-
-
@@ -5654,7 +5654,7 @@
/>
+
+
@@ -5778,7 +5782,7 @@
/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -7042,7 +7010,7 @@
/>
-
-
-
@@ -9583,6 +9543,14 @@
AdditionalIncludeDirectories="src\win32;$(NoInherit)"
/>
+
+
+
@@ -9757,7 +9725,7 @@
/>