diff --git a/aurorastation.dme b/aurorastation.dme index 818854107fd..fc29ab16927 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -20,6 +20,7 @@ #include "code\__defines\_macros.dm" #include "code\__defines\admin.dm" #include "code\__defines\atmos.dm" +#include "code\__defines\battle_monsters.dm" #include "code\__defines\callback.dm" #include "code\__defines\chemistry.dm" #include "code\__defines\damage_organs.dm" @@ -153,6 +154,7 @@ #include "code\controllers\subsystems\ao.dm" #include "code\controllers\subsystems\arrivals.dm" #include "code\controllers\subsystems\assets.dm" +#include "code\controllers\subsystems\battle_monsters.dm" #include "code\controllers\subsystems\cargo.dm" #include "code\controllers\subsystems\chemistry.dm" #include "code\controllers\subsystems\effects.dm" @@ -1139,6 +1141,17 @@ #include "code\modules\awaymissions\pamphlet.dm" #include "code\modules\awaymissions\trigger.dm" #include "code\modules\awaymissions\zlevel.dm" +#include "code\modules\battlemonsters\datum_core.dm" +#include "code\modules\battlemonsters\datum_elements.dm" +#include "code\modules\battlemonsters\datum_monsters.dm" +#include "code\modules\battlemonsters\datum_spells.dm" +#include "code\modules\battlemonsters\datum_titles.dm" +#include "code\modules\battlemonsters\datum_traps.dm" +#include "code\modules\battlemonsters\items\card.dm" +#include "code\modules\battlemonsters\items\core.dm" +#include "code\modules\battlemonsters\items\deck.dm" +#include "code\modules\battlemonsters\items\wrapped.dm" +#include "code\modules\battlemonsters\items\furniture\dueling_area.dm" #include "code\modules\blob\blob.dm" #include "code\modules\cargo\bounty.dm" #include "code\modules\cargo\export_scanner.dm" diff --git a/code/__defines/battle_monsters.dm b/code/__defines/battle_monsters.dm new file mode 100644 index 00000000000..b3737dae408 --- /dev/null +++ b/code/__defines/battle_monsters.dm @@ -0,0 +1,74 @@ +//Rarity +#define BATTLE_MONSTERS_RARITY_COMMON 100 +#define BATTLE_MONSTERS_RARITY_UNCOMMON 25 +#define BATTLE_MONSTERS_RARITY_RARE 5 +#define BATTLE_MONSTERS_RARITY_MYTHICAL 2.5 +#define BATTLE_MONSTERS_RARITY_LEGENDARY 1 + +//Card Types +#define BATTLE_MONSTERS_CARDTYPE_MONSTER 0 +#define BATTLE_MONSTERS_CARDTYPE_TRAP 1 +#define BATTLE_MONSTERS_CARDTYPE_SPELL 1 + +//Attack Types +#define BATTLE_MONSTERS_ATTACKTYPE_NONE 0x0 +#define BATTLE_MONSTERS_ATTACKTYPE_SPELLCASTER 0x1 +#define BATTLE_MONSTERS_ATTACKTYPE_SWORDSMAN 0x2 +#define BATTLE_MONSTERS_ATTACKTYPE_ARMY 0x4 +#define BATTLE_MONSTERS_ATTACKTYPE_CLAWS 0x8 +#define BATTLE_MONSTERS_ATTACKTYPE_CLUB 0x10 +#define BATTLE_MONSTERS_ATTACKTYPE_TEETH 0x20 +#define BATTLE_MONSTERS_ATTACKTYPE_SHIELD 0x40 + +//Defense Types +#define BATTLE_MONSTERS_DEFENSETYPE_NONE 0x0 +#define BATTLE_MONSTERS_DEFENSETYPE_HUMAN 0x1 +#define BATTLE_MONSTERS_DEFENSETYPE_GOD 0x2 +#define BATTLE_MONSTERS_DEFENSETYPE_MACHINE 0x4 +#define BATTLE_MONSTERS_DEFENSETYPE_CREATURE 0x8 +#define BATTLE_MONSTERS_DEFENSETYPE_FLYING 0x10 +#define BATTLE_MONSTERS_DEFENSETYPE_COLOSSUS 0x20 +#define BATTLE_MONSTERS_DEFENSETYPE_REPTILE 0x40 +#define BATTLE_MONSTERS_DEFENSETYPE_FELINE 0x80 +#define BATTLE_MONSTERS_DEFENSETYPE_INSECT 0x100 +#define BATTLE_MONSTERS_DEFENSETYPE_DEMON 0x200 + + +#define BATTLE_MONSTERS_DEFENSETYPE_ANTMAN BATTLE_MONSTERS_DEFENSETYPE_INSECT | BATTLE_MONSTERS_DEFENSETYPE_HUMAN +#define BATTLE_MONSTERS_DEFENSETYPE_CATMAN BATTLE_MONSTERS_DEFENSETYPE_FELINE | BATTLE_MONSTERS_DEFENSETYPE_HUMAN +#define BATTLE_MONSTERS_DEFENSETYPE_LIZARDMAN BATTLE_MONSTERS_DEFENSETYPE_REPTILE | BATTLE_MONSTERS_DEFENSETYPE_HUMAN +#define BATTLE_MONSTERS_DEFENSETYPE_DEMIGOD BATTLE_MONSTERS_DEFENSETYPE_GOD | BATTLE_MONSTERS_DEFENSETYPE_HUMAN +#define BATTLE_MONSTERS_DEFENSETYPE_CYBORG BATTLE_MONSTERS_DEFENSETYPE_MACHINE | BATTLE_MONSTERS_DEFENSETYPE_HUMAN +#define BATTLE_MONSTERS_DEFENSETYPE_HYBRID BATTLE_MONSTERS_DEFENSETYPE_CREATURE | BATTLE_MONSTERS_DEFENSETYPE_HUMAN + +#define BATTLE_MONSTERS_DEFENSETYPE_GIANT BATTLE_MONSTERS_DEFENSETYPE_COLOSSUS | BATTLE_MONSTERS_DEFENSETYPE_HUMAN + +#define BATTLE_MONSTERS_DEFENSETYPE_DRAGON BATTLE_MONSTERS_DEFENSETYPE_REPTILE | BATTLE_MONSTERS_DEFENSETYPE_FLYING +#define BATTLE_MONSTERS_DEFENSETYPE_DRAGONHYBRID BATTLE_MONSTERS_DEFENSETYPE_DRAGON | BATTLE_MONSTERS_DEFENSETYPE_HUMAN +#define BATTLE_MONSTERS_DEFENSETYPE_FERALDRAGON BATTLE_MONSTERS_DEFENSETYPE_CREATURE | BATTLE_MONSTERS_DEFENSETYPE_DRAGON +#define BATTLE_MONSTERS_DEFENSETYPE_GIANT_DRAGON BATTLE_MONSTERS_DEFENSETYPE_COLOSSUS | BATTLE_MONSTERS_DEFENSETYPE_DRAGON + +//Element Types +#define BATTLE_MONSTERS_ELEMENT_NONE 0x0 +#define BATTLE_MONSTERS_ELEMENT_NEUTRAL 0x1 +#define BATTLE_MONSTERS_ELEMENT_FIRE 0x2 +#define BATTLE_MONSTERS_ELEMENT_ENERGY 0x4 +#define BATTLE_MONSTERS_ELEMENT_WATER 0x8 +#define BATTLE_MONSTERS_ELEMENT_ICE 0x10 +#define BATTLE_MONSTERS_ELEMENT_EARTH 0x20 +#define BATTLE_MONSTERS_ELEMENT_STONE 0x40 +#define BATTLE_MONSTERS_ELEMENT_DARK 0x80 +#define BATTLE_MONSTERS_ELEMENT_LIGHT 0x100 +#define BATTLE_MONSTERS_ELEMENT_ALL 0xFFFF + +//MISC +#define BATTLE_MONSTERS_FORMAT_STAR "" + + +//Generation Helpers +#define BATTLE_MONSTERS_GENERATION_NAME 0x1 +#define BATTLE_MONSTERS_GENERATION_DESCRIPTION 0x2 +#define BATTLE_MONSTERS_GENERATION_SPECIALEFFECTS 0x4 +#define BATTLE_MONSTERS_GENERATION_FORM 0x8 +#define BATTLE_MONSTERS_GENERATION_STATS 0x10 +#define BATTLE_MONSTERS_GENERATION_ALL 0xFFFF //Everything diff --git a/code/controllers/subsystems/battle_monsters.dm b/code/controllers/subsystems/battle_monsters.dm new file mode 100644 index 00000000000..7609f99f552 --- /dev/null +++ b/code/controllers/subsystems/battle_monsters.dm @@ -0,0 +1,492 @@ +#define BATTLE_MONSTERS_GEN_PREFIX 1 +#define BATTLE_MONSTERS_GEN_ROOT 2 +#define BATTLE_MONSTERS_GEN_SUFFIX 3 +#define BATTLE_MONSTERS_GEN_TRAP 4 +#define BATTLE_MONSTERS_GEN_SPELL 5 + +var/datum/controller/subsystem/battle_monsters/SSbattlemonsters + +/datum/controller/subsystem/battle_monsters + name = "Battle Monsters" + init_order = SS_INIT_MISC_FIRST + flags = SS_NO_FIRE + + var/list/monster_elements + var/list/monster_roots + var/list/monster_titles + + var/list/monster_elements_rng + var/list/monster_roots_rng + var/list/monster_titles_rng + + var/list/traps + var/list/spells + + var/list/traps_rng + var/list/spells_rng + + +/datum/controller/subsystem/battle_monsters/New() + NEW_SS_GLOBAL(SSbattlemonsters) + +/datum/controller/subsystem/battle_monsters/Initialize() + GenerateDatum(BATTLE_MONSTERS_GEN_PREFIX) + GenerateDatum(BATTLE_MONSTERS_GEN_ROOT) + GenerateDatum(BATTLE_MONSTERS_GEN_SUFFIX) + GenerateDatum(BATTLE_MONSTERS_GEN_TRAP) + GenerateDatum(BATTLE_MONSTERS_GEN_SPELL) + +/datum/controller/subsystem/battle_monsters/proc/CreateCard(var/identifier,var/turf/cardloc) + var/list/splitstring = dd_text2List(identifier,",") + var/obj/item/battle_monsters/card/new_card + + if(splitstring[1] == "spell_type") + new_card = new(cardloc,null,null,null,null,splitstring[2]) + else if(splitstring[1] == "trap_type") + new_card = new(cardloc,null,null,null,splitstring[2],null) + else + new_card = new(cardloc,splitstring[1],splitstring[2],splitstring[3],null,null) + + return new_card + +/datum/controller/subsystem/battle_monsters/proc/GenerateDatum(var/generation_type) + + var/list/datum_paths + + switch(generation_type) + if(BATTLE_MONSTERS_GEN_PREFIX) + datum_paths = subtypesof(/datum/battle_monsters/element) + if(BATTLE_MONSTERS_GEN_ROOT) + datum_paths = subtypesof(/datum/battle_monsters/monster) + if(BATTLE_MONSTERS_GEN_SUFFIX) + datum_paths = subtypesof(/datum/battle_monsters/title) + if(BATTLE_MONSTERS_GEN_TRAP) + datum_paths = subtypesof(/datum/battle_monsters/trap) + if(BATTLE_MONSTERS_GEN_SPELL) + datum_paths = subtypesof(/datum/battle_monsters/spell) + + var/list/id_datum_list = list() + var/list/id_rng_list = list() + + for(var/path in datum_paths) + var/datum/battle_monsters/generated = new path() + if(!generated.id) + continue + id_datum_list[generated.id] = generated + id_rng_list[generated.id] = generated.rarity + + switch(generation_type) + if(BATTLE_MONSTERS_GEN_PREFIX) + monster_elements = id_datum_list + monster_elements_rng = id_rng_list + if(BATTLE_MONSTERS_GEN_ROOT) + monster_roots = id_datum_list + monster_roots_rng = id_rng_list + if(BATTLE_MONSTERS_GEN_SUFFIX) + monster_titles = id_datum_list + monster_titles_rng = id_rng_list + if(BATTLE_MONSTERS_GEN_TRAP) + traps = id_datum_list + traps_rng = id_rng_list + if(BATTLE_MONSTERS_GEN_SPELL) + spells = id_datum_list + spells_rng = id_rng_list + +/datum/controller/subsystem/battle_monsters/proc/GetRandomPrefix() + return FindMatchingPrefix(pickweight(monster_elements_rng)) + +/datum/controller/subsystem/battle_monsters/proc/GetRandomRoot() + return FindMatchingRoot(pickweight(monster_roots_rng)) + +/datum/controller/subsystem/battle_monsters/proc/GetRandomSuffix() + return FindMatchingSuffix(pickweight(monster_titles_rng)) + +/datum/controller/subsystem/battle_monsters/proc/GetRandomTrap() + return FindMatchingTrap(pickweight(traps_rng)) + +/datum/controller/subsystem/battle_monsters/proc/GetRandomSpell() + return FindMatchingSpell(pickweight(spells_rng)) + +/datum/controller/subsystem/battle_monsters/proc/GetRandomPrefix_Filtered(var/raremin,var/raremax) + var/list/edited_list = list() + + for(var/id in monster_elements_rng) + var/score = monster_elements_rng[id] + if(score > raremax) + continue + if(score < raremin) + continue + edited_list[id] = score + + if(edited_list.len <= 0) + edited_list = monster_elements_rng + + return FindMatchingPrefix(pickweight(edited_list)) + +/datum/controller/subsystem/battle_monsters/proc/GetRandomRoot_Filtered(var/raremin,var/raremax) + var/list/edited_list = list() + + for(var/id in monster_roots_rng) + var/score = monster_roots_rng[id] + if(score > raremax) + continue + if(score < raremin) + continue + edited_list[id] = score + + if(edited_list.len <= 0) + edited_list = monster_roots_rng + + return FindMatchingRoot(pickweight(edited_list)) + +/datum/controller/subsystem/battle_monsters/proc/GetRandomSuffix_Filtered(var/raremin,var/raremax) + var/list/edited_list = list() + + for(var/id in monster_titles_rng) + var/score = monster_titles_rng[id] + if(score > raremax) + continue + if(score < raremin) + continue + edited_list[id] = score + + if(edited_list.len <= 0) + edited_list = monster_titles_rng + + return FindMatchingSuffix(pickweight(edited_list)) + + +/datum/controller/subsystem/battle_monsters/proc/FindMatchingPrefix(var/text,var/failsafe = FALSE) + if(monster_elements[text]) + return monster_elements[text] + else if(failsafe) + return GetRandomPrefix() + else + return + +/datum/controller/subsystem/battle_monsters/proc/FindMatchingRoot(var/text,var/failsafe = FALSE) + if(monster_roots[text]) + return monster_roots[text] + else if(failsafe) + return GetRandomRoot() + else + return + +/datum/controller/subsystem/battle_monsters/proc/FindMatchingSuffix(var/text,var/failsafe = FALSE) + if(monster_titles[text]) + return monster_titles[text] + else if(failsafe) + return GetRandomSuffix() + else + return + +/datum/controller/subsystem/battle_monsters/proc/FindMatchingTrap(var/text,var/failsafe = FALSE) + if(traps[text]) + return traps[text] + else if(failsafe) + return GetRandomTrap() + else + return + +/datum/controller/subsystem/battle_monsters/proc/FindMatchingSpell(var/text,var/failsafe = FALSE) + if(spells[text]) + return spells[text] + else if(failsafe) + return GetRandomSpell() + else + return + +/datum/controller/subsystem/battle_monsters/proc/GetSpeciesGeneral(var/card_defense_type) + switch(card_defense_type) + if(BATTLE_MONSTERS_DEFENSETYPE_NONE) + return "monster" + if(BATTLE_MONSTERS_DEFENSETYPE_GIANT_DRAGON) + return "giant dragon" + if(BATTLE_MONSTERS_DEFENSETYPE_FERALDRAGON) + return "feral dragon" + if(BATTLE_MONSTERS_DEFENSETYPE_DRAGONHYBRID) + return "human-dragon hybrid" + if(BATTLE_MONSTERS_DEFENSETYPE_DRAGON) + return "dragon" + if(BATTLE_MONSTERS_DEFENSETYPE_DEMIGOD) + return "demi-god" + if(BATTLE_MONSTERS_DEFENSETYPE_CYBORG) + return "cyborg" + if(BATTLE_MONSTERS_DEFENSETYPE_HYBRID) + return "hybrid" + if(BATTLE_MONSTERS_DEFENSETYPE_CATMAN) + return "catman" + if(BATTLE_MONSTERS_DEFENSETYPE_LIZARDMAN) + return "lizardman" + if(BATTLE_MONSTERS_DEFENSETYPE_ANTMAN) + return "antman" + if(BATTLE_MONSTERS_DEFENSETYPE_GIANT) + return "colossus" + if(BATTLE_MONSTERS_DEFENSETYPE_REPTILE) + return "reptile" + if(BATTLE_MONSTERS_DEFENSETYPE_HUMAN) + return "human" + if(BATTLE_MONSTERS_DEFENSETYPE_INSECT) + return "insect" + if(BATTLE_MONSTERS_DEFENSETYPE_GOD) + return "god" + if(BATTLE_MONSTERS_DEFENSETYPE_FELINE) + return "feline" + if(BATTLE_MONSTERS_DEFENSETYPE_MACHINE) + return "machine" + if(BATTLE_MONSTERS_DEFENSETYPE_CREATURE) + return "creature" + if(BATTLE_MONSTERS_DEFENSETYPE_COLOSSUS) + return "colossus" + if(BATTLE_MONSTERS_DEFENSETYPE_FLYING) + return "winged monster" + + return "unknown" + +/datum/controller/subsystem/battle_monsters/proc/GetSpecies(card_defense_type, var/and_text = " and ") + + //This list looks odd to prevent runtime errors related to out of bounds indexes + var/list/translations = list( + "Human" = BATTLE_MONSTERS_DEFENSETYPE_HUMAN, + "God" = BATTLE_MONSTERS_DEFENSETYPE_GOD, + "Machine" = BATTLE_MONSTERS_DEFENSETYPE_MACHINE, + "Creature" = BATTLE_MONSTERS_DEFENSETYPE_CREATURE, + "Flying" = BATTLE_MONSTERS_DEFENSETYPE_FLYING, + "Colossus" = BATTLE_MONSTERS_DEFENSETYPE_COLOSSUS, + "Reptile" = BATTLE_MONSTERS_DEFENSETYPE_REPTILE, + "Feline" = BATTLE_MONSTERS_DEFENSETYPE_FELINE, + "Insect" = BATTLE_MONSTERS_DEFENSETYPE_INSECT, + "Demon" = BATTLE_MONSTERS_DEFENSETYPE_DEMON + ) + + var/list/included_elements = list() + + for(var/translation in translations) + if(!(translations[translation] & card_defense_type)) + continue + included_elements.Add(translation) + + return english_list(included_elements, nothing_text = "Monster", and_text = and_text) + +/datum/controller/subsystem/battle_monsters/proc/GetAttackType(var/card_attack_type, var/and_text = " and ") + + //This list looks odd to prevent runtime errors related to out of bounds indexes + var/list/translations = list( + "Spellcaster" = BATTLE_MONSTERS_ATTACKTYPE_SPELLCASTER, + "Warrior" = BATTLE_MONSTERS_ATTACKTYPE_SWORDSMAN, + "Commander" = BATTLE_MONSTERS_ATTACKTYPE_ARMY, + "Warrior" = BATTLE_MONSTERS_ATTACKTYPE_CLAWS, + "Warrior" = BATTLE_MONSTERS_ATTACKTYPE_TEETH, + "Warrior" = BATTLE_MONSTERS_ATTACKTYPE_CLUB, + "Defender" = BATTLE_MONSTERS_ATTACKTYPE_SHIELD + ) + + var/list/included_elements = list() + + for(var/translation in translations) + if(!(translations[translation] & card_attack_type)) + continue + if(translation in included_elements) + continue + included_elements.Add(translation) + + return english_list(included_elements, nothing_text = "Regular", and_text = and_text) + +/datum/controller/subsystem/battle_monsters/proc/GetWeapons(var/card_attack_type, var/and_text = " and ") + + //This list looks odd to prevent runtime errors related to out of bounds indexes + var/list/translations = list( + "staff" = BATTLE_MONSTERS_ATTACKTYPE_SPELLCASTER, + "sword" = BATTLE_MONSTERS_ATTACKTYPE_SWORDSMAN, + "army" = BATTLE_MONSTERS_ATTACKTYPE_ARMY, + "claws" = BATTLE_MONSTERS_ATTACKTYPE_CLAWS, + "club" = BATTLE_MONSTERS_ATTACKTYPE_CLUB, + "fangs" = BATTLE_MONSTERS_ATTACKTYPE_TEETH, + "shield" = BATTLE_MONSTERS_ATTACKTYPE_SHIELD + ) + + var/list/included_elements = list() + + for(var/translation in translations) + if(!(translations[translation] & card_attack_type)) + continue + included_elements.Add(translation) + + return english_list(included_elements, nothing_text = "fists", and_text = and_text) + +/datum/controller/subsystem/battle_monsters/proc/GetElements(var/card_elements,var/and_text = " and ") + + //This list looks odd to prevent runtime errors related to out of bounds indexes + var/list/translations = list( + "Neutral" = BATTLE_MONSTERS_ELEMENT_NEUTRAL, + "Fire" = BATTLE_MONSTERS_ELEMENT_FIRE, + "Energy" = BATTLE_MONSTERS_ELEMENT_ENERGY, + "Water" = BATTLE_MONSTERS_ELEMENT_WATER, + "Ice" = BATTLE_MONSTERS_ELEMENT_ICE, + "Earth" = BATTLE_MONSTERS_ELEMENT_EARTH, + "Stone" = BATTLE_MONSTERS_ELEMENT_STONE, + "Dark" = BATTLE_MONSTERS_ELEMENT_DARK, + "Light" = BATTLE_MONSTERS_ELEMENT_LIGHT, + ) + + var/list/included_elements = list() + + for(var/translation in translations) + if(!(translations[translation] & card_elements)) + continue + included_elements.Add(translation) + + return english_list(included_elements, nothing_text = "Neutral", and_text = and_text) + +/datum/controller/subsystem/battle_monsters/proc/GetStarLevel(var/power_rating) + return min(10,1 + round( (power_rating^1.25) * 0.00012)) + +/datum/controller/subsystem/battle_monsters/proc/FormatMonsterText(var/text,var/datum/battle_monsters/element/prefix_datum,var/datum/battle_monsters/monster/root_datum,var/datum/battle_monsters/title/suffix_datum) + + var/list/generated_stats = SSbattlemonsters.GenerateMonsterStats(prefix_datum,root_datum,suffix_datum) + + if(!generated_stats || generated_stats.len == 0) + return "Something went wrong... go bother the monsterous devs about it." + + var/list/replacements = list( + "%NAME" = generated_stats["name"], + + "%DESCRIPTION" = generated_stats["desc"], + "%SPECIAL_EFFECTS" = generated_stats["special_effects"], + + "%ELEMENT_AND" = GetElements(generated_stats["elements"]), + "%ELEMENT_OR" = GetElements(generated_stats["elements"], " or "), + "%ELEMENT_LIST" = GetElements(generated_stats["elements"], ", "), + + "%TYPE" = GetAttackType(generated_stats["attack_type"]), + "%ATTACKTYPE_LIST" = GetAttackType(generated_stats["attack_type"], ", "), + "%WEAPON_AND" = GetWeapons(generated_stats["attack_type"]), + + "%SPECIES_C" = capitalize(GetSpeciesGeneral(generated_stats["defense_type"])), + "%SPECIES_LIST" = GetSpecies(generated_stats["defense_type"], ", "), + "%SPECIES" = GetSpeciesGeneral(generated_stats["defense_type"]), + + "%ATTACK_POINTS" = generated_stats["attack_points"], + "%DEFENSE_POINTS" = generated_stats["defense_points"], + + "%STARLEVEL" = GetStarLevel(generated_stats["power"]) + ) + + for(var/word in replacements) + text = replacetext(text,word,replacements[word]) + + for(var/word in replacements)//2 passes for good measure. + text = replacetext(text,word,replacements[word]) + + return text + +/datum/controller/subsystem/battle_monsters/proc/FormatSpellText(var/text,var/datum/battle_monsters/spell_datum) + var/list/generated_stats = SSbattlemonsters.GenerateSpellStats(spell_datum) + + if(!generated_stats || generated_stats.len == 0) + return "Something went wrong... go bother the wizardly devs about it." + + var/list/replacements = list( + "%NAME" = generated_stats["name"], + + "%DESCRIPTION" = generated_stats["desc"], + "%SPECIAL_EFFECTS" = generated_stats["special_effects"], + + "%ELEMENT_AND" = GetElements(generated_stats["elements"]), + "%ELEMENT_OR" = GetElements(generated_stats["elements"], " or "), + "%ELEMENT_LIST" = GetElements(generated_stats["elements"], ", ") + ) + + for(var/word in replacements) + text = replacetext(text,word,replacements[word]) + + for(var/word in replacements)//2 passes for good measure. + text = replacetext(text,word,replacements[word]) + + return text + +/datum/controller/subsystem/battle_monsters/proc/GetMonsterFormatting() + return "%NAME | %ELEMENT_LIST %TYPE | %SPECIES_C
\ + Keywords: %SPECIES_LIST
\ + ATK: %ATTACK_POINTS | DEF: %DEFENSE_POINTS
\ + %SPECIAL_EFFECTS
\ + The card depicts %DESCRIPTION" + +/datum/controller/subsystem/battle_monsters/proc/GetSpellFormatting() + return "%NAME | Spell | %ELEMENT_LIST
\ + %SPECIAL_EFFECTS
\ + The card depicts %DESCRIPTION" + +/datum/controller/subsystem/battle_monsters/proc/GetTrapFormatting() + return "%NAME | Trap | %ELEMENT_LIST
\ + %SPECIAL_EFFECTS
\ + The card depicts %DESCRIPTION" + +/datum/controller/subsystem/battle_monsters/proc/ExamineMonsterCard(var/mob/user,var/datum/battle_monsters/element/prefix_datum,var/datum/battle_monsters/monster/root_datum,var/datum/battle_monsters/title/suffix_datum) + to_chat(user,FormatMonsterText(GetMonsterFormatting(),prefix_datum,root_datum,suffix_datum)) + +/datum/controller/subsystem/battle_monsters/proc/ExamineSpellCard(var/mob/user,var/datum/battle_monsters/spell/spell_datum) + to_chat(user,FormatSpellText(GetSpellFormatting(),spell_datum)) + +/datum/controller/subsystem/battle_monsters/proc/ExamineTrapCard(var/mob/user,var/datum/battle_monsters/trap/trap_datum) + to_chat(user,FormatSpellText(GetTrapFormatting(),trap_datum)) + +/datum/controller/subsystem/battle_monsters/proc/GenerateMonsterStats(var/datum/battle_monsters/element/prefix_datum,var/datum/battle_monsters/monster/root_datum,var/datum/battle_monsters/title/suffix_datum, var/limiter = BATTLE_MONSTERS_GENERATION_ALL) + + var/returning_list[0] //Byond documentation told me this is how you make an assoc list. + + returning_list["name"] = root_datum.name + if(prefix_datum.name) + returning_list["name"] = "[prefix_datum.name] [returning_list["name"]]" + if(suffix_datum.name) + returning_list["name"] = "[returning_list["name"]], [suffix_datum.name]" + + returning_list["desc"] = root_datum.description + if(prefix_datum.description) + returning_list["desc"] += " [prefix_datum.description]" + if(suffix_datum.description) + returning_list["desc"] += "
[suffix_datum.description]" + + returning_list["special_effects"] = "" + if(prefix_datum.special_effects) + returning_list["special_effects"] = trim("[returning_list["special_effects"]][prefix_datum.special_effects]
") + if(root_datum.special_effects) + returning_list["special_effects"] = trim("[returning_list["special_effects"]][root_datum.special_effects]
") + if(suffix_datum.special_effects) + returning_list["special_effects"] = trim("[returning_list["special_effects"]][suffix_datum.special_effects]
") + + returning_list["elements"] = prefix_datum.elements | root_datum.elements | suffix_datum.elements + returning_list["attack_type"] = prefix_datum.attack_type | root_datum.attack_type | suffix_datum.attack_type + returning_list["defense_type"] = prefix_datum.defense_type | root_datum.defense_type | suffix_datum.defense_type + + returning_list["rarity_score"] = prefix_datum.rarity_score + root_datum.rarity_score + suffix_datum.rarity_score + returning_list["attack_points"] = (prefix_datum.attack_add + root_datum.attack_add + suffix_datum.attack_add) * (prefix_datum.attack_mul * root_datum.attack_mul * suffix_datum.attack_mul) + returning_list["defense_points"] = (prefix_datum.defense_add + root_datum.defense_add + suffix_datum.defense_add) * (prefix_datum.defense_mul * root_datum.defense_mul * suffix_datum.defense_mul) + returning_list["power"] = (prefix_datum.power_add + root_datum.power_add + suffix_datum.power_add) * (prefix_datum.power_mul * root_datum.power_mul * suffix_datum.power_mul) + if(returning_list["attack_points"] >= returning_list["defense_points"]) + returning_list["defense_points"] = returning_list["defense_points"]/(returning_list["attack_points"] + returning_list["defense_points"]) + returning_list["attack_points"] = 1 - returning_list["defense_points"] + else + returning_list["attack_points"] = returning_list["attack_points"]/(returning_list["attack_points"] + returning_list["defense_points"]) + returning_list["defense_points"] = 1 - returning_list["attack_points"] + + returning_list["attack_points"] = round(returning_list["power"] * returning_list["attack_points"],100) + returning_list["defense_points"] = round(returning_list["power"] * returning_list["defense_points"],100) + returning_list["star_level"] = GetStarLevel(returning_list["power"]) + + return returning_list + +/datum/controller/subsystem/battle_monsters/proc/GenerateSpellStats(var/datum/battle_monsters/spell_datum) + var/returning_list[0] //Byond documentation told me this is how you make an assoc list. + returning_list["name"] = spell_datum.name + returning_list["desc"] = spell_datum.description + returning_list["special_effects"] = spell_datum.special_effects + returning_list["elements"] = spell_datum.elements + returning_list["rarity_score"] = spell_datum.rarity_score + return returning_list + +#undef BATTLE_MONSTERS_GEN_PREFIX +#undef BATTLE_MONSTERS_GEN_ROOT +#undef BATTLE_MONSTERS_GEN_SUFFIX +#undef BATTLE_MONSTERS_GEN_TRAP +#undef BATTLE_MONSTERS_GEN_SPELL \ No newline at end of file diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 54285dfdaea..8a395730de5 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -54,6 +54,7 @@ 'sound/ambience/ambigen14.ogg' ) var/list/forced_ambience = null + var/loop_ambience = TRUE var/sound_env = STANDARD_STATION var/turf/base_turf //The base turf type of the area, which can be used to override the z-level's base turf var/no_light_control = 0 // if 1, lights in area cannot be toggled with light controller @@ -338,12 +339,12 @@ var/list/mob/living/forced_ambiance_list = new if(!L.client.ambience_playing) L.client.ambience_playing = 1 - L << sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = 2) + L << sound('sound/ambience/shipambience.ogg', repeat = loop_ambience, wait = 0, volume = 35, channel = 2) if(forced_ambience) if(forced_ambience.len) forced_ambiance_list |= L - L << sound(pick(forced_ambience), repeat = 1, wait = 0, volume = 25, channel = 1) + L << sound(pick(forced_ambience), repeat = loop_ambience, wait = 0, volume = 25, channel = 1) else L << sound(null, channel = 1) else if(src.ambience.len && prob(35)) diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm index a7cb46c5589..f2601c3045f 100644 --- a/code/game/objects/items/weapons/manuals.dm +++ b/code/game/objects/items/weapons/manuals.dm @@ -1416,4 +1416,14 @@

201: Means that the frame is not rated to handle the entirety of the heat energy of the components. Either upgrade the frame, or downgrade the components.

- "} \ No newline at end of file + "} + +/obj/item/weapon/book/manual/battlemonsters + name = "\improper Guide to Battlemonsters" + icon_state ="battlemonsters" + author = "Macro Toy Company" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned + title = "Guide to Battlemonsters" + +/obj/item/weapon/book/manual/battlemonsters/New() + ..() + dat = {""} diff --git a/code/modules/battlemonsters/datum_core.dm b/code/modules/battlemonsters/datum_core.dm new file mode 100644 index 00000000000..af880ff0f10 --- /dev/null +++ b/code/modules/battlemonsters/datum_core.dm @@ -0,0 +1,21 @@ +datum/battle_monsters/ + var/name = "ERROR" + var/icon_state + var/id + var/description = "" + var/special_effects = "" + var/tip = "" //A tip for the card. + var/elements = BATTLE_MONSTERS_ELEMENT_NONE + var/attack_type = BATTLE_MONSTERS_ATTACKTYPE_NONE + var/defense_type = BATTLE_MONSTERS_DEFENSETYPE_NONE + var/rarity = 1 //Relative chance of choosing this attribute + var/rarity_score = 0 + + var/power_add = 0 + var/power_mul = 1 + + var/attack_add = 0 + var/attack_mul = 1 + + var/defense_add = 0 + var/defense_mul = 1 \ No newline at end of file diff --git a/code/modules/battlemonsters/datum_elements.dm b/code/modules/battlemonsters/datum_elements.dm new file mode 100644 index 00000000000..6b2cfcb897a --- /dev/null +++ b/code/modules/battlemonsters/datum_elements.dm @@ -0,0 +1,473 @@ +//General Rules for special effects: +//Fire: Teamwork. +//Energy: Can attack on the first turn or do things during the opponent's turn. +//Water: After attack. +//Ice: Benifits when defending. +//Earth: Elements against the opponent. +//Stone: Alchemy Gimmick + +/datum/battle_monsters/element + name = "neutral" //The name of the element + elements = BATTLE_MONSTERS_ELEMENT_NEUTRAL //Their general element. + //Note, values are normalized at the end of generation. + rarity = 1 //Relative rarity multiplier. Use for whether or not this card is picked for generation. + description = "%THEYRE neutral." //Description to add. + special_effects = "" //The special effects this element has, if any. + attack_type = BATTLE_MONSTERS_ATTACKTYPE_NONE //The attack flags of the monster. This is basically a general indicator of the weapon it uses. + defense_type = BATTLE_MONSTERS_ATTACKTYPE_NONE //The defense flags of the monster. This is basically a general indicator of what the monster is made out of. Not to be confused with their element. + rarity_score = 0 //Rarity score to add to this card. + //1 or lower means common, 2 means uncommon, 3 means rare, 4 or higher means legendary. + //Uncommon or higher rarities should be used sparringly, and only to cards that are super noteable. + +/datum/battle_monsters/element/fire + name = "Firebrand" + id = "fire" + icon_state = "fire" + elements = BATTLE_MONSTERS_ELEMENT_FIRE + attack_add = 0.25 + attack_type = BATTLE_MONSTERS_ATTACKTYPE_SWORDSMAN + description = "Great balls of %ELEMENT_AND circles around them and their %WEAPON_AND. Firebrands are vikings who hail from the North, who grew a dedication to mastering fire after countless harsh winters." + rarity = BATTLE_MONSTERS_RARITY_COMMON + +/datum/battle_monsters/element/fire/lava + name = "Fireborn" + id = "lava" + icon_state = "fireborn" + description = "They're covered head to toe in a firey blaze. These types of %SPECIES are born from magic %ELEMENT_AND of dark wizards and witches. They make excellent spellcasters." + attack_type = BATTLE_MONSTERS_ATTACKTYPE_SPELLCASTER + special_effects = "Element Spell Immune: %NAME is immune to all %ELEMENT_OR based spell and trap cards if another revealed fire element monster is on the same side of the field." + power_add = 100 + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + +/datum/battle_monsters/element/fire/molten + name = "Molten" + id = "molten" + icon_state = "magma" + description = "Liquid %ELEMENT_AND drips from their eyes and %WEAPON_AND. It is clear that %NAME came from the depths of below the earth." + special_effects = "Element Monster Immune: %NAME is immune to all %ELEMENT_OR based monster attacks if another revealed fire element monster is on the same side of the field." + tip = "%NAME can still be attacked, however the attacker's special effects will be nullified and the attack will be considered a draw if %NAME lost battle calculation." + power_add = 250 + defense_add = 0.25 + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + +/datum/battle_monsters/element/fire/candle + name = "Candle Wax" + id = "wax" + icon_state = "candle" + elements = BATTLE_MONSTERS_ELEMENT_FIRE | BATTLE_MONSTERS_ELEMENT_DARK + description = "They are covered entirely with dark burning wax, a telltale sign of the unholy Candle Wax Cult." + special_effects = "Waxing Power: %NAME passively gains 100 attack points for every other revealed %ELEMENT_OR type monster on your side of the field." + power_add = 250 + defense_add = 0.25 + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/element/fire/burned + name = "Burned" + id = "burned" + icon_state = "burned" + elements = BATTLE_MONSTERS_ELEMENT_FIRE | BATTLE_MONSTERS_ELEMENT_DARK + attack_type = BATTLE_MONSTERS_ATTACKTYPE_SPELLCASTER + description = "Visible scorch marks and bandages appear all over their body from centuries of using %ELEMENT_AND. This %SPECIES is clearly a veteran of using the magical arts." + special_effects = "Battle Reminder: If a %ELEMENT_OR type monster is sent to a graveyard, the card's owner can choose to reveal and send one fire element monster from the owner's hand to the graveyard in it's place." + tip = "The chosen monster card sent in the other person's place will have it's special effects triggered as if it was revealed on the field." + power_add = 500 + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/element/fire/scorching_blade + name = "Scorching Blade" + id = "scorching_blade" + icon_state = "scorching_blade" + elements = BATTLE_MONSTERS_ELEMENT_FIRE | BATTLE_MONSTERS_ELEMENT_STONE + description = "A giant, %ELEMENT_AND katana adorns their hip. The blade itself looks extremely unstable and pulsates with strange magic every now and then. Warriors of the east looking to improve their mastery of fire usually look to perform the Scorching Blade ritual." + special_effects = "Revenge: If %NAME is sent to a graveyard, the card's owner can choose to send one non-%ELEMENTS_OR based monster on the field to the graveyard as well." + tip = "If you know what you're doing, you can also send one of your own monsters to the graveyard with it." + attack_type = BATTLE_MONSTERS_ATTACKTYPE_SWORDSMAN + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + +/datum/battle_monsters/element/fire/burning_sun_god + name = "Burning Sun God" + id = "burning_sun_god" + icon_state = "burning_sun_god" + description = "Upon closer examination, various %ELEMENT_AND symbols are etched across their body. A slightly visible shadow of The Burning Sun God Ra'Kan is cast behind them. It's clear that the god is using them as a vessel for it's bidding." + special_effects = "Godly Protection: %ELEMENT_OR monsters cannot attack or be attacked by %NAME." + defense_type = BATTLE_MONSTERS_DEFENSETYPE_GOD + tip = "%NAME can still be affected by traps or spells." + power_add = 2000 + rarity = BATTLE_MONSTERS_RARITY_LEGENDARY + rarity_score = 3 + +/datum/battle_monsters/element/energy + name = "Energy" + id = "energy" + icon_state = "energy" + elements = BATTLE_MONSTERS_ELEMENT_ENERGY + attack_add = 0.25 + description = "Magical lighting flickers in the background, each strike hitting their %WEAPON_AND with %ELEMENT_AND." + rarity = BATTLE_MONSTERS_RARITY_COMMON + +/datum/battle_monsters/element/energy/thunder + name = "Thunderchild" + id = "thunder" + icon_state = "thunder" + power_add = 500 + attack_add = 0.25 + description = "A symbol on their forehead indicates that they are a %SPECIES thunderchild, born of the incredibly horny god Bleus after coitus with a %SPECIES. Children born of Bleus tend to show a god-like control over energy elements, such as lightning." + special_effects = "Charge: %NAME can attack as soon as it's revealed, regardless of other penalties." + tip = "Remember that 'played' is not the same as 'revealed', a card is considered 'played' when it's put into the field from the owner's hand." + defense_type = BATTLE_MONSTERS_DEFENSETYPE_GOD + power_mul = 0.75 + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + +/datum/battle_monsters/element/energy/powered + name = "Cybernetic" + id = "powered" + icon_state = "powered" + description = "Upon closer examination, it seems that they have advanced cybernetics. It is unknown where these cybernetics came from, or when, for that matter." + special_effects = "Null Field: When %NAME is visible, all the opponent's special effects are nullified during the opponent's turn." + rarity = BATTLE_MONSTERS_RARITY_RARE + defense_type = BATTLE_MONSTERS_DEFENSETYPE_MACHINE + rarity_score = 1 + +/datum/battle_monsters/element/energy/dragonslayer + name = "Dragonslayer" + id = "dragonslayer" + icon_state = "dragonslayer" + description = "They're wearing a dragonscale cape, and dragon skull shoulderpads. Dragonslayers can commonly be seen in the mountains hunting dragons for their prized bones and scales." + special_effects = "Dragonslayer: When %NAME is summoned, the card's owner can choose to send a dragon to the graveyard as long as the dragon's attack points does not exceed %NAME's attack points." + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/element/energy/dragoncult + name = "Dragoncult" + id = "dragoncult" + icon_state = "dragoncult" + description = "They're painted with various symbols belonging to the secretive Dragoncult, an ancient organization that serves the dragons." + special_effects = "Dragon Protection: As long as %NAME is visible, all allied Dragons are immune to spells." + elements = BATTLE_MONSTERS_ELEMENT_ENERGY | BATTLE_MONSTERS_ELEMENT_FIRE + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/element/energy/dragongod + name = "Dragon God" + id = "dragon_god" + icon_state = "dragon_god" + defense_type = BATTLE_MONSTERS_DEFENSETYPE_GOD | BATTLE_MONSTERS_DEFENSETYPE_GIANT_DRAGON + elements = BATTLE_MONSTERS_ELEMENT_ENERGY + description = "Their %ELEMENT_AND wings are absolutely massive, and their massive snout exhales deadly %ELEMENT_AND. This being is a common god among dragons, and it is theorized that one of the many breeds of dragons came from %NAME." + special_effects = "Godly Protection: %ELEMENT_OR monsters cannot attack or be attacked by %NAME.
Wingspan: When %NAME is summoned, all non-flying monsters on the field are sent to the graveyard." + tip = "%NAME can still be affected by traps or spells.
%NAME can also send friendly units to the graveyard." + power_add = 2000 + rarity = BATTLE_MONSTERS_RARITY_LEGENDARY + rarity_score = 3 + +/datum/battle_monsters/element/water + name = "Water" + id = "water" + icon_state = "water" + description = "Their %WEAPON_AND is coated with magical shifting water." + elements = BATTLE_MONSTERS_ELEMENT_WATER + rarity = BATTLE_MONSTERS_RARITY_COMMON + +/datum/battle_monsters/element/water/morphing + name = "Morphling" + id = "morphling" + icon_state = "water2" + description = "Upon closer examination, it appears that they can morph into various shapes using the magic of %ELEMENT_AND. Morphlings can common be seen near rivers, lakes, or streams harrassing travelers who dare to take a drink from the protected waters." + special_effects = "Morph: %NAME is automatically switched to defense mode if they attack, and automatically switched to attack mode if they succesfully defend from an attack. %NAME cannot be switched to attack mode or defense mode manually." + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + +/datum/battle_monsters/element/water/raincloud + name = "Rain" + id = "rain" + icon_state = "raincloud" + description = "Depressing rainclouds hover above them. Such rainclouds are usually caused by a curse given by witches for the penalty of being too sad." + special_effects = "Dark Rainclouds: %NAME is immune to all non %ELEMENT_OR based trap and spell cards as long as %NAME attacked on the owner's previous turn." + power_mul = 0.75 + attack_add = 0.5 + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + +/datum/battle_monsters/element/water/trench_pirate + name = "Trench" + id = "trench_pirate" + description = "They're covered entirely with seaweed and barnacles, with an eyepatch and a bandana complimenting their monsterous shape. Rumor has it that Trench beings were shipwrecked sailors whose bodies sunk into marine trenches into the hells below." + special_effects = "Changing Tides: %NAME cannot be attack or be attacked by non %ELEMENT_OR based monster cards as long as %NAME attacked on the owner's previous turn." + elements = BATTLE_MONSTERS_ELEMENT_WATER | BATTLE_MONSTERS_ELEMENT_DARK + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/element/water/typhoon_god + name = "Typhoon Lord" + id = "typhoon_lord" + description = "Their lower body resembles much of a fish, with massive tidal waves surging from under them. %NAME commonly sends typoons to villages near the waters that threaten the local sealife in the area." + special_effects = "Tidal Wave: When %NAME is summoned, all non water element monsters, traps, and spells on the field are sent to the graveyard." + elements = BATTLE_MONSTERS_ELEMENT_WATER + rarity = BATTLE_MONSTERS_RARITY_MYTHICAL + rarity_score = 2 + +/datum/battle_monsters/element/ice + name = "Ice" + id = "ice" + icon_state = "ice" + description = "They seem well equipped to deal with the harsh, icy weather on the Plains of Narbask." + elements = BATTLE_MONSTERS_ELEMENT_ICE + defense_add = 1 + rarity = BATTLE_MONSTERS_RARITY_COMMON + +/datum/battle_monsters/element/ice/defender + name = "Igloo Defender" + id = "igloo" + icon_state = "igloo" + description = "They stand silently outside an igloo in a freezing blizzard with a sturdy grip on their %WEAPON_AND. They seem unbothered by the cold." + attack_type = BATTLE_MONSTERS_ATTACKTYPE_SHIELD + power_add = 200 + special_effects = "Master Defender: As long as %NAME is visible, its owner cannot be attacked by monsters. " + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + +/datum/battle_monsters/element/ice/yeti + name = "Yeti" + id = "yeti" + icon_state = "white" + description = "They're covered head to toe in white, absorbant magical fur. Their %WEAPON_AND is ferocious, especially for a %SPECIES." + special_effects = "Spell Absorbtion: As long as %NAME is visible, it's owner cannot be affected by traps or spells." + defense_type = BATTLE_MONSTERS_DEFENSETYPE_CREATURE + attack_type = BATTLE_MONSTERS_ATTACKTYPE_CLAWS + power_add = 200 + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/element/ice/frostlord + name = "Frostlord" + id = "frostlord" + icon_state = "ice" + description = "They're wearing a large crown made entirely out of ice and diamonds, and a royal cape made out magical yeti fur. Frostlords gain their title by defeating a yeti in combat by wrestling it to death." + special_effects = "Royal Decree: As long as there are 2 other frost element monsters on the same side of the field, %NAME cannot be sent to the graveyard.
Spell Immunity: %NAME cannot be affected by traps or spells." + elements = BATTLE_MONSTERS_ELEMENT_ICE + power_add = 1000 + rarity = BATTLE_MONSTERS_RARITY_RARE + +/datum/battle_monsters/element/ice/frost_guardian + name = "Frost Guardian" + id = "frostguardian" + icon_state = "ice" + description = "They're wearing incredibly bulky armor, made entirely out of ice. Their still posture compliments the age-long growing of the icicles forming on their %WEAPON_AND." + special_effects = "Best Defense: As long as %NAME is on the field, its owner cannot lose life points from monster battles." + attack_mul = 0 + elements = BATTLE_MONSTERS_ELEMENT_ICE + power_add = 1000 + rarity = BATTLE_MONSTERS_RARITY_RARE + +/datum/battle_monsters/element/ice/blizzard_god + name = "Blizzard God" + id = "blizzard_god" + icon_state = "frost_god" + description = "Their general %SPECIES-like figure is clouded in a massive %ELEMENT_AND storm. All that come close to seeing it's true form usually perish from frostbite." + special_effects = "Godly Protection: As long as a frost element monster other than %NAME is on the field, %NAME cannot be attacked by monsters or spells." + defense_type = BATTLE_MONSTERS_DEFENSETYPE_GOD + power_add = 1000 + rarity = BATTLE_MONSTERS_RARITY_LEGENDARY + rarity_score = 3 + +/datum/battle_monsters/element/earth + name = "Earth" + id = "earth" + icon_state = "earth" + description = "Earthen roots shift around them with small flowers budding from it's branches, signifying a oneness with nature." + elements = BATTLE_MONSTERS_ELEMENT_EARTH + rarity = BATTLE_MONSTERS_RARITY_COMMON + +/datum/battle_monsters/element/earth/treant + name = "Treant" + id = "treant" + icon_state = "treant" + description = "They seem to be made out of living mystical wood." + special_effects = "Exploit Water: If there is a water monster on the opposing side of the field, %NAME gains 500 defense points." + defense_mul = 1.25 + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + +/datum/battle_monsters/element/earth/bonfire + name = "Bonfire" + id = "bonfire" + icon_state = "bonfire" + elements = BATTLE_MONSTERS_ELEMENT_EARTH | BATTLE_MONSTERS_ELEMENT_FIRE + description = "They seem to be made out of burning driftwood." + special_effects = "Exploit Fire: If there is a fire monster on the opposing side of the field, %NAME gains 500 attack points." + defense_mul = 1.25 + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + +/datum/battle_monsters/element/earth/fairy + name = "Fairy" + id = "fairy" + icon_state = "fairy" + elements = BATTLE_MONSTERS_ELEMENT_EARTH | BATTLE_MONSTERS_ELEMENT_LIGHT + attack_type = BATTLE_MONSTERS_ATTACKTYPE_CLAWS + defense_type = BATTLE_MONSTERS_DEFENSETYPE_FLYING + description = "They are quite tiny, and have little pixie wings growing out of their back and extra long claws." + special_effects = "Exploit Dark: If there is a dark monster on the opposing side of the field, all %ELEMENT_AND monsters gain 500 defense points for as long as %NAME is visible." + power_mul = 0.5 + defense_mul = 0.5 + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/element/earth/forest_god + name = "Forest God" + id = "frost_god" + icon_state = "earth_god" + elements = BATTLE_MONSTERS_ELEMENT_EARTH | BATTLE_MONSTERS_ELEMENT_WATER | BATTLE_MONSTERS_ELEMENT_STONE + defense_type = BATTLE_MONSTERS_DEFENSETYPE_GOD | BATTLE_MONSTERS_DEFENSETYPE_COLOSSUS + description = "They have roots for feet and massive tree trunks for arms. Their overall size rivals those of the greatest manmade structures on earth, and as such, their %WEAPON_AND must match their size." + special_effects = "Revenge of the Earth: When a %ELEMENT_OR element is sent to the graveyard, the card responsible will also be sent to the graveyard." + power_mul = 2000 + defense_mul = 2 + rarity = BATTLE_MONSTERS_RARITY_LEGENDARY + rarity_score = 3 + +/datum/battle_monsters/element/stone + name = "Stone" + id = "stone" + icon_state = "stone" + description = "They're rock hard. Made out of rock, that is." + elements = BATTLE_MONSTERS_ELEMENT_STONE + rarity = BATTLE_MONSTERS_RARITY_COMMON + +/datum/battle_monsters/element/stone/uranium + name = "Uranium" + id = "uranium" + icon_state = "uranium" + description = "They're made out of pure uranium." + special_effects = "EMP: If an Iron prefixed monster exists on the field when this card is played, send this card and all energy element monsters on the field to the graveyard." + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/element/stone/iron + name = "Iron" + id = "iron" + icon_state = "iron" + description = "They're made out of dense iron. A perfect protector of mankind." + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + defense_mul = 1.5 + power_add = 300 + +/datum/battle_monsters/element/stone/steel + name = "Steel" + id = "steel" + icon_state = "steel" + description = "They're made out of sturdy steel." + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + power_add = 600 + +/datum/battle_monsters/element/stone/aluminium + name = "Aluminium" + id = "aluminium" + icon_state = "alum" + description = "They're made out of incredibly lightweight metal." + defense_mul = 0.25 + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + power_add = 300 + +/datum/battle_monsters/element/stone/potassium + name = "Potassium" + id = "potassium" + icon_state = "potas" + description = "They're made entirely out of bananas, for some reason. Even their %WEAPON_AND is a banana. Everything is bananas." + special_effects = "Explosion: If a visble water element monster exists on the field when this card is revealed, send this card and all monsters with under <1000> defense points on the field to the graveyard.
Flash: If a visible Potassium prefixed monster is on the field when this card is revealed, the opponent's turn is skipped and %NAME is sent to the graveyard." + rarity = BATTLE_MONSTERS_RARITY_MYTHICAL + rarity_score = 2 + +/datum/battle_monsters/element/dark + name = "Dark" + id = "dark" + icon_state = "dark" + description = "A strange evil, shadowy aura embraces them and all those around it." + elements = BATTLE_MONSTERS_ELEMENT_DARK + power_add = 500 + attack_mul = 1.25 + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + rarity_score = 1 + +/datum/battle_monsters/element/dark/vampire + name = "Vampire" + id = "vampire" + icon_state = "vampire" + description = "They're incredibly pale and have two large snake-like fangs." + special_effects = "Leech: If %NAME attacks the opponent, the owner of the card gains 1 lifepoint as long as the owner's lifepoints are less than 5." + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/element/dark/cultist + name = "Cultist" + id = "cultist" + icon_state = "cultist" + description = "They're wearing dark, mysterious robes." + special_effects = "Summoning: If 6 monsters with a cultist prefix exist on your side of the field at once when %NAME is played or revealed, you win the game." + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/element/dark/demon + name = "Demon" + id = "demon" + icon_state = "demon" + attack_type = BATTLE_MONSTERS_ATTACKTYPE_CLAWS + defense_type = BATTLE_MONSTERS_DEFENSETYPE_FLYING | BATTLE_MONSTERS_DEFENSETYPE_REPTILE | BATTLE_MONSTERS_DEFENSETYPE_DEMON + description = "They have the head of a goat and hooved feet, with a menacing reptilian tail growing above their behind and dark wings for flight." + special_effects = "Sacrifice: %NAME can sacrifice a non-light element type monster on the same side of the field to attack again." + rarity = BATTLE_MONSTERS_RARITY_MYTHICAL + rarity_score = 2 + +/datum/battle_monsters/element/dark/devil //SPRITE NEEDED + name = "Devil" + id = "devil" + icon_state = "demon" + attack_type = BATTLE_MONSTERS_ATTACKTYPE_CLAWS + defense_type = BATTLE_MONSTERS_DEFENSETYPE_FLYING | BATTLE_MONSTERS_DEFENSETYPE_REPTILE | BATTLE_MONSTERS_DEFENSETYPE_DEMON | BATTLE_MONSTERS_DEFENSETYPE_GIANT + description = "Two boned horns sprout out of their forehead, and two dark demon wings sprout from their back." + special_effects = "Bargain: When %NAME is played, the card's owner can choose to sacrifice 2 of their lifepoints to remove 1 lifepoint from their opponent." + rarity = BATTLE_MONSTERS_RARITY_MYTHICAL + rarity_score = 2 + +/datum/battle_monsters/element/dark/unholy //SPRITE NEEDED + name = "Unholy" + id = "unholy" + description = "A dark, unholy aura shrouds their true shape and figure." + special_effects = "Unholy Barrier: As long as %NAME is in play, all monsters and players are immune to light element spells, traps, and special effects." + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/element/light + name = "Light" + id = "light" + icon_state = "light" + description = "A holy aura shapes around their beauty." + elements = BATTLE_MONSTERS_ELEMENT_LIGHT + defense_mul = 1.25 + power_add = 500 + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + rarity_score = 1 + +/datum/battle_monsters/element/light/angel //SPRITE NEEDED + name = "Guardian Angel" + id = "angel" + description = "A halo floats above them, and feathery white wings sprout from their back." + special_effects = "Sacrifice: If a friendly monster loses a battle, %NAME can be sent to the graveyard instead." + defense_type = BATTLE_MONSTERS_DEFENSETYPE_FLYING + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/element/light/undying //SPRITE NEEDED + name = "Undying" + id = "undying" + description = "Various scars are scattered across their body. Each scar seems to glow distinctly with holy energy." + special_effects = "Reborn: If %NAME is defeated in battle, go to the original owner's hand instead of the graveyard." + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/element/light/holy //SPRITE NEEDED + name = "Holy" + id = "holy" + description = "Their body seems to have an angelic glow." + special_effects = "Holy Barrier: As long as %NAME is in play, all monsters and players are immune to dark element spells, traps, and special effects." + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 \ No newline at end of file diff --git a/code/modules/battlemonsters/datum_monsters.dm b/code/modules/battlemonsters/datum_monsters.dm new file mode 100644 index 00000000000..6c429eb9c4c --- /dev/null +++ b/code/modules/battlemonsters/datum_monsters.dm @@ -0,0 +1,292 @@ +/datum/battle_monsters/monster + name = "monster" //The base name of the card. In the end it will look something like "dark monster, the great" + power_add = 500 //Their base power. Power is basically how strong the card in respect to it's defense and attack points. + defense_mul = 1 //Their defense point multiplier, or BDM + attack_mul = 1 //Their attack point multiplier, or BAM. + //Note: Values are normalized based on the highest multiplier. A BDM of 2 and a BAM of 1 is equal to a BDM of 1 and a BAM of 0.5. + //BDM of 0.75 and a BDA of 0.25 with a monster of 1000 BP means the monster will have 750 defense points and 250 attack points. + rarity = 1 //Relative rarity multiplier. Use for whether or not this card is picked for generation. + //For reference, 1 is common, 0.5 is uncommon, 0.25 is rare, and anything below it is ultra rare. + description = "a fat beast" //The description of this monster. It should make sense when put before "The card depicts" + special_effects = "" //The special effects a monster has, if any. + attack_type = BATTLE_MONSTERS_ATTACKTYPE_NONE //The attack flags of the monster. This is basically a general indicator of the weapon it uses. + defense_type = BATTLE_MONSTERS_DEFENSETYPE_NONE //The defense flags of the monster. This is basically a general indicator of what the monster is made out of. Not to be confused with their element. + rarity_score = 0 //Rarity score to add to this card. + //1 or lower means common, 2 means uncommon, 3 means rare, 4 or higher means legendary. + //Uncommon or higher rarities should be used sparringly, and only to cards that are super noteable. + +/datum/battle_monsters/monster/human + name = "Human" + id = "human_male" + icon_state = "human" + power_add = 300 + defense_add = 1 + attack_add = 1 + description = "a typical male %SPECIES inhabitant of Great Kingdom of Garoosh. While not a trained fighter, all %SPECIESs are quick thinkers and know how to fight when it matters with their %WEAPON_AND." + special_effects = "" + attack_type = BATTLE_MONSTERS_ATTACKTYPE_SWORDSMAN + defense_type = BATTLE_MONSTERS_DEFENSETYPE_HUMAN + rarity = BATTLE_MONSTERS_RARITY_COMMON + rarity_score = -1 + +/datum/battle_monsters/monster/human/female + name = "Human" + id = "human_female" + icon_state = "human" + power_add = 300 + defense_add = 1 + attack_add = 0.75 + description = "a typical female %SPECIES inhabitant of Great Kingdom of Garoosh. While not a trained fighter, all %SPECIESs are quick thinkers and know how to fight when it matters with their %WEAPON_AND." + special_effects = "" + attack_type = BATTLE_MONSTERS_ATTACKTYPE_SWORDSMAN + defense_type = BATTLE_MONSTERS_DEFENSETYPE_HUMAN + rarity = BATTLE_MONSTERS_RARITY_COMMON + rarity_score = -1 +/datum/battle_monsters/monster/human/mage + name = "Apprentice Mage" + id = "mage" + icon_state = "staff" + power_add = 400 + defense_add = 1 + attack_add = 3 + description = "a young and eager-looking male %SPECIES mage from the mysterious and secluded Gautem Islands. They appear to be reading from a book, while their %WEAPON_AND hovers around them." + special_effects = "Tutor: %NAME temporarily gains 250 bonus attack points if a visible spellcaster with more attack points than %NAME is on your side of the field." + attack_type = BATTLE_MONSTERS_ATTACKTYPE_SPELLCASTER + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + rarity_score = 0 + +/datum/battle_monsters/monster/human/sage + name = "Wise Sage" + id = "sage" + icon_state = "staff" + power_add = 800 + defense_add = 1 + attack_add = 2 + description = "an mysterious looking male %SPECIES, dressed in %ELEMENT_AND robes. A %WEAPON_AND seems to be holstered on their back, with a magic crystal ball hovering above their hands." + special_effects = "Elemental Defense: %NAME temporarily gains 500 bonus defense points when defending against another %ELEMENT_OR type monster." + attack_type = BATTLE_MONSTERS_ATTACKTYPE_SPELLCASTER + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + rarity_score = 0 + +/datum/battle_monsters/monster/human/wizard + name = "Wizard" + id = "wizard" + icon_state = "staff" + power_add = 2000 + defense_add = 1 + attack_add = 2 + description = "an elderly, long-bearded male %SPECIES, dressed in typical wizard garb. They hold a %WEAPON_AND proudly, and their beard humorously tangles around it." + special_effects = "Elemental Spell Immune: %NAME is immune to %ELEMENT_AND based spell cards." + attack_type = BATTLE_MONSTERS_ATTACKTYPE_SPELLCASTER + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +datum/battle_monsters/monster/human/warrior + name = "Barbarian" + id = "warrior" + icon_state = "human" + power_add = 1000 + defense_add = 2 + attack_add = 1 + description = "a seductively buff male %SPECIES barbarian wearing a simple fur loincloth and a chest full of hair. They seem to be in possession of a %WEAPON_AND." + special_effects = "%SPECIES_C Kinship: %NAME gains 300 attack points if there is another visible %SPECIES on the same side of the field." + attack_type = BATTLE_MONSTERS_ATTACKTYPE_SWORDSMAN + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + rarity_score = 0 + +/datum/battle_monsters/monster/human/amazon_warrior + name = "Amazon Warrior" + id = "amazon_warrior" + icon_state = "human" + power_add = 1000 + defense_add = 2 + attack_add = 1 + description = "a scantily clad male %SPECIES %NAME dressed in leopard skin. They proudly wield a giant %WEAPON_AND." + attack_type = BATTLE_MONSTERS_ATTACKTYPE_CLUB + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + rarity_score = 0 + +/datum/battle_monsters/monster/human/amazon_prime + name = "Amazon Prime" + id = "amazon_warrior" + icon_state = "human" + power_add = 1000 + defense_add = 2 + attack_add = 1 + description = "a scantily clad female %SPECIES %NAME dressed in leopard skin. They're one of the many queen guards of the Amazonian Kingdom." + special_effects = "Free Shipping: A trap or spell card can be played from the card owner's hand during their opponent's turn, as long as %NAME is visible." + attack_type = BATTLE_MONSTERS_ATTACKTYPE_CLUB + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/monster/human/knight + name = "Knight" + id = "knight" + icon_state = "human_knight" + power_add = 1000 + defense_add = 4 + attack_add = 1 + rarity = 0.25 + description = "a proud male %SPECIES %NAME dorned in heavy %ELEMENT_AND armor and wielding a decorative %WEAPON_AND. They're sworn to protect the Great Kingdom of Garoosh from Barbarians." + special_effects = "%SPECIES Protection: As long as %NAME is visible, all other %SPECIES are attack immune." + attack_type = BATTLE_MONSTERS_ATTACKTYPE_SWORDSMAN + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + rarity_score = 0 + +/datum/battle_monsters/monster/human/king + name = "King" + id = "king" + icon_state = "king" + power_add = 2000 + defense_add = 1 + attack_add = 10 + description = "a fat %SPECIES %NAME sitting atop a %ELEMENT_AND throne, with a %WEAPON_AND spread out across a gold chessboard. Their equally golden crown is quite large for their small head." + special_effects = "Selfish Protection: %NAME cannot be attacked if other monsters exist on the same side of the field." + attack_type = BATTLE_MONSTERS_ATTACKTYPE_ARMY + rarity = BATTLE_MONSTERS_RARITY_MYTHICAL + rarity_score = 1 + +/datum/battle_monsters/monster/human/queen + name = "Queen" + id = "queen" + icon_state = "king" + power_add = 2000 + defense_add = 1 + attack_add = 5 + description = "an incredibly voluptuous %SPECIES female adorned in a %ELEMENTS_AND robe. An equally tight-fitting crown sits atop her head." + special_effects = "Lustful Aurora: %NAME cannot be attacked by %SPECIES." + attack_type = BATTLE_MONSTERS_ATTACKTYPE_ARMY + rarity = BATTLE_MONSTERS_RARITY_MYTHICAL + rarity_score = 1 + +/datum/battle_monsters/monster/dragon + name = "Dragon" + id = "dragon" + icon_state = "dragon" + power_add = 1500 + defense_add = 2 + attack_add = 1 + description = "an adult male %SPECIES wielding %WEAPON_AND in each hand. %NAME such as these commonly inhabit the snowy mountains of the North." + attack_type = BATTLE_MONSTERS_ATTACKTYPE_CLAWS + defense_type = BATTLE_MONSTERS_DEFENSETYPE_FERALDRAGON + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/monster/dragon_giant + name = "Giant Dragon" + id = "dragon_giant" + icon_state = "dragon" + power_add = 3000 + defense_add = 4 + attack_add = 1 + description = "an incredibly rare female %SPECIES of the %ELEMENT_AND vairety. Female %NAME are exceptionally rare among %SPECIESs, as they usually only show themselves every 1000 years." + special_effects = "Sweeping Strike: %NAME can attack up to two targets per turn as long as the combined defense points of both targets does not exceed 1000." + attack_type = BATTLE_MONSTERS_ATTACKTYPE_CLAWS + defense_type = BATTLE_MONSTERS_DEFENSETYPE_GIANT_DRAGON + rarity = BATTLE_MONSTERS_RARITY_MYTHICAL + rarity_score = 1 + +/datum/battle_monsters/monster/dragon/hybrid + name = "Dragoness" + id = "dragon_hybrid" + icon_state = "dragon" + power_add = 2000 + defense_add = 2 + attack_add = 1 + description = "an unrealsticly busty feminine shaped %SPECIES. When not using their mammaries to confuse scientists, %NAME usually stalks careless human climbers for a quick and easy meal using their deadly %WEAPON_AND." + special_effects = "Lustful Aurora: %NAME cannot be attacked by %SPECIES." + attack_type = BATTLE_MONSTERS_ATTACKTYPE_CLAWS + defense_type = BATTLE_MONSTERS_DEFENSETYPE_DRAGONHYBRID + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/monster/dragon/drake + name = "Drake" + id = "drake" + icon_state = "dragon" + power_add = 2000 + defense_add = 4 + attack_mul = 0.25 + elements = BATTLE_MONSTERS_ELEMENT_FIRE + description = "a skinny dark-scaled male %SPECIES bard warrior that prefers to rhyme than to attack with their %WEAPON_AND." + special_effects = "Hotline Bling: All %ELEMENT_OR element monsters recieve an additional 200 attack points." + defense_type = BATTLE_MONSTERS_DEFENSETYPE_DRAGONHYBRID + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/monster/giant + name = "Giant" + id = "giant" + icon_state = "giant" + power_add = 1800 + defense_add = 1 + attack_add = 1 + description = "a hulking, unintellgent bipedal %SPECIES that can commonly be seen roaming the hillside searching for horses to herd and eat. It is theorized that %NAME are failed biological experiments of wizards from an older age." + special_effects = "Crush: %NAME can send 1 creature type to the graveyard when summoned." + defense_type = BATTLE_MONSTERS_DEFENSETYPE_GIANT + attack_type = BATTLE_MONSTERS_ATTACKTYPE_CLUB + rarity = BATTLE_MONSTERS_RARITY_RARE + rarity_score = 1 + +/datum/battle_monsters/monster/lizard + name = "Lizardman" + id = "lizardman" + icon_state = "lizard" + power_add = 500 + defense_add = 1 + attack_add = 1.5 + description = "a well-built muscled bipedal male %SPECIES citizen of the marshes of Ka'best. %NAME enjoy hunting for sport, and do so proudly with their %WEAPON_AND." + defense_type = BATTLE_MONSTERS_DEFENSETYPE_LIZARDMAN + attack_type = BATTLE_MONSTERS_ATTACKTYPE_CLAWS | BATTLE_MONSTERS_ATTACKTYPE_CLUB + rarity = BATTLE_MONSTERS_RARITY_COMMON + rarity_score = 0 + +/datum/battle_monsters/monster/lizard/female + name = "Lizardwoman" + id = "lizardwoman" + attack_add = 1.75 + description = "a well-built muscled bipedal female %SPECIES citizen of the marshes of Ka'best. %NAME enjoy hunting for sport, and do so proudly with their %WEAPON_AND." + +/datum/battle_monsters/monster/catbeast + name = "Catbeast" + id = "catman" + icon_state = "cat" + power_add = 400 + defense_add = 1 + attack_add = 1.50 + description = "a furred bipedal male %SPECIES citizen of the plains of Old Jargo. %NAME ocassionally hunt small creatures with their %WEAPON_AND." + defense_type = BATTLE_MONSTERS_DEFENSETYPE_CATMAN + attack_type = BATTLE_MONSTERS_ATTACKTYPE_CLAWS | BATTLE_MONSTERS_ATTACKTYPE_TEETH + rarity = BATTLE_MONSTERS_RARITY_COMMON + rarity_score = 0 + +/datum/battle_monsters/monster/catbeast/female + name = "Catbeastess" + id = "catwoman" + description = "a furred bipedal female %SPECIES citizen of the plains of Old Jargo. %NAME ocassionally hunt small creatures with their %WEAPON_AND." + +/datum/battle_monsters/monster/antman + name = "Great Ant Patron" + id = "antman" + icon_state = "ant" + power_add = 400 + defense_add = 1 + attack_add = 1.50 + description = "a quadruped chitin male %SPECIES citizen of the hills of Kalakest. Despite being a peaceful race, %NAME can be seen wielding %WEAPON_AND to defend their nests from foolish raiders looking to steal from their valuable eggs." + defense_type = BATTLE_MONSTERS_DEFENSETYPE_ANTMAN + attack_type = BATTLE_MONSTERS_ATTACKTYPE_CLAWS | BATTLE_MONSTERS_ATTACKTYPE_SWORDSMAN + rarity = BATTLE_MONSTERS_RARITY_COMMON + rarity_score = 0 + +/datum/battle_monsters/monster/antman/female + name = "Great Ant Matron" + id = "antwoman" + icon_state = "ant" + power_add = 800 + defense_add = 1.50 + attack_add = 1 + description = "a quadruped chitin female %SPECIES citizen of the hills of Kalakest. Despite being a peaceful race, %NAME can be seen wielding %WEAPON_AND to defend their nests from foolish raiders looking to steal from their valuable eggs. The females make excellent defenders because of this." + attack_type = BATTLE_MONSTERS_ATTACKTYPE_CLAWS | BATTLE_MONSTERS_ATTACKTYPE_SWORDSMAN | BATTLE_MONSTERS_ATTACKTYPE_SHIELD + rarity = BATTLE_MONSTERS_RARITY_UNCOMMON + rarity_score = 1 \ No newline at end of file diff --git a/code/modules/battlemonsters/datum_spells.dm b/code/modules/battlemonsters/datum_spells.dm new file mode 100644 index 00000000000..80d8c5c9557 --- /dev/null +++ b/code/modules/battlemonsters/datum_spells.dm @@ -0,0 +1,103 @@ +/datum/battle_monsters/spell + name = "oh no" //The name of the spell + id = "spell_error" + icon_state = "magic" + elements = BATTLE_MONSTERS_ELEMENT_NEUTRAL //Their general element. + rarity = 0 //Relative rarity multiplier. Use for whether or not this card is picked for generation. + description = "%THEYRE neutral." //Description to add. + special_effects = "" //The special effects this element has, if any. + rarity_score = 0 //Rarity score to add to this card. + +/datum/battle_monsters/spell/destroy_trap + name = "Creature's Revenge" + id = "destroy_trap" + icon_state = "pit" + elements = BATTLE_MONSTERS_ELEMENT_EARTH + rarity = 1 + description = "a wolf grinning slying as a hunter falls head first into a pit of spikes. Gruesome." + special_effects = "TRIGGER: When revealed. Single use.
EFFECT: The chosen trap card is sent to the graveyard." + tip = "Can be used on facedown cards with an unknown card type. However, if you get the card type wrong, then the spell is wasted." + rarity_score = 1 + +/datum/battle_monsters/spell/destroy_spell + name = "Fireball Accident" + id = "destroy_spell" + icon_state = "wood_fire" + elements = BATTLE_MONSTERS_ELEMENT_FIRE + rarity = 1 + description = "an apprentice casting a fireball, and accidentally hitting a bunch of important spell tomes, as the dismay of the nearby wizard." + special_effects = "TRIGGER: When revealed. Single use.
EFFECT: The chosen spell card is sent to the graveyard." + tip = "Can be used on facedown cards with an unknown card type. However, if you get the card type wrong, then the spell is wasted." + rarity_score = 1 + +/datum/battle_monsters/spell/destroy_monster + name = "Smite" + id = "destroy_monster" + icon_state = "from_above" + elements = BATTLE_MONSTERS_ELEMENT_LIGHT | BATTLE_MONSTERS_ELEMENT_DARK + rarity = 1 + description = "an incredibly angry bearded god pointing savagely at a very confused human villager." + special_effects = "TRIGGER: When activated. Single use.
EFFECT: The chosen monster is sent to the graveyard." + tip = "Can be used on facedown cards with an unknown card type. However, if you get the card type wrong, then the spell is wasted." + rarity_score = 1 + +/datum/battle_monsters/spell/destroy_facedown + name = "Guard's Stone Bludgeon" + id = "destroy_facedown" + icon_state = "stick" + elements = BATTLE_MONSTERS_ELEMENT_STONE + rarity = 1 + description = "a violet king's guard blugenoning an unknown assassin-like figure in the shadow." + special_effects = "TRIGGER: When revealed. Single use.
EFFECT: The chosen face down card is revealed and sent to the graveyard." + tip = "Beware that any cards with a reveal acitvation will be triggered when this card is revealed." + rarity_score = 1 + +/datum/battle_monsters/spell/draw3 + name = "Aces in the Boot" + id = "draw3" + icon_state = "boot" + elements = BATTLE_MONSTERS_ELEMENT_NEUTRAL + rarity = 1 + description = "a guard playing some card game with his fellow men in the barracks. You can see them reaching down to their boot, where three aces hide." + special_effects = "TRIGGER: When revealed. Single use.
EFFECT: Draw 3 cards." + rarity_score = 1 + +/datum/battle_monsters/spell/draw6 + name = "Card of Sharing" + id = "draw6" + icon_state = "gay" + elements = BATTLE_MONSTERS_ELEMENT_LIGHT + rarity = 1 + description = "rainbows, ponies, flowers, and cudly teddy bears. In other words, a world of filthy communism." + special_effects = "TRIGGER: When revealed. Single use.
EFFECT: Each player draws until they are holding 6 cards." + rarity_score = 1 + +/datum/battle_monsters/spell/restore1 + name = "Potion of Restore Health" + id = "restore1" + icon_state = "potion_red" + elements = BATTLE_MONSTERS_ELEMENT_LIGHT + rarity = 1 + description = "a shiny glass potion, filled to the brim with glowing red liquid." + special_effects = "TRIGGER: When revealed. Single use.
EFFECT: Restore health by 1 point, if under 5." + rarity_score = 1 + +/datum/battle_monsters/spell/damage1 + name = "Potion of Damage Health" + id = "damage1" + icon_state = "potion_blue" + elements = BATTLE_MONSTERS_ELEMENT_DARK + rarity = 1 + description = "a shiny glass potion, filled to the brim with glowing blue liquid." + special_effects = "TRIGGER: When revealed. Single use.
EFFECT: Damage the opponent's health by one point, if over 1,." + rarity_score = 1 + +/datum/battle_monsters/spell/polymerization + name = "Fuse" + id = "fuse" + icon_state = "swap" + elements = BATTLE_MONSTERS_ELEMENT_ENERGY + rarity = 1 + description = "two monsters chasing eachother, eventually becoming one giant blur." + special_effects = "TRIGGER: When revealed. Single use.
EFFECT: Fuse the special effects of two monsters together, and reveal both cards. Fused monsters cannot attack on the turn they are fused." + rarity_score = 1 diff --git a/code/modules/battlemonsters/datum_titles.dm b/code/modules/battlemonsters/datum_titles.dm new file mode 100644 index 00000000000..509d4f65eaf --- /dev/null +++ b/code/modules/battlemonsters/datum_titles.dm @@ -0,0 +1,60 @@ +/datum/battle_monsters/title + name = "the Monster" + elements = 0 //Elements to add, if any. + rarity = 1 //Relative rarity multiplier. Use for whether or not this card is picked for generation. + defense_mul = 1 //The added multipler for the monster's defense points. + attack_mul = 1 //The added multiplier for the monsters' attack points. + description = "" //Basically, why do they have this title? + special_effects = ""// The special effects of this title + attack_type = BATTLE_MONSTERS_ATTACKTYPE_NONE //The attack type flags added. + defense_type = BATTLE_MONSTERS_ATTACKTYPE_NONE //The defense type flags added. + +/datum/battle_monsters/title/none + name = "" + id = "no_title" + description = "" + rarity = 0 + +/datum/battle_monsters/title/great + name = "the Great" + id = "great" + power_add = 200 + defense_mul = 1.1 + power_mul = 1.1 + description = "%NAME is known for their extensive adventuring exploits in the Great Kingdom of Al'Karbaro. Rumor has it that their trusty %WEAPON_AND was discovered in a secret underground cave that held the secrets to %ELEMENT_AND." + rarity = 0.5 + rarity_score = 1 + +/datum/battle_monsters/title/powerful + name = "the Powerful" + id = "powerful" + attack_mul = 1.25 + power_add = 200 + power_mul = 1.25 + description = "%NAME is feared upon by most lesser beings, and with good reason. A single stroke of their %WEAPON_AND is known to destroy the very souls of those unlucky enough to even witness it's power over %ELEMENT_AND." + special_effects = "Absolute Power: %NAME cannot be attacked by monsters with a base attack rating less than 2000." + rarity = 0.5 + rarity_score = 1 + +/datum/battle_monsters/title/wise + name = "the Wise" + id = "wise" + power_add = 200 + power_mul = 1.1 + description = "Kings and philopshers all around the Kingdom send their servants to seek out %NAME for their sagely advice on %ELEMENT_AND. Their knowledge of such magic rivals even the greatest of the Old Wizards." + special_effects = "Elemental Defense: %NAME temporarily gains 800 bonus defense points when defending against another %ELEMENT_OR type monster." + rarity = 0.5 + rarity_score = 1 + +/datum/battle_monsters/title/elemental + name = "Master of Elements" + id = "master" + power_add = 200 + power_mul = 1.1 + attack_mul = 0.25 + description = "To master one element takes decades of work, to master all 8 takes several lifetimes of constant dedication. It is no doubt that %NAME is old enough to have the time to study all elements, or is powerful enough to manipulate time itself." + special_effects = "Neutral Restriction: %NAME can only be attacked by monsters with a neutral element." + elements = BATTLE_MONSTERS_ELEMENT_ALL + rarity = 0.5 + rarity_score = 1 + diff --git a/code/modules/battlemonsters/datum_traps.dm b/code/modules/battlemonsters/datum_traps.dm new file mode 100644 index 00000000000..e7b2506595e --- /dev/null +++ b/code/modules/battlemonsters/datum_traps.dm @@ -0,0 +1,52 @@ +//Super secret trap porn file +//Don't kinkshame + +/datum/battle_monsters/trap + name = "oh no" //The name of the trap + id = "trap_error" + icon_state = "stop" + elements = BATTLE_MONSTERS_ELEMENT_NEUTRAL //Their general element. + rarity = 0 //Relative rarity multiplier. Use for whether or not this card is picked for generation. + description = "%THEYRE neutral." //Description to add. + special_effects = "" //The special effects this element has, if any. + rarity_score = 1 //Rarity score to add to this card. + +/datum/battle_monsters/trap/block_spell + name = "Spellblock" + id = "block_spell" + icon_state = "block_spell" + elements = BATTLE_MONSTERS_ELEMENT_ICE + rarity = 1 + description = "a magical ice shield deflecting a red death beam." + special_effects = "TRIGGER: When the opponent plays a spell card. Single use.
EFFECT: The spell card played has its effect nullified and sent to the graveyard." + rarity_score = 1 + +/datum/battle_monsters/trap/block_trap + name = "Reverse Trap" + id = "block_trap" + icon_state = "trap" + elements = BATTLE_MONSTERS_ELEMENT_NEUTRAL + rarity = 1 + description = "a feminine looking male tinkering with a bear trap. A sly expression rests on their face." + special_effects = "TRIGGER: When the opponent reveals a trap card. Single use.
EFFECT: The trap card revealed has its effect nullified and sent to the graveyard." + rarity_score = 1 + +/datum/battle_monsters/trap/block_attack + name = "Stop Attack" + id = "block_attack" + elements = BATTLE_MONSTERS_ELEMENT_STONE + icon_state = "stop" + rarity = 1 + description = "a basic 'Do not enter' sign." + special_effects = "TRIGGER: When the opponent attacks a monster. Single use.
EFFECT: The attack is nullified and the monster that attacked cannot attack for the rest of the turn." + rarity_score = 1 + +/datum/battle_monsters/trap/reflect_spell + name = "Reflect Spell" + id = "reflect_spell" + icon_state = "reflect_spell" + elements = BATTLE_MONSTERS_ELEMENT_NEUTRAL + rarity = 1 + description = "a red laser beam being reflected by a blue shield." + special_effects = "TRIGGER: When the opponent plays a spell card. Single use.
EFFECT: The spell card's effect is instead applied to the chosen target, and sent to the graveyard." + rarity_score = 1 \ No newline at end of file diff --git a/code/modules/battlemonsters/items/card.dm b/code/modules/battlemonsters/items/card.dm new file mode 100644 index 00000000000..365e38c832e --- /dev/null +++ b/code/modules/battlemonsters/items/card.dm @@ -0,0 +1,172 @@ +/obj/item/battle_monsters/card + name = "battle monsters card" + desc = "A battle monster's card." + + var/card_type = BATTLE_MONSTERS_CARDTYPE_MONSTER + var/datum/battle_monsters/element/prefix_datum + var/datum/battle_monsters/monster/root_datum + var/datum/battle_monsters/title/suffix_datum + + var/datum/battle_monsters/spell/spell_datum + var/datum/battle_monsters/trap/trap_datum + + w_class = ITEMSIZE_TINY + + //Card information here + +/obj/item/battle_monsters/card/Initialize(var/mapload,var/prefix,var/root,var/title,var/trap,var/spell) + . = ..() + Generate_Card(prefix, root, title, trap, spell) + +/obj/item/battle_monsters/card/attackby(var/obj/item/attacking, var/mob/user) + if(istype(attacking,/obj/item/battle_monsters/card) && attacking != src) + var/obj/item/battle_monsters/card/adding_card = attacking + make_deck(user,adding_card) + +/obj/item/battle_monsters/card/attack_self(mob/user as mob) + flip_card(user) + +/obj/item/battle_monsters/card/proc/make_deck(var/mob/user,var/obj/item/battle_monsters/card/adding_card) + + var/obj/item/battle_monsters/deck/new_deck = new(src.loc) + + if(src.loc == user) + //Make a hand. + user.drop_from_inventory(src) + new_deck.icon_state = "hand" + user.put_in_inactive_hand(new_deck) + to_chat(user,span("notice","You combine \the [src] and the [adding_card] to form a hand.")) + else + new_deck.set_dir(dir) + new_deck.pixel_x = pixel_x + new_deck.pixel_y = pixel_y + new_deck.layer = max(layer,new_deck.layer) + user.visible_message(\ + span("notice","\The [user] combines \the [src] and the [adding_card] to form a deck."),\ + span("notice","You combine \the [src] and the [adding_card] to form a deck.")\ + ) + + new_deck.add_card(user,src) + new_deck.add_card(user,adding_card) + +/obj/item/battle_monsters/card/proc/flip_card(var/mob/user) + facedown = !facedown + + if(src.loc == user) + if(!facedown) + to_chat(user,span("notice","You reveal \the [name] to yourself, preparing to play it face up.")) + else + to_chat(user,span("notice", "You prepare \the [name] to be played face down.")) + else + if(!facedown) + user.visible_message(\ + span("notice","\The [user] flip the card face up and reveals \the [name]."),\ + span("notice","You flip the card face up and reveal \the [name].")\ + ) + else + user.visible_message(\ + span("notice","\The [user] flips \the [name] face down."),\ + span("notice","You flip \the [name] face down.")\ + ) + + update_icon() + +/obj/item/battle_monsters/card/proc/Generate_Card(var/prefix,var/root,var/title,var/trap,var/spell) + + if(trap) + trap_datum = SSbattlemonsters.FindMatchingTrap(trap,TRUE) + update_icon() + return + + if(spell) + spell_datum = SSbattlemonsters.FindMatchingSpell(spell,TRUE) + update_icon() + return + + if(prefix) + prefix_datum = SSbattlemonsters.FindMatchingPrefix(prefix,TRUE) + else + prefix_datum = SSbattlemonsters.GetRandomPrefix() + + if(root) + root_datum = SSbattlemonsters.FindMatchingRoot(root,TRUE) + else + root_datum = SSbattlemonsters.GetRandomRoot() + + var/rarity_score = prefix_datum.rarity_score + root_datum.rarity_score + + if(title) + suffix_datum = SSbattlemonsters.FindMatchingSuffix(title,TRUE) + else if(rarity_score >= 3) + suffix_datum = SSbattlemonsters.GetRandomSuffix() + else + suffix_datum = SSbattlemonsters.FindMatchingSuffix("no_title",TRUE) + +/obj/item/battle_monsters/card/update_icon() + + cut_overlays() + + if(facedown) + icon_state = "back" + else + + var/rounded_rarity_score + + if(trap_datum) + rounded_rarity_score = trap_datum.rarity_score + else if(spell_datum) + rounded_rarity_score = spell_datum.rarity_score + else + rounded_rarity_score = prefix_datum.rarity_score + root_datum.rarity_score + suffix_datum.rarity_score + + rounded_rarity_score = min(max(round(rounded_rarity_score,1),1),4) + + icon_state = "front_r_[rounded_rarity_score]" + add_overlay("front_label") + + if(trap_datum && trap_datum.icon_state) + add_overlay(trap_datum.icon_state) + + if(spell_datum && spell_datum.icon_state) + add_overlay(spell_datum.icon_state) + + if(prefix_datum && prefix_datum.icon_state) + add_overlay(prefix_datum.icon_state) + + if(root_datum && root_datum.icon_state) + add_overlay(root_datum.icon_state) + + if(suffix_datum && suffix_datum.icon_state) + add_overlay(suffix_datum.icon_state) + + if(rounded_rarity_score >= 2) + add_overlay("rarity_animation") + + var/matrix/M = matrix() + switch(dir) + if(NORTH) + M.Turn(0) + if(SOUTH) + M.Turn(180) + if(WEST) + M.Turn(270) + if(EAST) + M.Turn(90) + + transform = M + +/obj/item/battle_monsters/card/examine(mob/user) + + ..() + + if(facedown && src.loc != user) + to_chat(user,span("notice","You can't examine \the [src] while it's face down!")) + return + + if(trap_datum) + SSbattlemonsters.ExamineTrapCard(user,trap_datum) + else if(spell_datum) + SSbattlemonsters.ExamineSpellCard(user,spell_datum) + else + SSbattlemonsters.ExamineMonsterCard(user,prefix_datum,root_datum,suffix_datum) + diff --git a/code/modules/battlemonsters/items/core.dm b/code/modules/battlemonsters/items/core.dm new file mode 100644 index 00000000000..f48580a975e --- /dev/null +++ b/code/modules/battlemonsters/items/core.dm @@ -0,0 +1,108 @@ +/obj/item/battle_monsters/ + icon = 'icons/obj/battle_monsters/card.dmi' + icon_state = "" + var/list/center_of_mass = list("x"=16, "y"=16) + var/facedown = TRUE + var/rotated = FALSE + +/obj/item/battle_monsters/dropped(mob/user as mob) + set_dir(user.dir) + if(rotated) + set_dir(turn(dir,90)) + update_icon() + . = ..() + +/obj/item/battle_monsters/pickup(mob/user as mob) + set_dir(NORTH) + if(rotated) + set_dir(turn(dir,90)) + update_icon() + . = ..() + +/obj/item/battle_monsters/MouseDrop(mob/user) //Dropping the card onto something else. + if(istype(user)) + user.put_in_active_hand(src) + src.pickup(user) + return + + . = ..() + +/obj/item/battle_monsters/MouseDrop_T(var/atom/movable/C, mob/user) //Dropping C onto the card + if(istype(C,/obj/item/battle_monsters)) + src.attackby(C,user) + return + + . = ..() + +/obj/item/battle_monsters/AltClick(var/mob/user) + RotateCard(user) + +/obj/item/battle_monsters/CtrlClick(var/mob/user) + attack_self(user) + +/obj/item/battle_monsters/proc/RotateCard(var/mob/user) + + rotated = !rotated + + if(rotated) + if(src.loc == user) + to_chat(user,span("notice", "You prepare \the [name] to be played horizontally.")) + set_dir(turn(NORTH,90)) + else + set_dir(turn(user.dir,90)) + user.visible_message(\ + span("notice","\The [user] adjusts the orientation of \the [src] horizontally."),\ + span("notice","You adjust the orientation of \the [src] horizontally.")\ + ) + else + if(src.loc == user) + to_chat(user,span("notice", "You prepare \the [name] to be played vertically.")) + set_dir(NORTH) + else + set_dir(user.dir) + user.visible_message(\ + span("notice","\The [user] adjusts the orientation of \the [src] vertically."),\ + span("notice","You adjust the orientation of \the [src] vertically.")\ + ) + + update_icon() + + +#define CELLS_X 6 +#define CELLSIZE_X (32/CELLS_X) + +#define CELLS_Y 6 +#define CELLSIZE_Y (32/CELLS_Y) + +/obj/item/battle_monsters/afterattack(atom/A, mob/user, proximity, params) //Copy and pasted from foodcode. + if(proximity && params && (istype(A, /obj/structure/table) || (istype(A,/obj/structure/dueling_table) && A.density)) && center_of_mass.len) + + user.visible_message(\ + span("notice","\The [user] plays \the [src]."),\ + span("notice","You play \the [src].")\ + ) + + //Places the item on a grid + var/list/mouse_control = params2list(params) + + var/mouse_x = text2num(mouse_control["icon-x"]) + var/mouse_y = text2num(mouse_control["icon-y"]) + + if(!isnum(mouse_x) || !isnum(mouse_y)) + return + + var/cell_x = max(0, min(CELLS_X-1, round(mouse_x/CELLSIZE_X))) + var/cell_y = max(0, min(CELLS_Y-1, round(mouse_y/CELLSIZE_Y))) + + pixel_x = (CELLSIZE_X * (0.5 + cell_x)) - center_of_mass["x"] + pixel_y = (CELLSIZE_Y * (0.5 + cell_y)) - center_of_mass["y"] + + layer = A.layer + 0.1 + + . = ..() + +#undef CELLS_X +#undef CELLSIZE_X + +#undef CELLS_Y +#undef CELLSIZE_Y \ No newline at end of file diff --git a/code/modules/battlemonsters/items/deck.dm b/code/modules/battlemonsters/items/deck.dm new file mode 100644 index 00000000000..3182c266f89 --- /dev/null +++ b/code/modules/battlemonsters/items/deck.dm @@ -0,0 +1,167 @@ +/obj/item/battle_monsters/deck + name = "battle monsters deck" + icon_state = "stack" + w_class = ITEMSIZE_SMALL + var/list/stored_card_names = list() + var/deck_size = 52 + +/obj/item/battle_monsters/deck/proc/get_top_card() + return stored_card_names[stored_card_names.len] + +/obj/item/battle_monsters/deck/proc/get_bottom_card() + return stored_card_names[1] + +/obj/item/battle_monsters/deck/proc/add_card(var/user, var/obj/item/battle_monsters/card/added_card) + + if(added_card.spell_datum) + stored_card_names += "spell_type,[added_card.spell_datum.id],no_title" + else if(added_card.trap_datum) + stored_card_names += "trap_type,[added_card.trap_datum.id],no_title" + else + stored_card_names += "[added_card.prefix_datum.id],[added_card.root_datum.id],[added_card.suffix_datum.id]" + + qdel(added_card) + +/obj/item/battle_monsters/deck/proc/take_card(var/mob/user) + + if(icon_state == "stack") //Deck form + user.visible_message(\ + span("notice","\The [user] draws a card from their [src]."),\ + span("notice","You draw a card from their [src].")\ + ) + else + user.visible_message(\ + span("notice","\The [user] takes a card from their hand."),\ + span("notice","You take a card from your hand.")\ + ) + + take_specific_card(user,get_top_card()) + +/obj/item/battle_monsters/deck/proc/take_specific_card(var/mob/user, var/card_id) + if(card_id in stored_card_names) + var/obj/item/battle_monsters/card/new_card = SSbattlemonsters.CreateCard(card_id,src.loc) + + if(!user.get_active_hand()) + user.put_in_active_hand(new_card) + else if(!user.get_inactive_hand()) + user.put_in_inactive_hand(new_card) + else + to_chat(user,span("notice","Your hands are full!")) + return + + new_card.pickup(user) + stored_card_names -= card_id + + if(stored_card_names.len <= 0) + qdel(src) + +/obj/item/battle_monsters/deck/MouseDrop_T(var/atom/movable/C, mob/user) //Dropping C onto the card + + if(istype(C,/obj/item/battle_monsters/deck/)) + + var/obj/item/battle_monsters/deck/added_deck = C + stored_card_names += added_deck.stored_card_names + + user.visible_message(\ + span("notice","\The [user] combines two decks together."),\ + span("notice","You combine too decks together.")\ + ) + + qdel(C) + return + + . = ..() + +/obj/item/battle_monsters/deck/verb/toggle_mode() + set category = "Object" + set name = "Change Deck Type" + set src in view(1) + + if (use_check(usr, USE_DISALLOW_SILICONS)) + return + + if(icon_state == "hand") + usr.visible_message(\ + span("notice","\The [usr] turns their hand into a stack of cards."),\ + span("notice","You turn your hand into a stack of cards.")\ + ) + icon_state = "stack" + else + usr.visible_message(\ + span("notice","\The [usr] turns their stack of cards into a hand."),\ + span("notice","You turn your stack of cards into a hand.")\ + ) + icon_state = "hand" + +/obj/item/battle_monsters/deck/verb/shuffle_deck() + set category = "Object" + set name = "Shuffle Deck" + set src in view(1) + + if (use_check(usr, USE_DISALLOW_SILICONS)) + return + + usr.visible_message(\ + span("notice","\The [usr] shuffles \the [src]."),\ + span("notice","You shuffle \the [src].")\ + ) + + playsound(src.loc, 'sound/items/cardshuffle.ogg', 100, 1, -4) + + stored_card_names = shuffle(stored_card_names) + +/obj/item/battle_monsters/deck/attack_hand(var/mob/user) + take_card(user) + +/obj/item/battle_monsters/deck/attackby(var/obj/item/attacking, var/mob/user) + if(istype(attacking,/obj/item/battle_monsters/card) && attacking != src) + var/obj/item/battle_monsters/card/adding_card = attacking + add_card(user,adding_card) + +/obj/item/battle_monsters/deck/attack_self(mob/user) + + if(user != src.loc) //Idk how this is possible but you never know. + to_chat(user,span("notice","You'll have to pick up \the [src] to examine the cards!")) + return + + if(icon_state != "hand") + user.visible_message(\ + span("notice","\The [usr] begins searching through \the [src]..."),\ + span("notice","You begin searching through your deck..")\ + ) + if(!do_after(user, 40, act_target = src)) + user.visible_message(\ + span("notice","\The [usr] stops and thinks better of it."),\ + span("notice","You top and think better of it.")\ + ) + return + + BrowseDeck(user) + +/obj/item/battle_monsters/deck/proc/BrowseDeck(var/mob/user) + var/browse_data = "" + for(var/cardname in stored_card_names) + var/list/splitstring = dd_text2List(cardname,",") + var/formatted_data + if(splitstring[1] == "spell_type") + formatted_data = SSbattlemonsters.FormatSpellText(SSbattlemonsters.GetSpellFormatting(),SSbattlemonsters.FindMatchingSpell(splitstring[2])) + else if(splitstring[1] == "trap_type") + formatted_data = SSbattlemonsters.FormatSpellText(SSbattlemonsters.GetTrapFormatting(),SSbattlemonsters.FindMatchingTrap(splitstring[2])) + else + var/datum/battle_monsters/element/prefix_datum = SSbattlemonsters.FindMatchingPrefix(splitstring[1]) + var/datum/battle_monsters/monster/root_datum = SSbattlemonsters.FindMatchingRoot(splitstring[2]) + var/datum/battle_monsters/title/suffix_datum = SSbattlemonsters.FindMatchingSuffix(splitstring[3]) + formatted_data = SSbattlemonsters.FormatMonsterText(SSbattlemonsters.GetMonsterFormatting(),prefix_datum,root_datum,suffix_datum) + + browse_data = "[formatted_data]
Draw Card

[browse_data]" + + user << browse(browse_data, "window=battlemonsters_hand") + +/obj/item/battle_monsters/deck/Topic(href,href_list) + if(..()) + return 1 + + if(href_list["selection"]) + take_specific_card(usr, href_list["selection"]) + BrowseDeck(usr) + diff --git a/code/modules/battlemonsters/items/furniture/dueling_area.dm b/code/modules/battlemonsters/items/furniture/dueling_area.dm new file mode 100644 index 00000000000..9bfb0926640 --- /dev/null +++ b/code/modules/battlemonsters/items/furniture/dueling_area.dm @@ -0,0 +1,52 @@ +/obj/structure/dueling_table + name = "dueling table" + icon = 'icons/obj/battle_monsters/furniture.dmi' + anchored = 1 + density = 1 + climbable = 1 + throwpass = 1 + +/obj/structure/dueling_table/no_collide + density = 0 + +/obj/structure/dueling_table/no_collide/above_layer + layer = ABOVE_MOB_LAYER + +/obj/effect/decal/battlemonsters_logo + name = "battlemonsters logo" + icon = 'icons/obj/battle_monsters/logo.dmi' + icon_state = "logo" + anchored = 1 + density = 0 + mouse_opacity = 0 + +/obj/structure/dueling_table/attackby(obj/item/W as obj, mob/user as mob) + user.drop_item(src.loc) + return + +/obj/machinery/vending/battlemonsters + name = "\improper Battlemonsters vendor" + desc = "A good place to dump all your rent money." + icon_state = "battlemonsters" + vend_id = "battlemonsters" + products = list( + /obj/item/weapon/book/manual/battlemonsters = 5, + /obj/item/battle_monsters/wrapped = 20, + /obj/item/battle_monsters/wrapped/pro = 10, + /obj/item/battle_monsters/wrapped/rare = 2 + ) + prices = list( + /obj/item/weapon/book/manual/battlemonsters = 10, + /obj/item/battle_monsters/wrapped = 150, + /obj/item/battle_monsters/wrapped/pro = 75, + /obj/item/battle_monsters/wrapped/rare = 200, + /obj/item/battle_monsters/wrapped/legendary = 400 + ) + contraband = list( + /obj/item/battle_monsters/wrapped/legendary = 1 + ) + premium = list( + /obj/item/weapon/coin/battlemonsters = 10 + ) + + restock_items = 0 \ No newline at end of file diff --git a/code/modules/battlemonsters/items/wrapped.dm b/code/modules/battlemonsters/items/wrapped.dm new file mode 100644 index 00000000000..32a04880b23 --- /dev/null +++ b/code/modules/battlemonsters/items/wrapped.dm @@ -0,0 +1,59 @@ +/obj/item/battle_monsters/wrapped + name = "battle monsters starterpack" + desc = "A battle monsters 52 card deck starterpack. Contains 52 basic cards and a lifetime of sadness." + icon_state = "pack1" + w_class = ITEMSIZE_SMALL + var/contained_cards = 52 + var/rarity_max = BATTLE_MONSTERS_RARITY_COMMON + var/rarity_min = BATTLE_MONSTERS_RARITY_UNCOMMON + +/obj/item/battle_monsters/wrapped/attack_self(mob/user) + var/list/deck_data = list() + for(var/i=1,i <= contained_cards,i++) + CHECK_TICK //This stuff is a little intensive I think. + if(prob(25)) + if(prob(50)) + var/datum/battle_monsters/selected_trap = SSbattlemonsters.GetRandomTrap() + deck_data += "trap_type,[selected_trap.id],no_title" + else + var/datum/battle_monsters/selected_spell = SSbattlemonsters.GetRandomSpell() + deck_data += "spell_type,[selected_spell.id],no_title" + continue + + var/datum/battle_monsters/selected_prefix = SSbattlemonsters.GetRandomPrefix_Filtered(rarity_min,rarity_max) + var/datum/battle_monsters/selected_root = SSbattlemonsters.GetRandomRoot_Filtered(rarity_min,rarity_max) + var/datum/battle_monsters/selected_suffix = SSbattlemonsters.GetRandomSuffix_Filtered(rarity_min,rarity_max) + deck_data += "[selected_prefix.id],[selected_root.id],[(selected_prefix.rarity_score + selected_root.rarity_score) >= 3 ? selected_suffix.id : "no_title"]" + user.visible_message(\ + span("notice","\The [user] unwraps \the [src]."),\ + span("notice","You unwrap \the [src].")\ + ) + var/obj/item/battle_monsters/deck/generated_deck = new(get_turf(src)) + generated_deck.stored_card_names = deck_data + user.drop_from_inventory(src) + user.put_in_active_hand(generated_deck) + qdel(src) + +/obj/item/battle_monsters/wrapped/pro + name = "battle monsters booster pack" + desc = "A pack of 10 rare battle monster cards, with a chance of having legendary cards." + icon_state = "pack2" + contained_cards = 10 + rarity_max = BATTLE_MONSTERS_RARITY_UNCOMMON + rarity_min = BATTLE_MONSTERS_RARITY_LEGENDARY + +/obj/item/battle_monsters/wrapped/rare + name = "battle monsters rare booster pack" + desc = "A pack of 10 ultra-rare battle monster cards." + icon_state = "pack2" + contained_cards = 10 + rarity_max = BATTLE_MONSTERS_RARITY_RARE + rarity_min = BATTLE_MONSTERS_RARITY_LEGENDARY + +/obj/item/battle_monsters/wrapped/legendary + name = "battle monsters rare booster pack" + desc = "A pack of 4 legendary battle monster cards." + icon_state = "pack2" + contained_cards = 4 + rarity_max = BATTLE_MONSTERS_RARITY_LEGENDARY + rarity_min = BATTLE_MONSTERS_RARITY_LEGENDARY \ No newline at end of file diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index 2fc11e61bdb..6df6a456c7b 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -168,7 +168,8 @@ var/list/asset_datums = list() "bootstrap.min.js" = 'html/bootstrap/js/bootstrap.min.js', "jquery-2.0.0.min.js" = 'html/jquery/jquery-2.0.0.min.js', "ie-truth.min.js" = 'html/iestats/ie-truth.min.js', - "conninfo.min.js" = 'html/iestats/conninfo.min.js' + "conninfo.min.js" = 'html/iestats/conninfo.min.js', + "copyright_infrigement.png" = 'html/copyright_infrigement.png' ) /datum/asset/simple/paper diff --git a/code/modules/client/preference_setup/loadout/loadout_general.dm b/code/modules/client/preference_setup/loadout/loadout_general.dm index bd1b6044a1e..2f4efc4172b 100644 --- a/code/modules/client/preference_setup/loadout/loadout_general.dm +++ b/code/modules/client/preference_setup/loadout/loadout_general.dm @@ -117,4 +117,8 @@ /datum/gear/chess display_name = "chess game kit" - path = /obj/item/weapon/storage/box/chess_kit \ No newline at end of file + path = /obj/item/weapon/storage/box/chess_kit + +/datum/gear/battlemonsters + display_name = "battlemonsters starter deck" + path = /obj/item/battle_monsters/wrapped \ No newline at end of file diff --git a/code/modules/holodeck/HolodeckControl.dm b/code/modules/holodeck/HolodeckControl.dm index a1aafdecedf..509c11bdb2b 100644 --- a/code/modules/holodeck/HolodeckControl.dm +++ b/code/modules/holodeck/HolodeckControl.dm @@ -281,6 +281,8 @@ for(var/obj/holo_obj in holographic_objs) holo_obj.alpha *= 0.8 //give holodeck objs a slight transparency + linkedholodeck.loop_ambience = HP.loop_ambience + if(HP.ambience) linkedholodeck.forced_ambience = HP.ambience else diff --git a/code/modules/holodeck/HolodeckPrograms.dm b/code/modules/holodeck/HolodeckPrograms.dm index 4ae4361a21c..d1bca9a3e9c 100644 --- a/code/modules/holodeck/HolodeckPrograms.dm +++ b/code/modules/holodeck/HolodeckPrograms.dm @@ -1,7 +1,9 @@ /datum/holodeck_program var/target var/list/ambience = null + var/loop_ambience = TRUE -/datum/holodeck_program/New(var/target, var/list/ambience = null) +/datum/holodeck_program/New(var/target, var/list/ambience = null, var/loop_ambience = TRUE) src.target = target src.ambience = ambience + src.loop_ambience = loop_ambience diff --git a/code/modules/mining/coins.dm b/code/modules/mining/coins.dm index cd976f08a3d..2046e894423 100644 --- a/code/modules/mining/coins.dm +++ b/code/modules/mining/coins.dm @@ -44,6 +44,10 @@ name = "platinum coin" icon_state = "coin_adamantine" +/obj/item/weapon/coin/battlemonsters + name = "battlemonsters coin" + icon_state = "coin_battlemonsters" + /obj/item/weapon/coin/attackby(obj/item/weapon/W as obj, mob/user as mob) if(iscoil(W)) var/obj/item/stack/cable_coil/CC = W diff --git a/html/changelogs/burgerbb-card_game.yml b/html/changelogs/burgerbb-card_game.yml new file mode 100644 index 00000000000..cbcbf3807a4 --- /dev/null +++ b/html/changelogs/burgerbb-card_game.yml @@ -0,0 +1,38 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +# balance +################################# + +# Your name. +author: BurgerBB + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Added a fun new card game; Battle Monsters. A vending machine that dispenses these cards and the rulebook can be found in the library." + - rscadd: "Added a new holodeck preset: Battlemonsters Arena. Now you can duel it out like manchildren in the holodeck." diff --git a/html/copyright_infrigement.png b/html/copyright_infrigement.png new file mode 100644 index 00000000000..b698de85a1e Binary files /dev/null and b/html/copyright_infrigement.png differ diff --git a/icons/obj/battle_monsters/card.dmi b/icons/obj/battle_monsters/card.dmi new file mode 100644 index 00000000000..665c8ad9a20 Binary files /dev/null and b/icons/obj/battle_monsters/card.dmi differ diff --git a/icons/obj/battle_monsters/furniture.dmi b/icons/obj/battle_monsters/furniture.dmi new file mode 100644 index 00000000000..e6182b2dde7 Binary files /dev/null and b/icons/obj/battle_monsters/furniture.dmi differ diff --git a/icons/obj/battle_monsters/logo.dmi b/icons/obj/battle_monsters/logo.dmi new file mode 100644 index 00000000000..4a19141fd4a Binary files /dev/null and b/icons/obj/battle_monsters/logo.dmi differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index caea425c2de..04e89d7df9c 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index 40f3d109791..346976b4e79 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/vending.dmi b/icons/obj/vending.dmi index 78b2dfbe5b6..0e5f71d980c 100755 Binary files a/icons/obj/vending.dmi and b/icons/obj/vending.dmi differ diff --git a/maps/_common/areas/holodeck.dm b/maps/_common/areas/holodeck.dm index c27fe7cd8e3..342789fc307 100644 --- a/maps/_common/areas/holodeck.dm +++ b/maps/_common/areas/holodeck.dm @@ -78,3 +78,7 @@ name = "\improper Holodeck - Space" has_gravity = 0 sound_env = SPACE + +/area/holodeck/source_battlemonsters + name = "\improper Holodeck - Battlemonsters Arena" + sound_env = ARENA diff --git a/maps/aurora/aurora-1_centcomm.dmm b/maps/aurora/aurora-1_centcomm.dmm index 383dbc14e70..0e3fd3f8df8 100644 --- a/maps/aurora/aurora-1_centcomm.dmm +++ b/maps/aurora/aurora-1_centcomm.dmm @@ -12518,12 +12518,8 @@ }, /area/centcom/control) "BS" = ( -/turf/template_noop, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/shuttle/wall/dark{ - icon_state = "swall_c" - }, -/area/template_noop) +/turf/simulated/floor/holofloor/tiled/dark, +/area/holodeck/source_battlemonsters) "BT" = ( /obj/effect/decal/cleanable/dirt, /turf/unsimulated/floor{ @@ -13039,37 +13035,27 @@ }, /area/centcom/holding) "Df" = ( -/turf/template_noop, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/shuttle/wall/dark{ - icon_state = "swall_c"; - dir = 8 - }, -/area/template_noop) +/obj/structure/holostool, +/turf/simulated/floor/holofloor/tiled/dark, +/area/holodeck/source_battlemonsters) "Dg" = ( -/turf/template_noop, -/obj/effect/decal/cleanable/dirt, -/turf/simulated/shuttle/wall/dark{ - icon_state = "swall_c"; +/obj/structure/window/reinforced/holowindow{ dir = 4 }, -/area/template_noop) +/obj/structure/holostool, +/turf/simulated/floor/holofloor/tiled/dark, +/area/holodeck/source_battlemonsters) "Dh" = ( -/turf/unsimulated/floor{ - icon_state = "gcircuit" +/obj/structure/dueling_table/no_collide/above_layer{ + icon_state = "top_left" }, -/obj/structure/artilleryplaceholder/decorative{ - icon_state = "27" +/obj/effect/decal/battlemonsters_logo, +/obj/effect/floor_decal/spline/fancy/wood{ + icon_state = "spline_fancy"; + dir = 9 }, -/obj/structure/table/reinforced/steel, -/obj/machinery/button/remote/blast_door{ - id = "battery3"; - name = "Battery 3 Firing Control" - }, -/turf/unsimulated/floor{ - icon_state = "wood_siding10" - }, -/area/centcom/control) +/turf/simulated/floor/holofloor/wood, +/area/holodeck/source_battlemonsters) "Di" = ( /obj/machinery/light/spot{ icon_state = "tube1"; @@ -13141,21 +13127,15 @@ }, /area/centcom/holding) "Dr" = ( -/turf/unsimulated/floor{ - icon_state = "gcircuit" +/obj/structure/dueling_table/no_collide/above_layer{ + icon_state = "top_center" }, -/obj/structure/artilleryplaceholder/decorative{ - icon_state = "28" +/obj/effect/floor_decal/spline/fancy/wood{ + icon_state = "spline_fancy"; + dir = 1 }, -/obj/machinery/artillerycontrol{ - desc = "Bluespace Artillery; the thinking man's solution." - }, -/obj/effect/decal/warning_stripes, -/turf/unsimulated/floor{ - icon_state = "wood_siding2"; - dir = 6 - }, -/area/centcom/control) +/turf/simulated/floor/holofloor/wood, +/area/holodeck/source_battlemonsters) "Ds" = ( /turf/simulated/shuttle/floor, /area/shuttle/escape/centcom) @@ -13216,6 +13196,16 @@ icon_state = "floor" }, /area/centcom/holding) +"DA" = ( +/obj/structure/dueling_table/no_collide/above_layer{ + icon_state = "top_right" + }, +/obj/effect/floor_decal/spline/fancy/wood{ + icon_state = "spline_fancy"; + dir = 5 + }, +/turf/simulated/floor/holofloor/wood, +/area/holodeck/source_battlemonsters) "DB" = ( /obj/machinery/light/spot, /turf/simulated/shuttle/plating, @@ -13291,17 +13281,12 @@ }, /area/centcom/holding) "DJ" = ( -/turf/unsimulated/floor{ - icon_state = "gcircuit" +/obj/structure/window/reinforced/holowindow{ + dir = 8 }, -/obj/structure/artilleryplaceholder/decorative{ - icon_state = "29" - }, -/obj/machinery/porta_turret/crescent, -/turf/unsimulated/floor{ - icon_state = "wood_siding6" - }, -/area/centcom/control) +/obj/structure/holostool, +/turf/simulated/floor/holofloor/tiled/dark, +/area/holodeck/source_battlemonsters) "DK" = ( /obj/item/modular_computer/console/preset/security, /turf/simulated/shuttle/floor{ @@ -13309,22 +13294,15 @@ }, /area/shuttle/escape/centcom) "DL" = ( -/turf/unsimulated/floor{ - icon_state = "engine" +/obj/structure/dueling_table{ + icon_state = "center_left" }, -/obj/structure/window/phoronreinforced, -/obj/structure/window/phoronreinforced{ - icon_state = "phoronrwindow"; - dir = 1 - }, -/obj/structure/window/phoronreinforced{ - icon_state = "phoronrwindow"; +/obj/effect/floor_decal/spline/fancy/wood{ + icon_state = "spline_fancy"; dir = 8 }, -/turf/unsimulated/floor{ - icon_state = "wood_siding9" - }, -/area/centcom/control) +/turf/simulated/floor/holofloor/wood, +/area/holodeck/source_battlemonsters) "DM" = ( /turf/unsimulated/wall/riveted, /area/centcom/ferry) @@ -13515,21 +13493,12 @@ }, /area/centcom/ferry) "Eh" = ( -/turf/unsimulated/floor{ - icon_state = "gcircuit" +/turf/template_noop, +/obj/effect/decal/cleanable/dirt, +/turf/simulated/shuttle/wall/dark{ + icon_state = "swall_c" }, -/obj/structure/artilleryplaceholder/decorative{ - icon_state = "27" - }, -/obj/structure/table/reinforced/steel, -/obj/machinery/button/remote/blast_door{ - id = "battery2"; - name = "Battery 2 Firing Control" - }, -/turf/unsimulated/floor{ - icon_state = "wood_siding10" - }, -/area/centcom/control) +/area/template_noop) "Ei" = ( /obj/item/clothing/head/collectable/paper, /turf/unsimulated/beach/sand, @@ -13593,23 +13562,15 @@ }, /area/centcom/holding) "Er" = ( -/turf/unsimulated/floor{ - icon_state = "gcircuit" +/obj/structure/dueling_table{ + icon_state = "center_right" }, -/obj/structure/artilleryplaceholder/decorative{ - icon_state = "27" +/obj/effect/floor_decal/spline/fancy/wood{ + icon_state = "spline_fancy"; + dir = 4 }, -/obj/structure/table/reinforced/steel, -/obj/machinery/button/remote/blast_door{ - id = "battery1"; - name = "Battery 1 Firing Control" - }, -/obj/effect/decal/cleanable/cobweb, -/obj/item/weapon/reagent_containers/glass/rag, -/turf/unsimulated/floor{ - icon_state = "wood_siding10" - }, -/area/centcom/control) +/turf/simulated/floor/holofloor/wood, +/area/holodeck/source_battlemonsters) "Es" = ( /turf/unsimulated/floor{ icon_state = "sandwater" @@ -13785,15 +13746,15 @@ }, /area/centcom/holding) "ER" = ( -/turf/unsimulated/floor{ - icon_state = "engine" +/obj/structure/dueling_table/no_collide{ + icon_state = "bottom_leftt" }, -/obj/effect/decal/cleanable/dirt, -/turf/unsimulated/floor{ - icon_state = "wood_siding1"; - dir = 6 +/obj/effect/floor_decal/spline/fancy/wood{ + icon_state = "spline_fancy"; + dir = 8 }, -/area/centcom/control) +/turf/simulated/floor/holofloor/wood, +/area/holodeck/source_battlemonsters) "ES" = ( /obj/machinery/camera/network/crescent{ c_tag = "Crescent Arrivals East" @@ -13803,16 +13764,11 @@ }, /area/centcom/holding) "ET" = ( -/turf/unsimulated/floor{ - icon_state = "engine" +/obj/structure/dueling_table/no_collide{ + icon_state = "bottom_center" }, -/obj/effect/decal/cleanable/dirt, -/obj/item/weapon/stool, -/turf/unsimulated/floor{ - icon_state = "wood_siding1"; - dir = 6 - }, -/area/centcom/control) +/turf/simulated/floor/holofloor/wood, +/area/holodeck/source_battlemonsters) "EU" = ( /obj/machinery/door/airlock/external{ frequency = 1380; @@ -13950,34 +13906,25 @@ }, /area/centcom/holding) "Fl" = ( -/turf/unsimulated/floor{ - icon_state = "engine" +/obj/structure/dueling_table/no_collide{ + icon_state = "bottom_right" }, -/obj/effect/decal/cleanable/dirt, -/obj/item/weapon/storage/toolbox/electrical, -/turf/unsimulated/floor{ - icon_state = "wood_siding1"; - dir = 6 +/obj/effect/floor_decal/spline/fancy/wood{ + icon_state = "spline_fancy"; + dir = 4 }, -/area/centcom/control) +/turf/simulated/floor/holofloor/wood, +/area/holodeck/source_battlemonsters) "Fm" = ( -/turf/unsimulated/floor{ - icon_state = "engine" +/obj/structure/dueling_table/no_collide/above_layer{ + icon_state = "top_left" }, -/obj/structure/window/phoronreinforced{ - icon_state = "phoronrwindow"; +/obj/effect/floor_decal/spline/fancy/wood{ + icon_state = "spline_fancy"; dir = 8 }, -/obj/structure/window/phoronreinforced{ - icon_state = "phoronrwindow"; - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/generic, -/turf/unsimulated/floor{ - icon_state = "wood_siding9" - }, -/area/centcom/control) +/turf/simulated/floor/holofloor/wood, +/area/holodeck/source_battlemonsters) "Fn" = ( /obj/machinery/computer/med_data, /obj/structure/window/reinforced{ @@ -14357,6 +14304,13 @@ icon_state = "floor3" }, /area/shuttle/escape/centcom) +"Ga" = ( +/obj/effect/decal/battlemonsters_logo{ + icon_state = "logo"; + dir = 1 + }, +/turf/simulated/floor/holofloor/tiled/dark, +/area/holodeck/source_battlemonsters) "Gb" = ( /turf/unsimulated/floor{ icon_state = "greencorner"; @@ -15121,6 +15075,13 @@ "HK" = ( /turf/unsimulated/wall/riveted, /area/centcom/spawning) +"HL" = ( +/obj/effect/floor_decal/spline/fancy/wood{ + icon_state = "spline_fancy"; + dir = 9 + }, +/turf/simulated/floor/holofloor/reinforced, +/area/holodeck/source_battlemonsters) "HM" = ( /obj/structure/window/reinforced, /obj/structure/window/reinforced{ @@ -17188,6 +17149,10 @@ /obj/structure/sign/biohazard, /turf/unsimulated/wall/riveted, /area/centcom/spawning) +"Ma" = ( +/obj/structure/banner, +/turf/simulated/floor/holofloor/tiled/dark, +/area/holodeck/source_battlemonsters) "Mb" = ( /obj/structure/window/reinforced{ dir = 8 @@ -22003,15 +21968,11 @@ /turf/simulated/shuttle/floor, /area/shuttle/escape/centcom) "WE" = ( -/turf/unsimulated/floor{ - icon_state = "wood" +/obj/structure/dueling_table/no_collide/above_layer{ + icon_state = "top_center" }, -/obj/item/weapon/stool/padded, -/turf/unsimulated/floor{ - name = "plating"; - icon_state = "siding2" - }, -/area/centcom/holding) +/turf/simulated/floor/holofloor/wood, +/area/holodeck/source_battlemonsters) "WF" = ( /obj/machinery/status_display{ pixel_y = -32 @@ -22318,49 +22279,38 @@ }, /area/centcom/spawning) "Xl" = ( -/turf/unsimulated/floor{ - icon_state = "floor" +/obj/structure/dueling_table/no_collide/above_layer{ + icon_state = "top_right" }, -/obj/structure/bed/chair/unmovable{ - dir = 1 +/obj/effect/floor_decal/spline/fancy/wood{ + icon_state = "spline_fancy"; + dir = 4 }, -/turf/unsimulated/floor{ - icon_state = "wood_siding2" - }, -/area/centcom/spawning) +/turf/simulated/floor/holofloor/wood, +/area/holodeck/source_battlemonsters) "Xm" = ( -/turf/unsimulated/floor{ - icon_state = "floor" +/obj/structure/dueling_table{ + icon_state = "center_center" }, -/obj/machinery/vending/snack{ - name = "Free Chocolate Corp"; - prices = list() - }, -/turf/unsimulated/floor{ - icon_state = "wood_siding4" - }, -/area/centcom/spawning) +/turf/simulated/floor/holofloor/wood, +/area/holodeck/source_battlemonsters) "Xn" = ( -/turf/unsimulated/floor{ - icon_state = "floor" +/obj/structure/dueling_table/no_collide{ + icon_state = "bottom_leftt" }, -/obj/machinery/vending/cola{ - name = "Free Robust Softdrinks"; - prices = list() +/obj/effect/floor_decal/spline/fancy/wood{ + icon_state = "spline_fancy"; + dir = 10 }, -/turf/unsimulated/floor{ - icon_state = "wood_siding8" - }, -/area/centcom/spawning) +/turf/simulated/floor/holofloor/wood, +/area/holodeck/source_battlemonsters) "Xo" = ( -/turf/unsimulated/floor{ - icon_state = "floor" +/obj/structure/dueling_table/no_collide{ + icon_state = "bottom_center" }, -/obj/structure/bed/chair/unmovable, -/turf/unsimulated/floor{ - icon_state = "wood_siding1" - }, -/area/centcom/spawning) +/obj/effect/floor_decal/spline/fancy/wood, +/turf/simulated/floor/holofloor/wood, +/area/holodeck/source_battlemonsters) "Xp" = ( /obj/machinery/light{ dir = 8 @@ -22377,6 +22327,263 @@ }, /turf/simulated/floor/tiled/ramp, /area/shuttle/escape/centcom) +"Xr" = ( +/obj/structure/dueling_table/no_collide{ + icon_state = "bottom_right" + }, +/obj/effect/floor_decal/spline/fancy/wood{ + icon_state = "spline_fancy"; + dir = 6 + }, +/turf/simulated/floor/holofloor/wood, +/area/holodeck/source_battlemonsters) +"Xs" = ( +/obj/effect/floor_decal/spline/fancy/wood{ + icon_state = "spline_fancy"; + dir = 1 + }, +/turf/simulated/floor/holofloor/reinforced, +/area/holodeck/source_battlemonsters) +"Xt" = ( +/obj/effect/floor_decal/spline/fancy/wood{ + icon_state = "spline_fancy"; + dir = 5 + }, +/turf/simulated/floor/holofloor/reinforced, +/area/holodeck/source_battlemonsters) +"Xu" = ( +/obj/effect/floor_decal/spline/fancy/wood{ + icon_state = "spline_fancy"; + dir = 10 + }, +/turf/simulated/floor/holofloor/reinforced, +/area/holodeck/source_battlemonsters) +"Xv" = ( +/obj/effect/floor_decal/spline/fancy/wood, +/turf/simulated/floor/holofloor/reinforced, +/area/holodeck/source_battlemonsters) +"Xw" = ( +/obj/effect/floor_decal/spline/fancy/wood{ + icon_state = "spline_fancy"; + dir = 6 + }, +/turf/simulated/floor/holofloor/reinforced, +/area/holodeck/source_battlemonsters) +"Xx" = ( +/turf/template_noop, +/obj/effect/decal/cleanable/dirt, +/turf/simulated/shuttle/wall/dark{ + icon_state = "swall_c"; + dir = 8 + }, +/area/template_noop) +"Xy" = ( +/turf/template_noop, +/obj/effect/decal/cleanable/dirt, +/turf/simulated/shuttle/wall/dark{ + icon_state = "swall_c"; + dir = 4 + }, +/area/template_noop) +"Xz" = ( +/turf/unsimulated/floor{ + icon_state = "gcircuit" + }, +/obj/structure/artilleryplaceholder/decorative{ + icon_state = "27" + }, +/obj/structure/table/reinforced/steel, +/obj/machinery/button/remote/blast_door{ + id = "battery3"; + name = "Battery 3 Firing Control" + }, +/turf/unsimulated/floor{ + icon_state = "wood_siding10" + }, +/area/centcom/control) +"XA" = ( +/turf/unsimulated/floor{ + icon_state = "gcircuit" + }, +/obj/structure/artilleryplaceholder/decorative{ + icon_state = "28" + }, +/obj/machinery/artillerycontrol{ + desc = "Bluespace Artillery; the thinking man's solution." + }, +/obj/effect/decal/warning_stripes, +/turf/unsimulated/floor{ + icon_state = "wood_siding2"; + dir = 6 + }, +/area/centcom/control) +"XB" = ( +/turf/unsimulated/floor{ + icon_state = "gcircuit" + }, +/obj/structure/artilleryplaceholder/decorative{ + icon_state = "29" + }, +/obj/machinery/porta_turret/crescent, +/turf/unsimulated/floor{ + icon_state = "wood_siding6" + }, +/area/centcom/control) +"XC" = ( +/turf/unsimulated/floor{ + icon_state = "engine" + }, +/obj/structure/window/phoronreinforced, +/obj/structure/window/phoronreinforced{ + icon_state = "phoronrwindow"; + dir = 1 + }, +/obj/structure/window/phoronreinforced{ + icon_state = "phoronrwindow"; + dir = 8 + }, +/turf/unsimulated/floor{ + icon_state = "wood_siding9" + }, +/area/centcom/control) +"XD" = ( +/turf/unsimulated/floor{ + icon_state = "gcircuit" + }, +/obj/structure/artilleryplaceholder/decorative{ + icon_state = "27" + }, +/obj/structure/table/reinforced/steel, +/obj/machinery/button/remote/blast_door{ + id = "battery2"; + name = "Battery 2 Firing Control" + }, +/turf/unsimulated/floor{ + icon_state = "wood_siding10" + }, +/area/centcom/control) +"XE" = ( +/turf/unsimulated/floor{ + icon_state = "gcircuit" + }, +/obj/structure/artilleryplaceholder/decorative{ + icon_state = "27" + }, +/obj/structure/table/reinforced/steel, +/obj/machinery/button/remote/blast_door{ + id = "battery1"; + name = "Battery 1 Firing Control" + }, +/obj/effect/decal/cleanable/cobweb, +/obj/item/weapon/reagent_containers/glass/rag, +/turf/unsimulated/floor{ + icon_state = "wood_siding10" + }, +/area/centcom/control) +"XF" = ( +/turf/unsimulated/floor{ + icon_state = "engine" + }, +/obj/effect/decal/cleanable/dirt, +/turf/unsimulated/floor{ + icon_state = "wood_siding1"; + dir = 6 + }, +/area/centcom/control) +"XG" = ( +/turf/unsimulated/floor{ + icon_state = "engine" + }, +/obj/effect/decal/cleanable/dirt, +/obj/item/weapon/stool, +/turf/unsimulated/floor{ + icon_state = "wood_siding1"; + dir = 6 + }, +/area/centcom/control) +"XH" = ( +/turf/unsimulated/floor{ + icon_state = "engine" + }, +/obj/effect/decal/cleanable/dirt, +/obj/item/weapon/storage/toolbox/electrical, +/turf/unsimulated/floor{ + icon_state = "wood_siding1"; + dir = 6 + }, +/area/centcom/control) +"XI" = ( +/turf/unsimulated/floor{ + icon_state = "engine" + }, +/obj/structure/window/phoronreinforced{ + icon_state = "phoronrwindow"; + dir = 8 + }, +/obj/structure/window/phoronreinforced{ + icon_state = "phoronrwindow"; + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/generic, +/turf/unsimulated/floor{ + icon_state = "wood_siding9" + }, +/area/centcom/control) +"XJ" = ( +/turf/unsimulated/floor{ + icon_state = "wood" + }, +/obj/item/weapon/stool/padded, +/turf/unsimulated/floor{ + name = "plating"; + icon_state = "siding2" + }, +/area/centcom/holding) +"XK" = ( +/turf/unsimulated/floor{ + icon_state = "floor" + }, +/obj/structure/bed/chair/unmovable{ + dir = 1 + }, +/turf/unsimulated/floor{ + icon_state = "wood_siding2" + }, +/area/centcom/spawning) +"XL" = ( +/turf/unsimulated/floor{ + icon_state = "floor" + }, +/obj/machinery/vending/snack{ + name = "Free Chocolate Corp"; + prices = list() + }, +/turf/unsimulated/floor{ + icon_state = "wood_siding4" + }, +/area/centcom/spawning) +"XM" = ( +/turf/unsimulated/floor{ + icon_state = "floor" + }, +/obj/machinery/vending/cola{ + name = "Free Robust Softdrinks"; + prices = list() + }, +/turf/unsimulated/floor{ + icon_state = "wood_siding8" + }, +/area/centcom/spawning) +"XN" = ( +/turf/unsimulated/floor{ + icon_state = "floor" + }, +/obj/structure/bed/chair/unmovable, +/turf/unsimulated/floor{ + icon_state = "wood_siding1" + }, +/area/centcom/spawning) (1,1,1) = {" aa @@ -57006,7 +57213,7 @@ DM DM EP EP -WE +XJ Gq GE GF @@ -57263,7 +57470,7 @@ Fi Fo EP EP -WE +XJ Gq GF GF @@ -57520,7 +57727,7 @@ Fj Fp EP EP -WE +XJ Gq GF GF @@ -57777,7 +57984,7 @@ Fk Fp EP EP -WE +XJ Gq GF GF @@ -58034,7 +58241,7 @@ EP EP Fy EP -WE +XJ Gq GF GF @@ -58291,7 +58498,7 @@ EP EP EP EP -WE +XJ Gq GF GF @@ -64483,7 +64690,7 @@ Ms Id Id Id -Xm +XL Id Id Id @@ -64686,17 +64893,17 @@ wl xe xA yk -DL +XC wl xe xA yk -DL +XC wl xe xA Bp -Fm +XI uT Cq CG @@ -64739,9 +64946,9 @@ KZ Ms Id Id -Xl +XK OY -Xo +XN Id Id OA @@ -64996,9 +65203,9 @@ MN Ms Id Id -Xl +XK OZ -Xo +XN Id Id Qn @@ -65455,18 +65662,18 @@ it uT wo xh -Dh +Xz yl yE wo xh -Eh +XD yl yE wo xh -Er -ER +XE +XF BT uT Cq @@ -65510,9 +65717,9 @@ KZ Ms Id Id -Xl +XK Pa -Xo +XN Id Id OA @@ -65712,18 +65919,18 @@ aM uT wp xi -Dr +XA yl yE wp xi -Dr +XA yl yE wp xi -Dr -ET +XA +XG BT uT Cq @@ -65767,9 +65974,9 @@ Nw Ms Id Id -Xl +XK Pb -Xo +XN Id Id OA @@ -65969,18 +66176,18 @@ it uT wq xj -DJ +XB yl yE wq xj -DJ +XB yl yE wq xj -DJ -Fl +XB +XH BT uT Cq @@ -66024,9 +66231,9 @@ KZ Ms Id Id -Xl +XK Pc -Xo +XN Id Id OA @@ -66538,9 +66745,9 @@ MN Ms Id Id -Xl +XK Pb -Xo +XN Id Id OA @@ -66795,9 +67002,9 @@ KZ Ms Id Id -Xl +XK Pd -Xo +XN Id Id OA @@ -67053,7 +67260,7 @@ Ms Id Id Id -Xn +XM Id Id Id @@ -71221,16 +71428,16 @@ dl cP dl aO -bn -bn -bn -bn -bn -bn -bn -bn -bn -bn +Ma +BS +Df +Df +Df +Df +Df +Df +BS +Ma eO aM aM @@ -71478,16 +71685,16 @@ dm cQ cP aO -bn -bn -bn -bn -bn -bn -bn -bn -bn -bn +BS +BS +Dg +Dg +Dg +Dg +Dg +Dg +BS +BS eO aM aM @@ -71735,16 +71942,16 @@ cQ dm dl aO -bn -bn -bn -bn -bn -bn -bn -bn -bn -bn +BS +HL +Dh +DL +ER +Fm +DL +Xn +Xu +Ga eO aM aM @@ -71992,16 +72199,16 @@ dn dn eA aO -bn -bn -bn -bn -bn -bn -bn -bn -bn -bn +BS +Xs +Dr +Xm +ET +WE +Xm +Xo +Xv +BS eO aM aM @@ -72249,16 +72456,16 @@ cU do dp aO -bn -bn -bn -bn -bn -bn -bn -bn -bn -bn +BS +Xt +DA +Er +Fl +Xl +Er +Xr +Xw +BS eO aM aM @@ -72506,16 +72713,16 @@ do cU cV aO -bn -bn -bn -bn -bn -bn -bn -bn -bn -bn +BS +BS +DJ +DJ +DJ +DJ +DJ +DJ +BS +BS eO aM aM @@ -72763,16 +72970,16 @@ dp cV dp aO -bn -bn -bn -bn -bn -bn -bn -bn -bn -bn +Ma +BS +Df +Df +Df +Df +Df +Df +BS +Ma eO aM aM @@ -74851,7 +75058,7 @@ aM aM aM hV -Dg +Xy iw jb jh @@ -75893,7 +76100,7 @@ aM aM aM aM -Dg +Xy it aM aM @@ -79731,9 +79938,9 @@ aM aM aM aM -BS +Eh iH -Df +Xx aM aM aM diff --git a/maps/aurora/aurora-4_mainlevel.dmm b/maps/aurora/aurora-4_mainlevel.dmm index ea851adb101..1da5b946c31 100644 --- a/maps/aurora/aurora-4_mainlevel.dmm +++ b/maps/aurora/aurora-4_mainlevel.dmm @@ -5342,6 +5342,14 @@ /obj/item/device/multitool, /turf/simulated/floor/tiled, /area/engineering/atmos/storage) +"akI" = ( +/obj/machinery/vending/battlemonsters, +/turf/simulated/floor/tiled, +/area/hallway/primary/central_one) +"akJ" = ( +/obj/machinery/vending/coffee, +/turf/simulated/floor/tiled, +/area/hallway/primary/central_one) "akN" = ( /obj/structure/morgue{ icon_state = "morgue1"; @@ -46067,14 +46075,6 @@ /obj/structure/disposalpipe/trunk, /turf/simulated/floor/tiled, /area/hallway/primary/central_one) -"bCC" = ( -/obj/machinery/vending/snack, -/turf/simulated/floor/tiled, -/area/hallway/primary/central_one) -"bCD" = ( -/obj/machinery/vending/cola, -/turf/simulated/floor/tiled, -/area/hallway/primary/central_one) "bCE" = ( /obj/machinery/door/firedoor, /obj/machinery/door/blast/shutters{ @@ -96602,7 +96602,7 @@ byx bzE bAG bxs -bCC +akI cuG cuI cuO @@ -96859,7 +96859,7 @@ byy coh coi bxs -bCD +akJ bDx bEx cuP diff --git a/maps/aurora/code/aurora_holodeck.dm b/maps/aurora/code/aurora_holodeck.dm index ce0e7706847..c0cc16fe29e 100644 --- a/maps/aurora/code/aurora_holodeck.dm +++ b/maps/aurora/code/aurora_holodeck.dm @@ -61,7 +61,13 @@ ) ), "gym" = new /datum/holodeck_program(/area/holodeck/source_gym), - "turnoff" = new /datum/holodeck_program(/area/holodeck/source_plating, list()) + "battlemonsters" = new /datum/holodeck_program(/area/holodeck/source_battlemonsters, + list( + 'sound/music/battlemonsters_theme.ogg' + ), + FALSE + ), + "turnoff" = new /datum/holodeck_program(/area/holodeck/source_plating) ) holodeck_supported_programs = list( @@ -78,7 +84,8 @@ "Meeting Hall" = "meetinghall", "Courtroom" = "courtroom", "Chapel" = "chapel", - "Xavier Trasen Memorial Gymnasium" = "gym" + "Xavier Trasen Memorial Gymnasium" = "gym", + "Battle Monsters Duelling Arena" = "battlemonsters" ) holodeck_restricted_programs = list( "Atmospheric Burn Simulation" = "burntest", diff --git a/sound/music/battlemonsters_theme.ogg b/sound/music/battlemonsters_theme.ogg new file mode 100644 index 00000000000..84d4515620b Binary files /dev/null and b/sound/music/battlemonsters_theme.ogg differ diff --git a/sound/serversound_list.txt b/sound/serversound_list.txt index 21d48ed7f9e..5a5f21b90b0 100644 --- a/sound/serversound_list.txt +++ b/sound/serversound_list.txt @@ -9,5 +9,6 @@ sound/music/THUNDERDOME.ogg sound/music/title1.ogg sound/music/title2.ogg sound/music/traitor.ogg +sound/music/battlemonsters_theme.ogg sound/items/bikehorn.ogg sound/effects/siren.ogg \ No newline at end of file