diff --git a/Classes/ClientSettings.uc b/Classes/ClientSettings.uc index 12d8ef65..62a29543 100644 --- a/Classes/ClientSettings.uc +++ b/Classes/ClientSettings.uc @@ -82,6 +82,8 @@ var config float KillFeedX; var config float KillFeedY; var config float KillFeedSpeed; var config float KillFeedScale; +var config float DamageNumberTextLocationX; +var config float DamageNumberTextLocationY; enum EFraggerScopeChoice { FSC_None, @@ -393,6 +395,8 @@ simulated function string DumpSettings() { GetSetting("KillFeedY")$ GetSetting("KillFeedSpeed")$ GetSetting("KillFeedScale")$ + GetSetting("DamageNumberTextLocationX")$ + GetSetting("DamageNumberTextLocationY")$ GetSetting("FraggerScopeChoice")$ GetSetting("bEnableNetStats")$ GetSetting("bNetStatsUnconfirmedTime")$ @@ -493,6 +497,8 @@ defaultproperties KillFeedY=0.5 KillFeedSpeed=1.0 KillFeedScale=1.0 + DamageNumberTextLocationX=-1.0 + DamageNumberTextLocationY=-1.0 FraggerScopeChoice=FSC_Moveable bEnableNetStats=False bNetStatsUnconfirmedTime=True diff --git a/Classes/IGPlus_HitFeedback.uc b/Classes/IGPlus_HitFeedback.uc index 55aaaf68..c038b76b 100644 --- a/Classes/IGPlus_HitFeedback.uc +++ b/Classes/IGPlus_HitFeedback.uc @@ -45,7 +45,7 @@ function ModifyPlayer(Pawn P) { CreateTracker(P); } -function bool CheckVisibility(Pawn Orig, Pawn Dest) { +function bool DoVisibilityTrace(Pawn Orig, Pawn Dest) { local vector Start; local rotator DirYaw; local vector X,Y,Z; @@ -56,9 +56,6 @@ function bool CheckVisibility(Pawn Orig, Pawn Dest) { local vector HitLocation; local vector HitNormal; - if (bCheckVisibility == false) - return true; - Start = Orig.Location + vect(0,0,1)*Orig.BaseEyeHeight; DirYaw = rotator(Dest.Location - Start); DirYaw.Pitch = 0; @@ -85,6 +82,13 @@ function bool CheckVisibility(Pawn Orig, Pawn Dest) { return false; } +function bool CheckVisibility(Pawn Orig, Pawn Dest) { + if (bCheckVisibility == false) + return true; + + return DoVisibilityTrace(Orig, Dest); +} + function MutatorTakeDamage( out int ActualDamage, Pawn Victim, @@ -105,6 +109,14 @@ function MutatorTakeDamage( if (Tracker != none) TotalDamage = Tracker.LastDamage; + // When HFM_Always, do a separate trace for gameplay damage-number suppression. + // Negate TotalDamage to signal the client to suppress damage numbers. + // Hit sounds and markers are unaffected (they use Abs(Sw)). + if (!bCheckVisibility && TotalDamage > 0) { + if (!DoVisibilityTrace(InstigatedBy, Victim)) + TotalDamage = -TotalDamage; + } + InstigatedBy.ReceiveLocalizedMessage( Class'IGPlus_HitFeedbackMessage', TotalDamage, diff --git a/Classes/IGPlus_HitFeedbackMessage.uc b/Classes/IGPlus_HitFeedbackMessage.uc index 84af4efa..3afe557f 100644 --- a/Classes/IGPlus_HitFeedbackMessage.uc +++ b/Classes/IGPlus_HitFeedbackMessage.uc @@ -34,8 +34,8 @@ static function ClientReceive( if (bViewTarget || Settings == none || Settings.HitMarkerSource == HMSRC_Server) class'bbPlayerStatics'.static.PlayHitMarker(P, Settings, Abs(Sw), RelatedPRI_2.Team, RelatedPRI_1.Team); - - if (bbP != none && bbP.bEnableDamageDebugMode) + // Negative Sw suppresses gameplay damage numbers while preserving damage magnitude via Abs(Sw). Allows debug mode to show all damage while suppressing non LOS damage for clients. + if (bbP != none && (bbP.bEnableDamageDebugMode || (bbP.bShowDamageNumbers && Sw >= 0))) class'bbPlayerStatics'.static.PlayDamageMarker(P, Abs(Sw), RelatedPRI_2.Team, RelatedPRI_1.Team); if (bViewTarget || Settings == none || Settings.HitSoundSource == HSSRC_Server) diff --git a/Classes/IGPlus_ServerSettingsContent.uc b/Classes/IGPlus_ServerSettingsContent.uc index f38c6ba9..e08d13da 100644 --- a/Classes/IGPlus_ServerSettingsContent.uc +++ b/Classes/IGPlus_ServerSettingsContent.uc @@ -86,6 +86,9 @@ var localized string HitFeedbackModeDisabled; var localized string HitFeedbackModeVisibleOnly; var localized string HitFeedbackModeAlways; var localized string bEnablePingCompensatedSpawnHelp; +var UWindowCheckbox Chk_bShowDamageNumbers; +var localized string bShowDamageNumbersText; +var localized string bShowDamageNumbersHelp; var UWindowLabelControl Lbl_Movement; var localized string MovementText; @@ -187,6 +190,18 @@ var localized string bEnableDamageDebugConsoleMessagesHelp; var UWindowCheckbox Chk_bEnableHitboxDebugMode; var localized string bEnableHitboxDebugModeText; var localized string bEnableHitboxDebugModeHelp; +var IGPlus_EditControl Edit_DamageNumberDuration; +var localized string DamageNumberDurationText; +var localized string DamageNumberDurationHelp; +var IGPlus_EditControl Edit_DamageNumberDecayExponent; +var localized string DamageNumberDecayExponentText; +var localized string DamageNumberDecayExponentHelp; +var IGPlus_EditControl Edit_DamageNumberAccumulationTime; +var localized string DamageNumberAccumulationTimeText; +var localized string DamageNumberAccumulationTimeHelp; +var IGPlus_EditControl Edit_DamageNumberDrawOffset; +var localized string DamageNumberDrawOffsetText; +var localized string DamageNumberDrawOffsetHelp; var float PaddingX; var float PaddingY; @@ -545,6 +560,7 @@ function SaveServerSettings() { SaveServerSettingIfChanged(S, "bAlwaysRenderFlagCarrier", BoolToString(Chk_bAlwaysRenderFlagCarrier.bChecked)); SaveServerSettingIfChanged(S, "bAlwaysRenderDroppedFlags", BoolToString(Chk_bAlwaysRenderDroppedFlags.bChecked)); SaveServerSettingIfChanged(S, "HitFeedbackMode", HitFeedbackModeIndexToValue(Cmb_HitFeedbackMode.GetSelectedIndex())); + SaveServerSettingIfChanged(S, "bShowDamageNumbers", BoolToString(Chk_bShowDamageNumbers.bChecked)); SaveServerSettingIfChanged(S, "bEnablePingCompensatedSpawn", BoolToString(Chk_bEnablePingCompensatedSpawn.bChecked)); SaveServerSettingIfChanged(S, "bJumpingPreservesMomentum", BoolToString(Chk_bJumpingPreservesMomentum.bChecked)); @@ -579,6 +595,10 @@ function SaveServerSettings() { SaveServerSettingIfChanged(S, "bEnableDamageDebugMode", BoolToString(Chk_bEnableDamageDebugMode.bChecked)); SaveServerSettingIfChanged(S, "bEnableDamageDebugConsoleMessages", BoolToString(Chk_bEnableDamageDebugConsoleMessages.bChecked)); SaveServerSettingIfChanged(S, "bEnableHitboxDebugMode", BoolToString(Chk_bEnableHitboxDebugMode.bChecked)); + SaveServerSettingIfChanged(S, "DamageNumberDuration", Edit_DamageNumberDuration.GetValue()); + SaveServerSettingIfChanged(S, "DamageNumberDecayExponent", Edit_DamageNumberDecayExponent.GetValue()); + SaveServerSettingIfChanged(S, "DamageNumberAccumulationTime", Edit_DamageNumberAccumulationTime.GetValue()); + SaveServerSettingIfChanged(S, "DamageNumberDrawOffset", Edit_DamageNumberDrawOffset.GetValue()); } function AdminLoginFromUI() { @@ -888,6 +908,10 @@ function ConfigureResponsiveServerControls(Canvas C, float ControlWidth) { ConfigureFixedWidthEdit(Edit_LooseCheckCorrectionFactor, C, ControlWidth, 80); ConfigureFixedWidthEdit(Edit_LooseCheckCorrectionFactorOnMover, C, ControlWidth, 80); ConfigureFixedWidthEdit(Edit_WarpFixDelay, C, ControlWidth, 80); + ConfigureFixedWidthEdit(Edit_DamageNumberDuration, C, ControlWidth, 80); + ConfigureFixedWidthEdit(Edit_DamageNumberDecayExponent, C, ControlWidth, 80); + ConfigureFixedWidthEdit(Edit_DamageNumberAccumulationTime, C, ControlWidth, 80); + ConfigureFixedWidthEdit(Edit_DamageNumberDrawOffset, C, ControlWidth, 80); } function LoadServerSettings() { @@ -911,6 +935,7 @@ function LoadServerSettings() { Chk_bAlwaysRenderFlagCarrier.bChecked = S.bAlwaysRenderFlagCarrier; Chk_bAlwaysRenderDroppedFlags.bChecked = S.bAlwaysRenderDroppedFlags; Cmb_HitFeedbackMode.SetSelectedIndex(Clamp(int(S.HitFeedbackMode), 0, 2)); + Chk_bShowDamageNumbers.bChecked = S.bShowDamageNumbers; Chk_bJumpingPreservesMomentum.bChecked = S.bJumpingPreservesMomentum; Chk_bOldLandingMomentum.bChecked = S.bOldLandingMomentum; @@ -945,6 +970,10 @@ function LoadServerSettings() { Chk_bEnableDamageDebugMode.bChecked = S.bEnableDamageDebugMode; Chk_bEnableDamageDebugConsoleMessages.bChecked = S.bEnableDamageDebugConsoleMessages; Chk_bEnableHitboxDebugMode.bChecked = S.bEnableHitboxDebugMode; + Edit_DamageNumberDuration.SetValue(string(S.DamageNumberDuration)); + Edit_DamageNumberDecayExponent.SetValue(string(S.DamageNumberDecayExponent)); + Edit_DamageNumberAccumulationTime.SetValue(string(S.DamageNumberAccumulationTime)); + Edit_DamageNumberDrawOffset.SetValue(string(S.DamageNumberDrawOffset)); bLoadSucceeded = true; } @@ -996,6 +1025,7 @@ function Created() { Cmb_HitFeedbackMode.AddItem(HitFeedbackModeDisabled); Cmb_HitFeedbackMode.AddItem(HitFeedbackModeVisibleOnly); Cmb_HitFeedbackMode.AddItem(HitFeedbackModeAlways); + Chk_bShowDamageNumbers = CreateCheckbox(bShowDamageNumbersText, bShowDamageNumbersHelp); Chk_bEnablePingCompensatedSpawn = CreateCheckbox(bEnablePingCompensatedSpawnText, bEnablePingCompensatedSpawnHelp); Lbl_Movement = CreateSeparator(MovementText); @@ -1033,6 +1063,10 @@ function Created() { Chk_bEnableDamageDebugMode = CreateCheckbox(bEnableDamageDebugModeText, bEnableDamageDebugModeHelp); Chk_bEnableDamageDebugConsoleMessages = CreateCheckbox(bEnableDamageDebugConsoleMessagesText, bEnableDamageDebugConsoleMessagesHelp); Chk_bEnableHitboxDebugMode = CreateCheckbox(bEnableHitboxDebugModeText, bEnableHitboxDebugModeHelp); + Edit_DamageNumberDuration = CreateEdit(ECT_Real, DamageNumberDurationText, DamageNumberDurationHelp, 16, 80); + Edit_DamageNumberDecayExponent = CreateEdit(ECT_Real, DamageNumberDecayExponentText, DamageNumberDecayExponentHelp, 16, 80); + Edit_DamageNumberAccumulationTime = CreateEdit(ECT_Real, DamageNumberAccumulationTimeText, DamageNumberAccumulationTimeHelp, 16, 80); + Edit_DamageNumberDrawOffset = CreateEdit(ECT_Real, DamageNumberDrawOffsetText, DamageNumberDrawOffsetHelp, 16, 80); ControlOffset += PaddingY - 4; @@ -1104,6 +1138,7 @@ function BeforePaint(Canvas C, float X, float Y) { LayoutControl(Chk_bAlwaysRenderFlagCarrier, bShowSettings, WndWidth, Top); LayoutControl(Chk_bAlwaysRenderDroppedFlags, bShowSettings, WndWidth, Top); LayoutControl(Cmb_HitFeedbackMode, bShowSettings, WndWidth, Top); + LayoutControl(Chk_bShowDamageNumbers, bShowSettings, WndWidth, Top); LayoutControl(Chk_bEnablePingCompensatedSpawn, bShowSettings, WndWidth, Top); LayoutControl(Lbl_Movement, bShowSettings, WndWidth, Top); @@ -1141,6 +1176,10 @@ function BeforePaint(Canvas C, float X, float Y) { LayoutControl(Chk_bEnableDamageDebugMode, bShowSettings, WndWidth, Top); LayoutControl(Chk_bEnableDamageDebugConsoleMessages, bShowSettings, WndWidth, Top); LayoutControl(Chk_bEnableHitboxDebugMode, bShowSettings, WndWidth, Top); + LayoutControl(Edit_DamageNumberDuration, bShowSettings, WndWidth, Top); + LayoutControl(Edit_DamageNumberDecayExponent, bShowSettings, WndWidth, Top); + LayoutControl(Edit_DamageNumberAccumulationTime, bShowSettings, WndWidth, Top); + LayoutControl(Edit_DamageNumberDrawOffset, bShowSettings, WndWidth, Top); DesiredHeight = Top + PaddingY; } @@ -1262,6 +1301,8 @@ defaultproperties HitFeedbackModeDisabled="Disabled" HitFeedbackModeVisibleOnly="Visible Only" HitFeedbackModeAlways="Always" + bShowDamageNumbersText="Show Damage Numbers" + bShowDamageNumbersHelp="If checked, damage dealt is displayed as a number on screen for all players. Obeys LOS Checks." bEnablePingCompensatedSpawnHelp="If checked, enables ping-compensated spawn behavior" MovementText="Movement" @@ -1330,6 +1371,14 @@ defaultproperties bEnableDamageDebugConsoleMessagesHelp="If checked, prints damage debug messages to client consoles" bEnableHitboxDebugModeText="Enable Hitbox Debug Mode" bEnableHitboxDebugModeHelp="If checked, enables hitbox debug diagnostics" + DamageNumberDurationText="Damage Number Duration" + DamageNumberDurationHelp="How long damage numbers stay visible in seconds" + DamageNumberDecayExponentText="Damage Number Decay Exponent" + DamageNumberDecayExponentHelp="Fade curve exponent applied to damage number alpha" + DamageNumberAccumulationTimeText="Damage Number Accumulation Time" + DamageNumberAccumulationTimeHelp="Time window in seconds to accumulate multiple hits" + DamageNumberDrawOffsetText="Damage Number Default Position" + DamageNumberDrawOffsetHelp="Default horizontal offset from center where damage numbers appear. Overridden by each client's own damage number position setting." PaddingX=20 PaddingY=12 diff --git a/Classes/IGPlus_SettingsContent.uc b/Classes/IGPlus_SettingsContent.uc index f35abb13..896d41c5 100644 --- a/Classes/IGPlus_SettingsContent.uc +++ b/Classes/IGPlus_SettingsContent.uc @@ -339,6 +339,14 @@ var localized string MoreInformationText; var localized string KillFeedLocationText; var localized string KillFeedLocationHelp; +// Damage Numbers + var UWindowLabelControl Lbl_DamageNumbers; + var localized string DamageNumbersLblText; + + var IGPlus_ScreenLocationControl SLoc_DamageNumberTextLocation; + var localized string DamageNumberTextLocationText; + var localized string DamageNumberTextLocationHelp; + // Hit Marker var UWindowLabelControl Lbl_HitMarker; var localized string HitMarkerLblText; @@ -963,6 +971,9 @@ function Created() { Edit_KillFeedScale = CreateEdit(ECT_Real, KillFeedScaleText, KillFeedScaleHelp, , 64); SLoc_KillFeedLocation = CreateScreenLocation(100, KillFeedLocationText, KillFeedLocationHelp); + Lbl_DamageNumbers = CreateSeparator(DamageNumbersLblText); + SLoc_DamageNumberTextLocation = CreateScreenLocation(100, DamageNumberTextLocationText, DamageNumberTextLocationHelp); + Lbl_HitMarker = CreateSeparator(HitMarkerLblText); Cmb_HitMarkerSource = CreateComboBox(HitMarkerSourceText, HitMarkerSourceHelp, false, 150); SetUpHitSourceComboBox(Cmb_HitMarkerSource); @@ -1114,6 +1125,10 @@ function Load() { Edit_KillFeedSpeed.SetValue(string(Settings.KillFeedSpeed)); Edit_KillFeedScale.SetValue(string(Settings.KillFeedScale)); SLoc_KillFeedLocation.SetLocation(Settings.KillFeedX, Settings.KillFeedY); + if (Settings.DamageNumberTextLocationX >= 0.0 && Settings.DamageNumberTextLocationY >= 0.0) + SLoc_DamageNumberTextLocation.SetLocation(Settings.DamageNumberTextLocationX, Settings.DamageNumberTextLocationY); + else + SLoc_DamageNumberTextLocation.SetLocation(0.65, 0.5); Cmb_HitMarkerSource.SetSelectedIndex(Clamp(Settings.HitMarkerSource, 0, 1)); Cmb_HitMarkerColorMode.SetSelectedIndex(Clamp(Settings.HitMarkerColorMode, 0, 1)); @@ -1235,6 +1250,7 @@ function Save() { Settings.KillFeedSpeed = float(Edit_KillFeedSpeed.GetValue()); Settings.KillFeedScale = float(Edit_KillFeedScale.GetValue()); SLoc_KillFeedLocation.GetLocation(Settings.KillFeedX, Settings.KillFeedY); + SLoc_DamageNumberTextLocation.GetLocation(Settings.DamageNumberTextLocationX, Settings.DamageNumberTextLocationY); Settings.HitMarkerSource = Settings.IntToHitMarkerSource(Cmb_HitMarkerSource.GetSelectedIndex()); Settings.HitMarkerColorMode = Settings.IntToHitMarkerColorMode(Cmb_HitMarkerColorMode.GetSelectedIndex()); @@ -1548,6 +1564,11 @@ defaultproperties KillFeedLocationText="Location" KillFeedLocationHelp="Where on screen to show the kill feed" + DamageNumbersLblText="Damage Numbers" + + DamageNumberTextLocationText="Location" + DamageNumberTextLocationHelp="Where on screen to show damage numbers" + HitMarkerLblText="Hit Marker" HitMarkerSourceText="Hit Source" diff --git a/Classes/ServerSettings.uc b/Classes/ServerSettings.uc index 9124cc3b..70ad8d95 100644 --- a/Classes/ServerSettings.uc +++ b/Classes/ServerSettings.uc @@ -84,9 +84,14 @@ var config float SnapshotInterpRewindMs; var config bool bEnableWarpFix; var config bool bEnableCarcassCollision; var config bool ShowTouchedPackage; +var config bool bShowDamageNumbers; var config bool bEnableDamageDebugMode; var config bool bEnableDamageDebugConsoleMessages; var config bool bEnableHitboxDebugMode; +var config float DamageNumberDuration; +var config float DamageNumberDecayExponent; +var config float DamageNumberAccumulationTime; +var config float DamageNumberDrawOffset; enum EHitFeedbackMode { HFM_Disabled, @@ -154,9 +159,14 @@ function DumpServerSettings(PlayerPawn P) { DumpSetting(P, "bEnableWarpFix"); DumpSetting(P, "ShowTouchedPackage"); DumpSetting(P, "HitFeedbackMode"); + DumpSetting(P, "bShowDamageNumbers"); DumpSetting(P, "bEnableDamageDebugMode"); DumpSetting(P, "bEnableDamageDebugConsoleMessages"); - DumpSetting(P, "bEnableHitboxDebugMode"); + DumpSetting(P, "bEnableHitboxDebugMode"); + DumpSetting(P, "DamageNumberDuration"); + DumpSetting(P, "DamageNumberDecayExponent"); + DumpSetting(P, "DamageNumberAccumulationTime"); + DumpSetting(P, "DamageNumberDrawOffset"); } defaultproperties @@ -228,7 +238,12 @@ defaultproperties bEnableWarpFix=True bEnableCarcassCollision=True HitFeedbackMode=HFM_Always + bShowDamageNumbers=False bEnableDamageDebugMode=False bEnableDamageDebugConsoleMessages=False bEnableHitboxDebugMode=False + DamageNumberDuration=2.0 + DamageNumberDecayExponent=5.0 + DamageNumberAccumulationTime=0.4 + DamageNumberDrawOffset=96.0 } diff --git a/Classes/UTPure.uc b/Classes/UTPure.uc index 078d13c6..bc2498b6 100644 --- a/Classes/UTPure.uc +++ b/Classes/UTPure.uc @@ -1027,9 +1027,14 @@ function string IGPlus_NormalizeServerSettingKey(string Key) { if (Key ~= "bEnableWarpFix") return "bEnableWarpFix"; if (Key ~= "ShowTouchedPackage") return "ShowTouchedPackage"; if (Key ~= "HitFeedbackMode") return "HitFeedbackMode"; + if (Key ~= "bShowDamageNumbers") return "bShowDamageNumbers"; if (Key ~= "bEnableDamageDebugMode") return "bEnableDamageDebugMode"; if (Key ~= "bEnableDamageDebugConsoleMessages") return "bEnableDamageDebugConsoleMessages"; if (Key ~= "bEnableHitboxDebugMode") return "bEnableHitboxDebugMode"; + if (Key ~= "DamageNumberDuration") return "DamageNumberDuration"; + if (Key ~= "DamageNumberDecayExponent") return "DamageNumberDecayExponent"; + if (Key ~= "DamageNumberAccumulationTime") return "DamageNumberAccumulationTime"; + if (Key ~= "DamageNumberDrawOffset") return "DamageNumberDrawOffset"; return ""; } @@ -1066,8 +1071,13 @@ function IGPlus_ApplyServerSettingsToPlayers() { BP.IGPlus_SnapInterp_ServerNextTime = 0; BP.IGPlus_SnapInterp_ServerHasLast = false; } + BP.bShowDamageNumbers = Settings.bShowDamageNumbers; BP.bEnableDamageDebugMode = Settings.bEnableDamageDebugMode; BP.bEnableDamageDebugConsoleMessages = Settings.bEnableDamageDebugConsoleMessages; + BP.DamageNumberDuration = Settings.DamageNumberDuration; + BP.DamageNumberDecayExponent = Settings.DamageNumberDecayExponent; + BP.DamageNumberAccumulationTime = Settings.DamageNumberAccumulationTime; + BP.DamageNumberDrawOffset = Settings.DamageNumberDrawOffset; } } diff --git a/Classes/bbCHSpectator.uc b/Classes/bbCHSpectator.uc index e1371dc2..9374a7d9 100644 --- a/Classes/bbCHSpectator.uc +++ b/Classes/bbCHSpectator.uc @@ -1072,9 +1072,14 @@ function IGPlus_ServerRequestSettings() { IGPlus_ServerSendSetting("ShowTouchedPackage"); IGPlus_ServerSendSetting("HitFeedbackMode"); + IGPlus_ServerSendSetting("bShowDamageNumbers"); IGPlus_ServerSendSetting("bEnableDamageDebugMode"); IGPlus_ServerSendSetting("bEnableDamageDebugConsoleMessages"); IGPlus_ServerSendSetting("bEnableHitboxDebugMode"); + IGPlus_ServerSendSetting("DamageNumberDuration"); + IGPlus_ServerSendSetting("DamageNumberDecayExponent"); + IGPlus_ServerSendSetting("DamageNumberAccumulationTime"); + IGPlus_ServerSendSetting("DamageNumberDrawOffset"); IGPlus_ServerSettingsDone(true); } diff --git a/Classes/bbPlayer.uc b/Classes/bbPlayer.uc index c7c249a5..d0364767 100644 --- a/Classes/bbPlayer.uc +++ b/Classes/bbPlayer.uc @@ -459,8 +459,13 @@ struct ClientWeaponSettings { var ClientWeaponSettings ClientWeaponSettingsData; +var bool bShowDamageNumbers; var bool bEnableDamageDebugMode; var bool bEnableDamageDebugConsoleMessages; +var float DamageNumberDuration; +var float DamageNumberDecayExponent; +var float DamageNumberAccumulationTime; +var float DamageNumberDrawOffset; replication { @@ -505,8 +510,13 @@ replication IGPlus_ServerSnapInterpTrustedEcho, IGPlus_ServerSnapInterpDelayEchoTime, IGPlus_ServerSnapInterpLastAcceptedTimeEcho, + bShowDamageNumbers, bEnableDamageDebugMode, - bEnableDamageDebugConsoleMessages; + bEnableDamageDebugConsoleMessages, + DamageNumberDuration, + DamageNumberDecayExponent, + DamageNumberAccumulationTime, + DamageNumberDrawOffset; unreliable if ( Role == ROLE_Authority ) DuckFractionRepl, @@ -1310,8 +1320,13 @@ event Possess() IGPlus_EnableInputReplication = zzUTPure.Settings.bEnableInputReplication; IGPlus_EnableSnapshotInterpolation = zzUTPure.Settings.bEnableSnapshotInterpolation; + bShowDamageNumbers = zzUTPure.Settings.bShowDamageNumbers; bEnableDamageDebugMode = zzUTPure.Settings.bEnableDamageDebugMode; bEnableDamageDebugConsoleMessages = zzUTPure.Settings.bEnableDamageDebugConsoleMessages; + DamageNumberDuration = zzUTPure.Settings.DamageNumberDuration; + DamageNumberDecayExponent = zzUTPure.Settings.DamageNumberDecayExponent; + DamageNumberAccumulationTime = zzUTPure.Settings.DamageNumberAccumulationTime; + DamageNumberDrawOffset = zzUTPure.Settings.DamageNumberDrawOffset; if(!zzUTPure.bExludeKickers) { @@ -10196,7 +10211,7 @@ event PostRender( canvas zzCanvas ) HitMarkerTestTeam = 0; } - PlayerStatics.DrawDamageNumbers(zzCanvas, zzTick); + PlayerStatics.DrawDamageNumbers(zzCanvas, zzTick, self); if (HitMarkerTestDamage > 0 && PlayerStatics.default.DamageNumberLifespan == 0) { PlayerStatics.PlayDamageMarker(self, HitMarkerTestDamage, PlayerReplicationInfo.Team, HitMarkerTestTeam); ++HitMarkerTestTeam; @@ -12465,9 +12480,14 @@ function IGPlus_ServerRequestSettings() { IGPlus_ServerSendSetting("ShowTouchedPackage"); IGPlus_ServerSendSetting("HitFeedbackMode"); + IGPlus_ServerSendSetting("bShowDamageNumbers"); IGPlus_ServerSendSetting("bEnableDamageDebugMode"); IGPlus_ServerSendSetting("bEnableDamageDebugConsoleMessages"); IGPlus_ServerSendSetting("bEnableHitboxDebugMode"); + IGPlus_ServerSendSetting("DamageNumberDuration"); + IGPlus_ServerSendSetting("DamageNumberDecayExponent"); + IGPlus_ServerSendSetting("DamageNumberAccumulationTime"); + IGPlus_ServerSendSetting("DamageNumberDrawOffset"); IGPlus_ServerSettingsDone(true); } diff --git a/Classes/bbPlayerStatics.uc b/Classes/bbPlayerStatics.uc index 9320820e..8a08c2cd 100644 --- a/Classes/bbPlayerStatics.uc +++ b/Classes/bbPlayerStatics.uc @@ -19,7 +19,6 @@ var float DamageNumberLastHitTime; var float DamageNumberDuration; var float DamageNumberDecayExponent; var float DamageNumberAccumulationTime; -var float DamageNumberDrawSize; var float DamageNumberDrawOffset; // Hardcoded values (used directly in functions, not settings struct) @@ -180,6 +179,18 @@ static function PlayDamageMarker(PlayerPawn Me, float Damage, int OwnTeam, int E local color NumColor; local float TimeSinceLastHit; local bool bIsTeamHit; + local bbPlayer bbP; + local float Duration; + local float AccumulationTime; + + bbP = bbPlayer(Me); + if (bbP != none) { + Duration = bbP.DamageNumberDuration; + AccumulationTime = bbP.DamageNumberAccumulationTime; + } else { + Duration = default.DamageNumberDuration; + AccumulationTime = default.DamageNumberAccumulationTime; + } bIsTeamHit = (Me.GameReplicationInfo.bTeamGame && OwnTeam == EnemyTeam); @@ -191,42 +202,60 @@ static function PlayDamageMarker(PlayerPawn Me, float Damage, int OwnTeam, int E TimeSinceLastHit = Me.Level.TimeSeconds - default.DamageNumberLastHitTime; // Check for accumulation conditions: Active AND time < threshold - if (default.DamageNumberLifespan > 0.0 && TimeSinceLastHit < default.DamageNumberAccumulationTime) { + if (default.DamageNumberLifespan > 0.0 && TimeSinceLastHit < AccumulationTime) { default.DamageNumberDamage += Damage; - default.DamageNumberLifespan = default.DamageNumberDuration; + default.DamageNumberLifespan = Duration; default.DamageNumberColor = NumColor; default.DamageNumberLastHitTime = Me.Level.TimeSeconds; - if (bbPlayer(Me).bEnableDamageDebugConsoleMessages) - bbPlayer(Me).ClientMessage("[Debug] Damage done: " $ (int(default.DamageNumberDamage))); + if (bbP != none && bbP.bEnableDamageDebugConsoleMessages) + bbP.ClientMessage("[Debug] Damage done: " $ (int(default.DamageNumberDamage))); } else { // Start new / Replace old default.DamageNumberDamage = Damage; - default.DamageNumberLifespan = default.DamageNumberDuration; + default.DamageNumberLifespan = Duration; default.DamageNumberColor = NumColor; default.DamageNumberLastHitTime = Me.Level.TimeSeconds; - if (bbPlayer(Me).bEnableDamageDebugConsoleMessages) - bbPlayer(Me).ClientMessage("[Debug] Damage done: " $ int(default.DamageNumberDamage)); + if (bbP != none && bbP.bEnableDamageDebugConsoleMessages) + bbP.ClientMessage("[Debug] Damage done: " $ int(default.DamageNumberDamage)); } } -static function DrawDamageNumbers(Canvas C, float DeltaTime) { +static function DrawDamageNumbers(Canvas C, float DeltaTime, PlayerPawn Me) { local float FadeMultiplier; local string DamageText; local float TextX, TextY; local HUD MyHud; - local float DrawSize, DrawOffset; + local float LegacyDrawOffset; + local bbPlayer bbP; + local bbCHSpectator bbS; + local ClientSettings Settings; + local float Duration; + local float DecayExponent; if (default.DamageNumberLifespan <= 0.0) return; + bbP = bbPlayer(Me); + if (bbP != none) { + Settings = bbP.Settings; + LegacyDrawOffset = bbP.DamageNumberDrawOffset; + Duration = bbP.DamageNumberDuration; + DecayExponent = bbP.DamageNumberDecayExponent; + } else { + bbS = bbCHSpectator(Me); + if (bbS != none) + Settings = bbS.Settings; + LegacyDrawOffset = default.DamageNumberDrawOffset; + Duration = default.DamageNumberDuration; + DecayExponent = default.DamageNumberDecayExponent; + } + class'CanvasUtils'.static.SaveCanvas(C); - DrawSize = default.DamageNumberDrawSize; - DrawOffset = default.DamageNumberDrawOffset; - FadeMultiplier = ((default.DamageNumberLifespan / default.DamageNumberDuration) ** default.DamageNumberDecayExponent); + FadeMultiplier = ((default.DamageNumberLifespan / Duration) ** DecayExponent); MyHud = C.ViewPort.Actor.myHUD; if (MyHud != none && ChallengeHud(MyHud) != none && ChallengeHud(MyHud).MyFonts != none) { @@ -236,7 +265,10 @@ static function DrawDamageNumbers(Canvas C, float DeltaTime) { C.Font = ChallengeHud(MyHud).MyFonts.GetSmallFont(C.ClipX); C.TextSize(DamageText, TextX, TextY); C.DrawColor = default.DamageNumberColor * FadeMultiplier; - C.SetPos(C.SizeX/2 + DrawOffset + DrawSize + 5, C.SizeY/2 - TextY/2); + if (Settings != none && Settings.DamageNumberTextLocationX >= 0.0 && Settings.DamageNumberTextLocationY >= 0.0) + C.SetPos(Settings.DamageNumberTextLocationX * (C.SizeX - TextX), Settings.DamageNumberTextLocationY * (C.SizeY - TextY)); + else + C.SetPos(C.SizeX/2 + LegacyDrawOffset + 5, C.SizeY/2 - TextY/2); C.DrawText(DamageText); } @@ -351,8 +383,7 @@ defaultproperties { DamageNumberDuration=2.0 DamageNumberDecayExponent=5.0 DamageNumberAccumulationTime=0.4 - DamageNumberDrawSize=48.0 - DamageNumberDrawOffset=48.0 + DamageNumberDrawOffset=96.0 RemoteRole=ROLE_None bHidden=True } diff --git a/README.md b/README.md index e71a907b..db96abbb 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,8 @@ These settings can be found in **InstaGibPlus.ini** under section **\[ClientSett 1. [KillFeedY](#killfeedy) 1. [KillFeedSpeed](#killfeedspeed) 1. [KillFeedScale](#killfeedscale) +1. [DamageNumberTextLocationX](#damagenumbertextlocationx) +1. [DamageNumberTextLocationY](#damagenumbertextlocationy) 1. [FraggerScopeChoice](#fraggerscopechoice) 1. [bEnableNetStats](#benablenetstats) 1. [bNetStatsUnconfirmedTime](#bnetstatsunconfirmedtime) @@ -601,6 +603,22 @@ Increase to make lines disappear sooner. Decrease to make lines disappear later. Scales the size of individual lines of the KillFeed. +## DamageNumberTextLocationX +**Type: float** +**Default: -1.0** + +Horizontal position of damage numbers. Left edge of screen is 0. Right edge of screen is 1. + +If this value or [DamageNumberTextLocationY](#damagenumbertextlocationy) is negative, the client uses the legacy default placement. + +## DamageNumberTextLocationY +**Type: float** +**Default: -1.0** + +Vertical position of damage numbers. Top of screen is 0. Bottom of screen is 1. + +If this value or [DamageNumberTextLocationX](#damagenumbertextlocationx) is negative, the client uses the legacy default placement. + ## FraggerScopeChoice **Type: EFraggerScopeChoice** **Default: `FSC_Moveable`** @@ -1285,9 +1303,14 @@ Server settings can be found inside InstaGibPlus.ini. 1. [FireTimeout](#firetimeout) 1. [bEnableCarcassCollision](#benablecarcasscollision) 1. [ShowTouchedPackage](#showtouchedpackage) +1. [bShowDamageNumbers](#bshowdamagenumbers) 1. [bEnableDamageDebugMode](#benabledamagedebugmode) 1. [bEnableDamageDebugConsoleMessages](#benabledamagedebugconsolemessages) 1. [bEnableHitboxDebugMode](#benablehitboxdebugmode) +1. [DamageNumberDuration](#damagenumberduration) +1. [DamageNumberDecayExponent](#damagenumberdecayexponent) +1. [DamageNumberAccumulationTime](#damagenumberaccumulationtime) +1. [DamageNumberDrawOffset](#damagenumberdrawoffset) 1. [ExcludeMapsForKickers](#excludemapsforkickers) 1. [HitFeedbackMode](#hitfeedbackmode) 1. [ForcedSettings](#forcedsettings) @@ -1613,12 +1636,23 @@ Distance to any position over the last 500ms for hits to be counted. Send package-names of touched actors to clients when those clients touch the actors. +## bShowDamageNumbers + +**Type: bool** +**Default: False** + +If `True`, enables gameplay damage number display. + +Gameplay damage numbers are only shown when the server-side LOS check passes. + +Final screen placement can be customized client-side using [DamageNumberTextLocationX](#damagenumbertextlocationx) and [DamageNumberTextLocationY](#damagenumbertextlocationy). + ## bEnableDamageDebugMode **Type: bool** **Default: False** -If `True`, enables server-side damage debug instrumentation. +If `True`, enables debug damage number display, bypassing gameplay LOS restrictions. ## bEnableDamageDebugConsoleMessages @@ -1634,6 +1668,36 @@ If `True`, emits damage debug information to console messages. If `True`, enables hitbox debug instrumentation. +## DamageNumberDuration + +**Type: float** +**Default: 2.0** +**Unit: s** + +How long damage numbers remain visible on screen. + +## DamageNumberDecayExponent + +**Type: float** +**Default: 5.0** + +Controls how quickly damage numbers fade out over their lifetime. + +## DamageNumberAccumulationTime + +**Type: float** +**Default: 0.4** +**Unit: s** + +Window used to accumulate rapid consecutive damage events into one displayed value. + +## DamageNumberDrawOffset + +**Type: float** +**Default: 96.0** + +Default horizontal offset from the crosshair where damage numbers are displayed. Each client can override this with their own damage number position setting. + ## ExcludeMapsForKickers **Type: string\[128\]**