Skip to content

Commit 4206dc8

Browse files
Merge pull request #1 from Kamusvalenzuela/heal-and-knockback-implementation
Added the migration to MySQL and SQLite (By GeminiAI) + small fixes
2 parents 922eecf + 3e1baab commit 4206dc8

18 files changed

+457
-32
lines changed

Framework/Intersect.Framework.Core/Config/CombatOptions.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,5 @@ public partial class CombatOptions
8484
/// </summary>
8585
public bool EnableAllPlayersFriendlyInSafeZone { get; set; } = false;
8686

87-
/// <summary>
88-
/// Percentage of healing reduction when Grievous Wounds effect is applied. Default 50%.
89-
/// </summary>
90-
public int GrievousWoundsHealingReduction { get; set; } = 50;
9187

92-
/// <summary>
93-
/// Percentage of healing increase when Healing Boost effect is applied. Default 50%.
94-
/// </summary>
95-
public int HealingBoostPercentage { get; set; } = 50;
9688
}

Framework/Intersect.Framework.Core/Entities/SpellEffect.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public enum SpellEffect
3030

3131
Knockback = 13,
3232

33-
GrievousWounds = 14,
33+
HealingReduction = 14,
3434

3535
HealingBoost = 15,
3636
}

Framework/Intersect.Framework.Core/GameObjects/Spells/SpellCombatDescriptor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ public string PercentageStatDiffJson
8888
/// </summary>
8989
public int KnockbackTiles { get; set; } = 1;
9090

91+
public int? PercentageEffect { get; set; }
92+
9193
public string TransformSprite { get; set; }
9294

9395
[Column("OnHit")]

Intersect.Editor/Forms/Editors/frmSpell.Designer.cs

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Intersect.Editor/Forms/Editors/frmSpell.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ private void UpdateSpellTypePanels()
378378
chkHOTDOT.Checked = mEditorItem.Combat.HoTDoT;
379379
nudBuffDuration.Value = mEditorItem.Combat.Duration;
380380
nudTick.Value = mEditorItem.Combat.HotDotInterval;
381+
nudPercentageEffect.Value = mEditorItem.Combat.PercentageEffect ?? 0;
381382
cmbExtraEffect.SelectedIndex = (int)mEditorItem.Combat.Effect;
382383
cmbExtraEffect_SelectedIndexChanged(null, null);
383384
}
@@ -537,6 +538,8 @@ private void cmbExtraEffect_SelectedIndexChanged(object sender, EventArgs e)
537538
picSprite.Visible = false;
538539
lblKnockbackTiles.Visible = false;
539540
nudKnockbackTiles.Visible = false;
541+
lblPercentageEffect.Visible = false;
542+
nudPercentageEffect.Visible = false;
540543

541544
if (cmbExtraEffect.SelectedIndex == 6) //Transform
542545
{
@@ -576,6 +579,12 @@ private void cmbExtraEffect_SelectedIndexChanged(object sender, EventArgs e)
576579
nudKnockbackTiles.Visible = true;
577580
nudKnockbackTiles.Value = Math.Max(1, mEditorItem.Combat.KnockbackTiles);
578581
}
582+
583+
if (cmbExtraEffect.SelectedIndex == (int)SpellEffect.HealingReduction || cmbExtraEffect.SelectedIndex == (int)SpellEffect.HealingBoost)
584+
{
585+
lblPercentageEffect.Visible = true;
586+
nudPercentageEffect.Visible = true;
587+
}
579588
}
580589

581590
private void frmSpell_FormClosed(object sender, FormClosedEventArgs e)
@@ -1114,4 +1123,9 @@ private void nudKnockbackTiles_ValueChanged(object sender, EventArgs e)
11141123
{
11151124
mEditorItem.Combat.KnockbackTiles = (int)nudKnockbackTiles.Value;
11161125
}
1126+
1127+
private void nudPercentageEffect_ValueChanged(object sender, EventArgs e)
1128+
{
1129+
mEditorItem.Combat.PercentageEffect = (int)nudPercentageEffect.Value;
1130+
}
11171131
}

Intersect.Server.Core/Database/DbInterface.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -220,25 +220,28 @@ private static void ProcessMigrations<TContext>(TContext context)
220220
{
221221
if (!context.HasPendingMigrations)
222222
{
223-
ApplicationContext.Context.Value?.Logger.LogDebug($"No pending migrations for {context.GetType().GetName(qualified: true)}, skipping...");
223+
ApplicationContext.Context.Value?.Logger.LogInformation($"No pending migrations for {context.GetType().GetName(qualified: true)}, skipping...");
224224
return;
225225
}
226226

227-
ApplicationContext.Context.Value?.Logger.LogDebug($"Pending schema migrations for {typeof(TContext).Name}:\n\t{string.Join("\n\t", context.PendingSchemaMigrations)}");
228-
ApplicationContext.Context.Value?.Logger.LogDebug($"Pending data migrations for {typeof(TContext).Name}:\n\t{string.Join("\n\t", context.PendingDataMigrationNames)}");
227+
ApplicationContext.Context.Value?.Logger.LogInformation($"Pending schema migrations for {typeof(TContext).Name}:\n\t{string.Join("\n\t", context.PendingSchemaMigrations)}");
228+
ApplicationContext.Context.Value?.Logger.LogInformation($"Pending data migrations for {typeof(TContext).Name}:\n\t{string.Join("\n\t", context.PendingDataMigrationNames)}");
229229

230230
var migrationScheduler = new MigrationScheduler<TContext>(context);
231-
ApplicationContext.Context.Value?.Logger.LogDebug("Scheduling pending migrations...");
231+
ApplicationContext.Context.Value?.Logger.LogInformation("Scheduling pending migrations...");
232232
migrationScheduler.SchedulePendingMigrations();
233233

234-
ApplicationContext.Context.Value?.Logger.LogDebug("Applying scheduled migrations...");
234+
ApplicationContext.Context.Value?.Logger.LogInformation("Applying scheduled migrations...");
235235
migrationScheduler.ApplyScheduledMigrations();
236+
ApplicationContext.Context.Value?.Logger.LogInformation("Scheduled migrations applied.");
236237

237238
var remainingPendingSchemaMigrations = context.PendingSchemaMigrations.ToList();
238239
var processedSchemaMigrations =
239240
context.PendingSchemaMigrations.Where(migration => !remainingPendingSchemaMigrations.Contains(migration));
240241

242+
ApplicationContext.Context.Value?.Logger.LogInformation("Notifying context of processed schema migrations...");
241243
context.OnSchemaMigrationsProcessed(processedSchemaMigrations.ToArray());
244+
ApplicationContext.Context.Value?.Logger.LogInformation("Migration processing complete.");
242245
}
243246

244247
internal static ILoggerFactory CreateLoggerFactory<TDBContext>(DatabaseOptions databaseOptions)
@@ -302,6 +305,7 @@ private static bool EnsureUpdated(IServerContext serverContext)
302305
EnableSensitiveDataLogging = true,
303306
LoggerFactory = CreateLoggerFactory<LoggingContext>(loggingDatabaseOptions),
304307
});
308+
ApplicationContext.Context.Value?.Logger.LogInformation("Logging context created.");
305309

306310
// We don't want anyone running the old migration tool accidentally
307311
try
@@ -326,6 +330,7 @@ private static bool EnsureUpdated(IServerContext serverContext)
326330
// ignored
327331
}
328332

333+
ApplicationContext.Context.Value?.Logger.LogInformation("Checking pending migrations...");
329334
var gameContextPendingMigrations = gameContext.PendingSchemaMigrations;
330335
var playerContextPendingMigrations = playerContext.PendingSchemaMigrations;
331336
var loggingContextPendingMigrations = loggingContext.PendingSchemaMigrations;
@@ -340,6 +345,8 @@ private static bool EnsureUpdated(IServerContext serverContext)
340345
!loggingContextPendingMigrations.Contains("20191118024649_RequestLogs")
341346
);
342347

348+
ApplicationContext.Context.Value?.Logger.LogInformation($"Show migration warning: {showMigrationWarning}");
349+
343350
if (showMigrationWarning)
344351
{
345352
if (serverContext.StartupOptions.MigrateAutomatically)
@@ -394,11 +401,14 @@ private static bool EnsureUpdated(IServerContext serverContext)
394401
Console.WriteLine("No migrations pending that require user acceptance, skipping prompt...");
395402
}
396403

404+
ApplicationContext.Context.Value?.Logger.LogInformation("Processing migrations...");
397405
var contexts = new List<DbContext> { gameContext, playerContext, loggingContext };
398406
foreach (var context in contexts)
399407
{
400408
var contextType = context.GetType().FindGenericTypeParameters(typeof(IntersectDbContext<>)).First();
409+
ApplicationContext.Context.Value?.Logger.LogInformation($"Processing migration for context: {contextType.Name}");
401410
_methodInfoProcessMigrations.MakeGenericMethod(contextType).Invoke(null, new object[] { context });
411+
ApplicationContext.Context.Value?.Logger.LogInformation($"Finished migration for context: {contextType.Name}");
402412
}
403413

404414
return true;

Intersect.Server.Core/Database/MigrationScheduler.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,16 @@ public void ApplyScheduledMigrations()
6363

6464
while (scheduleSegment.Any())
6565
{
66+
ApplicationContext.Context.Value?.Logger.LogInformation($"Schedule segment count: {scheduleSegment.Count}");
6667
var targetMigration = scheduleSegment
6768
.TakeWhile(metadata => metadata is SchemaMigrationMetadata)
6869
.LastOrDefault();
6970

7071
if (targetMigration is SchemaMigrationMetadata)
7172
{
73+
ApplicationContext.Context.Value?.Logger.LogInformation($"Migrating schema via EF Core to: {targetMigration.Name}");
7274
migrator.Migrate(targetMigration.Name);
75+
ApplicationContext.Context.Value?.Logger.LogInformation($"EF Core migration to {targetMigration.Name} finished.");
7376

7477
scheduleSegment = scheduleSegment
7578
.SkipWhile(metadata => metadata is SchemaMigrationMetadata)
@@ -94,7 +97,9 @@ public void ApplyScheduledMigrations()
9497
throw new InvalidOperationException($"Failed to create instance of data migration: {scheduledDataMigration.MigratorType.FullName}");
9598
}
9699

100+
ApplicationContext.Context.Value?.Logger.LogInformation($"Executing data migration: {scheduledDataMigration.Name}");
97101
dataMigration.Up(_context.ContextOptions);
102+
ApplicationContext.Context.Value?.Logger.LogInformation($"Data migration {scheduledDataMigration.Name} finished.");
98103

99104
scheduleSegment = scheduleSegment
100105
.Skip(1)

Intersect.Server.Core/Entities/Entity.cs

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,8 +1564,9 @@ public void AddVital(Vital vital, long amount)
15641564
}
15651565

15661566
/// <summary>
1567-
/// Applies Grievous Wounds and Healing Boost modifiers to healing amount.
1568-
/// Formula: Healing × (1 + boost) × (1 - reduction)
1567+
/// Applies Healing Reduction and Healing Boost modifiers to healing amount.
1568+
/// Formula: Healing * (1 + boost) OR Healing * (1 - reduction)
1569+
/// Only the latest applied effect is considered.
15691570
/// </summary>
15701571
protected long ApplyHealingModifiers(long healAmount)
15711572
{
@@ -1574,28 +1575,34 @@ protected long ApplyHealingModifiers(long healAmount)
15741575
return healAmount;
15751576
}
15761577

1577-
var boostModifier = 0.0;
1578-
var reductionModifier = 0.0;
1578+
// Find the latest applied status that is either HealingReduction or HealingBoost
1579+
var latestStatus = CachedStatuses
1580+
.Where(s => s.Type == SpellEffect.HealingReduction || s.Type == SpellEffect.HealingBoost)
1581+
.OrderByDescending(s => s.StartTime)
1582+
.FirstOrDefault();
15791583

1580-
foreach (var status in CachedStatuses)
1584+
if (latestStatus == null)
15811585
{
1582-
if (status.Type == SpellEffect.GrievousWounds)
1583-
{
1584-
reductionModifier += Options.Instance.Combat.GrievousWoundsHealingReduction / 100.0;
1585-
}
1586-
else if (status.Type == SpellEffect.HealingBoost)
1587-
{
1588-
boostModifier += Options.Instance.Combat.HealingBoostPercentage / 100.0;
1589-
}
1586+
return healAmount;
15901587
}
15911588

1592-
// Cap reduction at 100% to avoid negative healing
1593-
reductionModifier = Math.Min(1.0, reductionModifier);
1589+
var percentage = latestStatus.Spell.Combat.PercentageEffect ?? 0;
15941590

1595-
// Apply multiplicative formula: Healing × (1 + boost) × (1 - reduction)
1596-
var finalModifier = (1.0 + boostModifier) * (1.0 - reductionModifier);
1591+
if (latestStatus.Type == SpellEffect.HealingReduction)
1592+
{
1593+
// Reduction: 0 to 100%
1594+
var reduction = Math.Clamp(percentage, 0, 100) / 100.0;
1595+
return (long)(healAmount * (1.0 - reduction));
1596+
}
1597+
1598+
if (latestStatus.Type == SpellEffect.HealingBoost)
1599+
{
1600+
// Boost: 0 to 1000%
1601+
var boost = Math.Clamp(percentage, 0, 1000) / 100.0;
1602+
return (long)(healAmount * (1.0 + boost));
1603+
}
15971604

1598-
return (long)(healAmount * finalModifier);
1605+
return healAmount;
15991606
}
16001607

16011608
public void SubVital(Vital vital, long amount)

Intersect.Server.Core/Migrations/Sqlite/Game/20251210000000_AddGrievousWoundsAndHealBoost.Designer.cs

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using Microsoft.EntityFrameworkCore.Migrations;
2+
3+
#nullable disable
4+
5+
namespace Intersect.Server.Migrations.Sqlite.Game
6+
{
7+
/// <inheritdoc />
8+
public partial class AddGrievousWoundsAndHealBoost : Migration
9+
{
10+
/// <inheritdoc />
11+
protected override void Up(MigrationBuilder migrationBuilder)
12+
{
13+
migrationBuilder.AddColumn<int>(
14+
name: "Combat_GrievousWoundsReduction",
15+
table: "Spells",
16+
type: "INTEGER",
17+
nullable: false,
18+
defaultValue: 0);
19+
20+
migrationBuilder.AddColumn<int>(
21+
name: "Combat_HealingBoostPercentage",
22+
table: "Spells",
23+
type: "INTEGER",
24+
nullable: false,
25+
defaultValue: 0);
26+
}
27+
28+
/// <inheritdoc />
29+
protected override void Down(MigrationBuilder migrationBuilder)
30+
{
31+
migrationBuilder.DropColumn(
32+
name: "Combat_GrievousWoundsReduction",
33+
table: "Spells");
34+
35+
migrationBuilder.DropColumn(
36+
name: "Combat_HealingBoostPercentage",
37+
table: "Spells");
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)