static bool Prefix(Vagon __instance) { if (!__instance.m_nview.IsValid()) { logger.LogDebug("m_nview invalid"); return(false); } // Attempt to attach the cart __instance.UpdateAudio(Time.fixedDeltaTime); if (__instance.m_nview.IsOwner()) { if ((bool)__instance.m_useRequester) { if (__instance.IsAttached()) { // If attached detach __instance.Detach(); } else { /// Determine if there is a valid animal in range and if so attempt to attach to it. /// If not attempt to attach to player Character closest_tamed = FindClosestAttachableAnimal(__instance); if (closest_tamed != null) { AttachCartTo(closest_tamed, __instance); } else if (__instance.CanAttach(__instance.m_useRequester.gameObject)) { AttachCartTo(__instance.m_useRequester, __instance); } else { __instance.m_useRequester.Message(MessageHud.MessageType.Center, "Not in the right position"); } } __instance.m_useRequester = null; } if (__instance.IsAttached()) { // Update detach distance before check if it should be detached __instance.m_detachDistance = GetCartDetachDistance(AttachedCharacter(__instance)); if (!__instance.CanAttach(((Component)(object)((Joint)__instance.m_attachJoin).connectedBody).gameObject)) { __instance.Detach(); logger.LogDebug("Cart no longer attachable."); } } } else if (__instance.IsAttached()) { __instance.Detach(); } return(false); }
/// <summary> /// Helper method to access the character currently attached to a cart /// </summary> /// <param name="cart"></param> /// <returns>Character currently attached</returns> static Character AttachedCharacter(Vagon cart) { if (cart && cart.IsAttached()) { return(cart.m_attachJoin.connectedBody.gameObject.GetComponent <Character>()); } return(null); }
static bool Prefix(ref bool __result, ref Vagon __instance) { if ((bool)__instance.m_container && __instance.m_container.IsInUse()) { __result = true; } else if (__instance.IsAttached()) { __result = (bool)__instance.m_attachJoin.connectedBody.gameObject.GetComponent <Player>(); } else { __result = false; } return(false); }
private void Update() { if (!modEnabled.Value || AedenthornUtils.IgnoreKeyPresses(true)) { return; } if (AedenthornUtils.CheckKeyDown(hotKey.Value)) { float closest = attachDistance.Value; Vagon closestVagon = null; Vector3 position = Player.m_localPlayer.transform.position + Vector3.up; foreach (Collider collider in Physics.OverlapSphere(position, attachDistance.Value)) { Vagon v = collider.transform.parent.gameObject.GetComponent <Vagon>(); if (collider?.attachedRigidbody && v != null && Vector3.Distance(collider.ClosestPoint(position), position) < closest && (v.IsAttached(Player.m_localPlayer) || !v.InUse())) { Dbgl("Got nearby cart"); closest = Vector3.Distance(collider.ClosestPoint(position), position); closestVagon = collider.transform.parent.gameObject.GetComponent <Vagon>(); } } if (closestVagon != null) { closestVagon.Interact(Player.m_localPlayer, false, false); } } }
private static void doMeleeAttack(Humanoid ___m_character, ItemDrop.ItemData ___m_weapon, Attack __instance, EffectList ___m_hitEffect, Skills.SkillType ___m_specialHitSkill, DestructibleType ___m_specialHitType, bool ___m_lowerDamagePerHit, float ___m_forceMultiplier, float ___m_staggerMultiplier, float ___m_damageMultiplier, int ___m_attackChainLevels, int ___m_currentAttackCainLevel, DestructibleType ___m_resetChainIfHit, ref int ___m_nextAttackChainLevel, EffectList ___m_hitTerrainEffect, float ___m_attackHitNoise, Vector3 pos, Collider col, Vector3 dir, GameObject ___m_spawnOnTrigger) { Vector3 zero = Vector3.zero; bool flag2 = false; //rename HashSet <Skills.SkillType> skillTypeSet = new HashSet <Skills.SkillType>(); bool hitOccured = false; ___m_weapon.m_shared.m_hitEffect.Create(pos, Quaternion.identity); ___m_hitEffect.Create(pos, Quaternion.identity); GameObject hitObject = Projectile.FindHitObject(col); if (!(hitObject == ___m_character.gameObject)) { Vagon component1 = hitObject.GetComponent <Vagon>(); if (!component1 || !component1.IsAttached(___m_character)) { Character component2 = hitObject.GetComponent <Character>(); if (!(component2 != null) || (___m_character.IsPlayer() || BaseAI.IsEnemy(___m_character, component2)) && (!___m_weapon.m_shared.m_dodgeable || !component2.IsDodgeInvincible())) { hitOccured = true; } } } if (!hitOccured) { return; } IDestructible component = hitObject.GetComponent <IDestructible>(); if (component != null) { DestructibleType destructibleType = component.GetDestructibleType(); Skills.SkillType skill = ___m_weapon.m_shared.m_skillType; if (___m_specialHitSkill != Skills.SkillType.None && (destructibleType & ___m_specialHitType) != DestructibleType.None) { skill = ___m_specialHitSkill; } float randomSkillFactor = ___m_character.GetRandomSkillFactor(skill); if (___m_lowerDamagePerHit) { randomSkillFactor /= 0.75f; } HitData hitData = new HitData(); hitData.m_toolTier = ___m_weapon.m_shared.m_toolTier; hitData.m_statusEffect = ___m_weapon.m_shared.m_attackStatusEffect ? ___m_weapon.m_shared.m_attackStatusEffect.name : ""; hitData.m_pushForce = ___m_weapon.m_shared.m_attackForce * randomSkillFactor * ___m_forceMultiplier; hitData.m_backstabBonus = ___m_weapon.m_shared.m_backstabBonus; hitData.m_staggerMultiplier = ___m_staggerMultiplier; hitData.m_dodgeable = ___m_weapon.m_shared.m_dodgeable; hitData.m_blockable = ___m_weapon.m_shared.m_blockable; hitData.m_skill = skill; hitData.m_damage = ___m_weapon.GetDamage(); hitData.m_point = pos; hitData.m_dir = dir; hitData.m_hitCollider = col; hitData.SetAttacker(___m_character); hitData.m_damage.Modify(___m_damageMultiplier); hitData.m_damage.Modify(randomSkillFactor); hitData.m_damage.Modify((float)getLevelDamageFactorMethod.Invoke(__instance, null)); if (___m_attackChainLevels > 1 && ___m_currentAttackCainLevel == ___m_attackChainLevels - 1) { hitData.m_damage.Modify(2f); hitData.m_pushForce *= 1.2f; } hitData.m_damage.Modify(MeshCooldown.calcDamageMultiplier()); ___m_character.GetSEMan().ModifyAttack(skill, ref hitData); if (component is Character) { flag2 = true; } component.Damage(hitData); if ((destructibleType & ___m_resetChainIfHit) != DestructibleType.None) { ___m_nextAttackChainLevel = 0; } skillTypeSet.Add(skill); } ___m_weapon.m_shared.m_hitTerrainEffect.Create(pos, Quaternion.identity); // Quaternion.identity might need to be replaced ___m_hitTerrainEffect.Create(pos, Quaternion.identity); if (___m_weapon.m_shared.m_spawnOnHitTerrain) { spawnOnHitTerrainMethod.Invoke(__instance, new object[] { pos, ___m_weapon.m_shared.m_spawnOnHitTerrain }); } if (___m_weapon.m_shared.m_useDurability && ___m_character.IsPlayer()) { ___m_weapon.m_durability -= ___m_weapon.m_shared.m_useDurabilityDrain; } ___m_character.AddNoise(___m_attackHitNoise); if (___m_weapon.m_shared.m_spawnOnHit) { Object.Instantiate(___m_weapon.m_shared.m_spawnOnHit, pos, Quaternion.identity).GetComponent <IProjectile>() ?.Setup(___m_character, zero, ___m_attackHitNoise, null, ___m_weapon); } foreach (Skills.SkillType skill in skillTypeSet) { ___m_character.RaiseSkill(skill, flag2 ? 1.5f : 1f); } if (!___m_spawnOnTrigger) { return; } Object.Instantiate(___m_spawnOnTrigger, zero, Quaternion.identity).GetComponent <IProjectile>()?.Setup(___m_character, ___m_character.transform.forward, -1f, null, ___m_weapon); return; }
// Token: 0x060002F6 RID: 758 RVA: 0x00018CFC File Offset: 0x00016EFC private void DoMeleeAttack() { Transform transform; Vector3 vector; this.GetMeleeAttackDir(out transform, out vector); Vector3 point = this.m_character.transform.InverseTransformDirection(vector); Quaternion quaternion = Quaternion.LookRotation(vector, Vector3.up); this.m_weapon.m_shared.m_triggerEffect.Create(transform.position, quaternion, transform, 1f); this.m_triggerEffect.Create(transform.position, quaternion, transform, 1f); Vector3 vector2 = transform.position + Vector3.up * this.m_attackHeight + this.m_character.transform.right * this.m_attackOffset; float num = this.m_attackAngle / 2f; float num2 = 4f; float attackRange = this.m_attackRange; List <Attack.HitPoint> list = new List <Attack.HitPoint>(); HashSet <Skills.SkillType> hashSet = new HashSet <Skills.SkillType>(); int layerMask = this.m_hitTerrain ? Attack.m_attackMaskTerrain : Attack.m_attackMask; for (float num3 = -num; num3 <= num; num3 += num2) { Quaternion rotation = Quaternion.identity; if (this.m_attackType == Attack.AttackType.Horizontal) { rotation = Quaternion.Euler(0f, -num3, 0f); } else if (this.m_attackType == Attack.AttackType.Vertical) { rotation = Quaternion.Euler(num3, 0f, 0f); } Vector3 vector3 = this.m_character.transform.TransformDirection(rotation * point); Debug.DrawLine(vector2, vector2 + vector3 * attackRange); RaycastHit[] array; if (this.m_attackRayWidth > 0f) { array = Physics.SphereCastAll(vector2, this.m_attackRayWidth, vector3, Mathf.Max(0f, attackRange - this.m_attackRayWidth), layerMask, QueryTriggerInteraction.Ignore); } else { array = Physics.RaycastAll(vector2, vector3, attackRange, layerMask, QueryTriggerInteraction.Ignore); } Array.Sort <RaycastHit>(array, (RaycastHit x, RaycastHit y) => x.distance.CompareTo(y.distance)); foreach (RaycastHit raycastHit in array) { if (!(raycastHit.collider.gameObject == this.m_character.gameObject)) { Vector3 vector4 = raycastHit.point; if (raycastHit.distance < 1E-45f) { if (raycastHit.collider is MeshCollider) { vector4 = vector2 + vector3 * attackRange; } else { vector4 = raycastHit.collider.ClosestPoint(vector2); } } if (this.m_attackAngle >= 180f || Vector3.Dot(vector4 - vector2, vector) > 0f) { GameObject gameObject = Projectile.FindHitObject(raycastHit.collider); if (!(gameObject == this.m_character.gameObject)) { Vagon component = gameObject.GetComponent <Vagon>(); if (!component || !component.IsAttached(this.m_character)) { Character component2 = gameObject.GetComponent <Character>(); if (!(component2 != null) || ((this.m_character.IsPlayer() || BaseAI.IsEnemy(this.m_character, component2)) && (!this.m_weapon.m_shared.m_dodgeable || !component2.IsDodgeInvincible()))) { this.AddHitPoint(list, gameObject, raycastHit.collider, vector4, raycastHit.distance); if (!this.m_hitThroughWalls) { break; } } } } } } } } int num4 = 0; Vector3 vector5 = Vector3.zero; bool flag = false; bool flag2 = false; foreach (Attack.HitPoint hitPoint in list) { GameObject go = hitPoint.go; Vector3 vector6 = hitPoint.avgPoint / (float)hitPoint.count; Vector3 vector7 = vector6; switch (this.m_hitPointtype) { case Attack.HitPointType.Closest: vector7 = hitPoint.closestPoint; break; case Attack.HitPointType.Average: vector7 = vector6; break; case Attack.HitPointType.First: vector7 = hitPoint.firstPoint; break; } num4++; vector5 += vector6; this.m_weapon.m_shared.m_hitEffect.Create(vector7, Quaternion.identity, null, 1f); this.m_hitEffect.Create(vector7, Quaternion.identity, null, 1f); IDestructible component3 = go.GetComponent <IDestructible>(); if (component3 != null) { DestructibleType destructibleType = component3.GetDestructibleType(); Skills.SkillType skillType = this.m_weapon.m_shared.m_skillType; if (this.m_specialHitSkill != Skills.SkillType.None && (destructibleType & this.m_specialHitType) != DestructibleType.None) { skillType = this.m_specialHitSkill; } float num5 = this.m_character.GetRandomSkillFactor(skillType); if (this.m_lowerDamagePerHit && list.Count > 1) { num5 /= (float)list.Count * 0.75f; } HitData hitData = new HitData(); hitData.m_toolTier = this.m_weapon.m_shared.m_toolTier; hitData.m_statusEffect = (this.m_weapon.m_shared.m_attackStatusEffect ? this.m_weapon.m_shared.m_attackStatusEffect.name : ""); hitData.m_pushForce = this.m_weapon.m_shared.m_attackForce * num5 * this.m_forceMultiplier; hitData.m_backstabBonus = this.m_weapon.m_shared.m_backstabBonus; hitData.m_staggerMultiplier = this.m_staggerMultiplier; hitData.m_dodgeable = this.m_weapon.m_shared.m_dodgeable; hitData.m_blockable = this.m_weapon.m_shared.m_blockable; hitData.m_skill = skillType; hitData.m_damage = this.m_weapon.GetDamage(); hitData.m_point = vector7; hitData.m_dir = (vector7 - vector2).normalized; hitData.m_hitCollider = hitPoint.collider; hitData.SetAttacker(this.m_character); hitData.m_damage.Modify(this.m_damageMultiplier); hitData.m_damage.Modify(num5); hitData.m_damage.Modify(this.GetLevelDamageFactor()); if (this.m_attackChainLevels > 1 && this.m_currentAttackCainLevel == this.m_attackChainLevels - 1) { hitData.m_damage.Modify(2f); hitData.m_pushForce *= 1.2f; } this.m_character.GetSEMan().ModifyAttack(skillType, ref hitData); if (component3 is Character) { flag2 = true; } component3.Damage(hitData); if ((destructibleType & this.m_resetChainIfHit) != DestructibleType.None) { this.m_nextAttackChainLevel = 0; } hashSet.Add(skillType); if (!this.m_multiHit) { break; } } if (go.GetComponent <Heightmap>() != null && !flag) { flag = true; this.m_weapon.m_shared.m_hitTerrainEffect.Create(vector6, quaternion, null, 1f); this.m_hitTerrainEffect.Create(vector6, quaternion, null, 1f); if (this.m_weapon.m_shared.m_spawnOnHitTerrain) { this.SpawnOnHitTerrain(vector6, this.m_weapon.m_shared.m_spawnOnHitTerrain); } if (!this.m_multiHit) { break; } } } if (num4 > 0) { vector5 /= (float)num4; if (this.m_weapon.m_shared.m_useDurability && this.m_character.IsPlayer()) { this.m_weapon.m_durability -= this.m_weapon.m_shared.m_useDurabilityDrain; } this.m_character.AddNoise(this.m_attackHitNoise); this.m_animEvent.FreezeFrame(0.15f); if (this.m_weapon.m_shared.m_spawnOnHit) { IProjectile component4 = UnityEngine.Object.Instantiate <GameObject>(this.m_weapon.m_shared.m_spawnOnHit, vector5, quaternion).GetComponent <IProjectile>(); if (component4 != null) { component4.Setup(this.m_character, Vector3.zero, this.m_attackHitNoise, null, this.m_weapon); } } foreach (Skills.SkillType skill in hashSet) { this.m_character.RaiseSkill(skill, flag2 ? 1.5f : 1f); } } if (this.m_spawnOnTrigger) { IProjectile component5 = UnityEngine.Object.Instantiate <GameObject>(this.m_spawnOnTrigger, vector2, Quaternion.identity).GetComponent <IProjectile>(); if (component5 != null) { component5.Setup(this.m_character, this.m_character.transform.forward, -1f, null, this.m_weapon); } } }