Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.
Sign up
Fetching contributors…
| #include "artifact.h" | |
| #include "output.h" // string_format | |
| #include "item_factory.h" | |
| #include <sstream> | |
| #include <fstream> | |
| std::vector<art_effect_passive> fill_good_passive(); | |
| std::vector<art_effect_passive> fill_bad_passive(); | |
| std::vector<art_effect_active> fill_good_active(); | |
| std::vector<art_effect_active> fill_bad_active(); | |
| int passive_effect_cost[NUM_AEPS] = { | |
| 0, // AEP_NULL | |
| 3, // AEP_STR_UP | |
| 3, // AEP_DEX_UP | |
| 3, // AEP_PER_UP | |
| 3, // AEP_INT_UP | |
| 5, // AEP_ALL_UP | |
| 4, // AEP_SPEED_UP | |
| 2, // AEP_IODINE | |
| 4, // AEP_SNAKES | |
| 7, // AEP_INVISIBLE | |
| 5, // AEP_CLAIRVOYANCE | |
| 50,// AEP_SUPER_CLAIRVOYANCE | |
| 2, // AEP_STEALTH | |
| 2, // AEP_EXTINGUISH | |
| 1, // AEP_GLOW | |
| 1, // AEP_PSYSHIELD | |
| 3, // AEP_RESIST_ELECTRICITY | |
| 3, // AEP_CARRY_MORE | |
| 5, // AEP_SAP_LIFE | |
| 0, // AEP_SPLIT | |
| -2, // AEP_HUNGER | |
| -2, // AEP_THIRST | |
| -1, // AEP_SMOKE | |
| -5, // AEP_EVIL | |
| -3, // AEP_SCHIZO | |
| -5, // AEP_RADIOACTIVE | |
| -3, // AEP_MUTAGENIC | |
| -5, // AEP_ATTENTION | |
| -2, // AEP_STR_DOWN | |
| -2, // AEP_DEX_DOWN | |
| -2, // AEP_PER_DOWN | |
| -2, // AEP_INT_DOWN | |
| -5, // AEP_ALL_DOWN | |
| -4, // AEP_SPEED_DOWN | |
| -5, // AEP_FORCE_TELEPORT | |
| -3, // AEP_MOVEMENT_NOISE | |
| -2, // AEP_BAD_WEATHER | |
| -1 // AEP_SICK | |
| }; | |
| int active_effect_cost[NUM_AEAS] = { | |
| 0, // AEA_NULL | |
| 2, // AEA_STORM | |
| 4, // AEA_FIREBALL | |
| 5, // AEA_ADRENALINE | |
| 4, // AEA_MAP | |
| 0, // AEA_BLOOD | |
| 0, // AEA_FATIGUE | |
| 4, // AEA_ACIDBALL | |
| 5, // AEA_PULSE | |
| 4, // AEA_HEAL | |
| 3, // AEA_CONFUSED | |
| 3, // AEA_ENTRANCE | |
| 3, // AEA_BUGS | |
| 5, // AEA_TELEPORT | |
| 1, // AEA_LIGHT | |
| 4, // AEA_GROWTH | |
| 6, // AEA_HURTALL | |
| 0, // AEA_SPLIT | |
| -3, // AEA_RADIATION | |
| -2, // AEA_PAIN | |
| -3, // AEA_MUTATE | |
| -2, // AEA_PARALYZE | |
| -3, // AEA_FIRESTORM | |
| -6, // AEA_ATTENTION | |
| -4, // AEA_TELEGLOW | |
| -2, // AEA_NOISE | |
| -2, // AEA_SCREAM | |
| -3, // AEA_DIM | |
| -4, // AEA_FLASH | |
| -2, // AEA_VOMIT | |
| -5 // AEA_SHADOWS | |
| }; | |
| enum artifact_natural_shape { | |
| ARTSHAPE_NULL, | |
| ARTSHAPE_SPHERE, | |
| ARTSHAPE_ROD, | |
| ARTSHAPE_TEARDROP, | |
| ARTSHAPE_LAMP, | |
| ARTSHAPE_SNAKE, | |
| ARTSHAPE_DISC, | |
| ARTSHAPE_BEADS, | |
| ARTSHAPE_NAPKIN, | |
| ARTSHAPE_URCHIN, | |
| ARTSHAPE_JELLY, | |
| ARTSHAPE_SPIRAL, | |
| ARTSHAPE_PIN, | |
| ARTSHAPE_TUBE, | |
| ARTSHAPE_PYRAMID, | |
| ARTSHAPE_CRYSTAL, | |
| ARTSHAPE_KNOT, | |
| ARTSHAPE_CRESCENT, | |
| ARTSHAPE_MAX | |
| }; | |
| struct artifact_shape_datum { | |
| std::string name; | |
| std::string desc; | |
| int volume_min, volume_max; | |
| int weight_min, weight_max; | |
| }; | |
| struct artifact_property_datum { | |
| std::string name; | |
| std::string desc; | |
| art_effect_passive passive_good[4]; | |
| art_effect_passive passive_bad[4]; | |
| art_effect_active active_good[4]; | |
| art_effect_active active_bad[4]; | |
| }; | |
| enum artifact_weapon_type { | |
| ARTWEAP_NULL, | |
| ARTWEAP_BULK, // A bulky item that works okay for bashing | |
| ARTWEAP_CLUB, // An item designed to bash | |
| ARTWEAP_SPEAR, // A stab-only weapon | |
| ARTWEAP_SWORD, // A long slasher | |
| ARTWEAP_KNIFE, // Short, slash and stab | |
| NUM_ARTWEAPS | |
| }; | |
| struct artifact_tool_form_datum { | |
| std::string name; | |
| char sym; | |
| nc_color color; | |
| std::string m1; | |
| std::string m2; | |
| int volume_min, volume_max; | |
| int weight_min, weight_max; | |
| artifact_weapon_type base_weapon; | |
| artifact_weapon_type extra_weapons[3]; | |
| }; | |
| enum artifact_tool_form { | |
| ARTTOOLFORM_NULL, | |
| ARTTOOLFORM_HARP, | |
| ARTTOOLFORM_STAFF, | |
| ARTTOOLFORM_SWORD, | |
| ARTTOOLFORM_KNIFE, | |
| ARTTOOLFORM_CUBE, | |
| NUM_ARTTOOLFORMS | |
| }; | |
| struct artifact_weapon_datum { | |
| std::string adjective; | |
| int volume, weight; // Only applicable if this is an *extra* weapon | |
| int bash_min, bash_max; | |
| int cut_min, cut_max; | |
| int to_hit_min, to_hit_max; | |
| std::string tag; | |
| }; | |
| enum artifact_armor_mod { | |
| ARMORMOD_NULL, | |
| ARMORMOD_LIGHT, | |
| ARMORMOD_BULKY, | |
| ARMORMOD_POCKETED, | |
| ARMORMOD_FURRED, | |
| ARMORMOD_PADDED, | |
| ARMORMOD_PLATED, | |
| NUM_ARMORMODS | |
| }; | |
| struct artifact_armor_form_datum { | |
| std::string name; | |
| nc_color color; | |
| std::string m1; | |
| std::string m2; | |
| int volume, weight; | |
| int encumb; | |
| int coverage; | |
| int thickness; | |
| int env_resist; | |
| int warmth; | |
| int storage; | |
| int melee_bash, melee_cut, melee_hit; | |
| unsigned char covers; | |
| bool plural; | |
| artifact_armor_mod available_mods[5]; | |
| }; | |
| enum artifact_armor_form { | |
| ARTARMFORM_NULL, | |
| ARTARMFORM_ROBE, | |
| ARTARMFORM_COAT, | |
| ARTARMFORM_MASK, | |
| ARTARMFORM_HELM, | |
| ARTARMFORM_GLOVES, | |
| ARTARMFORM_BOOTS, | |
| ARTARMFORM_RING, | |
| NUM_ARTARMFORMS | |
| }; | |
| std::string mk_artifact_id() | |
| { | |
| return string_format("artifact_%d", (int) artifact_itype_ids.size()); | |
| }; | |
| //see below, move them so gettext and be applied properly | |
| artifact_shape_datum artifact_shape_data[ARTSHAPE_MAX]; | |
| artifact_property_datum artifact_property_data[ARTPROP_MAX]; | |
| artifact_tool_form_datum artifact_tool_form_data[NUM_ARTTOOLFORMS]; | |
| artifact_weapon_datum artifact_weapon_data[NUM_ARTWEAPS]; | |
| artifact_armor_form_datum artifact_armor_form_data[NUM_ARTARMFORMS]; | |
| /* | |
| * Armor mods alter the normal values of armor. | |
| * If the basic armor type has "null" as its second material, and the mod has a | |
| * material attached, the second material will be changed. | |
| */ | |
| artifact_armor_form_datum artifact_armor_mod_data[NUM_ARMORMODS]; | |
| #define NUM_ART_ADJS 20 | |
| std::string artifact_adj[NUM_ART_ADJS]; | |
| #define NUM_ART_NOUNS 20 | |
| std::string artifact_noun[NUM_ART_NOUNS]; | |
| std::string artifact_name(std::string type); | |
| // Constructrs for artifact itypes. | |
| it_artifact_tool::it_artifact_tool() : it_tool() { | |
| id = mk_artifact_id(); | |
| ammo = "NULL"; | |
| price = 0; | |
| def_charges = 0; | |
| std::vector<long> rand_charges; | |
| charges_per_use = 1; | |
| charge_type = ARTC_NULL; | |
| turns_per_charge = 0; | |
| revert_to = "null"; | |
| use_methods.push_back( &iuse::artifact ); | |
| }; | |
| it_artifact_armor::it_artifact_armor() : it_armor() { | |
| id = mk_artifact_id(); | |
| price = 0; | |
| }; | |
| void init_artifacts() | |
| { | |
| artifact_shape_datum tmp_artifact_shape_data[ARTSHAPE_MAX] = { | |
| {"BUG", "BUG", 0, 0, 0, 0}, | |
| {_("sphere"), _("smooth sphere"), 2, 4, 1, 1150}, | |
| {_("rod"), _("tapered rod"), 1, 7, 1, 800}, | |
| {_("teardrop"), _("teardrop-shaped stone"), 2, 6, 1, 950}, | |
| {_("lamp"), _("hollow, transparent cube"), 4, 9, 1, 350}, | |
| {_("snake"), _("winding, flexible rod"), 0, 8, 1, 950}, | |
| {_("disc"), _("smooth disc"), 4, 6, 200, 400}, | |
| {_("beads"), _("string of beads"), 3, 7, 1, 700}, | |
| {_("napkin"), _("very thin sheet"), 0, 3, 1, 350}, | |
| {_("urchin"), _("spiked sphere"), 3, 5, 200, 700}, | |
| {_("jelly"), _("malleable blob"), 2, 8, 200, 450}, | |
| {_("spiral"), _("spiraling rod"), 5, 6, 200, 350}, | |
| {_("pin"), _("pointed rod"), 1, 5, 100, 1050}, | |
| {_("tube"), _("hollow tube"), 2, 5, 350, 700}, | |
| {_("pyramid"), _("regular tetrahedron"), 3, 7, 200, 450}, | |
| {_("crystal"), _("translucent crystal"), 1, 6, 200, 800}, | |
| {_("knot"), _("twisted, knotted cord"), 2, 6, 100, 800}, | |
| {_("crescent"), _("crescent-shaped stone"), 2, 6, 200, 700} | |
| }; | |
| for(int i = 0; i < ARTSHAPE_MAX; i++) { | |
| artifact_shape_data[i] = tmp_artifact_shape_data[i]; | |
| } | |
| artifact_property_datum tmp_artifact_property_data[ARTPROP_MAX] = { | |
| { | |
| "BUG", "BUG", | |
| {AEP_NULL, AEP_NULL, AEP_NULL, AEP_NULL}, | |
| {AEP_NULL, AEP_NULL, AEP_NULL, AEP_NULL}, | |
| {AEA_NULL, AEA_NULL, AEA_NULL, AEA_NULL}, | |
| {AEA_NULL, AEA_NULL, AEA_NULL, AEA_NULL} | |
| }, | |
| { | |
| _("wriggling"), _("is constantly wriggling"), | |
| {AEP_SPEED_UP, AEP_SNAKES, AEP_NULL, AEP_NULL}, | |
| {AEP_DEX_DOWN, AEP_FORCE_TELEPORT, AEP_SICK, AEP_NULL}, | |
| {AEA_TELEPORT, AEA_ADRENALINE, AEA_NULL, AEA_NULL}, | |
| {AEA_MUTATE, AEA_ATTENTION, AEA_VOMIT, AEA_NULL} | |
| }, | |
| { | |
| _("glowing"), _("glows faintly"), | |
| {AEP_INT_UP, AEP_GLOW, AEP_CLAIRVOYANCE, AEP_NULL}, | |
| {AEP_RADIOACTIVE, AEP_MUTAGENIC, AEP_ATTENTION, AEP_NULL}, | |
| {AEA_LIGHT, AEA_LIGHT, AEA_LIGHT, AEA_NULL}, | |
| {AEA_ATTENTION, AEA_TELEGLOW, AEA_FLASH, AEA_SHADOWS} | |
| }, | |
| { | |
| _("humming"), _("hums very quietly"), | |
| {AEP_ALL_UP, AEP_PSYSHIELD, AEP_NULL, AEP_NULL}, | |
| {AEP_SCHIZO, AEP_PER_DOWN, AEP_INT_DOWN, AEP_NULL}, | |
| {AEA_PULSE, AEA_ENTRANCE, AEA_NULL, AEA_NULL}, | |
| {AEA_NOISE, AEA_NOISE, AEA_SCREAM, AEA_NULL} | |
| }, | |
| { | |
| _("moving"), _("shifts from side to side slowly"), | |
| {AEP_STR_UP, AEP_DEX_UP, AEP_SPEED_UP, AEP_NULL}, | |
| {AEP_HUNGER, AEP_PER_DOWN, AEP_FORCE_TELEPORT, AEP_NULL}, | |
| {AEA_TELEPORT, AEA_TELEPORT, AEA_MAP, AEA_NULL}, | |
| {AEA_PARALYZE, AEA_VOMIT, AEA_VOMIT, AEA_NULL} | |
| }, | |
| { | |
| _("whispering"), _("makes very faint whispering sounds"), | |
| {AEP_CLAIRVOYANCE, AEP_EXTINGUISH, AEP_STEALTH, AEP_NULL}, | |
| {AEP_EVIL, AEP_SCHIZO, AEP_ATTENTION, AEP_NULL}, | |
| {AEA_FATIGUE, AEA_ENTRANCE, AEA_ENTRANCE, AEA_NULL}, | |
| {AEA_ATTENTION, AEA_SCREAM, AEA_SCREAM, AEA_SHADOWS} | |
| }, | |
| { | |
| _("breathing"), | |
| _("shrinks and grows very slightly with a regular pulse, as if breathing"), | |
| {AEP_SAP_LIFE, AEP_ALL_UP, AEP_SPEED_UP, AEP_CARRY_MORE}, | |
| {AEP_HUNGER, AEP_THIRST, AEP_SICK, AEP_BAD_WEATHER}, | |
| {AEA_ADRENALINE, AEA_HEAL, AEA_ENTRANCE, AEA_GROWTH}, | |
| {AEA_MUTATE, AEA_ATTENTION, AEA_SHADOWS, AEA_NULL} | |
| }, | |
| { | |
| _("dead"), _("is icy cold to the touch"), | |
| {AEP_INVISIBLE, AEP_CLAIRVOYANCE, AEP_EXTINGUISH, AEP_SAP_LIFE}, | |
| {AEP_HUNGER, AEP_EVIL, AEP_ALL_DOWN, AEP_SICK}, | |
| {AEA_BLOOD, AEA_HURTALL, AEA_NULL, AEA_NULL}, | |
| {AEA_PAIN, AEA_SHADOWS, AEA_DIM, AEA_VOMIT} | |
| }, | |
| { | |
| _("itchy"), _("makes your skin itch slightly when it is close"), | |
| {AEP_DEX_UP, AEP_SPEED_UP, AEP_PSYSHIELD, AEP_NULL}, | |
| {AEP_RADIOACTIVE, AEP_MUTAGENIC, AEP_SICK, AEP_NULL}, | |
| {AEA_ADRENALINE, AEA_BLOOD, AEA_HEAL, AEA_BUGS}, | |
| {AEA_RADIATION, AEA_PAIN, AEA_PAIN, AEA_VOMIT} | |
| }, | |
| { | |
| _("glittering"), _("glitters faintly under direct light"), | |
| {AEP_INT_UP, AEP_EXTINGUISH, AEP_GLOW, AEP_NULL}, | |
| {AEP_SMOKE, AEP_ATTENTION, AEP_NULL, AEP_NULL}, | |
| {AEA_MAP, AEA_LIGHT, AEA_CONFUSED, AEA_ENTRANCE}, | |
| {AEA_RADIATION, AEA_MUTATE, AEA_ATTENTION, AEA_FLASH} | |
| }, | |
| { | |
| _("electric"), _("very weakly shocks you when touched"), | |
| {AEP_RESIST_ELECTRICITY, AEP_DEX_UP, AEP_SPEED_UP, AEP_PSYSHIELD}, | |
| {AEP_THIRST, AEP_SMOKE, AEP_STR_DOWN, AEP_BAD_WEATHER}, | |
| {AEA_STORM, AEA_ADRENALINE, AEA_LIGHT, AEA_NULL}, | |
| {AEA_PAIN, AEA_PARALYZE, AEA_FLASH, AEA_FLASH} | |
| }, | |
| { | |
| _("slimy"), _("feels slimy"), | |
| {AEP_SNAKES, AEP_STEALTH, AEP_EXTINGUISH, AEP_SAP_LIFE}, | |
| {AEP_THIRST, AEP_DEX_DOWN, AEP_SPEED_DOWN, AEP_SICK}, | |
| {AEA_BLOOD, AEA_ACIDBALL, AEA_GROWTH, AEA_ACIDBALL}, | |
| {AEA_MUTATE, AEA_MUTATE, AEA_VOMIT, AEA_VOMIT} | |
| }, | |
| { | |
| _("engraved"), _("is covered with odd etchings"), | |
| {AEP_CLAIRVOYANCE, AEP_INVISIBLE, AEP_PSYSHIELD, AEP_SAP_LIFE}, | |
| {AEP_EVIL, AEP_ATTENTION, AEP_NULL, AEP_NULL}, | |
| {AEA_FATIGUE, AEA_TELEPORT, AEA_HEAL, AEA_FATIGUE}, | |
| {AEA_ATTENTION, AEA_ATTENTION, AEA_TELEGLOW, AEA_DIM} | |
| }, | |
| { | |
| _("crackling"), _("occasionally makes a soft crackling sound"), | |
| {AEP_EXTINGUISH, AEP_RESIST_ELECTRICITY, AEP_NULL, AEP_NULL}, | |
| {AEP_SMOKE, AEP_RADIOACTIVE, AEP_MOVEMENT_NOISE, AEP_NULL}, | |
| {AEA_STORM, AEA_FIREBALL, AEA_PULSE, AEA_NULL}, | |
| {AEA_PAIN, AEA_PARALYZE, AEA_NOISE, AEA_NOISE} | |
| }, | |
| { | |
| _("warm"), _("is warm to the touch"), | |
| {AEP_STR_UP, AEP_EXTINGUISH, AEP_GLOW, AEP_NULL}, | |
| {AEP_SMOKE, AEP_RADIOACTIVE, AEP_NULL, AEP_NULL}, | |
| {AEA_FIREBALL, AEA_FIREBALL, AEA_FIREBALL, AEA_LIGHT}, | |
| {AEA_FIRESTORM, AEA_FIRESTORM, AEA_TELEGLOW, AEA_NULL} | |
| }, | |
| { | |
| _("rattling"), _("makes a rattling sound when moved"), | |
| {AEP_DEX_UP, AEP_SPEED_UP, AEP_SNAKES, AEP_CARRY_MORE}, | |
| {AEP_ATTENTION, AEP_INT_DOWN, AEP_MOVEMENT_NOISE, AEP_MOVEMENT_NOISE}, | |
| {AEA_BLOOD, AEA_PULSE, AEA_BUGS, AEA_NULL}, | |
| {AEA_PAIN, AEA_ATTENTION, AEA_NOISE, AEA_NULL} | |
| }, | |
| { | |
| _("scaled"), _("has a surface reminiscent of reptile scales"), | |
| {AEP_SNAKES, AEP_SNAKES, AEP_SNAKES, AEP_STEALTH}, | |
| {AEP_THIRST, AEP_MUTAGENIC, AEP_SPEED_DOWN, AEP_NULL}, | |
| {AEA_ADRENALINE, AEA_BUGS, AEA_GROWTH, AEA_NULL}, | |
| {AEA_MUTATE, AEA_SCREAM, AEA_DIM, AEA_NULL} | |
| }, | |
| { | |
| _("fractal"), | |
| _("has a self-similar pattern which repeats until it is too small for you to see"), | |
| {AEP_ALL_UP, AEP_ALL_UP, AEP_CLAIRVOYANCE, AEP_PSYSHIELD}, | |
| {AEP_SCHIZO, AEP_ATTENTION, AEP_FORCE_TELEPORT, AEP_BAD_WEATHER}, | |
| {AEA_STORM, AEA_FATIGUE, AEA_TELEPORT, AEA_NULL}, | |
| {AEA_RADIATION, AEA_MUTATE, AEA_TELEGLOW, AEA_TELEGLOW} | |
| } | |
| }; | |
| for(int i = 0; i < ARTPROP_MAX; i++) { | |
| artifact_property_data[i] = tmp_artifact_property_data[i]; | |
| } | |
| artifact_tool_form_datum tmp_artifact_tool_form_data[NUM_ARTTOOLFORMS] = { | |
| { | |
| "", '*', c_white, "null", "null", 0, 0, 0, 0, ARTWEAP_BULK, | |
| {ARTWEAP_NULL, ARTWEAP_NULL, ARTWEAP_NULL} | |
| }, | |
| { | |
| _("Harp"), ';', c_yellow, "wood", "null", 20, 30, 1150, 2100, ARTWEAP_BULK, | |
| {ARTWEAP_SPEAR, ARTWEAP_SWORD, ARTWEAP_KNIFE} | |
| }, | |
| { | |
| _("Staff"), '/', c_brown, "wood", "null", 6, 12, 450, 1150, ARTWEAP_CLUB, | |
| {ARTWEAP_BULK, ARTWEAP_SPEAR, ARTWEAP_KNIFE} | |
| }, | |
| { | |
| _("Sword"), '/', c_ltblue, "steel", "null", 8, 14, 900, 3259, ARTWEAP_SWORD, | |
| {ARTWEAP_BULK, ARTWEAP_NULL, ARTWEAP_NULL} | |
| }, | |
| { | |
| _("Dagger"), ';', c_ltblue, "steel", "null", 1, 4, 100, 700, ARTWEAP_KNIFE, | |
| {ARTWEAP_NULL, ARTWEAP_NULL, ARTWEAP_NULL} | |
| }, | |
| { | |
| _("Cube"), '*', c_white, "steel", "null", 1, 3, 100, 2300, ARTWEAP_BULK, | |
| {ARTWEAP_SPEAR, ARTWEAP_NULL, ARTWEAP_NULL} | |
| } | |
| }; | |
| for(int i = 0; i < NUM_ARTTOOLFORMS; i++) { | |
| artifact_tool_form_data[i] = tmp_artifact_tool_form_data[i]; | |
| } | |
| artifact_weapon_datum tmp_artifact_weapon_data[NUM_ARTWEAPS] = { | |
| {"", 0, 0, 0, 0, 0, 0, 0, 0, ""}, | |
| // Adjective Vol,wgt Bash Cut To-Hit tags | |
| {_("Heavy"), 0, 1400, 10, 20, 0, 0, -2, 0, ""}, | |
| {_("Knobbed"), 1, 250, 14, 30, 0, 0, -1, 1, ""}, | |
| {_("Spiked"), 1, 100, 0, 0, 20, 40, -1, 1, "SPEAR"}, | |
| {_("Edged"), 2, 450, 0, 0, 20, 50, -1, 2, "CHOP"}, | |
| {_("Bladed"), 1, 2250, 0, 0, 12, 30, -1, 1, "STAB"} | |
| }; | |
| for(int i = 0; i < NUM_ARTWEAPS; i++) { | |
| artifact_weapon_data[i] = tmp_artifact_weapon_data[i]; | |
| } | |
| artifact_armor_form_datum tmp_artifact_armor_form_data[NUM_ARTARMFORMS] = { | |
| { | |
| "", c_white, "null", "null", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, false, | |
| {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL} | |
| }, | |
| // Name color Materials Vol Wgt Enc Cov Thk Env Wrm Sto Bsh Cut Hit | |
| { | |
| _("Robe"), c_red, "wool", "null", 6, 700, 1, 3, 3, 0, 2, 0, -8, 0, -3, | |
| mfb(bp_torso) | mfb(bp_legs), false, | |
| { | |
| ARMORMOD_LIGHT, ARMORMOD_BULKY, ARMORMOD_POCKETED, ARMORMOD_FURRED, | |
| ARMORMOD_PADDED | |
| } | |
| }, | |
| { | |
| _("Coat"), c_brown, "leather", "null", 14, 1600, 2, 3, 2, 1, 4, 4, -6, 0, -3, | |
| mfb(bp_torso), false, | |
| { | |
| ARMORMOD_LIGHT, ARMORMOD_POCKETED, ARMORMOD_FURRED, ARMORMOD_PADDED, | |
| ARMORMOD_PLATED | |
| } | |
| }, | |
| { | |
| _("Mask"), c_white, "wood", "null", 4, 100, 2, 2, 2, 1, 2, 0, 2, 0, -2, | |
| mfb(bp_eyes) | mfb(bp_mouth), false, | |
| { | |
| ARMORMOD_FURRED, ARMORMOD_FURRED, ARMORMOD_NULL, ARMORMOD_NULL, | |
| ARMORMOD_NULL | |
| } | |
| }, | |
| // Name color Materials Vol Wgt Enc Cov Thk Env Wrm Sto Bsh Cut Hit | |
| { | |
| _("Helm"), c_dkgray, "silver", "null", 6, 700, 2, 3, 3, 0, 1, 0, 8, 0, -2, | |
| mfb(bp_head), false, | |
| { | |
| ARMORMOD_BULKY, ARMORMOD_FURRED, ARMORMOD_PADDED, ARMORMOD_PLATED, | |
| ARMORMOD_NULL | |
| } | |
| }, | |
| { | |
| _("Gloves"), c_ltblue, "leather", "null", 2, 100, 1, 3, 3, 1, 2, 0, -4, 0, -2, | |
| mfb(bp_hands), true, | |
| { | |
| ARMORMOD_BULKY, ARMORMOD_FURRED, ARMORMOD_PADDED, ARMORMOD_PLATED, | |
| ARMORMOD_NULL | |
| } | |
| }, | |
| // Name color Materials Vol Wgt Enc Cov Thk Env Wrm Sto Bsh Cut Hit | |
| { | |
| _("Boots"), c_blue, "leather", "null", 6, 250, 1, 3, 3, 1, 3, 0, 4, 0, -1, | |
| mfb(bp_feet), true, | |
| { | |
| ARMORMOD_LIGHT, ARMORMOD_BULKY, ARMORMOD_PADDED, ARMORMOD_PLATED, | |
| ARMORMOD_NULL | |
| } | |
| }, | |
| { | |
| _("Ring"), c_ltgreen, "silver", "null", 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 0, true, | |
| {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL} | |
| } | |
| }; | |
| for(int i = 0; i < NUM_ARTARMFORMS; i++) { | |
| artifact_armor_form_data[i] = tmp_artifact_armor_form_data[i]; | |
| } | |
| artifact_armor_form_datum tmp_artifact_armor_mod_data[NUM_ARMORMODS] = { | |
| { | |
| "", c_white, "null", "null", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, | |
| {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL} | |
| }, | |
| // Description; "It is ..." or "They are ..." | |
| { | |
| _("very thin and light."), c_white, "null", "null", | |
| // Vol Wgt Enc Cov Thk Env Wrm Sto | |
| -4, -950, -2, -1, -1, -1, -1, 0, 0, 0, 0, 0, false, | |
| {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL} | |
| }, | |
| { | |
| _("extremely bulky."), c_white, "null", "null", | |
| 8, 1150, 2, 1, 1, 0, 1, 0, 0, 0, 0, 0, false, | |
| {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL} | |
| }, | |
| { | |
| _("covered in pockets."), c_white, "null", "null", | |
| 1, 150, 1, 0, 0, 0, 0, 16, 0, 0, 0, 0, false, | |
| {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL} | |
| }, | |
| { | |
| _("disgustingly furry."), c_white, "wool", "null", | |
| // Vol Wgt Enc Dmg Cut Env Wrm Sto | |
| 4, 250, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, false, | |
| {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL} | |
| }, | |
| { | |
| _("leather-padded."), c_white, "leather", "null", | |
| 4, 450, 1, 1, 1, 0, 1, -3, 0, 0, 0, 0, false, | |
| {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL} | |
| }, | |
| { | |
| _("plated in iron."), c_white, "iron", "null", | |
| 4, 1400, 3, 2, 2, 0, 1, -4, 0, 0, 0, 0, false, | |
| {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL} | |
| }, | |
| }; | |
| for(int i = 0; i < NUM_ARMORMODS; i++) { | |
| artifact_armor_mod_data[i] = tmp_artifact_armor_mod_data[i]; | |
| } | |
| std::string tmp_artifact_adj[NUM_ART_ADJS] = { | |
| _("Forbidden"), _("Unknown"), _("Forgotten"), _("Hideous"), _("Eldritch"), | |
| _("Gelatinous"), _("Ancient"), _("Cursed"), _("Bloody"), _("Undying"), | |
| _("Shadowy"), _("Silent"), _("Cyclopean"), _("Fungal"), _("Unspeakable"), | |
| _("Grotesque"), _("Frigid"), _("Shattered"), _("Sleeping"), _("Repellent") | |
| }; | |
| for(int i = 0; i < NUM_ART_ADJS; i++) { | |
| artifact_adj[i] = tmp_artifact_adj[i]; | |
| } | |
| std::string tmp_artifact_noun[NUM_ART_NOUNS] = { | |
| _("%s Technique"), _("%s Dreams"), _("%s Beasts"), _("%s Evil"), _("%s Miasma"), | |
| _("the %s Abyss"), _("the %s City"), _("%s Shadows"), _("%s Shade"), _("%s Illusion"), | |
| _("%s Justice"), _("the %s Necropolis"), _("%s Ichor"), _("the %s Monolith"), _("%s Aeons"), | |
| _("%s Graves"), _("%s Horrors"), _("%s Suffering"), _("%s Death"), _("%s Horror") | |
| }; | |
| for(int i = 0; i < NUM_ART_NOUNS; i++) { | |
| artifact_noun[i] = tmp_artifact_noun[i]; | |
| } | |
| } | |
| void it_artifact_tool::create_name(const std::string &type) | |
| { | |
| name = artifact_name(type); | |
| name_plural = name; | |
| } | |
| void it_artifact_tool::create_name(const std::string &property_name, const std::string &shape_name) | |
| { | |
| name = rmp_format(_("<artifact_name>%1$s %2$s"), property_name.c_str(), | |
| shape_name.c_str()); | |
| name_plural = name; | |
| } | |
| void it_artifact_armor::create_name(const std::string &type) | |
| { | |
| name = artifact_name(type); | |
| name_plural = name; | |
| } | |
| std::string new_artifact() | |
| { | |
| if (one_in(2)) { // Generate a "tool" artifact | |
| it_artifact_tool *art = new it_artifact_tool(); | |
| int form = rng(ARTTOOLFORM_NULL + 1, NUM_ARTTOOLFORMS - 1); | |
| artifact_tool_form_datum *info = &(artifact_tool_form_data[form]); | |
| art->create_name(info->name); | |
| art->color = info->color; | |
| art->sym = info->sym; | |
| art->m1 = info->m1; | |
| art->m2 = info->m2; | |
| art->volume = rng(info->volume_min, info->volume_max); | |
| art->weight = rng(info->weight_min, info->weight_max); | |
| // Set up the basic weapon type | |
| artifact_weapon_datum *weapon = &(artifact_weapon_data[info->base_weapon]); | |
| art->melee_dam = rng(weapon->bash_min, weapon->bash_max); | |
| art->melee_cut = rng(weapon->cut_min, weapon->cut_max); | |
| art->m_to_hit = rng(weapon->to_hit_min, weapon->to_hit_max); | |
| if( weapon->tag != "" ) { | |
| art->item_tags.insert(weapon->tag); | |
| } | |
| // Add an extra weapon perhaps? | |
| if (one_in(2)) { | |
| int select = rng(0, 2); | |
| if (info->extra_weapons[select] != ARTWEAP_NULL) { | |
| weapon = &(artifact_weapon_data[ info->extra_weapons[select] ]); | |
| art->volume += weapon->volume; | |
| art->weight += weapon->weight; | |
| art->melee_dam += rng(weapon->bash_min, weapon->bash_max); | |
| art->melee_cut += rng(weapon->bash_min, weapon->bash_max); | |
| art->m_to_hit += rng(weapon->to_hit_min, weapon->to_hit_max); | |
| if( weapon->tag != "" ) { | |
| art->item_tags.insert(weapon->tag); | |
| } | |
| std::stringstream newname; | |
| newname << weapon->adjective << " " << info->name; | |
| art->create_name(newname.str()); | |
| } | |
| } | |
| art->description = string_format( | |
| _("This is the %s.\nIt is the only one of its kind.\nIt may have unknown powers; use 'a' to activate them."), | |
| art->nname(1).c_str()); | |
| // Finally, pick some powers | |
| art_effect_passive passive_tmp = AEP_NULL; | |
| art_effect_active active_tmp = AEA_NULL; | |
| int num_good = 0, num_bad = 0, value = 0; | |
| std::vector<art_effect_passive> good_effects = fill_good_passive(); | |
| std::vector<art_effect_passive> bad_effects = fill_bad_passive(); | |
| // Wielded effects first | |
| while (!good_effects.empty() && !bad_effects.empty() && | |
| num_good < 3 && num_bad < 3 && | |
| (num_good < 1 || num_bad < 1 || one_in(num_good + 1) || | |
| one_in(num_bad + 1) || value > 1)) { | |
| if (value < 1 && one_in(2)) { // Good | |
| int index = rng(0, good_effects.size() - 1); | |
| passive_tmp = good_effects[index]; | |
| good_effects.erase(good_effects.begin() + index); | |
| num_good++; | |
| } else if (!bad_effects.empty()) { // Bad effect | |
| int index = rng(0, bad_effects.size() - 1); | |
| passive_tmp = bad_effects[index]; | |
| bad_effects.erase(bad_effects.begin() + index); | |
| num_bad++; | |
| } | |
| value += passive_effect_cost[passive_tmp]; | |
| art->effects_wielded.push_back(passive_tmp); | |
| } | |
| // Next, carried effects; more likely to be just bad | |
| num_good = 0; | |
| num_bad = 0; | |
| value = 0; | |
| good_effects = fill_good_passive(); | |
| bad_effects = fill_bad_passive(); | |
| while (one_in(2) && !good_effects.empty() && !bad_effects.empty() && | |
| num_good < 3 && num_bad < 3 && | |
| ((num_good > 2 && one_in(num_good + 1)) || num_bad < 1 || | |
| one_in(num_bad + 1) || value > 1)) { | |
| if (value < 1 && one_in(3)) { // Good | |
| int index = rng(0, good_effects.size() - 1); | |
| passive_tmp = good_effects[index]; | |
| good_effects.erase(good_effects.begin() + index); | |
| num_good++; | |
| } else { // Bad effect | |
| int index = rng(0, bad_effects.size() - 1); | |
| passive_tmp = bad_effects[index]; | |
| bad_effects.erase(bad_effects.begin() + index); | |
| num_bad++; | |
| } | |
| value += passive_effect_cost[passive_tmp]; | |
| art->effects_carried.push_back(passive_tmp); | |
| } | |
| // Finally, activated effects; not necessarily good or bad | |
| num_good = 0; | |
| num_bad = 0; | |
| value = 0; | |
| art->def_charges = 0; | |
| art->max_charges = 0; | |
| std::vector<art_effect_active> good_a_effects = fill_good_active(); | |
| std::vector<art_effect_active> bad_a_effects = fill_bad_active(); | |
| while (!good_a_effects.empty() && !bad_a_effects.empty() && | |
| num_good < 3 && num_bad < 3 && | |
| (value > 3 || (num_bad > 0 && num_good == 0) || | |
| !one_in(3 - num_good) || !one_in(3 - num_bad))) { | |
| if (!one_in(3) && value <= 1) { // Good effect | |
| int index = rng(0, good_a_effects.size() - 1); | |
| active_tmp = good_a_effects[index]; | |
| good_a_effects.erase(good_a_effects.begin() + index); | |
| num_good++; | |
| value += active_effect_cost[active_tmp]; | |
| } else { // Bad effect | |
| int index = rng(0, bad_a_effects.size() - 1); | |
| active_tmp = bad_a_effects[index]; | |
| bad_a_effects.erase(bad_a_effects.begin() + index); | |
| num_bad++; | |
| value += active_effect_cost[active_tmp]; | |
| } | |
| art->effects_activated.push_back(active_tmp); | |
| art->max_charges += rng(1, 3); | |
| } | |
| art->def_charges = art->max_charges; | |
| art->rand_charges.push_back(art->max_charges); | |
| // If we have charges, pick a recharge mechanism | |
| if (art->max_charges > 0) { | |
| art->charge_type = art_charge( rng(ARTC_NULL + 1, NUM_ARTCS - 1) ); | |
| } | |
| if (one_in(8) && num_bad + num_good >= 4) { | |
| art->charge_type = ARTC_NULL; // 1 in 8 chance that it can't recharge! | |
| } | |
| artifact_itype_ids.push_back(art->id); | |
| item_controller->add_item_type( art ); | |
| return art->id; | |
| } else { // Generate an armor artifact | |
| it_artifact_armor *art = new it_artifact_armor(); | |
| int form = rng(ARTARMFORM_NULL + 1, NUM_ARTARMFORMS - 1); | |
| artifact_armor_form_datum *info = &(artifact_armor_form_data[form]); | |
| art->create_name(info->name); | |
| art->sym = '['; // Armor is always [ | |
| art->color = info->color; | |
| art->m1 = info->m1; | |
| art->m2 = info->m2; | |
| art->volume = info->volume; | |
| art->weight = info->weight; | |
| art->melee_dam = info->melee_bash; | |
| art->melee_cut = info->melee_cut; | |
| art->m_to_hit = info->melee_hit; | |
| art->covers = info->covers; | |
| art->encumber = info->encumb; | |
| art->coverage = info->coverage; | |
| art->thickness = info->thickness; | |
| art->env_resist = info->env_resist; | |
| art->warmth = info->warmth; | |
| art->storage = info->storage; | |
| std::stringstream description; | |
| description << string_format(info->plural ? | |
| _("This is the %s.\nThey are the only ones of their kind.") : | |
| _("This is the %s.\nIt is the only one of its kind."), | |
| art->nname(1).c_str()); | |
| // Modify the armor further | |
| if (!one_in(4)) { | |
| int index = rng(0, 4); | |
| if (info->available_mods[index] != ARMORMOD_NULL) { | |
| artifact_armor_mod mod = info->available_mods[index]; | |
| artifact_armor_form_datum *modinfo = &(artifact_armor_mod_data[mod]); | |
| if (modinfo->volume >= 0 || art->volume > unsigned(abs(modinfo->volume))) { | |
| art->volume += modinfo->volume; | |
| } else { | |
| art->volume = 1; | |
| } | |
| if (modinfo->weight >= 0 || art->weight > unsigned(abs(modinfo->weight))) { | |
| art->weight += modinfo->weight; | |
| } else { | |
| art->weight = 1; | |
| } | |
| art->encumber += modinfo->encumb; | |
| if (modinfo->coverage > 0 || art->coverage > abs(modinfo->coverage)) { | |
| art->coverage += modinfo->coverage; | |
| } else { | |
| art->coverage = 0; | |
| } | |
| if (modinfo->thickness > 0 || art->thickness > abs(modinfo->thickness)) { | |
| art->thickness += modinfo->thickness; | |
| } else { | |
| art->thickness = 0; | |
| } | |
| if (modinfo->env_resist > 0 || art->env_resist > abs(modinfo->env_resist)) { | |
| art->env_resist += modinfo->env_resist; | |
| } else { | |
| art->env_resist = 0; | |
| } | |
| art->warmth += modinfo->warmth; | |
| if (modinfo->storage > 0 || art->storage > abs(modinfo->storage)) { | |
| art->storage += modinfo->storage; | |
| } else { | |
| art->storage = 0; | |
| } | |
| description << string_format(info->plural ? | |
| _("\nThey are %s") : | |
| _("\nIt is %s"), | |
| modinfo->name.c_str()); | |
| } | |
| } | |
| art->description = description.str(); | |
| // Finally, pick some effects | |
| int num_good = 0, num_bad = 0, value = 0; | |
| art_effect_passive passive_tmp = AEP_NULL; | |
| std::vector<art_effect_passive> good_effects = fill_good_passive(); | |
| std::vector<art_effect_passive> bad_effects = fill_bad_passive(); | |
| while (!good_effects.empty() && !bad_effects.empty() && | |
| num_good < 3 && num_bad < 3 && | |
| (num_good < 1 || one_in(num_good * 2) || value > 1 || | |
| (num_bad < 3 && !one_in(3 - num_bad)))) { | |
| if (value < 1 && one_in(2)) { // Good effect | |
| int index = rng(0, good_effects.size() - 1); | |
| passive_tmp = good_effects[index]; | |
| good_effects.erase(good_effects.begin() + index); | |
| num_good++; | |
| } else { // Bad effect | |
| int index = rng(0, bad_effects.size() - 1); | |
| passive_tmp = bad_effects[index]; | |
| bad_effects.erase(bad_effects.begin() + index); | |
| num_bad++; | |
| } | |
| value += passive_effect_cost[passive_tmp]; | |
| art->effects_worn.push_back(passive_tmp); | |
| } | |
| artifact_itype_ids.push_back(art->id); | |
| item_controller->add_item_type( art ); | |
| return art->id; | |
| } | |
| } | |
| std::string new_natural_artifact(artifact_natural_property prop) | |
| { | |
| // Natural artifacts are always tools. | |
| it_artifact_tool *art = new it_artifact_tool(); | |
| // Pick a form | |
| artifact_natural_shape shape = | |
| artifact_natural_shape(rng(ARTSHAPE_NULL + 1, ARTSHAPE_MAX - 1)); | |
| artifact_shape_datum *shape_data = &(artifact_shape_data[shape]); | |
| // Pick a property | |
| artifact_natural_property property = (prop > ARTPROP_NULL ? prop : | |
| artifact_natural_property(rng(ARTPROP_NULL + 1, | |
| ARTPROP_MAX - 1))); | |
| artifact_property_datum *property_data = &(artifact_property_data[property]); | |
| art->sym = ':'; | |
| art->color = c_yellow; | |
| art->m1 = "stone"; | |
| art->m2 = "null"; | |
| art->volume = rng(shape_data->volume_min, shape_data->volume_max); | |
| art->weight = rng(shape_data->weight_min, shape_data->weight_max); | |
| art->melee_dam = 0; | |
| art->melee_cut = 0; | |
| art->m_to_hit = 0; | |
| art->create_name(property_data->name, shape_data->name); | |
| art->description = rmp_format(_("<artifact_desc>This %1$s %2$s."), shape_data->desc.c_str(), | |
| property_data->desc.c_str()); | |
| // Three possibilities: good passive + bad passive, good active + bad active, | |
| // and bad passive + good active | |
| bool good_passive = false, bad_passive = false, | |
| good_active = false, bad_active = false; | |
| switch (rng(1, 3)) { | |
| case 1: | |
| good_passive = true; | |
| bad_passive = true; | |
| break; | |
| case 2: | |
| good_active = true; | |
| bad_active = true; | |
| break; | |
| case 3: | |
| bad_passive = true; | |
| good_active = true; | |
| break; | |
| } | |
| int value_to_reach = 0; // This is slowly incremented, allowing for better arts | |
| int value = 0; | |
| art_effect_passive aep_good = AEP_NULL, aep_bad = AEP_NULL; | |
| art_effect_active aea_good = AEA_NULL, aea_bad = AEA_NULL; | |
| do { | |
| if (good_passive) { | |
| aep_good = property_data->passive_good[ rng(0, 3) ]; | |
| if (aep_good == AEP_NULL || one_in(4)) { | |
| aep_good = art_effect_passive(rng(AEP_NULL + 1, AEP_SPLIT - 1)); | |
| } | |
| } | |
| if (bad_passive) { | |
| aep_bad = property_data->passive_bad[ rng(0, 3) ]; | |
| if (aep_bad == AEP_NULL || one_in(4)) { | |
| aep_bad = art_effect_passive(rng(AEP_SPLIT + 1, NUM_AEAS - 1)); | |
| } | |
| } | |
| if (good_active) { | |
| aea_good = property_data->active_good[ rng(0, 3) ]; | |
| if (aea_good == AEA_NULL || one_in(4)) { | |
| aea_good = art_effect_active(rng(AEA_NULL + 1, AEA_SPLIT - 1)); | |
| } | |
| } | |
| if (bad_active) { | |
| aea_bad = property_data->active_bad[ rng(0, 3) ]; | |
| if (aea_bad == AEA_NULL || one_in(4)) { | |
| aea_bad = art_effect_active(rng(AEA_SPLIT + 1, NUM_AEAS - 1)); | |
| } | |
| } | |
| value = passive_effect_cost[aep_good] + passive_effect_cost[aep_bad] + | |
| active_effect_cost[aea_good] + active_effect_cost[aea_bad]; | |
| value_to_reach++; // Yes, it is intentional that this is 1 the first check | |
| } while (value > value_to_reach); | |
| if (aep_good != AEP_NULL) { | |
| art->effects_carried.push_back(aep_good); | |
| } | |
| if (aep_bad != AEP_NULL) { | |
| art->effects_carried.push_back(aep_bad); | |
| } | |
| if (aea_good != AEA_NULL) { | |
| art->effects_activated.push_back(aea_good); | |
| } | |
| if (aea_bad != AEA_NULL) { | |
| art->effects_activated.push_back(aea_bad); | |
| } | |
| // Natural artifacts ALWAYS can recharge | |
| // (When "implanting" them in a mundane item, this ability may be lost | |
| if (!art->effects_activated.empty()) { | |
| art->max_charges = rng(1, 4); | |
| art->def_charges = art->max_charges; | |
| art->rand_charges.push_back(art->max_charges); | |
| art->charge_type = art_charge( rng(ARTC_NULL + 1, NUM_ARTCS - 1) ); | |
| } | |
| artifact_itype_ids.push_back(art->id); | |
| item_controller->add_item_type( art ); | |
| return art->id; | |
| } | |
| // Make a special debugging artifact. | |
| std::string architects_cube() | |
| { | |
| std::string artifact_name(std::string type); | |
| it_artifact_tool *art = new it_artifact_tool(); | |
| artifact_tool_form_datum *info = &(artifact_tool_form_data[ARTTOOLFORM_CUBE]); | |
| art->create_name(info->name); | |
| art->color = info->color; | |
| art->sym = info->sym; | |
| art->m1 = info->m1; | |
| art->m2 = info->m2; | |
| art->volume = rng(info->volume_min, info->volume_max); | |
| art->weight = rng(info->weight_min, info->weight_max); | |
| // Set up the basic weapon type | |
| artifact_weapon_datum *weapon = &(artifact_weapon_data[info->base_weapon]); | |
| art->melee_dam = rng(weapon->bash_min, weapon->bash_max); | |
| art->melee_cut = rng(weapon->cut_min, weapon->cut_max); | |
| art->m_to_hit = rng(weapon->to_hit_min, weapon->to_hit_max); | |
| if( weapon->tag != "" ) { | |
| art->item_tags.insert(weapon->tag); | |
| } | |
| // Add an extra weapon perhaps? | |
| art->description = _("The architect's cube."); | |
| art->effects_carried.push_back(AEP_SUPER_CLAIRVOYANCE); | |
| item_controller->add_item_type( art ); | |
| artifact_itype_ids.push_back(art->id); | |
| return art->id; | |
| } | |
| std::vector<art_effect_passive> fill_good_passive() | |
| { | |
| std::vector<art_effect_passive> ret; | |
| for (int i = AEP_NULL + 1; i < AEP_SPLIT; i++) { | |
| ret.push_back( art_effect_passive(i) ); | |
| } | |
| return ret; | |
| } | |
| std::vector<art_effect_passive> fill_bad_passive() | |
| { | |
| std::vector<art_effect_passive> ret; | |
| for (int i = AEP_SPLIT + 1; i < NUM_AEPS; i++) { | |
| ret.push_back( art_effect_passive(i) ); | |
| } | |
| return ret; | |
| } | |
| std::vector<art_effect_active> fill_good_active() | |
| { | |
| std::vector<art_effect_active> ret; | |
| for (int i = AEA_NULL + 1; i < AEA_SPLIT; i++) { | |
| ret.push_back( art_effect_active(i) ); | |
| } | |
| return ret; | |
| } | |
| std::vector<art_effect_active> fill_bad_active() | |
| { | |
| std::vector<art_effect_active> ret; | |
| for (int i = AEA_SPLIT + 1; i < NUM_AEAS; i++) { | |
| ret.push_back( art_effect_active(i) ); | |
| } | |
| return ret; | |
| } | |
| std::string artifact_name(std::string type) | |
| { | |
| std::string ret; | |
| const char *fmtstr = _("<artifact_name>%1$s of %2$s"); | |
| std::string noun = artifact_noun[rng(0, NUM_ART_NOUNS - 1)]; | |
| std::string adj = artifact_adj[rng(0, NUM_ART_ADJS - 1)]; | |
| ret = string_format(noun, adj.c_str()); | |
| ret = rmp_format(fmtstr, type.c_str(), ret.c_str()); | |
| return ret; | |
| } | |
| /* Json Loading and saving */ | |
| void load_artifacts(const std::string &artfilename) | |
| { | |
| std::ifstream file_test(artfilename.c_str(), | |
| std::ifstream::in | std::ifstream::binary); | |
| if (!file_test.good()) { | |
| file_test.close(); | |
| return; | |
| } | |
| try { | |
| load_artifacts_from_ifstream(file_test); | |
| } catch (std::string e) { | |
| debugmsg("%s: %s", artfilename.c_str(), e.c_str()); | |
| } | |
| file_test.close(); | |
| } | |
| void load_artifacts_from_ifstream(std::ifstream &f) | |
| { | |
| // delete current artefact ids | |
| artifact_itype_ids.clear(); | |
| // read and create artifacts from json array in artifacts.gsav | |
| JsonIn artifact_json(f); | |
| artifact_json.start_array(); | |
| while (!artifact_json.end_array()) { | |
| JsonObject jo = artifact_json.get_object(); | |
| std::string type = jo.get_string("type"); | |
| std::string id = jo.get_string("id"); | |
| if (type == "artifact_tool") { | |
| it_artifact_tool *art = new it_artifact_tool(jo); | |
| itypes[id] = art; | |
| artifact_itype_ids.push_back(id); | |
| } else if (type == "artifact_armor") { | |
| it_artifact_armor *art = new it_artifact_armor(jo); | |
| itypes[id] = art; | |
| artifact_itype_ids.push_back(id); | |
| } else { | |
| throw jo.line_number() + ": unrecognized artifact type."; | |
| } | |
| } | |
| } | |
| void it_artifact_tool::deserialize(JsonObject &jo) | |
| { | |
| id = jo.get_string("id"); | |
| name = jo.get_string("name"); | |
| description = jo.get_string("description"); | |
| sym = jo.get_int("sym"); | |
| color = int_to_color(jo.get_int("color")); | |
| price = jo.get_int("price"); | |
| m1 = jo.get_string("m1"); | |
| m2 = jo.get_string("m2"); | |
| volume = jo.get_int("volume"); | |
| weight = jo.get_int("weight"); | |
| melee_dam = jo.get_int("melee_dam"); | |
| melee_cut = jo.get_int("melee_cut"); | |
| m_to_hit = jo.get_int("m_to_hit"); | |
| item_tags = jo.get_tags("item_flags"); | |
| max_charges = jo.get_long("max_charges"); | |
| def_charges = jo.get_long("def_charges"); | |
| std::vector<int> rand_charges; | |
| JsonArray jarr = jo.get_array("rand_charges"); | |
| while (jarr.has_more()) { | |
| rand_charges.push_back(jarr.next_long()); | |
| } | |
| charges_per_use = jo.get_int("charges_per_use"); | |
| turns_per_charge = jo.get_int("turns_per_charge"); | |
| ammo = jo.get_string("ammo"); | |
| revert_to = jo.get_string("revert_to"); | |
| charge_type = (art_charge)jo.get_int("charge_type"); | |
| JsonArray ja = jo.get_array("effects_wielded"); | |
| while (ja.has_more()) { | |
| effects_wielded.push_back((art_effect_passive)ja.next_int()); | |
| } | |
| ja = jo.get_array("effects_activated"); | |
| while (ja.has_more()) { | |
| effects_activated.push_back((art_effect_active)ja.next_int()); | |
| } | |
| ja = jo.get_array("effects_carried"); | |
| while (ja.has_more()) { | |
| effects_carried.push_back((art_effect_passive)ja.next_int()); | |
| } | |
| } | |
| void it_artifact_armor::deserialize(JsonObject &jo) | |
| { | |
| id = jo.get_string("id"); | |
| name = jo.get_string("name"); | |
| description = jo.get_string("description"); | |
| sym = jo.get_int("sym"); | |
| color = int_to_color(jo.get_int("color")); | |
| price = jo.get_int("price"); | |
| m1 = jo.get_string("m1"); | |
| m2 = jo.get_string("m2"); | |
| volume = jo.get_int("volume"); | |
| weight = jo.get_int("weight"); | |
| melee_dam = jo.get_int("melee_dam"); | |
| melee_cut = jo.get_int("melee_cut"); | |
| m_to_hit = jo.get_int("m_to_hit"); | |
| item_tags = jo.get_tags("item_flags"); | |
| covers = jo.get_int("covers"); | |
| encumber = jo.get_int("encumber"); | |
| coverage = jo.get_int("coverage"); | |
| thickness = jo.get_int("material_thickness"); | |
| env_resist = jo.get_int("env_resist"); | |
| warmth = jo.get_int("warmth"); | |
| storage = jo.get_int("storage"); | |
| power_armor = jo.get_bool("power_armor"); | |
| JsonArray ja = jo.get_array("effects_worn"); | |
| while (ja.has_more()) { | |
| effects_worn.push_back((art_effect_passive)ja.next_int()); | |
| } | |
| } | |
| void it_artifact_tool::serialize(JsonOut &json) const | |
| { | |
| json.start_object(); | |
| json.member("type", "artifact_tool"); | |
| // generic data | |
| json.member("id", id); | |
| json.member("name", name); | |
| json.member("description", description); | |
| json.member("sym", sym); | |
| json.member("color", color_to_int(color)); | |
| json.member("price", price); | |
| json.member("m1", m1); | |
| json.member("m2", m2); | |
| json.member("volume", volume); | |
| json.member("weight", weight); | |
| json.member("melee_dam", melee_dam); | |
| json.member("melee_cut", melee_cut); | |
| json.member("m_to_hit", m_to_hit); | |
| json.member("item_flags", item_tags); | |
| json.member("techniques", techniques); | |
| // tool data | |
| json.member("ammo", ammo); | |
| json.member("max_charges", max_charges); | |
| json.member("def_charges", def_charges); | |
| json.member("rand_charges", rand_charges); | |
| json.member("charges_per_use", charges_per_use); | |
| json.member("turns_per_charge", turns_per_charge); | |
| json.member("revert_to", revert_to); | |
| // artifact data | |
| json.member("charge_type", charge_type); | |
| json.member("effects_wielded", effects_wielded); | |
| json.member("effects_activated", effects_activated); | |
| json.member("effects_carried", effects_carried); | |
| json.end_object(); | |
| } | |
| void it_artifact_armor::serialize(JsonOut &json) const | |
| { | |
| json.start_object(); | |
| json.member("type", "artifact_armor"); | |
| // generic data | |
| json.member("id", id); | |
| json.member("name", name); | |
| json.member("description", description); | |
| json.member("sym", sym); | |
| json.member("color", color_to_int(color)); | |
| json.member("price", price); | |
| json.member("m1", m1); | |
| json.member("m2", m2); | |
| json.member("volume", volume); | |
| json.member("weight", weight); | |
| json.member("melee_dam", melee_dam); | |
| json.member("melee_cut", melee_cut); | |
| json.member("m_to_hit", m_to_hit); | |
| json.member("item_flags", item_tags); | |
| json.member("techniques", techniques); | |
| // armor data | |
| json.member("covers", covers); | |
| json.member("encumber", encumber); | |
| json.member("coverage", coverage); | |
| json.member("material_thickness", thickness); | |
| json.member("env_resist", env_resist); | |
| json.member("warmth", warmth); | |
| json.member("storage", storage); | |
| json.member("power_armor", power_armor); | |
| // artifact data | |
| json.member("effects_worn", effects_worn); | |
| json.end_object(); | |
| } | |