rheirman / GiddyUpCore

20 stars 21 forks source link

Rotation change optimization #35

Closed kbatbouta closed 4 years ago

kbatbouta commented 4 years ago
kbatbouta commented 4 years ago

The patched property Thing.Rotation.Setter original code with some comments is

        set
    {

        if (value == rotationInt) /* This is what Saved us <--- */
        {
            return;
        }
        if (Spawned && (def.size.x != 1 || def.size.z != 1))
        {
            if (def.AffectsRegions)
            {
                Log.Warning("Changed rotation of a spawned non-single-cell thing which affects regions. This is not supported.");
            }
            RegionListersUpdater.DeregisterInRegions(this, Map);
            Map.thingGrid.Deregister(this);
        }
        rotationInt = value;

      /*
    ---> PATCH IS INJECTED HERE <---
     */

        if (Spawned && (def.size.x != 1 || def.size.z != 1))
        {
            Map.thingGrid.Register(this);
            RegionListersUpdater.RegisterInRegions(this, Map);
            if (def.AffectsReachability)
            {
                Map.reachability.ClearCache();
            }
        }
    }
kbatbouta commented 4 years ago

This can be used to change the draw offset in Pawn_DrawTracker_get_DrawPos so it doesn't have to check rotation every tick thus saving some run time.

rheirman commented 4 years ago

Thanks for your PR. Ill probably do an update next weekend, so I'll look into it then.

kbatbouta commented 4 years ago

UPDATE: now this is part of the fix...

I just tried a fix for Pawn_DrawTracker_get_DrawPos so far so good!! It needs more testing thus i'm gonna share the code here rather in the PR cuz i'm still figuring out bugs in it but so far it's about 5 times faster!

The new Pawn_DrawTracker_get_DrawPos

[HarmonyPatch(typeof(Pawn_DrawTracker), "get_DrawPos")]
static class Pawn_DrawTracker_get_DrawPos
{
static void Postfix(Pawn_DrawTracker __instance, ref Vector3 __result, ref Pawn ___pawn)
{
    ExtendedDataStorage store = Base.Instance.GetExtendedDataStorage();

    if (store == null) { return; }

    ExtendedPawnData pawnData = store.GetExtendedDataFor(___pawn);

    if (pawnData != null && pawnData.mount != null)
    {
        __result += pawnData.drawOffsetCache;
    }
    else if (pawnData != null)
    {
        pawnData.drawOffsetCache = Vector3.zero;
    }
}
...

The new Pawn_RotationTracker_UpdateRotation

[HarmonyPatch(typeof(Thing), "Rotation", MethodType.Setter)]
public static class Pawn_RotationTracker_UpdateRotation
{
public static MethodInfo mChanged = AccessTools.Method(typeof(Pawn_RotationTracker_UpdateRotation), nameof(Pawn_RotationTracker_UpdateRotation.RotChanged));

public static void RotChanged(Thing __instance)
{
    if (__instance != null && !(__instance is Pawn)) { return; }

    ExtendedDataStorage store = Base.Instance.GetExtendedDataStorage();

    if (store == null) { return; }

    var pawn = __instance as Pawn;
    if (!__instance.Destroyed && pawn.jobs != null && pawn.jobs.curDriver is JobDriver_Mounted jobDriver)
    {
        var rotation = jobDriver.Rider.Rotation;
        __instance.Rotation = rotation;

        ExtendedPawnData pawnData = store.GetExtendedDataFor(jobDriver.Rider);

        if (pawnData != null && pawnData.mount != null)
        {
            pawnData.drawOffsetCache = Vector3.zero;
            __instance.Rotation = rotation;

            if (pawnData.drawOffset != -1)
                pawnData.drawOffsetCache.z = pawnData.drawOffset;

            if (pawnData.mount.def.HasModExtension<DrawingOffsetPatch>())
            {
                pawnData.drawOffsetCache += AddCustomOffsets(jobDriver.Rider, pawnData);
            }

            if (rotation == Rot4.South)
            {
                AnimalRecord value;
                bool found = Base.drawSelecter.Value.InnerList.TryGetValue(pawnData.mount.def.defName, out value);
                if (found && value.isSelected)
                {
                    pawnData.drawOffsetCache.y = -1;
                }

            }
        }
    }
...
rheirman commented 4 years ago

Hey, what's the status on this? Is it working without any issues now? I'm asking because in your latest post you said it needs more testing.

kbatbouta commented 4 years ago

It is working great!! i've been using it ever since with no problems.

kbatbouta commented 4 years ago

I updated all of the GiddyUp mods and and WTH and GiddyUp Mechaniods. I posted them on dubs discord server.

kbatbouta commented 4 years ago

This is an experimental build using Zetrith Prepatcher it's adding the storage units to type Pawns as new field. It require the Prepatcher loaded right after harmony. GiddyUpCore.zip

https://github.com/Zetrith/Prepatcher