public bool EnemyFitsSpawnPointRequirements(EnemyCharacterData e) { bool isAllowedRank = e.rank == allowedRank; bool isAllowedSize = (allowedSizes & e.size) == e.size; return(isAllowedRank && isAllowedSize); }
protected override void ExpandFromPrototype() { Init(); EnemyCharacterData prototype = (EnemyCharacterData)Get(id); prototype.CopyPrototypeValuesToInstance(this); }
void SpawnEnemy() { Debug.Log("spawnEnemy"); GameObject go = Instantiate <GameObject>(enemyPrefap, transform.position + Vector3.right * Random.Range(-4.0f, 4.0f) + Vector3.up * Random.Range(-4.0f, 4.0f), Quaternion.identity, transform); go.name = "enemy"; EnemyCharacter ecScript = go.GetComponent <EnemyCharacter>(); EnemyCharacterData newEnemyData = new EnemyCharacterData { maxHp = 15, curHp = 15, atk = 2, atkSpeed = 1.5f, atkRange = 0.5f, def = 0, name = "enemy_cat1" }; ecScript.EnemyData = newEnemyData; BattleManager.Instance.enemyList.Add(go); }
/// <summary> /// InspectorのGUIを更新 /// </summary> public override void OnInspectorGUI() { //元のInspector部分を表示 base.OnInspectorGUI(); //ボタンを表示 if (GUILayout.Button("Update")) { EnemyCharacterDataList dataList = target as EnemyCharacterDataList; EnemyCharacterData data = Resources.Load <EnemyCharacterData>("Data/EnemyCharacterData"); foreach (var character in dataList.EnemyCharacters) { if (data.EnemyCharacters.ContainsKey(character.Id)) { data.EnemyCharacters[character.Id] = character; } else { data.EnemyCharacters.Add(character.Id, character); } } EditorUtility.SetDirty(data); AssetDatabase.SaveAssets(); } }
public override CharacterData GetCopy() { EnemyCharacterData copy = new EnemyCharacterData(); copy.Init(); copy.SetId(id); CopyPrototypeValuesToInstance(copy); return(copy); }
static void CheckEnemyCharacterDataAsset() { EnemyCharacterData data = Resources.Load <EnemyCharacterData>("Data/EnemyCharacterData"); foreach (var character in data.EnemyCharacters) { Debug.LogFormat("EnemyCharacter Id:{0}, Name:{1}", character.Value.Id, character.Value.Name); } }
new void Awake() { enemyData = (EnemyCharacterData)Instantiate(CharacterData); base.Awake(); Blood.Stop(); enemyData.Character.Stats.Life.OnValueChanged += new ValueChangedHandler(BloodSplatter); enemyData.Character.Stats.Life.OnValueChanged += new ValueChangedHandler(PlayDamagedSound); enemyData.Character.OnCombatSkillUsed += new CombatSkillUsedHandler(PlayAttackSound); enemyData.Character.OnStateChanged += new StateChangedHandler(PlayDefeatedSound); }
public override void CopyPrototypeValuesToInstance(CharacterData inInstance) { base.CopyPrototypeValuesToInstance(inInstance); EnemyCharacterData ecd = (EnemyCharacterData)inInstance; ecd.SetStorageId(storageId); ecd.SetRankAndSize(rank, size); ecd.SetSpawnValues(spawnRate, areaSpawnRange.min, areaSpawnRange.max); ecd.SetItemDrops(dropRate, itemDrops); ecd.SetVisualValues(fps, frames, shadowSize, shadowOffset, fadeAmt); ecd.SetFlightValue(flyHeight, flySpeed); ecd.SetProjectileOffset(projectileSpawnOffset); ecd.SetVariableTargetPreference(variableTargetPreference); ecd.spawnAreas = spawnAreas; }
public void ChangeRandomSpawnTo(EnemyCharacterData inCharacter) { spawnPoints.GetRandomElement().characterId = inCharacter.id; }
private void EarnLootForCharacter(CharacterData inCharacter) { //REMOVED: local stat reporting if (inCharacter is EnemyCharacterData) { EnemyCharacterData enemy = (EnemyCharacterData)inCharacter; LootBundle enemyLoot = PoolManager.poolLootBundles.GetNext(); //REMOVED: local stat reporting //only earn gold if the enemy isn't ore if (!enemy.isOre) { long goldDrop = enemy.GetGoldValue(); goldDrop = adventure.BoostGoldByActiveMultipliers(goldDrop, true); enemyLoot.AddGold(goldDrop); } //were they holding essence? if (enemy.hasEssence) { long baseEssence = enemy.GetEssence(); long extraEssence = 0; //if the last skill used was strike, and it was from a player character, and they have an essence reaver equipped, +1 essence if ((activeSkillCommand.skill.id == SkillId.STRIKE || activeSkillCommand.skill.id == SkillId.DUAL_STRIKE) && activeSkillCommand.source is PlayerCharacterData) { PlayerCharacterData pcd = (PlayerCharacterData)activeSkillCommand.source; int numEssenceReaversEquipped = pcd.NumItemOrVariantEquipped(ItemId.ESSENCE_REAVER); //if the skill was a regular strike make sure we cap this back to 1: even if the character has two equipped they only get credit for both if dual strike was used if (activeSkillCommand.skill.id == SkillId.STRIKE && numEssenceReaversEquipped > 1) { numEssenceReaversEquipped = 1; } if (numEssenceReaversEquipped > 0) { extraEssence += (long)(baseEssence * (numEssenceReaversEquipped * .15)); } } //check for essence boost from cook if (adventure.nextEnemyEssenceBoostPercent > 0) { float extraFraction = (adventure.nextEnemyEssenceBoostPercent / 100f); extraEssence += (long)(baseEssence * extraFraction); adventure.nextEnemyEssenceBoostPercent = 0; } enemyLoot.AddEssence(baseEssence + extraEssence); } int dropChance = enemy.dropRate; //the default drop rate for enemies is currently 1 in 9 //100 item find = an extra 10 drop chance (max 10) int additionalDropChance = playerTeam.teamItemFindBonus / 10; if (additionalDropChance > 10) { additionalDropChance = 10; } dropChance -= additionalDropChance; if (dropChance < 1) { dropChance = 1; } if (dropChance != 0) { //int roll = UnityEngine.Random.Range(1, dropChance); if (Utils.OneIn(dropChance)) { string itemDropId = ""; //chance to drop an item from this area. otherwise drop the enemy's material bool enemyDropsAreaItem = Utils.PercentageChance(33); if (enemy.dropRate == 1 || enemy.isOre) { enemyDropsAreaItem = false; //ore always drops its material, and a native drop rate of "1" means the enemy is always meant to drop their item (1 in 1 chance) } if (enemy.HasItemDrops()) { if (enemyDropsAreaItem) { itemDropId = adventure.RollItemForArea(); } else { itemDropId = enemy.GetRandomItemDrop(); } } else { if (enemyDropsAreaItem) { itemDropId = adventure.RollItemForArea(); } else { //no materials and no chance of area item drop? they get NOTHING } } if (itemDropId != "") { int dropQuantity = 1; if (enemy.isOre) { dropQuantity += adventure.nextOreBonusDrops; adventure.nextOreBonusDrops = 0; } enemyLoot.AddLoot(LootType.ITEM, itemDropId, dropQuantity); } } } int keysEarned = 0; if (curFile.FlagIsSet(Flag.SEEN_ADVENTURE_KEY)) { if (enemy.rank == EnemyRank.MBOS || enemy.rank == EnemyRank.BOSS) { int chance = 0; if (adventure.battleNum < 100) { chance = 15; } else if (adventure.battleNum < 200) { chance = 10; } else if (adventure.battleNum < 250) { chance = 5; } if (enemy.rank == EnemyRank.BOSS) { chance += 10; } chance += adventure.playerTeam.teamKeyBonus; //chance currently caps at 70% if (chance > 70) { chance = 70; } if (Utils.PercentageChance(chance)) { keysEarned++; } } } else { //is it time to give them their first key? if (adventure.battleNum >= 25 && enemy.rank == EnemyRank.MBOS && curFile.FlagIsSet(Flag.SEEN_ALT_PATH) && !adventure.isInteractiveCutscene) { keysEarned = 1; } } //chance to earn an enigmatic fragment/remnant? if (enemy.tempered && Utils.OneIn(100)) { enemyLoot.AddLoot(LootType.ITEM, ItemId.ENIGMATIC_SHARD, 1); } //report what loot was earned if (EEnemyLootEarned != null) { EEnemyLootEarned(inCharacter, enemyLoot, keysEarned); } PoolManager.Recycle(enemyLoot); } }
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 EnemyCharacter(EnemyCharacterData data, GameSession session) : base(data, session) { m_enemyData = data; }
public void ResolveEffects(Adventure inAdventure) { if (!wasEvaded) { //update most recent source of damage to target target.UpdateMostRecentSourceOfDamage(source.name, skill.id, false, wasBackAttack); target.stats.Add(statChanges); StatusEffect curEffect; int numStatusNegative = 0; int numStatusResisted = 0; for (int i = 0; i < statusEffects.Count; i++) { curEffect = statusEffects[i]; if (curEffect.IsNegative()) { numStatusNegative++; if (target.HasItemToPreventStatusEffect(curEffect.type) || target.PassesStatusResistCheck(curEffect.type)) { numStatusResisted++; curEffect.MarkAsResisted(); } else { target.ApplyStatusEffect(curEffect); } } else { target.ApplyStatusEffect(curEffect); } } int numStatusNegativeReceived = numStatusNegative - numStatusResisted; //REMOVED: tracking/recording stats related to status effects if (numStatusNegative > 0 && numStatusNegative == numStatusResisted) { resistedAllNegativeStatuses = true; } //clear the resisted ones statusEffects.RemoveAll(e => e.wasResisted); target.stats.EnforceNonzeroForKeys(statChanges.GetKeys()); target.stats.EnforceLimits(); //turn target around if (turnedTargetAround) { target.FlipDirection(); } //item earned on hit? if (itemIdEarnedOnHit != null) { inAdventure.AddLoot(new Loot(LootType.ITEM, itemIdEarnedOnHit, 1)); } //stolen loot? if (stolenLoot != null) { inAdventure.AddLootBundle(stolenLoot); } //exhaustion if (turnsExhaustedSourceFor > 0) { source.SetExhaustedTurns(turnsExhaustedSourceFor); } //autocrits? if (autocritsGiven > 0) { target.SetAutoCrits(autocritsGiven); } //huntress capture? if (!target.isOre && source.id == CharId.HUNTRESS && target.IsInFaction(Faction.ENEMY) && target.species == Species.CREATURE) { if (target.stats.Get(Stat.hp) == 0) { wasHuntressCapture = true; EnemyCharacterData ecd = (EnemyCharacterData)target; //Main.services.saveManager.currentFile.IncrementHuntressCaptures(ecd.storageId); } } } }
public static void CreateEnemyCharacters() { enemyCollection = new Dictionary <string, EnemyCharacterData>(); //use this line to load from a json file //EnemyCharacterMap map = Utils.LoadJsonFromPath<EnemyCharacterMap>(inPath); /* * {"id":"1:rat", "area": "CAVERNS|JAIL", "rank":"NORM", "size": "MD", "base_stats" : ["hp=2", "atk=1", "spd=default"], "spawn_rate": 1, "area_spawn_range": "0-50", "drop_rate":"3", "drops": "6", "fps":4, "frames":3, "shadow_size": 7, "shadow_offset":0, "fly_height": 0, "fly_speed": 0, "projectile_spawn_offset":"0,0", "fade_amt":0, "flags": "CANT_STRIKE", "variable_target_preference":1, "skills":"CLAW"}, * {"id":"11:tunneler", "area": "CAVERNS", "rank":"MBOS", "size": "LG", "base_stats" : ["hp=8", "atk=2", "spd=default"], "spawn_rate": 1, "area_spawn_range": "0-50", "drop_rate":"1", "drops": "3", "fps":4, "frames":3, "shadow_size": 0, "shadow_offset":0, "fly_height": 0, "fly_speed": 0, "projectile_spawn_offset":"0,0", "fade_amt":0, "flags": "IN_GROUND", "variable_target_preference":1, "skills":""}, * {"id":"13:dragon", "area": "CAVERNS", "rank":"BOSS", "size": "XL", "base_stats" : ["hp=28", "atk=3", "spd=default"], "spawn_rate": 1, "area_spawn_range": "0-50", "drop_rate":"50", "drops": "55", "fps":4, "frames":3, "shadow_size": 23, "shadow_offset":0, "fly_height": 30, "fly_speed": 10, "projectile_spawn_offset":"0,0", "fade_amt":0, "flags": "", "variable_target_preference":1, "skills":"METEOR"}, */ //instead, create the data manually var ratData = new EnemyCharacterRow() { id = "1:" + EnemyId.RAT, area = "CAVERNS|JAIL", rank = "NORM", size = "MD", base_stats = new string[] { "hp=2", "atk=1", "spd=default" }, spawn_rate = 1, area_spawn_range = "0-50", drop_rate = "3", drops = "6", flags = "", variable_target_preference = 1, skills = "" }; var tunnelerData = new EnemyCharacterRow() { id = "11:" + EnemyId.TUNNELER, area = "CAVERNS", rank = "MBOS", size = "MD", base_stats = new string[] { "hp=8", "atk=2", "spd=default" }, spawn_rate = 1, area_spawn_range = "0-50", drop_rate = "1", drops = "", flags = "IN_GROUND", variable_target_preference = 1, skills = "" }; var dragonData = new EnemyCharacterRow() { id = "13:" + EnemyId.DRAGON, area = "CAVERNS", rank = "BOSS", size = "MD", base_stats = new string[] { "hp=28", "atk=3", "spd=default" }, spawn_rate = 1, area_spawn_range = "0-50", drop_rate = "50", drops = "", flags = "", variable_target_preference = 1, skills = "METEOR" }; EnemyCharacterMap map = new EnemyCharacterMap(); map.enemy_characters = new EnemyCharacterRow[] { ratData, tunnelerData, dragonData }; EnemyCharacterRow row; EnemyCharacterData tempCharacter; string[] idPieces; for (int i = 0; i < map.enemy_characters.Length; i++) { row = map.enemy_characters[i]; tempCharacter = new EnemyCharacterData(); tempCharacter.Init(); idPieces = row.id.Split(':'); int storageId = int.Parse(idPieces[0]); tempCharacter.SetId(idPieces[1]); tempCharacter.SetStorageId(storageId); tempCharacter.SetSpecies(Species.CREATURE); tempCharacter.SetBaseFaction(Faction.ENEMY); Stats.ParseArrayIntoStatObject(row.base_stats, tempCharacter.baseStats); tempCharacter.spawnAreas = Utils.ParseStringToFlagEnum <AdventureArea>(row.area, '|'); EnemyRank parsedRank = (EnemyRank)Enum.Parse(typeof(EnemyRank), row.rank); EnemySize parsedSize = (EnemySize)Enum.Parse(typeof(EnemySize), row.size); tempCharacter.SetRankAndSize(parsedRank, parsedSize); int spawnRate = row.spawn_rate; string[] rangeInfo = row.area_spawn_range.Split('-'); if (rangeInfo.Length != 2) { throw new Exception("Spawn range for enemy " + row.id + " is not exactly two elements"); } int minSpawnRange = int.Parse(rangeInfo[0]); int maxSpawnRange = int.Parse(rangeInfo[1]); tempCharacter.SetSpawnValues(spawnRate, minSpawnRange, maxSpawnRange); string[] drops = row.drops == "" ? new string[] { } : row.drops.Split('|'); for (int j = 0; j < drops.Length; j++) { if (!ItemId.IsValid(drops[j])) { throw new Exception("Item drop id '" + drops[j] + "' is not valid"); } } int dropRate = 9; if (row.drop_rate != "default") { dropRate = int.Parse(row.drop_rate); } tempCharacter.SetItemDrops(dropRate, drops); tempCharacter.SetVisualValues(row.fps, row.frames, row.shadow_size, row.shadow_offset, row.fade_amt); tempCharacter.SetFlightValue(row.fly_height, row.fly_speed); CharacterFlags flags = Utils.ParseStringToFlagEnum <CharacterFlags>(row.flags, ','); flags |= CharacterFlags.CANT_DEFEND; tempCharacter.SetFlags(flags); tempCharacter.SetVariableTargetPreference(row.variable_target_preference); if (row.skills.Length > 0) { tempCharacter.SetBaseSkills(row.skills.Split(',')); } //was the cant strike flag set? only allow this if the enemy has at least one other skill that costs 0 mp if (tempCharacter.FlagIsSet(CharacterFlags.CANT_STRIKE)) { if (tempCharacter.baseSkills[0].mpCost != 0) { throw new Exception("0 mp Default skill not provided for enemy " + row.id + " (cant_strike flag set)"); } } enemyCollection.Add(tempCharacter.id, tempCharacter); characterCollection.Add(tempCharacter.id, tempCharacter); } enemyCollectionList = enemyCollection.Values.ToList(); if (enemyCollection.Count > GameContext.MAX_NUM_ENEMIES_SUPPPORTED) { throw new Exception("Loaded " + enemyCollection.Count + " enemy types but game only allows a max of " + GameContext.MAX_NUM_ENEMIES_SUPPPORTED); } }