Upload from upload_mods.ps1
This commit is contained in:
178
Scripts/Items/ModularActions/ActionModuleMetaConsumer.cs
Normal file
178
Scripts/Items/ModularActions/ActionModuleMetaConsumer.cs
Normal file
@@ -0,0 +1,178 @@
|
||||
using HarmonyLib;
|
||||
using KFCommonUtilityLib;
|
||||
using KFCommonUtilityLib.Scripts.Attributes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection.Emit;
|
||||
using UniLinq;
|
||||
|
||||
[TypeTarget(typeof(ItemActionRanged))]
|
||||
public class ActionModuleMetaConsumer
|
||||
{
|
||||
public string[] consumeDatas;
|
||||
public FastTags<TagGroup.Global>[] consumeTags;
|
||||
private float[] consumeStocks;
|
||||
private float[] consumeValues;
|
||||
private static FastTags<TagGroup.Global> TagsConsumption = FastTags<TagGroup.Global>.Parse("ConsumptionValue");
|
||||
|
||||
[HarmonyPatch(nameof(ItemAction.ReadFrom)), MethodTargetPostfix]
|
||||
private void Postfix_ReadFrom(DynamicProperties _props, ItemAction __instance)
|
||||
{
|
||||
string consumeData = string.Empty;
|
||||
_props.Values.TryGetValue("ConsumeData", out consumeData);
|
||||
_props.Values.TryGetValue("ConsumeTags", out string tags);
|
||||
FastTags<TagGroup.Global> commonTags = string.IsNullOrEmpty(tags) ? FastTags<TagGroup.Global>.none : FastTags<TagGroup.Global>.Parse(tags);
|
||||
if (string.IsNullOrEmpty(consumeData))
|
||||
{
|
||||
Log.Error($"No consume data found on item {__instance.item.Name} action {__instance.ActionIndex}");
|
||||
return;
|
||||
}
|
||||
|
||||
consumeDatas = consumeData.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToArray();
|
||||
consumeTags = consumeDatas.Select(s => FastTags<TagGroup.Global>.Parse(s) | commonTags | TagsConsumption).ToArray();
|
||||
consumeStocks = new float[consumeDatas.Length];
|
||||
consumeValues = new float[consumeDatas.Length];
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(ItemActionRanged), nameof(ItemAction.ExecuteAction)), MethodTargetTranspiler]
|
||||
private static IEnumerable<CodeInstruction> Transpiler_ItemActionRanged_ExecuteAction(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var codes = instructions.ToList();
|
||||
|
||||
var fld_started = AccessTools.Field(typeof(ItemActionRanged.ItemActionDataRanged), nameof(ItemActionRanged.ItemActionDataRanged.burstShotStarted));
|
||||
var fld_infinite = AccessTools.Field(typeof(ItemActionAttack), nameof(ItemActionAttack.InfiniteAmmo));
|
||||
var mtd_consume = AccessTools.Method(typeof(ItemActionRanged), nameof(ItemActionRanged.ConsumeAmmo));
|
||||
var lbd_module = generator.DeclareLocal(typeof(ActionModuleMetaConsumer));
|
||||
var prop_instance = AccessTools.PropertyGetter(typeof(IModuleContainerFor<ActionModuleMetaConsumer>), nameof(IModuleContainerFor<ActionModuleMetaConsumer>.Instance));
|
||||
var prop_itemvalue = AccessTools.PropertyGetter(typeof(ItemInventoryData), nameof(ItemInventoryData.itemValue));
|
||||
|
||||
for (int i = 0; i < codes.Count; i++)
|
||||
{
|
||||
if (codes[i].opcode == OpCodes.Stloc_S && ((LocalBuilder)codes[i].operand).LocalIndex == 6)
|
||||
{
|
||||
codes.InsertRange(i - 4, new[]
|
||||
{
|
||||
new CodeInstruction(OpCodes.Ldarg_0).WithLabels(codes[i - 4].ExtractLabels()),
|
||||
new CodeInstruction(OpCodes.Castclass, typeof(IModuleContainerFor<ActionModuleMetaConsumer>)),
|
||||
new CodeInstruction(OpCodes.Callvirt, prop_instance),
|
||||
new CodeInstruction(OpCodes.Stloc_S, lbd_module),
|
||||
});
|
||||
i += 4;
|
||||
}
|
||||
else if (codes[i].StoresField(fld_started) && codes[i - 1].LoadsConstant(1))
|
||||
{
|
||||
var lbl = generator.DefineLabel();
|
||||
var original = codes[i - 2];
|
||||
codes.InsertRange(i - 2, new[]
|
||||
{
|
||||
new CodeInstruction(OpCodes.Ldloc_S, lbd_module).WithLabels(original.ExtractLabels()),
|
||||
new CodeInstruction(OpCodes.Ldloc_0),
|
||||
CodeInstruction.LoadField(typeof(ItemActionData), nameof(ItemActionData.invData)),
|
||||
new CodeInstruction(OpCodes.Callvirt, prop_itemvalue),
|
||||
new CodeInstruction(OpCodes.Ldloc_S, 6),
|
||||
new CodeInstruction(OpCodes.Ldarg_0),
|
||||
CodeInstruction.LoadField(typeof(ItemActionAttack), nameof(ItemActionAttack.soundEmpty)),
|
||||
CodeInstruction.Call(typeof(ActionModuleMetaConsumer), nameof(CheckAndCacheMetaData)),
|
||||
new CodeInstruction(OpCodes.Brtrue_S, lbl),
|
||||
new CodeInstruction(OpCodes.Ret)
|
||||
});
|
||||
original.WithLabels(lbl);
|
||||
i += 10;
|
||||
}
|
||||
else if (codes[i].Calls(mtd_consume))
|
||||
{
|
||||
var lbl = generator.DefineLabel();
|
||||
for (int j = i - 1; j >= 0; j--)
|
||||
{
|
||||
if (codes[j].LoadsField(fld_infinite) && codes[j + 1].Branches(out _))
|
||||
{
|
||||
codes[j + 1].operand = lbl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
codes.InsertRange(i + 1, new[]
|
||||
{
|
||||
new CodeInstruction(OpCodes.Ldloc_S, lbd_module).WithLabels(lbl),
|
||||
new CodeInstruction(OpCodes.Ldloc_0),
|
||||
CodeInstruction.LoadField(typeof(ItemActionData), nameof(ItemActionData.invData)),
|
||||
new CodeInstruction(OpCodes.Callvirt, prop_itemvalue),
|
||||
new CodeInstruction(OpCodes.Ldloc_S, 6),
|
||||
CodeInstruction.Call(typeof(ActionModuleMetaConsumer), nameof(ConsumeMetaData)),
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return codes;
|
||||
}
|
||||
|
||||
public bool CheckAndCacheMetaData(ItemValue itemValue, EntityAlive holdingEntity, string soundEmpty)
|
||||
{
|
||||
for (int i = 0; i < consumeDatas.Length; i++)
|
||||
{
|
||||
string consumeData = consumeDatas[i];
|
||||
float stock = (float)itemValue.GetMetadata(consumeData);
|
||||
float consumption = EffectManager.GetValue(CustomEnums.CustomTaggedEffect, itemValue, float.MaxValue, holdingEntity, null, consumeTags[i]);
|
||||
if (stock < consumption)
|
||||
{
|
||||
holdingEntity.PlayOneShot(soundEmpty);
|
||||
return false;
|
||||
}
|
||||
consumeStocks[i] = stock;
|
||||
consumeValues[i] = consumption;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ConsumeMetaData(ItemValue itemValue, EntityAlive holdingEntity)
|
||||
{
|
||||
for (int i = 0; i < consumeDatas.Length; i++)
|
||||
{
|
||||
itemValue.SetMetadata(consumeDatas[i], consumeStocks[i] - consumeValues[i], TypedMetadataValue.TypeTag.Float);
|
||||
holdingEntity.MinEventContext.Tags = consumeTags[i];
|
||||
holdingEntity.FireEvent(CustomEnums.onRechargeValueUpdate, true);
|
||||
}
|
||||
}
|
||||
|
||||
//[HarmonyPatch(nameof(ItemAction.ExecuteAction)), MethodTargetPrefix]
|
||||
//private bool Prefix_ExecuteAction(ItemActionData _actionData, bool _bReleased, ItemActionRanged __instance)
|
||||
//{
|
||||
// ItemActionRanged.ItemActionDataRanged _data = _actionData as ItemActionRanged.ItemActionDataRanged;
|
||||
// EntityAlive holdingEntity = _actionData.invData.holdingEntity;
|
||||
// ItemValue itemValue = _actionData.invData.itemValue;
|
||||
// if (!_bReleased)
|
||||
// {
|
||||
// int burstCount = __instance.GetBurstCount(_actionData);
|
||||
// if (holdingEntity.inventory.holdingItemItemValue.PercentUsesLeft <= 0f || (_data.curBurstCount >= burstCount && burstCount != -1) || (!__instance.InfiniteAmmo && itemValue.Meta <= 0))
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// for (int i = 0; i < consumeDatas.Length; i++)
|
||||
// {
|
||||
// string consumeData = consumeDatas[i];
|
||||
// float stock = (float)itemValue.GetMetadata(consumeData);
|
||||
// float consumption = EffectManager.GetValue(CustomEnums.CustomTaggedEffect, itemValue, float.MaxValue, _actionData.invData.holdingEntity, null, consumeTags[i]);
|
||||
// if (stock < consumption)
|
||||
// {
|
||||
// if (!_data.bPressed)
|
||||
// {
|
||||
// holdingEntity.PlayOneShot(__instance.soundEmpty);
|
||||
// _data.bPressed = true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
// consumeStocks[i] = stock;
|
||||
// consumeValues[i] = consumption;
|
||||
// }
|
||||
|
||||
// for (int i = 0; i < consumeDatas.Length; i++)
|
||||
// {
|
||||
// itemValue.SetMetadata(consumeDatas[i], consumeStocks[i] - consumeValues[i], TypedMetadataValue.TypeTag.Float);
|
||||
// holdingEntity.MinEventContext.Tags = consumeTags[i];
|
||||
// holdingEntity.FireEvent(CustomEnums.onRechargeValueUpdate, true);
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
//}
|
||||
}
|
||||
Reference in New Issue
Block a user