diff --git a/src/g_inventory/a_artifacts.cpp b/src/g_inventory/a_artifacts.cpp index 80ddac56d..37aedc1ea 100644 --- a/src/g_inventory/a_artifacts.cpp +++ b/src/g_inventory/a_artifacts.cpp @@ -167,7 +167,7 @@ void APowerup::Serialize(FSerializer &arc) PalEntry APowerup::GetBlend () { - if (EffectTics <= BLINKTHRESHOLD && !(EffectTics & 8)) + if (isBlinking()) return 0; if (IsSpecialColormap(BlendColor)) return 0; @@ -202,6 +202,22 @@ void APowerup::CallInitEffect() else InitEffect(); } +//=========================================================================== +// +// APowerup :: isBlinking +// +//=========================================================================== + +bool APowerup::isBlinking() const +{ + return (EffectTics <= BLINKTHRESHOLD && (EffectTics & 8) && !(ItemFlags & IF_NOSCREENBLINK)); +} + +DEFINE_ACTION_FUNCTION(APowerup, isBlinking) +{ + PARAM_SELF_PROLOGUE(APowerup); + ACTION_RETURN_BOOL(self->isBlinking()); +} //=========================================================================== // @@ -222,7 +238,7 @@ void APowerup::DoEffect () if (Colormap != NOFIXEDCOLORMAP) { - if (EffectTics > BLINKTHRESHOLD || (EffectTics & 8)) + if (!isBlinking()) { Owner->player->fixedcolormap = Colormap; } @@ -294,7 +310,7 @@ bool APowerup::DrawPowerup (int x, int y) { return false; } - if (EffectTics > BLINKTHRESHOLD || !(EffectTics & 16)) + if (!isBlinking()) { FTexture *pic = TexMan(Icon); screen->DrawTexture (pic, x, y, @@ -904,7 +920,7 @@ void APowerLightAmp::DoEffect () if (Owner->player != NULL && Owner->player->fixedcolormap < NUMCOLORMAPS) { - if (EffectTics > BLINKTHRESHOLD || (EffectTics & 8)) + if (!isBlinking()) { Owner->player->fixedlightlevel = 1; } diff --git a/src/g_inventory/a_artifacts.h b/src/g_inventory/a_artifacts.h index f8eec5554..95182ce43 100644 --- a/src/g_inventory/a_artifacts.h +++ b/src/g_inventory/a_artifacts.h @@ -30,6 +30,7 @@ public: virtual void InitEffect (); virtual void DoEffect () override; virtual void EndEffect (); + bool isBlinking() const; protected: void CallInitEffect(); diff --git a/src/g_inventory/a_pickups.cpp b/src/g_inventory/a_pickups.cpp index e7a21fee6..aa00ba8b0 100644 --- a/src/g_inventory/a_pickups.cpp +++ b/src/g_inventory/a_pickups.cpp @@ -645,6 +645,8 @@ void AInventory::BecomeItem () RemoveFromHash (); flags &= ~MF_SPECIAL; ChangeStatNum(STAT_INVENTORY); + // stop all sounds this item is playing. + for(int i = 1;i<=7;i++) S_StopSound(this, i); SetState (FindState("Held")); } diff --git a/src/g_inventory/a_pickups.h b/src/g_inventory/a_pickups.h index ea87cfe85..eedadbdff 100644 --- a/src/g_inventory/a_pickups.h +++ b/src/g_inventory/a_pickups.h @@ -46,6 +46,7 @@ enum IF_ALWAYSRESPAWN = 1<<23, // Always respawn, regardless of dmflag IF_TRANSFER = 1<<24, // All inventory items that the inventory item contains is also transfered to the pickuper IF_NOTELEPORTFREEZE = 1<<25, // does not 'freeze' the player right after teleporting. + IF_NOSCREENBLINK = 1<<26, // Does not blink the screen overlay when expiring. }; diff --git a/src/g_shared/a_randomspawner.cpp b/src/g_shared/a_randomspawner.cpp index 9be5cac7b..d084e1316 100644 --- a/src/g_shared/a_randomspawner.cpp +++ b/src/g_shared/a_randomspawner.cpp @@ -17,6 +17,7 @@ #include "doomstat.h" #include "doomdata.h" #include "g_levellocals.h" +#include "virtual.h" #define MAX_RANDOMSPAWNERS_RECURSION 32 // Should be largely more than enough, honestly. static FRandom pr_randomspawn("RandomSpawn"); @@ -211,6 +212,12 @@ class ARandomSpawner : public AActor AActor *rep = GetDefaultByType(GetClass()->GetReplacee()); if (rep && ((rep->flags4 & MF4_BOSSDEATH) || (rep->flags2 & MF2_BOSS))) boss = true; + + IFVIRTUAL(ARandomSpawner, PostSpawn) + { + VMValue params[2] = { (DObject*)this, newmobj }; + GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr); + } } if (boss) this->tracer = newmobj; diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index b90f656c1..32161ed07 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -2270,6 +2270,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CustomRailgun) PARAM_FLOAT_DEF (spawnofs_z) PARAM_INT_DEF (SpiralOffset) PARAM_INT_DEF (limit) + PARAM_FLOAT_DEF (veleffect) if (range == 0) range = 8192.; if (sparsity == 0) sparsity = 1; @@ -2308,7 +2309,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CustomRailgun) // Let the aim trail behind the player if (aim) { - saved_angle = self->Angles.Yaw = self->AngleTo(self->target, -self->target->Vel.X * 3, -self->target->Vel.Y * 3); + saved_angle = self->Angles.Yaw = self->AngleTo(self->target, -self->target->Vel.X * veleffect, -self->target->Vel.Y * veleffect); if (aim == CRF_AIMDIRECT) { @@ -2318,7 +2319,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CustomRailgun) spawnofs_xy * self->Angles.Yaw.Cos(), spawnofs_xy * self->Angles.Yaw.Sin())); spawnofs_xy = 0; - self->Angles.Yaw = self->AngleTo(self->target,- self->target->Vel.X * 3, -self->target->Vel.Y * 3); + self->Angles.Yaw = self->AngleTo(self->target,- self->target->Vel.X * veleffect, -self->target->Vel.Y * veleffect); } if (self->target->flags & MF_SHADOW) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index b6ffcb699..43cafeebc 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -952,7 +952,7 @@ static inline bool isFakePain(AActor *target, AActor *inflictor, int damage) // Returns the amount of damage actually inflicted upon the target, or -1 if // the damage was cancelled. -int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags, DAngle angle) +static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags, DAngle angle) { DAngle ang; player_t *player = NULL; @@ -1589,9 +1589,24 @@ DEFINE_ACTION_FUNCTION(AActor, DamageMobj) PARAM_NAME(mod); PARAM_INT_DEF(flags); PARAM_FLOAT_DEF(angle); - ACTION_RETURN_INT(P_DamageMobj(self, inflictor, source, damage, mod, flags, angle)); + ACTION_RETURN_INT(DamageMobj(self, inflictor, source, damage, mod, flags, angle)); } +int P_DamageMobj(AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags, DAngle angle) +{ + IFVIRTUALPTR(target, AActor, DamageMobj) + { + VMValue params[7] = { target, inflictor, source, damage, mod.GetIndex(), flags, angle.Degrees }; + VMReturn ret; + int retval; + ret.IntAt(&retval); + GlobalVMStack.Call(func, params, 7, &ret, 1, nullptr); + return retval; + } + else return DamageMobj(target, inflictor, source, damage, mod, flags, angle); +} + + void P_PoisonMobj (AActor *target, AActor *inflictor, AActor *source, int damage, int duration, int period, FName type) { // Check for invulnerability. diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 46485b226..a1f2786da 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -408,6 +408,7 @@ static FFlagDef InventoryFlagDefs[] = DEFINE_FLAG(IF, ALWAYSRESPAWN, AInventory, ItemFlags), DEFINE_FLAG(IF, TRANSFER, AInventory, ItemFlags), DEFINE_FLAG(IF, NOTELEPORTFREEZE, AInventory, ItemFlags), + DEFINE_FLAG(IF, NOSCREENBLINK, AInventory, ItemFlags), DEFINE_DUMMY_FLAG(FORCERESPAWNINSURVIVAL, false), diff --git a/src/sound/oalsound.cpp b/src/sound/oalsound.cpp index 53c471a31..1b34583f9 100644 --- a/src/sound/oalsound.cpp +++ b/src/sound/oalsound.cpp @@ -407,7 +407,7 @@ public: virtual FString GetStats() { FString stats; - size_t pos, len; + size_t pos = 0, len = 0; ALfloat volume; ALint offset; ALint processed; @@ -429,28 +429,34 @@ public: return stats; } - pos = Decoder->getSampleOffset(); - len = Decoder->getSampleLength(); + if (Decoder != nullptr) + { + pos = Decoder->getSampleOffset(); + len = Decoder->getSampleLength(); + } lock.unlock(); stats = (state == AL_INITIAL) ? "Buffering" : (state == AL_STOPPED) ? "Underrun" : (state == AL_PLAYING || state == AL_PAUSED) ? "Ready" : "Unknown state"; - if(state == AL_STOPPED) - offset = BufferCount * (Data.Size()/FrameSize); - else - { - size_t rem = queued*(Data.Size()/FrameSize) - offset; - if(pos > rem) pos -= rem; - else if(len > 0) pos += len - rem; - else pos = 0; - } - pos = (size_t)(pos * 1000.0 / SampleRate); - len = (size_t)(len * 1000.0 / SampleRate); - stats.AppendFormat(",%3u%% buffered", 100 - 100*offset/(BufferCount*(Data.Size()/FrameSize))); - stats.AppendFormat(", %zu.%03zu", pos/1000, pos%1000); - if(len > 0) - stats.AppendFormat(" / %zu.%03zu", len/1000, len%1000); + if (Decoder != nullptr) + { + if (state == AL_STOPPED) + offset = BufferCount * (Data.Size() / FrameSize); + else + { + size_t rem = queued*(Data.Size() / FrameSize) - offset; + if (pos > rem) pos -= rem; + else if (len > 0) pos += len - rem; + else pos = 0; + } + pos = (size_t)(pos * 1000.0 / SampleRate); + len = (size_t)(len * 1000.0 / SampleRate); + stats.AppendFormat(",%3u%% buffered", 100 - 100 * offset / (BufferCount*(Data.Size() / FrameSize))); + stats.AppendFormat(", %zu.%03zu", pos / 1000, pos % 1000); + if (len > 0) + stats.AppendFormat(" / %zu.%03zu", len / 1000, len % 1000); + } if(state == AL_PAUSED) stats += ", paused"; if(state == AL_PLAYING) diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 8778d4c9e..ba9174f64 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -364,7 +364,7 @@ class Actor : Thinker native native void SetIdle(bool nofunction = false); native bool CheckMeleeRange(); native bool CheckMeleeRange2(); - native int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags = 0, double angle = 0); + native virtual int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags = 0, double angle = 0); native void PoisonMobj (Actor inflictor, Actor source, int damage, int duration, int period, Name type); native double AimLineAttack(double angle, double distance, out FTranslatedLineTarget pLineTarget = null, double vrange = 0., int flags = 0, Actor target = null, Actor friender = null); native Actor, int LineAttack(double angle, double distance, double pitch, int damage, Name damageType, class pufftype, int flags = 0, out FTranslatedLineTarget victim = null); @@ -703,7 +703,7 @@ class Actor : Thinker native native action state A_Jump(int chance, statelabel label, ...); native void A_SpawnProjectile(class missiletype, double spawnheight = 32, double spawnofs_xy = 0, double angle = 0, int flags = 0, double pitch = 0, int ptr = AAPTR_TARGET); native void A_CustomBulletAttack(double spread_xy, double spread_z, int numbullets, int damageperbullet, class pufftype = "BulletPuff", double range = 0, int flags = 0, int ptr = AAPTR_TARGET, class missile = null, double Spawnheight = 32, double Spawnofs_xy = 0); - native void A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = 0, color color2 = 0, int flags = 0, int aim = 0, double maxdiff = 0, class pufftype = "BulletPuff", double spread_xy = 0, double spread_z = 0, double range = 0, int duration = 0, double sparsity = 1.0, double driftspeed = 1.0, class spawnclass = null, double spawnofs_z = 0, int spiraloffset = 270, int limit = 0); + native void A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = 0, color color2 = 0, int flags = 0, int aim = 0, double maxdiff = 0, class pufftype = "BulletPuff", double spread_xy = 0, double spread_z = 0, double range = 0, int duration = 0, double sparsity = 1.0, double driftspeed = 1.0, class spawnclass = null, double spawnofs_z = 0, int spiraloffset = 270, int limit = 0, double veleffect = 3); native bool A_SetInventory(class itemtype, int amount, int ptr = AAPTR_DEFAULT, bool beyondMax = false); native bool A_GiveInventory(class itemtype, int amount = 0, int giveto = AAPTR_DEFAULT); native bool A_TakeInventory(class itemtype, int amount = 0, int flags = 0, int giveto = AAPTR_DEFAULT); diff --git a/wadsrc/static/zscript/shared/powerups.txt b/wadsrc/static/zscript/shared/powerups.txt index 549c3eece..2842989f0 100644 --- a/wadsrc/static/zscript/shared/powerups.txt +++ b/wadsrc/static/zscript/shared/powerups.txt @@ -28,6 +28,7 @@ class Powerup : Inventory native native virtual void InitEffect(); native virtual void EndEffect(); + native bool isBlinking(); } diff --git a/wadsrc/static/zscript/shared/sharedmisc.txt b/wadsrc/static/zscript/shared/sharedmisc.txt index 1b5ad4ee9..c692fe4b2 100644 --- a/wadsrc/static/zscript/shared/sharedmisc.txt +++ b/wadsrc/static/zscript/shared/sharedmisc.txt @@ -189,6 +189,9 @@ class RandomSpawner : Actor native +NOGRAVITY +THRUACTORS } + + virtual void PostSpawn(Actor spawned) + {} } // Sector flag setter ------------------------------------------------------