177 lines
13 KiB
C#
177 lines
13 KiB
C#
namespace Harmony.ProjectileMoveScriptPatches
|
|
{
|
|
[HarmonyPatch(typeof(ProjectileMoveScript))]
|
|
[HarmonyPatch("checkCollision")]
|
|
public class checkCollisionPatch
|
|
{
|
|
public static bool Prefix(ProjectileMoveScript __instance)
|
|
{
|
|
if (__instance.state != ProjectileMoveScript.State.Active || (UnityEngine.Object)ProjectileMoveScript.gameManager == (UnityEngine.Object)null)
|
|
return false;
|
|
World world = ProjectileMoveScript.gameManager.World;
|
|
if (world == null)
|
|
return false;
|
|
Vector3 vector3_1 = !__instance.bOnIdealPos ? __instance.idealPosition : __instance.transform.position + Origin.position;
|
|
Vector3 vector3_2 = vector3_1 - __instance.previousPosition;
|
|
float magnitude = vector3_2.magnitude;
|
|
if ((double)magnitude < 0.039999999105930328)
|
|
return false;
|
|
EntityAlive firingEntity = (EntityAlive)__instance.firingEntity;
|
|
Ray ray = new Ray(__instance.previousPosition, vector3_2.normalized);
|
|
__instance.waterCollisionParticles.CheckCollision(ray.origin, ray.direction, magnitude, (UnityEngine.Object)firingEntity != (UnityEngine.Object)null ? firingEntity.entityId : -1);
|
|
int _layerId = -1;
|
|
if ((UnityEngine.Object)firingEntity != (UnityEngine.Object)null && (UnityEngine.Object)firingEntity.emodel != (UnityEngine.Object)null)
|
|
{
|
|
_layerId = firingEntity.GetModelLayer();
|
|
firingEntity.SetModelLayer(2);
|
|
}
|
|
int _hitMask = __instance.hmOverride == 0 ? 80 : __instance.hmOverride;
|
|
int num1 = Voxel.Raycast(world, ray, magnitude, -538750997, _hitMask, __instance.radius) ? 1 : 0;
|
|
if (_layerId >= 0)
|
|
firingEntity.SetModelLayer(_layerId);
|
|
if (num1 != 0 && (GameUtils.IsBlockOrTerrain(Voxel.voxelRayHitInfo.tag) || Voxel.voxelRayHitInfo.tag.StartsWith("E_")))
|
|
{
|
|
if ((UnityEngine.Object)__instance.firingEntity != (UnityEngine.Object)null && !__instance.firingEntity.isEntityRemote)
|
|
{
|
|
firingEntity.MinEventContext.Other = ItemActionAttack.FindHitEntity(Voxel.voxelRayHitInfo) as EntityAlive;
|
|
ItemActionAttack.AttackHitInfo _attackDetails = new ItemActionAttack.AttackHitInfo()
|
|
{
|
|
WeaponTypeTag = ItemActionAttack.RangedTag
|
|
};
|
|
ItemActionAttack.Hit(Voxel.voxelRayHitInfo, __instance.ProjectileOwnerID, EnumDamageTypes.Piercing, Mathf.Lerp(1f, __instance.itemActionProjectile.GetDamageBlock(__instance.itemValueLauncher, ItemActionAttack.GetBlockHit(world, Voxel.voxelRayHitInfo), firingEntity), __instance.actionData.strainPercent), Mathf.Lerp(1f, __instance.itemActionProjectile.GetDamageEntity(__instance.itemValueLauncher, firingEntity), __instance.actionData.strainPercent), 1f, 1f, EffectManager.GetValue(PassiveEffects.CriticalChance, __instance.itemValueLauncher, __instance.itemProjectile.CritChance.Value, firingEntity, tags: __instance.itemProjectile.ItemTags), ItemAction.GetDismemberChance((ItemActionData)__instance.actionData, Voxel.voxelRayHitInfo), __instance.itemProjectile.MadeOfMaterial.SurfaceCategory, __instance.itemActionProjectile.GetDamageMultiplier(), __instance.getBuffActions(), _attackDetails, _actionExp: __instance.itemActionProjectile.ActionExp, _actionExpBonus: __instance.itemActionProjectile.ActionExpBonusMultiplier, damagingItemValue: __instance.itemValueLauncher);
|
|
if ((UnityEngine.Object)firingEntity.MinEventContext.Other == (UnityEngine.Object)null)
|
|
firingEntity.FireEvent(MinEventTypes.onSelfPrimaryActionMissEntity);
|
|
firingEntity.FireEvent(MinEventTypes.onProjectileImpact, false);
|
|
MinEventParams.CachedEventParam.Self = firingEntity;
|
|
MinEventParams.CachedEventParam.Position = Voxel.voxelRayHitInfo.hit.pos;
|
|
MinEventParams.CachedEventParam.ItemValue = __instance.itemValueProjectile;
|
|
MinEventParams.CachedEventParam.Other = firingEntity.MinEventContext.Other;
|
|
__instance.itemProjectile.FireEvent(MinEventTypes.onProjectileImpact, MinEventParams.CachedEventParam);
|
|
if (__instance.itemActionProjectile.Explosion.ParticleIndex > 0)
|
|
{
|
|
Vector3 hitPos = Voxel.voxelRayHitInfo.hit.pos - vector3_2.normalized * 0.1f;
|
|
Vector3i vector3i = World.worldToBlockPos(hitPos);
|
|
if (!world.GetBlock(vector3i).isair)
|
|
vector3i = Voxel.OneVoxelStep(vector3i, hitPos, -vector3_2.normalized, out hitPos, out BlockFace _);
|
|
ProjectileMoveScript.gameManager.ExplosionServer(Voxel.voxelRayHitInfo.hit.clrIdx, hitPos, vector3i, Quaternion.identity, __instance.itemActionProjectile.Explosion, __instance.ProjectileOwnerID, 0.0f, false, __instance.itemValueLauncher);
|
|
__instance.SetState(ProjectileMoveScript.State.Dead);
|
|
return false;
|
|
}
|
|
if (__instance.itemProjectile.IsSticky)
|
|
{
|
|
GameRandom gameRandom = world.GetGameRandom();
|
|
|
|
ProgressionValue progressionValue = firingEntity.Progression.GetProgressionValue("FuriousRamsayPerkBows");
|
|
int progressionLevel = 1;
|
|
|
|
if (!RebirthUtilities.ScenarioSkip() && progressionValue != null)
|
|
{
|
|
progressionLevel = progressionValue.Level;
|
|
}
|
|
|
|
float baseStickChance = 0f;
|
|
float addedChance = 0f;
|
|
float stickChance;
|
|
bool isArrow = __instance.itemProjectile.Name.ToLower().Contains("ammoarrow") ||
|
|
__instance.itemProjectile.Name.ToLower().Contains("ammocrossbowbolt");
|
|
|
|
if (!isArrow)
|
|
{
|
|
stickChance = EffectManager.GetValue(PassiveEffects.ProjectileStickChance, __instance.itemValueLauncher, 0.5f, firingEntity, tags: __instance.itemProjectile.ItemTags);
|
|
}
|
|
else
|
|
{
|
|
if (__instance.itemProjectile.Name.ToLower().Contains("stone"))
|
|
{
|
|
baseStickChance = 0.3f;
|
|
addedChance = progressionLevel / 25f;
|
|
//Log.Out("ProjectileMoveScriptPatches-checkCollision STONE, addedChance: " + addedChance);
|
|
stickChance = baseStickChance + addedChance;
|
|
}
|
|
else if (__instance.itemProjectile.Name.ToLower().Contains("iron"))
|
|
{
|
|
baseStickChance = 0.4f;
|
|
addedChance = progressionLevel / 25f;
|
|
//Log.Out("ProjectileMoveScriptPatches-checkCollision IRON, addedChance: " + addedChance);
|
|
stickChance = baseStickChance + addedChance;
|
|
}
|
|
else if (__instance.itemProjectile.Name.ToLower().Contains("steelap"))
|
|
{
|
|
baseStickChance = 0.5f;
|
|
addedChance = progressionLevel / 25f;
|
|
//Log.Out("ProjectileMoveScriptPatches-checkCollision STEEL, addedChance: " + addedChance);
|
|
stickChance = baseStickChance + addedChance;
|
|
}
|
|
else
|
|
{
|
|
//Log.Out("ProjectileMoveScriptPatches-checkCollision OTHER");
|
|
stickChance = 0f;
|
|
}
|
|
}
|
|
|
|
float random = gameRandom.RandomFloat;
|
|
|
|
//Log.Out("ProjectileMoveScriptPatches-checkCollision baseStickChance: " + baseStickChance);
|
|
//Log.Out("ProjectileMoveScriptPatches-checkCollision addedChance: " + addedChance);
|
|
//Log.Out("ProjectileMoveScriptPatches-checkCollision progressionLevel: " + progressionLevel);
|
|
//Log.Out("ProjectileMoveScriptPatches-checkCollision stickChance: " + stickChance);
|
|
|
|
//Log.Out("ProjectileMoveScriptPatches-checkCollision ItemClass.Name: " + __instance.itemValueLauncher.ItemClass.Name);
|
|
//Log.Out("ProjectileMoveScriptPatches-checkCollision itemProjectile.Name: " + __instance.itemProjectile.Name);
|
|
|
|
//Log.Out("ProjectileMoveScriptPatches-checkCollision random: " + random);
|
|
|
|
if (GameUtils.IsBlockOrTerrain(Voxel.voxelRayHitInfo.tag))
|
|
{
|
|
double randomFloat = (double)gameRandom.RandomFloat;
|
|
ItemValue itemValueLauncher = __instance.itemValueLauncher;
|
|
EntityAlive _entity = firingEntity;
|
|
FastTags<TagGroup.Global> itemTags = __instance.itemProjectile.ItemTags;
|
|
BlockValue blockValue = Voxel.voxelRayHitInfo.fmcHit.blockValue;
|
|
FastTags<TagGroup.Global> fastTags = FastTags<TagGroup.Global>.Parse(blockValue.Block.blockMaterial.SurfaceCategory);
|
|
FastTags<TagGroup.Global> tags = itemTags | fastTags;
|
|
double num2 = (double)EffectManager.GetValue(PassiveEffects.ProjectileStickChance, itemValueLauncher, 0.5f, _entity, tags: tags);
|
|
if (randomFloat < num2)
|
|
{
|
|
__instance.ProjectileID = ProjectileManager.AddProjectileItem(__instance.transform, _position: Voxel.voxelRayHitInfo.hit.pos, _movementLastFrame: vector3_2.normalized, _itemValueType: __instance.itemValueProjectile.type);
|
|
__instance.SetState(ProjectileMoveScript.State.Sticky);
|
|
}
|
|
else
|
|
{
|
|
GameManager gameManager = ProjectileMoveScript.gameManager;
|
|
Vector3 pos = Voxel.voxelRayHitInfo.hit.pos;
|
|
Quaternion rotation = Utils.BlockFaceToRotation(Voxel.voxelRayHitInfo.fmcHit.blockFace);
|
|
Color white = Color.white;
|
|
blockValue = Voxel.voxelRayHitInfo.fmcHit.blockValue;
|
|
string _soundName = string.Format("{0}hit{1}", (object)blockValue.Block.blockMaterial.SurfaceCategory, (object)__instance.itemProjectile.MadeOfMaterial.SurfaceCategory);
|
|
ParticleEffect _pe = new ParticleEffect("impact_metal_on_wood", pos, rotation, 1f, white, _soundName, (Transform)null);
|
|
int entityId = __instance.firingEntity.entityId;
|
|
gameManager.SpawnParticleEffectServer(_pe, entityId, false, false);
|
|
__instance.SetState(ProjectileMoveScript.State.Dead);
|
|
}
|
|
}
|
|
else if (random < stickChance)
|
|
{
|
|
__instance.ProjectileID = ProjectileManager.AddProjectileItem(__instance.transform, _position: Voxel.voxelRayHitInfo.hit.pos, _movementLastFrame: vector3_2.normalized, _itemValueType: __instance.itemValueProjectile.type);
|
|
Utils.SetLayerRecursively(ProjectileManager.GetProjectile(__instance.ProjectileID).gameObject, 14);
|
|
__instance.SetState(ProjectileMoveScript.State.Sticky);
|
|
}
|
|
else
|
|
{
|
|
ProjectileMoveScript.gameManager.SpawnParticleEffectServer(new ParticleEffect("impact_metal_on_wood", Voxel.voxelRayHitInfo.hit.pos, Utils.BlockFaceToRotation(Voxel.voxelRayHitInfo.fmcHit.blockFace), 1f, Color.white, "bullethitwood", (Transform)null), __instance.firingEntity.entityId, false, false);
|
|
__instance.SetState(ProjectileMoveScript.State.Dead);
|
|
}
|
|
}
|
|
else
|
|
__instance.SetState(ProjectileMoveScript.State.Dead);
|
|
}
|
|
else
|
|
__instance.SetState(ProjectileMoveScript.State.Dead);
|
|
}
|
|
__instance.previousPosition = vector3_1;
|
|
|
|
return false;
|
|
}
|
|
}
|
|
}
|