public static void CreateItems() { items = new Dictionary <string, Item>(); //use this line to load from a json file //ItemMap map = Utils.LoadJsonFromPath<ItemMap>("data/item_data"); /* * {"id":"3:wooden_sword", "type":"WEAPON", "stats" : ["atk=2", "crit_chance=1","crit_bonus=10"], "spawn_rate":"15", "min_spawn_lvl":"5", "max_spawn_lvl":"0", "area":"CAVERNS", "attached_skill_ids":"", "season":"ALL", "slots": [], "flags":"", "explicit_rarity":"", "explicit_value":0}, * {"id":"4:buckler", "type":"SHIELD", "stats" : ["hp=2"], "spawn_rate":"15", "min_spawn_lvl":"5", "max_spawn_lvl":"0", "area":"CAVERNS", "attached_skill_ids":"", "season":"ALL", "slots": [], "flags":"", "explicit_rarity":"", "explicit_value":0}, * {"id":"5:leather_armor", "type":"ARMOR", "stats" : ["hp=1"], "spawn_rate":"20", "min_spawn_lvl":"5", "max_spawn_lvl":"0", "area":"CAVERNS", "attached_skill_ids":"", "season":"ALL", "slots": [], "flags":"", "explicit_rarity":"", "explicit_value":0}, * */ //instead, create the data manually var woodenSwordData = new ItemRow() { id = "3:" + ItemId.WOODEN_SWORD, type = "WEAPON", stats = new string[] { "atk=2", "crit_chance=1", "crit_bonus=10" }, spawn_rate = 15, min_spawn_lvl = 5, max_spawn_lvl = 0, area = "CAVERNS", attached_skill_ids = "", slots = new string[] { }, flags = "" }; var woodenShieldData = new ItemRow() { id = "4:" + ItemId.BUCKLER, type = "SHIELD", stats = new string[] { "hp=2" }, spawn_rate = 15, min_spawn_lvl = 5, max_spawn_lvl = 0, area = "CAVERNS", attached_skill_ids = "", slots = new string[] { }, flags = "" }; var leatherArmorData = new ItemRow() { id = "5:" + ItemId.LEATHER_ARMOR, type = "ARMOR", stats = new string[] { "hp=1" }, spawn_rate = 20, min_spawn_lvl = 5, max_spawn_lvl = 0, area = "CAVERNS", attached_skill_ids = "", slots = new string[] { }, flags = "" }; var peltData = new ItemRow() { id = "6:" + ItemId.PELT, type = "RESOURCE", stats = new string[] { }, spawn_rate = 0, min_spawn_lvl = 0, max_spawn_lvl = 0, area = "CAVERNS", attached_skill_ids = "", slots = new string[] { }, flags = "" }; ItemMap map = new ItemMap(); map.items = new ItemRow[] { woodenSwordData, woodenShieldData, leatherArmorData, peltData }; ItemRow row; Item tempItem; string[] idPieces; string id; for (int i = 0; i < map.items.Length; i++) { row = map.items[i]; //item ids are provied in a number:name format. the name is only present in the data file for readability, so we need to discard it idPieces = row.id.Split(':'); id = idPieces[0]; if (!ItemId.IsValid(id)) { throw new Exception("Item id '" + row.id + "' does not exist"); } tempItem = new Item(); tempItem.Init(); tempItem.SetId(id); tempItem.DeriveBaseAndStorageId(); ItemType parsedType = (ItemType)Enum.Parse(typeof(ItemType), row.type); tempItem.SetType(parsedType); Stats.ParseArrayIntoStatObject(row.stats, tempItem.baseStats); AdventureArea parsedAreas = Utils.ParseStringToFlagEnum <AdventureArea>(row.area, '|'); tempItem.SetSpawnInfo(row.spawn_rate, row.min_spawn_lvl, row.max_spawn_lvl, parsedAreas); if (string.IsNullOrEmpty(row.explicit_rarity)) { tempItem.DeriveRarity(); } else { tempItem._rarity = (Rarity)Enum.Parse(typeof(Rarity), row.explicit_rarity); } char[] separators = new char[',']; //must define a separator array so that we can pass in the stringsplit option param tempItem.attachedSkillIds = row.attached_skill_ids.Split(separators, StringSplitOptions.RemoveEmptyEntries); string curId; for (int j = 0; j < tempItem.attachedSkillIds.Length; j++) { curId = tempItem.attachedSkillIds[j]; if (!SkillId.IsValid(curId)) { throw new Exception(curId + " is not a valid skill id to attach to an item"); } } int numSlots = row.slots.Length; tempItem.slotPositions = new Vector2[numSlots]; string[] coords; for (int j = 0; j < numSlots; j++) { coords = row.slots[j].Split(','); tempItem.slotPositions[j] = new Vector2(float.Parse(coords[0]), float.Parse(coords[1])); } tempItem.flags = Utils.ParseStringToFlagEnum <ItemFlags>(row.flags, ','); if (row.explicit_value == 0) { tempItem.CalculateValue(); } else { tempItem.value = row.explicit_value; } items.Add(tempItem.id, tempItem); } //record the number of un-leveled items numBasicItemsInGame = items.Count; //create leveled items itemLevelBoosts = new Stats(); itemLevelBoosts.Set(Stat.hp, 3); itemLevelBoosts.Set(Stat.mp, 4); itemLevelBoosts.Set(Stat.atk, 2); itemLevelBoosts.Set(Stat.crit_chance, 1); itemLevelBoosts.Set(Stat.crit_bonus, 1); itemLevelBoosts.Set(Stat.dmg_reduction, 1); itemLevelBoosts.Set(Stat.evade, 1); itemLevelBoosts.Set(Stat.gold_find, 3); itemLevelBoosts.Set(Stat.item_find, 2); itemLevelBoosts.Set(Stat.magic_boost, 2); itemLevelBoosts.Set(Stat.phys_boost, 2); itemLevelBoosts.Set(Stat.hp_boost, 1); itemLevelBoosts.Set(Stat.mp_boost, 1); itemLevelBoosts.Set(Stat.atk_boost, 1); itemLevelBoosts.Set(Stat.dmg_reflection, 2); itemLevelBoosts.Set(Stat.mastery_xp_boost, 2); itemTypesThatLevelUp = ItemType.WEAPON | ItemType.ARMOR | ItemType.SHIELD; List <Item> existingItems = items.Values.ToList(); Item newItem; int spawnRange = 100; for (int i = 0; i < existingItems.Count; i++) { tempItem = existingItems[i]; if (tempItem.IsTypeThatLevelsUp()) { //TODO manually exclude some stuff from leveling up if (tempItem.id == ItemId.APHOTIC_BLADE || tempItem.id == ItemId.MOP || tempItem.id == ItemId.IRON_SKILLET) { continue; } //force all items to have a max spawn level of min + 100 tempItem._spawnMaxLevel = tempItem.spawnMinLevel + spawnRange; //right now just levels 2 to the "max" for (int j = 2; j <= GameContext.MAX_ITEM_LEVEL_WITHOUT_ENHANCING; j++) { newItem = tempItem.GetCopy(); newItem.BoostItemToLevel(j); items.Add(newItem.id, newItem); //once item is level 5 or higher it can ALWAYS spawn, otherwise limit it if (j > 4) { newItem._spawnMaxLevel = 0; } else { newItem._spawnMaxLevel = newItem.spawnMinLevel + spawnRange; } } } } //copy ALL items into a parallel list for convenience itemCollectionList = items.Values.ToList(); //create specialized lists foodItemIds = new List <string>() { ItemId.APPLE, ItemId.BACON, ItemId.CARROT, ItemId.CARAMEL, ItemId.EGGPLANT, ItemId.MUSHROOM, ItemId.RADISH }; //build this dict to make status effect prevention checks much faster statusEffectToPreventionFlagMap = new Dictionary <StatusEffectType, ItemFlags>(); statusEffectToPreventionFlagMap[StatusEffectType.BURN] = ItemFlags.PREVENTS_BURN; statusEffectToPreventionFlagMap[StatusEffectType.STONE] = ItemFlags.PREVENTS_STONE; statusEffectToPreventionFlagMap[StatusEffectType.SPEED_DOWN] = ItemFlags.PREVENTS_SPEED_DOWN; statusEffectToPreventionFlagMap[StatusEffectType.SLEEP] = ItemFlags.PREVENTS_SLEEP; }
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); } }