public void OnPlayerUseWorldItemSecondary(object secondaryResult) { WIListResult dialogResult = secondaryResult as WIListResult; switch (dialogResult.SecondaryResult) { case "Shear": State.LastTimeSheared = WorldClock.AdjustedRealTime; //spawn a random number of wool items //make it pop off the chest body part, upwards WorldItem shearedWorldItem = null; BodyPart chestBodyPart = null; creature.Body.GetBodyPart(BodyPartType.Chest, out chestBodyPart); Bounds colliderBounds = chestBodyPart.PartCollider.bounds; Vector3 popPosition; Vector3 popDirection; System.Random random = new System.Random(Profile.Get.CurrentGame.Seed); int numShearedItems = random.Next(MinShearedItems, MaxShearedItems); Debug.Log("Shearing " + numShearedItems.ToString() + " Items in " + name); for (int i = 0; i < numShearedItems; i++) { popPosition = (UnityEngine.Random.onUnitSphere * 5f) + chestBodyPart.tr.position; popPosition = chestBodyPart.PartCollider.ClosestPointOnBounds(popPosition); //give it a push in a direction away from the body popDirection = Vector3.Normalize(chestBodyPart.tr.position - popPosition); if (WorldItems.CloneWorldItem(ShearedItem, STransform.zero, false, WIGroups.GetCurrent(), out shearedWorldItem)) { shearedWorldItem.Initialize(); shearedWorldItem.SetMode(WIMode.World); shearedWorldItem.tr.position = popPosition; shearedWorldItem.ApplyForce(popDirection, popPosition); } //let them all fall away } //the creature freaks out but doesn't actually take damage creature.OnTakeDamage(); break; default: break; } }
public void SendDamage(DamagePackage damage, BodyPart bodyPart) { damageReceiver = damage.Target; damageHandler = null; damageWorldItem = null; damage.OnPackageSent.SafeInvoke(); if (damageReceiver != null) { //check if it's a player because it's the eaiest switch (damageReceiver.IOIType) { case ItemOfInterestType.Player: damageHandler = Player.Local.DamageHandler; break; case ItemOfInterestType.WorldItem: Damageable damageable = null; damageWorldItem = damageReceiver.worlditem; if (damageReceiver.worlditem.Is <Damageable> (out damageable)) { damageHandler = damageable; } else { //if it's an instant kill, destroy it now if (damage.InstantKill) { Debug.Log("Instant kill in damage manager"); damage.HitTarget = true; damage.TargetIsDead = true; damage.DamageDealt = damage.DamageSent; damageReceiver.worlditem.RemoveFromGame(); return; } } break; case ItemOfInterestType.Scenery: DamageableChild dc = null; if (damageReceiver.gameObject.HasComponent <DamageableChild> (out dc)) //get the parent from the damageable child { damageHandler = dc.DamageableParent; } else { //if it's not a world item and it's not a body part check for a general damage handler //this includes the player's damage handler damageHandler = (IDamageable)damageReceiver.gameObject.GetComponent(typeof(IDamageable)); } break; default: break; } } //apply damage using the damage handler if (damageHandler != null) { receiverMaterial = damageHandler.BaseMaterialType; receiverArmorMaterials = damageHandler.ArmorMaterialTypes; int receiverArmorLevel = 0; if (receiverArmorMaterials != WIMaterialType.None) { receiverArmorLevel = damageHandler.ArmorLevel(receiverArmorMaterials); } //get damage multiplier for material types //TODO re-enable these //damage.DamageSent = damage.DamageSent * BaseWeaponDamageMultiplier (damage.SenderMaterial, receiverMaterial); //damage.DamageSent = damage.DamageSent * BaseArmorReductionMultiplier (damage.SenderMaterial, receiverArmorMaterials); //check if there's a material bonus for this damage sender if (damage.MaterialBonus != WIMaterialType.None) { if (Flags.Check((uint)receiverMaterial, (uint)damage.MaterialBonus, Flags.CheckType.MatchAny)) { damage.DamageSent *= Globals.DamageMaterialBonusMultiplier; } } if (damage.MaterialPenalty != WIMaterialType.None) { if (Flags.Check((uint)receiverMaterial, (uint)damage.MaterialPenalty, Flags.CheckType.MatchAny)) { damage.DamageSent *= Globals.DamageMaterialPenaltyMultiplier; } } damageHandler.LastDamageSource = damage.Source; //this has a good chance of being null damageHandler.LastBodyPartHit = bodyPart; if (damage.InstantKill) { damageHandler.InstantKill(damage.Source); } else { damage.HitTarget = damageHandler.TakeDamage(damage.SenderMaterial, damage.Point, damage.DamageSent, damage.Force, damage.SenderName, out damage.DamageDealt, out damage.TargetIsDead); } if (damage.HitTarget) { SpawnDamageFX(damage.Point, receiverMaterial, damage.DamageDealt); PlayDamageSound(damage.Point, receiverMaterial, damage.DamageDealt); if (bodyPart != null && !damage.TargetIsDead) { switch (bodyPart.Type) { case BodyPartType.Eye: GUI.GUIManager.PostSuccess("Inflicted eye wound"); damage.DamageSent = Globals.DamageBodyPartEyeMultiplier; break; case BodyPartType.Head: case BodyPartType.Face: case BodyPartType.Neck: GUI.GUIManager.PostSuccess("Inflicted head wound"); damage.DamageSent *= Globals.DamageBodyPartHeadMultiplier; break; case BodyPartType.Chest: case BodyPartType.Hip: case BodyPartType.Segment: case BodyPartType.Shoulder: case BodyPartType.None: default: GUI.GUIManager.PostSuccess("Inflicted torso wound"); damage.DamageSent *= Globals.DamageBodyPartTorsoMultiplier; break; case BodyPartType.Finger: case BodyPartType.Hand: case BodyPartType.Wrist: case BodyPartType.Arm: case BodyPartType.Foot: case BodyPartType.Shin: case BodyPartType.Leg: GUI.GUIManager.PostSuccess("Inflicted limb wound"); damage.DamageSent *= Globals.DamageBodyPartLimbMultiplier; break; } } } damage.OnPackageReceived.SafeInvoke(); } else { //if we didn't find a damage handler but we did find a worlditem //send force to the worlditem so it doesn't just sit there if (damageWorldItem != null) { damageWorldItem.ApplyForce(damage.Force, damage.Point); } } //play the sender's fx no matter what SpawnDamageFX(damage.Point, damage.SenderMaterial, damage.DamageDealt); PlayDamageSound(damage.Point, damage.SenderMaterial, damage.DamageDealt); }