private void game_PlayerActed(Guid playerId, ActionType action, int amountToCall, int amount) { var actionBucket = ActionAbstracter.MapToBucket(action, amountToCall, currentGame.PotSize, amount); actionHistory.Add(actionBucket); FeatureAction featureAction = FeatureActionAbstracter.FromActionBucket(actionBucket); var currentPhasehistory = actionHistoriesPerPhase.FirstOrDefault(x => x.Phase == currentGame.Phase); currentPhasehistory.ActionHistory.Add(featureAction); if (this.Id != playerId) { Positioning opponentPositioning = Positioning.None; Aggression opponentAggression = Aggression.None; if (currentGame.Phase > GamePhase.PreFlop) { opponentPositioning = getOpponentPositioning(currentPhasehistory.ActionHistory.Count); opponentAggression = getOpponentAggression(opponentPositioning); } opponent.UpdateFeaturesAfterAction(currentPhasehistory.ActionHistory, currentGame.Phase, opponentAggression, opponentPositioning); } }
/// <summary> /// Body or another living has been attacked. /// </summary> /// <param name="living"></param> /// <param name="attackData"></param> protected virtual void OnAttacked(AttackData attackData) { if (attackData == null) { return; } if (attackData.Target == Body) { if (Body.IsReturningToSpawnPoint) { Body.CancelWalkToSpawn(); } if (!attackData.IsMeleeAttack) { ISpellHandler spellhandler = attackData.SpellHandler; if (spellhandler != null && spellhandler is TauntSpellHandler) { OnTaunted(attackData); return; } } Aggression.Raise(attackData.Attacker, attackData.Damage); // TODO: Process attack data and change the amount of aggro // accordingly. } else { OnLivingAttacked(attackData.Target, attackData.Attacker); } }
public void OnUnlinkPet() { m_Pet = null; m_Anchor = null; m_Aggression = Aggression.Aggressive; InvalidateProperties(); }
private bool ShouldTargetHuman <T>(Human otherHuman) where T : IResource { if (otherHuman.Dead) { return(false); } var isFoodSource = typeof(T) == typeof(IFoodSource); var aggression = Aggression.Get(_team, otherHuman._team); if (aggression == Aggression.Level.Neutral) { // Only if I'm starving return(isFoodSource && Hunger <= 5); } if (aggression == Aggression.Level.Aggressive) { // Only if I'm hungry return(isFoodSource && Hunger <= MAX_HUNGER / 2); } // If we're friendly we'll share, if we're murderous we'll kill return(true); }
public override void Deserialize(GenericReader reader) { base.Deserialize(reader); int v = reader.ReadInt(); m_Owner = reader.ReadMobile(); m_Pet = reader.ReadMobile() as DespiseCreature; m_LeashLength = (LeashLength)reader.ReadInt(); m_Aggression = (Aggression)reader.ReadInt(); m_Alignment = (Alignment)reader.ReadInt(); m_Conscripted = reader.ReadBool(); switch (reader.ReadInt()) { case 0: break; case 1: m_Anchor = reader.ReadMobile(); break; case 2: m_Anchor = reader.ReadItem(); break; } if (m_Anchor == null && m_Pet != null) { Anchor = m_Owner; } m_Orbs.Add(this); }
/// <summary> /// An enemy has been killed. /// </summary> /// <param name="living"></param> protected virtual void OnEnemyKilled(GameLiving living) { if (living == null) { return; } Aggression.Remove(living); }
public static bool CheckCombat(Mobile m, bool restrict = true) { if (!restrict) { return(false); } return(Aggression.CheckHasAggression(m, true)); }
public void ResourceDestroyed(IResource resource, Human culprit) { if (Dead) { return; } if (resource == _targetResource) { _targetResource = null; SetAnimationState(AnimationState.Standing); Aggression.Adjust(_team, culprit._team, 5); } }
public AI_FSM(NavMeshAgent _agent, Unit _unit) { agent = _agent; unit = _unit; state = State.idle; status = Status.inactive; aggression = Aggression.defensive; timer = 0; ally = null; enemy = null; location = agent.transform.position; caller = State.idle; }
/// <summary> /// The NPC has been taunted (spell). /// </summary> /// <param name="attackData"></param> protected virtual void OnTaunted(AttackData attackData) { GameLiving attacker = attackData.Attacker; if (attackData.Target == Body) { Aggression.Raise(attackData.Attacker, attackData.IsSpellResisted ? 0 : TauntAggressionAmount); } else { OnLivingAttacked(attackData.Target, attacker); } }
/// <summary> /// The NPC has nothing to do. /// </summary> protected virtual void OnIdle() { if (Body == null) { return; } foreach (GamePlayer player in Body.GetPlayersInRadius(AggressionRange)) { if (Util.Chance(GetChanceToAggroOn(player))) { Aggression.Raise(player, InternalAggression.Initial); return; } } }
/// <summary> /// An enemy was healed. /// </summary> /// <param name="source"></param> /// <param name="amount"></param> protected virtual void OnEnemyHealed(GameObject source, int amount) { if (source == null) { return; } if (source is GameLiving && amount > 1) { Aggression.Raise(source as GameLiving, amount / 2); } // TODO: Track the source of the heal, e.g. if the heal originated // from an object, find out who the owner is. // Adjust amount of aggro generated. }
protected override void WriteDataXML(XElement ele, ElderScrollsPlugin master) { XElement subEle; ele.TryPathTo("Aggression", true, out subEle); subEle.Value = Aggression.ToString(); ele.TryPathTo("Confidence", true, out subEle); subEle.Value = Confidence.ToString(); ele.TryPathTo("EnergyLevel", true, out subEle); subEle.Value = EnergyLevel.ToString(); ele.TryPathTo("Responsibility", true, out subEle); subEle.Value = Responsibility.ToString(); ele.TryPathTo("Mood", true, out subEle); subEle.Value = Mood.ToString(); WriteUnusedXML(ele, master); ele.TryPathTo("Services", true, out subEle); subEle.Value = Services.ToString(); ele.TryPathTo("Teaches", true, out subEle); subEle.Value = Teaches.ToString(); ele.TryPathTo("MaxTrainingLevel", true, out subEle); subEle.Value = MaxTrainingLevel.ToString(); ele.TryPathTo("Assistance", true, out subEle); subEle.Value = Assistance.ToString(); ele.TryPathTo("AggroRadiusBehavior", true, out subEle); subEle.Value = AggroRadiusBehavior.ToString(); ele.TryPathTo("AggroRadius", true, out subEle); subEle.Value = AggroRadius.ToString(); }
/// <summary> /// Pick the next target. /// </summary> private void PickTarget() { if (Body.IsIncapacitated) { return; } GameLiving target = Aggression.PrimaryTarget; if (target == null) { AttackBehaviour.Retreat(); Aggression.Clear(); Body.TargetObject = null; AttackBehaviour = PassiveBehaviour; Body.WalkToSpawn(); } else { if (AttackBehaviour is PassiveBehaviour) { AttackBehaviour = (Body.CanCastHarmfulSpells) ? CastingBehaviour : MeleeBehaviour; } else { if (AttackBehaviour is MeleeBehaviour) { if (Body.CanCastHarmfulSpells && Util.Chance(Properties.GAMENPC_CHANCES_TO_CAST)) { AttackBehaviour = CastingBehaviour; } } } AttackBehaviour.Attack(target); } }
public void TakeFood(Human taker) { if (Aggression.Get(_team, taker._team) == Aggression.Level.Friendly) { // Sharing is caring if (HasFood) { Food--; taker.Feed(1); } } else { // I have been killed Dead = true; SetAnimationState(AnimationState.Dying); taker.Feed(Food); Food = 0; // I shall be avenged Aggression.Adjust(_team, taker._team, 15); } }
/// <summary> /// Check if any past or future action is within bet or fold range depending on opponent's past actions /// </summary> public FeatureAction?GetCounterAction(List <FeatureAction> possibleActions, List <FeatureAction> lastActions, GamePhase phase, Aggression aggression, Positioning positioning) { var reversedActions = new List <FeatureAction>(lastActions.ToArray()); reversedActions.Reverse(); //is there any past action feature? var pastActionFeature = Features.FirstOrDefault(x => x.Phase == phase && x.IsGlobal == false && (x.PreCondition == null || ((x.PreCondition.Aggression == Aggression.None || x.PreCondition.Aggression == aggression) && (x.PreCondition.Positioning == Positioning.None || x.PreCondition.Positioning == positioning) && (x.PreCondition.LastActions.Count == 0 || reversedActions.Take(x.PreCondition.LastActions.Count).SequenceEqual <FeatureAction>(x.PreCondition.LastActions))))); if (pastActionFeature != null && pastActionFeature.CountTotal > MinCountThreshold) { if (pastActionFeature.IsInBetRange) { return(FeatureAction.Bet); } if (pastActionFeature.IsInPassRange) { return(FeatureAction.Pass); } } foreach (var possibleAction in possibleActions) { var actions = new List <FeatureAction>(lastActions.ToArray()); actions.Add(possibleAction); actions.Reverse(); var futureActionFeature = Features.FirstOrDefault(x => x.Phase == phase && x.IsGlobal == false && (x.PreCondition != null && ((x.PreCondition.Aggression == Aggression.None || x.PreCondition.Aggression == aggression) && (x.PreCondition.Positioning == Positioning.None || x.PreCondition.Positioning == positioning) && (x.PreCondition.LastActions.Count == 0 || actions.Take(x.PreCondition.LastActions.Count).SequenceEqual <FeatureAction>(x.PreCondition.LastActions))))); if (futureActionFeature != null && futureActionFeature.CountTotal > MinCountThreshold) { if (futureActionFeature.IsInBetRange) { return(FeatureAction.Bet); } if (futureActionFeature.IsInPassRange) { return(FeatureAction.Pass); } } } return(null); }
public SentientNpc(string name, int level, char gender, Race race, Caste caste, int team, Aggression aggression, int[] abilityScoreValues = null, MapPoint location = null) : base(name, level, gender, race, caste, team, abilityScoreValues, location) { Aggression = aggression; }
/// <summary> /// Updates the features which are relevant in the current state of the game. /// </summary> /// <param name="lastActions">Last actions of the current phase</param> /// <param name="phase">Phase of the game</param> /// <param name="aggression">Aggression of the player</param> /// <param name="positioning">Positioning of the player</param> public void UpdateFeaturesAfterAction(List <FeatureAction> lastActions, GamePhase phase, Aggression aggression, Positioning positioning) { //reverse action list to make it easier comparable var reversedActions = new List <FeatureAction>(lastActions.ToArray()); reversedActions.Reverse(); FeatureAction lastAction = reversedActions[0]; reversedActions = reversedActions.Skip(1).ToList(); var featuresToUpdate = Features.Where(x => x.AlreadyIncremented == false && x.Phase == phase && (x.PreCondition == null || ((x.PreCondition.Aggression == Aggression.None || x.PreCondition.Aggression == aggression) && (x.PreCondition.Positioning == Positioning.None || x.PreCondition.Positioning == positioning) && (x.PreCondition.LastActions.Count == 0 || reversedActions.Take(x.PreCondition.LastActions.Count).SequenceEqual <FeatureAction>(x.PreCondition.LastActions))))); foreach (var feature in featuresToUpdate) { if (feature.ActionsToMeasure.Contains(lastAction)) { feature.Count++; feature.AlreadyIncremented = true; } if (!feature.IsGlobal) { feature.CountTotal++; } } }
public override Task <GameActionEntity> GetAction(List <ActionType> possibleActions, int amountToCall) { var possibleFeatureActions = new List <FeatureAction>(); foreach (var possibleAction in possibleActions) { var featureAction = FeatureActionAbstracter.FromActionType(possibleAction); if (!possibleFeatureActions.Contains(featureAction)) { possibleFeatureActions.Add(featureAction); } } var currentPhasehistory = actionHistoriesPerPhase.FirstOrDefault(x => x.Phase == currentGame.Phase); Positioning opponentPositioning = Positioning.None; Aggression opponentAggression = Aggression.None; if (currentGame.Phase > GamePhase.PreFlop) { opponentPositioning = getOpponentPositioning(currentPhasehistory.ActionHistory.Count); opponentAggression = getOpponentAggression(opponentPositioning); } var counterAction = opponent.GetCounterAction(possibleFeatureActions, currentPhasehistory.ActionHistory, currentGame.Phase, opponentAggression, opponentPositioning); ActionBucket selectedActionBucket = ActionBucket.None; if (counterAction == null) { if (currentGame.Phase == GamePhase.PreFlop) { switch (opponent.PlayStyle) { case PlayStyle.LooseAggressive: case PlayStyle.LoosePassive: if (this.IsBigBlind) { selectedActionBucket = ActionBucket.LowBet; } else { if (startHandBucket >= StartHandBucket.VeryBad) { selectedActionBucket = ActionBucket.LowBet; } else { selectedActionBucket = ActionBucket.Pass; } } break; case PlayStyle.TightAggressive: case PlayStyle.TightPassive: //play hyper aggressive selectedActionBucket = ActionBucket.LowBet; break; } } else { switch (opponent.PlayStyle) { case PlayStyle.LooseAggressive: //play TightAggressive if (handStrengthBucket >= HandStrengthBucket.HighCardAce) { selectedActionBucket = ActionBucket.LowBet; } else { selectedActionBucket = ActionBucket.Pass; } break; case PlayStyle.LoosePassive: selectedActionBucket = ActionBucket.LowBet; break; case PlayStyle.TightAggressive: //play LooseAggressive if (handStrengthBucket >= HandStrengthBucket.LowPair) { selectedActionBucket = ActionBucket.LowBet; } else { selectedActionBucket = ActionBucket.Pass; } break; case PlayStyle.TightPassive: //play LooseAggressive if (handStrengthBucket >= HandStrengthBucket.HighCardElse) { selectedActionBucket = ActionBucket.LowBet; } else { selectedActionBucket = ActionBucket.Pass; } break; } } } else { if (currentGame.Phase == GamePhase.PreFlop) { switch (counterAction) { case FeatureAction.Bet: if (startHandBucket > StartHandBucket.Worst) { selectedActionBucket = ActionBucket.LowBet; } break; case FeatureAction.Pass: if (startHandBucket < StartHandBucket.Bad) { selectedActionBucket = ActionBucket.Pass; } break; } } else { switch (counterAction) { case FeatureAction.Bet: selectedActionBucket = ActionBucket.LowBet; break; case FeatureAction.Pass: if (handStrengthBucket < HandStrengthBucket.LowPair) { selectedActionBucket = ActionBucket.Pass; } break; } } } switch (selectedActionBucket) { case ActionBucket.None: //no counter move has been found. Fall back to randomness randomBot.ChipStack = this.ChipStack; return(randomBot.GetAction(possibleActions, amountToCall)); default: ActionType selectedAction = ActionAbstracter.MapToAction(selectedActionBucket, amountToCall); int betSize = 0; switch (selectedAction) { case ActionType.Bet: case ActionType.Raise: betSize = ActionAbstracter.GetBetSize(selectedActionBucket, amountToCall, currentGame.PotSize); break; case ActionType.Call: betSize = amountToCall; break; } if (!possibleActions.Contains(selectedAction)) { switch (selectedAction) { case ActionType.Bet: case ActionType.Raise: case ActionType.Check: if (possibleActions.Contains(ActionType.Call)) { selectedAction = ActionType.Call; } break; default: throw new Exception("Selected action is illegal!"); } } if (ChipStack < betSize) { betSize = this.ChipStack; } return(Task.FromResult <GameActionEntity>( new GameActionEntity { ActionType = selectedAction, Amount = betSize, PlayerId = this.Id })); } }
public void OnUnlinkPet() { m_Pet = null; m_Anchor = null; m_Aggression = Aggression.Following; InvalidateProperties(); }
/// <summary> /// Check whether or not this living is an enemy. /// </summary> /// <param name="living"></param> /// <returns></returns> protected bool IsEnemy(GameLiving living) { return((living == null) ? false : (Aggression.IsEnemy(living))); }
/// <summary> /// Process game events. /// </summary> /// <param name="e"></param> /// <param name="sender"></param> /// <param name="args"></param> public override void Notify(DOLEvent e, object sender, EventArgs args) { base.Notify(e, sender, args); // Process body only related events first. if (sender == Body) { if (e == GameNPCEvent.ArriveAtSpawnPoint) { Body.TurnTo(Body.SpawnHeading); return; } if (e == GameLivingEvent.Interrupted || e == GameLivingEvent.CastFailed || e == GameNPCEvent.CastFailed) { AttackBehaviour = MeleeBehaviour; PickTarget(); return; } if (e == GameLivingEvent.CastFinished || e == GameNPCEvent.CastFinished || e == GameLivingEvent.CrowdControlExpired || e == GameLivingEvent.InterruptExpired) { PickTarget(); return; } if (e == GameLivingEvent.CrowdControlled) { Body.TargetObject = null; return; } } if (e == GameLivingEvent.AttackedByEnemy) { if (args is AttackedByEnemyEventArgs) { AttackData attackData = (args as AttackedByEnemyEventArgs).AttackData; OnAttacked(attackData); } return; } if (e == GameLivingEvent.EnemyHealed) { if (args is EnemyHealedEventArgs) { EnemyHealedEventArgs healed = args as EnemyHealedEventArgs; if (IsEnemy(healed.Enemy)) { OnEnemyHealed(healed.HealSource, healed.HealAmount); } } return; } if (e == GameLivingEvent.EnemyKilled) { if (args is EnemyKilledEventArgs) { EnemyKilledEventArgs killed = args as EnemyKilledEventArgs; if (IsEnemy(killed.Target)) { OnEnemyKilled(killed.Target); } } return; } if (e == GameLivingEvent.LowHealth) { OnLowHealth(sender as GameLiving); return; } if (e == GameLivingEvent.Dying) { if (sender == Body) { Aggression.Clear(); } // Aredhel: Although GameLivingEvent.Dying clearly is a GameLiving // event, DyingEventArgs.Killer is a mere GameObject. It might make // sense to send this event for GameObjects if, for example, the // GameObjects belonged to this brain's body and could be re-summoned. if (args is DyingEventArgs) { OnDying(sender as GameObject, (args as DyingEventArgs).Killer); } return; } }
public override void Deserialize(GenericReader reader) { base.Deserialize(reader); int v = reader.ReadInt(); m_Owner = reader.ReadMobile(); m_Pet = reader.ReadMobile() as DespiseCreature; m_LeashLength = (LeashLength)reader.ReadInt(); m_Aggression = (Aggression)reader.ReadInt(); m_Alignment = (Alignment)reader.ReadInt(); m_Conscripted = reader.ReadBool(); switch (reader.ReadInt()) { case 0: break; case 1: m_Anchor = (IPoint3D)reader.ReadMobile(); break; case 2: m_Anchor = (IPoint3D)reader.ReadPoint3D(); break; } if (m_Anchor == null && m_Pet != null) m_Pet.Home = m_Pet.Location; m_Orbs.Add(this); }
public void ChangeAggression(Aggression aggression) { CombatManager.ChangeAggression(_creature, aggression); _aggression = aggression; }
public NonSentientNpc(string name, int level, char gender, int team, Aggression aggression, int[] abilityScoreValues = null, Die hitDie = null, MapPoint location = null) : base(name, level, gender, team, abilityScoreValues, hitDie, location) { Aggression = aggression; }
public override int GetHashCode() { return(Aggression.GetHashCode()); }
public override void _Process(float delta) { if (Dead) { return; } Thirst -= delta; Hunger -= delta; if (Thirst < MAX_THIRST / 2) { var waterSource = _targetResource as IWaterSource; if (waterSource == null || !waterSource.HasWater) { // Seek water var waterSources = new List <IWaterSource>(); Group.CallGroup(GetTree(), Group.WaterSources, source => { if (source.HasWater) { waterSources.Add(source); } }); TargetClosestResource(waterSources); waterSource = _targetResource as IWaterSource; } if (waterSource != null && waterSource.HasWater && Position.DistanceSquaredTo(_targetPosition) <= INTERACTION_RADIUS_SQUARED) { waterSource.TakeWater(this); _targetResource = null; } } else if (Hunger < MAX_HUNGER / 2) { if (Food > 0) { // If we have food, eat Eat(); } else { // Otherwise, seek food var foodSource = _targetResource as IFoodSource; if (foodSource == null || !foodSource.HasFood) { var foodSources = new List <IFoodSource>(); Group.CallGroup(GetTree(), Group.FoodSources, source => { if (!source.HasFood) { return; } var humanSource = source as Human; if (humanSource != null) { if (!ShouldTargetHuman <IFoodSource>(humanSource)) { return; } } foodSources.Add(source); }); TargetClosestResource(foodSources); foodSource = _targetResource as IFoodSource; } if (foodSource != null && foodSource.HasFood && Position.DistanceSquaredTo(_targetPosition) <= INTERACTION_RADIUS_SQUARED) { foodSource.TakeFood(this); _targetResource = null; } } } else { // Not thirsty and not hungry. Anyone we wanna murder nearby? var murderTarget = _targetResource as Human; if (murderTarget == null || murderTarget.Dead) { var peopleIWantToKill = new List <Human>(); Group.Humans.Call(GetTree(), human => { if (human.Dead || Position.DistanceSquaredTo(human.Position) > RAGE_RADIUS_SQUARED) { return; } var aggression = Aggression.Get(_team, human._team); if (aggression == Aggression.Level.Murderous) { peopleIWantToKill.Add(human); } }); TargetClosestResource(peopleIWantToKill); } murderTarget = _targetResource as Human; if (murderTarget != null && !murderTarget.Dead && Position.DistanceSquaredTo(murderTarget.Position) <= RAGE_RADIUS_SQUARED) { // Humans can move, so update the target position regularly _targetPosition = murderTarget.Position; if (Position.DistanceSquaredTo(_targetPosition) <= INTERACTION_RADIUS_SQUARED) { // This will kill them and take all their stuff. Nice! murderTarget.TakeFood(this); _targetResource = null; } } } if (_targetResource != null) { SetAnimationState(AnimationState.Walking); var velocity = (_targetPosition - Position).Normalized() * SPEED * delta; Position += velocity; } else { SetAnimationState(AnimationState.Standing); } if (Thirst <= 0 || Hunger <= 0) { Dead = true; SetAnimationState(AnimationState.Dying); } }