public CreatureObject GetNearest(CreatureObject Source, List<CreatureObject> Creatures) { AreaObject SourceArea = Source.Area; Vector3 SourcePos = Source.Position; CreatureObject RetValue = null; if (Creatures.Count == 0) return RetValue; float ShortestDistance = -1.0f; foreach (CreatureObject Target in Creatures) { // Only interested in objects in the same area. if (SourceArea != Target.Area) continue; Vector3 TargetPos = Target.Position; float Distance = MathOps.DistanceSq(SourcePos, TargetPos); if ((ShortestDistance < 0) || (Distance < ShortestDistance)) { ShortestDistance = Distance; RetValue = Target; } } return RetValue; }
public CreatureObject GetFarthest(CreatureObject Source, List<CreatureObject> Creatures) { AreaObject SourceArea = Source.Area; Vector3 SourcePos = Source.Position; CreatureObject RetValue = null; if (Creatures.Count == 0) return RetValue; float LongestDistance = -1.0f; foreach (CreatureObject Target in Creatures) { // Only interested in objects in the same area. if (SourceArea != Target.Area) continue; Vector3 TargetPos = Target.Position; float Distance = MathOps.DistanceSq(SourcePos, TargetPos); if ((LongestDistance < 0) || ((Distance > LongestDistance) && (Distance < 100.0f * 100.0f))) // 100 meters is about as far as we'd expect combat to reach. { LongestDistance = Distance; RetValue = Target; } } return RetValue; }
public void AddPartyEnemy(CreatureObject PartyEnemy) { if (PartyEnemy == null) { throw new ApplicationException("Trying to add party enemy, but that creature does not exist."); } Enemies.Add(PartyEnemy); if (CanPartySee(PartyEnemy)) { int EnemyArmorRank = PartyEnemy.Script.GetArmorRank(PartyEnemy.Script.GetItemInSlot(CLRScriptBase.INVENTORY_SLOT_CARMOUR, PartyEnemy.ObjectId)); if (EnemyArmorRank == CLRScriptBase.ARMOR_RANK_HEAVY || EnemyArmorRank == CLRScriptBase.ARMOR_RANK_MEDIUM) EnemyHardTargets.Add(PartyEnemy); if (EnemyArmorRank == CLRScriptBase.ARMOR_RANK_LIGHT || EnemyArmorRank == CLRScriptBase.ARMOR_RANK_NONE) EnemySoftTargets.Add(PartyEnemy); if (_LooksLikeSpellcaster(PartyEnemy)) EnemySpellcasters.Add(PartyEnemy); } else { EnemiesLost.Add(PartyEnemy); } }
public void RemovePartyEnemy(CreatureObject PartyEnemy) { Enemies.Remove(PartyEnemy); EnemyHardTargets.Remove(PartyEnemy); EnemySoftTargets.Remove(PartyEnemy); EnemySpellcasters.Remove(PartyEnemy); EnemyHealers.Remove(PartyEnemy); }
/// <summary> /// Promote a creature in the party to party leader. /// </summary> /// <param name="PartyLeader">Supplies the new party leader.</param> public void PromotePartyLeader(CreatureObject PartyLeader) { if (PartyLeader != null) { if (PartyLeader.Party != this) { throw new ApplicationException(String.Format( "Trying to promote creature {0} to party leader, but it is not in this party.", PartyLeader)); } } this.PartyLeader = PartyLeader; }
/// <summary> /// Add a party member. /// </summary> /// <param name="Creature">Supplies the creature to add.</param> public void AddPartyMember(CreatureObject Creature) { if (Creature.Party != null) { throw new ApplicationException(String.Format( "Adding creature {0} to party, but it is already joined to a party.")); } PartyMembers.Add(Creature); Creature.Party = this; // No party leader defined. Guess it's this guy! if (PartyLeader == null) { PartyLeader = Creature; } // Existing party leader. Is this guy better at it? else { // If I'm the more charismatic leader, I take over. if (Creature.Script.GetAbilityScore(Creature.ObjectId, CLRScriptBase.ABILITY_CHARISMA, CLRScriptBase.TRUE) > PartyLeader.Script.GetAbilityScore(PartyLeader.ObjectId, CLRScriptBase.ABILITY_CHARISMA, CLRScriptBase.TRUE)) PartyLeader = Creature; // We're equally charismatic, but I'm more experienced. I take over. else if (Creature.Script.GetAbilityScore(Creature.ObjectId, CLRScriptBase.ABILITY_CHARISMA, CLRScriptBase.TRUE) == PartyLeader.Script.GetAbilityScore(PartyLeader.ObjectId, CLRScriptBase.ABILITY_CHARISMA, CLRScriptBase.TRUE) && Creature.Script.GetHitDice(Creature.ObjectId) > PartyLeader.Script.GetHitDice(PartyLeader.ObjectId)) PartyLeader = Creature; } // Now that leadership is established, what sort of guy is this? AIParty.AIType TacticsType = (AIParty.AIType)Creature.Script.GetLocalInt(Creature.ObjectId, "ACR_CREATURE_BEHAVIOR"); if (TacticsType == AIType.BEHAVIOR_TYPE_UNDEFINED) { string Tactics = Creature.Script.GetLocalString(Creature.ObjectId, "ACR_CREATURE_BEHAVIOR"); if (!Enum.TryParse<AIParty.AIType>(Tactics.ToUpper(), out TacticsType)) TacticsType = AIType.BEHAVIOR_TYPE_UNDEFINED; } if(TacticsType != AIType.BEHAVIOR_TYPE_UNDEFINED) { if(TacticsType == AIType.BEHAVIOR_TYPE_ANIMAL) { this.PartyAnimals.Add(Creature); Creature.TacticsType = TacticsType; } else if(TacticsType == AIType.BEHAVIOR_TYPE_ARCHER) { this.PartyArchers.Add(Creature); Creature.TacticsType = TacticsType; } else if(TacticsType == AIType.BEHAVIOR_TYPE_BUFFS) { this.PartyBuffs.Add(Creature); Creature.TacticsType = TacticsType; } else if(TacticsType == AIType.BEHAVIOR_TYPE_CONTROL) { this.PartyControls.Add(Creature); Creature.TacticsType = TacticsType; } else if(TacticsType == AIType.BEHAVIOR_TYPE_COWARD) { this.PartyCowards.Add(Creature); Creature.TacticsType = TacticsType; } else if(TacticsType == AIType.BEHAVIOR_TYPE_FLANK) { this.PartyFlanks.Add(Creature); Creature.TacticsType = TacticsType; } else if(TacticsType == AIType.BEHAVIOR_TYPE_MEDIC) { this.PartyMedics.Add(Creature); Creature.TacticsType = TacticsType; } else if(TacticsType == AIType.BEHAVIOR_TYPE_MINDLESS) { this.PartyMindless.Add(Creature); Creature.TacticsType = TacticsType; } else if(TacticsType == AIType.BEHAVIOR_TYPE_NUKE) { this.PartyNukes.Add(Creature); Creature.TacticsType = TacticsType; } else if(TacticsType == AIType.BEHAVIOR_TYPE_SHOCK) { this.PartyShocks.Add(Creature); Creature.TacticsType = TacticsType; } else if(TacticsType == AIType.BEHAVIOR_TYPE_SKIRMISH) { this.PartySkrimishers.Add(Creature); Creature.TacticsType = TacticsType; } else if(TacticsType == AIType.BEHAVIOR_TYPE_TANK) { this.PartyTanks.Add(Creature); Creature.TacticsType = TacticsType; } else { TacticsType = AIType.BEHAVIOR_TYPE_UNDEFINED; Creature.Script.SendMessageToAllDMs(String.Format("** ERROR ** : {0} has an AI type {1} defined, but that type is not understood by ACR_CreatureBehavior. This creature DOES NOT KNOW HOW TO FIGHT, and needs to be despawned.", Creature, TacticsType)); throw new ApplicationException(String.Format("Creature {0} has an AI type {1} defined, but that type is not understood by ACR_CreatureBehavior.", Creature, TacticsType)); } } else if (TacticsType == AIType.BEHAVIOR_TYPE_UNDEFINED) { //================================================================================================================================================== // Maybe this is an easy question. Is the creature stupid? //================================================================================================================================================== // The creature is mindless; that's a simple thing. if (Creature.Script.GetAbilityScore(Creature.ObjectId, CLRScriptBase.ABILITY_INTELLIGENCE, CLRScriptBase.TRUE) == 0) { Creature.TacticsType = AIType.BEHAVIOR_TYPE_MINDLESS; this.PartyMindless.Add(Creature); } // The creature is too dumb to take more than simple orders. else if (Creature.Script.GetAbilityScore(Creature.ObjectId, CLRScriptBase.ABILITY_INTELLIGENCE, CLRScriptBase.TRUE) < 6) { Creature.TacticsType = AIType.BEHAVIOR_TYPE_ANIMAL; this.PartyAnimals.Add(Creature); } //================================================================================================================================================== // No such luck. We have to figure out how to make this creature act. Count and categorize classes. //================================================================================================================================================== else { int Heal = 0; int Buff = 0; int Blast = 0; int Tank = 0; int Crush = 0; int Flank = 0; int Skirm = 0; int Arch = 0; int Cont = 0; for (int nClassPosition = 0; nClassPosition < 4; nClassPosition++) { int nClass = Creature.Script.GetClassByPosition(nClassPosition, Creature.ObjectId); int nClassLevel = Creature.Script.GetLevelByClass(nClass, Creature.ObjectId); // Members of these classes commonly have and prepare healing spells. if (nClass == CLRScriptBase.CLASS_TYPE_CLERIC || nClass == CLRScriptBase.CLASS_TYPE_DRUID || nClass == CLRScriptBase.CLASS_TYPE_FAVORED_SOUL || nClass == CLRScriptBase.CLASS_TYPE_SPIRIT_SHAMAN) { Heal += nClassLevel; } // Members of these classes commonly have good support magic. else if (nClass == CLRScriptBase.CLASS_TYPE_BARD) { Buff += nClassLevel; } // Members of these classes are usually well-set to focus on aggressive magic. else if (nClass == CLRScriptBase.CLASS_TYPE_SORCERER || nClass == CLRScriptBase.CLASS_TYPE_WARLOCK) { Blast += nClassLevel; } // Members of these classes tend to have some combination of high AC, good saves, and/or damage reduction. else if (nClass == CLRScriptBase.CLASS_TYPE_FIGHTER || nClass == CLRScriptBase.CLASS_TYPE_PALADIN || nClass == 35 || nClass == CLRScriptBase.CLASS_TYPE_UNDEAD || nClass == CLRScriptBase.CLASS_TYPE_CONSTRUCT) // CLASS_TYPE_PLANT is undefined. { Tank += nClassLevel; } // Members of these classes tend to do a lot of damage in direct melee combat. else if (nClass == CLRScriptBase.CLASS_TYPE_BARBARIAN || nClass == CLRScriptBase.CLASS_TYPE_OOZE || nClass == CLRScriptBase.CLASS_TYPE_VERMIN || nClass == CLRScriptBase.CLASS_TYPE_OUTSIDER || nClass == CLRScriptBase.CLASS_TYPE_GIANT || nClass == CLRScriptBase.CLASS_TYPE_BEAST || nClass == CLRScriptBase.CLASS_TYPE_ELEMENTAL || nClass == CLRScriptBase.CLASS_TYPE_MONSTROUS || nClass == CLRScriptBase.CLASS_TYPE_HUMANOID) { Crush += nClassLevel; } // Members of these classes are typically the most-threatening if they can stab an opponent in the back. else if (nClass == CLRScriptBase.CLASS_TYPE_ROGUE || nClass == CLRScriptBase.CLASS_TYPE_SWASHBUCKLER) { Flank += nClassLevel; } // Members of these classes are typically highly-mobile. else if (nClass == CLRScriptBase.CLASS_TYPE_MONK || nClass == CLRScriptBase.CLASS_TYPE_RANGER || nClass == CLRScriptBase.CLASS_TYPE_SHAPECHANGER || nClass == CLRScriptBase.CLASS_TYPE_MAGICAL_BEAST || nClass == CLRScriptBase.CLASS_TYPE_ANIMAL) { Skirm += nClassLevel; } // Members of these classes are typically best at attacking from a distance. else if (nClass == CLRScriptBase.CLASS_TYPE_RANGER) { Arch += nClassLevel; } // Members of these classes typically have or prepare spells which control the battlefield. else if (nClass == CLRScriptBase.CLASS_TYPE_WIZARD || nClass == CLRScriptBase.CLASS_TYPE_FEY || nClass == CLRScriptBase.CLASS_TYPE_ABERRATION) { Cont += nClassLevel; } } //================================================================================================================================================== // Now that we know classes by their generic type, we compare the varieties. //================================================================================================================================================== // Spellcasting conters are higher than the others; this person is mostly a spellcaster. if (Heal + Buff + Blast + Cont > Tank + Crush && Heal + Buff + Blast + Cont > Flank + Skirm + Arch) { // Spellcaster is better at controlling the field than others. if (Cont > Buff && Cont > Blast && Cont > Heal) { this.PartyControls.Add(Creature); Creature.TacticsType = AIType.BEHAVIOR_TYPE_CONTROL; } // Spellcaster is better at support magic than others. else if (Buff > Blast && Buff > Heal) { this.PartyBuffs.Add(Creature); Creature.TacticsType = AIType.BEHAVIOR_TYPE_BUFFS; } // Spellcaster is better at destroying things than not. else if (Blast > Heal) { this.PartyNukes.Add(Creature); Creature.TacticsType = AIType.BEHAVIOR_TYPE_NUKE; } // Spellcaster is either a healer or we don't know. We'll set them to taking care of pals. else { this.PartyMedics.Add(Creature); Creature.TacticsType = AIType.BEHAVIOR_TYPE_MEDIC; } } // Looks like a melee fighter. else if (Tank + Crush > Flank + Skirm + Arch) { if (Tank > Crush) { this.PartyTanks.Add(Creature); Creature.TacticsType = AIType.BEHAVIOR_TYPE_TANK; } else { this.PartyShocks.Add(Creature); Creature.TacticsType = AIType.BEHAVIOR_TYPE_SHOCK; } } // Looks like a skilled character. else if (Flank + Skirm + Arch > 0) { if (Flank > Skirm && Flank > Arch) { this.PartyFlanks.Add(Creature); Creature.TacticsType = AIType.BEHAVIOR_TYPE_FLANK; } else if (Arch > Skirm) { this.PartyArchers.Add(Creature); Creature.TacticsType = AIType.BEHAVIOR_TYPE_ARCHER; } else { this.PartySkrimishers.Add(Creature); Creature.TacticsType = AIType.BEHAVIOR_TYPE_SKIRMISH; } } // None of them have any value. This guy is probably useless, except that he can run for help. else { this.PartyCowards.Add(Creature); Creature.TacticsType = AIType.BEHAVIOR_TYPE_COWARD; } } } }
/// <summary> /// This serves as a wrapper about calls to ActionAttack, to apply things like the uncanny /// dodge modifiers /// </summary> /// <returns>true if the attack is successfully staged</returns> public bool _AttackWrapper(CreatureObject AttackTarget) { if (Script.GetIsObjectValid(AttackTarget.ObjectId) == CLRScriptBase.TRUE) { if (Script.GetHasFeat(2179, ObjectId, CLRScriptBase.TRUE) == CLRScriptBase.TRUE) // Shadow touch attack { Script.ActionUseTalentOnObject(Script.TalentFeat(2179), AttackTarget.ObjectId); return true; } else { if (Script.GetCurrentAction(ObjectId) == CLRScriptBase.ACTION_ATTACKOBJECT && Script.GetAttackTarget(ObjectId) == AttackTarget.ObjectId) { return true; } else { Script.ClearAllActions(CLRScriptBase.FALSE); Script.ActionAttack(AttackTarget.ObjectId, CLRScriptBase.FALSE); return true; } } } return false; }
public Int32 ScriptMain([In] object[] ScriptParameters, [In] Int32 DefaultReturnCode) { Int32 ReturnCode = 0; switch ((EVENT_TYPE)ScriptParameters[0]) { case EVENT_TYPE.CREATURE_ON_SPAWN: { CreatureObject Creature = new CreatureObject(OBJECT_SELF, Server.ObjectManager); Creature.OnSpawn(); } break; case EVENT_TYPE.CREATURE_ON_SPELL_CAST_AT: { CreatureObject Creature = Server.ObjectManager.GetCreatureObject(OBJECT_SELF); if (Creature != null) Creature.OnSpellCastAt(GetLastSpellCaster(), GetLastSpell()); } break; case EVENT_TYPE.CREATURE_ON_PHYSICALLY_ATTACKED: { CreatureObject Creature = Server.ObjectManager.GetCreatureObject(OBJECT_SELF); if (Creature != null) Creature.OnAttacked(GetLastAttacker(OBJECT_SELF)); } break; case EVENT_TYPE.CREATURE_ON_DAMAGED: { CreatureObject Creature = Server.ObjectManager.GetCreatureObject(OBJECT_SELF); if (Creature != null) Creature.OnDamaged(GetLastDamager(OBJECT_SELF), GetTotalDamageDealt()); } break; case EVENT_TYPE.CREATURE_ON_DEATH: { CreatureObject Creature = Server.ObjectManager.GetCreatureObject(OBJECT_SELF); if (Creature != null) Creature.OnDeath(GetLastKiller()); } break; case EVENT_TYPE.CREATURE_ON_BLOCKED: { CreatureObject Creature = Server.ObjectManager.GetCreatureObject(OBJECT_SELF); if (Creature != null) Creature.OnBlocked(GetBlockingDoor()); } break; case EVENT_TYPE.CREATURE_END_COMBAT_ROUND: { CreatureObject Creature = Server.ObjectManager.GetCreatureObject(OBJECT_SELF); if (Creature != null) Creature.OnEndCombatRound(); } break; case EVENT_TYPE.CREATURE_ON_CONVERSATION: { CreatureObject Creature = Server.ObjectManager.GetCreatureObject(OBJECT_SELF); if (Creature != null) Creature.OnConversation(); } break; case EVENT_TYPE.CREATURE_ON_INVENTORY_DISTURBED: { CreatureObject Creature = Server.ObjectManager.GetCreatureObject(OBJECT_SELF); if (Creature != null) Creature.OnInventoryDisturbed(); } break; case EVENT_TYPE.CREATURE_ON_HEARTBEAT: { CreatureObject Creature = Server.ObjectManager.GetCreatureObject(OBJECT_SELF); if (Creature != null) Creature.OnHeartbeat(); } break; case EVENT_TYPE.CREATURE_ON_RESTED: { CreatureObject Creature = Server.ObjectManager.GetCreatureObject(OBJECT_SELF); if (Creature != null) Creature.OnRested(); } break; case EVENT_TYPE.CREATURE_ON_PERCEPTION: { CreatureObject Creature = Server.ObjectManager.GetCreatureObject(OBJECT_SELF); if (Creature != null) { Creature.OnPerception(GetLastPerceived(), GetLastPerceptionHeard() != CLRScriptBase.FALSE ? true : false, GetLastPerceptionInaudible() != CLRScriptBase.FALSE ? true : false, GetLastPerceptionSeen() != CLRScriptBase.FALSE ? true : false, GetLastPerceptionVanished() != CLRScriptBase.FALSE ? true : false); } } break; case EVENT_TYPE.CREATURE_ON_USER_DEFINED: { CreatureObject Creature = Server.ObjectManager.GetCreatureObject(OBJECT_SELF); if (Creature != null) Creature.OnUserDefined(GetUserDefinedEventNumber()); } break; case EVENT_TYPE.MODULE_ON_STARTED: { // // Initialize the server subsystem. // Server.Initialize(); foreach (AreaObject Area in Server.ObjectManager.GetAreas()) { foreach (uint ObjectInAreaId in Area.GetObjectIdsInArea()) { if (GetObjectType(ObjectInAreaId) == CLRScriptBase.OBJECT_TYPE_TRIGGER) { if (GetTransitionTarget(ObjectInAreaId) != OBJECT_INVALID) { AreaObject.AreaTransition Transition = new AreaObject.AreaTransition(); Transition.ObjectId = ObjectInAreaId; Transition.TargetArea = Server.ObjectManager.GetAreaObject(GetArea(GetTransitionTarget(ObjectInAreaId))); Area.AreaTransitions.Add(Transition); } } } } } break; case EVENT_TYPE.AREA_ON_INSTANCE_CREATE: { if (Server.ObjectManager == null) break; ModuleObject Module = Server.ObjectManager.Module; if (Module == null) break; Module.AddInstancedArea(OBJECT_SELF); } break; } if (Server.ObjectManager != null) Server.ObjectManager.ProcessPendingDeletions(); return ReturnCode; }
/// <summary> /// This will look for status afflictions that need healing. /// </summary> /// <param name="HealTarget">The target to be healed</param> /// <returns>True if an appropriate action is found and assigned</returns> public bool TryRemoveStatusAfflictions(CreatureObject HealTarget) { if (HealTarget.Confused || HealTarget.Insane || HealTarget.Frightened || HealTarget.Paralyzed || HealTarget.AbilityDamaged || HealTarget.Diseased || HealTarget.Blinded || HealTarget.Deaf || HealTarget.Poisoned) { if (Script.GetHasSpell(CLRScriptBase.SPELL_HEAL, ObjectId) == CLRScriptBase.TRUE) { Script.ActionUseTalentOnObject(Script.TalentSpell(CLRScriptBase.SPELL_HEAL), HealTarget.ObjectId); return true; } else { if (HealTarget.AbilityDamaged) { if (Script.GetHasSpell(CLRScriptBase.SPELL_LESSER_RESTORATION, ObjectId) == CLRScriptBase.TRUE && Script.GetHasSpell(CLRScriptBase.SPELL_RESTORATION, ObjectId) == CLRScriptBase.FALSE && Script.GetHasSpell(CLRScriptBase.SPELL_GREATER_RESTORATION, ObjectId) == CLRScriptBase.FALSE) { Script.ActionUseTalentOnObject(Script.TalentSpell(CLRScriptBase.SPELL_LESSER_RESTORATION), HealTarget.ObjectId); return true; } } if (HealTarget.Diseased) { if (Script.GetHasSpell(CLRScriptBase.SPELL_LESSER_RESTORATION, ObjectId) == CLRScriptBase.TRUE) { Script.ActionUseTalentOnObject(Script.TalentSpell(CLRScriptBase.SPELL_REMOVE_DISEASE), HealTarget.ObjectId); return true; } } if (HealTarget.Blinded || HealTarget.Deaf) { if (Script.GetHasSpell(CLRScriptBase.SPELL_REMOVE_BLINDNESS_AND_DEAFNESS, ObjectId) == CLRScriptBase.TRUE) { Script.ActionUseTalentOnObject(Script.TalentSpell(CLRScriptBase.SPELL_REMOVE_BLINDNESS_AND_DEAFNESS), HealTarget.ObjectId); return true; } } if (HealTarget.Poisoned) { if (Script.GetHasSpell(CLRScriptBase.SPELL_NEUTRALIZE_POISON, ObjectId) == CLRScriptBase.TRUE) { Script.ActionUseTalentOnObject(Script.TalentSpell(CLRScriptBase.SPELL_NEUTRALIZE_POISON), HealTarget.ObjectId); return true; } } } } if (HealTarget.Petrified) { if (Script.GetHasSpell(CLRScriptBase.SPELL_STONE_TO_FLESH, ObjectId) == CLRScriptBase.TRUE) { Script.ActionUseTalentOnObject(Script.TalentSpell(CLRScriptBase.SPELL_STONE_TO_FLESH), HealTarget.ObjectId); return true; } } if ((HealTarget.AbilityDrained || HealTarget.LevelDrain) || (HealTarget.AbilityDamaged && Script.GetHasSpell(CLRScriptBase.SPELL_LESSER_RESTORATION, ObjectId) == CLRScriptBase.FALSE)) { if (Script.GetHasSpell(CLRScriptBase.SPELL_RESTORATION, ObjectId) == CLRScriptBase.TRUE) { Script.ActionUseTalentOnObject(Script.TalentSpell(CLRScriptBase.SPELL_RESTORATION), HealTarget.ObjectId); return true; } else if (Script.GetHasSpell(CLRScriptBase.SPELL_GREATER_RESTORATION, ObjectId) == CLRScriptBase.FALSE) { Script.ActionUseTalentOnObject(Script.TalentSpell(CLRScriptBase.SPELL_GREATER_RESTORATION), HealTarget.ObjectId); return true; } } if (HealTarget.Cursed) { if (Script.GetHasSpell(CLRScriptBase.SPELL_REMOVE_CURSE, ObjectId) == CLRScriptBase.FALSE) { Script.ActionUseTalentOnObject(Script.TalentSpell(CLRScriptBase.SPELL_REMOVE_CURSE), HealTarget.ObjectId); return true; } } if (HealTarget.Wounded) { int nMissingHitPoints = HealTarget.MaxHitPoints - HealTarget.CurrentHitPoints; if (nMissingHitPoints == 0) nMissingHitPoints = 1; if (TryToHeal(HealTarget, nMissingHitPoints)) return true; } return false; }
/// <summary> /// This will search for an ability that will directly restore about HitPoints of hit points and use it on HealTarget /// </summary> /// <param name="HealTarget">The one to receive healing.</param> /// <param name="HitPoints">The amount to heal.</param> /// <returns>True if an ability is found.</returns> public bool TryToHeal(CreatureObject HealTarget, int HitPoints) { int SpellId = -1; NWTalent Healing = null; if (HitPoints > 50 && Script.GetHasSpell(CLRScriptBase.SPELL_HEAL, ObjectId) == CLRScriptBase.TRUE) SpellId = CLRScriptBase.SPELL_HEAL; else if(HitPoints > 50 && Script.GetHasSpell(CLRScriptBase.SPELL_MASS_HEAL, ObjectId) == CLRScriptBase.TRUE) SpellId = CLRScriptBase.SPELL_MASS_HEAL; else if (HitPoints > 21 && Script.GetHasSpell(CLRScriptBase.SPELL_CURE_CRITICAL_WOUNDS, ObjectId) == CLRScriptBase.TRUE) SpellId = CLRScriptBase.SPELL_CURE_CRITICAL_WOUNDS; else if (HitPoints > 21 && Script.GetHasSpell(CLRScriptBase.SPELL_MASS_CURE_CRITICAL_WOUNDS, ObjectId) == CLRScriptBase.TRUE) SpellId = CLRScriptBase.SPELL_MASS_CURE_CRITICAL_WOUNDS; else if (HitPoints > 16 && Script.GetHasSpell(CLRScriptBase.SPELL_CURE_SERIOUS_WOUNDS, ObjectId) == CLRScriptBase.TRUE) SpellId = CLRScriptBase.SPELL_CURE_SERIOUS_WOUNDS; else if (HitPoints > 16 && Script.GetHasSpell(CLRScriptBase.SPELL_MASS_CURE_SERIOUS_WOUNDS, ObjectId) == CLRScriptBase.TRUE) SpellId = CLRScriptBase.SPELL_MASS_CURE_SERIOUS_WOUNDS; else if (HitPoints > 10 && Script.GetHasSpell(CLRScriptBase.SPELL_CURE_MODERATE_WOUNDS, ObjectId) == CLRScriptBase.TRUE) SpellId = CLRScriptBase.SPELL_CURE_MODERATE_WOUNDS; else if (HitPoints > 10 && Script.GetHasSpell(CLRScriptBase.SPELL_MASS_CURE_MODERATE_WOUNDS, ObjectId) == CLRScriptBase.TRUE) SpellId = CLRScriptBase.SPELL_MASS_CURE_MODERATE_WOUNDS; else if (Script.GetHasSpell(CLRScriptBase.SPELL_CURE_LIGHT_WOUNDS, ObjectId) == CLRScriptBase.TRUE) SpellId = CLRScriptBase.SPELL_CURE_LIGHT_WOUNDS; else if (Script.GetHasSpell(CLRScriptBase.SPELL_MASS_CURE_LIGHT_WOUNDS, ObjectId) == CLRScriptBase.TRUE) SpellId = CLRScriptBase.SPELL_MASS_CURE_LIGHT_WOUNDS; else if (Script.GetHasSpell(CLRScriptBase.SPELL_CURE_MODERATE_WOUNDS, ObjectId) == CLRScriptBase.TRUE) SpellId = CLRScriptBase.SPELL_CURE_MODERATE_WOUNDS; else if (Script.GetHasSpell(CLRScriptBase.SPELL_CURE_SERIOUS_WOUNDS, ObjectId) == CLRScriptBase.TRUE) SpellId = CLRScriptBase.SPELL_CURE_SERIOUS_WOUNDS; else if (Script.GetHasSpell(CLRScriptBase.SPELL_CURE_CRITICAL_WOUNDS, ObjectId) == CLRScriptBase.TRUE) SpellId = CLRScriptBase.SPELL_CURE_CRITICAL_WOUNDS; if (SpellId != -1) { Healing = Script.TalentSpell(SpellId); Script.ActionUseTalentOnObject(Healing, HealTarget.ObjectId); return true; } else { if (HealTarget == this) { Healing = Script.GetCreatureTalentBest(CLRScriptBase.TALENT_CATEGORY_BENEFICIAL_HEALING_POTION, 20, ObjectId, 0); if (Script.GetIsTalentValid(Healing) == CLRScriptBase.TRUE) { Script.ActionUseTalentOnObject(Healing, HealTarget.ObjectId); return true; } } } return false; }
/// <summary> /// This will look for the most-urgent disabling status afflictions on HealTarget and attempt to cure them. /// </summary> /// <param name="HealTarget">The target to be healed</param> /// <returns>true if an appropriate action is assigned.</returns> public bool TryRemoveUrgentStatusAfflictions(CreatureObject HealTarget) { if (HealTarget.Confused || HealTarget.Insane || HealTarget.Frightened || HealTarget.Paralyzed || HealTarget.Blinded) { if (Script.GetHasSpell(CLRScriptBase.SPELL_HEAL, ObjectId) == CLRScriptBase.TRUE) { Script.ActionUseTalentOnObject(Script.TalentSpell(CLRScriptBase.SPELL_HEAL), HealTarget.ObjectId); return true; } if (HealTarget.Blinded || HealTarget.Deaf) { if (Script.GetHasSpell(CLRScriptBase.SPELL_REMOVE_BLINDNESS_AND_DEAFNESS, ObjectId) == CLRScriptBase.TRUE) { Script.ActionUseTalentOnObject(Script.TalentSpell(CLRScriptBase.SPELL_REMOVE_BLINDNESS_AND_DEAFNESS), HealTarget.ObjectId); return true; } } } if (HealTarget.Petrified) { if (Script.GetHasSpell(CLRScriptBase.SPELL_STONE_TO_FLESH, ObjectId) == CLRScriptBase.TRUE) { Script.ActionUseTalentOnObject(Script.TalentSpell(CLRScriptBase.SPELL_STONE_TO_FLESH), HealTarget.ObjectId); return true; } } if (HealTarget.Wounded) { int nMissingHitPoints = HealTarget.MaxHitPoints - HealTarget.CurrentHitPoints; if (nMissingHitPoints == 0) nMissingHitPoints = 1; if (TryToHeal(HealTarget, nMissingHitPoints)) return true; } return false; }
public bool CanPartyHear(CreatureObject Creature) { if (Creature == null) return false; if (Creature.ObjectId == null || Creature.ObjectId == 0) return false; if (PartyMembers == null) return false; // If there's no one in the party, well, obviously. foreach (CreatureObject PartyMember in PartyMembers) { if (PartyMember != null && PartyMember.Script.GetObjectHeard(PartyMember.ObjectId, Creature.ObjectId) == CLRScriptBase.TRUE) return true; } return false; }
public void RemovePartyEnemy(CreatureObject PartyEnemy) { if(Enemies.Contains(PartyEnemy)) Enemies.Remove(PartyEnemy); if(EnemyHardTargets.Contains(PartyEnemy)) EnemyHardTargets.Remove(PartyEnemy); if(EnemySoftTargets.Contains(PartyEnemy)) EnemySoftTargets.Remove(PartyEnemy); if(EnemySpellcasters.Contains(PartyEnemy)) EnemySpellcasters.Remove(PartyEnemy); if(EnemyHealers.Contains(PartyEnemy)) EnemyHealers.Remove(PartyEnemy); }
public bool CanPartyHear(CreatureObject Creature) { foreach (CreatureObject PartyMember in PartyMembers) { if (PartyMember.Script.GetObjectHeard(PartyMember.ObjectId, Creature.ObjectId) == CLRScriptBase.TRUE) return true; } return false; }
/// <summary> /// Remove a party member. If the party member was the last in the /// party, then the party is dissolved. /// </summary> /// <param name="Creature">Supplies the creature to remove.</param> public void RemovePartyMember(CreatureObject Creature) { if (Creature.Party != this) { throw new ApplicationException(String.Format( "Removing creature {0} from party, but it is not in this party.")); } PartyMembers.Remove(Creature); Creature.Party = null; if (PartyLeader == Creature) PartyLeader = null; if (PartyMembers.Count == 0) PartyManager.RemoveParty(this); switch ((AIType)Creature.TacticsType) { case AIType.BEHAVIOR_TYPE_ANIMAL: PartyAnimals.Remove(Creature); break; case AIType.BEHAVIOR_TYPE_ARCHER: PartyArchers.Remove(Creature); break; case AIType.BEHAVIOR_TYPE_BUFFS: PartyBuffs.Remove(Creature); break; case AIType.BEHAVIOR_TYPE_CONTROL: PartyControls.Remove(Creature); break; case AIType.BEHAVIOR_TYPE_COWARD: PartyCowards.Remove(Creature); break; case AIType.BEHAVIOR_TYPE_FLANK: PartyFlanks.Remove(Creature); break; case AIType.BEHAVIOR_TYPE_MEDIC: PartyMedics.Remove(Creature); break; case AIType.BEHAVIOR_TYPE_MINDLESS: PartyMindless.Remove(Creature); break; case AIType.BEHAVIOR_TYPE_NUKE: PartyNukes.Remove(Creature); break; case AIType.BEHAVIOR_TYPE_SHOCK: PartyShocks.Remove(Creature); break; case AIType.BEHAVIOR_TYPE_SKIRMISH: PartySkrimishers.Remove(Creature); break; case AIType.BEHAVIOR_TYPE_TANK: PartyTanks.Remove(Creature); break; default: break; } if (PartyMembers.Count > 0 && PartyLeader == null) { int nCha = 0; foreach (CreatureObject Member in PartyMembers) { if (Member.Script.GetAbilityModifier(CLRScriptBase.ABILITY_CHARISMA, Member.ObjectId) > nCha) { nCha = Member.Script.GetAbilityModifier(CLRScriptBase.ABILITY_CHARISMA, Member.ObjectId); PartyLeader = Member; } } } }
/// <summary> /// This function seeks signs of a spellcaster, looking for visible paraphenalia. Visibility is assumed, and should be checked separately. /// </summary> /// <param name="Creature">The creature to be assessed</param> /// <returns>True if there is some visible paraphenalia that suggests spellcasting.</returns> private bool _LooksLikeSpellcaster(CreatureObject Creature) { int VisibleSpellbooks = 0; foreach (uint Item in Creature.Script.GetItemsInInventory(Creature.ObjectId)) { if (Creature.Script.GetTag(Item) == "ACR_MOD_SPELLBOOK" || Creature.Script.GetTag(Item) == "ACR_MOD_HOLYSYMBOL") VisibleSpellbooks++; if (Creature.Script.GetHasInventory(Item) == CLRScriptBase.TRUE) { foreach (uint ContainerContents in Creature.Script.GetItemsInInventory(Item)) { if (Creature.Script.GetTag(ContainerContents) == "ACR_MOD_SPELLBOOK" || Creature.Script.GetTag(ContainerContents) == "ACR_MOD_HOLYSYMBOL") VisibleSpellbooks--; } } } if (VisibleSpellbooks > 0) return true; return false; }
/// <summary> /// This serves as a wrapper about calls to ActionAttack, to apply things like the uncanny /// dodge modifiers /// </summary> /// <returns>true if the attack is successfully staged</returns> public bool _AttackWrapper(CreatureObject AttackTarget) { Script.ActionAttack(AttackTarget.ObjectId, CLRScriptBase.FALSE); return false; }