Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved mod reporting, more mod support, small fixes. #46

Merged
merged 6 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading