diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 269fd3bd7..911fce1ed 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -861,7 +861,6 @@ set( NOT_COMPILED_SOURCE_FILES sc_man_scanner.re g_hexen/a_heresiarch.cpp g_hexen/a_spike.cpp - g_strife/a_alienspectres.cpp g_strife/a_coin.cpp g_strife/a_crusader.cpp g_strife/a_entityboss.cpp diff --git a/src/c_console.cpp b/src/c_console.cpp index 3064abb0d..1016be9fd 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -65,6 +65,7 @@ #include "g_level.h" #include "d_event.h" #include "d_player.h" +#include "gstrings.h" #include "c_consolebuffer.h" #include "gi.h" @@ -1729,6 +1730,20 @@ void C_MidPrintBold (FFont *font, const char *msg) } } +DEFINE_ACTION_FUNCTION(DObject, C_MidPrint) +{ + PARAM_PROLOGUE; + PARAM_STRING(font); + PARAM_STRING(text); + PARAM_BOOL_DEF(bold); + + FFont *fnt = FFont::FindFont(font); + const char *txt = GStrings(text); + if (!bold) C_MidPrint(fnt, txt); + else C_MidPrintBold(fnt, txt); + return 0; +} + /****** Tab completion code ******/ struct TabData diff --git a/src/g_strife/a_alienspectres.cpp b/src/g_strife/a_alienspectres.cpp deleted file mode 100644 index 194bfd9e0..000000000 --- a/src/g_strife/a_alienspectres.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/* -#include "actor.h" -#include "m_random.h" -#include "a_action.h" -#include "p_local.h" -#include "p_enemy.h" -#include "s_sound.h" -#include "m_random.h" -#include "a_strifeglobal.h" -#include "c_console.h" -#include "gstrings.h" -#include "vm.h" -#include "doomstat.h" -*/ - -static FRandom pr_spectrespawn ("AlienSpectreSpawn"); -static FRandom pr_spectrechunk ("212e4"); - -//============================================================================ - -DEFINE_ACTION_FUNCTION(AActor, A_SpectreChunkSmall) -{ - PARAM_SELF_PROLOGUE(AActor); - - AActor *foo = Spawn("AlienChunkSmall", self->PosPlusZ(10.), ALLOW_REPLACE); - - if (foo != NULL) - { - int t; - - t = pr_spectrechunk() & 15; - foo->Vel.X = (t - (pr_spectrechunk() & 7)); - - t = pr_spectrechunk() & 15; - foo->Vel.Y = (t - (pr_spectrechunk() & 7)); - - foo->Vel.Z = (pr_spectrechunk() & 15); - } - return 0; -} - -DEFINE_ACTION_FUNCTION(AActor, A_SpectreChunkLarge) -{ - PARAM_SELF_PROLOGUE(AActor); - - AActor *foo = Spawn("AlienChunkLarge", self->PosPlusZ(10.), ALLOW_REPLACE); - - if (foo != NULL) - { - int t; - - t = pr_spectrechunk() & 7; - foo->Vel.X = (t - (pr_spectrechunk() & 15)); - - t = pr_spectrechunk() & 7; - foo->Vel.Y = (t - (pr_spectrechunk() & 15)); - - foo->Vel.Z = (pr_spectrechunk() & 7); - } - return 0; -} - -DEFINE_ACTION_FUNCTION(AActor, A_Spectre3Attack) -{ - PARAM_SELF_PROLOGUE(AActor); - - if (self->target == NULL) - return 0; - - AActor *foo = Spawn("SpectralLightningV2", self->PosPlusZ(32.), ALLOW_REPLACE); - - foo->Vel.Z = -12; - foo->target = self; - foo->FriendPlayer = 0; - foo->tracer = self->target; - - self->Angles.Yaw -= 90.; - for (int i = 0; i < 20; ++i) - { - self->Angles.Yaw += 9.; - P_SpawnSubMissile (self, PClass::FindActor("SpectralLightningBall2"), self); - } - self->Angles.Yaw -= 90.; - return 0; -} - -DEFINE_ACTION_FUNCTION(AActor, A_AlienSpectreDeath) -{ - PARAM_SELF_PROLOGUE(AActor); - - AActor *player; - char voc[32]; - int log; - int i; - - A_Unblock(self, true); // [RH] Need this for Sigil rewarding - if (!CheckBossDeath (self)) - { - return 0; - } - for (i = 0, player = NULL; i < MAXPLAYERS; ++i) - { - if (playeringame[i] && players[i].health > 0) - { - player = players[i].mo; - break; - } - } - if (player == NULL) - { - return 0; - } - - switch (self->GetClass()->TypeName) - { - case NAME_AlienSpectre1: - EV_DoFloor (DFloor::floorLowerToLowest, NULL, 999, 1., 0., -1, 0, false); - log = 95; - break; - - case NAME_AlienSpectre2: - C_MidPrint(SmallFont, GStrings("TXT_KILLED_BISHOP")); - log = 74; - player->GiveInventoryType (QuestItemClasses[20]); - break; - - case NAME_AlienSpectre3: - { - C_MidPrint(SmallFont, GStrings("TXT_KILLED_ORACLE")); - // If there are any Oracles still alive, kill them. - TThinkerIterator it(NAME_Oracle); - AActor *oracle; - - while ( (oracle = it.Next()) != NULL) - { - if (oracle->health > 0) - { - oracle->health = 0; - oracle->CallDie (self, self); - } - } - player->GiveInventoryType (QuestItemClasses[22]); - if (player->FindInventory (QuestItemClasses[20])) - { // If the Bishop is dead, set quest item 22 - player->GiveInventoryType (QuestItemClasses[21]); - } - if (player->FindInventory (QuestItemClasses[23]) == NULL) - { // Macil is calling us back... - log = 87; - } - else - { // You wield the power of the complete Sigil. - log = 85; - } - EV_DoDoor (DDoor::doorOpen, NULL, NULL, 222, 8., 0, 0, 0); - break; - } - - case NAME_AlienSpectre4: - C_MidPrint(SmallFont, GStrings("TXT_KILLED_MACIL")); - player->GiveInventoryType (QuestItemClasses[23]); - if (player->FindInventory (QuestItemClasses[24]) == NULL) - { // Richter has taken over. Macil is a snake. - log = 79; - } - else - { // Back to the factory for another Sigil! - log = 106; - } - break; - - case NAME_AlienSpectre5: - C_MidPrint(SmallFont, GStrings("TXT_KILLED_LOREMASTER")); - ASigil *sigil; - - player->GiveInventoryType (QuestItemClasses[25]); - if (!multiplayer) - { - player->GiveInventoryType (RUNTIME_CLASS(AUpgradeStamina)); - player->GiveInventoryType (RUNTIME_CLASS(AUpgradeAccuracy)); - } - sigil = player->FindInventory(); - if (sigil != NULL && sigil->NumPieces == 5) - { // You wield the power of the complete Sigil. - log = 85; - } - else - { // Another Sigil piece. Woohoo! - log = 83; - } - EV_DoFloor (DFloor::floorLowerToLowest, NULL, 666, 1., 0., -1, 0, false); - break; - - default: - return 0; - } - mysnprintf (voc, countof(voc), "svox/voc%d", log); - S_Sound (CHAN_VOICE, voc, 1, ATTN_NORM); - player->player->SetLogNumber (log); - return 0; -} diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index ed56407f5..bf1379d3a 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -25,7 +25,6 @@ // Include all the other Strife stuff here to reduce compile time #include "a_spectral.cpp" -#include "a_alienspectres.cpp" #include "a_coin.cpp" #include "a_crusader.cpp" #include "a_entityboss.cpp" diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp index 1909ec781..0630089d6 100644 --- a/src/g_strife/a_strifeweapons.cpp +++ b/src/g_strife/a_strifeweapons.cpp @@ -566,40 +566,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaulerTorpedoWave) return 0; } -AActor *P_SpawnSubMissile (AActor *source, PClassActor *type, AActor *target) -{ - AActor *other = Spawn (type, source->Pos(), ALLOW_REPLACE); - - if (other == NULL) - { - return NULL; - } - - other->target = target; - other->Angles.Yaw = source->Angles.Yaw; - other->VelFromAngle(); - - if (other->flags4 & MF4_SPECTRAL) - { - if (source->flags & MF_MISSILE && source->flags4 & MF4_SPECTRAL) - { - other->FriendPlayer = source->FriendPlayer; - } - else - { - other->SetFriendPlayer(target->player); - } - } - - if (P_CheckMissileSpawn (other, source->radius)) - { - DAngle pitch = P_AimLineAttack (source, source->Angles.Yaw, 1024.); - other->Vel.Z = -other->Speed * pitch.Sin(); - return other; - } - return NULL; -} - class APhosphorousFire : public AActor { DECLARE_CLASS (APhosphorousFire, AActor) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 4f4920c6f..fcd8f9cee 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -3339,6 +3339,12 @@ bool CheckBossDeath (AActor *actor) return true; } +DEFINE_ACTION_FUNCTION(AActor, CheckBossDeath) +{ + PARAM_SELF_PROLOGUE(AActor); + ACTION_RETURN_BOOL(CheckBossDeath(self)); +} + // // A_BossDeath // Possibly trigger special effects if on a boss level diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index c2d958050..3c3347ec1 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -767,7 +767,7 @@ DEFINE_ACTION_FUNCTION(AActor, Die) PARAM_SELF_PROLOGUE(AActor); PARAM_OBJECT(source, AActor); PARAM_OBJECT(inflictor, AActor); - PARAM_INT(dmgflags); + PARAM_INT_DEF(dmgflags); self->Die(source, inflictor, dmgflags); return 0; } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 6268c9395..a52ee4976 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6554,6 +6554,48 @@ DEFINE_ACTION_FUNCTION(AActor, SpawnMissileAngleZSpeed) ACTION_RETURN_OBJECT(P_SpawnMissileAngleZSpeed(self, z, type, angle, vz, speed, owner, checkspawn)); } + +AActor *P_SpawnSubMissile(AActor *source, PClassActor *type, AActor *target) +{ + AActor *other = Spawn(type, source->Pos(), ALLOW_REPLACE); + + if (other == NULL) + { + return NULL; + } + + other->target = target; + other->Angles.Yaw = source->Angles.Yaw; + other->VelFromAngle(); + + if (other->flags4 & MF4_SPECTRAL) + { + if (source->flags & MF_MISSILE && source->flags4 & MF4_SPECTRAL) + { + other->FriendPlayer = source->FriendPlayer; + } + else + { + other->SetFriendPlayer(target->player); + } + } + + if (P_CheckMissileSpawn(other, source->radius)) + { + DAngle pitch = P_AimLineAttack(source, source->Angles.Yaw, 1024.); + other->Vel.Z = -other->Speed * pitch.Sin(); + return other; + } + return NULL; +} + +DEFINE_ACTION_FUNCTION(AActor, SpawnSubMissile) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_CLASS(cls, AActor); + PARAM_OBJECT(target, AActor); + ACTION_RETURN_OBJECT(P_SpawnSubMissile(self, cls, target)); +} /* ================ = diff --git a/src/s_sound.cpp b/src/s_sound.cpp index a51a7101b..81b94b0f2 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -1232,6 +1232,16 @@ void S_Sound (int channel, FSoundID sound_id, float volume, float attenuation) S_StartSound (NULL, NULL, NULL, NULL, channel, sound_id, volume, attenuation); } +DEFINE_ACTION_FUNCTION(DObject, S_Sound) +{ + PARAM_PROLOGUE; + PARAM_SOUND(id); + PARAM_INT(channel); + PARAM_FLOAT_DEF(volume); + PARAM_FLOAT_DEF(attn); + return 0; +} + //========================================================================== // // S_Sound - An actor is source diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 09b983843..dd1bec839 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -264,7 +264,7 @@ class Actor : Thinker native virtual native void Activate(Actor activator); virtual native void Deactivate(Actor activator); virtual native int DoSpecialDamage (Actor target, int damage, Name damagetype); - virtual native void Die(Actor source, Actor inflictor, int dmgflags); + virtual native void Die(Actor source, Actor inflictor, int dmgflags = 0); virtual native bool Slam(Actor victim); virtual native bool UseInventory(Inventory item); virtual native bool SpecialBlastHandling (Actor source, double strength); @@ -309,11 +309,13 @@ class Actor : Thinker native native Actor SpawnMissileXYZ(Vector3 pos, Actor dest, Class type, bool checkspawn = true, Actor owner = null); native Actor SpawnMissileZ (double z, Actor dest, class type); native Actor SpawnMissileAngleZSpeed (double z, class type, double angle, double vz, double speed, Actor owner = null, bool checkspawn = true); + native Actor SpawnSubMissile(Class type, Actor target); native Actor, Actor SpawnPlayerMissile(class type, double angle = 0, double x = 0, double y = 0, double z = 0, out FTranslatedLineTarget pLineTarget = null, bool nofreeaim = false, bool noautoaim = false, int aimflags = 0); native void SpawnTeleportFog(Vector3 pos, bool beforeTele, bool setTarget); native Actor RoughMonsterSearch(int distance, bool onlyseekable = false, bool frontonly = false); native int ApplyDamageFactor(Name damagetype, int damage); native int GetModifiedDamage(Name damagetype, int damage, bool passive); + native bool CheckBossDeath(); void A_Light(int extralight) { if (player) player.extralight = clamp(extralight, -20, 20); } void A_Light0() { if (player) player.extralight = 0; } diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 3a96cbbcb..c76e4590e 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -8,6 +8,8 @@ class Object native native static vector3, int G_PickDeathmatchStart(); native static vector3, int G_PickPlayerStart(int pnum, int flags = 0); native static int GameType(); + native static void S_Sound (Sound sound_id, int channel, float volume = 1, float attenuation = ATTN_NORM); + native static void C_MidPrint(string fontname, string textlabel, bool bold = false); // always uses the stringtable. /*virtual*/ native void Destroy(); } diff --git a/wadsrc/static/zscript/strife/acolyte.txt b/wadsrc/static/zscript/strife/acolyte.txt index 1c50b318c..45f075d6b 100644 --- a/wadsrc/static/zscript/strife/acolyte.txt +++ b/wadsrc/static/zscript/strife/acolyte.txt @@ -98,21 +98,13 @@ class Acolyte : StrifeHumanoid return; // Make sure all the other blue acolytes are dead. - ThinkerIterator it = ThinkerIterator.Create("AcolyteBlue"); - Actor other; - - while ( (other = Actor(it.Next ())) ) + if (CheckBossDeath()) { - if (other != self && other.health > 0) - { // Found a living one - return; - } + players[i].mo.GiveInventoryType ("QuestItem7"); + players[i].SetLogNumber (14); + A_StopSound (CHAN_VOICE); + A_PlaySound ("svox/voc14", CHAN_VOICE); } - - players[i].mo.GiveInventoryType ("QuestItem7"); - players[i].SetLogNumber (14); - A_StopSound (CHAN_VOICE); - A_PlaySound ("svox/voc14", CHAN_VOICE); } } diff --git a/wadsrc/static/zscript/strife/alienspectres.txt b/wadsrc/static/zscript/strife/alienspectres.txt index 0fe9826f0..2beee63ea 100644 --- a/wadsrc/static/zscript/strife/alienspectres.txt +++ b/wadsrc/static/zscript/strife/alienspectres.txt @@ -32,8 +32,6 @@ class AlienSpectre1 : SpectralMonster +NOICEDEATH } - native void A_AlienSpectreDeath (); - States { Spawn: @@ -76,6 +74,116 @@ class AlienSpectre1 : SpectralMonster AL1P R 5 Bright A_AlienSpectreDeath; Stop; } + + //============================================================================ + + void A_AlienSpectreDeath () + { + PlayerPawn player = null; + int log = 0; + + A_NoBlocking(); // [RH] Need this for Sigil rewarding + if (!CheckBossDeath ()) + { + return; + } + for (int i = 0; i < MAXPLAYERS; ++i) + { + if (playeringame[i] && players[i].health > 0) + { + player = players[i].mo; + break; + } + } + if (player == null) + { + return; + } + + class cls = GetClass(); + if (cls == "AlienSpectre1") + { + Floor_LowerToLowest(999, 8); + log = 95; + } + else if (cls == "AlienSpectre2") + { + C_MidPrint("SmallFont", "TXT_KILLED_BISHOP"); + log = 74; + player.GiveInventoryType ("QuestItem21"); + } + else if (cls == "AlienSpectre3") + { + C_MidPrint("SmallFont", "TXT_KILLED_ORACLE"); + // If there are any Oracles still alive, kill them. + ThinkerIterator it = ThinkerIterator.Create("Oracle"); + Actor oracle; + + while ( (oracle = Actor(it.Next())) != null) + { + if (oracle.health > 0) + { + oracle.health = 0; + oracle.Die (self, self); + } + } + player.GiveInventoryType ("QuestItem23"); + if (player.FindInventory ("QuestItem21")) + { // If the Bishop is dead, set quest item 22 + player.GiveInventoryType ("QuestItem22"); + } + if (player.FindInventory ("QuestItem24") == null) + { // Macil is calling us back... + log = 87; + } + else + { // You wield the power of the complete Sigil. + log = 85; + } + Door_Open(222, 64); + } + else if (cls == "AlienSpectre4") + { + C_MidPrint("SmallFont", "TXT_KILLED_MACIL"); + player.GiveInventoryType ("QuestItem24"); + if (player.FindInventory ("QuestItem25") == null) + { // Richter has taken over. Macil is a snake. + log = 79; + } + else + { // Back to the factory for another Sigil! + log = 106; + } + } + else if (cls == "AlienSpectre5") + { + C_MidPrint("SmallFont", "TXT_KILLED_LOREMASTER"); + + player.GiveInventoryType ("QuestItem26"); + if (!multiplayer) + { + player.GiveInventoryType ("UpgradeStamina"); + player.GiveInventoryType ("UpgradeAccuracy"); + } + Sigil sigl = Sigil(player.FindInventory("Sigil")); + if (sigl != null /*&& sigl.NumPieces == 5*/) + { // You wield the power of the complete Sigil. + log = 85; + } + else + { // Another Sigil piece. Woohoo! + log = 83; + } + Floor_LowerToLowest(666, 8); + } + if (log > 0) + { + String voc = "svox/voc" .. log; + A_PlaySound(voc, CHAN_VOICE); + player.player.SetLogNumber (log); + } + } + } diff --git a/wadsrc/static/zscript/strife/spectral.txt b/wadsrc/static/zscript/strife/spectral.txt index d6a234904..9ea95ba1d 100644 --- a/wadsrc/static/zscript/strife/spectral.txt +++ b/wadsrc/static/zscript/strife/spectral.txt @@ -11,10 +11,66 @@ class SpectralMonster : Actor native +SPECTRAL +NOICEDEATH } + + //============================================================================ + + void A_SpectreChunkSmall () + { + Actor foo = Spawn("AlienChunkSmall", pos + (0, 0, 10), ALLOW_REPLACE); + + if (foo != null) + { + int t; + + t = random[SpectreChunk]() & 15; + foo.Vel.X = (t - (random[SpectreChunk]() & 7)); + + t = random[SpectreChunk]() & 15; + foo.Vel.Y = (t - (random[SpectreChunk]() & 7)); + + foo.Vel.Z = (random[SpectreChunk]() & 15); + } + } + + void A_SpectreChunkLarge () + { + Actor foo = Spawn("AlienChunkLarge", pos + (0, 0, 10), ALLOW_REPLACE); + + if (foo != null) + { + int t; + + t = random[SpectreChunk]() & 7; + foo.Vel.X = (t - (random[SpectreChunk]() & 15)); + + t = random[SpectreChunk]() & 7; + foo.Vel.Y = (t - (random[SpectreChunk]() & 15)); + + foo.Vel.Z = (random[SpectreChunk]() & 7); + } + } + + void A_Spectre3Attack () + { + if (target == null) + return; + + Actor foo = Spawn("SpectralLightningV2", Pos + (0, 0, 32), ALLOW_REPLACE); + + foo.Vel.Z = -12; + foo.target = self; + foo.FriendPlayer = 0; + foo.tracer = target; + + Angle -= 90.; + for (int i = 0; i < 20; ++i) + { + Angle += 9.; + SpawnSubMissile ("SpectralLightningBall2", self); + } + Angle -= 90.; + } - native void A_SpectreChunkSmall (); - native void A_SpectreChunkLarge (); - native void A_Spectre3Attack (); native void A_SpotLightning (); }