public void RunAutocombatForActiveCharacter() { CharacterTeam opposingTeam = adventure.GetTeamOppositeOfFaction(activeCharacter.curFaction); CharacterTeam ownTeam = adventure.GetTeamForFaction(activeCharacter.curFaction); SodaScript acScript = null; if (activeCharacter.curFaction == Faction.PLAYER) { acScript = activeCharacter.activeSodaScript; } else { acScript = defaultEnemyScript; } acScript.Execute(activeCharacter, adventure, cachedSkillCommand); //keep track of how many times a team has healed itself in a row. this is used inside of soda script execution to break out of infinite heal loops if (cachedSkillCommand.skill.isHealing) { ownTeam.consecutiveHeals++; } else { ownTeam.consecutiveHeals = 0; } adventure.ReceiveCommand(cachedSkillCommand); }
public void Cleanup() { isProcessing = false; adventure = null; turnQueue.Clear(); charactersInBattle.Clear(); currentDeadCharacters.Clear(); turnQueue = charactersInBattle = currentDeadCharacters = null; activeCharacter = null; currentSkillResults.Clear(); currentSkillResults = null; activeSkillCommand = null; defaultEnemyScript = null; EBattleStarted = null; ECharacterActivated = null; ESkillResolved = null; EStatusProc = null; EStatusExpired = null; ERegenProc = null; EFinishCharacterProcs = null; ECharactersDied = null; EEnemyLootEarned = null; EBattleEnded = null; }
public void CopyTriggersFrom(SodaScript inOtherScript) { triggers.Clear(); for (int i = 0; i < inOtherScript.triggers.Count; i++) { triggers.Add(inOtherScript.triggers[i].GetCopy()); } }
//should only be used for a player team public void CacheActiveSodaScriptReferences() { numMembersUsingCustomSodaScript = 0; for (int i = 0; i < members.Count; i++) { members[i].activeSodaScript = SodaScript.GetPremadeScript(SodaScript.SCRIPT_DEFAULT_PLAYER); } }
private List <CharacterData[]> pendingCharacterTransformations; //this is NOT for transmuting. this is for when a character "dies" and turns into another public BattleManager(Adventure inAdventure) { adventure = inAdventure; curFile = SaveFile.GetSaveFile(); charactersInBattle = new List <CharacterData>(); turnQueue = new List <CharacterData>(); currentSkillResults = new List <SkillResult>(); currentDeadCharacters = new List <CharacterData>(); pendingCharacterTransformations = new List <CharacterData[]>(); cachedSkillCommand = new SkillCommand(); stepsInATurn = new List <Action>(); stepsInATurn.Add(EnactPendingCharacterTransformations); stepsInATurn.Add(BeginTurn); stepsInATurn.Add(CheckForRegenProc); stepsInATurn.Add(ActivateNextCharacter); stepsInATurn.Add(RequestActiveCharacterInput); stepsInATurn.Add(ResolveActiveSkillCommand); stepsInATurn.Add(CleanupActiveSkillCommand); stepsInATurn.Add(DeactivateActiveCharacter); stepsInATurn.Add(CheckForStatusProc); stepsInATurn.Add(CheckForDeaths); stepsInATurn.Add(EarnLootForDeadEnemies); stepsInATurn.Add(EndTurn); stepsInATurn.Add(CheckForPlayerTeamRevive); stepsInATurn.Add(CheckForBattleEnd); stepsInATurn.Add(Repeat); defaultEnemyScript = SodaScript.GetPremadeScript(SodaScript.SCRIPT_DEFAULT_ENEMY); playerTeamHasRevivedOnceThisTrip = false; }
static void Main(string[] args) { Console.WriteLine("Soda Dungeon Adventure System"); //initialize data that the adventure requires to run Stats.BuildDefaultStats(); SkillId.CacheIds(); Skill.CreateSkills(); DungeonData.CreateDungeons(); ItemId.CacheIds(); Item.CreateItems(); SpawnTable.CreateOreTables(); SpawnPattern.CreateSpawnPatterns(); SodaScript.CreateScripts(); StatusEffect.CreateAncillaryTypeData(); CharacterData.InitCharacterCollection(); PlayerCharacterData.CreatePlayerCharacters(); EnemyCharacterData.CreateEnemyCharacters(); PoolManager.CreateObjectPools(); //create two characters for our party and add them to a list. It's important that we create them as copies of the prototypes from the master character collection var character1 = (PlayerCharacterData)CharacterData.GetCopy(CharId.SODA_JUNKIE); var character2 = (PlayerCharacterData)CharacterData.GetCopy(CharId.NURSE); var character3 = (PlayerCharacterData)CharacterData.GetCopy(CharId.CARPENTER); var character4 = (PlayerCharacterData)CharacterData.GetCopy(CharId.NURSE); var playerCharacters = new List <PlayerCharacterData>(); playerCharacters.Add(character1); playerCharacters.Add(character2); playerCharacters.Add(character3); playerCharacters.Add(character4); //create a new adventure in the castle, provide characters, and set input mode to auto (otherwise the adventure will stop and wait for player input) var adventure = new Adventure(DungeonId.CASTLE, playerCharacters); adventure.SetInputMode(AdventureInputMode.AUTO); //set this to true if you want the adventure to log a message every time it processes a step adventure.showVerboseOutput = false; //when input mode is set to auto, combat decisions will handled by soda script. however, we can still allow the player to choose random treasure chests and paths. //this is off by default; if you turn it on you must listen for events such as EAltPathsEncountered and respond with OnAltPathClicked(choice) adventure.requireInputForRandomChoices = false; //listen for various events to receive information about the adventure progress adventure.EBattleStarted += OnBattleStarted; adventure.ESkillUsed += OnSkillUsed; adventure.ESkillResolved += OnSkillResolved; adventure.EEnemyLootEarned += OnEnemyLootEarned; adventure.ECharactersDied += OnCharactersDied; adventure.EAltPathsEncountered += OnAltPathsEncountered; adventure.EAltPathConfirmed += OnAltPathConfirmed; adventure.ETreasureRoomConfirmed += OnTreasureRoomConfirmed; //start the adventure adventure.Start(); //read key so that the output window won't close immediately after the adventure finishes Console.ReadKey(); }
public static void CreateScripts() { scripts = new List <SodaScript>(); SodaScript script; SodaScriptTrigger trigger; //ENEMY script = new SodaScript(SCRIPT_DEFAULT_ENEMY); script._isReadonly = true; //testing trigger, use this to force a skill //trigger = script.AddTrigger(SodaScriptTarget.ENEMY, SodaScriptCondition.ANY); //trigger.SetSkill(SodaScriptSkillCategory.SPECIFIC, SkillId.STUN); trigger = script.AddTrigger(SodaScriptTarget.SELF, SodaScriptCondition.HP, SodaScriptComparison.LESS_THAN, "50"); trigger.SetSkill(SodaScriptSkillCategory.STRONGEST_HEAL); trigger.percentageChance = 70; trigger = script.AddTrigger(SodaScriptTarget.ALLY, SodaScriptCondition.HP, SodaScriptComparison.LESS_THAN, "60"); trigger.SetSkill(SodaScriptSkillCategory.STRONGEST_HEAL); trigger.percentageChance = 90; trigger = script.AddTrigger(SodaScriptTarget.SELF, SodaScriptCondition.STATUS, SodaScriptComparison.NOT_EQUALS, StatusEffectCategory.POSITIVE.ToString()); trigger.SetSkill(SodaScriptSkillCategory.ANY_SELF_BUFF); trigger.percentageChance = 70; //we can use this to attempt debuffs specifically, but any debuff is included in "any non friendly that consumes mp" trigger //trigger = script.AddTrigger(SodaScriptTarget.ENEMY, SodaScriptCondition.STATUS, SodaScriptComparison.NOT_EQUALS, StatusEffectCategory.NEGATIVE.ToString()); //trigger.SetSkill(SodaScriptSkillCategory.ANY_DEBUFF); trigger = script.AddTrigger(SodaScriptTarget.ENEMY, SodaScriptCondition.ANY); trigger.SetSkill(SodaScriptSkillCategory.ANY_NON_FRIENDLY_THAT_CONSUMES_MP); trigger.percentageChance = 25; trigger = script.AddTrigger(SodaScriptTarget.ENEMY, SodaScriptCondition.ANY); trigger.SetSkill(SodaScriptSkillCategory.ANY_NON_FRIENDLY_THAT_DOESNT_CONSUME_MP); trigger = script.AddTrigger(SodaScriptTarget.ENEMY, SodaScriptCondition.ANY); trigger.SetSkill(SodaScriptSkillCategory.DEFAULT); scripts.Add(script); //PLAYER script = new SodaScript(SCRIPT_DEFAULT_PLAYER); script._isReadonly = true; //testing trigger, use this to force a skill //trigger = script.AddTrigger(SodaScriptTarget.ENEMY, SodaScriptCondition.ANY); //trigger.SetSkill(SodaScriptSkillCategory.SPECIFIC, SkillId.STUN); trigger = script.AddTrigger(SodaScriptTarget.SELF, SodaScriptCondition.HP, SodaScriptComparison.LESS_THAN, "60"); trigger.SetSkill(SodaScriptSkillCategory.STRONGEST_HEAL); trigger = script.AddTrigger(SodaScriptTarget.ALLY, SodaScriptCondition.HP, SodaScriptComparison.LESS_THAN, "60"); trigger.SetSkill(SodaScriptSkillCategory.STRONGEST_HEAL); trigger = script.AddTrigger(SodaScriptTarget.ENEMY, SodaScriptCondition.TEAM_ALIVE, SodaScriptComparison.GREATER_THAN, "2"); trigger.SetSkill(SodaScriptSkillCategory.STRONGEST_GROUP_ATTACK); //50% chance to use a debuff skill on character with no debuffs trigger = script.AddTrigger(SodaScriptTarget.ENEMY, SodaScriptCondition.STATUS, SodaScriptComparison.NOT_EQUALS, StatusEffectCategory.NEGATIVE.ToString()); trigger.SetSkill(SodaScriptSkillCategory.ANY_DEBUFF); trigger.percentageChance = 50; trigger = script.AddTrigger(SodaScriptTarget.ENEMY, SodaScriptCondition.RANK, SodaScriptComparison.GREATER_THAN, EnemyRank.MBOS.ToString()); trigger.SetSecondaryCondition(SodaScriptCondition.HP, SodaScriptComparison.GREATER_THAN, "50"); trigger.SetSkill(SodaScriptSkillCategory.STRONGEST_SINGLE_TARGET_ATTACK); trigger = script.AddTrigger(SodaScriptTarget.ENEMY, SodaScriptCondition.ISNT_ORE); trigger.SetSecondaryCondition(SodaScriptCondition.WEAKEST); trigger.SetSkill(SodaScriptSkillCategory.DEFAULT); scripts.Add(script); //default trigger that will mostly be used by player scripts defaultTrigger = new SodaScriptTrigger(SodaScriptTarget.ENEMY, SodaScriptCondition.WEAKEST); defaultTrigger.SetSkill(SodaScriptSkillCategory.DEFAULT); //create some lists to limit user input to logically correct values USER_ALLOWED_TARGETS = new SodaScriptTarget[] { SodaScriptTarget.ENEMY, SodaScriptTarget.ALLY, SodaScriptTarget.SELF }; allowedConditionsForTarget = new Dictionary <SodaScriptTarget, SodaScriptCondition[]>(); allowedConditionsForTarget[SodaScriptTarget.ENEMY] = new SodaScriptCondition[] { SodaScriptCondition.WEAKEST, SodaScriptCondition.HP, SodaScriptCondition.MP, SodaScriptCondition.TEAM_ALIVE, SodaScriptCondition.TEAM_HP, SodaScriptCondition.RANK, SodaScriptCondition.IS_ORE, SodaScriptCondition.ISNT_ORE, SodaScriptCondition.BACK_IS_TURNED, SodaScriptCondition.BACK_ISNT_TURNED, SodaScriptCondition.STATUS, SodaScriptCondition.HAS_ESSENCE, SodaScriptCondition.NO_ESSENCE, SodaScriptCondition.IS_JANITOR, SodaScriptCondition.ISNT_JANITOR, SodaScriptCondition.ANY }; allowedConditionsForTarget[SodaScriptTarget.ALLY] = new SodaScriptCondition[] { SodaScriptCondition.WEAKEST, SodaScriptCondition.HP, SodaScriptCondition.MP, SodaScriptCondition.TEAM_ALIVE, SodaScriptCondition.TEAM_HP, SodaScriptCondition.STATUS, SodaScriptCondition.POSITION, SodaScriptCondition.ANY }; allowedConditionsForTarget[SodaScriptTarget.SELF] = new SodaScriptCondition[] { SodaScriptCondition.HP, SodaScriptCondition.MP, SodaScriptCondition.TEAM_ALIVE, SodaScriptCondition.TEAM_HP, SodaScriptCondition.STATUS }; conditionsThatRequireAComparison = new SodaScriptCondition[] { SodaScriptCondition.HP, SodaScriptCondition.MP, SodaScriptCondition.TEAM_ALIVE, SodaScriptCondition.TEAM_HP, SodaScriptCondition.RANK, SodaScriptCondition.STATUS, SodaScriptCondition.POSITION }; allComparisons = new SodaScriptComparison[] { SodaScriptComparison.GREATER_THAN, SodaScriptComparison.LESS_THAN, SodaScriptComparison.EQUALS, SodaScriptComparison.NOT_EQUALS }; justEqualsComparison = new SodaScriptComparison[] { SodaScriptComparison.EQUALS, SodaScriptComparison.NOT_EQUALS }; greaterOrLessThanComparison = new SodaScriptComparison[] { SodaScriptComparison.LESS_THAN, SodaScriptComparison.GREATER_THAN }; /********************************************************************************************************************** * DATA AND LABELS FOR COMPARISON VALUES THAT BELONG TO SPECIFIC CONDITIONS * ******************************************************************************************************************** */ string[] zeroToOneHundred = GenerateNumericDataList(0, 100, 5); string[] zeroToSix = GenerateNumericDataList(0, 6, 1); string[] oneToSix = GenerateNumericDataList(1, 6, 1); comparisonValuesForCondition = new Dictionary <SodaScriptCondition, string[]>(); comparisonValuesForCondition[SodaScriptCondition.HP] = zeroToOneHundred; comparisonValuesForCondition[SodaScriptCondition.MP] = zeroToOneHundred; comparisonValuesForCondition[SodaScriptCondition.TEAM_ALIVE] = zeroToSix; comparisonValuesForCondition[SodaScriptCondition.POSITION] = oneToSix; comparisonValuesForCondition[SodaScriptCondition.TEAM_HP] = zeroToOneHundred; EnemyRank[] ranks = new EnemyRank[] { EnemyRank.NORM, EnemyRank.MBOS, EnemyRank.BOSS, EnemyRank.DBOS }; comparisonValuesForCondition[SodaScriptCondition.RANK] = ranks.Select(d => d.ToString()).ToArray <string>(); StatusEffectCategory[] effectCategories = new StatusEffectCategory[] { StatusEffectCategory.POSITIVE, StatusEffectCategory.NEGATIVE, StatusEffectCategory.NONE }; comparisonValuesForCondition[SodaScriptCondition.STATUS] = effectCategories.Select(d => d.ToString()).ToArray <string>(); /********************************************************************************************************************** * SKILL CATEGORIES AND IDS * ******************************************************************************************************************** */ USER_ALLOWED_SKILL_CATEGORIES = new SodaScriptSkillCategory[] { SodaScriptSkillCategory.DEFAULT, SodaScriptSkillCategory.STRONGEST_ATTACK, SodaScriptSkillCategory.STRONGEST_GROUP_ATTACK, SodaScriptSkillCategory.STRONGEST_SINGLE_TARGET_ATTACK, SodaScriptSkillCategory.STRONGEST_HEAL, SodaScriptSkillCategory.STRONGEST_GROUP_HEAL, SodaScriptSkillCategory.ANY_BUFF, SodaScriptSkillCategory.ANY_DEBUFF, SodaScriptSkillCategory.ANY, SodaScriptSkillCategory.SPECIFIC }; //this array is locally scoped, we only use it to derive more specific lists //defend is not included here, it is a special case added later string[] userAllowedSkillIds = new string[] { SkillId.SWIFT_METAL, SkillId.BIOHAZARD, SkillId.FIRST_AID, SkillId.HEAL }; allowedSkillIdsForTarget = new Dictionary <SodaScriptTarget, string[]>(); //build out the lists/arrays Skill curSkill; List <string> allowedEnemySkillIds = new List <string>(); List <string> allowedAllySkillIds = new List <string>(); List <string> allowedSelfSkillIds = new List <string>(); for (int i = 0; i < userAllowedSkillIds.Length; i++) { curSkill = Skill.GetSkill(userAllowedSkillIds[i]); if (curSkill.isFriendly) { allowedAllySkillIds.Add(curSkill.id); if (curSkill.allowsSelfTarget) { allowedSelfSkillIds.Add(curSkill.id); } } else { allowedEnemySkillIds.Add(curSkill.id); } } //make sure to add "defend" for all categories allowedEnemySkillIds.Add(SkillId.DEFEND); allowedAllySkillIds.Add(SkillId.DEFEND); allowedSelfSkillIds.Add(SkillId.DEFEND); allowedSkillIdsForTarget[SodaScriptTarget.ENEMY] = allowedEnemySkillIds.ToArray <string>(); allowedSkillIdsForTarget[SodaScriptTarget.ALLY] = allowedAllySkillIds.ToArray <string>(); allowedSkillIdsForTarget[SodaScriptTarget.SELF] = allowedSelfSkillIds.ToArray <string>(); }