Skip to content

Commit

Permalink
Improved mod reporting, more mod support, small fixes. (#46)
Browse files Browse the repository at this point in the history
* Fix loading screen text.

* Add mod reporting build date parameter.

Old requests are now rejected.

* Attempt to fix skill null issue.

* Add support for new mods.

* Make mod report date parameter a string because the json parser sucks.

* Idle animations now inherit pawn pos/rotation/scale by default.
  • Loading branch information
Epicguru authored Apr 26, 2024
1 parent 75751be commit 350cdbf
Show file tree
Hide file tree
Showing 132 changed files with 1,544 additions and 90 deletions.
1 change: 1 addition & 0 deletions Languages/English/Keyed/Keys.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<LanguageData>

<AM.ModTitle>Epicguru's Melee Animation</AM.ModTitle>
<AM.LoadingText>Loading Melee Animation</AM.LoadingText>

<AM.Animation>Animation</AM.Animation>

Expand Down
9 changes: 8 additions & 1 deletion Source/1.5/AnimationMod/AMSettings/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,18 @@ public class Settings : SimpleSettingsBase
#region General
[Header("General")]
[Label("Always Animate Weapons")]
[Description("If enabled, melee weapons are animated whenever they are held, such as when standing drafted or while moving in combat.\nIf disabled, animations are limited to duels, special skills and executions.\n\n" +
[Description("If enabled, melee weapons are animated whenever they are held, such as when standing drafted, while moving in combat or while attacking.\nIf disabled, animations are limited to duels, special skills and executions.\n\n" +
"<b>Leaving this enabled can have a large performance impact on densely populated maps.\nPlease reload your save after changing this setting.</b>")]
[WebContent("AlwaysAnimate", true)]
public bool AnimateAtIdle = true;

[Label("Animations Use Body Posture")]
[Description("When enabled, simple animations (such as holding, walking and attacking with a melee weapon) will inherit body posture.\n" +
"This means that any other mods that modify pawn position, angle or size will also apply that change to the animated hands and weapon.\n" +
"Note: this does not apply to execution or duel animations, for technical reasons.")]
[VisibleIf(nameof(AnimateAtIdle))]
public bool InheritBodyPosture = true;

[Label("Enable Unique Skills")]
[Description("Enables or disables the Unique Skill system.\n" +
"Unique Skills are powerful attacks or abilities that are unlocked under certain conditions.\n" +
Expand Down
4 changes: 4 additions & 0 deletions Source/1.5/AnimationMod/AnimationMod.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,9 @@
<OutputPath>..\..\..\$(RimworldVersion)\Assemblies\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="echo Build time is $([System.DateTime]::UtcNow.ToString(&quot;yyyyMMddHHmmss&quot;)). Assign this value in ModReportingFacade.cs and update the AWS API!" />
</Target>

</Project>
24 changes: 13 additions & 11 deletions Source/1.5/AnimationMod/Core.cs
Original file line number Diff line number Diff line change
Expand Up @@ -253,16 +253,19 @@ private void LoadAllTweakData()
Warn($"{pair.Key} '{pair.Value.name}' has {pair.Value.wc} missing weapon tweak data.");
}

var toUpload = new List<MissingModRequest>();
toUpload.AddRange(modsAndMissingWeaponCount.Select(p => new MissingModRequest
{
ModID = p.Key,
ModName = p.Value.name,
WeaponCount = p.Value.wc
}));

if (Settings.SendStatistics && !Settings.IsFirstTimeRunning)
{
var modBuildTime = GetBuildDate(Assembly.GetExecutingAssembly());

var toUpload = new List<MissingModRequest>();
toUpload.AddRange(modsAndMissingWeaponCount.Select(p => new MissingModRequest
{
ModID = p.Key,
ModName = p.Value.name,
WeaponCount = p.Value.wc,
ModBuildTimeUtc = modBuildTime
}));

Task.Run(() => UploadMissingModData(toUpload)).ContinueWith(t =>
{
if (t.IsCompletedSuccessfully)
Expand Down Expand Up @@ -300,7 +303,6 @@ private void AddLateLoadEvents()
// Different thread loading...
LongEventHandler.QueueLongEvent(() =>
{
LongEventHandler.SetCurrentEventText("Load Advanced Animation Mod");
while (lateLoadActions.TryDequeue(out var pair))
{
try
Expand All @@ -313,7 +315,7 @@ private void AddLateLoadEvents()
Error($"Exception in post-load event (async) '{pair.title}':", e);
}
}
}, "Load Advanced Animation Mod", true, null);
}, "AM.LoadingText", true, null);

// Same thread loading...
LongEventHandler.QueueLongEvent(() =>
Expand All @@ -330,7 +332,7 @@ private void AddLateLoadEvents()
Error($"Exception in post-load event '{pair.title}':", e);
}
}
}, "Load Advanced Animation Mod", false, null);
}, "AM.LoadingText", false, null);
}

private void AddLateLoadAction(bool synchronous, string title, Action a)
Expand Down
31 changes: 24 additions & 7 deletions Source/1.5/AnimationMod/Idle/IdleControllerComp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using UnityEngine;
using Verse;
using LudeonTK;
using System.Linq;

namespace AM.Idle;

Expand Down Expand Up @@ -463,27 +464,43 @@ public void NotifyPawnDidMeleeAttack(Thing target, Verb_MeleeAttack verbUsed)

private Matrix4x4 MakePawnMatrix(Pawn pawn, bool north)
{
var mat = Matrix4x4.TRS(pawn.DrawPos + new Vector3(0, north ? -0.8f : 0.1f), Quaternion.identity, Vector3.one);
var offset = new Vector3(0, north ? -0.8f : 0.1f, 0);

Matrix4x4 animationMatrix;
if (Core.Settings.InheritBodyPosture)
{
var currentDrawResults = pawn.drawer.renderer.results;
animationMatrix = currentDrawResults.parms.matrix * Matrix4x4.Translate(offset);
}
else
{
animationMatrix = Matrix4x4.TRS(pawn.DrawPos + offset, Quaternion.identity, Vector3.one);
}

if (CurrentAnimation == null || !CurrentAnimation.Def.pointAtTarget)
return mat;
return animationMatrix;

float frame = CurrentAnimation.CurrentTime * 60f;
float lerp = Mathf.InverseLerp(CurrentAnimation.Def.returnToIdleStart, CurrentAnimation.Def.returnToIdleEnd, frame);

float idle = 0;
const float IDLE_ANGLE = 0;
float point = -pauseAngle;
if (CurrentAnimation.MirrorHorizontal)
{
point -= 180;
}

if (CurrentAnimation.Def.idleType == IdleType.AttackNorth)
{
point += 90;
if (CurrentAnimation.Def.idleType == IdleType.AttackSouth)
}
else if (CurrentAnimation.Def.idleType == IdleType.AttackSouth)
{
point -= 90;
}

float a = Mathf.LerpAngle(point, idle, lerp);
return mat * Matrix4x4.Rotate(Quaternion.Euler(0f, a, 0f));
float a = Mathf.LerpAngle(point, IDLE_ANGLE, lerp);
return animationMatrix * Matrix4x4.Rotate(Quaternion.Euler(0f, a, 0f));
}

public override void PostDeSpawn(Map map)
Expand Down Expand Up @@ -520,7 +537,7 @@ public override void PostExposeData()
if (!ShouldHaveSkills())
return;

if (skills == null)
if (skills == null || skills.Any(s => s == null))
PopulateSkills();

for (int i = 0; i < skills.Length; i++)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,35 @@
using ModRequestAPI.Backend.Facade;
using ModRequestAPI.Models;

namespace ModRequestAPI.Backend.Controllers
namespace ModRequestAPI.Backend.Controllers;

[Route("api/[controller]")]
[ApiController]
public class ModReportingController : ControllerBase
{
[Route("api/[controller]")]
[ApiController]
public class ModReportingController : ControllerBase
{
private readonly ModReportingFacade facade;
private readonly ModReportingFacade facade;

public ModReportingController(ModReportingFacade facade)
{
this.facade = facade;
}
public ModReportingController(ModReportingFacade facade)
{
this.facade = facade;
}

[HttpPost("report-missing-mods")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(string))]
public async Task<IActionResult> ReportMissingMod([FromBody] IEnumerable<MissingModRequest?> mods)
{
string? errorMsg = await facade.ReportMissingModAsync(mods);
if (errorMsg != null)
return BadRequest($"Error: {errorMsg}");
[HttpPost("report-missing-mods")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(string))]
public async Task<IActionResult> ReportMissingMod([FromBody] IEnumerable<MissingModRequest?> mods)
{
string? errorMsg = await facade.ReportMissingModAsync(mods);
if (errorMsg != null)
return BadRequest($"Error: {errorMsg}");

return Ok();
}
return Ok();
}

[HttpHead("health-check")]
[ProducesResponseType(StatusCodes.Status200OK)]
public IActionResult HealthCheck()
{
return Ok();
}
[HttpHead("health-check")]
[ProducesResponseType(StatusCodes.Status200OK)]
public IActionResult HealthCheck()
{
return Ok();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
using ModRequestAPI.Backend.DAL;
using System.Globalization;
using ModRequestAPI.Backend.DAL;
using ModRequestAPI.Models;

namespace ModRequestAPI.Backend.Facade;

public class ModReportingFacade
{
// CHANGE THIS DATE TIME WHEN UPDATING!
private static readonly DateTime currentBuildDate = DateTime.ParseExact("20240426161658", "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.None);

private readonly ModReportingDAL dal;

public ModReportingFacade(ModReportingDAL dal)
Expand All @@ -14,7 +18,7 @@ public ModReportingFacade(ModReportingDAL dal)

/// <summary>
/// Attempts to record a missing mod.
/// Returns false if an error occurs.
/// Returns the error message if an error occurs.
/// </summary>
public async Task<string?> ReportMissingModAsync(IEnumerable<MissingModRequest?> requests)
{
Expand All @@ -34,6 +38,17 @@ public ModReportingFacade(ModReportingDAL dal)

if (req.ModName.Length > 64)
return "Mod name too long";

if (req.ModBuildTimeUtc == null)
return "Missing mod build time, probably very old version of Melee Animation submitting the request.";

if (req.ModBuildTimeUtc.Value < currentBuildDate)
{
TimeSpan delta = currentBuildDate - req.ModBuildTimeUtc.Value;
TimeSpan deltaToNow = DateTime.UtcNow - currentBuildDate;
return "Your version of Melee Animation is not up to date, mod support request is rejected.\nPlease update to the latest version of the mod.\n" +
$"Last Melee Animation mod update: {deltaToNow.TotalDays} days ago. Your mod version is {delta.TotalDays} days out of date.";
}
}

return await dal.WriteModRequestAsync(requests!) ? null : "Internal error when writing to db.";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,54 @@
using ModRequestAPI.Backend.DAL;
using ModRequestAPI.Backend.Facade;

namespace ModRequestAPI.Backend
namespace ModRequestAPI.Backend;

public class Startup
{
public class Startup
{
public IConfiguration Configuration { get; }
public IConfiguration Configuration { get; }

public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

// This method gets called by the runtime. Use this method to add services to the container
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen();
// This method gets called by the runtime. Use this method to add services to the container
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen();

services.AddAWSLambdaHosting(LambdaEventSource.HttpApi);
services.AddDefaultAWSOptions(Configuration.GetAWSOptions());
services.AddAWSService<IAmazonDynamoDB>();
services.AddAWSLambdaHosting(LambdaEventSource.HttpApi);
services.AddDefaultAWSOptions(Configuration.GetAWSOptions());
services.AddAWSService<IAmazonDynamoDB>();

services.AddSingleton<ModReportingFacade>();
services.AddSingleton<ModReportingDAL>();
}
services.AddSingleton<ModReportingFacade>();
services.AddSingleton<ModReportingDAL>();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();

// Setup swagger:
app.UseSwagger();
app.UseSwaggerUI(op =>
{
op.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
op.RoutePrefix = string.Empty;
});
}

app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
app.UseDeveloperExceptionPage();

// Setup swagger:
app.UseSwagger();
app.UseSwaggerUI(op =>
{
endpoints.MapControllers();
op.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
op.RoutePrefix = string.Empty;
});
}

app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
11 changes: 9 additions & 2 deletions Source/1.5/ModRequestAPI.Models/MissingModRequest.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using Newtonsoft.Json;
using System;
using Newtonsoft.Json;

namespace ModRequestAPI.Models
{
public class MissingModRequest
public sealed class MissingModRequest
{
/// <summary>
/// The ID of the mod that is missing weapons.
Expand All @@ -21,5 +22,11 @@ public class MissingModRequest
/// </summary>
[JsonProperty("WeaponCount")]
public int WeaponCount { get; set; }

/// <summary>
/// The time and date, in UTC time, that the Melee Animation mod was built at.
/// </summary>
[JsonProperty("ModBuildTimeUtc")]
public DateTime? ModBuildTimeUtc { get; set; }
}
}
Loading

0 comments on commit 350cdbf

Please sign in to comment.