public static List<IEffect> getCommand(FullCombatCharacter source, List<FullCombatCharacter> targets, CombatData combatData) { if (source.className == "Goblin") { return Goblins.GoblinAbilityProcessing.getCommand(source, targets, combatData); } return new List<IEffect>(); }
//Basic Goblin, only attacks public static List<IEffect> getCommand(FullCombatCharacter source, List<FullCombatCharacter> targets, CombatData combatData) { List<IEffect> effects = new List<IEffect>(); FullCombatCharacter target = BasicAbilityProcessing.identifyWeakestTarget(targets); int dmg = (int)((source.strength * 5 / target.vitality)); target.inflictDamage(ref dmg); effects.Add(new Effect(EffectTypes.DealDamage, target.combatUniq, string.Empty, dmg)); effects.Add(new Effect(EffectTypes.Message, 0, source.name + " has attacked " + target.name + " for " + dmg.ToString() + " damage!", 0)); GeneralProcessor.calculateNextAttackTime(source, 1.0f); return effects; }
public static List<IEffect> getCommand(FullCombatCharacter source, List<FullCombatCharacter> targets, CombatData combatData) { List<IEffect> effects = new List<IEffect>(); float coefficient = 1.0f; FullCombatCharacter target = BasicAbilityProcessing.identifyWeakestTarget(targets); int dmg = (int)((CombatCalculator.getNormalAttackValue(source) * 5 / target.vitality)); if (target.inflictDamage(ref dmg) == FullCombatCharacter.HitEffect.Unbalance) { coefficient = coefficient * 2; } effects.Add(new Effect(EffectTypes.Attack, source.combatUniq, string.Empty, 0)); effects.Add(new Effect(EffectTypes.DealDamage, target.combatUniq, string.Empty, dmg)); effects.Add(new Effect(EffectTypes.Message, 0, source.name + " has attacked " + target.name + " for " + dmg.ToString() + " damage!", 0)); GeneralProcessor.calculateNextAttackTime(source, coefficient, combatData); return effects; }
public static void calculateNextAttackTime(FullCombatCharacter character, float abilityCoefficient, CombatData combatData) { int nextAttackTime; if (combatData.doubleSelectionState != PlayerModels.CombatDataModels.CombatDataModel.DoubleSelectionState.None) { abilityCoefficient = abilityCoefficient * 1.5f; } if (BasicModificationsGeneration.hasMod(character, "Adrenaline")) { nextAttackTime = calculateNextAttackTime(character.nextAttackTime, abilityCoefficient / 3, character.agility); } else { nextAttackTime = calculateNextAttackTime(character.nextAttackTime, abilityCoefficient, character.agility); } if (combatData.doubleSelectionState == PlayerModels.CombatDataModels.CombatDataModel.DoubleSelectionState.None) { character.nextAttackTime = nextAttackTime; } else { if (combatData.doubleSelectionState == PlayerModels.CombatDataModels.CombatDataModel.DoubleSelectionState.First) { combatData.doubleSelectionDelay = nextAttackTime; combatData.doubleSelectionState = PlayerModels.CombatDataModels.CombatDataModel.DoubleSelectionState.Second; } else { combatData.doubleSelectionDelay += (nextAttackTime - character.nextAttackTime); character.nextAttackTime = combatData.doubleSelectionDelay; combatData.doubleSelectionState = PlayerModels.CombatDataModels.CombatDataModel.DoubleSelectionState.None; } } }
public static List<ICommand> getClassAbilities(FullCombatCharacter source, CombatData combatData) { return GeneralProcessor.getClassCommands(source, combatData); }
private ProcessResult processFunction(Func<FullCombatCharacter, List<FullCombatCharacter>, CombatData, List<IEffect>, AbilityInfo, ProcessResult> executingFunction, FullCombatCharacter source, List<FullCombatCharacter> targets, CombatData combatData, List<IEffect> effects) { if (executingFunction != null) { return executingFunction(source, targets, combatData, effects, this); } return ProcessResult.Normal; }
private ProcessResult Process(FullCombatCharacter source, List<FullCombatCharacter> target, CombatData combatData, List<IEffect> effects) { //Deal damage etc. foreach (FullCombatCharacter t in target) { int dmg = 0; if (damageType == DamageType.Physical) { dmg = (int)((CombatCalculator.getNormalAttackValue(source) * damageCoefficient * damageMultiplier / t.vitality)); for (int i = 0; i < hits; i++) { if (t.inflictDamage(ref dmg) == FullCombatCharacter.HitEffect.Unbalance) { attackTimeCoefficient = attackTimeCoefficient * 2; } } effects.Add(new Effect(EffectTypes.DealDamage, t.combatUniq, string.Empty, dmg)); string newMessage = message.Replace("{Name}", source.name) .Replace("{Target}", t.name) .Replace("{Damage}", dmg.ToString()) .Replace("{HitCount}", hits.ToString()); if (newMessage != string.Empty) { effects.Add(new Effect(EffectTypes.Message, 0, newMessage, 0)); } } else if (damageType == DamageType.Magical) { dmg = (int)((CombatCalculator.getMagicAttackValue(source) * damageCoefficient * damageMultiplier / t.wisdom)); for (int i = 0; i < hits; i++) { t.inflictDamage(ref dmg); } effects.Add(new Effect(EffectTypes.DealDamage, t.combatUniq, string.Empty, dmg)); string newMessage = message.Replace("{Name}", source.name) .Replace("{Target}", t.name) .Replace("{Damage}", dmg.ToString()) .Replace("{HitCount}", hits.ToString()); if (newMessage != string.Empty) { effects.Add(new Effect(EffectTypes.Message, 0, newMessage, 0)); } } } return ProcessResult.Normal; }
private ProcessResult PreProcess(FullCombatCharacter source, List<FullCombatCharacter> target, CombatData combatData, List<IEffect> effects) { //Determine if it's a valid skill or on cooldown etc if (source.classLevel < requiredClassLevel || combatData.hasCooldown(source.name, cooldown) || target.Count > maxTargets) { return ProcessResult.EndTurn; } if (BasicModificationsGeneration.hasMod(source, "Ranged")) { damageCoefficient = damageCoefficient * .75f; if (!ranged) { effects.Add(new Effect(EffectTypes.Message, 0, "Using a melee attack has removed the ranged advantage!", 0)); CombatCalculator.removeRanged(source); } } if (oncePerRest != string.Empty && source.usedAbilities.Contains(oncePerRest)) { return ProcessResult.EndTurn; } return ProcessResult.Normal; }
private ProcessResult PostProcess(FullCombatCharacter source, List<FullCombatCharacter> target, CombatData combatData, List<IEffect> effects) { //Set next attack time etc. if (cooldown != string.Empty) { combatData.cooldowns.Add(new CooldownModel { character = source.name, name = cooldown, time = (source.nextAttackTime + cooldownDuration) }); } GeneralProcessor.calculateNextAttackTime(source, attackTimeCoefficient, combatData); if (oncePerRest != string.Empty) { source.usedAbilities.Add(oncePerRest); } if (mpCost != 0) { source.mp = source.mp - mpCost; } return ProcessResult.Normal; }
public static bool isDisabled(string abilityName, FullCombatCharacter source, CombatData combatData) { if(processors.ContainsKey(source.className)) { return processors[source.className].isDisabled(abilityName, source, combatData); } return false; }
public static List<ICommand> getClassCommands(FullCombatCharacter source, CombatData combatData) { if (processors.ContainsKey(source.className)) { return processors[source.className].getClassCommands(source, combatData); } return new List<ICommand>(); }
public Combat(PlayerModels.PlayerModel playerModel, string map, int encounterSelection, Func<float> initiativeCalculator, Action onGameOver, Action onUpdate, Action<CombatEndType> onCombatComplete) { int currentUniq = 1; this.playerModel = playerModel; uniqBridge = new Dictionary<int, int>(); pcs = new Dictionary<int, FullCombatCharacter>(); npcs = new Dictionary<int, FullCombatCharacter>(); currentEffects = new List<IEffect>(); currentCharacter = new FullCombatCharacter(); this.onGameOver = onGameOver; this.onUpdate = onUpdate; this.onCombatComplete = onCombatComplete; this.map = map; bool canFlee = true; List<PlayerModels.Models.PartyCharacterModel> partyCharacterModels = PlayerModels.PlayerDataManager.getCurrentPartyPartyStats(playerModel); List<int> characterUniqs = new List<int>(); foreach (PlayerModels.Models.PartyCharacterModel pcm in partyCharacterModels) { characterUniqs.Add(pcm.characterUniq); } List<PlayerModels.Models.CharacterModel> characterModels = PlayerModels.PlayerDataManager.getCurrentParty(playerModel, characterUniqs); bool hasPreviousCombatModels = false; if (playerModel.currentCombat == null) { combatCharacterModels = new List<PlayerModels.CombatDataModels.CombatCharacterModel>(); combatNPCModels = new List<CombatCharacterModel>(); playerModel.currentCombat = new CombatModel(); playerModel.currentCombat.currentTime = 0; playerModel.currentCombat.pcs = combatCharacterModels; playerModel.currentCombat.npcs = combatNPCModels; } else { combatCharacterModels = playerModel.currentCombat.pcs; combatNPCModels = playerModel.currentCombat.npcs; hasPreviousCombatModels = true; } foreach (int characterUniq in characterUniqs) { string name = string.Empty; int hp = 0; int maxHP = 0; int mp = 0; int maxMP = 0; int turnOrder = 0; string classType = string.Empty; int level = 0; int strength = 0; int vitality = 0; int agility = 0; int intellect = 0; int wisdom = 0; int nextAttackTime = 0; int classLevel = 0; int combatUniq = currentUniq; List<CombatModificationsModel> mods = new List<CombatModificationsModel>(); List<string> usedAbilities = new List<string>(); uniqBridge.Add(currentUniq, characterUniq); foreach (PlayerModels.Models.CharacterModel cm in characterModels) { if (cm.uniq == characterUniq) { name = cm.name; maxHP = cm.stats.maxHP; maxMP = cm.stats.maxMP; classType = cm.currentClass; level = cm.lvl; strength = cm.stats.strength; vitality = cm.stats.vitality; agility = cm.stats.agility; intellect = cm.stats.intellect; wisdom = cm.stats.wisdom; foreach (PlayerModels.Models.CharacterClassModel ccm in cm.characterClasses) { if (ccm.className == classType) { classLevel = ccm.lvl; } } } } foreach (PlayerModels.Models.PartyCharacterModel pcm in partyCharacterModels) { if (pcm.characterUniq == characterUniq) { hp = pcm.hp; mp = pcm.mp; usedAbilities = (pcm.usedAbilities == null ? new List<string>() : pcm.usedAbilities); } } nextAttackTime = GeneralProcessor.calculateNextAttackTime(0, initiativeCalculator(), agility); if (hasPreviousCombatModels) { foreach (CombatCharacterModel ccm in combatCharacterModels) { if (ccm.characterUniq == characterUniq) { nextAttackTime = ccm.nextAttackTime; hp = ccm.stats.hp; mp = ccm.stats.mp; combatUniq = ccm.combatUniq; } } } else { combatCharacterModels.Add(new PlayerModels.CombatDataModels.CombatCharacterModel() { characterUniq = characterUniq, stats = new PlayerModels.CombatDataModels.TemporaryCombatStatsModel() { hp = hp, mp = mp }, nextAttackTime = nextAttackTime, combatUniq = combatUniq }); } pcs.Add(characterUniq, new FullCombatCharacter() { name = name, maxHP = maxHP, hp = hp, maxMP = maxMP, mp = mp, characterUniq = characterUniq, combatUniq = currentUniq, className = classType, classLevel = classLevel, level = level, strength = strength, vitality = vitality, intellect = intellect, agility = agility, wisdom = wisdom, nextAttackTime = nextAttackTime, mods = new List<CombatModificationsModel>(), usedAbilities = usedAbilities }); combatCharacterModels[combatCharacterModels.Count - 1].mods = pcs[characterUniq].mods; currentUniq++; } if (hasPreviousCombatModels) //Combat was already initialized previously, just load the previous combatants { foreach (CombatCharacterModel ccm in combatNPCModels) { int hp = ccm.stats.hp; int mp = ccm.stats.mp; string name = ccm.name; int nextAttackTime = ccm.nextAttackTime; List<CombatModificationsModel> mods = ccm.mods; List<string> usedAbilities = new List<string>(); MapDataClasses.MapDataClasses.Enemy enemy = MapDataClasses.MapDataManager.getEnemy(map, ccm.classType); if (!this.npcs.ContainsKey(currentUniq)) { this.npcs.Add(currentUniq, new FullCombatCharacter() { name = name, hp = hp, maxHP = enemy.maxHP, mp = mp, maxMP = enemy.maxMP, characterUniq = 0, combatUniq = currentUniq, className = enemy.type, level = enemy.level, strength = enemy.strength, vitality = enemy.vitality, agility = enemy.agility, intellect = enemy.intellect, wisdom = enemy.wisdom, nextAttackTime = nextAttackTime, mods = mods, usedAbilities = usedAbilities }); } currentUniq++; } } else //Generate a new encounter based on the map type { Encounter encounter = MapDataClasses.MapDataManager.getEncounter(this.playerModel.getActiveParty().location, playerModel.rootX, playerModel.rootY, encounterSelection); currentEffects.Add(new Effect(EffectTypes.Message, 0, encounter.message, 0)); combatNPCModels = new List<PlayerModels.CombatDataModels.CombatCharacterModel>(); canFlee = encounter.canFlee; foreach (MapDataClasses.MapDataClasses.Enemy enemy in encounter.enemies) { int nextAttackTime = GeneralProcessor.calculateNextAttackTime(0, initiativeCalculator(), enemy.agility); int hp = enemy.maxHP; int mp = enemy.maxMP; int combatUniq = currentUniq; List<CombatModificationsModel> mods = new List<CombatModificationsModel>(); List<string> usedAbilities = new List<string>(); this.npcs.Add(currentUniq, new FullCombatCharacter() { name = enemy.name, hp = hp, maxHP = enemy.maxHP, mp = mp, maxMP = enemy.maxMP, characterUniq = 0, combatUniq = currentUniq, className = enemy.type, level = enemy.level, strength = enemy.strength, vitality = enemy.vitality, agility = enemy.agility, intellect = enemy.intellect, wisdom = enemy.wisdom, nextAttackTime = nextAttackTime, mods = mods, usedAbilities = usedAbilities }); this.combatNPCModels.Add(new PlayerModels.CombatDataModels.CombatCharacterModel() { name = enemy.name, stats = new PlayerModels.CombatDataModels.TemporaryCombatStatsModel() { hp = hp, mp = mp }, nextAttackTime = nextAttackTime, combatUniq = currentUniq, characterUniq = 0, classType = enemy.type, mods = this.npcs[currentUniq].mods }); currentUniq++; } } playerModel.currentCombat.npcs = combatNPCModels; if (combatNPCModels.Count == 0) { throw new Exception("No NPCs were loaded :("); } calculateTurnOrder(); this.combatData = new CombatData(playerModel.currentCombat, canFlee); if (!this.combatData.combatInitalized) { foreach (int key in pcs.Keys) //Check for initial code { FullCombatCharacter fcc = pcs[key]; List<IEffect> newEffects = GeneralProcessor.initialExecute(fcc)(getAllPcsAsList(), getAllNpcsAsList(), this.combatData); currentEffects.AddRange(newEffects); } this.combatData.combatInitalized = true; } calculateTurn(false); }
public bool isDisabled(string abilityName, FullCombatCharacter source, CombatData combatData) { if (abilityName == "First Strike") { if (!combatData.isFirstTurn(source.name)) { return true; } } return false; }
public List<ICommand> getClassCommands(FullCombatCharacter source, CombatData combatData) { List<ICommand> commands = new List<ICommand>(); int level = source.classLevel; commands.Add(new Command(false, new List<ICommand>(), false, 0, 0, "Glance", false, 0, true, isDisabled("Glance", source, combatData))); if (level >= 3) { commands.Add(new Command(false, new List<ICommand>(), false, 0, 0, "Guarded Strike", false, 0, true, isDisabled("Guarded Strike", source, combatData))); } if (level >= 5) { commands.Add(new Command(false, new List<ICommand>(), false, 0, 0, "Reckless Hit", false, 0, true, isDisabled("Reckless Hit", source, combatData))); } if (level >= 7) { commands.Add(new Command(false, new List<ICommand>(), false, 0, 0, "Guided Strike", false, 0, true, isDisabled("Guided Strike", source, combatData))); } if (level >= 9) { commands.Add(new Command(false, new List<ICommand>(), false, 0, 0, "Throw Rock", false, 0, true, isDisabled("Throw Rock", source, combatData))); } if (level >= 15) { commands.Add(new Command(false, new List<ICommand>(), false, 0, 0, "First Strike", false, 0, true, isDisabled("First Strike", source, combatData))); } return commands; }