Upload from upload_mods.ps1
This commit is contained in:
80
.gitignore
vendored
Normal file
80
.gitignore
vendored
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
# Build and Object Folders
|
||||||
|
bin/
|
||||||
|
obj/
|
||||||
|
|
||||||
|
# Nuget packages directory
|
||||||
|
packages/
|
||||||
|
|
||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Rr]elease/
|
||||||
|
x64/
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.pch
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
*.ncrunch*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help
|
||||||
|
UpgradeLog*.XML
|
||||||
|
|
||||||
|
# Lightswitch
|
||||||
|
_Pvt_Extensions
|
||||||
|
GeneratedArtifacts
|
||||||
|
*.xap
|
||||||
|
ModelManifest.xml
|
||||||
|
|
||||||
|
#Backup file
|
||||||
|
*.bak
|
||||||
|
|
||||||
|
#zzzili
|
||||||
|
v15/
|
||||||
|
|
||||||
86
FullautoLauncher.csproj
Normal file
86
FullautoLauncher.csproj
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<?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>{F485DD15-9EDF-42C3-A31B-66AE0DFB7356}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>FullautoLauncher</RootNamespace>
|
||||||
|
<AssemblyName>FullautoLauncher</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>.\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>portable</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>.\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="0Harmony">
|
||||||
|
<HintPath>..\0_TFP_Harmony\0Harmony.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Assembly-CSharp">
|
||||||
|
<HintPath>..\..\7DaysToDie_Data\Managed\Assembly-CSharp.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="LogLibrary">
|
||||||
|
<HintPath>..\..\7DaysToDie_Data\Managed\LogLibrary.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="UnityEngine">
|
||||||
|
<HintPath>..\..\7DaysToDie_Data\Managed\UnityEngine.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.AnimationModule">
|
||||||
|
<HintPath>..\..\7DaysToDie_Data\Managed\UnityEngine.AnimationModule.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.CoreModule">
|
||||||
|
<HintPath>..\..\7DaysToDie_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Harmony\Init.cs" />
|
||||||
|
<Compile Include="Harmony\Patches.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Scripts\ItemActions\ItemActionBetterLauncher.cs" />
|
||||||
|
<Compile Include="Scripts\ProjectileManager\CustomProjectileManager.cs" />
|
||||||
|
<Compile Include="Scripts\ProjectileManager\ParameterHolderAbs.cs" />
|
||||||
|
<Compile Include="Scripts\ProjectileManager\PHGameObject.cs" />
|
||||||
|
<Compile Include="Scripts\ProjectileManager\PHSimpleMesh.cs" />
|
||||||
|
<Compile Include="Scripts\ProjectileManager\PIGGameObject.cs" />
|
||||||
|
<Compile Include="Scripts\ProjectileManager\ProjectileItemGroupAbs.cs" />
|
||||||
|
<Compile Include="Scripts\ProjectileManager\PIGSimpleMesh.cs" />
|
||||||
|
<Compile Include="Scripts\ProjectileManager\ProjectileParams.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="ModInfo.xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
||||||
BIN
FullautoLauncher.dll
Normal file
BIN
FullautoLauncher.dll
Normal file
Binary file not shown.
BIN
FullautoLauncher.pdb
Normal file
BIN
FullautoLauncher.pdb
Normal file
Binary file not shown.
21
Harmony/Init.cs
Normal file
21
Harmony/Init.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using FullautoLauncher.Scripts.ProjectileManager;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
public class FullautoLauncherInit : IModApi
|
||||||
|
{
|
||||||
|
private static bool inited = false;
|
||||||
|
public void InitMod(Mod _modInstance)
|
||||||
|
{
|
||||||
|
if(inited)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
inited = true;
|
||||||
|
Log.Out(" Loading Patch: " + GetType());
|
||||||
|
var harmony = new HarmonyLib.Harmony(GetType().ToString());
|
||||||
|
harmony.PatchAll(Assembly.GetExecutingAssembly());
|
||||||
|
|
||||||
|
ModEvents.UnityUpdate.RegisterHandler(CustomProjectileManager.Update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
208
Harmony/Patches.cs
Normal file
208
Harmony/Patches.cs
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
using FullautoLauncher.Scripts.ProjectileManager;
|
||||||
|
using HarmonyLib;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
[HarmonyPatch]
|
||||||
|
class ItemActionLauncherProjectilePatch
|
||||||
|
{
|
||||||
|
public static FieldInfo fldinfo_meta = AccessTools.Field(typeof(ItemValue), nameof(ItemValue.Meta));
|
||||||
|
public static MethodInfo mtdinfo_gbc = AccessTools.Method(typeof(ItemActionRanged), nameof(ItemActionRanged.GetBurstCount), new Type[] { typeof(ItemActionData) });
|
||||||
|
public static MethodInfo mtdinfo_gac = AccessTools.Method(typeof(AnimatorRangedReloadState), "GetAmmoCount", new Type[] { typeof(EntityAlive), typeof(ItemValue), typeof(Int32) });
|
||||||
|
public static MethodInfo mtdinfo_sta = AccessTools.Method(typeof(GameObject), nameof(GameObject.SetActive), new Type[] { typeof(bool) });
|
||||||
|
public static int getProjectileCount(ItemActionData _data)
|
||||||
|
{
|
||||||
|
int rps = 1;
|
||||||
|
ItemInventoryData invD = _data != null ? _data.invData : null;
|
||||||
|
if (invD != null)
|
||||||
|
{
|
||||||
|
ItemClass item = invD.itemValue != null ? invD.itemValue.ItemClass : null;
|
||||||
|
rps = (int)EffectManager.GetValue(PassiveEffects.RoundRayCount, invD.itemValue, rps, invD.holdingEntity, null, item != null ? item.ItemTags | _data.ActionTags : default);
|
||||||
|
}
|
||||||
|
return rps > 0 ? rps : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(ItemActionLauncher), nameof(ItemActionLauncher.StartHolding))]
|
||||||
|
[HarmonyTranspiler]
|
||||||
|
private static IEnumerable<CodeInstruction> Transpiler_StartHolding_ItemActionLauncher(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||||
|
{
|
||||||
|
var codes = new List<CodeInstruction>(instructions);
|
||||||
|
|
||||||
|
LocalBuilder lbd_rps = generator.DeclareLocal(typeof(int));
|
||||||
|
|
||||||
|
var list_insert = new List<CodeInstruction>
|
||||||
|
{
|
||||||
|
new CodeInstruction(OpCodes.Ldloc_S, lbd_rps),
|
||||||
|
new CodeInstruction(OpCodes.Mul)
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < codes.Count; i++)
|
||||||
|
{
|
||||||
|
if ( codes[i].LoadsField(fldinfo_meta))
|
||||||
|
{
|
||||||
|
codes.InsertRange(i + 1, list_insert);
|
||||||
|
i += list_insert.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
codes.InsertRange(0, new CodeInstruction[]
|
||||||
|
{
|
||||||
|
new CodeInstruction(OpCodes.Ldarg_1),
|
||||||
|
CodeInstruction.Call(typeof(ItemActionLauncherProjectilePatch), nameof(getProjectileCount), new Type[] { typeof(ItemActionData) }),
|
||||||
|
new CodeInstruction(OpCodes.Stloc_S, lbd_rps)
|
||||||
|
});
|
||||||
|
|
||||||
|
return codes;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(ItemActionLauncher), nameof(ItemActionLauncher.ItemActionEffects))]
|
||||||
|
[HarmonyTranspiler]
|
||||||
|
private static IEnumerable<CodeInstruction> Transpiler_ItemActionEffects_ItemActionLauncher(IEnumerable<CodeInstruction> instructions)
|
||||||
|
{
|
||||||
|
var codes = new List<CodeInstruction>(instructions);
|
||||||
|
|
||||||
|
for(int i = 0, totali = codes.Count; i < totali; i++)
|
||||||
|
{
|
||||||
|
if (codes[i].Calls(mtdinfo_gbc))
|
||||||
|
{
|
||||||
|
codes.InsertRange(i + 1, new CodeInstruction[]
|
||||||
|
{
|
||||||
|
new CodeInstruction(OpCodes.Ldarg_2),
|
||||||
|
CodeInstruction.Call(typeof(ItemActionLauncherProjectilePatch), nameof(getProjectileCount), new Type[] { typeof(ItemActionData) })
|
||||||
|
});
|
||||||
|
codes.RemoveRange(i - 2, 3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return codes;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(ItemActionLauncher), nameof(ItemActionLauncher.ConsumeAmmo))]
|
||||||
|
[HarmonyTranspiler]
|
||||||
|
private static IEnumerable<CodeInstruction> Transpiler_ConsumeAmmo_ItemActionLauncher(IEnumerable<CodeInstruction> instructions)
|
||||||
|
{
|
||||||
|
var codes = new List<CodeInstruction>()
|
||||||
|
{
|
||||||
|
new CodeInstruction(OpCodes.Ldarg_0),
|
||||||
|
new CodeInstruction(OpCodes.Ldarg_1),
|
||||||
|
CodeInstruction.Call(typeof(ItemActionRanged), nameof(ItemActionRanged.ConsumeAmmo), new Type[]{ typeof(ItemActionData) }),
|
||||||
|
new CodeInstruction(OpCodes.Ret)
|
||||||
|
};
|
||||||
|
|
||||||
|
return codes;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(ItemClass), nameof(ItemClass.ExecuteAction))]
|
||||||
|
[HarmonyTranspiler]
|
||||||
|
private static IEnumerable<CodeInstruction> Transpiler_ExecuteAction_ItemClass(IEnumerable<CodeInstruction> instructions)
|
||||||
|
{
|
||||||
|
var codes = new List<CodeInstruction>(instructions);
|
||||||
|
|
||||||
|
for (int i = 0; i < codes.Count; i++)
|
||||||
|
{
|
||||||
|
if (codes[i].opcode == OpCodes.Isinst && codes[i].OperandIs(typeof(ItemActionLauncher)))
|
||||||
|
{
|
||||||
|
codes.RemoveRange(i - 2, 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return codes;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(AnimatorRangedReloadState), nameof(AnimatorRangedReloadState.OnStateEnter))]
|
||||||
|
[HarmonyTranspiler]
|
||||||
|
private static IEnumerable<CodeInstruction> Transpiler_OnStateEnter_AnimatorRangedReloadState(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||||
|
{
|
||||||
|
var codes = new List<CodeInstruction>(instructions);
|
||||||
|
|
||||||
|
LocalBuilder lbd_rps = generator.DeclareLocal(typeof(int));
|
||||||
|
|
||||||
|
for (int i = 0, totali = codes.Count; i < totali; i++)
|
||||||
|
{
|
||||||
|
if (codes[i].Calls(mtdinfo_gac))
|
||||||
|
{
|
||||||
|
codes.InsertRange(i + 1, new CodeInstruction[]
|
||||||
|
{
|
||||||
|
new CodeInstruction(OpCodes.Ldloc_S, 6),
|
||||||
|
CodeInstruction.Call(typeof(ItemActionLauncherProjectilePatch), nameof(getProjectileCount), new Type[] { typeof(ItemActionData) }),
|
||||||
|
new CodeInstruction(OpCodes.Stloc_S, lbd_rps),
|
||||||
|
new CodeInstruction(OpCodes.Ldloc_S, lbd_rps),
|
||||||
|
new CodeInstruction(OpCodes.Mul)
|
||||||
|
});
|
||||||
|
totali += 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//else if (codes[i].opcode == OpCodes.Ldc_R4 && codes[i].OperandIs(0.005f))
|
||||||
|
//{
|
||||||
|
// codes.Insert(i + 2, new CodeInstruction(OpCodes.Ldc_R4, 0f));
|
||||||
|
// codes.RemoveRange(i - 2, 4);
|
||||||
|
// break;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
return codes;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(ItemActionLauncher), nameof(ItemActionLauncher.instantiateProjectile))]
|
||||||
|
[HarmonyPrefix]
|
||||||
|
private static bool Prefix_instantiateProjectile_ItemActionLauncher(ref Vector3 _positionOffset)
|
||||||
|
{
|
||||||
|
_positionOffset = Vector3.zero;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(ItemActionLauncher), nameof(ItemActionLauncher.instantiateProjectile))]
|
||||||
|
[HarmonyPostfix]
|
||||||
|
private static void Postfix_instantiateProjectile_ItemActionLauncher(Transform __result, ItemActionLauncher __instance)
|
||||||
|
{
|
||||||
|
if (__instance.Properties.Contains("VisibleInMag") && !__instance.Properties.GetBool("VisibleInMag"))
|
||||||
|
{
|
||||||
|
__result.gameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(GameManager), nameof(GameManager.FixedUpdate))]
|
||||||
|
[HarmonyPostfix]
|
||||||
|
private static void Postfix_FixedUpdate_GameManager()
|
||||||
|
{
|
||||||
|
CustomProjectileManager.FixedUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
//custom projectile manager workarounds
|
||||||
|
private static void ParseProjectileType(XElement _node)
|
||||||
|
{
|
||||||
|
string itemName = _node.GetAttribute("name");
|
||||||
|
if (string.IsNullOrEmpty(itemName))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ItemClass item = ItemClass.GetItemClass(itemName);
|
||||||
|
for (int i = 0; i < item.Actions.Length; i++)
|
||||||
|
{
|
||||||
|
if (item.Actions[i] is ItemActionProjectile proj && proj.Properties.Contains("CustomProjectileType"))
|
||||||
|
{
|
||||||
|
CustomProjectileManager.InitClass(item, proj.Properties.GetString("CustomProjectileType"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(ItemClassesFromXml), nameof(ItemClassesFromXml.parseItem))]
|
||||||
|
[HarmonyPostfix]
|
||||||
|
private static void Postfix_parseItem_ItemClassesFromXml(XElement _node)
|
||||||
|
{
|
||||||
|
ParseProjectileType(_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(GameManager), nameof(GameManager.SaveAndCleanupWorld))]
|
||||||
|
[HarmonyPostfix]
|
||||||
|
private static void Postfix_SaveAndCleanupWorld_GameManager()
|
||||||
|
{
|
||||||
|
CustomProjectileManager.Cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
9
ModInfo.xml
Normal file
9
ModInfo.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<xml>
|
||||||
|
<Name value="FullautoLauncher" />
|
||||||
|
<DisplayName value="Fullauto Launcher" />
|
||||||
|
<Description value="Change the way Launcher class fires and initializes projectile, so that making a full automatic launcher is possible." />
|
||||||
|
<Author value="closer_ex" />
|
||||||
|
<Version value="1.3.2" />
|
||||||
|
</xml>
|
||||||
36
Properties/AssemblyInfo.cs
Normal file
36
Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// 有关程序集的一般信息由以下
|
||||||
|
// 控制。更改这些特性值可修改
|
||||||
|
// 与程序集关联的信息。
|
||||||
|
[assembly: AssemblyTitle("FullautoLauncher")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("FullautoLauncher")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2022")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||||
|
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||||
|
//请将此类型的 ComVisible 特性设置为 true。
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||||
|
[assembly: Guid("f485dd15-9edf-42c3-a31b-66ae0dfb7356")]
|
||||||
|
|
||||||
|
// 程序集的版本信息由下列四个值组成:
|
||||||
|
//
|
||||||
|
// 主版本
|
||||||
|
// 次版本
|
||||||
|
// 生成号
|
||||||
|
// 修订号
|
||||||
|
//
|
||||||
|
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
|
||||||
|
//通过使用 "*",如下所示:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
138
Scripts/ItemActions/ItemActionBetterLauncher.cs
Normal file
138
Scripts/ItemActions/ItemActionBetterLauncher.cs
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
using Audio;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine.Scripting;
|
||||||
|
using UnityEngine;
|
||||||
|
using FullautoLauncher.Scripts.ProjectileManager;
|
||||||
|
using static ItemActionLauncher;
|
||||||
|
using static ItemActionRanged;
|
||||||
|
|
||||||
|
[Preserve]
|
||||||
|
public class ItemActionBetterLauncher : ItemActionRanged
|
||||||
|
{
|
||||||
|
private IProjectileItemGroup group;
|
||||||
|
public override ItemActionData CreateModifierData(ItemInventoryData _invData, int _indexInEntityOfAction)
|
||||||
|
{
|
||||||
|
return new ItemActionDataBetterLauncher(_invData, _indexInEntityOfAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ReadFrom(DynamicProperties _props)
|
||||||
|
{
|
||||||
|
base.ReadFrom(_props);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void StartHolding(ItemActionData _actionData)
|
||||||
|
{
|
||||||
|
base.StartHolding(_actionData);
|
||||||
|
ItemActionDataBetterLauncher ItemActionDataBetterLauncher = (ItemActionDataBetterLauncher)_actionData;
|
||||||
|
ItemValue launcherValue = ItemActionDataBetterLauncher.invData.itemValue;
|
||||||
|
ItemClass forId = ItemClass.GetForId(ItemClass.GetItem(MagazineItemNames[launcherValue.SelectedAmmoTypeIndex], false).type);
|
||||||
|
group = CustomProjectileManager.Get(forId.Name);
|
||||||
|
if (launcherValue.Meta != 0 && GetMaxAmmoCount(ItemActionDataBetterLauncher) != 0)
|
||||||
|
{
|
||||||
|
group.Pool(launcherValue.Meta * (int)EffectManager.GetValue(PassiveEffects.RoundRayCount, launcherValue, 1f, ItemActionDataBetterLauncher.invData.holdingEntity));
|
||||||
|
}
|
||||||
|
ItemActionDataBetterLauncher.info = new ProjectileParams.ItemInfo()
|
||||||
|
{
|
||||||
|
actionData = ItemActionDataBetterLauncher,
|
||||||
|
itemProjectile = forId,
|
||||||
|
itemActionProjectile = (ItemActionProjectile)((forId.Actions[0] is ItemActionProjectile) ? forId.Actions[0] : forId.Actions[1]),
|
||||||
|
itemValueLauncher = launcherValue,
|
||||||
|
itemValueProjectile = new ItemValue(forId.Id)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnModificationsChanged(ItemActionData _data)
|
||||||
|
{
|
||||||
|
base.OnModificationsChanged(_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void StopHolding(ItemActionData _data)
|
||||||
|
{
|
||||||
|
base.StopHolding(_data);
|
||||||
|
ItemActionDataBetterLauncher itemActionDataLauncher = (ItemActionDataBetterLauncher)_data;
|
||||||
|
itemActionDataLauncher.info = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SwapAmmoType(EntityAlive _entity, int _ammoItemId = -1)
|
||||||
|
{
|
||||||
|
base.SwapAmmoType(_entity, _ammoItemId);
|
||||||
|
ItemActionDataBetterLauncher ItemActionDataBetterLauncher = (ItemActionDataBetterLauncher)_entity.inventory.holdingItemData.actionData[ActionIndex];
|
||||||
|
ItemValue itemValue = ItemActionDataBetterLauncher.invData.itemValue;
|
||||||
|
ItemClass forId = ItemClass.GetForId(ItemClass.GetItem(MagazineItemNames[itemValue.SelectedAmmoTypeIndex], false).type);
|
||||||
|
group = CustomProjectileManager.Get(forId.Name);
|
||||||
|
ItemActionDataBetterLauncher.info = new ProjectileParams.ItemInfo()
|
||||||
|
{
|
||||||
|
actionData = ItemActionDataBetterLauncher,
|
||||||
|
itemProjectile = forId,
|
||||||
|
itemActionProjectile = (ItemActionProjectile)((forId.Actions[0] is ItemActionProjectile) ? forId.Actions[0] : forId.Actions[1]),
|
||||||
|
itemValueLauncher = itemValue,
|
||||||
|
itemValueProjectile = new ItemValue(forId.Id)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Vector3 fireShot(int _shotIdx, ItemActionDataRanged _actionData, ref bool hitEntity)
|
||||||
|
{
|
||||||
|
hitEntity = true;
|
||||||
|
return Vector3.zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ItemActionEffects(GameManager _gameManager, ItemActionData _actionData, int _firingState, Vector3 _startPos, Vector3 _direction, int _userData = 0)
|
||||||
|
{
|
||||||
|
base.ItemActionEffects(_gameManager, _actionData, _firingState, _startPos, _direction, _userData);
|
||||||
|
if (_firingState == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
EntityAlive entity = _actionData.invData.holdingEntity;
|
||||||
|
if (entity.isEntityRemote && GameManager.IsDedicatedServer)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ItemActionDataBetterLauncher ItemActionDataBetterLauncher = (ItemActionDataBetterLauncher)_actionData;
|
||||||
|
ItemValue holdingItemItemValue = _actionData.invData.holdingEntity.inventory.holdingItemItemValue;
|
||||||
|
ItemClass forId = ItemClass.GetForId(ItemClass.GetItem(MagazineItemNames[holdingItemItemValue.SelectedAmmoTypeIndex], false).type);
|
||||||
|
int projCount = (int)EffectManager.GetValue(PassiveEffects.RoundRayCount, ItemActionDataBetterLauncher.invData.itemValue, 1f, ItemActionDataBetterLauncher.invData.holdingEntity);
|
||||||
|
if (projCount <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ItemActionDataBetterLauncher.info == null)
|
||||||
|
{
|
||||||
|
Log.Error("null info!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ItemActionDataBetterLauncher.projectileJoint == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Vector3 realStartPosition = ItemActionDataBetterLauncher.projectileJoint.position + Origin.position;
|
||||||
|
for (int i = 0; i < projCount; i++)
|
||||||
|
{
|
||||||
|
var par = group.Fire(entity.entityId, ItemActionDataBetterLauncher.info, _startPos, realStartPosition, getDirectionOffset(ItemActionDataBetterLauncher, _direction, i), entity, hitmaskOverride);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void getImageActionEffectsStartPosAndDirection(ItemActionData _actionData, out Vector3 _startPos, out Vector3 _direction)
|
||||||
|
{
|
||||||
|
Ray lookRay = _actionData.invData.holdingEntity.GetLookRay();
|
||||||
|
_startPos = lookRay.origin;
|
||||||
|
_direction = lookRay.direction;//getDirectionOffset(ItemActionDataBetterLauncher, lookRay.direction, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ItemActionDataBetterLauncher : ItemActionDataRanged
|
||||||
|
{
|
||||||
|
public ItemActionDataBetterLauncher(ItemInventoryData _invData, int _indexInEntityOfAction)
|
||||||
|
: base(_invData, _indexInEntityOfAction)
|
||||||
|
{
|
||||||
|
projectileJoint = (_invData.model?.FindInChilds("ProjectileJoint", false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transform projectileJoint;
|
||||||
|
public ProjectileParams.ItemInfo info;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
51
Scripts/ProjectileManager/CustomProjectileManager.cs
Normal file
51
Scripts/ProjectileManager/CustomProjectileManager.cs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FullautoLauncher.Scripts.ProjectileManager
|
||||||
|
{
|
||||||
|
public static class CustomProjectileManager
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<string, IProjectileItemGroup> dict_item_groups = new Dictionary<string, IProjectileItemGroup>();
|
||||||
|
|
||||||
|
public static IProjectileItemGroup Get(string name) => dict_item_groups[name];
|
||||||
|
|
||||||
|
public static void InitClass(ItemClass item, string typename)
|
||||||
|
{
|
||||||
|
if (dict_item_groups.ContainsKey(item.Name))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Type type = ReflectionHelpers.GetTypeWithPrefix("PIG", typename);
|
||||||
|
IProjectileItemGroup group = (IProjectileItemGroup)Activator.CreateInstance(type, new object[] {item});
|
||||||
|
dict_item_groups.Add(item.Name, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Update()
|
||||||
|
{
|
||||||
|
foreach (var group in dict_item_groups.Values)
|
||||||
|
{
|
||||||
|
group.Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FixedUpdate()
|
||||||
|
{
|
||||||
|
foreach (var group in dict_item_groups.Values)
|
||||||
|
{
|
||||||
|
group.FixedUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Cleanup()
|
||||||
|
{
|
||||||
|
foreach (var group in dict_item_groups.Values)
|
||||||
|
{
|
||||||
|
group.Cleanup();
|
||||||
|
}
|
||||||
|
dict_item_groups.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
36
Scripts/ProjectileManager/PHGameObject.cs
Normal file
36
Scripts/ProjectileManager/PHGameObject.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace FullautoLauncher.Scripts.ProjectileManager
|
||||||
|
{
|
||||||
|
public class PHGameObject : ParameterHolderAbs, IDisposable
|
||||||
|
{
|
||||||
|
public Transform Transform { get; }
|
||||||
|
public PHGameObject(Transform transform, ProjectileParams par) : base(par)
|
||||||
|
{
|
||||||
|
Transform = transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Fire()
|
||||||
|
{
|
||||||
|
Transform.gameObject.SetActive(true);
|
||||||
|
UpdatePosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdatePosition()
|
||||||
|
{
|
||||||
|
Vector3 realPos = par.renderPosition - Origin.position;
|
||||||
|
Transform.position = realPos;
|
||||||
|
Transform.LookAt(realPos + par.moveDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
GameObject.Destroy(Transform.gameObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
48
Scripts/ProjectileManager/PHSimpleMesh.cs
Normal file
48
Scripts/ProjectileManager/PHSimpleMesh.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
using static AstarManager;
|
||||||
|
|
||||||
|
namespace FullautoLauncher.Scripts.ProjectileManager
|
||||||
|
{
|
||||||
|
public class SimpleMeshTransformData
|
||||||
|
{
|
||||||
|
public readonly Matrix4x4 TRS;
|
||||||
|
public readonly Bounds bounds;
|
||||||
|
|
||||||
|
public SimpleMeshTransformData(Matrix4x4 TRS, Bounds bounds)
|
||||||
|
{
|
||||||
|
this.TRS = TRS;
|
||||||
|
this.bounds = bounds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PHSimpleMesh : ParameterHolderAbs
|
||||||
|
{
|
||||||
|
public Matrix4x4 finalMat;
|
||||||
|
public RenderParams renderParams;
|
||||||
|
private SimpleMeshTransformData data;
|
||||||
|
|
||||||
|
public PHSimpleMesh(ProjectileParams par, SimpleMeshTransformData data, in RenderParams renderPar) : base(par)
|
||||||
|
{
|
||||||
|
this.data = data;
|
||||||
|
this.renderParams = renderPar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Fire()
|
||||||
|
{
|
||||||
|
UpdatePosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdatePosition()
|
||||||
|
{
|
||||||
|
finalMat = Matrix4x4.Translate(par.renderPosition - Origin.position) * Matrix4x4.Rotate(Quaternion.LookRotation(par.moveDir)) * data.TRS;
|
||||||
|
Bounds bounds = data.bounds;
|
||||||
|
bounds.center = finalMat.MultiplyPoint3x4(bounds.center);
|
||||||
|
renderParams.worldBounds = bounds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
49
Scripts/ProjectileManager/PIGGameObject.cs
Normal file
49
Scripts/ProjectileManager/PIGGameObject.cs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
using FullautoLauncher.Scripts.ProjectileManager;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class PIGGameObject : ProjectileItemGroupAbs<PHGameObject>
|
||||||
|
{
|
||||||
|
public PIGGameObject(ItemClass item) : base(item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Cleanup()
|
||||||
|
{
|
||||||
|
foreach (var proj in queue_pool)
|
||||||
|
{
|
||||||
|
proj.Dispose();
|
||||||
|
}
|
||||||
|
queue_pool.Clear();
|
||||||
|
|
||||||
|
foreach (var set in dict_fired_projectiles.Values)
|
||||||
|
{
|
||||||
|
foreach (var proj in set)
|
||||||
|
{
|
||||||
|
proj.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dict_fired_projectiles.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Pool(PHGameObject par)
|
||||||
|
{
|
||||||
|
base.Pool(par);
|
||||||
|
par.Transform.gameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override PHGameObject Create(ProjectileParams par)
|
||||||
|
{
|
||||||
|
return new PHGameObject(item.CloneModel(GameManager.Instance.World, new ItemValue(item.Id), Vector3.zero, null), par);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
54
Scripts/ProjectileManager/PIGSimpleMesh.cs
Normal file
54
Scripts/ProjectileManager/PIGSimpleMesh.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using FullautoLauncher.Scripts.ProjectileManager;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class PIGSimpleMesh : ProjectileItemGroupAbs<PHSimpleMesh>
|
||||||
|
{
|
||||||
|
private Transform renderTrans;
|
||||||
|
private Mesh mesh;
|
||||||
|
private RenderParams renderParams;
|
||||||
|
private SimpleMeshTransformData data;
|
||||||
|
|
||||||
|
public PIGSimpleMesh(ItemClass item) : base(item)
|
||||||
|
{
|
||||||
|
renderTrans = item.CloneModel(GameManager.Instance.World, new ItemValue(item.Id), Vector3.zero, null);
|
||||||
|
MeshFilter filter = renderTrans.GetComponentInChildren<MeshFilter>();
|
||||||
|
mesh = filter.sharedMesh;
|
||||||
|
MeshRenderer renderer = renderTrans.GetComponentInChildren<MeshRenderer>();
|
||||||
|
renderParams = new RenderParams(renderer.material)
|
||||||
|
{
|
||||||
|
layer = renderer.gameObject.layer,
|
||||||
|
lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off,
|
||||||
|
shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off,
|
||||||
|
rendererPriority = renderer.rendererPriority,
|
||||||
|
renderingLayerMask = renderer.renderingLayerMask,
|
||||||
|
motionVectorMode = MotionVectorGenerationMode.ForceNoMotion
|
||||||
|
};
|
||||||
|
data = new SimpleMeshTransformData(renderer.localToWorldMatrix, mesh.bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update()
|
||||||
|
{
|
||||||
|
if (GameManager.IsDedicatedServer)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var set in dict_fired_projectiles.Values)
|
||||||
|
{
|
||||||
|
foreach (var projectile in set)
|
||||||
|
{
|
||||||
|
Graphics.RenderMesh(in projectile.renderParams, mesh, 0, projectile.finalMat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override PHSimpleMesh Create(ProjectileParams par)
|
||||||
|
{
|
||||||
|
return new PHSimpleMesh(par, data, in renderParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
32
Scripts/ProjectileManager/ParameterHolderAbs.cs
Normal file
32
Scripts/ProjectileManager/ParameterHolderAbs.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FullautoLauncher.Scripts.ProjectileManager
|
||||||
|
{
|
||||||
|
public abstract class ParameterHolderAbs
|
||||||
|
{
|
||||||
|
public ProjectileParams Params => par;
|
||||||
|
|
||||||
|
protected readonly ProjectileParams par;
|
||||||
|
|
||||||
|
protected ParameterHolderAbs(ProjectileParams par)
|
||||||
|
{
|
||||||
|
this.par = par;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return par.ProjectileID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void UpdatePosition();
|
||||||
|
|
||||||
|
public virtual void Fire()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
121
Scripts/ProjectileManager/ProjectileItemGroupAbs.cs
Normal file
121
Scripts/ProjectileManager/ProjectileItemGroupAbs.cs
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace FullautoLauncher.Scripts.ProjectileManager
|
||||||
|
{
|
||||||
|
public interface IProjectileItemGroup
|
||||||
|
{
|
||||||
|
void Pool(int count);
|
||||||
|
ProjectileParams Fire(int entityID, ProjectileParams.ItemInfo info, Vector3 _idealStartPosition, Vector3 _realStartPosition, Vector3 _flyDirection, Entity _firingEntity, int _hmOverride = 0, float _radius = 0f);
|
||||||
|
void Update();
|
||||||
|
void FixedUpdate();
|
||||||
|
void Cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class ProjectileItemGroupAbs<T> : IProjectileItemGroup where T : ParameterHolderAbs
|
||||||
|
{
|
||||||
|
protected readonly Queue<T> queue_pool = new Queue<T>();
|
||||||
|
protected readonly Dictionary<int, HashSet<T>> dict_fired_projectiles = new Dictionary<int, HashSet<T>>();
|
||||||
|
protected readonly ItemClass item;
|
||||||
|
protected readonly int maxPoolCount = 1000;
|
||||||
|
private int nextID;
|
||||||
|
private int NextID { get => nextID++; }
|
||||||
|
|
||||||
|
public ProjectileItemGroupAbs(ItemClass item)
|
||||||
|
{
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract T Create(ProjectileParams par);
|
||||||
|
|
||||||
|
public virtual void Cleanup()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Pool(int count)
|
||||||
|
{
|
||||||
|
count = Mathf.Min(maxPoolCount - queue_pool.Count, count - queue_pool.Count);
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
queue_pool.Enqueue(Create(new ProjectileParams(NextID)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Pool(T par)
|
||||||
|
{
|
||||||
|
if (maxPoolCount > queue_pool.Count)
|
||||||
|
{
|
||||||
|
par.Params.bOnIdealPosition = false;
|
||||||
|
queue_pool.Enqueue(par);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProjectileParams Fire(int entityID, ProjectileParams.ItemInfo info, Vector3 _idealStartPosition, Vector3 _realStartPosition, Vector3 _flyDirection, Entity _firingEntity, int _hmOverride = 0, float _radius = 0f)
|
||||||
|
{
|
||||||
|
T par = queue_pool.Count == 0 ? Create(new ProjectileParams(NextID)) : queue_pool.Dequeue();
|
||||||
|
if(!dict_fired_projectiles.TryGetValue(entityID, out HashSet<T> set))
|
||||||
|
{
|
||||||
|
set = new HashSet<T>();
|
||||||
|
dict_fired_projectiles.Add(entityID, set);
|
||||||
|
}
|
||||||
|
set.Add(par);
|
||||||
|
par.Params.Fire(info, _idealStartPosition, _realStartPosition, _flyDirection, _firingEntity, _hmOverride, _radius);
|
||||||
|
par.Fire();
|
||||||
|
return par.Params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void Update();
|
||||||
|
|
||||||
|
private List<T> list_remove = new List<T>();
|
||||||
|
public void FixedUpdate()
|
||||||
|
{
|
||||||
|
if (GameManager.Instance == null || GameManager.Instance.IsPaused() || GameManager.Instance.World == null)
|
||||||
|
return;
|
||||||
|
foreach (var pair in dict_fired_projectiles)
|
||||||
|
{
|
||||||
|
EntityAlive entityAlive = GameManager.Instance.World.GetEntity(pair.Key) as EntityAlive;
|
||||||
|
|
||||||
|
list_remove.Clear();
|
||||||
|
foreach (var projectile in pair.Value)
|
||||||
|
{
|
||||||
|
if (projectile.Params.UpdatePosition())
|
||||||
|
{
|
||||||
|
list_remove.Add(projectile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
projectile.UpdatePosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entityAlive != null)
|
||||||
|
{
|
||||||
|
int prevLayer = 0;
|
||||||
|
if (entityAlive.emodel != null)
|
||||||
|
{
|
||||||
|
prevLayer = entityAlive.GetModelLayer();
|
||||||
|
entityAlive.SetModelLayer(2, false, null);
|
||||||
|
}
|
||||||
|
foreach (var projectile in pair.Value)
|
||||||
|
{
|
||||||
|
if (projectile.Params.CheckCollision(entityAlive))
|
||||||
|
{
|
||||||
|
list_remove.Add(projectile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (entityAlive.emodel != null)
|
||||||
|
{
|
||||||
|
entityAlive.SetModelLayer(prevLayer, false, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var remove in list_remove)
|
||||||
|
{
|
||||||
|
pair.Value.Remove(remove);
|
||||||
|
Pool(remove);
|
||||||
|
}
|
||||||
|
list_remove.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
188
Scripts/ProjectileManager/ProjectileParams.cs
Normal file
188
Scripts/ProjectileManager/ProjectileParams.cs
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace FullautoLauncher.Scripts.ProjectileManager
|
||||||
|
{
|
||||||
|
public class ProjectileParams
|
||||||
|
{
|
||||||
|
public int ProjectileID;
|
||||||
|
public ItemInfo info;
|
||||||
|
public Vector3 flyDirection;
|
||||||
|
public Vector3 renderPosition;
|
||||||
|
public Vector3 velocity;
|
||||||
|
public Vector3 previousPosition;
|
||||||
|
public Vector3 currentPosition;
|
||||||
|
public Vector3 gravity;
|
||||||
|
public Vector3 moveDir;
|
||||||
|
public float timeShotStarted;
|
||||||
|
public int hmOverride;
|
||||||
|
public float radius;
|
||||||
|
public bool bOnIdealPosition = false;
|
||||||
|
public CollisionParticleController waterCollisionParticles = new CollisionParticleController();
|
||||||
|
|
||||||
|
public ProjectileParams(int projectileID)
|
||||||
|
{
|
||||||
|
ProjectileID = projectileID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Fire(ItemInfo _info, Vector3 _idealStartPosition, Vector3 _realStartPosition, Vector3 _flyDirection, Entity _firingEntity, int _hmOverride = 0, float _radius = 0f)
|
||||||
|
{
|
||||||
|
info = _info;
|
||||||
|
flyDirection = _flyDirection.normalized;
|
||||||
|
moveDir = flyDirection;
|
||||||
|
previousPosition = currentPosition = _idealStartPosition;
|
||||||
|
renderPosition = _realStartPosition;
|
||||||
|
velocity = flyDirection.normalized * EffectManager.GetValue(PassiveEffects.ProjectileVelocity, info.itemValueLauncher, info.itemActionProjectile.Velocity, _firingEntity as EntityAlive);
|
||||||
|
hmOverride = _hmOverride;
|
||||||
|
radius = _radius;
|
||||||
|
waterCollisionParticles.Init(_firingEntity.entityId, info.itemProjectile.MadeOfMaterial.SurfaceCategory, "water", 16);
|
||||||
|
gravity = Vector3.up * EffectManager.GetValue(PassiveEffects.ProjectileGravity, info.itemValueLauncher, info.itemActionProjectile.Gravity, _firingEntity as EntityAlive);
|
||||||
|
timeShotStarted = Time.time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return ProjectileID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool UpdatePosition()
|
||||||
|
{
|
||||||
|
float flyTime = Time.time - timeShotStarted;
|
||||||
|
if (flyTime >= info.itemActionProjectile.LifeTime)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (flyTime >= info.itemActionProjectile.FlyTime)
|
||||||
|
{
|
||||||
|
velocity += gravity * Time.fixedDeltaTime;
|
||||||
|
}
|
||||||
|
moveDir = velocity * Time.fixedDeltaTime;
|
||||||
|
previousPosition = currentPosition;
|
||||||
|
currentPosition += moveDir;
|
||||||
|
renderPosition += moveDir;
|
||||||
|
if (!bOnIdealPosition)
|
||||||
|
{
|
||||||
|
bOnIdealPosition = flyTime > 0.5f;
|
||||||
|
}
|
||||||
|
if(!bOnIdealPosition)
|
||||||
|
{
|
||||||
|
renderPosition = Vector3.Lerp(renderPosition, currentPosition, flyTime * 2f);
|
||||||
|
}
|
||||||
|
//Log.Out($"projectile {ProjectileID} position {currentPosition} entity position {info.actionData.invData.holdingEntity.position}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CheckCollision(EntityAlive entityAlive)
|
||||||
|
{
|
||||||
|
//Already checked in ItemActionBetterLauncher.ItemActionEffects, projectiles are not created on dedi if fired from remote entity.
|
||||||
|
//if(entityAlive.isEntityRemote && GameManager.IsDedicatedServer)
|
||||||
|
// return true;
|
||||||
|
World world = GameManager.Instance.World;
|
||||||
|
Vector3 dir = currentPosition - previousPosition;
|
||||||
|
Vector3 dirNorm = dir.normalized;
|
||||||
|
float magnitude = dir.magnitude;
|
||||||
|
if (magnitude < 0.04f)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ray ray = new Ray(previousPosition, dir);
|
||||||
|
waterCollisionParticles.CheckCollision(ray.origin, ray.direction, magnitude, (entityAlive != null) ? entityAlive.entityId : (-1));
|
||||||
|
int hitmask = ((hmOverride == 0) ? 80 : hmOverride);
|
||||||
|
bool bHit = Voxel.Raycast(world, ray, magnitude, -538750997, hitmask, radius);
|
||||||
|
if (bHit && (GameUtils.IsBlockOrTerrain(Voxel.voxelRayHitInfo.tag) || Voxel.voxelRayHitInfo.tag.StartsWith("E_")))
|
||||||
|
{
|
||||||
|
if (entityAlive != null && !entityAlive.isEntityRemote)
|
||||||
|
{
|
||||||
|
entityAlive.MinEventContext.Other = ItemActionAttack.FindHitEntity(Voxel.voxelRayHitInfo) as EntityAlive;
|
||||||
|
ItemActionAttack.AttackHitInfo attackHitInfo = new ItemActionAttack.AttackHitInfo
|
||||||
|
{
|
||||||
|
WeaponTypeTag = ItemActionAttack.RangedTag
|
||||||
|
};
|
||||||
|
ItemActionAttack.Hit(Voxel.voxelRayHitInfo,
|
||||||
|
entityAlive.entityId,
|
||||||
|
EnumDamageTypes.Piercing,
|
||||||
|
info.itemActionProjectile.GetDamageBlock(info.itemValueLauncher, ItemActionAttack.GetBlockHit(world, Voxel.voxelRayHitInfo), entityAlive, info.actionData.indexInEntityOfAction),
|
||||||
|
info.itemActionProjectile.GetDamageEntity(info.itemValueLauncher, entityAlive, info.actionData.indexInEntityOfAction),
|
||||||
|
1f,
|
||||||
|
1f,
|
||||||
|
EffectManager.GetValue(PassiveEffects.CriticalChance, info.itemValueLauncher, info.itemProjectile.CritChance.Value, entityAlive, null, info.itemProjectile.ItemTags),
|
||||||
|
ItemAction.GetDismemberChance(info.actionData, Voxel.voxelRayHitInfo),
|
||||||
|
info.itemProjectile.MadeOfMaterial.SurfaceCategory,
|
||||||
|
info.itemActionProjectile.GetDamageMultiplier(),
|
||||||
|
info.itemActionProjectile.BuffActions,
|
||||||
|
attackHitInfo,
|
||||||
|
1,
|
||||||
|
info.itemActionProjectile.ActionExp,
|
||||||
|
info.itemActionProjectile.ActionExpBonusMultiplier,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
ItemActionAttack.EnumAttackMode.RealNoHarvesting,
|
||||||
|
null,
|
||||||
|
-1,
|
||||||
|
info.itemValueLauncher);
|
||||||
|
if (entityAlive.MinEventContext.Other == null)
|
||||||
|
{
|
||||||
|
entityAlive.FireEvent(MinEventTypes.onSelfPrimaryActionMissEntity, true);
|
||||||
|
}
|
||||||
|
entityAlive.FireEvent(MinEventTypes.onProjectileImpact, false);
|
||||||
|
MinEventParams.CachedEventParam.Self = entityAlive;
|
||||||
|
MinEventParams.CachedEventParam.Position = Voxel.voxelRayHitInfo.hit.pos;
|
||||||
|
MinEventParams.CachedEventParam.ItemValue = info.itemValueProjectile;
|
||||||
|
MinEventParams.CachedEventParam.Other = entityAlive.MinEventContext.Other;
|
||||||
|
info.itemProjectile.FireEvent(MinEventTypes.onProjectileImpact, MinEventParams.CachedEventParam);
|
||||||
|
if (info.itemActionProjectile.Explosion.ParticleIndex > 0)
|
||||||
|
{
|
||||||
|
Vector3 vector3 = Voxel.voxelRayHitInfo.hit.pos - dirNorm * 0.1f;
|
||||||
|
Vector3i vector3i = World.worldToBlockPos(vector3);
|
||||||
|
if (!world.GetBlock(vector3i).isair)
|
||||||
|
{
|
||||||
|
BlockFace blockFace;
|
||||||
|
vector3i = Voxel.OneVoxelStep(vector3i, vector3, -dirNorm, out vector3, out blockFace);
|
||||||
|
}
|
||||||
|
GameManager.Instance.ExplosionServer(Voxel.voxelRayHitInfo.hit.clrIdx, vector3, vector3i, Quaternion.identity, info.itemActionProjectile.Explosion, entityAlive.entityId, 0f, false, info.itemValueProjectile);
|
||||||
|
}
|
||||||
|
else if (info.itemProjectile.IsSticky)
|
||||||
|
{
|
||||||
|
GameRandom gameRandom = world.GetGameRandom();
|
||||||
|
if (GameUtils.IsBlockOrTerrain(Voxel.voxelRayHitInfo.tag))
|
||||||
|
{
|
||||||
|
if (gameRandom.RandomFloat < EffectManager.GetValue(PassiveEffects.ProjectileStickChance, info.itemValueLauncher, 0.5f, entityAlive, null, info.itemProjectile.ItemTags | FastTags<TagGroup.Global>.Parse(Voxel.voxelRayHitInfo.fmcHit.blockValue.Block.blockMaterial.SurfaceCategory)))
|
||||||
|
{
|
||||||
|
global::ProjectileManager.AddProjectileItem(null, -1, Voxel.voxelRayHitInfo.hit.pos, dirNorm, info.itemValueProjectile.type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GameManager.Instance.SpawnParticleEffectServer(new ParticleEffect("impact_metal_on_wood", Voxel.voxelRayHitInfo.hit.pos, Utils.BlockFaceToRotation(Voxel.voxelRayHitInfo.fmcHit.blockFace), 1f, Color.white, string.Format("{0}hit{1}", Voxel.voxelRayHitInfo.fmcHit.blockValue.Block.blockMaterial.SurfaceCategory, info.itemProjectile.MadeOfMaterial.SurfaceCategory), null), entityAlive.entityId, false, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (gameRandom.RandomFloat < EffectManager.GetValue(PassiveEffects.ProjectileStickChance, info.itemValueLauncher, 0.5f, entityAlive, null, info.itemProjectile.ItemTags))
|
||||||
|
{
|
||||||
|
int id = global::ProjectileManager.AddProjectileItem(null, -1, Voxel.voxelRayHitInfo.hit.pos, dirNorm, info.itemValueProjectile.type);
|
||||||
|
Utils.SetLayerRecursively(global::ProjectileManager.GetProjectile(id).gameObject, 14, null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GameManager.Instance.SpawnParticleEffectServer(new ParticleEffect("impact_metal_on_wood", Voxel.voxelRayHitInfo.hit.pos, Utils.BlockFaceToRotation(Voxel.voxelRayHitInfo.fmcHit.blockFace), 1f, Color.white, "bullethitwood", null), entityAlive.entityId, false, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ItemInfo
|
||||||
|
{
|
||||||
|
public ItemActionProjectile itemActionProjectile;
|
||||||
|
public ItemClass itemProjectile;
|
||||||
|
public ItemValue itemValueProjectile;
|
||||||
|
public ItemValue itemValueLauncher;
|
||||||
|
public ItemActionData actionData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user