public override void OnThink() { base.OnThink(); Point3D location = Location; Map map = Map; //Outside of Guard Area if (GuardsHome && !(ControlMaster is PlayerMobile)) { if (Utility.GetDistance(Home, location) > MaxDistanceAllowedFromHome) { TimedStatic dirt = new TimedStatic(Utility.RandomList(7681, 7682), 5); dirt.Name = "dirt"; dirt.MoveToWorld(location, map); dirt.PublicOverheadMessage(MessageType.Regular, 0, false, ReturnHomeString); Effects.PlaySound(location, map, 0x657); int projectiles = 6; int particleSpeed = 4; for (int a = 0; a < projectiles; a++) { Point3D newLocation = new Point3D(location.X + Utility.RandomList(-5, -4, -3, -2, -1, 1, 2, 3, 4, 5), location.Y + Utility.RandomList(-5, -4, -3, -2, -1, 1, 2, 3, 4, 5), location.Z); SpellHelper.AdjustField(ref newLocation, map, 12, false); IEntity effectStartLocation = new Entity(Serial.Zero, new Point3D(location.X, location.Y, location.Z + 5), map); IEntity effectEndLocation = new Entity(Serial.Zero, new Point3D(newLocation.X, newLocation.Y, newLocation.Z + 5), map); Effects.SendMovingEffect(effectStartLocation, effectEndLocation, Utility.RandomList(0x3728), particleSpeed, 0, false, false, 0, 0); } Location = Home; Combatant = null; return; } } if (m_NeedWaypoint && m_CanTeleportToBaseNode && !(ControlMaster is PlayerMobile)) { Dictionary <UOACZWayPoint, int> DictWaypoints = new Dictionary <UOACZWayPoint, int>(); foreach (UOACZWayPoint waypoint in UOACZWayPoint.m_UOACZWaypoints) { if (!UOACZRegion.ContainsItem(waypoint)) { continue; } if (!waypoint.IsBaseNode) { continue; } int distanceToWaypoint = (Utility.GetDistance(Location, waypoint.Location)); if (distanceToWaypoint >= UOACZSystem.UndeadMaxDynamicWaypointRange) { continue; } int distanceWeight = (int)(Math.Round(((double)UOACZSystem.UndeadMaxDynamicWaypointRange - (double)distanceToWaypoint) * .05)); if (distanceWeight < 1) { distanceWeight = 1; } DictWaypoints.Add(waypoint, distanceWeight); } if (DictWaypoints.Count > 0) { int TotalValues = 0; foreach (KeyValuePair <UOACZWayPoint, int> pair in DictWaypoints) { TotalValues += pair.Value; } double ItemCheck = Utility.RandomDouble(); double CumulativeAmount = 0.0; double AdditionalAmount = 0.0; foreach (KeyValuePair <UOACZWayPoint, int> pair in DictWaypoints) { AdditionalAmount = (double)pair.Value / (double)TotalValues; if (ItemCheck >= CumulativeAmount && ItemCheck < (CumulativeAmount + AdditionalAmount)) { UOACZWayPoint waypoint = pair.Key; if (waypoint != null) { if (!waypoint.Deleted) { CurrentWaypoint = pair.Key; m_NeedWaypoint = false; return; } } break; } CumulativeAmount += AdditionalAmount; } } else { m_NeedWaypoint = false; } } if ((DateTime.UtcNow >= m_LastActivity + InactivityThreshold) && !(ControlMaster is PlayerMobile)) { //Send to Random Town Waypoint BaseNode if (m_CanTeleportToBaseNode) { List <UOACZWayPoint> m_ValidBaseNodes = new List <UOACZWayPoint>(); foreach (UOACZWayPoint waypoint in UOACZWayPoint.m_UOACZWaypoints) { if (waypoint == null) { continue; } if (waypoint.Deleted) { continue; } if (!UOACZRegion.ContainsItem(waypoint)) { continue; } if (!waypoint.IsBaseNode) { continue; } if (waypoint.WaypointType == UOACZWayPoint.UOACZWaypointType.UndeadWilderness) { continue; } m_ValidBaseNodes.Add(waypoint); } if (m_ValidBaseNodes.Count > 0) { UOACZWayPoint targetWaypoint = m_ValidBaseNodes[Utility.RandomMinMax(0, m_ValidBaseNodes.Count - 1)]; MoveToWorld(targetWaypoint.Location, targetWaypoint.Map); CurrentWaypoint = targetWaypoint; m_LastActivity = DateTime.UtcNow; m_NeedWaypoint = false; return; } } m_NeedWaypoint = true; return; } if (Utility.RandomDouble() < 0.005) { if (Combatant == null) { Say(idleSpeech[Utility.Random(idleSpeech.Length - 1)]); } else { Say(combatSpeech[Utility.Random(combatSpeech.Length - 1)]); } } bool ignoreBreakableStatics = false; if (Hidden && ControlMaster is PlayerMobile) { ignoreBreakableStatics = true; } if (DateTime.UtcNow >= m_NextBreakableStaticCheckAllowed && DateTime.UtcNow >= m_NextBreakableStaticAttackAllowed && !ignoreBreakableStatics) { m_NextBreakableStaticCheckAllowed = DateTime.UtcNow + BreakableStaticCheckDelay; BreakableStatic targetBreakableStatic = null; Dictionary <BreakableStatic, int> DictBreakableStatics = new Dictionary <BreakableStatic, int>(); IPooledEnumerable nearbyItems = Map.GetItemsInRange(Location, 1); foreach (Item item in nearbyItems) { if (item.Deleted) { continue; } if (item is BreakableStatic) { if (!Map.InLOS(Location, item.Location)) { continue; } BreakableStatic breakableStatic = item as BreakableStatic; if (breakableStatic is UOACZBreakableStatic) { UOACZBreakableStatic uoaczBreakableStatic = breakableStatic as UOACZBreakableStatic; if (uoaczBreakableStatic.AllowHumanDamage) { continue; } } if (breakableStatic.DamageState == BreakableStatic.DamageStateType.Broken) { continue; } int weight = 5; if (breakableStatic == m_LastBreakableStaticAttacked) { weight += 10; } int damageBonus = (int)Math.Round((10 * (1 - (double)breakableStatic.HitPoints / (double)breakableStatic.MaxHitPoints))); weight += damageBonus; DictBreakableStatics.Add(breakableStatic, weight); } } nearbyItems.Free(); int TotalValues = 0; foreach (KeyValuePair <BreakableStatic, int> pair in DictBreakableStatics) { TotalValues += pair.Value; } double ItemCheck = Utility.RandomDouble(); double CumulativeAmount = 0.0; double AdditionalAmount = 0.0; foreach (KeyValuePair <BreakableStatic, int> pair in DictBreakableStatics) { AdditionalAmount = (double)pair.Value / (double)TotalValues; if (ItemCheck >= CumulativeAmount && ItemCheck < (CumulativeAmount + AdditionalAmount)) { targetBreakableStatic = pair.Key; break; } CumulativeAmount += AdditionalAmount; } if (targetBreakableStatic != null) { double minHinder = 1; double maxHinder = 1; double weaponUsageDelay = 3; BaseWeapon weapon = Weapon as BaseWeapon; if (weapon != null) { weaponUsageDelay = weapon.GetDelay(this, false).TotalSeconds; } bool stockpileNearby = false; if (targetBreakableStatic is UOACZStockpile) { stockpileNearby = true; } else { switch (targetBreakableStatic.DamageState) { case BreakableStatic.DamageStateType.Normal: minHinder = weaponUsageDelay * .5; maxHinder = weaponUsageDelay; break; case BreakableStatic.DamageStateType.LightlyDamaged: minHinder = weaponUsageDelay * .65; maxHinder = weaponUsageDelay; break; case BreakableStatic.DamageStateType.HeavilyDamaged: minHinder = weaponUsageDelay * .8; maxHinder = weaponUsageDelay; break; } } double delay = minHinder + ((maxHinder - minHinder) * Utility.RandomDouble()); if (ControlMaster is PlayerMobile) { delay = 1; SpecialAbilities.EntangleSpecialAbility(1.0, null, this, 1, delay, 0, false, "", "", "-1"); } else { if (stockpileNearby) { delay = 10; SpecialAbilities.EntangleSpecialAbility(1.0, null, this, 1, delay, 0, false, "", "", "-1"); m_NextBreakableStaticAttackAllowed = DateTime.UtcNow + BreakableStaticAttackDelay; } else { if (Utility.RandomDouble() <= .5) { SpecialAbilities.HinderSpecialAbility(1.0, null, this, 1, delay, true, 0, false, "", "", "-1"); } else { SpecialAbilities.EntangleSpecialAbility(1.0, null, this, 1, delay, 0, false, "", "", "-1"); } m_NextBreakableStaticAttackAllowed = DateTime.UtcNow + BreakableStaticAttackDelay; } } targetBreakableStatic.Interact(this, BreakableStatic.InteractionType.Weapon); } } }
protected override void OnTick() { if (m_RepairHammer == null || m_Player == null) { if (m_RepairHammer != null) { m_RepairHammer.m_Owner = null; } if (m_RepairHammer != null) { m_Player.EndAction(typeof(UOACZRepairHammer)); } Stop(); return; } if (m_RepairHammer.Deleted || m_Player.Deleted) { m_RepairHammer.m_Owner = null; m_Player.EndAction(typeof(UOACZRepairHammer)); Stop(); return; } List <UOACZBreakableStatic> m_NearbyBreakableStatics = GetNearbyBreakableStatics(m_Player); if (m_NearbyBreakableStatics.Count == 0) { m_RepairHammer.m_Owner = null; m_Player.EndAction(typeof(UOACZRepairHammer)); Stop(); return; } UOACZBreakableStatic randomBreakableStatic = m_NearbyBreakableStatics[Utility.RandomMinMax(0, m_NearbyBreakableStatics.Count - 1)]; int repairableCount = 0; foreach (UOACZBreakableStatic breakableStatic in m_NearbyBreakableStatics) { if (breakableStatic.CanRepair(m_Player, m_RepairHammer, 1.0, false)) { repairableCount++; } } if (repairableCount == 0) { m_RepairHammer.m_Owner = null; m_Player.EndAction(typeof(UOACZRepairHammer)); m_Player.SendMessage("You stop making repairs."); Stop(); return; } if (m_RepairTicks == 0) { m_Player.BeginAction(typeof(BreakableStatic)); TimeSpan repairCooldown = TimeSpan.FromSeconds(RepairActionTickDuration.TotalSeconds * (double)RepairActionTicksNeeded); Timer.DelayCall(repairCooldown, delegate { if (m_Player != null) { m_Player.EndAction(typeof(BreakableStatic)); } }); } m_RepairTicks++; if (randomBreakableStatic.RepairSound != -1) { Effects.PlaySound(m_Player.Location, m_Player.Map, randomBreakableStatic.RepairSound); } m_Player.Animate(12, 5, 1, true, false, 0); m_Player.RevealingAction(); if (m_RepairTicks >= UOACZRepairHammer.RepairActionTicksNeeded) { m_RepairTicks = 0; int minRepairAmount = 40; int maxRepairAmount = 60; double baseRepairScalarBonus = 1.0; double carpentryScalar = 1 + (baseRepairScalarBonus * m_Player.Skills.Carpentry.Value / 100); double blacksmithingScalar = 1 + (baseRepairScalarBonus * m_Player.Skills.Carpentry.Value / 100); double tinkeringScalar = 1 + (baseRepairScalarBonus * m_Player.Skills.Carpentry.Value / 100); double bestScalar = 1; if (carpentryScalar > bestScalar) { bestScalar = carpentryScalar; } if (blacksmithingScalar > bestScalar) { bestScalar = blacksmithingScalar; } if (tinkeringScalar > bestScalar) { bestScalar = tinkeringScalar; } double repairValue = m_Player.GetSpecialAbilityEntryValue(SpecialAbilityEffect.EmergencyRepairs); bestScalar += repairValue; bool outpostWasRepaired = false; foreach (UOACZBreakableStatic breakableStatic in m_NearbyBreakableStatics) { int repairAmount = Utility.RandomMinMax(minRepairAmount, maxRepairAmount); repairAmount = (int)(Math.Round(((double)repairAmount * bestScalar))); if (breakableStatic.RequiresFullRepair) { BreakableStatic.DamageStateType damageState = breakableStatic.DamageState; breakableStatic.HitPoints += repairAmount; breakableStatic.PublicOverheadMessage(MessageType.Regular, UOACZSystem.greenTextHue, false, "+" + repairAmount); if (breakableStatic.HitPoints < breakableStatic.MaxHitPoints) { breakableStatic.DamageState = damageState; } else { breakableStatic.DamageState = BreakableStatic.DamageStateType.Normal; } } else { breakableStatic.HitPoints += repairAmount; breakableStatic.PublicOverheadMessage(MessageType.Regular, UOACZSystem.greenTextHue, false, "+" + repairAmount); } UOACZPersistance.CheckAndCreateUOACZAccountEntry(m_Player); m_Player.m_UOACZAccountEntry.TotalRepairAmount += repairAmount; m_Player.SendMessage("You repair an object for " + repairAmount.ToString() + " hitpoints."); if (UOACZPersistance.m_OutpostComponents.Contains(breakableStatic)) { outpostWasRepaired = true; UOACZEvents.RepairOutpostComponent(); } } UOACZPersistance.CheckAndCreateUOACZAccountEntry(m_Player); m_Player.m_UOACZAccountEntry.TimesRepaired++; bool scored = false; double scoreChance = UOACZSystem.HumanRepairScoreChance; if (outpostWasRepaired) { scoreChance += UOACZSystem.HumanOutpostRepairScoreChance; } if (Utility.RandomDouble() <= UOACZSystem.HumanRepairScoreChance) { UOACZSystem.ChangeStat(m_Player, UOACZSystem.UOACZStatType.HumanScore, 1, true); scored = true; } if (m_Player.Backpack != null) { if (Utility.RandomDouble() <= UOACZSystem.HumanRepairSurvivalStoneChance * UOACZPersistance.HumanBalanceScalar) { m_Player.Backpack.DropItem(new UOACZSurvivalStone(m_Player)); m_Player.SendMessage(UOACZSystem.greenTextHue, "You have earned a survival stone for your repair efforts!"); } if (Utility.RandomDouble() <= UOACZSystem.HumanRepairUpgradeTokenChance * UOACZPersistance.HumanBalanceScalar) { m_Player.Backpack.DropItem(new UOACZHumanUpgradeToken(m_Player)); m_Player.SendMessage(UOACZSystem.greenTextHue, "You have earned an upgrade token for your repair efforts!"); } } m_RepairHammer.Charges--; if (m_RepairHammer.Charges <= 0) { m_RepairHammer.Delete(); } } }