Skip to content

Commit

Permalink
Added AI_ReverseTrap project
Browse files Browse the repository at this point in the history
  • Loading branch information
ManlyMarco committed Nov 16, 2019
1 parent 9687fb3 commit f0f1acc
Show file tree
Hide file tree
Showing 7 changed files with 376 additions and 4 deletions.
89 changes: 89 additions & 0 deletions AI_ReverseTrap/AI_ReverseTrap.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{24E7EF57-8992-404A-B9A6-FFB9ABFEB4AB}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AI_ReverseTrap</RootNamespace>
<AssemblyName>AI_ReverseTrap</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>embedded</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>embedded</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Reference Include="0Harmony">
<HintPath>..\..\..\KKEC\KKAPI\paket-files\IllusionMods\IllusionLibs\lib\BepInEx\0Harmony.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="AIAPI">
<HintPath>..\..\..\KKEC\KKAPI\bin\AIAPI.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="AI_ExtensibleSaveFormat">
<HintPath>..\..\BepisPlugins\bin\BepInEx\plugins\AI_BepisPlugins\AI_ExtensibleSaveFormat.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Assembly-CSharp">
<HintPath>..\..\..\KKEC\KKAPI\paket-files\IllusionMods\IllusionLibs\lib\AISyoujyo\Assembly-CSharp.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="BepInEx">
<HintPath>..\..\..\KKEC\KKAPI\paket-files\IllusionMods\IllusionLibs\lib\BepInEx\BepInEx.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="BepInEx.Harmony">
<HintPath>..\..\..\KKEC\KKAPI\paket-files\IllusionMods\IllusionLibs\lib\BepInEx\BepInEx.Harmony.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Sirenix.Serialization">
<HintPath>..\..\..\KKEC\KKAPI\paket-files\IllusionMods\IllusionLibs\lib\AISyoujyo\Sirenix.Serialization.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="UnityEngine">
<HintPath>..\..\..\KKEC\KKAPI\paket-files\IllusionMods\IllusionLibs\lib\AISyoujyo\UnityEngine.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.AnimationModule">
<HintPath>..\..\..\KKEC\KKAPI\paket-files\IllusionMods\IllusionLibs\lib\AISyoujyo\UnityEngine.AnimationModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.AssetBundleModule">
<HintPath>..\..\..\KKEC\KKAPI\paket-files\IllusionMods\IllusionLibs\lib\AISyoujyo\UnityEngine.AssetBundleModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>..\..\..\KKEC\KKAPI\paket-files\IllusionMods\IllusionLibs\lib\AISyoujyo\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ReverseTrap.cs" />
<Compile Include="ReverseTrap.Hooks.cs" />
<Compile Include="ReverseTrapController.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
35 changes: 35 additions & 0 deletions AI_ReverseTrap/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.InteropServices;
using AI_ReverseTrap;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("AI_ReverseTrap")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AI_ReverseTrap")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("24e7ef57-8992-404a-b9a6-ffb9abfeb4ab")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion(ReverseTrap.Version)]
34 changes: 34 additions & 0 deletions AI_ReverseTrap/ReverseTrap.Hooks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using AIChara;
using AIProject;
using HarmonyLib;
using UnityEngine;

namespace AI_ReverseTrap
{
public partial class ReverseTrap
{
private static class Hooks
{
[HarmonyPostfix]
// void ActorAnimation.SetAnimatorController(RuntimeAnimatorController rac)
[HarmonyPatch(typeof(ActorAnimation), nameof(ActorAnimation.SetAnimatorController), typeof(RuntimeAnimatorController))]
private static void SetAnimatorPost(ActorAnimation __instance)
{
if (__instance.Actor != null && __instance.Actor.ChaControl != null)
{
var ctrl = __instance.Actor.ChaControl.GetComponent<ReverseTrapController>();
ctrl?.RefreshOverrideAnimations();
}
}

[HarmonyPostfix]
// RuntimeAnimatorController LoadAnimation(string assetBundleName, string assetName, string manifestName)
[HarmonyPatch(typeof(ChaControl), nameof(ChaControl.LoadAnimation), typeof(string), typeof(string), typeof(string))]
private static void SetAnimatorPost2(ChaControl __instance)
{
var ctrl = __instance.GetComponent<ReverseTrapController>();
ctrl?.RefreshOverrideAnimations();
}
}
}
}
116 changes: 116 additions & 0 deletions AI_ReverseTrap/ReverseTrap.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using System.Linq;
using BepInEx;
using BepInEx.Harmony;
using BepInEx.Logging;
using KKAPI;
using KKAPI.Chara;
using KKAPI.Maker;
using KKAPI.Maker.UI;
using UnityEngine;

namespace AI_ReverseTrap
{
[BepInPlugin(GUID, "Reverse Trap", Version)]
[BepInProcess("AI-Syoujyo")]
[BepInDependency(KoikatuAPI.GUID, KoikatuAPI.VersionConst)]
public partial class ReverseTrap : BaseUnityPlugin
{
public const string GUID = "ReverseTrap";
public const string Version = "1.0";

internal static new ManualLogSource Logger { get; private set; }

internal const int MaleSex = 0;
internal static AnimationClip[] MaleAnimations { get; private set; }
internal static readonly Dictionary<string, string> ToMaleAnimationLookup = new Dictionary<string, string>
{
{"Idle_00", "m_Idle_00"},
{"mc_f_move_00", "mc_m_move_00"},
{"mc_f_move_05", "mc_m_move_01"},
{"mc_f_move_08_L", "mc_m_move_05_L"},
{"mc_f_move_07_L", "mc_m_move_04_L"},
{"Turn_Idle_00", "m_Turn_Idle_00"},
{"mc_f_move_07_R", "mc_m_move_04_R"},
{"mc_f_move_08_R", "mc_m_move_05_R"},
{"mc_pf_move_02_S_in", "mc_m_move_02_S_in"},
{"mc_pf_move_02_M_in", "mc_m_move_02_M_in"},
{"mc_pf_move_02_L_in", "mc_m_move_02_L_in"},
{"mc_pf_move_02_S_loop", "mc_m_move_02_S_loop"},
{"mc_pf_move_02_M_loop", "mc_m_move_02_M_loop"},
{"mc_pf_move_02_L_loop", "mc_m_move_02_L_loop"},
{"mc_pf_move_03_S", "mc_m_move_03_S"},
{"mc_pf_move_03_M", "mc_m_move_03_M"},
{"mc_pf_move_03_L", "mc_m_move_03_L"},
{"mc_f_action_00", "mc_m_action_00"},
{"mc_pf_action_01", "mc_m_action_01"},
{"mc_pf_action_02", "mc_m_action_02"},
{"mc_pf_action_03", "mc_m_action_03"},
{"mc_pf_action_04", "mc_m_action_04"},
{"neko_01", "m_neko_00"},
{"pf_neko_04_in", "m_neko_01_in"},
{"pf_neko_04_loop", "m_neko_01_loop"},
{"pf_neko_05", "m_neko_02"},
{"pf_neko_06", "m_neko_03"},
{"chair_Idle_00_M", "m_chair_Idle_00"},
{"chair_16_S", "m_chair_00_S"},
{"chair_16_M", "m_chair_00_M"},
{"chair_16_L", "m_chair_00_L"},
{"chair_15_S", "m_chair_01_S"},
{"chair_15_M", "m_chair_01_M"},
{"chair_15_L", "m_chair_01_L"},
{"deskchair_Idle_00_M", "m_deskchair_Idle_00"},
{"mc_pf_move_00_01", "mc_m_move_00_01"},
{"mc_pf_move_05_01", "mc_m_move_01_01"},
{"mc_pf_move_00_02", "mc_m_move_00_02"},
{"mc_pf_move_05_02", "mc_m_move_01_02"},
{"pf_Idle_00_03_S", "m_Idle_00_03_S"},
{"pf_Idle_00_03_M", "m_Idle_00_03_M"},
{"pf_Idle_00_03_L", "m_Idle_00_03_L"},
{"mc_pf_move_00_03_S", "mc_m_move_00_03_S"},
{"mc_pf_move_00_03_M", "mc_m_move_00_03_M"},
{"mc_pf_move_00_03_L", "mc_m_move_00_03_L"}
};

private void Start()
{
Logger = base.Logger;

try
{
// Load male animation clips for overriding
var ab = AssetBundle.LoadFromFile(Application.dataPath + @"\..\abdata\animator\action\male\00.unity3d");
var anim = ab.LoadAsset<RuntimeAnimatorController>("m_player.controller");
MaleAnimations = anim.animationClips.ToArray();
ab.Unload(false);
Destroy(anim);
}
catch (Exception ex)
{
Logger.LogError("Failed to read male player animation data - " + ex);
}

if (MaleAnimations != null && MaleAnimations.Any())
{
CharacterApi.RegisterExtraBehaviour<ReverseTrapController>(GUID);

MakerAPI.RegisterCustomSubCategories += MakerAPI_RegisterCustomSubCategories;

HarmonyWrapper.PatchAll(typeof(Hooks));
}
}

private void MakerAPI_RegisterCustomSubCategories(object sender, RegisterSubCategoriesEvent e)
{
if (MakerAPI.GetMakerSex() != MaleSex)
{
var makerToggle = e.AddControl(new MakerToggle(MakerConstants.Body.All, "Male walking animations", this));

makerToggle.BindToFunctionController<ReverseTrapController, bool>(
controller => controller.ForceMaleAnimations,
(controller, value) => controller.ForceMaleAnimations = value);
}
}
}
}
91 changes: 91 additions & 0 deletions AI_ReverseTrap/ReverseTrapController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using System.Linq;
using ExtensibleSaveFormat;
using KKAPI;
using KKAPI.Chara;
using UnityEngine;

namespace AI_ReverseTrap
{
public class ReverseTrapController : CharaCustomFunctionController
{
private bool _forceMaleAnimations;

public bool ForceMaleAnimations
{
get => _forceMaleAnimations;
set
{
value = value && ChaControl.sex != ReverseTrap.MaleSex;

if (_forceMaleAnimations != value)
{
_forceMaleAnimations = value;

RefreshOverrideAnimations();
}
}
}

protected override void OnCardBeingSaved(GameMode currentGameMode)
{
if (ChaControl.sex != ReverseTrap.MaleSex)
{
var data = new PluginData { data = { [nameof(ForceMaleAnimations)] = ForceMaleAnimations } };
SetExtendedData(data);
}
else
SetExtendedData(null);
}

protected override void OnReload(GameMode currentGameMode)
{
if (ChaControl.sex != ReverseTrap.MaleSex)
{
var data = GetExtendedData()?.data;
ForceMaleAnimations = data != null && data.TryGetValue(nameof(ForceMaleAnimations), out var force) && force as bool? == true;
}
else
ForceMaleAnimations = false;
}

internal void RefreshOverrideAnimations()
{
var animBody = ChaControl.animBody;

if (ReverseTrap.MaleAnimations == null || animBody == null || animBody.runtimeAnimatorController == null) return;

var overrideControler = animBody.runtimeAnimatorController as AnimatorOverrideController;
if (overrideControler == null)
{
if (!ForceMaleAnimations) return;

overrideControler = new AnimatorOverrideController(animBody.runtimeAnimatorController);
animBody.runtimeAnimatorController = overrideControler;
}
else if (!ForceMaleAnimations)
{
animBody.runtimeAnimatorController = overrideControler.runtimeAnimatorController;
return;
}

var animationClips = animBody.runtimeAnimatorController.animationClips.ToArray();

foreach (var animationClip in animationClips)
{
if (ReverseTrap.ToMaleAnimationLookup.TryGetValue(animationClip.name, out var targetClipName))
{
var replacement = ReverseTrap.MaleAnimations.FirstOrDefault(clip => clip.name == targetClipName);
if (replacement != null)
{
ReverseTrap.Logger.LogDebug($"Replacing animation {animationClip.name} with {replacement.name}");
overrideControler[animationClip] = replacement;
}
else
{
ReverseTrap.Logger.LogWarning($"Failed to replace animation {animationClip.name} with {targetClipName} because replacement clip was not found");
}
}
}
}
}
}
6 changes: 6 additions & 0 deletions KK_BecomeTrap.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ VisualStudioVersion = 15.0.28010.2016
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KK_BecomeTrap", "KK_BecomeTrap\KK_BecomeTrap.csproj", "{F47E187C-9A8F-45E7-A778-5057E1D9B3F0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AI_ReverseTrap", "AI_ReverseTrap\AI_ReverseTrap.csproj", "{24E7EF57-8992-404A-B9A6-FFB9ABFEB4AB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -15,6 +17,10 @@ Global
{F47E187C-9A8F-45E7-A778-5057E1D9B3F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F47E187C-9A8F-45E7-A778-5057E1D9B3F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F47E187C-9A8F-45E7-A778-5057E1D9B3F0}.Release|Any CPU.Build.0 = Release|Any CPU
{24E7EF57-8992-404A-B9A6-FFB9ABFEB4AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{24E7EF57-8992-404A-B9A6-FFB9ABFEB4AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{24E7EF57-8992-404A-B9A6-FFB9ABFEB4AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{24E7EF57-8992-404A-B9A6-FFB9ABFEB4AB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Loading

0 comments on commit f0f1acc

Please sign in to comment.