internal void DisperseSeeds() { if (!m_nview || !m_nview.IsOwner() || !m_nview.IsValid() || Player.m_localPlayer == null) { return; } bool dispersed = false; int totalPlaced = 0; int maxRetries = configMaxRetries.Value; while (GetQueueSize() > 0) { string currentSeed = GetQueuedSeed(); int currentCount = GetQueuedSeedCount(); if (!seedPrefabMap.ContainsKey(currentSeed)) { logger.LogWarning("Key '" + currentSeed + "' not found in seedPrefabMap"); DumpQueueDetails(); logger.LogWarning("Shifting queue to remove invalid entry"); ShiftQueueDown(); return; } ItemConversion conversion = seedPrefabMap[currentSeed]; PlacementStatus status = TryPlacePlant(conversion, maxRetries); SetStatus(status); if (status == PlacementStatus.Planting) { totalPlaced += 1; dispersed = true; } else if (status == PlacementStatus.WrongBiome) { logger.LogDebug("Wrong biome deteced, moving " + currentSeed + " to end of queue"); MoveToEndOfQueue(currentSeed, currentCount, status); break; } else if (status == PlacementStatus.NoRoom) { break; } if (totalPlaced >= configDispersionCount.Value) { break; } } ; if (dispersed) { m_disperseEffects.Create(transform.position, Quaternion.Euler(0f, Random.Range(0, 360), 0f), transform, configRadius.Value / 5f); } }
// This is an exact copy of the ingame method "UseItem" to provide a reliable way of controlling it later static bool Prefix(Humanoid __instance, Inventory inventory, ItemDrop.ItemData item, bool fromInventoryGui, Inventory ___m_inventory, EffectList ___m_consumeItemEffects, ZSyncAnimation ___m_zanim) { if (inventory == null) { inventory = ___m_inventory; } if (!inventory.ContainsItem(item)) { return(false); } var hoverObject = __instance.GetHoverObject(); var hoverable = (hoverObject ? hoverObject.GetComponentInParent <Hoverable>() : null); if (hoverable != null && !fromInventoryGui) { var componentInParent = hoverObject.GetComponentInParent <Interactable>(); if (componentInParent != null && componentInParent.UseItem(__instance, item)) { return(false); } } if (item.m_shared.m_itemType == ItemDrop.ItemData.ItemType.Consumable) { if (__instance.ConsumeItem(inventory, item)) { ___m_consumeItemEffects.Create(Player.m_localPlayer.transform.position, Quaternion.identity); ___m_zanim.SetTrigger("eat"); } else { return(false); } } else if ((inventory != ___m_inventory || !(bool)_toggleEquiped.Invoke(__instance, new [] { item })) && !fromInventoryGui) { if (hoverable != null) { // FIXME Fix localization __instance.Message(MessageHud.MessageType.Center, "$msg_cantuseon"); // __instance.Message(MessageHud.MessageType.Center, Localization.instance.Localize("$msg_cantuseon", item.m_shared.m_name, hoverable.GetHoverName())); } else { // FIXME Fix localization __instance.Message(MessageHud.MessageType.Center, "$msg_useonwhat"); // __instance.Message(MessageHud.MessageType.Center, Localization.instance.Localize("$msg_useonwhat", item.m_shared.m_name)); } return(false); } Longship.Instance.EventManager.DispatchEvent(new HumanoidUseItemEvent(__instance, inventory, item)); return(false); }
// This is an exact copy of the ingame method "DropItem" to provide a reliable way of controlling it later static bool Prefix(Humanoid __instance, ref bool __result, Inventory inventory, ItemDrop.ItemData item, int amount, ItemDrop.ItemData ___m_hiddenLeftItem, ItemDrop.ItemData ___m_hiddenRightItem, ZSyncAnimation ___m_zanim, EffectList ___m_dropEffects, VisEquipment ___m_visEquipment) { if (item.m_shared.m_questItem) { __instance.Message(MessageHud.MessageType.Center, "$msg_cantdrop"); __result = false; return(false); } __instance.RemoveFromEquipQueue(item); __instance.UnequipItem(item, triggerEquipEffects: false); if (___m_hiddenLeftItem == item) { ___m_hiddenLeftItem = null; _setupVisEquipment.Invoke(__instance, new [] { ___m_visEquipment, (object)false }); } if (___m_hiddenRightItem == item) { ___m_hiddenRightItem = null; _setupVisEquipment.Invoke(__instance, new [] { ___m_visEquipment, (object)false }); } if (amount == item.m_stack) { // ZLog.Log("drop all " + amount + " " + item.m_stack); if (!inventory.RemoveItem(item)) { // ZLog.Log("Was not removed"); __result = false; return(false); } } else { // ZLog.Log("drop some " + amount + " " + item.m_stack); inventory.RemoveItem(item, amount); } ItemDrop itemDrop = ItemDrop.DropItem(item, amount, __instance.transform.position + __instance.transform.forward + __instance.transform.up, __instance.transform.rotation); Longship.Instance.EventManager.DispatchEvent(new HumanoidDropItemEvent(__instance, item, amount)); if (__instance.IsPlayer()) { itemDrop.OnPlayerDrop(); } itemDrop.GetComponent <Rigidbody>().velocity = (__instance.transform.forward + Vector3.up) * 5f; ___m_zanim.SetTrigger("interact"); ___m_dropEffects.Create(__instance.transform.position, Quaternion.identity); __instance.Message(MessageHud.MessageType.TopLeft, "$msg_dropped " + itemDrop.m_itemData.m_shared.m_name, itemDrop.m_itemData.m_stack, itemDrop.m_itemData.GetIcon()); __result = true; return(false); }
private static void PlayEffects() { EffectList effects = new EffectList(); List <EffectList.EffectData> effectList = new List <EffectList.EffectData>(); for (int i = 0; i < Player.m_localPlayer.m_deathEffects.m_effectPrefabs.Length; i++) { effectList.Add(Player.m_localPlayer.m_deathEffects.m_effectPrefabs[i]); } effects.m_effectPrefabs = effectList.ToArray(); effects.Create(Player.m_localPlayer.transform.position, Player.m_localPlayer.transform.rotation, Player.m_localPlayer.transform, 1f); }
private static IEnumerator DestroyNow(Ragdoll ragdoll, ZNetView nview, EffectList m_removeEffect) { Dbgl($"delaying destroying ragdoll"); yield return(new WaitForSeconds(Mathf.Max(destroyDelay.Value - dropDelay.Value, 0))); if (!modEnabled.Value) { yield break; } if (!nview.IsValid() || !nview.IsOwner()) { yield break; } Dbgl($"destroying ragdoll"); Vector3 averageBodyPosition = ragdoll.GetAverageBodyPosition(); m_removeEffect.Create(averageBodyPosition, Quaternion.identity, null, 1f, -1); ZNetScene.instance.Destroy(ragdoll.gameObject); }
// This is an exact copy of the ingame method "Pickup" to provide a reliable way of controlling it later static bool Prefix(GameObject go, Humanoid __instance, Inventory ___m_inventory, ZNetView ___m_nview, ItemDrop.ItemData ___m_rightItem, ItemDrop.ItemData ___m_hiddenRightItem, EffectList ___m_pickupEffects, ref bool __result) { var component = go.GetComponent <ItemDrop>(); if (component == null) { __result = false; return(false); } if (!component.CanPickup()) { __result = false; return(false); } if (___m_inventory.ContainsItem(component.m_itemData)) { __result = false; return(false); } if (component.m_itemData.m_shared.m_questItem && __instance.HaveUniqueKey(component.m_itemData.m_shared.m_name)) { __instance.Message(MessageHud.MessageType.Center, "$msg_cantpickup"); __result = false; return(false); } var flag = ___m_inventory.AddItem(component.m_itemData); if (___m_nview.GetZDO() == null) { UnityEngine.Object.Destroy(go); __result = true; return(true); } if (!flag) { __instance.Message(MessageHud.MessageType.Center, "$msg_noroom"); __result = false; return(false); } Longship.Instance.EventManager.DispatchEvent(new HumanoidPickupItemEvent(__instance, component.m_itemData)); if (component.m_itemData.m_shared.m_questItem) { __instance.AddUniqueKey(component.m_itemData.m_shared.m_name); } ZNetScene.instance.Destroy(go); if (flag && __instance.IsPlayer() && ___m_rightItem == null && ___m_hiddenRightItem == null && component.m_itemData.IsWeapon()) { __instance.EquipItem(component.m_itemData); } ___m_pickupEffects.Create(__instance.transform.position, Quaternion.identity); if (__instance.IsPlayer()) { __instance.ShowPickupMessage(component.m_itemData, component.m_itemData.m_stack); } __result = flag; return(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; }
private void FixedUpdate() { if (!GetComponent <ZNetView>()) { return; //wait for network spawn } bool wasPressed = isPressed; bool newPressed = FindPlayerInRange(); if (newPressed) { List <DoorPowerState> doors = DoorPowerState.FindDoorsInPlateRange(transform.position); float?maxTime = doors.Max(i => i.GetDoorConfig()?.openTime); pressCooldown = maxTime ?? Plugin.plateOpenDelay.Value; isPressed = true; } else { if (pressCooldown > 0) { pressCooldown -= Time.fixedDeltaTime; isPressed = true; } else { isPressed = false; } } bool stateChange = isPressed != wasPressed; Vector3 pos = isPressed ? new Vector3(0f, -0.025f, 0f) : new Vector3(0f, 0.05f, 0f); plate.transform.localPosition = pos; if (stateChange) { if (isPressed) { pressEffects.Create(transform.position, Quaternion.identity); } else { releaseEffects.Create(transform.position, Quaternion.identity); } List <DoorPowerState> doors = DoorPowerState.FindDoorsInPlateRange(transform.position); foreach (DoorPowerState door in doors) { if (isPressed) { door.AddPoweringPlate(this); } else { door.RemovePoweringPlate(this); } } } if (lastPlayer == null) { return; } if (stateChange || isPressed) { List <DoorPowerState> doors = DoorPowerState.FindDoorsInPlateRange(transform.position); foreach (DoorPowerState door in doors) { if (isPressed) { // always open the door if the plate is pressed door.Open(lastPlayer); } else { // only close the door if this is the last plate powering it if (door.GetPoweringPlates().Count(i => i != this) > 0) { continue; } door.Close(lastPlayer); } } } }