/// <summary> /// Applies the effect. Notify the StatusEffect to the event manager /// </summary> /// <param name="effects">Effects.</param> /// <param name="targetEntity">Target entity.</param> private void ApplyEffect(StatusEffectRule combatEffectRule, BattleEntity srcEntity) { // BattleEntity destEntity = combatEffectRule.rule; // IStatusEffectRunner statusEffect = combatEffectRule.effect; // first directly apply the effect, it will notify the event from the StatusEffectManager // destEntity.ApplyStatusEffect (statusEffect); }
public List<Position> InRangeTiles(BattleEntity self, Direction dir, BattleArena arena) { var result = new List<Position>(); for (int x = 0; x < arena.ArenaSize; x++) { for (int y = 0; y < arena.ArenaSize; y++) { Position target = new Position(x, y); if (dir == Direction.None) { if (InRange(arena, self, target)) { result.Add(target); } } else { if (InRange(arena, self, target, dir)) { result.Add(target); } } } } return result; }
/// <summary> /// Creates the allowed targets. /// </summary> /// <returns>The allowed targets.</returns> /// <param name="origin">Origin.</param> /// <param name="entityManager">Entity manager.</param>` /// <param name="skill">Skill.</param> public static SelectableTargetManager CreateAllowedTargets(BattleEntity origin, BattleEntityManagerComponent entityManager, ICombatSkill skill) { HashSet<BattleEntity> entitySet = new HashSet<BattleEntity>(entityManager.allEntities); List<SelectableTarget> targetList = new List<SelectableTarget>(); Dictionary<BattleEntity, SelectableTarget> targetMap = new Dictionary<BattleEntity, SelectableTarget>(); // filter FilterSkill(entitySet, skill); // populate targets if(origin.isPC) { PopulateSelectableTargets(targetList, (PCBattleEntity) origin, entitySet, skill); } else { PopulateSelectableTargets(targetList, (EnemyBattleEntity) origin, entitySet, skill); } // create map foreach(SelectableTarget target in targetList) { foreach(BattleEntity entity in target.entities) { targetMap[entity] = target; } } return new SelectableTargetManager(skill, targetList, targetMap); }
public void PostActionRequired(BattleEntity entity) { Debug.Log("entity decision required: " + entity); if (!mActionRequiredQueue.Contains(entity)) { mActionRequiredQueue.Enqueue(entity); } }
public HealEvent(BattleEntity srcEntity, BattleEntity destEntity, float heal, float critHeal) { this.mSrcEntity = srcEntity; this.mDestEntity = destEntity; this.mHeal = heal; this.mCritHeal = critHeal; }
public static CombatResolver CreateSource(BattleEntity entity, CombatRound round) { return entity.CreateCombatNodeBuilder() .SetSkillCombatNode(round) .SetWeaponIndex(round.weaponIndex) .BuildResolver(); }
public DamageEvent(BattleEntity srcEntity, BattleEntity destEntity, ElementVector damage, ElementVector critDamage, ElementVector defense) { this.mSrcEntity = srcEntity; this.mDestEntity = destEntity; this.mDamage = damage; this.mCritDamage = critDamage; this.mDefense = defense; }
/// <summary> /// Sets the entities that are used for turn based combat /// </summary> /// <param name="entities">Entities.</param> public void InitEntities(BattleEntity [] entities) { unitArray = new BattleEntity[entities.Length]; for(int i=0; i < entities.Length; i++) { entities[i].InitializeBattlePhase(); unitArray[i] = entities[i]; } }
public BattleAction(ICombatSkill skill, BattleEntity sourceEntity, ITargetResolver targetResolver) { this.combatSkill = skill; this.sourceEntity = sourceEntity; this.targetResolver = targetResolver; this.mCombatRoundIndex = 0; this.mCombatRoundCount = skill.CombatRounds.Length; }
public override bool IsValidTarget(BattleEntity entity) { if(isAlive) { return entity.currentHP > 0; } else { return entity.currentHP <= 0; } }
/// <summary> /// Determines whether this instance is valid target the specified entity. /// </summary> /// <returns><c>true</c> if this instance is valid target the specified entity; otherwise, <c>false</c>.</returns> /// <param name="entity">Entity.</param> public bool IsValidTarget(BattleEntity entity) { foreach(TargetConditionSO condition in conditions) { if(!condition.IsValidTarget(entity)) { return false; } } return true; }
public override void ApplyCost(BattleEntity self, Position target) { int cost = Position.Distance(self.CurrentPos, target) * Value; self.MP -= cost; if (self.MP < 0) { self.AP += self.MP; self.MP = 0; } }
/// <summary> /// Initializes a new instance of the <see cref="StatusEffectEvent"/> class. /// </summary> /// <param name="srcEntity">Source entity.</param> /// <param name="statusEffectProperty">Status effect property.</param> /// <param name="statusEventType">Status event type.</param> /// <param name="statusType">Status type.</param> public StatusEffectEvent(BattleEntity srcEntity, StatusEffectProperty statusEffectProperty, StatusEventType statusEventType, StatusEffectType statusType) { this.SrcEntity = srcEntity; this.statusEffectProperty = statusEffectProperty; this.statusEventType = statusEventType; this.statusType = statusType; }
public override bool InRange(BattleArena arena, BattleEntity self, Position target, Direction dir) { var origin = self.CurrentPos; var dist = Math.Abs(origin.X - target.X) + Math.Abs(origin.Y - target.Y); if (dist <= Dist && dist != 0) { return true; } return false; }
public override bool InRange(BattleArena arena, BattleEntity self, Position target) { foreach (Direction dir in Enum.GetValues(typeof(Direction))) { if (InRange(arena, self, target, dir)) { return true; } } return false; }
protected override void OnActionRequired(BattleEntity entity) { if (entity is PCBattleEntity) { mTurnManager.QueuePC((PCBattleEntity)entity); } else if(entity is EnemyBattleEntity) { EnemyBattleEntity npc = (EnemyBattleEntity)entity; IBattleAction enemyAction = npc.enemyCharacter.skillResolver.ResolveAction(mEntityManager, npc); mBattleTimeQueue.SetAction(entity, enemyAction); } }
// filter out by if targets are within range public void FilterEntities(BattleEntity sourceEntity, HashSet<BattleEntity> entities) { // first row filter PCCharacter.RowPosition rowPosition = PCCharacter.RowPosition.FRONT; switch(mRowCondition) { case AISkillRule.RowCondition.BACK_COUNT_GT: case AISkillRule.RowCondition.BACK_COUNT_LT: rowPosition = PCCharacter.RowPosition.BACK; break; case AISkillRule.RowCondition.FRONT_COUNT_GT: case AISkillRule.RowCondition.FRONT_COUNT_LT: rowPosition = PCCharacter.RowPosition.FRONT; break; case AISkillRule.RowCondition.MIDDLE_COUNT_GT: case AISkillRule.RowCondition.MIDDLE_COUNT_LT: rowPosition = PCCharacter.RowPosition.MIDDLE; break; } // then remove all entries are not that row entities.RemoveWhere(delegate(BattleEntity obj) { if(obj is PCBattleEntity && ((PCBattleEntity)obj).pcCharacter.rowPosition == rowPosition) { return false; } return true; }); // finally see if it meets the condition, if it does, leave them, if it doesnt, remove all switch(mRowCondition) { case AISkillRule.RowCondition.BACK_COUNT_GT: case AISkillRule.RowCondition.FRONT_COUNT_GT: case AISkillRule.RowCondition.MIDDLE_COUNT_GT: if(entities.Count > mFilterCount) { // ok } else { entities.Clear(); } break; case AISkillRule.RowCondition.BACK_COUNT_LT: case AISkillRule.RowCondition.FRONT_COUNT_LT: case AISkillRule.RowCondition.MIDDLE_COUNT_LT: if(entities.Count < mFilterCount) { // ok } else { entities.Clear(); } break; } }
public void FilterEntities(BattleEntity sourceEntity, HashSet<BattleEntity> entities) { // leftover targets should already be in the party, we should just count and filter out the rest if its needed switch(mPartyCondition) { case AISkillRule.PartyCondition.PARTY_COUNT_GT: if(entities.Count <= mPartyCount) { entities.Clear(); } break; case AISkillRule.PartyCondition.PARTY_COUNT_LT: if(entities.Count >= mPartyCount) { entities.Clear(); } break; } }
public void FilterEntities(BattleEntity sourceEntity, HashSet<BattleEntity> entities) { switch(mTargetParam) { case AISkillRule.ConditionTarget.ENEMY: entities.RemoveWhere(FilterEnemy); break; case AISkillRule.ConditionTarget.PC: entities.RemoveWhere(FilterPC); break; case AISkillRule.ConditionTarget.SELF: entities.RemoveWhere(delegate(BattleEntity obj) { return sourceEntity != obj; }); break; } }
public override bool InRange(BattleArena arena, BattleEntity self, Position target, Direction dir) { var origin = self.CurrentPos; switch (dir) { case Direction.Up: return target.X == origin.X && target.Y > origin.Y && target.Y - Dist <= origin.Y; case Direction.Right: return target.Y == origin.Y && target.X > origin.X && target.X - Dist <= origin.X; case Direction.Down: return target.X == origin.X && target.Y < origin.Y && target.Y + Dist >= origin.Y; case Direction.Left: return target.Y == origin.Y && target.X < origin.X && target.X + Dist >= origin.X; default: return false; } }
private void Update() { //TODO dont constantly raycast GameObject raycastObject = MouseRaycast(playerMovementRange); //TODO change this if (CurrentTurn == Turn.Player) { if (raycastObject != null) { if (!friendlies[0].IsMoving && !Attacking) { List <Node> path = Pathfinding.FindPath(friendlies[0].nodeParent, GetTargetNode(raycastObject.GetComponent <Tile>()), reverse: true); if (canDisplayPathTiles) { Pathfinding.SelectNodes(playerMovementRange, movementRangeColour); Pathfinding.SelectNodes(path, pathColour); } } else if (Attacking) { if (Input.GetMouseButtonDown(0)) { BattleEntity entity = raycastObject.GetComponent <BattleEntity>(); //print("Attacking: " + entity.name); Attack.AttackTarget(lastSelectedAttack, entity); //End turn once attacked canMove = true; OnPlayerInfoChangedEvent(canMove: canMove.ToString()); OnEndTurn(); } } //Else if repairing do similar stuff as the above if else if (true) { } } } //TODO do not do this else if (CurrentTurn == Turn.Enemy && !eventCalled) { eventCalled = true; OnEnemyTurnEvent(friendlies); } }
public bool AddEntity(BattleEntity entity) { if (entity == null) { return(false); } if (GetEntity(entity.id) != null) { return(false); } entities.Add(entity.id, entity); entity.Init(); return(true); }
public bool IsInAllysOuterIntimidationRing(BattleEntity entity) { foreach (KeyValuePair <BattleEntity, BattleEntityConnection> bec in bEntityConnection) { if (bec.Value.inEntitiesIntimidationRangeOuter) { if (bec.Key.entityType == EntityType.Player && entity.entityType == EntityType.Player) { return(true); } if (bec.Key.entityType == EntityType.Enemy && entity.entityType == EntityType.Enemy) { return(true); } } } return(false); }
private void OnEntityDeath(BattleEntity entity) { BattleEnemy enemy = entity as BattleEnemy; if (enemy != null) { enemies.Remove(enemy); } else { friendlies.Remove(entity); } Destroy(entity.gameObject); BattleStatus status = CheckBattleStatus(); ProcessBattleStatus(status); }
public bool IsInEnemysOuterIntimidationRing(BattleEntity entity) { foreach (KeyValuePair <BattleEntity, BattleEntityConnection> bec in bEntityConnection) { if (bec.Value.inEntitiesIntimidationRangeOuter) { if (bec.Key.entityType == EntityType.Player && entity.entityType == EntityType.Enemy) { return(true); } if (bec.Key.entityType == EntityType.Enemy && entity.entityType == EntityType.Player) { return(true); } } } return(false); /* * bool flag = true; * if(inEntitiesIntimidationRange.Count == 0) { * return false; * } * foreach(BattleEntity be in inEntitiesIntimidationRange) { * * if(entity == EntityType.Enemy && be.entityType == EntityType.Player) { * * if(Tile.Distance(be.tile, this) == be.entity.stats.intimidationRange) * flag &= true; * else * flag &= false; * } * else if(entity == EntityType.Player && be.entityType == EntityType.Enemy) { * * if(Tile.Distance(be.tile, this) == be.entity.stats.intimidationRange) * flag &= true; * else * flag &= false; * } * else * flag &= false; * } * return flag;*/ }
public static ICombatOperation createOperation(BattleEntity src, BattleEntity dest, CombatRound combatRound) { CombatResolver srcRes = CombatResolverFactory.CreateSource(src, combatRound); CombatResolver destRes = CombatResolverFactory.CreateDestination(dest); HitChanceLogic hitChanceLogic = new HitChanceLogic (); DamageLogic damageLogic = new DamageLogic (); CombatOperation.Builder builder = new CombatOperation.Builder (); builder.AddLogic(damageLogic) .Require(delegate(ICombatLogic [] conditions) { HitChanceLogic hitChance = (HitChanceLogic) conditions[0]; return hitChance.Hits; }, hitChanceLogic); AddHitChanceStatusEffectRules(builder, hitChanceLogic, combatRound); return builder.Build(srcRes, destRes); }
protected void addAction(BattleEntity caster, Skill skill, BattleEntity target) { Action action = new Action(caster, skill, target); this.selectedActions.Add(action); // Si la cantidad de acciones es igual a la cantidad de la player party vivos, entonces el jugador ya terminó de elegir acciones // Ahora hay que hacer que los enemigos elijan las suyas if (this.selectedActions.Count == this.playerParty.Where(x => x.getState() != BattleEntity.DEAD).ToList().Count) { foreach (var enemy in this.enemyParty.Where(x => x.getState() != BattleEntity.DEAD).ToList()) { this.selectedActions.Add(enemy.decideAction(this.playerParty, this.enemyParty)); } this.setState(BattleState.PERFORMING_ACTIONS); } this.hideEnemyButtons(); this.hideSkillButtons(); }
public override void apply(BattleEntity self, BattleEntity target, Direction dir, BattleArena arena) { var lvl = self.Level; var atk = self.Atk; //gérer spe var def = target.Def; //gérer spe double damage = 2; damage *= (2d * lvl + 10d) / 250d; damage *= atk / def; damage *= Value; damage *= 0.85 + rnd.NextDouble() * 15 / 100; //random //gérer stab, crit, type, etc int damageInt = (int)Math.Floor(damage); target.HP -= damageInt; if (target.HP < 0) { target.HP = 0; } }
public void RefreshParty() { _partyCount = 0; for (int i = 0; i < Enum.GetValues(typeof(Character)).Length - 1; i++) { BattleEntityData readEntity; var success = BattleEntity.ReadEntity(EntityType.Party, i, out readEntity); _partyEntities[i] = readEntity; if (readEntity.pointer_1 == 0 || !success) { (TabEntity.Items[i] as TabItem).Visibility = Visibility.Collapsed; continue; } var entityTab = TabEntity.Items[i] as TabItem; entityTab.Visibility = Visibility.Visible; entityTab.Header = ((Character)i).ToString(); _partyCount++; } }
public void FilterEntities(BattleEntity sourceEntity, HashSet<BattleEntity> entities) { switch(mHpCondition) { case AISkillRule.ResourceCondition.RES_EMPTY: entities.RemoveWhere(delegate(BattleEntity obj) { return obj.character.curResource > 0; }); break; case AISkillRule.ResourceCondition.RES_GT: entities.RemoveWhere(delegate(BattleEntity obj) { return obj.character.curResource / obj.character.maxResource <= mHpPercValue; }); break; case AISkillRule.ResourceCondition.RES_LT: entities.RemoveWhere(delegate(BattleEntity obj) { return obj.character.curResource / obj.character.maxResource >= mHpPercValue; }); break; // highest, just find the max case AISkillRule.ResourceCondition.RES_HIGHEST: float maxResource = -1; foreach(BattleEntity entity in entities) { maxResource = Mathf.Max(maxResource, entity.character.curResource); } entities.RemoveWhere(delegate(BattleEntity obj) { return obj.character.curResource != maxResource; }); break; case AISkillRule.ResourceCondition.RES_LOWEST: float minResource = 9999999; foreach(BattleEntity entity in entities) { // we want to make sure we dont count dead people minResource = Mathf.Min(minResource, entity.character.curResource); } entities.RemoveWhere(delegate(BattleEntity obj) { return obj.character.curResource != minResource; }); break; } }
public void FilterEntities(BattleEntity sourceEntity, HashSet<BattleEntity> entities) { switch(mHpCondition) { case AISkillRule.HitPointCondition.HP_DEAD: entities.RemoveWhere(delegate(BattleEntity obj) { return obj.character.curHP > 0; }); break; case AISkillRule.HitPointCondition.HP_GT: entities.RemoveWhere(delegate(BattleEntity obj) { return obj.character.curHP / obj.character.maxHP <= mHpPercValue; }); break; case AISkillRule.HitPointCondition.HP_LT: entities.RemoveWhere(delegate(BattleEntity obj) { return obj.character.curHP / obj.character.maxHP >= mHpPercValue; }); break; // highest, just find the max case AISkillRule.HitPointCondition.HP_HIGHEST: float maxHP = -1; foreach(BattleEntity entity in entities) { maxHP = Mathf.Max(maxHP, entity.character.curHP); } entities.RemoveWhere(delegate(BattleEntity obj) { return obj.character.curHP != maxHP; }); break; case AISkillRule.HitPointCondition.HP_LOWEST: float minHP = 9999999; foreach(BattleEntity entity in entities) { // we want to make sure we dont count dead people minHP = Mathf.Max(1, Mathf.Min(minHP, entity.character.curHP)); } entities.RemoveWhere(delegate(BattleEntity obj) { return obj.character.curHP != minHP; }); break; } }
public override void OnStateExcute(float deltaTime) { base.OnStateExcute(deltaTime); if (action.type == ActionType.Attack) { if (mTargetEntity == null || mTargetEntity.id != action.target) { mTargetEntity = BattleManager.Instance.GetEntity(action.target); } if (mTargetEntity != null) { var direction = mTargetEntity.position - agent.position; agent.rotation = Quaternion.Lerp(agent.rotation, Quaternion.LookRotation(direction), deltaTime * 10); } } else if (action.type == ActionType.Run) { if (action.paths.Count > 0) { var point = action.paths.First.Value; if (point.arrive == false) { Vector3 direction = point.destination - agent.position; if (direction != Vector3.zero) { agent.rotation = Quaternion.LookRotation(direction); } } else { if (point.velocity != Vector3.zero) { agent.rotation = Quaternion.LookRotation(point.velocity); } } } } }
/// <summary> /// Handles the add status. /// </summary> /// <param name="effect">Effect.</param> /// <param name="printLog">If set to <c>true</c> print log.</param> public void HandleAddStatus(BattleEntity sourceEntity, IStatusEffect effect) { StatusEffectNode node = GetNode (effect); bool wasEmpty = node.isEmpty; node.ApplyEffect(sourceEntity, effect); CheckCleanup(node); // check to see if we should fire an event if(wasEmpty && !node.isEmpty) { BattleSystem.Instance.PostBattleEvent(new StatusEffectEvent( mBattleEntity, effect.property, StatusEffectEvent.StatusEventType.NEW, effect.type)); } else if(!wasEmpty && node.isEmpty) { BattleSystem.Instance.PostBattleEvent(new StatusEffectEvent( mBattleEntity, effect.property, StatusEffectEvent.StatusEventType.REMOVED, effect.type)); } }
public void RefreshEnemies() { _enemyCount = 0; for (int i = 0; i < 8; i++) { BattleEntityData readEntity; var success = BattleEntity.ReadEntity(EntityType.Enemy, i, out readEntity); _enemyEntities[i] = readEntity; if (readEntity.guid == 0 || !success) { (TabEntity.Items[i] as TabItem).Visibility = Visibility.Collapsed; continue; } var entityTab = TabEntity.Items[i] as TabItem; entityTab.Visibility = Visibility.Visible; entityTab.Header = StringConverter.ToString(readEntity.text_name); _enemyCount++; } }
private void CheckPositiveFlag_OnChecked(object sender, RoutedEventArgs e) { if (!_canWriteData) { return; } var name = (sender as CheckBox).Name; var index = int.Parse(name.Substring(17)) - 1; var byteIndex = index / 8; var bitIndex = index % 8; BattleEntityData readEntity; BattleEntity.ReadEntity((EntityType)TabBattle.SelectedIndex, TabEntity.SelectedIndex, out readEntity); var positiveFlags = readEntity.status_flags_positive; positiveFlags[byteIndex] = BitHelper.ToggleBit(positiveFlags[byteIndex], bitIndex); BattleEntity.WriteBytes((EntityType)TabBattle.SelectedIndex, TabEntity.SelectedIndex, "status_flags_positive", positiveFlags); }
void UpdateEntityInfoWindow(BattleEntity entity) { const float barLength = 80f; entityInfoWindow.transform.Find("Upper Half").Find("Name").GetChild(0).GetComponent <Text>().text = entity.name; entityInfoWindow.transform.Find("Upper Half").Find("HP MANA").Find("HP MANA VALUE").Find("HP").Find("Text").GetChild(0).GetComponent <Text>().text = entity.entity.stats.health + "/" + entity.entity.stats.maxHealth; entityInfoWindow.transform.Find("Upper Half").Find("HP MANA").Find("HP MANA VALUE").Find("MP").Find("Text").GetChild(0).GetComponent <Text>().text = entity.entity.stats.mana + "/" + entity.entity.stats.maxMana; float bar = barLength; if (entity.entity.stats.maxHealth != 0) { bar = (entity.entity.stats.health / (float)entity.entity.stats.maxHealth) * barLength; } entityInfoWindow.transform.Find("Upper Half").Find("HP MANA").Find("HP MANA VALUE").Find("HP").Find("Bar").Find("Green Bar").GetComponent <RectTransform>().offsetMax = new Vector2(bar, 0f); if (entity.entity.stats.maxMana != 0) { bar = (entity.entity.stats.mana / (float)entity.entity.stats.maxMana) * barLength; } entityInfoWindow.transform.Find("Upper Half").Find("HP MANA").Find("HP MANA VALUE").Find("MP").Find("Bar").Find("Blue Bar").GetComponent <RectTransform>().offsetMax = new Vector2(bar, 0f); entityInfoWindow.transform.Find("Bottom Half").Find("Stats Value").GetChild(0).GetChild(0).GetComponent <Text>().text = entity.entity.stats.attack + "\n" + entity.entity.stats.defence + "\n" + entity.entity.stats.agility + "\n" + entity.entity.stats.speed + "\n" + entity.entity.stats.attackPower; }
public void TargetHit(NpcMonsterSkill npcMonsterSkill) { if (Monster == null || (!((DateTime.Now - LastSkill).TotalMilliseconds >= 1000 + Monster.BasicCooldown * 250) && npcMonsterSkill == null) || HasBuff(CardType.SpecialAttack, (byte)AdditionalTypes.SpecialAttack.NoAttack)) { return; } LastSkill = DateTime.Now; if (npcMonsterSkill != null) { if (CurrentMp < npcMonsterSkill.Skill.MpCost) { FollowTarget(); return; } npcMonsterSkill.LastSkillUse = DateTime.Now; CurrentMp -= npcMonsterSkill.Skill.MpCost; MapInstance.Broadcast($"ct 3 {MapMonsterId} {(byte)Target.SessionType()} {Target.GetId()} {npcMonsterSkill.Skill.CastAnimation} {npcMonsterSkill.Skill.CastEffect} {npcMonsterSkill.Skill.SkillVNum}"); } LastMove = DateTime.Now; BattleEntity.TargetHit(Target, TargetHitType.SingleTargetHit, npcMonsterSkill?.Skill, skillEffect: Monster.BasicSkill); }
public async Task <CreateBattleResult> CreateBattleAsync(CreateBattleCommand command) { if (String.IsNullOrWhiteSpace(command.Name)) { return(new CreateBattleResult(new Error("Empty name", "Name can't be empty"))); } var battle = new BattleEntity() { Description = command.Description, Name = command.Name, Settings = new BattleSettingsEntity { CenterX = 0, CenterY = 0, Cooldown = 0, ChunkHeight = 100, ChunkWidth = 100, MaxHeightIndex = 99, MaxWidthIndex = 99, MinHeightIndex = -100, MinWidthIndex = -100 }, StartDateUTC = DateTime.UtcNow, EndDateUTC = DateTime.UtcNow.AddDays(100) }; var result = await BattleStore.CreateBattleAsync(battle, CancellationToken); if (result.Succeeded) { return(new CreateBattleResult(battle.BattleId)); } else { return(new CreateBattleResult(result.Errors)); } }
public void ChangeCombatants(SpellswordGame game, Character player, Character enemy) { if (player is Player) { this.player = new BattlePlayer(game, this, (Player)player); } this.enemy = new BattleEnemy(game, this, enemy); if (this.player is BattlePlayer) { ((BattlePlayer)this.player).FinishedTurn += OnPlayerFinishedTurn; } if (this.player.ThisEntity != null) { this.player.ThisEntity.Died += HandleDeath; } if (this.enemy.ThisEntity != null) { this.enemy.ThisEntity.Died += HandleDeath; } }
public override void Initialize() { FirstX = MapX; FirstY = MapY; Life = null; LastSkill = LastMove = LastEffect = DateTime.Now; Target = null; Path = new List <Node>(); IsAlive = true; ShouldRespawn = ShouldRespawn ?? true; Monster = ServerManager.Instance.GetNpc(MonsterVNum); IsHostile = Monster.IsHostile; CurrentHp = Monster.MaxHP; CurrentMp = Monster.MaxMP; Monster.Skills.ForEach(s => Skills.Add(s)); BattleEntity = new BattleEntity(this); DamageList = new ConcurrentDictionary <IBattleEntity, long>(); _random = new Random(MapMonsterId); _movetime = ServerManager.Instance.RandomNumber(400, 3200); IsPercentage = Monster.IsPercent; TakesDamage = Monster.TakeDamages; GiveDamagePercent = Monster.GiveDamagePercentage; Faction = MonsterVNum == 679 ? FactionType.Angel : MonsterVNum == 680 ? FactionType.Demon : FactionType.Neutral; }
public void DisplayRangeWithTargetableEntities(BattleEntity bEntity, RangeType rangeType, Relationship relationship) { ResetGridColor(); List <Tile> range = new List <Tile>(); Dictionary <Tile, TileColorType> color = new Dictionary <Tile, TileColorType>(); switch (rangeType) { case RangeType.Melee: range = bEntity.tilesInMeleeRange; break; case RangeType.Intimidation: range = bEntity.tilesInIntimidationRange; break; case RangeType.Movement: range = bEntity.tilesInMovementRange; break; case RangeType.Any: range.AddRange(bEntity.tilesInMovementRange); range.AddRange(bEntity.tilesInMeleeRange); range.AddRange(bEntity.tilesInIntimidationRange); range = range.Distinct().ToList(); break; } foreach (Tile t in range) { if (t.entityOnTile.CompareEntityRelationShip(bEntity, relationship)) { } } }
public static BQEOut_FinalDamageApplied Alloc(BattleEntity p_target, int p_finalDamageApplied) { return(new BQEOut_FinalDamageApplied { Target = p_target, FinalDamage = p_finalDamageApplied }); }
internal static void AttackCharacter(this ClientSession session, Mate attacker, NpcMonsterSkill skill, Character target) { if (attacker == null || target == null) { return; } if (target.Hp > 0 && attacker.Hp > 0) { if ((session.CurrentMapInstance.MapInstanceId == ServerManager.Instance.ArenaInstance.MapInstanceId || session.CurrentMapInstance.MapInstanceId == ServerManager.Instance.FamilyArenaInstance.MapInstanceId) && (session.CurrentMapInstance.Map.JaggedGrid[session.Character.PositionX][ session.Character.PositionY]?.Value != 0 || target.Session.CurrentMapInstance.Map.JaggedGrid[target.PositionX][ target.PositionY] ?.Value != 0)) { // User in SafeZone session.SendPacket(StaticPacketHelper.Cancel(2, target.CharacterId)); return; } if (target.IsSitting) { target.Rest(); } short castAnimation = -1; short castEffect = -1; short skillVnum = 0; short cooldown = 0; byte type = 0; if (skill != null) { castAnimation = skill.Skill.CastAnimation; castEffect = skill.Skill.CastEffect; skillVnum = skill.SkillVNum; cooldown = skill.Skill.Cooldown; type = skill.Skill.Type; } var hitmode = 0; var onyxWings = false; BattleEntity battleEntity = new BattleEntity(attacker); BattleEntity battleEntityDefense = new BattleEntity(target); session.CurrentMapInstance?.Broadcast(StaticPacketHelper.CastOnTarget(UserType.Npc, attacker.MateTransportId, 3, target.CharacterId, castAnimation, castEffect, skillVnum)); session.CurrentMapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Npc, attacker.MateTransportId, 3, target.CharacterId, skillVnum, cooldown, castAnimation, castEffect, target.MapX, target.MapY, target.Hp > 0, (int)(target.Hp / (double)target.HPMax * 100), 0, 0, type)); var damage = DamageHelper.Instance.CalculateDamage(battleEntity, battleEntityDefense, skill?.Skill, ref hitmode, ref onyxWings); if (target.HasGodMode) { damage = 0; hitmode = 1; } else if (target.LastPvpRevive > DateTime.Now.AddSeconds(-10) || session.Character.LastPvpRevive > DateTime.Now.AddSeconds(-10)) { damage = 0; hitmode = 1; } int[] manaShield = target.GetBuff(BCardType.CardType.LightAndShadow, (byte)AdditionalTypes.LightAndShadow.InflictDamageToMP); if (manaShield[0] != 0 && hitmode != 1) { var reduce = damage / 100 * manaShield[0]; if (target.Mp < reduce) { target.Mp = 0; } else { target.Mp -= reduce; } } target.GetDamage(damage / 2); target.LastDefence = DateTime.Now; target.Session.SendPacket(target.GenerateStat()); var isAlive = target.Hp > 0; if (!isAlive && target.Session.HasCurrentMapInstance) { if (target.Session.CurrentMapInstance.Map?.MapTypes.Any( s => s.MapTypeId == (short)MapTypeEnum.Act4) == true) { if (ServerManager.Instance.ChannelId == 51 && ServerManager.Instance.Act4DemonStat.Mode == 0 && ServerManager.Instance.Act4AngelStat.Mode == 0) { switch (session.Character.Faction) { case FactionType.Angel: ServerManager.Instance.Act4AngelStat.Percentage += 100; break; case FactionType.Demon: ServerManager.Instance.Act4DemonStat.Percentage += 100; break; } } session.Character.Act4Kill++; target.Act4Dead++; target.GetAct4Points(-1); if (target.Level + 10 >= session.Character.Level && session.Character.Level <= target.Level - 10) { session.Character.GetAct4Points(2); } if (target.Reputation < 50000) { target.Session.SendPacket(session.Character.GenerateSay( string.Format(Language.Instance.GetMessageFromKey("LOSE_REP"), 0), 11)); } else { target.Reputation -= target.Level * 50; session.Character.Reputation += target.Level * 50; session.SendPacket(session.Character.GenerateLev()); target.Session.SendPacket(target.GenerateSay( string.Format(Language.Instance.GetMessageFromKey("LOSE_REP"), (short)(target.Level * 50)), 11)); } foreach (ClientSession sess in ServerManager.Instance.Sessions.Where( s => s.HasSelectedCharacter)) { if (sess.Character.Faction == session.Character.Faction) { sess.SendPacket(sess.Character.GenerateSay( string.Format( Language.Instance.GetMessageFromKey( $"ACT4_PVP_KILL{(int)target.Faction}"), session.Character.Name), 12)); } else if (sess.Character.Faction == target.Faction) { sess.SendPacket(sess.Character.GenerateSay( string.Format( Language.Instance.GetMessageFromKey( $"ACT4_PVP_DEATH{(int)target.Faction}"), target.Name), 11)); } } target.Session.SendPacket(target.GenerateFd()); target.DisableBuffs(BuffType.All, force: true); target.Session.CurrentMapInstance.Broadcast(target.Session, target.GenerateIn(), ReceiverType.AllExceptMe); target.Session.CurrentMapInstance.Broadcast(target.Session, target.GenerateGidx(), ReceiverType.AllExceptMe); target.Session.SendPacket( target.GenerateSay(Language.Instance.GetMessageFromKey("ACT4_PVP_DIE"), 11)); target.Session.SendPacket( UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("ACT4_PVP_DIE"), 0)); Observable.Timer(TimeSpan.FromMilliseconds(2000)).Subscribe(o => { target.Session.CurrentMapInstance?.Broadcast(target.Session, $"c_mode 1 {target.CharacterId} 1564 0 0 0"); target.Session.CurrentMapInstance?.Broadcast(target.GenerateRevive()); }); Observable.Timer(TimeSpan.FromMilliseconds(30000)).Subscribe(o => { target.Hp = (int)target.HPLoad(); target.Mp = (int)target.MPLoad(); var x = (short)(39 + ServerManager.RandomNumber <short>(-2, 3)); var y = (short)(42 + ServerManager.RandomNumber <short>(-2, 3)); switch (target.Faction) { case FactionType.Angel: ServerManager.Instance.ChangeMap(target.CharacterId, 130, x, y); break; case FactionType.Demon: ServerManager.Instance.ChangeMap(target.CharacterId, 131, x, y); break; default: { target.MapId = 145; target.MapX = 51; target.MapY = 41; var connection = CommunicationServiceClient.Instance.RetrieveOriginWorld(session.Account.AccountId); if (string.IsNullOrWhiteSpace(connection)) { return; } var port = Convert.ToInt32(connection.Split(':')[1]); session.Character.ChangeChannel(connection.Split(':')[0], port, 3); return; } } target.Session.CurrentMapInstance?.Broadcast(target.Session, target.GenerateTp()); target.Session.CurrentMapInstance?.Broadcast(target.GenerateRevive()); target.Session.SendPacket(target.GenerateStat()); }); } } if (hitmode != 1) { skill?.Skill?.BCards.Where(s => s.Type.Equals((byte)BCardType.CardType.Buff)).ToList() .ForEach(s => s.ApplyBCards(target, session.Character)); } session.CurrentMapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Npc, attacker.MateTransportId, 1, target.CharacterId, 0, 12, 11, 200, 0, 0, isAlive, (int)(target.Hp / target.HPLoad() * 100), damage, hitmode, 0)); } else { // monster already has been killed, send cancel session.SendPacket(StaticPacketHelper.Cancel(2, target.CharacterId)); } }
public DeathEvent(BattleEntity entity) { mSrcEntity = entity; }
public static bool Exit_Path(BattleManager __instance) { // 如果MOD状态是关闭的话 if (!FormationMod.enable) { // 执行原本的方法 return(true); } // 退出战斗时还原是否组成阵型的状态 ModifierUtil.resetEnableStatus(); __instance.DieEntityList.Clear(); __instance.BrokenEquipmentMap.Clear(); Dictionary <int, List <int> > mTeamEntities = Traverse.Create(__instance).Field("mTeamEntities").GetValue <Dictionary <int, List <int> > >(); for (int i = 0; i < 2; i++) { mTeamEntities[i].Clear(); } Dictionary <int, BattleEntityView> mEntityViewMap = Traverse.Create(__instance).Field("mEntityViewMap").GetValue <Dictionary <int, BattleEntityView> >(); foreach (KeyValuePair <int, BattleEntityView> keyValuePair in mEntityViewMap) { BattleEntityView value = keyValuePair.Value; Singleton <ResourcesManager> .Instance.ReleaseInstance(value.mContainer.transform.gameObject); } mEntityViewMap.Clear(); __instance.Hide(); SingletonMonoBehaviour <UIManager> .Instance.CloseUnique(PanelEnum.Battle); SingletonMonoBehaviour <AudioManager> .Instance.StopAllMusic(); SingletonMonoBehaviour <AudioManager> .Instance.PlayGameBGM(); SingletonMonoBehaviour <UIManager> .Instance.ShowAll(); TimeModel instance = SingletonMonoBehaviour <TimeModel> .Instance; int timeStop = instance.TimeStop; instance.TimeStop = timeStop - 1; GameTempValue.GameSpeedHotKeyLock--; GameTempValue.MapMoveHotKeyLock--; GameTempValue.SamllMapKeyLock--; GameTempValue.TapKeyLock--; GameTempValue.BackpackKeyLock--; bool flag = false; Dictionary <int, BattleEntity> mEntities = Traverse.Create(__instance).Field("mEntities").GetValue <Dictionary <int, BattleEntity> >(); foreach (KeyValuePair <int, BattleEntity> keyValuePair2 in mEntities) { BattleEntity value2 = keyValuePair2.Value; bool flag2 = value2.mChr.GetCurrentValue(CharacterPropertyType.HP) == 0; if (flag2) { value2.mChr.SetStatRawValue(CharacterPropertyType.HP, 1); } bool flag3 = !value2.mChr.IsPlayer(); if (flag3) { bool flag4 = value2.DroppedWeapon != null; if (flag4) { value2.mChr.EquipItem(value2.DroppedWeapon); } value2.mChr.RemoveAllMartialModifier(); } else { bool flag5 = value2.TakenDamageMap.Count > 0; if (flag5) { flag = true; } } bool flag6 = value2.Team != 0 || value2.mChr.IsPlayer(); if (flag6) { value2.AddInjury(); } __instance.RecycleEntity(value2); } mEntities.Clear(); bool flag7 = flag; if (flag7) { SingletonMonoBehaviour <GuideModel> .Instance.TryGuide(0); } switch (__instance.BattleType) { case BattleType.Kill: case BattleType.Compete: SingletonMonoBehaviour <MapModel> .Instance.BattleEnd(__instance.BattleType, __instance.Result); break; case BattleType.Invade: SingletonMonoBehaviour <SchoolModel> .Instance.BattleEnd(__instance.BattleType, __instance.Result); break; case BattleType.LunWu: SingletonMonoBehaviour <MartialCompeteModel> .Instance.BattleEnd(__instance.BattleType, __instance.Result); break; } // 获取背景 Traverse mBackground = Traverse.Create(__instance).Field("mBackground"); TransformContainer mBackgroundValue = mBackground.GetValue <TransformContainer>(); // 释放资源 Singleton <ResourcesManager> .Instance.ReleaseInstance(mBackgroundValue.transform.gameObject); mBackground.SetValue(null); // 返回false表示不执行原方法 return(false); }
public abstract void Consume(BattleEntity target);
public TurnState(BattleEntity entity) { this.entity = entity; }
protected void OnActionSelected(BattleEntity entity, IBattleAction action) { mBattleTimeQueue.SetAction(entity, action); }
public void push_battleEntity(BattleEntity p_battleEntity) { p_battleEntity.ATB_Value = 0.0f; this.BattleEntities.Add(p_battleEntity); }
protected abstract void OnActionRequired(BattleEntity entity);
internal static void AttackCharacter(this ClientSession session, Mate attacker, Skill skil, Character target) { if (attacker == null || target == null) { return; } if (skil == null) { skil = ServerManager.GetSkill(200); } if (target.Hp > 0 && attacker.IsAlive) { if ((session.CurrentMapInstance.MapInstanceId == ServerManager.Instance.ArenaInstance.MapInstanceId || session.CurrentMapInstance.MapInstanceId == ServerManager.Instance.FamilyArenaInstance.MapInstanceId) && (session.CurrentMapInstance.Map.JaggedGrid[session.Character.PositionX][ session.Character.PositionY]?.Value != 0 || target.Session.CurrentMapInstance.Map.JaggedGrid[target.PositionX][ target.PositionY] ?.Value != 0)) { // User in SafeZone session.SendPacket(StaticPacketHelper.Cancel(2, target.CharacterId)); return; } if (target.IsSitting) { target.Rest(); } int hitmode = 0; bool onyxWings = false; attacker.LastSkillUse = DateTime.UtcNow; BattleEntity battleEntity = new BattleEntity(attacker); BattleEntity battleEntityDefense = new BattleEntity(target, null); session.CurrentMapInstance?.Broadcast(StaticPacketHelper.CastOnTarget(UserType.Npc, attacker.MateTransportId, 1, target.CharacterId, skil.CastAnimation, skil.CastEffect, skil.SkillVNum)); int damage = DamageHelper.Instance.CalculateDamage(battleEntity, battleEntityDefense, skil, ref hitmode, ref onyxWings); if (target.HasGodMode) { damage = 0; hitmode = 1; } else if (target.LastPvpRevive > DateTime.UtcNow.AddSeconds(-10) || session.Character.LastPvpRevive > DateTime.UtcNow.AddSeconds(-10)) { damage = 0; hitmode = 1; } int[] manaShield = target.GetBuff(BCardType.CardType.LightAndShadow, (byte)AdditionalTypes.LightAndShadow.InflictDamageToMP); if (manaShield[0] != 0 && hitmode != 1) { int reduce = damage / 100 * manaShield[0]; if (target.Mp < reduce) { target.Mp = 0; } else { target.Mp -= reduce; } } target.GetDamage(damage / 2); target.LastDefence = DateTime.UtcNow; target.Session.SendPacket(target.GenerateStat()); bool isAlive = target.Hp > 0; if (!isAlive && target.Session.HasCurrentMapInstance) { if (target.Session.CurrentMapInstance.Map?.MapTypes.Any( s => s.MapTypeId == (short)MapTypeEnum.Act4) == true) { if (ServerManager.Instance.ChannelId == 51 && ServerManager.Instance.Act4DemonStat.Mode == 0 && ServerManager.Instance.Act4AngelStat.Mode == 0) { switch (session.Character.Faction) { case FactionType.Angel: ServerManager.Instance.Act4AngelStat.Percentage += 500; break; case FactionType.Demon: ServerManager.Instance.Act4DemonStat.Percentage += 500; break; } } session.Character.Act4Kill++; target.Act4Dead++; target.GetAct4Points(-1); if (target.Level + 20 >= session.Character.Level && session.Character.Level <= target.Level - 20) { session.Character.GetAct4Points(2); } if (target.Reputation < 9999999999) { target.Session.SendPacket(session.Character.GenerateSay( string.Format(Language.Instance.GetMessageFromKey("LOSE_REP"), 0), 11)); } else { target.Reputation -= target.Level * 0; session.Character.Reputation += target.Level * 150; session.SendPacket(session.Character.GenerateLev()); target.Session.SendPacket(target.GenerateSay( string.Format(Language.Instance.GetMessageFromKey("LOSE_REP"), (short)(target.Level * 0)), 11)); } foreach (ClientSession sess in ServerManager.Instance.Sessions.Where( s => s.HasSelectedCharacter)) { if (sess.Character.Faction == session.Character.Faction) { sess.SendPacket(sess.Character.GenerateSay( string.Format( Language.Instance.GetMessageFromKey( $"ACT4_PVP_KILL{(int)target.Faction}"), session.Character.Name), 12)); } else if (sess.Character.Faction == target.Faction) { sess.SendPacket(sess.Character.GenerateSay( string.Format( Language.Instance.GetMessageFromKey( $"ACT4_PVP_DEATH{(int)target.Faction}"), target.Name), 11)); } } target.Session.SendPacket(target.GenerateFd()); target.DisableBuffs(BuffType.All, force: true); target.Session.CurrentMapInstance.Broadcast(target.Session, target.GenerateIn(), ReceiverType.AllExceptMe); target.Session.CurrentMapInstance.Broadcast(target.Session, target.GenerateGidx(), ReceiverType.AllExceptMe); target.Session.SendPacket( target.GenerateSay(Language.Instance.GetMessageFromKey("ACT4_PVP_DIE"), 11)); target.Session.SendPacket( UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("ACT4_PVP_DIE"), 0)); if (target.MapInstanceId == CaligorRaid.CaligorMapInstance?.MapInstanceId) { target.Hp = (int)target.HPLoad(); target.Mp = (int)target.MPLoad(); if (target.Faction == FactionType.Angel) { ServerManager.Instance.ChangeMapInstance(target.CharacterId, CaligorRaid.CaligorMapInstance.MapInstanceId, 70, 159); } else if (target.Faction == FactionType.Demon) { ServerManager.Instance.ChangeMapInstance(target.CharacterId, CaligorRaid.CaligorMapInstance.MapInstanceId, 110, 159); } target.Session.CurrentMapInstance?.Broadcast(target.Session, target.GenerateTp()); target.Session.CurrentMapInstance?.Broadcast(target.GenerateRevive()); target.Session.SendPacket(target.GenerateStat()); return; } Observable.Timer(TimeSpan.FromMilliseconds(2000)).Subscribe(o => { target.Session.CurrentMapInstance?.Broadcast(target.Session, $"c_mode 1 {target.CharacterId} 1564 0 0 0"); target.Session.CurrentMapInstance?.Broadcast(target.GenerateRevive()); }); Observable.Timer(TimeSpan.FromMilliseconds(30000)).Subscribe(o => { target.Hp = (int)target.HPLoad(); target.Mp = (int)target.MPLoad(); short x = (short)(39 + ServerManager.RandomNumber(-2, 3)); short y = (short)(42 + ServerManager.RandomNumber(-2, 3)); if (target.Faction == FactionType.Angel) { ServerManager.Instance.ChangeMap(target.CharacterId, 130, x, y); } else if (target.Faction == FactionType.Demon) { ServerManager.Instance.ChangeMap(target.CharacterId, 131, x, y); } else { target.MapId = 145; target.MapX = 51; target.MapY = 41; string connection = CommunicationServiceClient.Instance.RetrieveOriginWorld(session.Account.AccountId); if (string.IsNullOrWhiteSpace(connection)) { return; } int port = Convert.ToInt32(connection.Split(':')[1]); session.Character.ChangeChannel(connection.Split(':')[0], port, 3); return; } target.Session.CurrentMapInstance?.Broadcast(target.Session, target.GenerateTp()); target.Session.CurrentMapInstance?.Broadcast(target.GenerateRevive()); target.Session.SendPacket(target.GenerateStat()); }); } else { session.Character.TalentWin++; target.TalentLose++; session.CurrentMapInstance?.Broadcast(session.Character.GenerateSay( string.Format(Language.Instance.GetMessageFromKey("PVP_KILL"), session.Character.Name, target.Name), 10)); Observable.Timer(TimeSpan.FromMilliseconds(1000)).Subscribe(o => ServerManager.Instance.AskPvpRevive(target.CharacterId)); } } if (hitmode != 1) { skil.BCards.Where(s => s.Type.Equals((byte)BCardType.CardType.Buff)).ToList() .ForEach(s => s.ApplyBCards(target, session.Character)); } session.SendPacket(StaticPacketHelper.GenerateEff(UserType.Npc, attacker.MateTransportId, 5005)); Observable.Timer(TimeSpan.FromMilliseconds(skil.CastTime)).Subscribe(o => { session.CurrentMapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Npc, attacker.MateTransportId, 1, target.CharacterId, skil.SkillVNum, skil.Cooldown, skil.AttackAnimation, skil.Effect, 0, 0, target.Hp > 0, (int)(target.Hp / (float)target.HPLoad() * 100), damage, hitmode, 0)); }); // switch (hitRequest.TargetHitType) { case TargetHitType.SingleTargetHit: // hitRequest.Session.CurrentMapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Player, // hitRequest.Session.Character.CharacterId, 1, target.Character.CharacterId, // hitRequest.Skill.SkillVNum, hitRequest.Skill.Cooldown, // hitRequest.Skill.AttackAnimation, hitRequest.SkillEffect, // hitRequest.Session.Character.PositionX, hitRequest.Session.Character.PositionY, // isAlive, (int) (target.Character.Hp / (float) target.Character.HPLoad() * 100), // damage, hitmode, (byte) (hitRequest.Skill.SkillType - 1))); break; // // case TargetHitType.SingleTargetHitCombo: // hitRequest.Session.CurrentMapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Player, // hitRequest.Session.Character.CharacterId, 1, target.Character.CharacterId, // hitRequest.Skill.SkillVNum, hitRequest.Skill.Cooldown, // hitRequest.SkillCombo.Animation, hitRequest.SkillCombo.Effect, // hitRequest.Session.Character.PositionX, hitRequest.Session.Character.PositionY, // isAlive, (int) (target.Character.Hp / (float) target.Character.HPLoad() * 100), // damage, hitmode, (byte) (hitRequest.Skill.SkillType - 1))); break; // // case TargetHitType.SingleAOETargetHit: switch (hitmode) { case 1: hitmode = 4; break; // // case 3: hitmode = 6; break; // // default: hitmode = 5; break; } // // if (hitRequest.ShowTargetHitAnimation) { // hitRequest.Session.CurrentMapInstance?.Broadcast(StaticPacketHelper.SkillUsed( // UserType.Player, hitRequest.Session.Character.CharacterId, 1, // target.Character.CharacterId, hitRequest.Skill.SkillVNum, // hitRequest.Skill.Cooldown, hitRequest.Skill.AttackAnimation, // hitRequest.SkillEffect, 0, 0, isAlive, (int) (target.Character.Hp / (float) // target.Character.HPLoad() * 100), 0, 0, (byte) (hitRequest.Skill.SkillType - 1))); } // // hitRequest.Session.CurrentMapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Player, // hitRequest.Session.Character.CharacterId, 1, target.Character.CharacterId, // hitRequest.Skill.SkillVNum, hitRequest.Skill.Cooldown, // hitRequest.Skill.AttackAnimation, hitRequest.SkillEffect, // hitRequest.Session.Character.PositionX, hitRequest.Session.Character.PositionY, // isAlive, (int) (target.Character.Hp / (float) target.Character.HPLoad() * 100), // damage, hitmode, (byte) (hitRequest.Skill.SkillType - 1))); break; // // case TargetHitType.AOETargetHit: switch (hitmode) { case 1: hitmode = 4; break; // // case 3: hitmode = 6; break; // // default: hitmode = 5; break; } // // hitRequest.Session.CurrentMapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Player, // hitRequest.Session.Character.CharacterId, 1, target.Character.CharacterId, // hitRequest.Skill.SkillVNum, hitRequest.Skill.Cooldown, // hitRequest.Skill.AttackAnimation, hitRequest.SkillEffect, // hitRequest.Session.Character.PositionX, hitRequest.Session.Character.PositionY, // isAlive, (int) (target.Character.Hp / (float) target.Character.HPLoad() * 100), // damage, hitmode, (byte) (hitRequest.Skill.SkillType - 1))); break; // // case TargetHitType.ZoneHit: // hitRequest.Session.CurrentMapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Player, // hitRequest.Session.Character.CharacterId, 1, target.Character.CharacterId, // hitRequest.Skill.SkillVNum, hitRequest.Skill.Cooldown, // hitRequest.Skill.AttackAnimation, hitRequest.SkillEffect, hitRequest.MapX, // hitRequest.MapY, isAlive, (int) (target.Character.Hp / (float) // target.Character.HPLoad() * 100), damage, 5, (byte) (hitRequest.Skill.SkillType - // 1))); break; // // case TargetHitType.SpecialZoneHit: // hitRequest.Session.CurrentMapInstance?.Broadcast(StaticPacketHelper.SkillUsed(UserType.Player, // hitRequest.Session.Character.CharacterId, 1, target.Character.CharacterId, // hitRequest.Skill.SkillVNum, hitRequest.Skill.Cooldown, // hitRequest.Skill.AttackAnimation, hitRequest.SkillEffect, // hitRequest.Session.Character.PositionX, hitRequest.Session.Character.PositionY, // isAlive, (int) (target.Character.Hp / target.Character.HPLoad() * 100), damage, 0, // (byte) (hitRequest.Skill.SkillType - 1))); break; // // default: Logger.Warn("Not Implemented TargetHitType Handling!"); break; } } else { // player already has been killed, send cancel session.SendPacket(StaticPacketHelper.Cancel(2, target.CharacterId)); } }
/// <summary> /// Determines the attack score /// </summary> /// <param name="target">The target</param> /// <returns>The chosen attack</returns> private Attack DetermineAttackScore(BattleEntity target) { this.RefreshParent(); int distanceToTarget = Pathfinding.GetDistance(nodeParent, target.nodeParent); target.RefreshParent(); Attack currentAttack = null; List <Attack> allAttacks = new List <Attack>(); List <Attack> attacksInReadyRange = new List <Attack>(); List <Attack> attacksInMovementRange = new List <Attack>(); foreach (Attack attack in data.Attacks) { int valueOne, valueTwo; valueOne = valueTwo = (attack.Range - distanceToTarget); if (canMove) { valueTwo += data.Speed; } //entity is able to attack if (valueOne >= 0) { allAttacks.Add(attack); attacksInReadyRange.Add(attack); attackingScore += 10; moveForAttack = false; } //Entity can attack if moves else if (valueTwo >= 0) { allAttacks.Add(attack); attacksInMovementRange.Add(attack); attackingScore += data.Speed; moveForAttack = true; } } if (attacksInReadyRange.Count > 0) { currentAttack = attacksInReadyRange[0]; } else if (attacksInMovementRange.Count > 0) { currentAttack = attacksInMovementRange[0]; } //Get the attack with highest damage //TODO factor in other values such as armour piercing for (int i = 1; i < allAttacks.Count; i++) { if (allAttacks[i].Damage > currentAttack.Damage) { currentAttack = allAttacks[i]; } } //target can be killed in one hit if (currentAttack != null && target.data.CurrentHealth <= currentAttack.Damage) { //print("Setting attack score to max"); attackingScore = 999; } else if (currentAttack != null) { attackingScore = 50; } return(currentAttack); }
public List <BattleEntity> GetEntitiesInRange(BattleEntity entity, RangeType rangeType, Relationship relationship) { List <BattleEntity> bes = new List <BattleEntity>(); foreach (KeyValuePair <BattleEntity, BattleEntityConnection> bec in bEntityConnection) { if (rangeType == RangeType.Movement && bec.Value.inEntitiesMovementRange) { if (relationship == Relationship.Ally && ((entity.entityType == EntityType.Player && bec.Key.entityType == EntityType.Player) || (entity.entityType == EntityType.Enemy && bec.Key.entityType == EntityType.Enemy))) { bes.Add(bec.Key); } else if (relationship == Relationship.Enemy && ((entity.entityType == EntityType.Player && bec.Key.entityType == EntityType.Enemy) || (entity.entityType == EntityType.Enemy && bec.Key.entityType == EntityType.Player))) { bes.Add(bec.Key); } else if (relationship == Relationship.Any) { bes.Add(bec.Key); } } else if (rangeType == RangeType.Intimidation && bec.Value.inEntitiesIntimidationRange) { if (relationship == Relationship.Ally && ((entity.entityType == EntityType.Player && bec.Key.entityType == EntityType.Player) || (entity.entityType == EntityType.Enemy && bec.Key.entityType == EntityType.Enemy))) { bes.Add(bec.Key); } else if (relationship == Relationship.Enemy && ((entity.entityType == EntityType.Player && bec.Key.entityType == EntityType.Enemy) || (entity.entityType == EntityType.Enemy && bec.Key.entityType == EntityType.Player))) { bes.Add(bec.Key); } else if (relationship == Relationship.Any) { bes.Add(bec.Key); } } else if (rangeType == RangeType.OuterIntimidation && bec.Value.inEntitiesIntimidationRangeOuter) { if (relationship == Relationship.Ally && ((entity.entityType == EntityType.Player && bec.Key.entityType == EntityType.Player) || (entity.entityType == EntityType.Enemy && bec.Key.entityType == EntityType.Enemy))) { bes.Add(bec.Key); } else if (relationship == Relationship.Enemy && ((entity.entityType == EntityType.Player && bec.Key.entityType == EntityType.Enemy) || (entity.entityType == EntityType.Enemy && bec.Key.entityType == EntityType.Player))) { bes.Add(bec.Key); } else if (relationship == Relationship.Any) { bes.Add(bec.Key); } } else if (rangeType == RangeType.Melee && bec.Value.inEntitiesMeleeRange) { if (relationship == Relationship.Ally && ((entity.entityType == EntityType.Player && bec.Key.entityType == EntityType.Player) || (entity.entityType == EntityType.Enemy && bec.Key.entityType == EntityType.Enemy))) { bes.Add(bec.Key); } else if (relationship == Relationship.Enemy && ((entity.entityType == EntityType.Player && bec.Key.entityType == EntityType.Enemy) || (entity.entityType == EntityType.Enemy && bec.Key.entityType == EntityType.Player))) { bes.Add(bec.Key); } else { bes.Add(bec.Key); } } else if (rangeType == RangeType.OuterMelee && bec.Value.inEntitiesMeleeRangeOuter) { if (relationship == Relationship.Ally && (entity.entityType == EntityType.Player && bec.Key.entityType == EntityType.Player) || (entity.entityType == EntityType.Enemy && bec.Key.entityType == EntityType.Enemy)) { bes.Add(bec.Key); } else if (relationship == Relationship.Enemy && (entity.entityType == EntityType.Player && bec.Key.entityType == EntityType.Enemy) || (entity.entityType == EntityType.Enemy && bec.Key.entityType == EntityType.Player)) { bes.Add(bec.Key); } else if (relationship == Relationship.Any) { bes.Add(bec.Key); } } } return(bes); }
private Node DetermineMoveScore(BattleEntity target, bool canAttack, bool canConsume) { List <Node> movementRange = Pathfinding.GetRange(battleController.Nodes, nodeParent, data.Speed); Node node = null; if (!canMove) { moveScore = -100000; return(null); } //IF cant attack or consume, then moving is the only option if (!canAttack && !canConsume) { //print("cant attack or comsume"); moveScore = 1000; } //TODO do stuff if health is slow aka RETREAT //if health low //Move as far as you can away //Use healing consumable int minDistance = int.MinValue; if (data.CurrentHealth <= data.MaxHealth / 2 && canConsume) { //Find node farthest from target but within range foreach (Node _node in movementRange) { int distance = Pathfinding.GetDistance(_node, target.nodeParent); if (distance > minDistance) { node = _node; minDistance = distance; } } moveScore += 200; } //Get highest range attack Attack highestRangeAttack = data.Attacks[0]; for (int i = 1; i < data.Attacks.Count; i++) { if (data.Attacks[i].Range > highestRangeAttack.Range) { highestRangeAttack = data.Attacks[i]; } } if (node == null) { //Get closest node that is within the range foreach (Node _node in movementRange) { int distance = Pathfinding.GetDistance(_node, target.nodeParent); if (distance < minDistance && distance >= highestRangeAttack.Range) { node = _node; minDistance = distance; } } } minDistance = int.MaxValue; if (node == null) { foreach (Node _node in movementRange) { int distance = Pathfinding.GetDistance(_node, target.nodeParent); if (distance < minDistance) { minDistance = distance; node = _node; } } } moveScore += 20; return(node); }
public void update(float d) { this.Out_DamageApplied_Events.Clear(); this.Out_Death_Events.Clear(); this.Out_CompletedBattlequeue_Events.Clear(); // Update ATB_Values if (!this.ATB_Locked) { for (int i = 0; i < this.BattleEntities.Count; i++) { BattleEntity l_entity = this.BattleEntities[i]; if (!l_entity.IsDead) { l_entity.ATB_Value = Math.Min(l_entity.ATB_Value + (l_entity.ATB_Speed * d), 1.0f); if (l_entity.ATB_Value >= 1.0f) { if (!l_entity.IsControlledByPlayer) { this.BattleActionDecision_UserFunction.Invoke(this, l_entity); } } } this.BattleEntities[i] = l_entity; } } // A step takes the first entry of the BattleQueueEvents and initialize it step: if (this.CurrentExecutingEvent == null) { if (this.BattleQueueEvents.Count > 0) { this.CurrentExecutingEvent = this.BattleQueueEvents.Dequeue(); switch (this.BattleQueueEventInitialize_UserFunction.Invoke(this.CurrentExecutingEvent)) { case Initialize_ReturnCode.NOTHING: // When initialization doesn't require further processing, then we perform another step. this.on_currentActionFinished(); goto step; } } } if (this.CurrentExecutingEvent != null) { this.ATB_Locked = true; // We perform specific operation every frame for the current executing event switch (this.CurrentExecutingEvent.Type) { case BattleQueueEvent_Type.ATTACK: { // We consume damage events of the BQE_Attack event and push it to the global queue. BQE_Attack l_event = (BQE_Attack)this.CurrentExecutingEvent.Event; if (l_event.Out_DamageSteps != null && l_event.Out_DamageSteps.Count > 0) { for (int i = 0; i < l_event.Out_DamageSteps.Count; i++) { this.DamageEvents.Add(l_event.Out_DamageSteps[i]); } l_event.Out_DamageSteps.Clear(); } if (l_event.HasEnded) { on_currentActionFinished(); } } break; } } else { this.ATB_Locked = false; } // Effectively apply damage events if (this.DamageEvents.Count > 0) { for (int i = 0; i < this.DamageEvents.Count; i++) { BaseDamageStep l_damageEvent = this.DamageEvents[i]; int l_appliedDamage = DamageCalculation_Algorithm.calculate(l_damageEvent); if (DamageCalculation_Algorithm.apply_damage_raw(l_appliedDamage, l_damageEvent.Target)) { l_damageEvent.Target.IsDead = true; push_death_event(l_damageEvent.Target); this.BattleEntities.Remove(l_damageEvent.Target); this.DeadBattleEntities.Add(l_damageEvent.Target); } this.Out_DamageApplied_Events.Add(BQEOut_FinalDamageApplied.Alloc(l_damageEvent.Target, l_appliedDamage)); } this.DamageEvents.Clear(); } }
/// <summary> /// Logic to be executed on enemy turn /// </summary> /// <param name="targets">List of possible targets</param> private void OnEnemyTurn(List <BattleEntity> targets) { target = GetTarget(targets); currentAttack = DetermineAttackScore(target); consumable = DetermineConsumableScore(); node = DetermineMoveScore(target, canAttack: currentAttack != null, canConsume: consumable != null); //print("A-score: " + attackingScore + " C-score: "+ consumableScore + " M-Score: "+moveScore); //If enemy cant do anything just end turn if (currentAttack == null && (consumable == null || consumableScore <= 0) && !canMove) { RaiseEndTurnEvent(); } state = GetState(); switch (state) { case State.Attack: print("Attacking..."); if (currentAttack != null && moveForAttack) //TODO remove the first condition { Node nodeToMoveTo = null; List <Node> movementRangeNodes = Pathfinding.GetRange(battleController.Nodes, nodeParent, (data.Speed)); int minDistance = int.MaxValue; for (int i = 0; i < movementRangeNodes.Count; i++) { if (nodeParent != movementRangeNodes[i] && target.nodeParent != movementRangeNodes[i]) { List <Node> attackRangeNodes = Pathfinding.GetRange(battleController.Nodes, movementRangeNodes[i], currentAttack.Range); int currentDistance = Pathfinding.GetDistance(target.nodeParent, movementRangeNodes[i]); if (currentDistance < minDistance) { minDistance = currentDistance; nodeToMoveTo = movementRangeNodes[i]; } } } List <Node> path = Pathfinding.FindPath(nodeParent, nodeToMoveTo, reverse: true); for (int i = 0; i < path.Count; i++) { int distance = Pathfinding.GetDistance(path[i], target.nodeParent); if (distance <= currentAttack.Range) { path = Pathfinding.FindPath(nodeParent, path[i], reverse: true); break; } } SetPathNodes(path); node = path[path.Count - 1]; checkForLocationReached = true; } else if (currentAttack != null) { Attack.AttackTarget(currentAttack, target); RaiseEndTurnEvent(); } break; case State.Consumable: print("consuming"); consumable.Consume(this); data.Consumables.Remove(consumable); print("Consuming " + consumable.Name); consumable = null; //TODO allow selecting other targets(party members) RaiseEndTurnEvent(); break; case State.Move: print("Moving..."); List <Node> _path = Pathfinding.FindPath(nodeParent, node, reverse: true); if (_path != null) { SetPathNodes(_path); node = _path[_path.Count - 1]; } checkForLocationReached = true; break; } }
private void push_death_event(BattleEntity p_activeEntityHandle) { this.Out_Death_Events.Add(p_activeEntityHandle); }
// Update is called once per frame public void Update() { BattleManager.Instance.Update(Time.deltaTime); if (mEntity == null) { mEntity = BattleManager.Instance.GetEntity(1); } if (mEntity == null) { return; } if (Input.GetMouseButtonDown(1)) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); float distance; mPlane.Raycast(ray, out distance); Vector3 point = ray.GetPoint(distance); var tile = TileAt(point); if (tile != null) { tile.isValid = !tile.isValid; tile.SetColor(); } } if (Input.GetMouseButtonDown(0)) { mShowPath = true; } if (Input.GetMouseButtonUp(0)) { mShowPath = false; if (mTile != null) { if (mEntity != null) { EntityAction jump = mEntity.GetFirst(ActionType.Jump); if (Chess.Instance.jump) { if (jump == null) { jump = ObjectPool.GetInstance <EntityAction>(); jump.AddPathPoint(mTile.position, Vector3.zero, false, (entity, destination) => { var p = TileAt(destination); if (p != null) { p.SetColor(); } }); mEntity.PlayAction(ActionType.Jump, jump); } else { jump.AddPathPoint(mTile.position, Vector3.zero, false, (entity, destination) => { var p = TileAt(destination); if (p != null) { p.SetColor(); } }); } } else { var position = mEntity.position; if (jump != null && jump.paths.Count > 0) { position = jump.paths.Last.Value.destination; } var result = FindPath(TileAt(position), mTile, (tile) => { return(tile.isValid); }, (tile) => { return(Neighbours(tile)); }, GetCostValue); if (jump == null) { jump = ObjectPool.GetInstance <EntityAction>(); while (result.Count > 0) { var path = result.Pop(); jump.AddPathPoint(path.position, Vector3.zero, false, (entity, destination) => { var p = TileAt(destination); if (p != null) { p.SetColor(); } }, (entity, destination) => { var p = TileAt(destination); if (p != null) { p.SetColor(); } }); } mEntity.PlayAction(ActionType.Jump, jump); } else { while (result.Count > 0) { var path = result.Pop(); jump.AddPathPoint(path.position, Vector3.zero, false, (entity, destination) => { var p = TileAt(destination); if (p != null) { p.SetColor(); } }, (entity, destination) => { var p = TileAt(destination); if (p != null) { p.SetColor(); } }); } } } } } mTile = null; } if (mShowPath) { if (mPathRenderer == null) { if (root) { mPathRenderer = root.GetComponent <LineRenderer>(); if (mPathRenderer == null) { mPathRenderer = root.gameObject.AddComponent <LineRenderer>(); } AssetLoader.LoadAsset <Material>("arrow.mat", (asset) => { mPathRenderer.material = asset.assetObject; }); mPathRenderer.startWidth = 1f; mPathRenderer.endWidth = 1f; mPathRenderer.startColor = Color.yellow; mPathRenderer.endColor = Color.yellow; mPathRenderer.receiveShadows = false; mPathRenderer.shadowCastingMode = ShadowCastingMode.Off; } } if (mPathRenderer != null) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); float distance; mPlane.Raycast(ray, out distance); Vector3 point = ray.GetPoint(distance); var tile = TileAt(point); if (tile == null) { int minDistance = -1; var it = tiles.GetEnumerator(); while (it.MoveNext()) { int d = Distance(point, it.Current.Value.position); if (minDistance == -1 || d < minDistance) { tile = it.Current.Value; minDistance = d; } } } if (tile != null) { if (mTile == null || (tile.index != mTile.index)) { Vector3 position = mEntity.position; var run = mEntity.GetLast(ActionType.Jump); if (run != null) { if (run.paths.Count > 0) { position = run.paths.Last.Value.destination; } } BattleHexTile t = TileAt(position); if (t != null && t.index == tile.index) { ClearPath(); } else { if (mTile != null) { mTile.Select(false); } mTile = tile; mTile.Select(true); if (Chess.Instance.jump == false) { var result = FindPath(t, mTile, (o) => { return(o.isValid); }, (o) => { return(Neighbours(o)); }, GetCostValue ); var it = tiles.GetEnumerator(); while (it.MoveNext()) { it.Current.Value.SetColor(); } var jumps = mEntity.GetActions(ActionType.Jump); if (jumps != null) { var j = jumps.GetEnumerator(); while (j.MoveNext()) { var jump = j.Current as EntityAction; var d = jump.paths.GetEnumerator(); while (d.MoveNext()) { var dest = TileAt(d.Current.destination); if (dest != null) { dest.SetColor(Color.green); } } } } var r = result.GetEnumerator(); while (r.MoveNext()) { r.Current.SetColor(Color.green); } } BattleBezierPath.GetPath(position, mTile.position, 0.5f, ActionJumpPlugin.SPEED, ActionJumpPlugin.MINHEIGHT, ActionJumpPlugin.MAXHEIGHT, ActionJumpPlugin.GRAVITY, ref mPathPoints); mPathRenderer.positionCount = mPathPoints.Count; mPathRenderer.SetPositions(mPathPoints.ToArray()); } } } else { ClearPath(); } } } else { ClearPath(); } }
public void OnDecisionRequired(BattleEntity entity) { BattleSystem.Instance.PostActionRequired(entity); }
public void setTarget(Skill skill, BattleEntity selectedTarget) { skill.setTarget(selectedTarget); }