diff --git a/CataclysmWin.cbp b/CataclysmWin.cbp index eac983cb55f9b..0e622c062d5a1 100644 --- a/CataclysmWin.cbp +++ b/CataclysmWin.cbp @@ -188,7 +188,6 @@ - diff --git a/animation_curses.cpp b/animation_curses.cpp index b727aa5723e12..800acdd845cbd 100644 --- a/animation_curses.cpp +++ b/animation_curses.cpp @@ -58,6 +58,7 @@ void game::draw_hit_mon(int x, int y, monster m, bool dead) /* Player hit animation */ void game::draw_hit_player(player *p, bool dead) { + (void)dead; //unused hit_animation(POSX + (p->posx - (u.posx + u.view_offset_x)), POSY + (p->posy - (u.posy + u.view_offset_y)), red_background(p->color()), '@'); @@ -91,6 +92,8 @@ void game::draw_line(const int x, const int y, const point center_point, std::ve } void game::draw_line(const int x, const int y, std::vector vPoint) { + (void)x; //unused + (void)y; //unused for (int i = 1; i < vPoint.size(); i++) { m.drawsq(w_terrain, u, vPoint[i-1].x, vPoint[i-1].y, true, true); diff --git a/animation_tiles.cpp b/animation_tiles.cpp index c94beab387038..aad1757d05be8 100644 --- a/animation_tiles.cpp +++ b/animation_tiles.cpp @@ -41,6 +41,8 @@ void game::draw_explosion(int x, int y, int radius, nc_color col) // need to have a version where there is no player defined, possibly. That way shrapnel works as intended void game::draw_bullet(player &p, int tx, int ty, int i, std::vector trajectory, char bullet_char, timespec &ts) { + (void)i; //unused + (void)trajectory; //unused if (u_see(tx, ty)) { std::string bullet;// = "animation_bullet_normal"; switch(bullet_char) @@ -94,6 +96,7 @@ void game::draw_hit_mon(int x, int y, monster m, bool dead) /* Player hit animation */ void game::draw_hit_player(player *p, bool dead) { + (void)dead; //unused if (use_tiles) { // get base name of player id diff --git a/artifact.cpp b/artifact.cpp index 20f2096647a07..9c015a62e01ca 100644 --- a/artifact.cpp +++ b/artifact.cpp @@ -1,8 +1,13 @@ -#include -#include -#include "game.h" #include "artifact.h" -#include "artifactdata.h" + +#include "itype.h" +#include "output.h" // string_format +#include "json.h" + +#include +#include +#include +#include std::vector fill_good_passive(); std::vector fill_bad_passive(); @@ -101,7 +106,7 @@ std::string artifact_adj[NUM_ART_ADJS]; std::string artifact_noun[NUM_ART_NOUNS]; std::string artifact_name(std::string type); -void game::init_artifacts() +void init_artifacts() { artifact_shape_datum tmp_artifact_shape_data[ARTSHAPE_MAX] = { {"BUG", "BUG", 0, 0, 0, 0}, @@ -367,7 +372,7 @@ void game::init_artifacts() } -itype* game::new_artifact() +itype* new_artifact(itypemap &itypes) { if (one_in(2)) { // Generate a "tool" artifact @@ -612,7 +617,7 @@ itype* game::new_artifact() } } -itype* game::new_natural_artifact(artifact_natural_property prop) +itype* new_natural_artifact(itypemap &itypes, artifact_natural_property prop) { // Natural artifacts are always tools. it_artifact_tool *art = new it_artifact_tool(); @@ -771,273 +776,204 @@ std::string artifact_name(std::string type) } -void game::process_artifact(item *it, player *p, bool wielded) -{ - std::vector effects; - if (it->is_armor()) { - it_artifact_armor* armor = dynamic_cast(it->type); - effects = armor->effects_worn; - } else if (it->is_tool()) { - it_artifact_tool* tool = dynamic_cast(it->type); - effects = tool->effects_carried; - if (wielded) { - for (int i = 0; i < tool->effects_wielded.size(); i++) - effects.push_back(tool->effects_wielded[i]); - } -// Recharge it if necessary - if (it->charges < tool->max_charges) { - switch (tool->charge_type) { - case ARTC_TIME: - if (turn.seconds() == 0 && turn.minutes() == 0) // Once per hour - it->charges++; - break; - case ARTC_SOLAR: - if (turn.seconds() == 0 && turn.minutes() % 10 == 0 && - is_in_sunlight(p->posx, p->posy)) - it->charges++; - break; - case ARTC_PAIN: - if (turn.seconds() == 0) { - add_msg(_("You suddenly feel sharp pain for no reason.")); - p->pain += 3 * rng(1, 3); - it->charges++; - } - break; - case ARTC_HP: - if (turn.seconds() == 0) { - add_msg(_("You feel your body decaying.")); - p->hurtall(1); - it->charges++; - } - break; - } - } - } - - for (int i = 0; i < effects.size(); i++) { - switch (effects[i]) { - case AEP_STR_UP: - p->str_cur += 4; - break; - case AEP_DEX_UP: - p->dex_cur += 4; - break; - case AEP_PER_UP: - p->per_cur += 4; - break; - case AEP_INT_UP: - p->int_cur += 4; - break; - case AEP_ALL_UP: - p->str_cur += 2; - p->dex_cur += 2; - p->per_cur += 2; - p->int_cur += 2; - break; - case AEP_SPEED_UP: // Handled in player::current_speed() - break; - - case AEP_IODINE: - if (p->radiation > 0) - p->radiation--; - break; - - case AEP_SMOKE: - if (one_in(10)) { - int x = p->posx + rng(-1, 1), y = p->posy + rng(-1, 1); - if (m.add_field(this, x, y, fd_smoke, rng(1, 3))) - add_msg(_("The %s emits some smoke."), it->tname().c_str()); - } - break; - - case AEP_SNAKES: - break; // Handled in player::hit() +/* Json Loading and saving */ - case AEP_EXTINGUISH: - for (int x = p->posx - 1; x <= p->posx + 1; x++) { - for (int y = p->posy - 1; y <= p->posy + 1; y++) { - m.adjust_field_age(point(x,y), fd_fire, -1); +void load_artifacts(const std::string &artfilename, itypemap &itypes) +{ + std::ifstream file_test(artfilename.c_str(), + std::ifstream::in | std::ifstream::binary); + if (!file_test.good()) { + file_test.close(); + return; } - } - - case AEP_HUNGER: - if (one_in(100)) - p->hunger++; - break; - - case AEP_THIRST: - if (one_in(120)) - p->thirst++; - break; - - case AEP_EVIL: - if (one_in(150)) { // Once every 15 minutes, on average - p->add_disease("evil", 300); - if (!wielded && !it->is_armor()) - add_msg((it->is_armor() ? _("You have an urge to wear the %s.") : _("You have an urge to wield the %s.")), it->tname().c_str()); - } - break; - - case AEP_SCHIZO: - break; // Handled in player::suffer() - case AEP_RADIOACTIVE: - if (one_in(4)) - p->radiation++; - break; + try { + load_artifacts_from_ifstream(&file_test, itypes); + } catch (std::string e) { + debugmsg("%s: %s", artfilename.c_str(), e.c_str()); + } - case AEP_STR_DOWN: - p->str_cur -= 3; - break; + file_test.close(); +} - case AEP_DEX_DOWN: - p->dex_cur -= 3; - break; +void load_artifacts_from_ifstream(std::ifstream *f, itypemap &itypes) +{ + // 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."; + } + } +} - case AEP_PER_DOWN: - p->per_cur -= 3; - break; - case AEP_INT_DOWN: - p->int_cur -= 3; - break; +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_int("max_charges"); + def_charges = jo.get_int("def_charges"); + 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()); + } - case AEP_ALL_DOWN: - p->str_cur -= 2; - p->dex_cur -= 2; - p->per_cur -= 2; - p->int_cur -= 2; - break; + ja = jo.get_array("effects_activated"); + while (ja.has_more()) { + effects_activated.push_back((art_effect_active)ja.next_int()); + } - case AEP_SPEED_DOWN: - break; // Handled in player::current_speed() - } - } + ja = jo.get_array("effects_carried"); + while (ja.has_more()) { + effects_carried.push_back((art_effect_passive)ja.next_int()); + } } -void game::add_artifact_messages(std::vector effects) +void it_artifact_armor::deserialize(JsonObject &jo) { - int net_str = 0, net_dex = 0, net_per = 0, net_int = 0, net_speed = 0; - for (int i = 0; i < effects.size(); i++) { - switch (effects[i]) { - case AEP_STR_UP: net_str += 4; break; - case AEP_DEX_UP: net_dex += 4; break; - case AEP_PER_UP: net_per += 4; break; - case AEP_INT_UP: net_int += 4; break; - case AEP_ALL_UP: net_str += 2; - net_dex += 2; - net_per += 2; - net_int += 2; break; - case AEP_STR_DOWN: net_str -= 3; break; - case AEP_DEX_DOWN: net_dex -= 3; break; - case AEP_PER_DOWN: net_per -= 3; break; - case AEP_INT_DOWN: net_int -= 3; break; - case AEP_ALL_DOWN: net_str -= 2; - net_dex -= 2; - net_per -= 2; - net_int -= 2; break; - - case AEP_SPEED_UP: net_speed += 20; break; - case AEP_SPEED_DOWN: net_speed -= 20; break; - - case AEP_IODINE: - break; // No message - - case AEP_SNAKES: - add_msg(_("Your skin feels slithery.")); - break; - - case AEP_INVISIBLE: - add_msg(_("You fade into invisibility!")); - break; - - case AEP_CLAIRVOYANCE: - add_msg(_("You can see through walls!")); - break; - - case AEP_SUPER_CLAIRVOYANCE: - add_msg(_("You can see through everything!")); - break; - - case AEP_STEALTH: - add_msg(_("Your steps stop making noise.")); - break; - - case AEP_GLOW: - add_msg(_("A glow of light forms around you.")); - break; - - case AEP_PSYSHIELD: - add_msg(_("Your mental state feels protected.")); - break; - - case AEP_RESIST_ELECTRICITY: - add_msg(_("You feel insulated.")); - break; - - case AEP_CARRY_MORE: - add_msg(_("Your back feels strengthened.")); - break; - - case AEP_HUNGER: - add_msg(_("You feel hungry.")); - break; - - case AEP_THIRST: - add_msg(_("You feel thirsty.")); - break; - - case AEP_EVIL: - add_msg(_("You feel an evil presence...")); - break; - - case AEP_SCHIZO: - add_msg(_("You feel a tickle of insanity.")); - break; - - case AEP_RADIOACTIVE: - add_msg(_("Your skin prickles with radiation.")); - break; - - case AEP_MUTAGENIC: - add_msg(_("You feel your genetic makeup degrading.")); - break; - - case AEP_ATTENTION: - add_msg(_("You feel an otherworldly attention upon you...")); - break; - - case AEP_FORCE_TELEPORT: - add_msg(_("You feel a force pulling you inwards.")); - break; - - case AEP_MOVEMENT_NOISE: - add_msg(_("You hear a rattling noise coming from inside yourself.")); - break; - - case AEP_BAD_WEATHER: - add_msg(_("You feel storms coming.")); - break; - } - } - - std::string stat_info = ""; - if (net_str != 0) { - stat_info += string_format(_("Str %s%d! "), (net_str > 0 ? "+" : ""), net_str); - } - if (net_dex != 0) { - stat_info += string_format( _("Dex %s%d! "), (net_dex > 0 ? "+" : ""), net_dex); - } - if (net_int != 0) { - stat_info += string_format(_("Int %s%d! "), (net_int > 0 ? "+" : ""), net_int); - } - if (net_per != 0) { - stat_info += string_format(_("Per %s%d! "), (net_per > 0 ? "+" : ""), net_per); - } + 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()); + } +} - if (stat_info.length() > 0) - add_msg(stat_info.c_str()); +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("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(); +} - if (net_speed != 0) - add_msg(_("Speed %s%d! "), (net_speed > 0 ? "+" : ""), net_speed); +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("id", id); + 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(); } + diff --git a/artifact.h b/artifact.h index d040ccdd98fcf..9c68cbbf77c78 100644 --- a/artifact.h +++ b/artifact.h @@ -1,8 +1,12 @@ #ifndef _ARTIFACT_H_ #define _ARTIFACT_H_ +#include "itype.h" +#include "json.h" + #include #include +#include enum art_effect_passive { AEP_NULL = 0, @@ -50,6 +54,8 @@ enum art_effect_passive { NUM_AEPS }; +extern int passive_effect_cost[NUM_AEPS]; + enum art_effect_active { AEA_NULL = 0, @@ -89,6 +95,8 @@ enum art_effect_active { NUM_AEAS }; +extern int active_effect_cost[NUM_AEAS]; + enum art_charge { ARTC_NULL, // Never recharges! @@ -145,4 +153,188 @@ enum artifact_natural_property ARTPROP_MAX }; +struct artifact_shape_datum +{ + std::string name; + std::string desc; + int volume_min, volume_max; + int weight_min, weight_max; +}; + +extern artifact_shape_datum artifact_shape_data[ARTSHAPE_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]; +}; + +extern artifact_property_datum artifact_property_data[ARTPROP_MAX]; + +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 +}; + +extern artifact_tool_form_datum artifact_tool_form_data[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; +}; + +extern artifact_weapon_datum artifact_weapon_data[NUM_ARTWEAPS]; + +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 +}; + +extern 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. + */ +extern artifact_armor_form_datum artifact_armor_mod_data[NUM_ARMORMODS]; + +#define NUM_ART_ADJS 20 +extern std::string artifact_adj[NUM_ART_ADJS]; + +#define NUM_ART_NOUNS 20 +extern std::string artifact_noun[NUM_ART_NOUNS]; + + +/* CLASSES */ + +class it_artifact_tool : public it_tool, public JsonSerializer, public JsonDeserializer +{ +public: + art_charge charge_type; + std::vector effects_wielded; + std::vector effects_activated; + std::vector effects_carried; + + bool is_artifact() { return true; } + void serialize(JsonOut &json) const; + void deserialize(JsonObject &jo); + + it_artifact_tool(JsonObject &jo) : it_tool() { deserialize(jo); }; + + it_artifact_tool() : it_tool() { + ammo = "NULL"; + price = 0; + def_charges = 0; + charges_per_use = 1; + charge_type = ARTC_NULL; + turns_per_charge = 0; + revert_to = "null"; + use = &iuse::artifact; + }; +}; + +class it_artifact_armor : public it_armor, public JsonSerializer, public JsonDeserializer +{ +public: + std::vector effects_worn; + + bool is_artifact() { return true; } + void serialize(JsonOut &json) const; + void deserialize(JsonObject &jo); + + it_artifact_armor(JsonObject &jo) : it_armor() { deserialize(jo); }; + it_artifact_armor() : it_armor() { price = 0; }; +}; + + +/* FUNCTIONS */ + +typedef std::map itypemap; + +void init_artifacts(); +itype* new_artifact(itypemap &itypes); +itype* new_natural_artifact(itypemap &itypes, artifact_natural_property prop = ARTPROP_NULL); + +// note: needs to be called by main() before MAPBUFFER.load +void load_artifacts(const std::string &filename, itypemap &itypes); +void load_artifacts_from_ifstream(std::ifstream *f, itypemap &itypes); + #endif diff --git a/artifactdata.h b/artifactdata.h deleted file mode 100644 index 8742dacd3abf3..0000000000000 --- a/artifactdata.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef _ARTIFACTDATA_H_ -#define _ARTIFACTDATA_H_ - -#include -#include "artifact.h" -#include "itype.h" - -extern int passive_effect_cost[NUM_AEPS]; - -extern int active_effect_cost[NUM_AEAS]; - - -struct artifact_shape_datum -{ - std::string name; - std::string desc; - int volume_min, volume_max; - int weight_min, weight_max; -}; - -extern artifact_shape_datum artifact_shape_data[ARTSHAPE_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]; -}; - -extern artifact_property_datum artifact_property_data[ARTPROP_MAX]; - -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 -}; - -extern artifact_tool_form_datum artifact_tool_form_data[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; -}; - -extern artifact_weapon_datum artifact_weapon_data[NUM_ARTWEAPS]; - -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 -}; - -extern 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. - */ -extern artifact_armor_form_datum artifact_armor_mod_data[NUM_ARMORMODS]; - -#define NUM_ART_ADJS 20 -extern std::string artifact_adj[NUM_ART_ADJS]; - -#define NUM_ART_NOUNS 20 -extern std::string artifact_noun[NUM_ART_NOUNS]; - -#endif diff --git a/building_generation.cpp b/building_generation.cpp index d68451f1873c2..44c32de0562b3 100644 --- a/building_generation.cpp +++ b/building_generation.cpp @@ -265,7 +265,7 @@ void mapgen_forest_general(map *m, oter_id terrain_type, mapgendata dat, int tur if ((forest_chance > 0 && rn > 13) || one_in(100 - forest_chance)) { if (one_in(250)) { m->ter_set(i, j, t_tree_apple); - m->spawn_item(i, j, "apple", turn); + m->spawn_item(i, j, "apple", 1, 0, turn); } else { m->ter_set(i, j, t_tree); } @@ -1019,7 +1019,7 @@ void mapgen_river_curved(map *m, oter_id terrain_type) } } -void mapgen_parking_lot(map *m, oter_id terrain_type, mapgendata dat, int turn) +void mapgen_parking_lot(map *m, mapgendata dat, int turn) { for (int i = 0; i < SEEX * 2; i++) { for (int j = 0; j < SEEY * 2; j++) { @@ -1208,7 +1208,7 @@ void mapgen_park(map *m) m->add_spawn("mon_zombie_child", rng(2, 8), SEEX, SEEY); } -void mapgen_gas_station(map *m, oter_id terrain_type, int turn, float density) +void mapgen_gas_station(map *m, oter_id terrain_type, float density) { int top_w = rng(5, 14); int bottom_w = SEEY * 2 - rng(1, 2); diff --git a/building_generation.h b/building_generation.h index 9dae761700eba..12a933e915caf 100644 --- a/building_generation.h +++ b/building_generation.h @@ -46,9 +46,9 @@ void mapgen_highway(map *m, oter_id terrain_type, int turn); void mapgen_river_curved_not(map *m, oter_id terrain_type); void mapgen_river_straight(map *m, oter_id terrain_type); void mapgen_river_curved(map *m, oter_id terrain_type); -void mapgen_parking_lot(map *m, oter_id terrain_type, mapgendata dat, int turn); +void mapgen_parking_lot(map *m, mapgendata dat, int turn); void mapgen_pool(map *m); void mapgen_park(map *m); -void mapgen_gas_station(map *m, oter_id terrain_type, int turn, float density); +void mapgen_gas_station(map *m, oter_id terrain_type, float density); #endif diff --git a/construction.cpp b/construction.cpp index 37f4935f56f05..2e87dc0ae00bd 100644 --- a/construction.cpp +++ b/construction.cpp @@ -1011,11 +1011,14 @@ bool construct::able_deconstruct(game *g, point p) void construct::done_window_pane(game *g, point p) { - g->m.spawn_item(g->u.posx, g->u.posy, "glass_sheet", 0); + (void)p; //unused + g->m.spawn_item(g->u.posx, g->u.posy, "glass_sheet"); } +// STUB void construct::done_move(game *g, point p) { + (void)g; (void)p; // TODO: something? return; // stub } @@ -1036,11 +1039,12 @@ void construct::done_tree(game *g, point p) void construct::done_trunk_log(game *g, point p) { - g->m.spawn_item(p.x, p.y, "log", int(g->turn), rng(5, 15)); + g->m.spawn_item(p.x, p.y, "log", 1, 0, g->turn, rng(5, 15)); } void construct::done_trunk_plank(game *g, point p) { + (void)p; //unused int num_logs = rng(5, 15); for( int i = 0; i < num_logs; ++i ) { item tmplog(g->itypes["log"], int(g->turn), g->nextinv); @@ -1095,9 +1099,9 @@ void construct::done_deconstruct(game *g, point p) case old_f_makeshift_bed: case old_f_bed: case old_f_armchair: - g->m.spawn_item(p.x, p.y, "2x4", 0, 10); - g->m.spawn_item(p.x, p.y, "rag", 0, rng(10,15)); - g->m.spawn_item(p.x, p.y, "nail", 0, 0, rng(6,8)); + g->m.spawn_item(p.x, p.y, "2x4", 10); + g->m.spawn_item(p.x, p.y, "rag", rng(10,15)); + g->m.spawn_item(p.x, p.y, "nail", 0, rng(6,8)); g->m.furn_set(p.x, p.y, f_null); case old_f_bench: case old_f_crate_o: @@ -1106,57 +1110,57 @@ void construct::done_deconstruct(game *g, point p) case old_f_cupboard: case old_f_desk: case old_f_bulletin: - g->m.spawn_item(p.x, p.y, "2x4", 0, 4); - g->m.spawn_item(p.x, p.y, "nail", 0, 0, rng(6,10)); + g->m.spawn_item(p.x, p.y, "2x4", 4); + g->m.spawn_item(p.x, p.y, "nail", 0, rng(6,10)); g->m.furn_set(p.x, p.y, f_null); break; case old_f_locker: - g->m.spawn_item(p.x, p.y, "sheet_metal", 0, rng(1,2)); - g->m.spawn_item(p.x, p.y, "pipe", 0, rng(4,8)); + g->m.spawn_item(p.x, p.y, "sheet_metal", rng(1,2)); + g->m.spawn_item(p.x, p.y, "pipe", rng(4,8)); g->m.furn_set(p.x, p.y, f_null); break; case old_f_rack: - g->m.spawn_item(p.x, p.y, "pipe", 0, rng(6,12)); + g->m.spawn_item(p.x, p.y, "pipe", rng(6,12)); g->m.furn_set(p.x, p.y, f_null); break; case old_f_oven: - g->m.spawn_item(p.x, p.y, "scrap", 0, rng(2,6)); - g->m.spawn_item(p.x, p.y, "steel_chunk", 0, rng(2,3)); - g->m.spawn_item(p.x, p.y, "element", 0, rng(1,4)); - g->m.spawn_item(p.x, p.y, "pilot_light", 0, 1); + g->m.spawn_item(p.x, p.y, "scrap", rng(2,6)); + g->m.spawn_item(p.x, p.y, "steel_chunk", rng(2,3)); + g->m.spawn_item(p.x, p.y, "element", rng(1,4)); + g->m.spawn_item(p.x, p.y, "pilot_light", 1); g->m.furn_set(p.x, p.y, f_null); case old_f_fridge: - g->m.spawn_item(p.x, p.y, "scrap", 0, rng(2,6)); - g->m.spawn_item(p.x, p.y, "steel_chunk", 0, rng(2,3)); - g->m.spawn_item(p.x, p.y, "hose", 0, 1); - g->m.spawn_item(p.x, p.y, "cu_pipe", 0, rng(3, 6)); + g->m.spawn_item(p.x, p.y, "scrap", rng(2,6)); + g->m.spawn_item(p.x, p.y, "steel_chunk", rng(2,3)); + g->m.spawn_item(p.x, p.y, "hose", 1); + g->m.spawn_item(p.x, p.y, "cu_pipe", rng(3, 6)); g->m.furn_set(p.x, p.y, f_null); break; case old_f_glass_fridge: - g->m.spawn_item(p.x, p.y, "scrap", 0, rng(2,6)); - g->m.spawn_item(p.x, p.y, "steel_chunk", 0, rng(2,3)); - g->m.spawn_item(p.x, p.y, "hose", 0, 1); - g->m.spawn_item(p.x, p.y, "glass_sheet", 0, 1); - g->m.spawn_item(p.x, p.y, "cu_pipe", 0, rng(3, 6)); + g->m.spawn_item(p.x, p.y, "scrap", rng(2,6)); + g->m.spawn_item(p.x, p.y, "steel_chunk", rng(2,3)); + g->m.spawn_item(p.x, p.y, "hose", 1); + g->m.spawn_item(p.x, p.y, "glass_sheet", 1); + g->m.spawn_item(p.x, p.y, "cu_pipe", rng(3, 6)); g->m.furn_set(p.x, p.y, f_null); break; case old_f_counter: case old_f_dresser: case old_f_table: - g->m.spawn_item(p.x, p.y, "2x4", 0, 6); - g->m.spawn_item(p.x, p.y, "nail", 0, 0, rng(6,8)); + g->m.spawn_item(p.x, p.y, "2x4", 6); + g->m.spawn_item(p.x, p.y, "nail", 0, rng(6,8)); g->m.furn_set(p.x, p.y, f_null); break; case old_f_pool_table: - g->m.spawn_item(p.x, p.y, "2x4", 0, 4); - g->m.spawn_item(p.x, p.y, "rag", 0, 4); - g->m.spawn_item(p.x, p.y, "nail", 0, 0, rng(6,10)); + g->m.spawn_item(p.x, p.y, "2x4", 4); + g->m.spawn_item(p.x, p.y, "rag", 4); + g->m.spawn_item(p.x, p.y, "nail", 0, rng(6,10)); g->m.furn_set(p.x, p.y, f_null); break; case old_f_bookcase: - g->m.spawn_item(p.x, p.y, "2x4", 0, 12); - g->m.spawn_item(p.x, p.y, "nail", 0, 0, rng(12,16)); + g->m.spawn_item(p.x, p.y, "2x4", 12); + g->m.spawn_item(p.x, p.y, "nail", 0, rng(12,16)); g->m.furn_set(p.x, p.y, f_null); break; default: @@ -1169,40 +1173,40 @@ void construct::done_deconstruct(game *g, point p) { case old_t_door_c: case old_t_door_o: - g->m.spawn_item(p.x, p.y, "2x4", 0, 4); - g->m.spawn_item(p.x, p.y, "nail", 0, 0, rng(6,12)); + g->m.spawn_item(p.x, p.y, "2x4", 4); + g->m.spawn_item(p.x, p.y, "nail", 0, rng(6,12)); g->m.ter_set(p.x, p.y, t_door_frame); break; case old_t_curtains: case old_t_window_domestic: - g->m.spawn_item(g->u.posx, g->u.posy, "stick", 0); - g->m.spawn_item(g->u.posx, g->u.posy, "sheet", 0, 2); - g->m.spawn_item(g->u.posx, g->u.posy, "glass_sheet", 0); - g->m.spawn_item(g->u.posx, g->u.posy, "nail", 0, 0, rng(3,4)); - g->m.spawn_item(g->u.posx, g->u.posy, "string_36", 0, 0, 1); + g->m.spawn_item(g->u.posx, g->u.posy, "stick"); + g->m.spawn_item(g->u.posx, g->u.posy, "sheet", 2); + g->m.spawn_item(g->u.posx, g->u.posy, "glass_sheet"); + g->m.spawn_item(g->u.posx, g->u.posy, "nail", 0, rng(3,4)); + g->m.spawn_item(g->u.posx, g->u.posy, "string_36", 0, 1); g->m.ter_set(p.x, p.y, t_window_empty); break; case old_t_window: - g->m.spawn_item(p.x, p.y, "glass_sheet", 0); + g->m.spawn_item(p.x, p.y, "glass_sheet"); g->m.ter_set(p.x, p.y, t_window_empty); break; case old_t_backboard: - g->m.spawn_item(p.x, p.y, "2x4", 0, 4); - g->m.spawn_item(p.x, p.y, "nail", 0, 0, rng(6,10)); + g->m.spawn_item(p.x, p.y, "2x4", 4); + g->m.spawn_item(p.x, p.y, "nail", 0, rng(6,10)); g->m.ter_set(p.x, p.y, t_pavement); break; case old_t_sandbox: - g->m.spawn_item(p.x, p.y, "2x4", 0, 4); - g->m.spawn_item(p.x, p.y, "nail", 0, 0, rng(6,10)); + g->m.spawn_item(p.x, p.y, "2x4", 4); + g->m.spawn_item(p.x, p.y, "nail", 0, rng(6,10)); g->m.ter_set(p.x, p.y, t_floor); break; case old_t_slide: - g->m.spawn_item(p.x, p.y, "sheet_metal", 0); - g->m.spawn_item(p.x, p.y, "pipe", 0, rng(4,8)); + g->m.spawn_item(p.x, p.y, "sheet_metal"); + g->m.spawn_item(p.x, p.y, "pipe", rng(4,8)); g->m.ter_set(p.x, p.y, t_grass); break; case old_t_monkey_bars: - g->m.spawn_item(p.x, p.y, "pipe", 0, rng(6,12)); + g->m.spawn_item(p.x, p.y, "pipe", rng(6,12)); g->m.ter_set(p.x, p.y, t_grass); break; } diff --git a/crafting.cpp b/crafting.cpp index 00899a6f4db87..0f2a169e565f6 100644 --- a/crafting.cpp +++ b/crafting.cpp @@ -1533,7 +1533,7 @@ void game::disassemble(char ch) { //twice the volume then multiplied by 10 (a book with volume 3 will give 60 pages) int num_pages = (dis_item->volume() *2) * 10; - m.spawn_item(u.posx,u.posy,"paper", 0, 1, num_pages); + m.spawn_item(u.posx, u.posy, "paper", 0, num_pages); u.inv.remove_item(dis_item); } return; @@ -1624,7 +1624,7 @@ void game::complete_disassemble() if (newit.count_by_charges()) { if (dis->difficulty == 0 || comp_success) - m.spawn_item(u.posx, u.posy, dis->components[j][0].type, 0, 0, compcount); + m.spawn_item(u.posx, u.posy, dis->components[j][0].type, 0, compcount); else add_msg(_("You fail to recover a component.")); compcount = 0; diff --git a/data/json/monsters.json b/data/json/monsters.json index 908396f22de96..394c306b34573 100644 --- a/data/json/monsters.json +++ b/data/json/monsters.json @@ -25,7 +25,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"BITE", - "description":"One of the vesper bats, a family of winged insect-eating mammals. It roosts in caves and other hollows, and uses a form of echolocation to aerially navigate through tricky terrain at rapid speeds.", + "description":"One of the vesper bats, a family of winged insect-eating mammals. It roosts in caves and other hollows, and uses a form of echolocation to aerially navigate through tricky terrain at rapid speeds.", "flags":["SEES", "SMELLS", "HEARS", "GOODHEARING", "WARM", "FLIES", "ANIMAL", "VIS50", "BONES", "LEATHER"], "fear_triggers":["SOUND", "PLAYER_CLOSE"], "categories":["WILDLIFE"] @@ -56,7 +56,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"The North American beaver, the continent's largest rodent. Its paddle-shaped tail helps ferry it through the water, and its prominent teeth can chew through wood, which it uses to build dam-like nests in lakes and streams.", + "description":"The North American beaver, the continent's largest rodent. Its paddle-shaped tail helps ferry it through the water, and its prominent teeth can chew through wood, which it uses to build dam-like nests in lakes and streams.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "SWIMS", "WARM", "FUR", "BONES"], "anger_triggers":["PLAYER_CLOSE", "HURT"], "fear_triggers":["SOUND"], @@ -88,7 +88,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"The American black bear. A large omnivorous scavenger, it has powerful claws and jaws, and is an effective ambush hunter. It can pose a considerable threat, although most individuals are shy around humans.", + "description":"The American black bear. A large omnivorous scavenger, it has powerful claws and jaws, and is an effective ambush hunter. It can pose a considerable threat, although most individuals are shy around humans.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "FUR", "BLEED", "BASHES", "ATTACKMON", "BONES", "VIS40"], "anger_triggers":["HURT", "PLAYER_CLOSE"], "placate_triggers":["MEAT"], @@ -120,7 +120,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A spotted wild cat living across much of North America. It is not a serious threat to humans, but it can be aggressive if not left alone.", + "description":"A spotted wild cat living across much of North America. It is not a serious threat to humans, but it can be aggressive if not left alone.", "flags":["SEES", "HEARS", "GOODHEARING", "SMELLS", "ANIMAL", "WARM", "FUR", "HIT_AND_RUN", "VIS40", "BONES"], "placate_triggers":["MEAT"], "fear_triggers":["SOUND", "PLAYER_CLOSE"], @@ -152,7 +152,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A small domesticated predator gone feral in the absence of human stewardship. Harried by the elements and the rigors of survival, it is scruffy and skittish.", + "description":"A small domesticated predator gone feral in the absence of human stewardship. Harried by the elements and the rigors of survival, it is scruffy and skittish.", "flags":["SEES", "HEARS", "GOODHEARING", "SMELLS", "ANIMAL", "WARM", "FUR", "HIT_AND_RUN", "VIS40", "BONES"], "placate_triggers":["MEAT"], "fear_triggers":["SOUND", "PLAYER_CLOSE", "FRIEND_ATTACKED"], @@ -184,7 +184,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A domesticated juglefowl, it may still be the most numerous bird in the world. Before the Cataclysm, it was raised by humans as a source of meat, eggs, and early morning wakeup calls.", + "description":"A domesticated descendant of junglefowl, it may still be the most numerous bird in the world. Before the Cataclysm, it was raised by humans as a source of meat, eggs, and early morning wakeup calls.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "FLIES", "BONES", "FEATHER"], "categories":["WILDLIFE"] }, @@ -214,7 +214,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"The eastern chipmunk, a tiny omnivorous rodent with a characteristic striped coat. It spends much of the day patrolling its elaborate burrow and the precious stores of foraged food within.", + "description":"The eastern chipmunk, a tiny omnivorous rodent with a characteristic striped coat. It spends much of the day patrolling its elaborate burrow and the precious stores of foraged food within.", "flags":["SEES", "SMELLS", "HEARS", "WARM", "ANIMAL", "VIS40", "BONES"], "fear_triggers":["SOUND", "PLAYER_CLOSE"], "categories":["WILDLIFE"] @@ -245,7 +245,7 @@ "special_freq":5, "death_function":"NORMAL", "special_attack":"LEAP", - "description":"The Eastern cougar, a large feline predator. Once thought extinct in this region, conservation efforts were successful in restoring a thriving population.", + "description":"The Eastern cougar, a large feline predator. Once thought extinct in this region, conservation efforts were successful in restoring a thriving population.", "flags":["SEES", "HEARS", "GOODHEARING", "SMELLS", "ANIMAL", "WARM", "FUR", "HIT_AND_RUN", "KEENNOSE", "BLEED", "ATTACKMON", "VIS50", "BONES"], "anger_triggers":["STALK", "PLAYER_WEAK", "HURT", "PLAYER_CLOSE", "FRIEND_ATTACKED"], "placate_triggers":["MEAT"], @@ -278,7 +278,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"The domestic cow, a baleful, ruminating farm animal. It is quite muscular, and the males can have a violent streak to accompany their nasty-looking horns.", + "description":"The domestic cow, a baleful, ruminating farm animal. It is quite muscular, and the males can have a violent streak to accompany their nasty-looking horns.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "FUR", "BONES", "VIS40"], "anger_triggers":["HURT"], "placate_triggers":["PLAYER_WEAK"], @@ -311,7 +311,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"The Eastern Coyote, also called the Tweed Wolf, is a territorial canine descended from the offspring of grey wolves and true coyotes. It is intimidated by humans and other predators, but will fight if threatened.", + "description":"The Eastern Coyote, also called the Tweed Wolf, is a territorial canine descended from the offspring of grey wolves and true coyotes. It is intimidated by humans and other predators, but will fight if threatened.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "FUR", "HIT_AND_RUN", "KEENNOSE", "BLEED", "ATTACKMON", "BONES", "VIS50"], "anger_triggers":["STALK", "FRIEND_ATTACKED", "PLAYER_WEAK", "HURT", "PLAYER_CLOSE"], "placate_triggers":["MEAT"], @@ -343,7 +343,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"The Northeastern Coyote, a widespread canine pack hunter. More timid than a wolf, it is an opportunistic feeder and prefers to hunt smaller and weaker prey.", + "description":"The Northeastern Coyote, a widespread canine pack hunter. More timid than a wolf, it is an opportunistic feeder and prefers to hunt smaller and weaker prey.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "FUR", "KEENNOSE", "BLEED", "ATTACKMON", "BONES", "VIS50"], "anger_triggers":["FRIEND_ATTACKED", "PLAYER_WEAK", "PLAYER_CLOSE"], "placate_triggers":["MEAT"], @@ -375,7 +375,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A small, elegant black bird, famous for its distinctive call. An intelligent bird, there is a glitter of mischief behind its eyes.", + "description":"A small, elegant black bird, famous for its distinctive call. An intelligent bird, there is a glitter of mischief behind its eyes.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "FLIES", "VIS40", "BONES", "FEATHER"], "fear_triggers":["PLAYER_CLOSE"], "categories":["WILDLIFE"] @@ -406,7 +406,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"The northern woodland white-tailed deer, a quick and strong grazing animal. Favored prey of coyotes, wolves, and giant spider mutants.", + "description":"The northern woodland white-tailed deer, a quick and strong grazing animal. Favored prey of coyotes, wolves, and giant spider mutants.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "FUR", "VIS40", "BONES"], "fear_triggers":["SOUND", "PLAYER_CLOSE"], "categories":["WILDLIFE"] @@ -500,7 +500,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A small omnivorous canine with an almost cat-like manner. It is a solitary hunter, and one of the only canids able to climb trees.", + "description":"A small omnivorous canine with an almost cat-like manner. It is a solitary hunter, and one of the only canids able to climb trees.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "FUR", "HIT_AND_RUN", "KEENNOSE", "BLEED", "VIS40", "BONES"], "anger_triggers":["FRIEND_ATTACKED", "FRIEND_DIED"], "placate_triggers":["MEAT"], @@ -628,7 +628,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A hooved grazing mammal with a mane of hair, a sweeping tail, and powerful looking muscles", + "description":"A hooved grazing mammal with a mane of hair, a sweeping tail, and powerful looking muscles.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "FUR", "BONES", "VIS40"], "anger_triggers":["FRIEND_ATTACKED"], "placate_triggers":["PLAYER_WEAK"], @@ -661,7 +661,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"The Northern bog lemming, a small, predominantly vegetarian rodent that spends its life in the murk of swamps and other wetlands. Contrary to popular belief, these creatures are not particularly hapless or suicidal, but they can eat themselves into scarcity within a few generations.", + "description":"The Northern bog lemming, a small, predominantly vegetarian rodent that spends its life in the murk of swamps and other wetlands. Contrary to popular belief, these creatures are not particularly hapless or suicidal, but they can eat themselves into scarcity within a few generations.", "flags":["SEES", "SMELLS", "HEARS", "WARM", "SWIMS", "ANIMAL", "VIS40"], "fear_triggers":["SOUND", "PLAYER_CLOSE"], "categories":["WILDLIFE"] @@ -692,7 +692,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"The American mink, a partially-aquatic weasel, once factory-farmed for its fur. It is a capable fisher, but the presence of otters in these parts makes it rely more on food from the land.", + "description":"The American mink, a partially-aquatic weasel, once factory-farmed for its fur. It is a capable fisher, but the presence of otters in these parts makes it rely more on food from the land.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "FUR", "HIT_AND_RUN", "KEENNOSE", "BLEED", "VIS40", "BONES"], "anger_triggers":["FRIEND_ATTACKED", "FRIEND_DIED"], "placate_triggers":["MEAT"], @@ -725,7 +725,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"The Eastern Moose, the largest living species of deer. The bulls are quite ill-tempered, especially in the rutting season.", + "description":"The Eastern Moose, the largest living species of deer. The bulls are quite ill-tempered, especially in the rutting season.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "FUR", "BLEED", "VIS40", "ATTACKMON", "BONES"], "anger_triggers":["HURT", "PLAYER_CLOSE"], "placate_triggers":["PLAYER_WEAK"], @@ -758,7 +758,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A large omnivorous rodent with a thick furry pelt, found in wetlands across the northern hemisphere. It marks its territory with a musky odor for which it is named.", + "description":"A large omnivorous rodent with a thick furry pelt, found in wetlands across the northern hemisphere. It marks its territory with a musky odor for which it is named.", "flags":["SEES", "SMELLS", "HEARS", "WARM", "SWIMS", "ANIMAL", "FUR", "VIS40", "BONES"], "fear_triggers":["SOUND", "PLAYER_CLOSE"], "categories":["WILDLIFE"] @@ -789,7 +789,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"The North American river otter is a shy waterborne weasel living in large families along the banks of streams. It is an excellent fisher and a resourceful survivor, using the abandoned dens of beavers and other animals to raise its own young.", + "description":"The North American river otter is a shy water dwelling relative of the weasel living in large families along the banks of streams. It is an excellent fisher and a resourceful survivor, using the abandoned dens of beavers and other animals to raise its own young.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "SWIMS", "WARM", "FUR", "VIS40", "BONES"], "fear_triggers":["SOUND", "PLAYER_CLOSE"], "categories":["WILDLIFE"] @@ -853,7 +853,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A cute wiggling nose, cotton tail, made of delicious flesh.", + "description":"A small mammal with a cute wiggling nose, cotton tail, and made of delicious flesh.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "FUR", "BONES"], "fear_triggers":["SOUND", "PLAYER_CLOSE"], "categories":["WILDLIFE"] @@ -884,7 +884,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"The black rat, an omnivorous rodent with sheer black fur and a long, rough tail. Harbinger of pestilence, famine, and mange, it will sometimes swarm over the dead or dying.", + "description":"The black rat, an omnivorous rodent with sheer black fur and a long, rough tail. Harbinger of pestilence, famine, and mange, it will sometimes swarm over the dead or dying.", "flags":["SEES", "SMELLS", "HEARS", "WARM", "SWIMS", "ANIMAL", "FUR", "VIS40", "BONES"], "anger_triggers":["PLAYER_WEAK"], "fear_triggers":["PLAYER_CLOSE"], @@ -916,7 +916,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A worm-tailed rodent with long whiskers and beady eyes. The way it squeeks makes it sound... hungry.", + "description":"A worm-tailed rodent with long whiskers and beady eyes. The way it squeaks makes it sound... hungry.", "flags":["SEES", "SMELLS", "HEARS", "WARM", "SWIMS", "ANIMAL", "FUR", "VIS40", "BONES"], "anger_triggers":["PLAYER_WEAK", "FRIEND_ATTACKED", "FRIEND_DIED"], "categories":["WILDLIFE"] @@ -947,7 +947,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A timid hooved grazing mammal, and one of the first animals ever domesticated, its body is covered in a thick layer of wool, and the males have long, spiraling horns.", + "description":"A timid, hooved grazing mammal, and one of the first animals ever domesticated, its body is covered in a thick layer of wool, and the males have long, spiralling horns.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "WOOL", "BONES"], "anger_triggers":[], "placate_triggers":["PLAYER_WEAK"], @@ -980,7 +980,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"This black bear's eyes ooze with black fluid, and it's flesh is torn and scarred. It shuffles as it walks.", + "description":"This black bear's eyes ooze with black fluid, and its flesh is torn and scarred. It shuffles as it walks.", "flags":["SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "VIS40", "REVIVES"], "anger_triggers":["PLAYER_CLOSE", "HURT"], "fear_triggers":["FIRE"], @@ -1043,7 +1043,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A small granivorous rodent with a long bushy tail, often seen darting amid the branches of trees. A skittish varmint with an expression of unwavering austerity, it is the mortal enemy of cat and dog alike.", + "description":"A small granivorous rodent with a long bushy tail, often seen darting amid the branches of trees. A skittish varmint with an expression of unwavering austerity, it is the mortal enemy of cat and dog alike.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "FUR", "BONES"], "fear_triggers":["SOUND", "PLAYER_CLOSE"], "categories":["WILDLIFE"] @@ -1074,7 +1074,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A tiny opportunistic rodent with a long bushy tail, the pine squirrel is clever and cute, and hunted by nearly everything in the woods with a taste for meat.", + "description":"A tiny opportunistic rodent with a long bushy tail. The pine squirrel is clever and cute, and hunted by nearly everything in the woods with a taste for meat.", "fear_triggers":["SOUND", "PLAYER_CLOSE"], "categories":["WILDLIFE"] }, @@ -1104,7 +1104,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"The long-tailed weasel, a small but interminable predator whose range extends across the continent. It forms its den in small burrows, preferring to occupy the nesting holes of its prey.", + "description":"The long-tailed weasel, a small but ubiquitous predator whose range extends across the continent. It forms its den in small burrows, preferring to occupy the nesting holes of its prey.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "SWIMS", "WARM", "FUR", "VIS40", "BONES"], "fear_triggers":["SOUND", "PLAYER_CLOSE"], "categories":["WILDLIFE"] @@ -1135,7 +1135,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A cunning pack predator, once extinct in the New England area, was successfully reintroduced and their numbers reached record highs in the decade before the cataclysm. Lucky you.", + "description":"A cunning pack predator, once extinct in the New England area, the wolf successfully reintroduced and their numbers reached record highs in the decade before the cataclysm. Lucky you.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "FUR", "KEENNOSE", "BLEED", "ATTACKMON", "BONES", "VIS50"], "anger_triggers":["STALK", "FRIEND_ATTACKED", "FRIEND_DIED", "PLAYER_WEAK", "PLAYER_CLOSE"], "placate_triggers":["MEAT"], @@ -1167,7 +1167,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A pulsating sausage of glistening white flesh, the size of a large cat. On one end is a set of squirming mouth parts.", + "description":"A pulsating sausage of glistening white flesh, the size of a large cat. On one end is a set of squirming mouth parts.", "flags":["SMELLS", "POISON"] }, { @@ -1196,7 +1196,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"An enormous red ant covered in chitinous plates. It carries a pair of wriggling antennae and vicious-looking mandibles.", + "description":"An enormous red ant covered in chitinous plates. It possesses a pair of wriggling antennae and vicious-looking mandibles.", "flags":["HEARS", "SMELLS", "CHITIN"], "anger_triggers":["FRIEND_ATTACKED", "FRIEND_DIED", "HURT", "PLAYER_WEAK"] }, @@ -1226,7 +1226,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A huge and hairy red ant almost twice the size of other giant ants. Bulging pincers extrude from its jaws.", + "description":"A huge and hairy red ant almost twice the size of other giant ants. Bulging pincers extend from its jaws.", "flags":["HEARS", "SMELLS", "CHITIN"], "anger_triggers":["FRIEND_ATTACKED", "FRIEND_DIED", "HURT", "PLAYER_CLOSE"] }, @@ -1256,7 +1256,7 @@ "special_freq":1, "death_function":"NORMAL", "special_attack":"ANTQUEEN", - "description":"A colossal red ant with a bulging, bloated thorax. It moves slowly and delibrately, tending to nearby eggs and ever laying more.", + "description":"A colossal red ant with a bulging, bloated thorax. It moves slowly and deliberately, tending to nearby eggs and continually laying more.", "flags":["SMELLS", "QUEEN", "CHITIN"], "anger_triggers":["FRIEND_ATTACKED", "FRIEND_DIED", "HURT"] }, @@ -1345,7 +1345,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"With a stinger the size of a kitchen knife, this dog-sized insect's black and yellow markings warn you to leave it indisturbed.", + "description":"With a stinger the size of a kitchen knife, this dog-sized insect's black and yellow markings warn you to leave it undisturbed.", "flags":["SMELLS", "VENOM", "FLIES", "STUMBLES", "CHITIN"], "anger_triggers":["HURT", "FRIEND_DIED"] }, @@ -1375,7 +1375,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A gigantic slender-bodied wasp with an evil-looking stinger protruding from its abdomen. Its exoskeleton glowers with ominous red markings.", + "description":"A gigantic slender-bodied wasp with an evil-looking stinger protruding from its abdomen. Its exoskeleton glowers with ominous red markings.", "flags":["SMELLS", "VENOM", "FLIES", "CHITIN"], "anger_triggers":["HURT", "FRIEND_DIED", "PLAYER_CLOSE", "PLAYER_WEAK", "STALK"] }, @@ -1405,7 +1405,7 @@ "special_freq":0, "death_function":"WORM", "special_attack":"NONE", - "description":"A monstrous beast with a tripartite mouth that opens to reveal hundreds of writhing tongues with razor sharp edges. It keeps most of its enormous body hidden underground.", + "description":"A monstrous beast with a tripartite mouth that opens to reveal hundreds of writhing tongues with razor sharp edges. It keeps most of its enormous body hidden underground.", "flags":["DIGS", "HEARS", "POISON", "GOODHEARING", "DESTROYS", "WARM", "LEATHER"] }, { @@ -1434,7 +1434,7 @@ "special_freq":0, "death_function":"WORM", "special_attack":"NONE", - "description":"An enormous, mutated creature that might once have been a nightcrawler, it's large fanged mouth and and long slender body that comes up to your shoulders, with even more surely hiding underground, it's now something far worse.", + "description":"An enormous, mutated creature that might once have been a nightcrawler. It possesses a large fanged mouth and a long slender body that comes up to your shoulder, with even more surely hiding underground.", "flags":["DIGS", "HEARS", "GOODHEARING", "WARM", "LEATHER"] }, { @@ -1492,7 +1492,7 @@ "special_freq":0, "death_function":"MELT", "special_attack":"NONE", - "description":"A sluglike creature, eight feet long and the width of a refrigerator. Its black body glistens as it oozes its way along the ground. Eye stalks occassionally push their way out of the oily mass and look around.", + "description":"A sluglike creature, eight feet long and the width of a refrigerator. Its black body glistens as it oozes its way along the ground. Eye stalks occasionally push their way out of the oily mass and look around.", "flags":["NOHEAD", "SEES", "POISON", "HEARS", "REGENERATES_50", "SMELLS", "VIS30", "SLUDGEPROOF", "SLUDGETRAIL", "SWIMS", "FLAMMABLE"] }, { @@ -1521,7 +1521,7 @@ "special_freq":5, "death_function":"ZOMBIE", "special_attack":"BITE", - "description":"A human body, swaying as it moves, an unstoppable rage is visible beneath it's oily black eyes.", + "description":"A human body, swaying as it moves, an unstoppable rage is visible beneath its oily black eyes.", "flags":["SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "BLEED", "NO_BREATHE", "VIS40", "REVIVES"], "categories":["CLASSIC"] }, @@ -1581,7 +1581,7 @@ "special_freq":10, "death_function":"ZOMBIE", "special_attack":"SHRIEK", - "description":"An elongated human body with a swollen chest and a gaping hole where it's jaw used to be", + "description":"An elongated human body with a swollen chest and a gaping hole where its jaw used to be", "flags":["SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "VIS50", "REVIVES"] }, { @@ -1610,7 +1610,7 @@ "special_freq":20, "death_function":"ACID", "special_attack":"ACID", - "description":"A hunched human body with it's eyes pushed up into it's forehead and drooping cheeks, most of it's face is occupied by a puckered mouth. It's stomache is swollen and nearly translucent, with a sickly yellow tint.", + "description":"A hunched human body with its eyes pushed up into its forehead and drooping cheeks, most of its face is occupied by a puckered mouth. Its stomach is swollen and nearly translucent, with a sickly yellow tint.", "flags":["SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "ACIDPROOF", "NO_BREATHE", "VIS40", "REVIVES"] }, { @@ -1668,7 +1668,7 @@ "special_freq":1, "death_function":"SMOKEBURST", "special_attack":"SMOKECLOUD", - "description":"A blackened and twisted naked human body, strips of flesh hang from it's body, and it emits a constant haze of thick black smoke.", + "description":"A blackened and twisted naked human body, strips of flesh hang from its body, and it emits a constant haze of thick black smoke.", "flags":["SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "HARDTOSHOOT", "FRIENDLY_SPECIAL", "NO_BREATHE", "VIS50", "REVIVES"] }, { @@ -1697,7 +1697,7 @@ "special_freq":5, "death_function":"ZOMBIE", "special_attack":"BITE", - "description":"A slick and glistening human body. It's hands and feet are webbed, and it is clad in swimwear.", + "description":"A slick and glistening human body. Its hands and feet are webbed, and it is clad in swimwear.", "flags":["SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "NO_BREATHE", "VIS40", "BLEED", "SWIMS", "REVIVES"] }, { @@ -1900,7 +1900,7 @@ "special_freq":5, "death_function":"ZOMBIE", "special_attack":"BITE", - "description":"It's skin so tight the cracked bones are visible beneath it, covered in scar tissue and coils of scabbed black liquid and with eyes so deeply sunken into it's skill they are barely visible, it's a wonder this once-human creature can move at all.", + "description":"With its skin so tight the cracked bones are visible beneath it, covered in scar tissue and coils of scabbed black liquid and with eyes so deeply sunken into its skull they are barely visible, it's a wonder this once-human creature can move at all.", "flags":["SEES", "HEARS", "BLEED", "HARDTOSHOOT", "REVIVES", "NO_BREATHE", "VIS30"] }, { @@ -2018,7 +2018,7 @@ "special_freq":0, "death_function":"ZOMBIE", "special_attack":"NONE", - "description":"A deformed human body, once living. Its arms dangle from its sides like the limbs of some skinless ape, mindlessly groping at their surroundings.", + "description":"A deformed human body, once living. Its arms dangle from its sides like the limbs of some skinless ape, mindlessly groping at their surroundings.", "flags":["SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "POISON", "BLEED", "GRABS", "NO_BREATHE", "VIS30", "REVIVES"] }, { @@ -2047,7 +2047,7 @@ "special_freq":3, "death_function":"ZOMBIE", "special_attack":"UPGRADE", - "description":"Once human, its features have tightened, its lips pulled back into an unnatural grin, revealing rows of blackened teeth beneath its large, piercing eyes. It stands tall, its movements are fluid and tightly controlled. A feeling of danger permeates the air around it, and the light that falls on it somehow harsher and more glaring.", + "description":"Once human, its features have tightened, its lips pulled back into an unnatural grin, revealing rows of blackened teeth beneath its large, piercing eyes. It stands tall and its movements are fluid and tightly controlled. A feeling of danger permeates the air around it, and the light that falls on it somehow harsher and more glaring.", "flags":["SEES", "HEARS", "SMELLS", "WARM", "BASHES", "POISON", "NO_BREATHE", "VIS50", "REVIVES"], "anger_triggers":["HURT", "PLAYER_CLOSE", "PLAYER_WEAK"] }, @@ -2106,7 +2106,7 @@ "special_freq":5, "death_function":"ZOMBIE", "special_attack":"LEAP", - "description":"This once-human body is barely recognizable, scrambling about on all fours, it's nails and teeth both sharpened into dangerous looking spikes.", + "description":"This once-human body is barely recognizable, scrambling about on all fours, its nails and teeth both sharpened into dangerous looking spikes.", "flags":["SEES", "HEARS", "SMELLS", "WARM", "BASHES", "POISON", "NO_BREATHE", "VIS40", "REVIVES"], "categories":["CLASSIC"] }, @@ -2136,7 +2136,7 @@ "special_freq":0, "death_function":"ZOMBIE", "special_attack":"NONE", - "description":"It was only a child, and little is different about it now aside from the hungry look in it's eyes. You'd be hard pressed to not feel like you were killing an actual child by putting it down.", + "description":"It was only a child, and little is different about it now aside from the hungry look in its eyes. You'd be hard pressed to not feel like you were killing an actual child by putting it down.", "flags":["SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "BLEED", "POISON", "GUILT", "NO_BREATHE", "VIS30", "REVIVES"], "categories":["CLASSIC"] }, @@ -2166,7 +2166,7 @@ "special_freq":5, "death_function":"NORMAL", "special_attack":"FLESH_GOLEM", - "description":"A putrid amalgamation of body parts from humans and other creatures have fused together in this aberration of flesh. The eyes of all the heads dart about rapidly and the mouths form a chorus of groaning screams.", + "description":"A putrid amalgamation of body parts from humans and other creatures have fused together in this aberration of flesh. The eyes of all the heads dart about rapidly and the mouths form a chorus of groaning screams.", "flags":["SEES", "HEARS", "SMELLS", "STUMBLES", "WARM", "BASHES", "DESTROYS", "ATTACKMON", "LEATHER", "BONES", "VIS50", "POISON"] }, { @@ -2195,7 +2195,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A creeping animate plant, growing as tall as a moose. It has a single bark-covered stalk supporting a flowery head with a paralyzing sting concealed within.", + "description":"A creeping animate plant, growing as tall as a moose. It has a single bark-covered stalk supporting a flowery head with a paralyzing sting concealed within.", "flags":["SEES", "SMELLS", "BASHES", "NOHEAD", "PARALYZEVENOM"] }, { @@ -2253,7 +2253,7 @@ "special_freq":10, "death_function":"NORMAL", "special_attack":"PARA_STING", - "description":"A stout woody plant that can dig through the ground and flick spines from its branches. The thorns carry a fungicidal compound with paralytic effects.", + "description":"A stout woody plant that can dig through the ground and flick spines from its branches. The thorns carry a fungicidal compound with paralytic effects.", "flags":["HEARS", "SMELLS", "NOHEAD", "BADVENOM", "PARALYZEVENOM", "CAN_DIG"] }, { @@ -2282,7 +2282,7 @@ "special_freq":2, "death_function":"NORMAL", "special_attack":"GROWPLANTS", - "description":"A ponderous and particularly arborescent triffid. It has enormous red petals surrounded by a haze of spores, and two thick barbed vines stick out from the stems like wary harpoons.", + "description":"A ponderous and particularly arborescent triffid. It has enormous red petals surrounded by a haze of spores, and two thick barbed vines stick out from the stems like wary harpoons.", "flags":["HEARS", "SMELLS", "BASHES", "NOHEAD", "PARALYZEVENOM"] }, { @@ -2311,7 +2311,7 @@ "special_freq":2, "death_function":"KILL_VINES", "special_attack":"GROW_VINE", - "description":"A thick stalk, rooted to the ground. It rapidly sprouts thorny vines in all directions.", + "description":"A thick stalk, rooted to the ground. It rapidly sprouts thorny vines in all directions.", "flags":["NOHEAD", "IMMOBILE"] }, { @@ -2369,7 +2369,7 @@ "special_freq":2, "death_function":"NORMAL", "special_attack":"SPIT_SAP", - "description":"A drooped, quivering plant with a thick stalk adorned by a purple flower. Its petals are closed, and pulsate ominously.", + "description":"A drooped, quivering plant with a thick stalk adorned by a purple flower. Its petals are closed, and pulsate ominously.", "flags":["NOHEAD", "IMMOBILE"] }, { @@ -2398,7 +2398,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"An animated mass of roots and vines, creeping along the ground with alarming speed. The tangle is thick enough that the center from which they grow is concealed.", + "description":"An animated mass of roots and vines, creeping along the ground with alarming speed. The tangle is thick enough that the center from which they grow is concealed.", "flags":["HEARS", "GOODHEARING", "NOHEAD", "HARDTOSHOOT", "GRABS", "SWIMS", "PLASTIC"] }, { @@ -2427,7 +2427,7 @@ "special_freq":5, "death_function":"TRIFFID_HEART", "special_attack":"TRIFFID_HEARTBEAT", - "description":"A knot of tubular roots, flowing with sap and beating like a heart. Strands of vascular tissue reach out to the surrounding root walls.", + "description":"A knot of tubular roots, flowing with sap and beating like a heart. Strands of vascular tissue reach out to the surrounding root walls.", "flags":["NOHEAD", "IMMOBILE", "QUEEN"] }, { @@ -2456,7 +2456,7 @@ "special_freq":30, "death_function":"FUNGUS", "special_attack":"FUNGUS", - "description":"A pale white fungus, one meaty gray stalk supporting a bloom at the top. Spores are periodically expelled from its gills, and a few tendrils extend from the base, allowing mobility and some basic means of defense.", + "description":"A pale white fungus, one meaty gray stalk supporting a bloom at the top. Spores are periodically expelled from its gills, and a few tendrils extend from the base, allowing mobility and some basic means of defense.", "flags":["STUMBLES", "POISON", "NO_BREATHE", "NOHEAD"] }, { @@ -2485,7 +2485,7 @@ "special_freq":100, "death_function":"NORMAL", "special_attack":"FUNGUS_GROWTH", - "description":"A fungal stalk several feet in height. Two vicious looking tendrils extend from its thorned and leathery exterior, and it moves about faster than the larger fungaloids.", + "description":"A fungal stalk several feet in height. Two vicious looking tendrils extend from its thorned and leathery exterior, and it moves about faster than the larger fungaloids.", "flags":["HEARS", "POISON", "NO_BREATHE", "NOHEAD"] }, { @@ -2543,7 +2543,7 @@ "special_freq":10, "death_function":"FUNGUS", "special_attack":"FUNGUS_SPROUT", - "description":"An enormous fungal spire, towering over the ground. It pulsates slowly, continuously growing new defenses.", + "description":"An enormous fungal spire, towering over the ground. It pulsates slowly, continuously growing new defenses.", "flags":["NOHEAD", "POISON", "IMMOBILE", "NO_BREATHE", "QUEEN"] }, { @@ -2572,7 +2572,7 @@ "special_freq":10, "death_function":"DISINTEGRATE", "special_attack":"FUNGUS", - "description":"A veritable wall of fungus, grown as a natural defense by the fungal spire. New spores erupt from the surface every few seconds.", + "description":"A veritable wall of fungus, grown as a natural defense by the fungal spire. New spores erupt from the surface every few seconds.", "flags":["NOHEAD", "POISON", "NO_BREATHE", "IMMOBILE"] }, { @@ -2661,7 +2661,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"The C.H.U.D. or Cannibalistic Humanoid Underground Dweller. A human being turned pale and mad from years of underground isolation.", + "description":"The C.H.U.D. or Cannibalistic Humanoid Underground Dweller. A human being turned pale and mad from years of underground isolation.", "flags":["SEES", "HEARS", "WARM", "BASHES", "HUMAN", "VIS40", "BONES"] }, { @@ -2749,7 +2749,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A large mutant variety of carp. It has shimmering green scales and a mouth lined with three jagged rows of razor-sharp teeth.", + "description":"A large mutant variety of carp. It has shimmering green scales and a mouth lined with three jagged rows of razor-sharp teeth.", "flags":["SEES", "SMELLS", "WARM", "AQUATIC", "VIS30", "BONES"] }, { @@ -2778,7 +2778,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"An aggressive mutant variety of the worm snake, turned pale yellow from its underground life. It swarms beneath the ground and is named for its habit of infesting sewer lines.", + "description":"An aggressive mutant variety of the worm snake, turned pale yellow from its underground life. It swarms beneath the ground and is named for its habit of infesting sewer lines.", "flags":["SEES", "SMELLS", "WARM", "VENOM", "SWIMS", "LEATHER", "VIS30", "BONES"] }, { @@ -2807,7 +2807,7 @@ "special_freq":3, "death_function":"RATKING", "special_attack":"RATKING", - "description":"A towering swarm of mutated rats, their tails knotted together in a filthy mass. A foetid stench flows from its filthy presence." + "description":"A towering swarm of mutated rats, their tails knotted together in a filthy mass. A foetid stench flows from its filthy presence." }, { "type":"MONSTER", @@ -2835,7 +2835,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A blood-sucking fly with a needle-like proboscis. Its bite leaves behind itchy welts and can easily spread disease.", + "description":"A blood-sucking fly with a needle-like proboscis. Its bite leaves behind itchy welts and can easily spread disease.", "flags":["SMELLS", "HEARS", "STUMBLES", "VERMIN", "SMALL_BITES", "FLIES"] }, { @@ -3013,7 +3013,7 @@ "special_freq":5, "death_function":"NORMAL", "special_attack":"LEAP", - "description":"The American bullfrog, in its natural habitat. It feeds on insects, mice, lizards and any other living thing it can stuff down its gullet.", + "description":"The American bullfrog, in its natural habitat. It feeds on insects, mice, lizards and any other living thing it can stuff down its gullet.", "flags":["SEES", "SMELLS", "HEARS", "SWIMS", "HUNTS_VERMIN"], "fear_triggers":["PLAYER_CLOSE"] }, @@ -3043,7 +3043,7 @@ "special_freq":5, "death_function":"NORMAL", "special_attack":"LEAP", - "description":"A mutated bullfrog taller than you are. It stares with amber eyes as it considers the easiest way to swallow you whole.", + "description":"A mutated bullfrog taller than you are. It stares with amber eyes as it considers the easiest way to swallow you whole.", "flags":["SEES", "SMELLS", "HEARS", "SWIMS", "LEATHER", "VIS40", "ATTACKMON", "BONES"], "anger_triggers":["STALK", "PLAYER_WEAK", "PLAYER_CLOSE"] }, @@ -3103,7 +3103,7 @@ "special_freq":10, "death_function":"NORMAL", "special_attack":"ACID", - "description":"A mutated leopard slug, as wide as a golf cart. Venom dripping from its fanged maw, it slithers ahead slowly, leaving a trail of glistening slime.", + "description":"A mutated leopard slug, as wide as a golf cart. Venom dripping from its fanged maw, it slithers ahead slowly, leaving a trail of glistening slime.", "flags":["SEES", "SMELLS", "BASHES", "ACIDPROOF", "ACIDTRAIL", "VIS30"], "anger_triggers":["PLAYER_CLOSE"] }, @@ -3192,7 +3192,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A fairly large spider which tracks and catches prey through agility and stealth. Its bite can be irritating even to large animals.", + "description":"A fairly large spider which tracks and catches prey through agility and stealth. Its bite can be irritating even to large animals.", "flags":["SMELLS", "HEARS", "VERMIN", "SMALL_BITES", "HUNTS_VERMIN", "CHITIN"] }, { @@ -3280,7 +3280,7 @@ "special_freq":2, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A little spider with elongated forelegs. It does not build extensive webs, but leaps very quickly, appearing to move instantaneously from one spot to another.", + "description":"A little spider with elongated forelegs. It does not build extensive webs, but leaps very quickly, appearing to move instantaneously from one spot to another.", "flags":["SMELLS", "HEARS", "VERMIN", "HUNTS_VERMIN", "SMALL_BITES"], "anger_triggers":["PLAYER_CLOSE"] }, @@ -3310,7 +3310,7 @@ "special_freq":2, "death_function":"NORMAL", "special_attack":"LEAP", - "description":"A giant spider with big forelegs and two pairs of inquisitive-looking eyes. It can leap quite quickly, even into the treetops.", + "description":"A giant spider with big forelegs and two pairs of inquisitive-looking eyes. It can leap quite quickly, even into the treetops.", "flags":["SMELLS", "HEARS", "VENOM", "HIT_AND_RUN", "CHITIN"], "anger_triggers":["PLAYER_CLOSE"] }, @@ -3340,7 +3340,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A midsized spider with a bulbous thorax. It creates a subterranean nest and lies in wait for prey to draw close enough for capture.", + "description":"A midsized spider with a bulbous thorax. It creates a subterranean nest and lies in wait for prey to draw close enough for capture.", "flags":["SMELLS", "HEARS", "VERMIN", "WEBWALK"] }, { @@ -3369,7 +3369,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A gigantic spider with a bulbous thorax. It digs a deep underground burrow that serves as a pit to trap unwary prey.", + "description":"A gigantic spider with a bulbous thorax. It digs a deep underground burrow that serves as a pit to trap unwary prey.", "flags":["SMELLS", "HEARS", "VENOM", "GRABS", "CAN_DIG", "WEBWALK", "CHITIN"] }, { @@ -3427,7 +3427,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A giant mutated black widow spider. A highly venomous nightmare come to life.", + "description":"A giant mutated black widow spider. A highly venomous nightmare come to life.", "flags":["SMELLS", "HEARS", "BADVENOM", "WEBWALK", "CHITIN"], "anger_triggers":["PLAYER_WEAK", "PLAYER_CLOSE"] }, @@ -3457,7 +3457,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A huge mutated worm found deep underground. It has a gaping round mouth lined with dagger-like teeth, and its flesh is slick with bubbling blue slime.", + "description":"A huge mutated worm found deep underground. It has a gaping round mouth lined with dagger-like teeth, and its flesh is slick with bubbling blue slime.", "flags":["SMELLS", "HEARS", "GOODHEARING", "DESTROYS", "POISON", "SUNDEATH", "ACIDPROOF", "ACIDTRAIL"] }, { @@ -3486,7 +3486,7 @@ "special_freq":0, "death_function":"AMIGARA", "special_attack":"FEAR_PARALYZE", - "description":"A hellish, vaguely humanoid horror, two stories tall. Its face is grotesquely stretched out, its limbs deformed to unrecognizable outgrowths.", + "description":"A hellish, vaguely humanoid horror, two stories tall. Its face is grotesquely stretched out, its limbs deformed to unrecognizable outgrowths.", "flags":["SMELLS", "HEARS", "SEES", "STUMBLES", "HARDTOSHOOT"] }, { @@ -3515,7 +3515,7 @@ "special_freq":40, "death_function":"THING", "special_attack":"DOGTHING", - "description":"A domesticated mongrel of the canine persuasion. In the absence of human society, it has turned feral. You feel a sudden urge to destroy it.", + "description":"A domesticated mongrel of the canine persuasion. In the absence of human society, it has turned feral. You feel a sudden urge to destroy it.", "flags":["SEES", "SMELLS", "HEARS", "ANIMAL", "WARM", "FUR", "FRIENDLY_SPECIAL"] }, { @@ -3544,7 +3544,7 @@ "special_freq":5, "death_function":"THING", "special_attack":"TENTACLE", - "description":"A dog's body with a mass of ropy, black tentacles reaching out from its head.", + "description":"A dog's body with a mass of ropey, black tentacles reaching out from its head.", "flags":["SEES", "SMELLS", "HEARS", "BASHES"] }, { @@ -3602,7 +3602,7 @@ "special_freq":15, "death_function":"NORMAL", "special_attack":"ACID", - "description":"An enormous fleshy snail, with an oddly human face. The eyestalks protrude from where the eyes should be.", + "description":"An enormous fleshy snail, with an oddly human face. Eyestalks protrude from where the eyes should be.", "flags":["SMELLS", "HEARS", "POISON", "ACIDPROOF"], "anger_triggers":["PLAYER_WEAK", "FRIEND_DIED"] }, @@ -3632,7 +3632,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A human body, but with its limbs, neck, and\nhair impossibly twisted. It clambors around swiftly, making awful screeching sounds.", + "description":"A human body, but with its limbs, neck, and hair impossibly twisted. It clambers around swiftly, making awful screeching sounds.", "flags":["SEES", "HEARS", "GOODHEARING", "POISON", "HUMAN", "VIS40"] }, { @@ -3719,7 +3719,7 @@ "special_freq":0, "death_function":"MELT", "special_attack":"NONE", - "description":"A man-sized wormish creature that swoops around on bat-like wings. Its form dramatically shifts and changes from moment to moment, although its gigantic eyes and teeth are always prominent.", + "description":"A man-sized worm-like creature that swoops around on bat-like wings. Its form dramatically shifts and changes from moment to moment, although its gigantic eyes and teeth are always prominent.", "flags":["SEES", "SMELLS", "HEARS", "NOHEAD", "HARDTOSHOOT", "FLIES", "PLASTIC", "SUNDEATH", "NO_BREATHE", "HIT_AND_RUN"], "anger_triggers":["STALK", "PLAYER_WEAK", "PLAYER_CLOSE", "FRIEND_ATTACKED"] }, @@ -3749,7 +3749,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"PARROT", - "description":"A flexous monstrosity seeming as a giant crab covered in writhing antennae, clawform tentacles and star-shaped growths, with a head like the insides of a fish but for its dire utterance.", + "description":"A flexuous monstrosity seeming as a giant crab covered in writhing antennae, clawed tentacles, and star-shaped growths, with a head like the insides of a fish but for its dire utterance.", "flags":["SEES", "SMELLS", "HEARS", "WARM", "BASHES", "POISON", "NO_BREATHE", "VIS50"] }, { @@ -3778,7 +3778,7 @@ "special_freq":20, "death_function":"NORMAL", "special_attack":"GENE_STING", - "description":"An enormous white flatworm that burrows beneath the earth. Its mouth is lined with pointed teeth, and it is covered in fine hairs which can be shed and fired like darts.", + "description":"An enormous white flatworm that burrows beneath the earth. Its mouth is lined with pointed teeth, and it is covered in fine hairs which can be shed and fired like darts.", "flags":["SEES", "SMELLS", "HEARS", "BASHES", "DESTROYS", "POISON", "VENOM", "NO_BREATHE", "DIGS", "VIS40"] }, { @@ -3807,7 +3807,7 @@ "special_freq":4, "death_function":"MELT", "special_attack":"FORMBLOB", - "description":"A formless slime mold the size of a cow. Crusty bits of cytoplasm fall away as it oozes across the ground.", + "description":"A formless slime mold the size of a cow. Crusty bits of cytoplasm fall away as it oozes across the ground.", "flags":["SMELLS", "HEARS", "PLASTIC", "NO_BREATHE", "NOHEAD"], "phase":"LIQUID" }, @@ -3837,7 +3837,7 @@ "special_freq":12, "death_function":"NORMAL", "special_attack":"STARE", - "description":"An eyeball the size of an easy chair, covered in rolling blue flames. It floats through the air, spinning slowly to draw its gaze in every direction.", + "description":"An eyeball the size of an easy chair, covered in rolling blue flames. It floats through the air, spinning slowly to draw its gaze in every direction.", "flags":["SEES", "WARM", "FLIES", "FIREY", "NO_BREATHE", "NOHEAD"] }, { @@ -3895,7 +3895,7 @@ "special_freq":10, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A bizarre humanoid creature with a calculating stare. Its twitching hands move so fast they appear to be nothing but blurs.", + "description":"A bizarre humanoid creature with a calculating stare. Its twitching hands move so fast they appear to be nothing but blurs.", "flags":["SMELLS", "HEARS", "WARM", "NO_BREATHE", "GRABS", "BONES"] }, { @@ -3953,7 +3953,7 @@ "special_freq":20, "death_function":"NORMAL", "special_attack":"FEAR_PARALYZE", - "description":"A monster with an obese human body and the head of a cow. It treads slowly, and milky white drool drips from its mouth.", + "description":"A monster with an obese human body and the head of a cow. It treads slowly, and milky white drool drips from its mouth.", "flags":["SEES", "SMELLS", "HEARS", "WARM", "BASHES", "ANIMAL", "FUR", "NO_BREATHE", "VIS30", "BONES"] }, { @@ -4011,7 +4011,7 @@ "special_freq":6, "death_function":"KILL_BREATHERS", "special_attack":"BREATHE", - "description":"A weird mass of immobile pink goo. It seems to breathe.", + "description":"A weird mass of immobile pink goo. It seems to breathe.", "flags":["ACIDPROOF", "IMMOBILE"] }, { @@ -4040,7 +4040,7 @@ "special_freq":6, "death_function":"MELT", "special_attack":"BREATHE", - "description":"A weird mass of immobile pink goo. It seems to breathe.", + "description":"A weird mass of immobile pink goo. It seems to breathe.", "flags":["IMMOBILE"] }, { @@ -4127,7 +4127,7 @@ "special_freq":0, "death_function":"ZOMBIE", "special_attack":"NONE", - "description":"A pale hairless man with an impressive athletic physique. Its lidless eyes are totally black, and seeping with blood.", + "description":"A pale hairless man with an impressive athletic physique. Its lidless eyes are totally black, and seeping with blood.", "flags":["SEES", "HEARS", "SMELLS", "WARM", "BASHES", "BLEED", "HUMAN", "REVIVES"] }, { @@ -4156,7 +4156,7 @@ "special_freq":0, "death_function":"ZOMBIE", "special_attack":"FEAR_PARALYZE", - "description":"A defiled human body, once living. Tortured to death long ago, it remains chained to the altar, the putrescent flays of its peeled skin quivering like so much flotsam upon a murky pond.", + "description":"A defiled human body, once living. Tortured to death long ago, it remains chained to the altar, the putrescent flays of its peeled skin quivering like so much flotsam upon a murky pond.", "flags":["SEES", "HEARS", "SMELLS", "WARM", "BLEED", "IMMOBILE", "GUILT", "POISON", "REVIVES"] }, { @@ -4185,7 +4185,7 @@ "special_freq":0, "death_function":"ZOMBIE", "special_attack":"FEAR_PARALYZE", - "description":"A tall and slender man lacking skin and any normalcy of countenance. Wings of muscle curl forth from its back and a third eye dominates the forehead.", + "description":"A tall and slender man lacking skin and any normalcy of countenance. Wings of muscle curl forth from its back and a third eye dominates the forehead.", "flags":["SEES", "HEARS", "SMELLS", "WARM", "BLEED", "HARDTOSHOOT", "ATTACKMON", "HUMAN", "POISON", "REVIVES"] }, { @@ -4272,7 +4272,7 @@ "special_freq":5, "death_function":"NORMAL", "special_attack":"TAZER", - "description":"A insectoid robot the size of a small dog, designed for home security. Armed with two close-range tazers, it can skate across the ground with great speed.", + "description":"A insectoid robot the size of a small dog, designed for home security. Armed with two close-range tazers, it can skate across the ground with great speed.", "flags":["SEES", "HEARS", "GOODHEARING", "ATTACKMON", "ELECTRONIC", "NO_BREATHE", "VIS50"] }, { @@ -4301,7 +4301,7 @@ "special_freq":2, "death_function":"EXPLODE", "special_attack":"SMG", - "description":"The Northrop Watchman X-1 is a production series of heavily armored combat robots. Initially designed for military patrol and escort service, t rolls on a set of hydraulic treads and is armed with a 3\"/50 caliber gun.", + "description":"The Northrop Watchman X-1 is a production series of heavily armored combat robots. Initially designed for military patrol and escort service, it rolls on a set of hydraulic treads and is armed with a 3\"/50 caliber gun.", "flags":["SEES", "HEARS", "BASHES", "ATTACKMON", "ELECTRONIC", "NO_BREATHE", "VIS50"] }, { @@ -4359,7 +4359,7 @@ "special_freq":3, "death_function":"NORMAL", "special_attack":"COPBOT", - "description":"One of the many models of armored law enforcement robots employed shortly before the collapse of civilization. Solar powered like many other robots, it maintains its programmed pursuit of law and order, propelled on a trio of omni wheels.", + "description":"One of the many models of armored law enforcement robots employed shortly before the collapse of civilization. Solar powered like many other robots, it maintains its programmed pursuit of law and order, propelled on a trio of omni wheels.", "flags":["SEES", "HEARS", "BASHES", "ATTACKMON", "ELECTRONIC", "NO_BREATHE", "VIS50"] }, { @@ -4417,7 +4417,7 @@ "special_freq":10, "death_function":"NORMAL", "special_attack":"FLAMETHROWER", - "description":"The Honda Regnal, a tall robot walking on three spidery legs. For weapons, it has a trio of spiked retractable cables and a flamethrower mounted on its head.", + "description":"The Honda Regnal, a tall robot walking on three spidery legs. For weapons, it has a trio of spiked retractable cables and a flamethrower mounted on its head.", "flags":["SEES", "HEARS", "GOODHEARING", "BASHES", "NO_BREATHE", "ELECTRONIC"] }, { @@ -4446,7 +4446,7 @@ "special_freq":5, "death_function":"EXPLODE", "special_attack":"SMG", - "description":"The Northrop ATSV, a massive, heavily-armed and armored robot walking on a pair of reverse-jointed legs. Armed with a 40 mm Bofors gun, it is an effective automated sentry, though production was limited due to a legal dispute.", + "description":"The Northrop ATSV, a massive, heavily-armed and armored robot walking on a pair of reverse-jointed legs. Armed with a 40 mm Bofors gun, it is an effective automated sentry, though production was limited due to a legal dispute.", "flags":["SEES", "HEARS", "BASHES", "NO_BREATHE", "ELECTRONIC"] }, { @@ -4475,7 +4475,7 @@ "special_freq":4, "death_function":"NORMAL", "special_attack":"MULTI_ROBOT", - "description":"The Northrop Emancipator is the first and only model of automated tank, made shortly after the split-up of Northrup Grumman. Clad in depleted uranium plating, and armed with advanced munitions and a 120-mm gun, it is capable of delivering extraordinary firepower.", + "description":"The Northrop Emancipator is the first and only model of automated tank, made shortly after the split-up of Northrup Grumman. Clad in depleted uranium plating, and armed with advanced munitions and a 120-mm gun, it is capable of delivering extraordinary firepower.", "flags":["SEES", "HEARS", "GOODHEARING", "NOHEAD", "BASHES", "DESTROYS", "ATTACKMON", "NO_BREATHE", "ELECTRONIC"] }, { @@ -4504,7 +4504,7 @@ "special_freq":1, "death_function":"EXPLODE", "special_attack":"SMG", - "description":"The General Atomics TX-1 Guardian, a small, pill-shaped automated gun turret using state of the art ATR systems to dynamically reorient itself to new friends and enemies alike. The two SMG barrels can swivel a full 360 degrees.", + "description":"The General Atomics TX-1 Guardian, a small, pill-shaped automated gun turret using state of the art ATR systems to dynamically reorient itself to new friends and enemies alike. The two SMG barrels can swivel a full 360 degrees.", "flags":["SEES", "NOHEAD", "ELECTRONIC", "IMMOBILE", "NO_BREATHE", "FRIENDLY_SPECIAL"] }, { @@ -4533,7 +4533,7 @@ "special_freq":1, "death_function":"EXPLODE", "special_attack":"NONE", - "description":"A small, round turret which extends from\nthe floor. Two SMG barrels swivel 360\ndegrees.", + "description":"A small, round turret which extends from the floor. Two SMG barrels swivel 360 degrees.", "flags":["IMMOBILE", "NO_BREATHE"] }, { @@ -4591,7 +4591,7 @@ "special_freq":1, "death_function":"GAMEOVER", "special_attack":"GENERATOR", - "description":"Your precious generator, noisily humming away. Defend it at all costs!", + "description":"Your precious generator, noisily humming away. Defend it at all costs!", "flags":["NOHEAD", "ACIDPROOF", "IMMOBILE"] }, { @@ -4620,7 +4620,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A large and colorful game bird native to the forests of North America. Its head and beak are covered in fleshy accretions.", + "description":"A large and colorful game bird native to the forests of North America. Its head and beak are covered in fleshy protuberances.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "FLIES", "VIS50", "BONES", "FEATHER"], "fear_triggers":["PLAYER_CLOSE", "FRIEND_DIED"], "categories":["WILDLIFE"] @@ -4651,7 +4651,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A small mammal native to North America, distinctive for its dextrous paws and facial markings. It is resourceful and agile enough to open sealed containers with its paws.", + "description":"A small mammal native to North America, distinctive for its dextrous paws and facial markings. It is resourceful and agile enough to open sealed containers with its paws.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "FUR", "KEENNOSE", "BLEED", "BONES", "VIS50"], "anger_triggers":["FRIEND_ATTACKED", "HURT"], "categories":["WILDLIFE"] @@ -4682,7 +4682,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"The Virginia opossum, a small omnivorous marsupial native to North America. About the size of a cat, it is hardy and adaptive, and a fairly common sight in urban areas.", + "description":"The Virginia opossum, a small omnivorous marsupial native to North America. About the size of a cat, it is hardy and adaptive, and a fairly common sight in urban areas.", "flags":["SEES", "HEARS", "SMELLS", "ANIMAL", "WARM", "FUR", "KEENNOSE", "BLEED", "BONES", "VIS50"], "anger_triggers":["FRIEND_ATTACKED", "HURT"], "fear_triggers":["PLAYER_CLOSE"], @@ -4714,7 +4714,7 @@ "special_freq":6, "death_function":"NORMAL", "special_attack":"RATTLE", - "description":"The timber rattlesnake is the most venomous viper native to New England. Climatic changes have extended its range far into the north.", + "description":"The timber rattlesnake is the most venomous viper native to New England. Climatic changes have extended its range far into the north.", "flags":["SEES", "HEARS", "SMELLS", "BADVENOM", "HARDTOSHOOT", "SWIMS", "LEATHER", "VIS30", "BONES"], "anger_triggers":["HURT"], "placate_triggers":["PLAYER_WEAK"], @@ -4747,7 +4747,7 @@ "special_freq":0, "death_function":"NORMAL", "special_attack":"NONE", - "description":"A mutant, landfaring variety of the signal crayfish, this massive crustacean resembles a humongous lobster.", + "description":"A mutant, terrestrial variety of the signal crayfish, this massive crustacean resembles a humongous lobster.", "flags":["SMELLS", "HEARS", "SEES", "CHITIN", "SWIMS", "ATTACKMON", "GRABS"], "anger_triggers":["PLAYER_CLOSE", "HURT"], "fear_triggers":["FIRE"] diff --git a/data/json/vehicle_parts.json b/data/json/vehicle_parts.json index a06572146b244..954d24119b911 100644 --- a/data/json/vehicle_parts.json +++ b/data/json/vehicle_parts.json @@ -10,7 +10,8 @@ "durability": 100, "item": "NULL", "difficulty": 0, - "flags": ["NOINSTALL"] + "flags": ["NOINSTALL"], + "breaks_into": [] },{ "type" : "vehicle_part", "id" : "seat", @@ -27,6 +28,12 @@ "location": "center", "flags": [ "SEAT", "BOARDABLE", "CARGO", "BELTABLE" + ], + "breaks_into": [ + {"item": "leather", "min": 1, "max": 5}, + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 3, "max": 5}, + {"item": "scrap", "min": 3, "max": 5} ] },{ "type" : "vehicle_part", @@ -43,6 +50,10 @@ "location": "center", "flags": [ "SEAT", "BOARDABLE" + ], + "breaks_into": [ + {"item": "leather", "min": 0, "max": 1}, + {"item": "scrap", "min": 1, "max": 2} ] },{ "type" : "vehicle_part", @@ -60,6 +71,12 @@ "location": "center", "flags": [ "BED", "BOARDABLE", "CARGO" + ], + "breaks_into": [ + {"item": "leather", "min": 1, "max": 5}, + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 3, "max": 5}, + {"item": "scrap", "min": 3, "max": 5} ] },{ "type" : "vehicle_part", @@ -73,7 +90,12 @@ "item": "frame", "difficulty": 1, "location": "structure", - "flags": [] + "flags": [], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "frame_vertical", @@ -86,7 +108,12 @@ "item": "frame", "difficulty": 1, "location": "structure", - "flags": [] + "flags": [], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "frame_cross", @@ -99,7 +126,12 @@ "item": "frame", "difficulty": 1, "location": "structure", - "flags": [] + "flags": [], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "frame_nw", @@ -112,7 +144,12 @@ "item": "frame", "difficulty": 1, "location": "structure", - "flags": [] + "flags": [], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "frame_ne", @@ -125,7 +162,10 @@ "item": "frame", "difficulty": 1, "location": "structure", - "flags": [] + "flags": [], + "breaks_into": [ + {"item": "scrap", "min": 1, "max": 4} + ] },{ "type" : "vehicle_part", "id" : "frame_se", @@ -138,7 +178,12 @@ "item": "frame", "difficulty": 1, "location": "structure", - "flags": [] + "flags": [], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "frame_sw", @@ -151,7 +196,12 @@ "item": "frame", "difficulty": 1, "location": "structure", - "flags": [] + "flags": [], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "frame_horizontal_2", @@ -164,7 +214,12 @@ "item": "frame", "difficulty": 1, "location": "structure", - "flags": [] + "flags": [], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "frame_vertical_2", @@ -177,7 +232,12 @@ "item": "frame", "difficulty": 1, "location": "structure", - "flags": [] + "flags": [], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "frame_cover", @@ -190,7 +250,12 @@ "item": "frame", "difficulty": 1, "location": "structure", - "flags": [] + "flags": [], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "frame_handle", @@ -203,7 +268,12 @@ "item": "frame", "difficulty": 1, "location": "structure", - "flags": [] + "flags": [], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "board_horizontal", @@ -216,7 +286,12 @@ "item": "steel_plate", "difficulty": 1, "location": "center", - "flags": ["OPAQUE", "OBSTACLE"] + "flags": ["OPAQUE", "OBSTACLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "board_vertical", @@ -229,7 +304,12 @@ "item": "steel_plate", "difficulty": 1, "location": "center", - "flags": ["OPAQUE", "OBSTACLE"] + "flags": ["OPAQUE", "OBSTACLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "board_nw", @@ -242,7 +322,12 @@ "item": "steel_plate", "difficulty": 1, "location": "center", - "flags": ["OPAQUE", "OBSTACLE"] + "flags": ["OPAQUE", "OBSTACLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "board_ne", @@ -255,7 +340,12 @@ "item": "steel_plate", "difficulty": 1, "location": "center", - "flags": ["OPAQUE", "OBSTACLE"] + "flags": ["OPAQUE", "OBSTACLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "board_se", @@ -268,7 +358,12 @@ "item": "steel_plate", "difficulty": 1, "location": "center", - "flags": ["OPAQUE", "OBSTACLE"] + "flags": ["OPAQUE", "OBSTACLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "board_sw", @@ -281,7 +376,12 @@ "item": "steel_plate", "difficulty": 1, "location": "center", - "flags": ["OPAQUE", "OBSTACLE"] + "flags": ["OPAQUE", "OBSTACLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "halfboard_horizontal", @@ -294,7 +394,12 @@ "item": "steel_plate", "difficulty": 1, "location": "center", - "flags": ["OBSTACLE"] + "flags": ["OBSTACLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "halfboard_vertical", @@ -307,7 +412,12 @@ "item": "steel_plate", "difficulty": 1, "location": "center", - "flags": ["OBSTACLE"] + "flags": ["OBSTACLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "halfboard_nw", @@ -320,7 +430,12 @@ "item": "steel_plate", "difficulty": 1, "location": "center", - "flags": ["OBSTACLE"] + "flags": ["OBSTACLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "halfboard_ne", @@ -333,7 +448,12 @@ "item": "steel_plate", "difficulty": 1, "location": "center", - "flags": ["OBSTACLE"] + "flags": ["OBSTACLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "halfboard_se", @@ -346,7 +466,12 @@ "item": "steel_plate", "difficulty": 1, "location": "center", - "flags": ["OBSTACLE"] + "flags": ["OBSTACLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "halfboard_sw", @@ -359,7 +484,12 @@ "item": "steel_plate", "difficulty": 1, "location": "center", - "flags": ["OBSTACLE"] + "flags": ["OBSTACLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "halfboard_horizontal_2", @@ -372,7 +502,12 @@ "item": "steel_plate", "difficulty": 1, "location": "center", - "flags": ["OBSTACLE"] + "flags": ["OBSTACLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "halfboard_vertical_2", @@ -385,7 +520,12 @@ "item": "steel_plate", "difficulty": 1, "location": "center", - "flags": ["OBSTACLE"] + "flags": ["OBSTACLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "halfboard_cover", @@ -398,7 +538,12 @@ "item": "steel_plate", "difficulty": 1, "location": "center", - "flags": ["OBSTACLE"] + "flags": ["OBSTACLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "aisle_horizontal", @@ -411,7 +556,12 @@ "item": "frame", "difficulty": 1, "location": "center", - "flags": ["AISLE", "BOARDABLE"] + "flags": ["AISLE", "BOARDABLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "aisle_vertical", @@ -424,7 +574,12 @@ "item": "frame", "difficulty": 1, "location": "center", - "flags": ["AISLE", "BOARDABLE"] + "flags": ["AISLE", "BOARDABLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "trunk_floor", @@ -438,10 +593,43 @@ "item": "frame", "difficulty": 1, "location": "center", - "flags": ["AISLE", "BOARDABLE", "CARGO"] + "flags": ["AISLE", "BOARDABLE", "CARGO"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ - "type" : "vehicle_part", - "id" : "roof", + "type": "vehicle_part", + "id": "stowboard_horizontal", + "name": "stow board", + "symbol": "h", + "color": "white", + "broken_symbol": "#", + "broken_color": "light_gray", + "durability": 700, + "size": 200, + "item": "steel_plate", + "difficulty": 3, + "location": "center", + "flags": ["OBSTACLE", "OPAQUE", "CARGO"] + },{ + "type":"vehicle_part", + "id": "stowboard_vertical", + "name": "stow board", + "symbol": "j", + "color": "white", + "broken_symbol": "#", + "broken_color": "light_gray", + "durability": 700, + "size": 200, + "item": "steel_plate", + "difficulty": 3, + "location": "center", + "flags": ["OBSTACLE", "OPAQUE", "CARGO"] + },{ + "type": "vehicle_part", + "id": "roof", "name": "roof", "symbol": "#", "color": "light_gray", @@ -451,7 +639,12 @@ "item": "steel_plate", "difficulty": 1, "location": "roof", - "flags": ["ROOF"] + "flags": ["ROOF"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "door", @@ -465,7 +658,12 @@ "item": "frame", "difficulty": 2, "location": "center", - "flags": ["OBSTACLE", "OPENABLE", "BOARDABLE"] + "flags": ["OBSTACLE", "OPENABLE", "BOARDABLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "door_opaque", @@ -479,7 +677,12 @@ "item": "frame", "difficulty": 2, "location": "center", - "flags": ["OBSTACLE", "OPAQUE", "OPENABLE", "BOARDABLE"] + "flags": ["OBSTACLE", "OPAQUE", "OPENABLE", "BOARDABLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "door_internal", @@ -493,7 +696,12 @@ "item": "frame", "difficulty": 2, "location": "center", - "flags": ["OBSTACLE", "OPAQUE", "OPENABLE", "ROOF", "BOARDABLE"] + "flags": ["OBSTACLE", "OPAQUE", "OPENABLE", "ROOF", "BOARDABLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "windshield", @@ -507,7 +715,8 @@ "item": "glass_sheet", "difficulty": 1, "location": "center", - "flags": ["OVER", "OBSTACLE"] + "flags": ["OVER", "OBSTACLE"], + "breaks_into": [] },{ "type" : "vehicle_part", "id" : "blade_horizontal", @@ -521,7 +730,8 @@ "item": "blade", "difficulty": 2, "location": "structure", - "flags": ["UNMOUNT_ON_DAMAGE", "SHARP", "PROTRUSION"] + "flags": ["UNMOUNT_ON_DAMAGE", "SHARP", "PROTRUSION"], + "breaks_into": [] },{ "type" : "vehicle_part", "id" : "blade_vertical", @@ -535,7 +745,8 @@ "item": "blade", "difficulty": 2, "location": "structure", - "flags": ["UNMOUNT_ON_DAMAGE", "SHARP", "PROTRUSION"] + "flags": ["UNMOUNT_ON_DAMAGE", "SHARP", "PROTRUSION"], + "breaks_into": [] },{ "type" : "vehicle_part", "id" : "spike", @@ -549,7 +760,8 @@ "item": "spike", "difficulty": 2, "location": "structure", - "flags": ["UNMOUNT_ON_DAMAGE", "SHARP", "PROTRUSION"] + "flags": ["UNMOUNT_ON_DAMAGE", "SHARP", "PROTRUSION"], + "breaks_into": [] },{ "type" : "vehicle_part", "id" : "wheel", @@ -564,7 +776,12 @@ "item": "wheel", "difficulty": 4, "location": "under", - "flags": ["WHEEL", "VARIABLE_SIZE"] + "flags": ["WHEEL", "VARIABLE_SIZE"], + "breaks_into": [ + {"item": "steel_lump", "min": 1, "max": 2}, + {"item": "steel_chunk", "min": 1, "max": 2}, + {"item": "scrap", "min": 1, "max": 2} + ] },{ "type" : "vehicle_part", "id" : "wheel_wide", @@ -579,22 +796,12 @@ "item": "wheel_wide", "difficulty": 5, "location": "under", - "flags": ["WHEEL", "VARIABLE_SIZE"] - },{ - "type" : "vehicle_part", - "id" : "wheel_underbody", - "name": "wide wheel (underbody)", - "symbol": "H", - "color": "dark_gray", - "broken_symbol": "x", - "broken_color": "light_gray", - "damage_modifier": 50, - "durability": 400, - "wheel_width": 14, - "item": "wheel_wide", - "difficulty": 6, - "location": "under", - "flags": ["WHEEL", "VARIABLE_SIZE"] + "flags": ["WHEEL", "VARIABLE_SIZE"], + "breaks_into": [ + {"item": "steel_lump", "min": 2, "max": 3}, + {"item": "steel_chunk", "min": 2, "max": 3}, + {"item": "scrap", "min": 2, "max": 3} + ] },{ "type" : "vehicle_part", "id" : "wheel_unicycle", @@ -609,7 +816,12 @@ "item": "wheel_bicycle", "difficulty": 2, "location": "under", - "flags": ["WHEEL", "STABLE", "VARIABLE_SIZE"] + "flags": ["WHEEL", "STABLE", "VARIABLE_SIZE"], + "breaks_into": [ + {"item": "steel_lump", "min": 0, "max": 1}, + {"item": "steel_chunk", "min": 1, "max": 2}, + {"item": "scrap", "min": 1, "max": 2} + ] },{ "type" : "vehicle_part", "id" : "wheel_bicycle", @@ -624,7 +836,12 @@ "item": "wheel_bicycle", "difficulty": 1, "location": "under", - "flags": ["WHEEL", "VARIABLE_SIZE"] + "flags": ["WHEEL", "VARIABLE_SIZE"], + "breaks_into": [ + {"item": "steel_lump", "min": 0, "max": 1}, + {"item": "steel_chunk", "min": 1, "max": 2}, + {"item": "scrap", "min": 1, "max": 2} + ] },{ "type" : "vehicle_part", "id" : "wheel_motorbike", @@ -639,7 +856,12 @@ "item": "wheel_motorbike", "difficulty": 2, "location": "under", - "flags": ["WHEEL", "VARIABLE_SIZE"] + "flags": ["WHEEL", "VARIABLE_SIZE"], + "breaks_into": [ + {"item": "steel_lump", "min": 1, "max": 3}, + {"item": "steel_chunk", "min": 1, "max": 3}, + {"item": "scrap", "min": 1, "max": 3} + ] },{ "type" : "vehicle_part", "id" : "wheel_small", @@ -654,7 +876,12 @@ "item": "wheel_small", "difficulty": 2, "location": "under", - "flags": ["WHEEL", "VARIABLE_SIZE"] + "flags": ["WHEEL", "VARIABLE_SIZE"], + "breaks_into": [ + {"item": "steel_lump", "min": 1, "max": 1}, + {"item": "steel_chunk", "min": 1, "max": 3}, + {"item": "scrap", "min": 1, "max": 3} + ] },{ "type" : "vehicle_part", "id" : "wheel_caster", @@ -669,7 +896,11 @@ "item": "wheel_caster", "difficulty": 1, "location": "under", - "flags": ["WHEEL", "STABLE", "VARIABLE_SIZE"] + "flags": ["WHEEL", "STABLE", "VARIABLE_SIZE"], + "breaks_into": [ + {"item": "steel_lump", "min": 0, "max": 1}, + {"item": "steel_chunk", "min": 1, "max": 2}, + {"item": "scrap", "min": 1, "max": 2}] },{ "type" : "vehicle_part", "id" : "engine_1cyl", @@ -685,7 +916,12 @@ "item": "1cyl_combustion", "difficulty": 2, "location": "engine_block", - "flags": ["ENGINE", "VARIABLE_SIZE", "ALTERNATOR"] + "flags": ["ENGINE", "VARIABLE_SIZE", "ALTERNATOR"], + "breaks_into": [ + {"item": "steel_lump", "min": 5, "max": 10}, + {"item": "steel_chunk", "min": 5, "max": 10}, + {"item": "scrap", "min": 5, "max": 10} + ] },{ "type" : "vehicle_part", "id" : "engine_vtwin", @@ -701,7 +937,12 @@ "item": "v2_combustion", "difficulty": 2, "location": "engine_block", - "flags": ["ENGINE", "VARIABLE_SIZE", "ALTERNATOR"] + "flags": ["ENGINE", "VARIABLE_SIZE", "ALTERNATOR"], + "breaks_into": [ + {"item": "steel_lump", "min": 10, "max": 20}, + {"item": "steel_chunk", "min": 10, "max": 20}, + {"item": "scrap", "min": 10, "max": 20} + ] },{ "type" : "vehicle_part", "id" : "engine_inline4", @@ -716,7 +957,12 @@ "item": "i4_combustion", "difficulty": 3, "location": "engine_block", - "flags": ["ENGINE", "VARIABLE_SIZE", "ALTERNATOR"] + "flags": ["ENGINE", "VARIABLE_SIZE", "ALTERNATOR"], + "breaks_into": [ + {"item": "steel_lump", "min": 20, "max": 30}, + {"item": "steel_chunk", "min": 20, "max": 30}, + {"item": "scrap", "min": 20, "max": 30} + ] },{ "type" : "vehicle_part", "id" : "engine_v6", @@ -732,7 +978,12 @@ "item": "v6_combustion", "difficulty": 4, "location": "engine_block", - "flags": ["ENGINE", "VARIABLE_SIZE", "ALTERNATOR"] + "flags": ["ENGINE", "VARIABLE_SIZE", "ALTERNATOR"], + "breaks_into": [ + {"item": "steel_lump", "min": 30, "max": 40}, + {"item": "steel_chunk", "min": 30, "max": 40}, + {"item": "scrap", "min": 30, "max": 40} + ] },{ "type" : "vehicle_part", "id" : "engine_v8", @@ -748,7 +999,12 @@ "item": "v8_combustion", "difficulty": 4, "location": "engine_block", - "flags": ["ENGINE", "VARIABLE_SIZE", "ALTERNATOR"] + "flags": ["ENGINE", "VARIABLE_SIZE", "ALTERNATOR"], + "breaks_into": [ + {"item": "steel_lump", "min": 40, "max": 50}, + {"item": "steel_chunk", "min": 40, "max": 50}, + {"item": "scrap", "min": 40, "max": 50} + ] },{ "type" : "vehicle_part", "id" : "engine_electric", @@ -764,7 +1020,12 @@ "item": "motor", "difficulty": 3, "location": "engine_block", - "flags": ["ENGINE"] + "flags": ["ENGINE"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 3, "max": 5}, + {"item": "scrap", "min": 3, "max": 5} + ] },{ "type" : "vehicle_part", "id" : "engine_electric_large", @@ -780,7 +1041,12 @@ "item": "motor_large", "difficulty": 4, "location": "engine_block", - "flags": ["ENGINE"] + "flags": ["ENGINE"], + "breaks_into": [ + {"item": "steel_lump", "min": 30, "max": 40}, + {"item": "steel_chunk", "min": 30, "max": 40}, + {"item": "scrap", "min": 30, "max": 40} + ] },{ "type" : "vehicle_part", "id" : "engine_plasma", @@ -796,7 +1062,12 @@ "item": "plasma_engine", "difficulty": 6, "location": "engine_block", - "flags": ["ENGINE", "ALTERNATOR"] + "flags": ["ENGINE", "ALTERNATOR"], + "breaks_into": [ + {"item": "steel_lump", "min": 10, "max": 15}, + {"item": "steel_chunk", "min": 10, "max": 15}, + {"item": "scrap", "min": 10, "max": 15} + ] },{ "type" : "vehicle_part", "id" : "foot_pedals", @@ -812,7 +1083,11 @@ "item": "foot_crank", "difficulty": 1, "location": "engine_block", - "flags": ["ENGINE"] + "flags": ["ENGINE"], + "breaks_into": [ + {"item": "steel_chunk", "min": 1, "max": 2}, + {"item": "scrap", "min": 0, "max": 2} + ] },{ "type" : "vehicle_part", "id" : "gas_tank", @@ -828,7 +1103,12 @@ "item": "metal_tank", "difficulty": 1, "location": "fuel_source", - "flags": ["FUEL_TANK"] + "flags": ["FUEL_TANK"], + "breaks_into": [ + {"item": "steel_lump", "min": 1, "max": 1}, + {"item": "steel_chunk", "min": 1, "max": 2}, + {"item": "scrap", "min": 1, "max": 2} + ] },{ "type" : "vehicle_part", "id" : "small_storage_battery", @@ -844,7 +1124,10 @@ "item": "small_storage_battery", "difficulty": 1, "location": "fuel_source", - "flags": ["FUEL_TANK"] + "flags": ["FUEL_TANK"], + "breaks_into": [ + {"item": "scrap", "min": 1, "max": 2} + ] },{ "type" : "vehicle_part", "id" : "storage_battery", @@ -860,7 +1143,12 @@ "item": "storage_battery", "difficulty": 2, "location": "fuel_source", - "flags": ["FUEL_TANK"] + "flags": ["FUEL_TANK"], + "breaks_into": [ + {"item": "steel_lump", "min": 5, "max": 10}, + {"item": "steel_chunk", "min": 5, "max": 10}, + {"item": "scrap", "min": 5, "max": 10} + ] },{ "type" : "vehicle_part", "id" : "minireactor", @@ -876,7 +1164,12 @@ "item": "minireactor", "difficulty": 7, "location": "fuel_source", - "flags": ["FUEL_TANK"] + "flags": ["FUEL_TANK"], + "breaks_into": [ + {"item": "steel_lump", "min": 6, "max": 11}, + {"item": "steel_chunk", "min": 6, "max": 11}, + {"item": "scrap", "min": 6, "max": 11} + ] },{ "type" : "vehicle_part", "id" : "hydrogen_tank", @@ -892,7 +1185,12 @@ "item": "metal_tank", "difficulty": 1, "location": "fuel_source", - "flags": ["FUEL_TANK"] + "flags": ["FUEL_TANK"], + "breaks_into": [ + {"item": "steel_lump", "min": 1, "max": 1}, + {"item": "steel_chunk", "min": 1, "max": 2}, + {"item": "scrap", "min": 1, "max": 2} + ] },{ "type" : "vehicle_part", "id" : "water_tank", @@ -908,7 +1206,12 @@ "item": "metal_tank", "difficulty": 1, "location": "fuel_source", - "flags": ["FUEL_TANK"] + "flags": ["FUEL_TANK"], + "breaks_into": [ + {"item": "steel_lump", "min": 1, "max": 1}, + {"item": "steel_chunk", "min": 1, "max": 2}, + {"item": "scrap", "min": 1, "max": 2} + ] },{ "type" : "vehicle_part", "id" : "minifridge", @@ -923,7 +1226,13 @@ "item": "minifridge", "difficulty": 3, "location": "center", - "flags": ["CARGO", "OBSTACLE"] + "flags": ["CARGO", "OBSTACLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 8, "max": 13}, + {"item": "steel_chunk", "min": 8, "max": 13}, + {"item": "scrap", "min": 8, "max": 13}, + {"item": "hose", "min": 0, "max": 1} + ] },{ "type" : "vehicle_part", "id" : "trunk", @@ -938,7 +1247,12 @@ "item": "frame", "difficulty": 1, "location": "center", - "flags": ["CARGO"] + "flags": ["CARGO"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "box", @@ -953,7 +1267,12 @@ "item": "frame", "difficulty": 1, "location": "center", - "flags": ["CARGO", "BOARDABLE"] + "flags": ["CARGO", "BOARDABLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "controls", @@ -966,7 +1285,12 @@ "durability": 250, "item": "vehicle_controls", "difficulty": 3, - "flags": ["CONTROLS"] + "flags": ["CONTROLS"], + "breaks_into": [ + {"item": "steel_lump", "min": 1, "max": 1}, + {"item": "steel_chunk", "min": 1, "max": 3}, + {"item": "scrap", "min": 1, "max": 3} + ] },{ "type" : "vehicle_part", "id" : "muffler", @@ -980,7 +1304,12 @@ "bonus": 40, "item": "muffler", "difficulty": 2, - "flags": ["MUFFLER"] + "flags": ["MUFFLER"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 5}, + {"item": "steel_chunk", "min": 3, "max": 5}, + {"item": "scrap", "min": 3, "max": 5} + ] },{ "type" : "vehicle_part", "id" : "seatbelt", @@ -995,7 +1324,10 @@ "item": "rope_6", "difficulty": 1, "location": "on_seat", - "flags": ["SEATBELT"] + "flags": ["SEATBELT"], + "breaks_into": [ + {"item": "string_36", "min": 0, "max": 3} + ] },{ "type" : "vehicle_part", "id" : "solar_panel", @@ -1010,7 +1342,12 @@ "item": "solar_panel", "difficulty": 6, "location": "on_roof", - "flags": ["SOLAR_PANEL"] + "flags": ["SOLAR_PANEL"], + "breaks_into": [ + {"item": "steel_lump", "min": 2, "max": 4}, + {"item": "steel_chunk", "min": 2, "max": 4}, + {"item": "scrap", "min": 2, "max": 4} + ] },{ "type" : "vehicle_part", "id" : "reinforced_solar_panel", @@ -1025,7 +1362,12 @@ "item": "reinforced_solar_panel", "difficulty": 6, "location": "on_roof", - "flags": ["SOLAR_PANEL"] + "flags": ["SOLAR_PANEL"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 7}, + {"item": "steel_chunk", "min": 4, "max": 7}, + {"item": "scrap", "min": 4, "max": 7} + ] },{ "type" : "vehicle_part", "id" : "kitchen_unit", @@ -1040,7 +1382,14 @@ "item": "kitchen_unit", "difficulty": 4, "location": "center", - "flags": ["CARGO", "OBSTACLE", "KITCHEN"] + "flags": ["CARGO", "OBSTACLE", "KITCHEN"], + "breaks_into": [ + {"item": "steel_lump", "min": 30, "max": 40}, + {"item": "steel_chunk", "min": 30, "max": 40}, + {"item": "scrap", "min": 30, "max": 40}, + {"item": "pan", "min": 0, "max": 1}, + {"item": "pot", "min": 0, "max": 1} + ] },{ "type" : "vehicle_part", "id" : "welding_rig", @@ -1055,7 +1404,13 @@ "item": "weldrig", "difficulty": 4, "location": "center", - "flags": ["CARGO", "OBSTACLE", "WELDRIG"] + "flags": ["CARGO", "OBSTACLE", "WELDRIG"], + "breaks_into": [ + {"item": "steel_lump", "min": 3, "max": 6}, + {"item": "steel_chunk", "min": 3, "max": 6}, + {"item": "scrap", "min": 3, "max": 6}, + {"item": "welder", "min": 0, "max": 1} + ] },{ "type" : "vehicle_part", "id" : "craft_rig", @@ -1070,7 +1425,18 @@ "item": "craftrig", "difficulty": 4, "location": "center", - "flags": ["CARGO", "OBSTACLE", "CRAFTRIG"] + "flags": ["CARGO", "OBSTACLE", "CRAFTRIG"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 7}, + {"item": "steel_chunk", "min": 4, "max": 7}, + {"item": "scrap", "min": 4, "max": 7}, + {"item": "pan", "min": 0, "max": 1}, + {"item": "pot", "min": 0, "max": 1}, + {"item": "water_purifier", "min": 0, "max": 1}, + {"item": "vac_sealer", "min": 0, "max": 1}, + {"item": "dehydrator", "min": 0, "max": 1}, + {"item": "press", "min": 0, "max": 1} + ] },{ "type" : "vehicle_part", "id" : "veh_forge", @@ -1084,7 +1450,12 @@ "item": "forge", "difficulty": 3, "location": "center", - "flags": ["OBSTACLE", "FORGE"] + "flags": ["OBSTACLE", "FORGE"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 5}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "m249", @@ -1100,7 +1471,10 @@ "size" : 40, "difficulty": 6, "location": "on_roof", - "flags": ["TURRET", "CARGO"] + "flags": ["TURRET", "CARGO"], + "breaks_into": [ + {"item": "m249", "min": 0, "max": 1} + ] },{ "type" : "vehicle_part", "id" : "flamethrower", @@ -1115,7 +1489,10 @@ "item": "flamethrower", "difficulty": 7, "location": "on_roof", - "flags": ["TURRET"] + "flags": ["TURRET"], + "breaks_into": [ + {"item": "flamethrower", "min": 0, "max": 1} + ] },{ "type" : "vehicle_part", "id" : "plasma_gun", @@ -1130,7 +1507,10 @@ "item": "plasma_rifle", "difficulty": 7, "location": "on_roof", - "flags": ["TURRET"] + "flags": ["TURRET"], + "breaks_into": [ + {"item": "plasma_rifle", "min": 0, "max": 1} + ] },{ "type" : "vehicle_part", "id" : "fusion_gun", @@ -1146,7 +1526,10 @@ "difficulty": 7, "size": 10, "location": "on_roof", - "flags": ["TURRET", "CARGO"] + "flags": ["TURRET", "CARGO"], + "breaks_into": [ + {"item": "ftk93", "min": 0, "max": 1} + ] },{ "type" : "vehicle_part", "id" : "plating_steel", @@ -1159,7 +1542,12 @@ "item": "steel_plate", "difficulty": 3, "location": "armor", - "flags": ["ARMOR"] + "flags": ["ARMOR"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "plating_superalloy", @@ -1172,7 +1560,12 @@ "item": "alloy_plate", "difficulty": 4, "location": "armor", - "flags": ["ARMOR"] + "flags": ["ARMOR"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "plating_spiked", @@ -1186,7 +1579,13 @@ "item": "spiked_plate", "difficulty": 3, "location": "armor", - "flags": ["ARMOR", "SHARP"] + "flags": ["ARMOR", "SHARP"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6}, + {"item": "spike", "min": 0, "max": 2} + ] },{ "type" : "vehicle_part", "id" : "plating_hard", @@ -1199,7 +1598,12 @@ "item": "hard_plate", "difficulty": 4, "location": "armor", - "flags": ["ARMOR"] + "flags": ["ARMOR"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "headlight", @@ -1214,7 +1618,10 @@ "bonus": 480, "item": "flashlight", "difficulty": 1, - "flags": ["CONE_LIGHT"] + "flags": ["CONE_LIGHT"], + "breaks_into": [ + {"item": "scrap", "min": 0, "max": 2} + ] },{ "type" : "vehicle_part", "id" : "reinforced_windshield", @@ -1228,7 +1635,8 @@ "item": "reinforced_glass_sheet", "difficulty": 6, "location": "center", - "flags": ["OBSTACLE"] + "flags": ["OBSTACLE"], + "breaks_into": [] },{ "type" : "vehicle_part", "id" : "horn_bicycle", @@ -1242,7 +1650,10 @@ "bonus": 15, "item": "horn_bicycle", "difficulty": 1, - "flags": ["HORN"] + "flags": ["HORN"], + "breaks_into": [ + {"item": "scrap", "min": 0, "max": 1} + ] },{ "type" : "vehicle_part", "id" : "horn_car", @@ -1256,7 +1667,10 @@ "bonus": 30, "item": "horn_car", "difficulty": 3, - "flags": ["HORN"] + "flags": ["HORN"], + "breaks_into": [ + {"item": "scrap", "min": 0, "max": 2} + ] },{ "type" : "vehicle_part", "id" : "horn_big", @@ -1270,7 +1684,10 @@ "bonus": 45, "item": "horn_big", "difficulty": 3, - "flags": ["HORN"] + "flags": ["HORN"], + "breaks_into": [ + {"item": "steel_chunk", "min": 0, "max": 1} + ] },{ "type" : "vehicle_part", "id" : "battery_motorbike", @@ -1285,7 +1702,12 @@ "fuel_type": "battery", "item": "battery_motorbike", "difficulty": 2, - "flags": ["FUEL_TANK"] + "flags": ["FUEL_TANK"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 7}, + {"item": "steel_chunk", "min": 4, "max": 7}, + {"item": "scrap", "min": 4, "max": 7} + ] },{ "type" : "vehicle_part", "id" : "battery_car", @@ -1300,7 +1722,12 @@ "fuel_type": "battery", "item": "battery_car", "difficulty": 2, - "flags": ["FUEL_TANK"] + "flags": ["FUEL_TANK"], + "breaks_into": [ + {"item": "steel_lump", "min": 6, "max": 9}, + {"item": "steel_chunk", "min": 6, "max": 9}, + {"item": "scrap", "min": 6, "max": 9} + ] },{ "type" : "vehicle_part", "id" : "battery_truck", @@ -1315,7 +1742,12 @@ "fuel_type": "battery", "item": "battery_truck", "difficulty": 2, - "flags": ["FUEL_TANK"] + "flags": ["FUEL_TANK"], + "breaks_into": [ + {"item": "steel_lump", "min": 8, "max": 12}, + {"item": "steel_chunk", "min": 8, "max": 12}, + {"item": "scrap", "min": 8, "max": 12} + ] },{ "type" : "vehicle_part", "id" : "door_trunk", @@ -1329,7 +1761,12 @@ "item": "frame", "difficulty": 2, "location": "center", - "flags": ["OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE"] + "flags": ["OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "door_shutter", @@ -1343,7 +1780,12 @@ "item": "steel_plate", "difficulty": 3, "location": "center", - "flags": ["OPAQUE", "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE"] + "flags": ["OPAQUE", "OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "door_sliding", @@ -1357,7 +1799,12 @@ "item": "frame", "difficulty": 2, "location": "center", - "flags": ["OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE"] + "flags": ["OBSTACLE", "OPENABLE", "MULTISQUARE", "BOARDABLE"], + "breaks_into": [ + {"item": "steel_lump", "min": 4, "max": 6}, + {"item": "steel_chunk", "min": 4, "max": 6}, + {"item": "scrap", "min": 4, "max": 6} + ] },{ "type" : "vehicle_part", "id" : "light_red", @@ -1373,7 +1820,11 @@ "item": "light_emergency_red", "difficulty": 1, "location": "on_roof", - "flags": ["CIRCLE_LIGHT", "ODDTURN"] + "flags": ["CIRCLE_LIGHT", "ODDTURN"], + "breaks_into": [ + {"item": "steel_chunk", "min": 0, "max": 1}, + {"item": "scrap", "min": 1, "max": 1} + ] },{ "type" : "vehicle_part", "id" : "light_blue", @@ -1389,6 +1840,10 @@ "item": "light_emergency_blue", "difficulty": 1, "location": "on_roof", - "flags": ["CIRCLE_LIGHT", "EVENTURN"] + "flags": ["CIRCLE_LIGHT", "EVENTURN"], + "breaks_into": [ + {"item": "steel_chunk", "min": 0, "max": 1}, + {"item": "scrap", "min": 1, "max": 1} + ] } ] diff --git a/defense.cpp b/defense.cpp index f615a1d4899a4..5508130d6d0c7 100644 --- a/defense.cpp +++ b/defense.cpp @@ -158,10 +158,12 @@ void defense_game::pre_action(game *g, action_id &act) void defense_game::post_action(game *g, action_id act) { + (void)g; (void)act; } void defense_game::game_over(game *g) { + (void)g; //unused popup(_("You managed to survive through wave %d!"), current_wave); // Reset changed information reset_mtypes(); @@ -238,6 +240,7 @@ void defense_game::init_itypes(game *g) void defense_game::init_mtypes(game *g) { + (void)g; //unused m_flag flags[] = {MF_BASHES, MF_SMELLS, MF_HEARS, MF_SEES}; monflags_to_add.insert(flags, flags + 4); @@ -273,6 +276,7 @@ void defense_game::init_constructions(game *g) void defense_game::init_recipes(game *g) { + (void)g; //unused for (recipe_map::iterator map_iter = recipes.begin(); map_iter != recipes.end(); ++map_iter) { for (recipe_list::iterator list_iter = map_iter->second.begin(); list_iter != map_iter->second.end(); ++list_iter) @@ -1318,6 +1322,7 @@ void defense_game::spawn_wave(game *g) std::vector defense_game::pick_monster_wave(game *g) { + (void)g; //unused std::vector valid; std::vector ret; diff --git a/disease.cpp b/disease.cpp index 37730cff64bc3..dde43942e58d6 100644 --- a/disease.cpp +++ b/disease.cpp @@ -1124,7 +1124,7 @@ void dis_effect(player &p, disease &dis) { if (dis.duration > 3600) { // 12 teles if (one_in(4000 - int(.25 * (dis.duration - 3600)))) { - MonsterGroupResult spawn_details = MonsterGroupManager::GetResultFromGroup("GROUP_NETHER", &g->mtypes); + MonsterGroupResult spawn_details = MonsterGroupManager::GetResultFromGroup("GROUP_NETHER"); monster beast(GetMType(spawn_details.name)); int x, y; int tries = 0; @@ -1191,7 +1191,7 @@ void dis_effect(player &p, disease &dis) { case DI_ATTENTION: if (one_in(100000 / dis.duration) && one_in(100000 / dis.duration) && one_in(250)) { - MonsterGroupResult spawn_details = MonsterGroupManager::GetResultFromGroup("GROUP_NETHER", &g->mtypes); + MonsterGroupResult spawn_details = MonsterGroupManager::GetResultFromGroup("GROUP_NETHER"); monster beast(GetMType(spawn_details.name)); int x, y; int tries = 0; @@ -2222,7 +2222,7 @@ void manage_fungal_infection(player& p, disease& dis) { g->add_msg(_("The %s is covered in tiny spores!"), g->zombie(zid).name().c_str()); } - if (!g->zombie(zid).make_fungus(g)) { + if (!g->zombie(zid).make_fungus()) { g->kill_mon(zid); } } else if (one_in(4) && g->num_zombies() <= 1000){ diff --git a/editmap.cpp b/editmap.cpp index 7c9323804158e..acfad48e0d4d4 100644 --- a/editmap.cpp +++ b/editmap.cpp @@ -28,7 +28,6 @@ #include #include #include "debug.h" -#include "artifactdata.h" #define dbg(x) dout((DebugLevel)(x),D_GAME) << __FILE__ << ":" << __LINE__ << ": " #define maplim 132 @@ -264,7 +263,7 @@ void editmap::uphelp (std::string txt1, std::string txt2, std::string title) * main() */ -point editmap::edit(point coords) +point editmap::edit() { target.x = g->u.posx + g->u.view_offset_x; target.y = g->u.posy + g->u.view_offset_y; @@ -298,16 +297,16 @@ point editmap::edit(point coords) input = get_input(ch); // get_input: Not very useful for arbitrary keys, so check getch value first. } if(ch == 'g') { - edit_ter( target ); + edit_ter(); lastop = 'g'; } else if ( ch == 'f' ) { - edit_fld( target ); + edit_fld(); lastop = 'f'; } else if ( ch == 'i' ) { - edit_itm( target ); + edit_itm(); lastop = 'i'; } else if ( ch == 't' ) { - edit_trp( target ); + edit_trp(); lastop = 't'; } else if ( ch == 'v' ) { uberdraw = !uberdraw; @@ -317,14 +316,14 @@ point editmap::edit(point coords) int veh_part = -1; vehicle *veh = g->m.veh_at(target.x, target.y, veh_part); if(mon_index >= 0) { - edit_mon(target); + edit_mon(); } else if (npc_index >= 0) { - edit_npc(target); + edit_npc(); } else if (veh) { - edit_veh(target); + edit_veh(); } } else if ( ch == 'o' ) { - edit_mapgen( target ); + edit_mapgen(); lastop = 'o'; target_list.clear(); origin = target; @@ -630,7 +629,7 @@ int get_alt_ter(bool isvert, ter_id sel_ter) { ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///// edit terrain type / furniture -int editmap::edit_ter(point coords) +int editmap::edit_ter() { int ret = 0; int pwh = TERRAIN_WINDOW_HEIGHT - 4; @@ -945,7 +944,7 @@ void editmap::update_fmenu_entry(uimenu *fmenu, field *field, int idx) fmenu->entries[idx].extratxt.color = ftype.color[fdens-1]; } -void editmap::setup_fmenu(uimenu *fmenu, field *field) +void editmap::setup_fmenu(uimenu *fmenu) { std::string fname; fmenu->entries.clear(); @@ -963,7 +962,7 @@ void editmap::setup_fmenu(uimenu *fmenu, field *field) } } -int editmap::edit_fld(point coords) +int editmap::edit_fld() { int ret = 0; uimenu fmenu; @@ -972,7 +971,7 @@ int editmap::edit_fld(point coords) fmenu.w_y = 0; fmenu.w_x = TERRAIN_WINDOW_WIDTH + VIEW_OFFSET_X; fmenu.return_invalid = true; - setup_fmenu(&fmenu, cur_field); + setup_fmenu(&fmenu); do { uphelp("[s/tab] shape select, [m]ove, [<,>] density", @@ -1064,7 +1063,7 @@ int editmap::edit_fld(point coords) int sel_tmp = fmenu.selected; int ret = select_shape(editshape, ( fmenu.keypress == 'm' ? 1 : 0 ) ); if ( ret > 0 ) { - setup_fmenu(&fmenu, cur_field); + setup_fmenu(&fmenu); } fmenu.selected = sel_tmp; } else if ( fmenu.keypress == 'v' ) { @@ -1078,7 +1077,7 @@ int editmap::edit_fld(point coords) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///// edit traps -int editmap::edit_trp(point coords) +int editmap::edit_trp() { int ret = 0; int pwh = TERRAIN_WINDOW_HEIGHT - infoHeight - 1; @@ -1166,7 +1165,7 @@ enum editmap_imenu_ent { imenu_exit, }; -int editmap::edit_itm(point coords) +int editmap::edit_itm() { int ret = 0; uimenu ilmenu; @@ -1281,7 +1280,7 @@ int editmap::edit_itm(point coords) /* * Todo */ -int editmap::edit_mon(point coords) +int editmap::edit_mon() { int ret = 0; int mon_index = g->mon_at(target.x, target.y); @@ -1291,7 +1290,7 @@ int editmap::edit_mon(point coords) } -int editmap::edit_veh(point coords) +int editmap::edit_veh() { int ret = 0; int veh_part = -1; @@ -1400,7 +1399,7 @@ bool editmap::move_target( InputEvent &input, int ch, int moveorigin ) /* * Todo */ -int editmap::edit_npc(point coords) +int editmap::edit_npc() { int ret = 0; int npc_index = g->npc_at(target.x, target.y); @@ -1714,7 +1713,7 @@ int editmap::mapgen_preview( real_coords &tc, uimenu &gmenu ) /* * Move mapgen's target, which is different enough from the standard tile edit to warrant it's own function. */ -int editmap::mapgen_retarget ( WINDOW *preview, map *mptr) +int editmap::mapgen_retarget() { int ret = 0; int ch = 0; @@ -1762,7 +1761,7 @@ int editmap::mapgen_retarget ( WINDOW *preview, map *mptr) /* * apply mapgen to a temporary map and overlay over terrain window, optionally regenerating, rotating, and applying to the real in-game map */ -int editmap::edit_mapgen(point coords) +int editmap::edit_mapgen() { int ret = 0; point orig = target; diff --git a/editmap.h b/editmap.h index 60fecd272aa5f..c1bc5d18c27b7 100644 --- a/editmap.h +++ b/editmap.h @@ -38,25 +38,25 @@ class editmap point pos2screen( const int x, const int y ); point screen2pos( const int i, const int j ); bool eget_direction ( int &x, int &y, InputEvent &input, int ch ); - point edit(point coords); + point edit(); void uber_draw_ter( WINDOW * w, map * m ); void update_view(bool update_info = false); - int edit_ter(point coords); - - int edit_fld(point coords); - int edit_trp(point coords); - int edit_itm(point coords); - int edit_mon(point coords); - int edit_npc(point coords); - int edit_veh(point coords); - int edit_mapgen(point coords); + int edit_ter(); + + int edit_fld(); + int edit_trp(); + int edit_itm(); + int edit_mon(); + int edit_npc(); + int edit_veh(); + int edit_mapgen(); void cleartmpmap( tinymap & tmpmap ); int mapgen_preview(real_coords &tc, uimenu &gmenu); - int mapgen_retarget(WINDOW * preview = NULL, map * mptr = NULL); + int mapgen_retarget(); int select_shape(shapetype shape, int mode = -1 ); void update_fmenu_entry(uimenu *fmenu, field *field, int idx); - void setup_fmenu(uimenu *fmenu, field *field); + void setup_fmenu(uimenu *fmenu); bool change_fld(std::vector coords, field_id fid, int density); WINDOW *w_info; WINDOW *w_help; diff --git a/faction.h b/faction.h index 753a7f3d4dfd0..947f78096a08a 100644 --- a/faction.h +++ b/faction.h @@ -1,6 +1,8 @@ #ifndef _FACTION_H_ #define _FACTION_H_ +#include "json.h" + #include #include @@ -77,7 +79,9 @@ struct faction_value_datum { int cult; }; -struct faction { +class faction : public JsonSerializer, public JsonDeserializer +{ +public: static std::string faction_adj_pos[15]; static std::string faction_adj_neu[15]; static std::string faction_adj_bad[15]; @@ -92,13 +96,15 @@ struct faction { static faction_value_datum facjob_data[NUM_FACJOBS]; static faction_value_datum facval_data[NUM_FACVALS]; - faction(); - faction(int uid); - ~faction(); - std::string save_info(); - void load_info(std::string data); - void json_load(picojson::value parsed, game * g); - picojson::value json_save(bool save_contents = false); + faction(); + faction(int uid); + ~faction(); + std::string save_info(); + void load_info(std::string data); + using JsonDeserializer::deserialize; + void deserialize(JsonObject &jsobj); + using JsonSerializer::serialize; + void serialize(JsonOut &jsout) const; void randomize(); void make_army(); diff --git a/game.cpp b/game.cpp index d7191ab2987b9..42b916449921f 100644 --- a/game.cpp +++ b/game.cpp @@ -49,7 +49,6 @@ #endif #include #include "debug.h" -#include "artifactdata.h" #if (defined _WIN32 || defined __WIN32__) #ifndef NOMINMAX @@ -145,8 +144,6 @@ game::~game() { delete gamemode; itypes.clear(); - for (int i = 0; i < mtypes.size(); i++) - delete mtypes[i]; delwin(w_terrain); delwin(w_minimap); delwin(w_HP); @@ -2505,7 +2502,7 @@ bool game::is_game_over() { if (uquit == QUIT_SUICIDE){ if (u.in_vehicle) - g->m.unboard_vehicle(this, u.posx, u.posy); + g->m.unboard_vehicle(u.posx, u.posy); std::stringstream playerfile; playerfile << world_generator->active_world->world_path << "/" << base64_encode(u.name) << ".sav"; DebugLog() << "Unlinking player file: <"<< playerfile.str() << "> -- "; @@ -2519,7 +2516,7 @@ bool game::is_game_over() for (int i = 0; i <= hp_torso; i++){ if (u.hp_cur[i] < 1) { if (u.in_vehicle) - g->m.unboard_vehicle(this, u.posx, u.posy); + g->m.unboard_vehicle(u.posx, u.posy); place_corpse(); std::stringstream playerfile; playerfile << world_generator->active_world->world_path << "/" << base64_encode(u.name) << ".sav"; @@ -2646,148 +2643,19 @@ void game::load_uistate(std::string worldname) { savefile << world_generator->all_worlds[worldname]->world_path << "/uistate.json"; std::ifstream fin; - fin.open(savefile.str().c_str()); + fin.open(savefile.str().c_str(), std::ifstream::in | std::ifstream::binary); if(!fin.good()) { fin.close(); return; } - picojson::value wrapped_data; - fin >> wrapped_data; - fin.close(); - std::string jsonerr=picojson::get_last_error(); - if ( ! jsonerr.empty() ) { - dbg(D_ERROR) << "load_uistate: " << jsonerr.c_str(); - return; - } - bool success=uistate.load(wrapped_data); - if ( ! success ) { - dbg(D_ERROR) << "load_uistate: " << uistate.errdump; - } - uistate.errdump=""; -} - -void game::load_artifacts(std::string worldname) -{ - std::stringstream artifactfile; - artifactfile << world_generator->all_worlds[worldname]->world_path << "/artifacts.gsav"; - std::ifstream file_test(artifactfile.str().c_str(), std::ifstream::in | std::ifstream::binary); - if (!file_test.good()) { - file_test.close(); - return; - } - try { - load_artifacts_from_file(&file_test); + JsonIn jsin(&fin); + JsonObject jo = jsin.get_object(); + uistate.deserialize(jo); } catch (std::string e) { - debugmsg("%s: %s", artifactfile.str().c_str(), e.c_str()); - } - - file_test.close(); - } - -void game::load_artifacts_from_file(std::ifstream *f) - { - // read 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 id = jo.get_string("id"); - unsigned int price = jo.get_int("price"); - std::string name = jo.get_string("name"); - std::string description = jo.get_string("description"); - char sym = jo.get_int("sym"); - nc_color color = int_to_color(jo.get_int("color")); - std::string m1 = jo.get_string("m1"); - std::string m2 = jo.get_string("m2"); - unsigned int volume = jo.get_int("volume"); - unsigned int weight = jo.get_int("weight"); - signed char melee_dam = jo.get_int("melee_dam"); - signed char melee_cut = jo.get_int("melee_cut"); - signed char m_to_hit = jo.get_int("m_to_hit"); - std::set item_tags = jo.get_tags("item_flags"); - - std::string type = jo.get_string("type"); - if (type == "artifact_tool") { - unsigned int max_charges = jo.get_int("max_charges"); - unsigned int def_charges = jo.get_int("def_charges"); - unsigned char charges_per_use = jo.get_int("charges_per_use"); - unsigned char turns_per_charge = jo.get_int("turns_per_charge"); - ammotype ammo = jo.get_string("ammo"); - std::string revert_to = jo.get_string("revert_to"); - - it_artifact_tool* art_type = new it_artifact_tool( - id, price, name, description, sym, color, m1, m2, volume, - weight, melee_dam, melee_cut, m_to_hit, item_tags, - max_charges, def_charges, charges_per_use, turns_per_charge, - ammo, revert_to); - - art_charge charge_type = (art_charge)jo.get_int("charge_type"); - - JsonArray effects_wielded_json = jo.get_array("effects_wielded"); - std::vector effects_wielded; - while (effects_wielded_json.has_more()) { - art_effect_passive effect = - (art_effect_passive)effects_wielded_json.next_int(); - effects_wielded.push_back(effect); - } - - JsonArray effects_activated_json = jo.get_array("effects_activated"); - std::vector effects_activated; - while (effects_activated_json.has_more()) { - art_effect_active effect = - (art_effect_active)effects_activated_json.next_int(); - effects_activated.push_back(effect); - } - - JsonArray effects_carried_json = jo.get_array("effects_carried"); - std::vector effects_carried; - while (effects_carried_json.has_more()) { - art_effect_passive effect = - (art_effect_passive)effects_carried_json.next_int(); - effects_carried.push_back(effect); - } - - art_type->charge_type = charge_type; - art_type->effects_wielded = effects_wielded; - art_type->effects_activated = effects_activated; - art_type->effects_carried = effects_carried; - - itypes[id] = art_type; - } - else if (type == "artifact_armor") - { - unsigned char covers = jo.get_int("covers"); - signed char encumber = jo.get_int("encumber"); - unsigned char coverage = jo.get_int("coverage"); - unsigned char thickness = jo.get_int("material_thickness"); - unsigned char env_resist = jo.get_int("env_resist"); - signed char warmth = jo.get_int("warmth"); - unsigned char storage = jo.get_int("storage"); - bool power_armor = jo.get_bool("power_armor"); - - it_artifact_armor* art_type = new it_artifact_armor( - id, price, name, description, sym, color, m1, m2, volume, - weight, melee_dam, melee_cut, m_to_hit, item_tags, - covers, encumber, coverage, thickness, env_resist, warmth, - storage); - art_type->power_armor = power_armor; - - JsonArray effects_worn_json = jo.get_array("effects_worn"); - std::vector effects_worn; - while (effects_worn_json.has_more()) { - art_effect_passive effect = - (art_effect_passive)effects_worn_json.next_int(); - effects_worn.push_back(effect); - } - art_type->effects_worn = effects_worn; - - itypes[id] = art_type; - } - - jo.finish(); + dbg(D_ERROR) << "load_uistate: " << e; } + fin.close(); } void game::load(std::string worldname, std::string name) @@ -2860,18 +2728,22 @@ void game::save_factions_missions_npcs () void game::save_artifacts() { std::ofstream fout; - std::vector artifacts; - std::stringstream artifactfile; - artifactfile << world_generator->active_world->world_path << "/artifacts.gsav"; - fout.open(artifactfile.str().c_str()); + std::string artfilename = world_generator->active_world->world_path + "/artifacts.gsav"; + fout.open(artfilename.c_str()); + JsonOut json(&fout); + json.start_array(); for ( std::vector::iterator it = artifact_itype_ids.begin(); it != artifact_itype_ids.end(); ++it) { - artifacts.push_back(itypes[*it]->save_data()); + it_artifact_tool *art = dynamic_cast(itypes[*it]); + if (art) { + json.write(*art); + } else { + json.write(*(dynamic_cast(itypes[*it]))); } - picojson::value out = picojson::value(artifacts); - fout << out.serialize(); + } + json.end_array(); fout.close(); } @@ -2887,9 +2759,8 @@ void game::save_uistate() { savefile << world_generator->active_world->world_path << "/uistate.json"; std::ofstream fout; fout.open(savefile.str().c_str()); - fout << uistate.save(); + fout << uistate.serialize(); fout.close(); - uistate.errdump=""; } void game::save() @@ -3379,7 +3250,7 @@ Current turn: %d; Next spawn %d.\n\ artifact_natural_property prop = artifact_natural_property(rng(ARTPROP_NULL + 1, ARTPROP_MAX - 1)); m.create_anomaly(center.x, center.y, prop); - m.spawn_artifact(center.x, center.y, new_natural_artifact(prop), 0); + m.spawn_artifact(center.x, center.y, new_natural_artifact(itypes, prop), 0); } break; @@ -5372,6 +5243,10 @@ void game::knockback(int sx, int sy, int tx, int ty, int force, int stun, int da void game::knockback(std::vector& traj, int force, int stun, int dam_mult) { + (void)force; //FIXME: unused but header says it should do something + // TODO: make the force parameter actually do something. + // the header file says higher force causes more damage. + // perhaps that is what it should do? int tx = traj.front().x; int ty = traj.front().y; const int zid = mon_at(tx, ty); @@ -5740,7 +5615,7 @@ void game::resonance_cascade(int x, int y) case 13: case 14: case 15: - spawn_details = MonsterGroupManager::GetResultFromGroup("GROUP_NETHER", &mtypes); + spawn_details = MonsterGroupManager::GetResultFromGroup("GROUP_NETHER"); invader = monster(GetMType(spawn_details.name), i, j); add_zombie(invader); break; @@ -6090,7 +5965,7 @@ void game::explode_mon(int index) } } } - m.spawn_item(tarx, tary, meat, turn); + m.spawn_item(tarx, tary, meat, 1, 0, turn); } } } @@ -6676,7 +6551,7 @@ void game::moving_vehicle_dismount(int tox, int toy) } int d = (45 * (direction_from(u.posx, u.posy, tox, toy)) - 90) % 360; add_msg(_("You dive from the %s."), veh->name.c_str()); - m.unboard_vehicle(this, u.posx, u.posy); + m.unboard_vehicle(u.posx, u.posy); u.moves -= 200; // Dive three tiles in the direction of tox and toy fling_player_or_monster(&u, 0, d, 30, true); @@ -6800,9 +6675,9 @@ void game::peek() u.posy = prevy; } //////////////////////////////////////////////////////////////////////////////////////////// -point game::look_debug(point coords) { +point game::look_debug() { editmap * edit=new editmap(this); - point ret=edit->edit(coords); + point ret=edit->edit(); delete edit; edit=0; return ret; @@ -9552,20 +9427,20 @@ void game::complete_butcher(int index) if (bones > 0) { if (corpse->has_flag(MF_BONES)) { - m.spawn_item(u.posx, u.posy, "bone", age, bones); + m.spawn_item(u.posx, u.posy, "bone", bones, 0, age); add_msg(_("You harvest some usable bones!")); } else if (corpse->mat == "veggy") { - m.spawn_item(u.posx, u.posy, "plant_sac", age, bones); + m.spawn_item(u.posx, u.posy, "plant_sac", bones, 0, age); add_msg(_("You harvest some fluid bladders!")); } } if (sinews > 0) { if (corpse->has_flag(MF_BONES)) { - m.spawn_item(u.posx, u.posy, "sinew", age, sinews); + m.spawn_item(u.posx, u.posy, "sinew", sinews, 0, age); add_msg(_("You harvest some usable sinews!")); } else if (corpse->mat == "veggy") { - m.spawn_item(u.posx, u.posy, "plant_fibre", age, sinews); + m.spawn_item(u.posx, u.posy, "plant_fibre", sinews, 0, age); add_msg(_("You harvest some plant fibres!")); } } @@ -9595,14 +9470,14 @@ void game::complete_butcher(int index) } } - if(chitin) m.spawn_item(u.posx, u.posy, "chitin_piece", age, chitin); - if(fur) m.spawn_item(u.posx, u.posy, "fur", age, fur); - if(leather) m.spawn_item(u.posx, u.posy, "leather", age, leather); + if(chitin) m.spawn_item(u.posx, u.posy, "chitin_piece", chitin, 0, age); + if(fur) m.spawn_item(u.posx, u.posy, "fur", fur, 0, age); + if(leather) m.spawn_item(u.posx, u.posy, "leather", leather, 0, age); } if (feathers > 0) { if (corpse->has_flag(MF_FEATHER)) { - m.spawn_item(u.posx, u.posy, "feather", age, feathers); + m.spawn_item(u.posx, u.posy, "feather", feathers, 0, age); add_msg(_("You harvest some feathers!")); } } @@ -9614,18 +9489,18 @@ void game::complete_butcher(int index) add_msg(_("You discover a CBM in the %s!"), corpse->name.c_str()); //To see if it spawns a battery if(rng(0,1) == 1){ //The battery works - m.spawn_item(u.posx, u.posy, "bio_power_storage", age); + m.spawn_item(u.posx, u.posy, "bio_power_storage", 1, 0, age); }else{//There is a burnt out CBM - m.spawn_item(u.posx, u.posy, "burnt_out_bionic", age); + m.spawn_item(u.posx, u.posy, "burnt_out_bionic", 1, 0, age); } } if(skill_shift >= 0){ //To see if it spawns a random additional CBM if(rng(0,1) == 1){ //The CBM works Item_tag bionic_item = item_controller->id_from("bionics"); - m.spawn_item(u.posx, u.posy, bionic_item, age); + m.spawn_item(u.posx, u.posy, bionic_item, 1, 0, age); }else{//There is a burnt out CBM - m.spawn_item(u.posx, u.posy, "burnt_out_bionic", age); + m.spawn_item(u.posx, u.posy, "burnt_out_bionic", 1, 0, age); } } } @@ -9636,7 +9511,7 @@ void game::complete_butcher(int index) add_msg(_("You discover a %s in the %s!"), contents[i].tname().c_str(), corpse->name.c_str()); m.add_item_or_charges(u.posx, u.posy, contents[i]); } else if (contents[i].is_bionic()){ - m.spawn_item(u.posx, u.posy, "burnt_out_bionic", age); + m.spawn_item(u.posx, u.posy, "burnt_out_bionic", 1, 0, age); } } @@ -9684,7 +9559,7 @@ void game::forage() { add_msg(_("You found some wild veggies!")); u.practice(turn, "survival", 10); - m.spawn_item(u.activity.placement.x, u.activity.placement.y, "veggy_wild", turn, 0); + m.spawn_item(u.activity.placement.x, u.activity.placement.y, "veggy_wild", 1, 0, turn); m.ter_set(u.activity.placement.x, u.activity.placement.y, t_dirt); } else @@ -10623,7 +10498,7 @@ void game::plmove(int dx, int dy) if (query_yn(_("Deactivate the turret?"))) { remove_zombie(mondex); u.moves -= 100; - m.spawn_item(x, y, "bot_turret", turn); + m.spawn_item(x, y, "bot_turret", 1, 0, turn); } return; } else { @@ -10641,7 +10516,7 @@ void game::plmove(int dx, int dy) // If the player is in a vehicle, unboard them from the current part if (u.in_vehicle) - m.unboard_vehicle(this, u.posx, u.posy); + m.unboard_vehicle(u.posx, u.posy); // Move the player u.posx = x; @@ -10765,7 +10640,7 @@ void game::plmove(int dx, int dy) if(tunneldist) //you tunneled { if (u.in_vehicle) - m.unboard_vehicle(this, u.posx, u.posy); + m.unboard_vehicle(u.posx, u.posy); u.power_level -= (tunneldist * 10); //tunneling costs 10 bionic power per impassable tile u.moves -= 100; //tunneling costs 100 moves u.posx += (tunneldist + 1) * (x - u.posx); //move us the number of tiles we tunneled in the x direction, plus 1 for the last tile @@ -11150,7 +11025,7 @@ void game::vertical_move(int movez, bool force) if (rope_ladder) m.ter_set(u.posx, u.posy, t_rope_up); if (m.ter(stairx, stairy) == t_manhole_cover) { - m.spawn_item(stairx + rng(-1, 1), stairy + rng(-1, 1), "manhole_cover", 0); + m.spawn_item(stairx + rng(-1, 1), stairy + rng(-1, 1), "manhole_cover"); m.ter_set(stairx, stairy, t_manhole); } @@ -11541,7 +11416,7 @@ void game::spawn_mon(int shiftx, int shifty) nextspawn += rng(group * 4 + num_zombies() * 4, group * 10 + num_zombies() * 10); for (int j = 0; j < group; j++) { // For each monster in the group get some spawn details - MonsterGroupResult spawn_details = MonsterGroupManager::GetResultFromGroup( cur_om->zg[i].type, &mtypes, + MonsterGroupResult spawn_details = MonsterGroupManager::GetResultFromGroup( cur_om->zg[i].type, &group, (int)turn ); zom = monster(GetMType(spawn_details.name)); for (int kk = 0; kk < spawn_details.pack_size; kk++){ @@ -11792,7 +11667,7 @@ void game::teleport(player *p) } while (tries < 15 && !is_empty(newx, newy)); bool can_see = (is_u || u_see(newx, newy)); if (p->in_vehicle) { - m.unboard_vehicle (this, p->posx, p->posy); + m.unboard_vehicle(p->posx, p->posy); } p->posx = newx; p->posy = newy; @@ -12158,3 +12033,295 @@ make the terminal just a smidgen taller?"), erase(); } +void game::process_artifact(item *it, player *p, bool wielded) +{ + std::vector effects; + if (it->is_armor()) { + it_artifact_armor* armor = dynamic_cast(it->type); + effects = armor->effects_worn; + } else if (it->is_tool()) { + it_artifact_tool* tool = dynamic_cast(it->type); + effects = tool->effects_carried; + if (wielded) { + for (int i = 0; i < tool->effects_wielded.size(); i++) { + effects.push_back(tool->effects_wielded[i]); + } + } + // Recharge it if necessary + if (it->charges < tool->max_charges) { + switch (tool->charge_type) { + case ARTC_TIME: + // Once per hour + if (turn.seconds() == 0 && turn.minutes() == 0) { + it->charges++; + } + break; + case ARTC_SOLAR: + if (turn.seconds() == 0 && turn.minutes() % 10 == 0 && + is_in_sunlight(p->posx, p->posy)) { + it->charges++; + } + break; + case ARTC_PAIN: + if (turn.seconds() == 0) { + add_msg(_("You suddenly feel sharp pain for no reason.")); + p->pain += 3 * rng(1, 3); + it->charges++; + } + break; + case ARTC_HP: + if (turn.seconds() == 0) { + add_msg(_("You feel your body decaying.")); + p->hurtall(1); + it->charges++; + } + break; + } + } + } + + for (int i = 0; i < effects.size(); i++) { + switch (effects[i]) { + case AEP_STR_UP: + p->str_cur += 4; + break; + case AEP_DEX_UP: + p->dex_cur += 4; + break; + case AEP_PER_UP: + p->per_cur += 4; + break; + case AEP_INT_UP: + p->int_cur += 4; + break; + case AEP_ALL_UP: + p->str_cur += 2; + p->dex_cur += 2; + p->per_cur += 2; + p->int_cur += 2; + break; + case AEP_SPEED_UP: // Handled in player::current_speed() + break; + + case AEP_IODINE: + if (p->radiation > 0) { + p->radiation--; + } + break; + + case AEP_SMOKE: + if (one_in(10)) { + int x = p->posx + rng(-1, 1), y = p->posy + rng(-1, 1); + if (m.add_field(this, x, y, fd_smoke, rng(1, 3))) { + add_msg(_("The %s emits some smoke."), + it->tname().c_str()); + } + } + break; + + case AEP_SNAKES: + break; // Handled in player::hit() + + case AEP_EXTINGUISH: + for (int x = p->posx - 1; x <= p->posx + 1; x++) { + for (int y = p->posy - 1; y <= p->posy + 1; y++) { + m.adjust_field_age(point(x,y), fd_fire, -1); + } + } + + case AEP_HUNGER: + if (one_in(100)) { + p->hunger++; + } + break; + + case AEP_THIRST: + if (one_in(120)) { + p->thirst++; + } + break; + + case AEP_EVIL: + if (one_in(150)) { // Once every 15 minutes, on average + p->add_disease("evil", 300); + if (it->is_armor()) { + add_msg(_("You have an urge to wear the %s."), + it->tname().c_str()); + } else if (!wielded) { + add_msg(_("You have an urge to wield the %s."), + it->tname().c_str()); + } + } + break; + + case AEP_SCHIZO: + break; // Handled in player::suffer() + + case AEP_RADIOACTIVE: + if (one_in(4)) { + p->radiation++; + } + break; + + case AEP_STR_DOWN: + p->str_cur -= 3; + break; + + case AEP_DEX_DOWN: + p->dex_cur -= 3; + break; + + case AEP_PER_DOWN: + p->per_cur -= 3; + break; + + case AEP_INT_DOWN: + p->int_cur -= 3; + break; + + case AEP_ALL_DOWN: + p->str_cur -= 2; + p->dex_cur -= 2; + p->per_cur -= 2; + p->int_cur -= 2; + break; + + case AEP_SPEED_DOWN: + break; // Handled in player::current_speed() + } + } +} + +void game::add_artifact_messages(std::vector effects) +{ + int net_str = 0, net_dex = 0, net_per = 0, net_int = 0, net_speed = 0; + + for (int i = 0; i < effects.size(); i++) { + switch (effects[i]) { + case AEP_STR_UP: net_str += 4; break; + case AEP_DEX_UP: net_dex += 4; break; + case AEP_PER_UP: net_per += 4; break; + case AEP_INT_UP: net_int += 4; break; + case AEP_ALL_UP: net_str += 2; + net_dex += 2; + net_per += 2; + net_int += 2; break; + case AEP_STR_DOWN: net_str -= 3; break; + case AEP_DEX_DOWN: net_dex -= 3; break; + case AEP_PER_DOWN: net_per -= 3; break; + case AEP_INT_DOWN: net_int -= 3; break; + case AEP_ALL_DOWN: net_str -= 2; + net_dex -= 2; + net_per -= 2; + net_int -= 2; break; + + case AEP_SPEED_UP: net_speed += 20; break; + case AEP_SPEED_DOWN: net_speed -= 20; break; + + case AEP_IODINE: + break; // No message + + case AEP_SNAKES: + add_msg(_("Your skin feels slithery.")); + break; + + case AEP_INVISIBLE: + add_msg(_("You fade into invisibility!")); + break; + + case AEP_CLAIRVOYANCE: + add_msg(_("You can see through walls!")); + break; + + case AEP_SUPER_CLAIRVOYANCE: + add_msg(_("You can see through everything!")); + break; + + case AEP_STEALTH: + add_msg(_("Your steps stop making noise.")); + break; + + case AEP_GLOW: + add_msg(_("A glow of light forms around you.")); + break; + + case AEP_PSYSHIELD: + add_msg(_("Your mental state feels protected.")); + break; + + case AEP_RESIST_ELECTRICITY: + add_msg(_("You feel insulated.")); + break; + + case AEP_CARRY_MORE: + add_msg(_("Your back feels strengthened.")); + break; + + case AEP_HUNGER: + add_msg(_("You feel hungry.")); + break; + + case AEP_THIRST: + add_msg(_("You feel thirsty.")); + break; + + case AEP_EVIL: + add_msg(_("You feel an evil presence...")); + break; + + case AEP_SCHIZO: + add_msg(_("You feel a tickle of insanity.")); + break; + + case AEP_RADIOACTIVE: + add_msg(_("Your skin prickles with radiation.")); + break; + + case AEP_MUTAGENIC: + add_msg(_("You feel your genetic makeup degrading.")); + break; + + case AEP_ATTENTION: + add_msg(_("You feel an otherworldly attention upon you...")); + break; + + case AEP_FORCE_TELEPORT: + add_msg(_("You feel a force pulling you inwards.")); + break; + + case AEP_MOVEMENT_NOISE: + add_msg(_("You hear a rattling noise coming from inside yourself.")); + break; + + case AEP_BAD_WEATHER: + add_msg(_("You feel storms coming.")); + break; + } + } + + std::string stat_info = ""; + if (net_str != 0) { + stat_info += string_format(_("Str %s%d! "), + (net_str > 0 ? "+" : ""), net_str); + } + if (net_dex != 0) { + stat_info += string_format(_("Dex %s%d! "), + (net_dex > 0 ? "+" : ""), net_dex); + } + if (net_int != 0) { + stat_info += string_format(_("Int %s%d! "), + (net_int > 0 ? "+" : ""), net_int); + } + if (net_per != 0) { + stat_info += string_format(_("Per %s%d! "), + (net_per > 0 ? "+" : ""), net_per); + } + + if (stat_info.length() > 0) { + add_msg(stat_info.c_str()); + } + + if (net_speed != 0) { + add_msg(_("Speed %s%d! "), (net_speed > 0 ? "+" : ""), net_speed); + } +} diff --git a/game.h b/game.h index 78dd9e61f760c..01776b81d3149 100644 --- a/game.h +++ b/game.h @@ -246,13 +246,11 @@ class game faction* random_good_faction(); faction* random_evil_faction(); - itype* new_artifact(); - itype* new_natural_artifact(artifact_natural_property prop = ARTPROP_NULL); void process_artifact(item *it, player *p, bool wielded = false); void add_artifact_messages(std::vector effects); void peek(); - point look_debug(point pnt=point(-256,-256)); + point look_debug(); point look_around();// Look at nearby terrain ';' int list_items(); //List all items around the player int list_monsters(); //List all monsters around the player @@ -289,7 +287,6 @@ class game special_game_id gametype() const { return (gamemode) ? gamemode->id() : SGAME_NULL; } std::map itypes; - std::vector mtypes; std::map vtypes; std::vector traps; std::vector constructions; // The list of constructions @@ -342,10 +339,6 @@ class game bionic_id random_good_bionic() const; // returns a non-faulty, valid bionic - void load_artifacts(std::string worldname); // Load artifact data - // Needs to be called by main() before MAPBUFFER.load - void load_artifacts_from_file(std::ifstream *f); // Load artifact data - // Knockback functions: knock target at (tx,ty) along a line, either calculated // from source position (sx,sy) using force parameter or passed as an argument; // force determines how far target is knocked, if trajectory is calculated @@ -411,7 +404,6 @@ class game void init_fields(); void init_weather(); void init_overmap(); - void init_artifacts(); void init_morale(); void init_itypes(); // Initializes item types void init_skills() throw (std::string); diff --git a/gamemode.h b/gamemode.h index f7f6a170dbacf..30fc60170e00c 100644 --- a/gamemode.h +++ b/gamemode.h @@ -25,16 +25,16 @@ struct special_game virtual ~special_game() { return; }; virtual special_game_id id() { return SGAME_NULL; }; // init is run when the game begins - virtual bool init(game *g) { return true; }; + virtual bool init(game *) { return true; }; // per_turn is run every turn--before any player actions - virtual void per_turn(game *g) { }; + virtual void per_turn(game *) { }; // pre_action is run after a keypress, but before the game handles the action // It may modify the action, e.g. to cancel it - virtual void pre_action(game *g, action_id &act) { }; + virtual void pre_action(game *, action_id &) { }; // post_action is run after the game handles the action - virtual void post_action(game *g, action_id act) { }; + virtual void post_action(game *, action_id) { }; // game_over is run when the player dies (or the game otherwise ends) - virtual void game_over(game *g) { }; + virtual void game_over(game *) { }; }; @@ -72,7 +72,7 @@ struct tutorial_game : public special_game virtual void per_turn(game *g); virtual void pre_action(game *g, action_id &act); virtual void post_action(game *g, action_id act); - virtual void game_over(game *g) { }; + virtual void game_over(game *) { }; private: void add_message(game *g, tut_lesson lesson); diff --git a/gamesave.cpp b/gamesave.cpp index 08be45cac6e8e..d16cc109aa185 100644 --- a/gamesave.cpp +++ b/gamesave.cpp @@ -27,7 +27,6 @@ #include #include #include "debug.h" -#include "artifactdata.h" #include "weather.h" #include "savegame.h" @@ -253,7 +252,7 @@ void game::unserialize(std::ifstream & fin) { clear_zombies(); monster montmp; for( picojson::array::iterator pit = vdata->begin(); pit != vdata->end(); ++pit) { - montmp.json_load( *pit, &mtypes ); + montmp.json_load(*pit); add_zombie(montmp); } @@ -590,55 +589,70 @@ void game::unserialize_master(std::ifstream &fin) { popup_nowait(_("Cannot find loader for save data in old version %d, attempting to load as current version %d."),savegame_loading_version, savegame_version); } } - picojson::value pval; - fin >> pval; - std::string jsonerr = picojson::get_last_error(); - if ( ! jsonerr.empty() ) { - debugmsg("Bad save json\n%s", jsonerr.c_str() ); - } - picojson::object &data = pval.get(); - picoint(data, "next_mission_id", next_mission_id); - picoint(data, "next_faction_id", next_faction_id); - picoint(data, "next_npc_id", next_npc_id); - - picojson::array * vdata = pgetarray(data,"active_missions"); - if(vdata != NULL) { - for( picojson::array::iterator pit = vdata->begin(); pit != vdata->end(); ++pit) { - mission tmp; - tmp.json_load( *pit, this ); - active_missions.push_back(tmp); - } - } - - vdata = pgetarray(data,"factions"); - if(vdata != NULL) { - for( picojson::array::iterator pit = vdata->begin(); pit != vdata->end(); ++pit) { - faction tmp; - tmp.json_load( *pit, this ); - factions.push_back(tmp); + try { + JsonIn jsin(&fin); + jsin.start_object(); + while (!jsin.end_object()) { + std::string name = jsin.get_member_name(); + if (name == "next_mission_id") { + next_mission_id = jsin.get_int(); + } else if (name == "next_faction_id") { + next_faction_id = jsin.get_int(); + } else if (name == "next_npc_id") { + next_npc_id = jsin.get_int(); + } else if (name == "active_missions") { + jsin.start_array(); + while (!jsin.end_array()) { + mission mis; + JsonObject mis_json = jsin.get_object(); + mis.deserialize(mis_json); + active_missions.push_back(mis); + } + } else if (name == "factions") { + jsin.start_array(); + while (!jsin.end_array()) { + faction fac; + JsonObject fac_json = jsin.get_object(); + fac.deserialize(fac_json); + factions.push_back(fac); + } + } else { + // silently ignore anything else + jsin.skip_value(); + } } + } catch (std::string e) { + debugmsg("error loading master.gsav: %s", e.c_str()); } - } void game::serialize_master(std::ofstream &fout) { fout << "# version " << savegame_version << std::endl; - std::map data; - data["next_mission_id"] = pv ( next_mission_id ); - data["next_faction_id"] = pv ( next_faction_id ); - data["next_npc_id"] = pv ( next_npc_id ); - - std::vector vdata; - for (int i = 0; i < active_missions.size(); i++) { - vdata.push_back( pv( active_missions[i].json_save() ) ); - } - data["active_missions"] = pv( vdata ); - vdata.clear(); + try { + JsonOut json(&fout); + json.start_object(); + + json.member("next_mission_id", next_mission_id); + json.member("next_faction_id", next_faction_id); + json.member("next_npc_id", next_npc_id); + + json.member("active_missions"); + json.start_array(); + for (int i = 0; i < active_missions.size(); ++i) { + active_missions[i].serialize(json); + } + json.end_array(); - for (int i = 0; i < factions.size(); i++) { - vdata.push_back( pv( factions[i].json_save() ) ); + json.member("factions"); + json.start_array(); + for (int i = 0; i < factions.size(); ++i) { + factions[i].serialize(json); + } + json.end_array(); + + json.end_object(); + } catch (std::string e) { + debugmsg("error saving to master.gsav: %s", e.c_str()); } - data["factions"] = pv( vdata ); - vdata.clear(); - fout << pv( data ).serialize() << std::endl; } + diff --git a/iexamine.cpp b/iexamine.cpp index 042e5f07b0f82..ae9b0da30b445 100644 --- a/iexamine.cpp +++ b/iexamine.cpp @@ -19,8 +19,10 @@ #include #include -void iexamine::none(game *g, player *p, map *m, int examx, int examy) { - g->add_msg(_("That is a %s."), m->name(examx, examy).c_str()); +void iexamine::none(game *g, player *p, map *m, int examx, int examy) +{ + (void)p; //unused + g->add_msg(_("That is a %s."), m->name(examx, examy).c_str()); }; void iexamine::gaspump(game *g, player *p, map *m, int examx, int examy) { @@ -105,10 +107,14 @@ void iexamine::toilet(game *g, player *p, map *m, int examx, int examy) { } } -void iexamine::elevator(game *g, player *p, map *m, int examx, int examy){ - if (!query_yn(_("Use the %s?"),m->tername(examx, examy).c_str())) return; - int movez = (g->levz < 0 ? 2 : -2); - g->vertical_move( movez, false ); +void iexamine::elevator(game *g, player *p, map *m, int examx, int examy) +{ + (void)p; //unused + if (!query_yn(_("Use the %s?"), m->tername(examx, examy).c_str())) { + return; + } + int movez = (g->levz < 0 ? 2 : -2); + g->vertical_move( movez, false ); } void iexamine::controls_gate(game *g, player *p, map *m, int examx, int examy) { @@ -430,28 +436,30 @@ void iexamine::remove_fence_barbed(game *g, player *p, map *m, int examx, int ex p->moves -= 200; } -void iexamine::slot_machine(game *g, player *p, map *m, int examx, int examy) { - if (p->cash < 10) - g->add_msg(_("You need $10 to play.")); - else if (query_yn(_("Insert $10?"))) { - do { - if (one_in(5)) - popup(_("Three cherries... you get your money back!")); - else if (one_in(20)) { - popup(_("Three bells... you win $50!")); - p->cash += 40; // Minus the $10 we wagered - } else if (one_in(50)) { - popup(_("Three stars... you win $200!")); - p->cash += 190; - } else if (one_in(1000)) { - popup(_("JACKPOT! You win $5000!")); - p->cash += 4990; - } else { - popup(_("No win.")); - p->cash -= 10; - } - } while (p->cash >= 10 && query_yn(_("Play again?"))); - } +void iexamine::slot_machine(game *g, player *p, map *m, int examx, int examy) +{ + (void)m; (void)examx; (void)examy; //unused + if (p->cash < 10) { + g->add_msg(_("You need $10 to play.")); + } else if (query_yn(_("Insert $10?"))) { + do { + if (one_in(5)) { + popup(_("Three cherries... you get your money back!")); + } else if (one_in(20)) { + popup(_("Three bells... you win $50!")); + p->cash += 40; // Minus the $10 we wagered + } else if (one_in(50)) { + popup(_("Three stars... you win $200!")); + p->cash += 190; + } else if (one_in(1000)) { + popup(_("JACKPOT! You win $5000!")); + p->cash += 4990; + } else { + popup(_("No win.")); + p->cash -= 10; + } + } while (p->cash >= 10 && query_yn(_("Play again?"))); + } } void iexamine::safe(game *g, player *p, map *m, int examx, int examy) { @@ -473,33 +481,36 @@ void iexamine::safe(game *g, player *p, map *m, int examx, int examy) { } void iexamine::bulletin_board(game *g, player *p, map *m, int examx, int examy) { - basecamp *camp = m->camp_at(examx, examy); - if (camp && camp->board_x() == examx && camp->board_y() == examy) { - std::vector options; - options.push_back(_("Cancel")); - // Causes a warning due to being unused, but don't want to delete since - // it's clearly what's intened for future functionality. - //int choice = menu_vec(true, camp->board_name().c_str(), options) - 1; - } - else { - bool create_camp = m->allow_camp(examx, examy); - std::vector options; - if (create_camp) - options.push_back(_("Create camp")); - options.push_back(_("Cancel")); - // TODO: Other Bulletin Boards - int choice = menu_vec(true, _("Bulletin Board"), options) - 1; - if (choice >= 0 && choice < options.size()) { - if (options[choice] == _("Create camp")) { - // TODO: Allow text entry for name - m->add_camp(_("Home"), examx, examy); - } - } - } + (void)g; (void)p; //unused + basecamp *camp = m->camp_at(examx, examy); + if (camp && camp->board_x() == examx && camp->board_y() == examy) { + std::vector options; + options.push_back(_("Cancel")); + // Causes a warning due to being unused, but don't want to delete + // since it's clearly what's intened for future functionality. + //int choice = menu_vec(true, camp->board_name().c_str(), options) - 1; + } else { + bool create_camp = m->allow_camp(examx, examy); + std::vector options; + if (create_camp) { + options.push_back(_("Create camp")); + } + options.push_back(_("Cancel")); + // TODO: Other Bulletin Boards + int choice = menu_vec(true, _("Bulletin Board"), options) - 1; + if (choice >= 0 && choice < options.size()) { + if (options[choice] == _("Create camp")) { + // TODO: Allow text entry for name + m->add_camp(_("Home"), examx, examy); + } + } + } } -void iexamine::fault(game *g, player *p, map *m, int examx, int examy) { - popup(_("\ +void iexamine::fault(game *g, player *p, map *m, int examx, int examy) +{ + (void)g; (void)p; (void)m; (void)examx; (void)examy; //unused + popup(_("\ This wall is perfectly vertical. Odd, twisted holes are set in it, leading\n\ as far back into the solid rock as you can see. The holes are humanoid in\n\ shape, but with long, twisted, distended limbs.")); @@ -621,8 +632,8 @@ void iexamine::flower_poppy(game *g, player *p, map *m, int examx, int examy) { } m->furn_set(examx, examy, f_null); - m->spawn_item(examx, examy, "poppy_flower", 0); - m->spawn_item(examx, examy, "poppy_bud", 0); + m->spawn_item(examx, examy, "poppy_flower"); + m->spawn_item(examx, examy, "poppy_bud"); } void iexamine::fungus(game *g, player *p, map *m, int examx, int examy) { @@ -640,7 +651,7 @@ void iexamine::fungus(game *g, player *p, map *m, int examx, int examy) { g->add_msg(_("The %s is covered in tiny spores!"), g->zombie(mondex).name().c_str()); } - if (!g->zombie(mondex).make_fungus(g)) { + if (!g->zombie(mondex).make_fungus()) { g->kill_mon(mondex, false); } } else if (g->u.posx == i && g->u.posy == j) { @@ -741,7 +752,7 @@ void iexamine::dirtmound(game *g, player *p, map *m, int examx, int examy) { g->u.remove_weapon(); } } - m->spawn_item(examx, examy, seed_types[seed_index], g->turn, 1, 1); + m->spawn_item(examx, examy, seed_types[seed_index], 1, 1, g->turn); m->set(examx, examy, t_dirt, f_plant_seed); p->moves -= 500; g->add_msg(_("Planted %s"), seed_names[seed_index].c_str()); @@ -765,8 +776,8 @@ void iexamine::aggie_plant(game *g, player *p, map *m, int examx, int examy) { plantCount = 12; } - m->spawn_item(examx, examy, seedType.substr(5), g->turn, plantCount); - m->spawn_item(examx, examy, seedType, 0, 1, rng(plantCount / 4, plantCount / 2)); + m->spawn_item(examx, examy, seedType.substr(5), plantCount, 0, g->turn); + m->spawn_item(examx, examy, seedType, 1, rng(plantCount / 4, plantCount / 2)); p->moves -= 500; } @@ -780,7 +791,7 @@ void iexamine::aggie_plant(game *g, player *p, map *m, int examx, int examy) { m->i_at(examx, examy)[0].bday = 0; } p->use_charges("fertilizer_liquid", 1); - m->spawn_item(examx, examy, "fertilizer", 0, 1, 1); + m->spawn_item(examx, examy, "fertilizer", 1, 1); } } @@ -800,10 +811,10 @@ void iexamine::pick_plant(game *g, player *p, map *m, int examx, int examy, std: if (plantCount > 12) plantCount = 12; - m->spawn_item(examx, examy, itemType, g->turn, plantCount); + m->spawn_item(examx, examy, itemType, plantCount, 0, g->turn); if (seeds) { - m->spawn_item(examx, examy, "seed_" + itemType, g->turn, 1, rng(plantCount / 4, plantCount / 2)); + m->spawn_item(examx, examy, "seed_" + itemType, 1, rng(plantCount / 4, plantCount / 2), g->turn); } m->ter_set(examx, examy, (ter_id)new_ter); @@ -934,22 +945,22 @@ void iexamine::recycler(game *g, player *p, map *m, int examx, int examy) { for (int i = 0; i < num_lumps; i++) { - m->spawn_item(p->posx, p->posy, "steel_lump", 0); + m->spawn_item(p->posx, p->posy, "steel_lump"); } for (int i = 0; i < num_sheets; i++) { - m->spawn_item(p->posx, p->posy, "sheet_metal", 0); + m->spawn_item(p->posx, p->posy, "sheet_metal"); } for (int i = 0; i < num_chunks; i++) { - m->spawn_item(p->posx, p->posy, "steel_chunk", 0); + m->spawn_item(p->posx, p->posy, "steel_chunk"); } for (int i = 0; i < num_scraps; i++) { - m->spawn_item(p->posx, p->posy, "scrap", 0); + m->spawn_item(p->posx, p->posy, "scrap"); } } diff --git a/init.cpp b/init.cpp index 5f7c7b005f108..279ee476c12b0 100644 --- a/init.cpp +++ b/init.cpp @@ -17,6 +17,7 @@ #include "monstergenerator.h" #include "inventory.h" #include "tutorial.h" +#include "artifact.h" #include #include @@ -69,6 +70,7 @@ void init_data_mappings() { // TODO: make this actually load files from the named directory std::vector listfiles(std::string const &dirname) { + (void)dirname; //not used yet std::vector ret; ret.push_back("data/json/materials.json"); @@ -124,7 +126,7 @@ void load_object(JsonObject &jo) } } -void null_load_target(JsonObject &jo){} +void null_load_target(JsonObject &) {} void init_data_structures() { @@ -178,6 +180,7 @@ void init_data_structures() init_translation(); init_martial_arts(); init_inventory_categories(); + init_artifacts(); } void release_data_structures() diff --git a/input.cpp b/input.cpp index aff1c93859674..2d93dc36d1293 100644 --- a/input.cpp +++ b/input.cpp @@ -1,6 +1,6 @@ #include "cursesdef.h" #include "input.h" -#include "picojson.h" +#include "json.h" #include "output.h" #include "keypress.h" #include @@ -154,49 +154,32 @@ void input_manager::init() { init_keycode_mapping(); std::ifstream data_file; - picojson::value input_value; std::string file_name = "data/raw/keybindings.json"; - data_file.open(file_name.c_str()); + data_file.open(file_name.c_str(), std::ifstream::in | std::ifstream::binary); if(!data_file.good()) { throw "Could not read " + file_name; } - data_file >> input_value; - data_file.close(); - - if(!input_value.is()) { - throw file_name + "is not an array"; - } + JsonIn jsin(&data_file); //Crawl through once and create an entry for every definition - const picojson::array& root = input_value.get(); - - for (picojson::array::const_iterator entry = root.begin(); - entry != root.end(); ++entry) { - if( !(entry->is()) ){ - debugmsg("Invalid keybinding setting, entry not a JSON object"); - continue; - } - + jsin.start_array(); + while (!jsin.end_array()) { // JSON object representing the action - const picojson::value& action_object = *entry; + JsonObject action = jsin.get_object(); - const std::string& action_id = action_object.get("id").get(); - - std::string context = "default"; - if(action_object.contains("category")) { - context = action_object.get("category").get(); - } + const std::string action_id = action.get_string("id"); + actionID_to_name[action_id] = action.get_string("name", action_id); + const std::string context = action.get_string("category", "default"); // Iterate over the bindings JSON array - const picojson::array& keybindings = action_object.get("bindings").get(); - for (picojson::array::const_iterator subentry = keybindings.begin(); - subentry != keybindings.end(); ++subentry) { - - const picojson::value& keybinding = *subentry; - const std::string& input_method = keybinding.get("input_method").get(); + JsonArray bindings = action.get_array("bindings"); + const bool defaultcontext = (context == "default"); + while (bindings.has_more()) { + JsonObject keybinding = bindings.next_object(); + std::string input_method = keybinding.get_string("input_method"); input_event new_event; if(input_method == "keyboard") { new_event.type = CATA_INPUT_KEYBOARD; @@ -206,33 +189,29 @@ void input_manager::init() { new_event.type = CATA_INPUT_MOUSE; } - if(keybinding.get("key").is()) { - const std::string& key = keybinding.get("key").get(); - - new_event.sequence.push_back(inp_mngr.get_keycode(key)); - } else if(keybinding.get("key").is()) { - picojson::array keys = keybinding.get("key").get(); - for(int i=0; i(); - - new_event.sequence.push_back(inp_mngr.get_keycode(next_key)); + if (keybinding.has_array("key")) { + JsonArray keys = keybinding.get_array("key"); + while (keys.has_more()) { + new_event.sequence.push_back( + get_keycode(keys.next_string()) + ); } + } else { // assume string if not array, and throw if not string + new_event.sequence.push_back( + get_keycode(keybinding.get_string("key")) + ); } - if(context == "default") { + if (defaultcontext) { action_to_input[action_id].push_back(new_event); } else { action_contexts[context][action_id].push_back(new_event); } } + } - if(!action_object.contains("name")) { - actionID_to_name[action_id] = action_id; - } else { - actionID_to_name[action_id] = action_object.get("name").get(); + data_file.close(); } - } -} void input_manager::add_keycode_pair(long ch, const std::string& name) { keycode_to_keyname[ch] = name; diff --git a/inventory.h b/inventory.h index 76c152872d23b..fb03d17341bec 100644 --- a/inventory.h +++ b/inventory.h @@ -2,6 +2,8 @@ #define _INVENTORY_H_ #include "item.h" +#include "artifact.h" + #include #include #include diff --git a/inventory_ui.cpp b/inventory_ui.cpp index 91443ce9d7b86..3659475594f80 100644 --- a/inventory_ui.cpp +++ b/inventory_ui.cpp @@ -117,7 +117,7 @@ void print_inv_statics(game *g, WINDOW* w_inv, std::string title, mvwprintz(w_inv, 3, 45, c_white, "%c + %s", g->u.weapon.invlet, g->u.weapname().c_str()); else - mvwprintz(w_inv, 3, 45, g->u.weapon.color_in_inventory(&(g->u)), "%c - %s", + mvwprintz(w_inv, 3, 45, g->u.weapon.color_in_inventory(), "%c - %s", g->u.weapon.invlet, g->u.weapname().c_str()); } else mvwprintz(w_inv, 3, 45, c_ltgray, g->u.weapname().c_str()); @@ -199,7 +199,7 @@ char game::inv(inventory& inv, std::string title) item& it = slice[cur_it]->front(); if(cur_it==selected) selected_char=(int)it.invlet; mvwputch (w_inv, cur_line, 0, (cur_it == selected ? h_white : c_white), it.invlet); - mvwprintz(w_inv, cur_line, 1, (cur_it == selected ? h_white : it.color_in_inventory(&u) ), " %s", + mvwprintz(w_inv, cur_line, 1, (cur_it == selected ? h_white : it.color_in_inventory() ), " %s", it.tname(this).c_str()); if (slice[cur_it]->size() > 1) wprintw(w_inv, " x %d", slice[cur_it]->size()); diff --git a/item.cpp b/item.cpp index b1fb71edaa513..89b1501522b26 100644 --- a/item.cpp +++ b/item.cpp @@ -744,14 +744,13 @@ nc_color item::color(player *u) const return ret; } -nc_color item::color_in_inventory(player *u) +nc_color item::color_in_inventory() { // Items in our inventory get colorized specially - nc_color ret = c_white; - if (active && !is_food() && !is_food_container()) - ret = c_yellow; - - return ret; + if (active && !is_food() && !is_food_container()) { + return c_yellow; + } + return c_white; } std::string item::tname(game *g) @@ -1092,6 +1091,7 @@ bool item::has_quality(std::string quality_id) const { bool item::has_quality(std::string quality_id, int quality_value) const { // TODO: actually implement this >:( + (void)quality_id; (void)quality_value; //unused grrr bool ret = false; if(type->qualities.size() > 0){ @@ -1100,7 +1100,7 @@ bool item::has_quality(std::string quality_id, int quality_value) const { return ret; } -bool item::has_technique(matec_id tech, player *p) +bool item::has_technique(matec_id tech) { return type->techniques.count(tech); } @@ -2264,10 +2264,11 @@ bool item::reload(player &u, char ammo_invlet) return false; } -void item::use(player &u) +void item::use() { - if (charges > 0) + if (charges > 0) { charges--; + } } bool item::burn(int amount) diff --git a/item.h b/item.h index 6361a018fc6a0..ec601a42a2a44 100644 --- a/item.h +++ b/item.h @@ -74,9 +74,9 @@ class item item in_its_container(std::map *itypes); nc_color color(player *u) const; - nc_color color_in_inventory(player *u); + nc_color color_in_inventory(); std::string tname(game *g = NULL); // g needed for rotten-test - void use(player &u); + void use(); bool burn(int amount = 1); // Returns true if destroyed // Firearm specifics @@ -122,7 +122,7 @@ class item bool has_flag(std::string f) const; bool has_quality(std::string quality_id) const; bool has_quality(std::string quality_id, int quality_value) const; - bool has_technique(std::string t, player *p = NULL); + bool has_technique(std::string t); int has_gunmod(itype_id type); item* active_gunmod(); item const* inspect_active_gunmod() const; diff --git a/item_factory.h b/item_factory.h index 112fbb34d7ef2..29de959c07cb5 100644 --- a/item_factory.h +++ b/item_factory.h @@ -5,7 +5,6 @@ #include "itype.h" #include "item.h" #include "color.h" -#include "picojson.h" #include "json.h" #include "item_group.h" #include "iuse.h" diff --git a/itype.h b/itype.h index d5691e583617c..d67429504a1c5 100644 --- a/itype.h +++ b/itype.h @@ -8,7 +8,6 @@ #include "bodypart.h" #include "skill.h" #include "bionics.h" -#include "artifact.h" #include "picojson.h" #include "rng.h" #include "material.h" @@ -276,7 +275,6 @@ struct it_var_veh_part: public itype char psym, nc_color pcolor, std::string pm1, std::string pm2, unsigned short pvolume, unsigned int pweight, signed char pmelee_dam, signed char pmelee_cut, signed char pm_to_hit, - unsigned effects, unsigned int big_min, unsigned int big_max, @@ -702,219 +700,4 @@ struct it_stationary : public itype } }; -struct it_artifact_tool : public it_tool -{ - art_charge charge_type; - std::vector effects_wielded; - std::vector effects_activated; - std::vector effects_carried; - - virtual bool is_artifact() { return true; } - virtual picojson::value save_data() - { - std::map data; - - data[std::string("type")] = picojson::value("artifact_tool"); - - // generic data - data[std::string("id")] = picojson::value(id); - data[std::string("price")] = picojson::value(price); - data[std::string("name")] = picojson::value(name); - data[std::string("description")] = picojson::value(description); - data[std::string("sym")] = picojson::value(sym); - data[std::string("color")] = picojson::value(color_to_int(color)); - data[std::string("m1")] = picojson::value(m1); - data[std::string("m2")] = picojson::value(m2); - data[std::string("volume")] = picojson::value(volume); - data[std::string("weight")] = picojson::value(weight); - data[std::string("id")] = picojson::value(id); - data[std::string("melee_dam")] = picojson::value(melee_dam); - data[std::string("melee_cut")] = picojson::value(melee_cut); - data[std::string("m_to_hit")] = picojson::value(m_to_hit); - - std::vector tags_json; - for(std::set::iterator it = item_tags.begin(); - it != item_tags.end(); ++it) - { - tags_json.push_back(picojson::value(*it)); - } - data[std::string("item_flags")] = picojson::value(tags_json); - - std::vector techniques_json; - for(std::set::iterator it = techniques.begin(); - it != techniques.end(); ++it) - { - techniques_json.push_back(picojson::value(*it)); - } - data[std::string("techniques")] = - picojson::value(techniques_json); - - // tool data - data[std::string("ammo")] = picojson::value(ammo); - data[std::string("max_charges")] = picojson::value(max_charges); - data[std::string("def_charges")] = picojson::value(def_charges); - data[std::string("charges_per_use")] = picojson::value(charges_per_use); - data[std::string("turns_per_charge")] = picojson::value(turns_per_charge); - data[std::string("revert_to")] = picojson::value(revert_to); - - // artifact data - data[std::string("charge_type")] = picojson::value(charge_type); - - std::vector effects_wielded_json; - for(std::vector::iterator it = effects_wielded.begin(); - it != effects_wielded.end(); ++it) - { - effects_wielded_json.push_back(picojson::value(*it)); - } - data[std::string("effects_wielded")] = - picojson::value(effects_wielded_json); - - std::vector effects_activated_json; - for(std::vector::iterator it = - effects_activated.begin(); - it != effects_activated.end(); ++it) - { - effects_activated_json.push_back(picojson::value(*it)); - } - data[std::string("effects_activated")] = - picojson::value(effects_activated_json); - - std::vector effects_carried_json; - for(std::vector::iterator it = effects_carried.begin(); - it != effects_carried.end(); ++it) - { - effects_carried_json.push_back(picojson::value(*it)); - } - data[std::string("effects_carried")] = - picojson::value(effects_carried_json); - - return picojson::value(data); - } - - it_artifact_tool() :it_tool(){ - ammo = "NULL"; - price = 0; - def_charges = 0; - charges_per_use = 1; - charge_type = ARTC_NULL; - turns_per_charge = 0; - revert_to = "null"; - use = &iuse::artifact; - }; - - it_artifact_tool(std::string pid, unsigned int pprice, std::string pname, - std::string pdes, char psym, nc_color pcolor, std::string pm1, - std::string pm2, unsigned short pvolume, unsigned int pweight, - signed char pmelee_dam, signed char pmelee_cut, - signed char pm_to_hit, std::set pitem_tags, - - unsigned int pmax_charges, unsigned int pdef_charges, - unsigned char pcharges_per_use, - unsigned char pturns_per_charge, - ammotype pammo, itype_id prevert_to) - -:it_tool(pid, pprice, pname, pdes, psym, pcolor, pm1, pm2, SOLID, - pvolume, pweight, pmelee_dam, pmelee_cut, pm_to_hit, - pmax_charges, pdef_charges, pcharges_per_use, pturns_per_charge, - pammo, prevert_to, &iuse::artifact) - { - charge_type = ARTC_NULL; - item_tags = pitem_tags; - artifact_itype_ids.push_back(pid); - }; -}; - -struct it_artifact_armor : public it_armor -{ - std::vector effects_worn; - - virtual bool is_artifact() { return true; } - - virtual picojson::value save_data() - { - std::map data; - - data[std::string("type")] = picojson::value("artifact_armor"); - - // generic data - data[std::string("id")] = picojson::value(id); - data[std::string("price")] = picojson::value(price); - data[std::string("name")] = picojson::value(name); - data[std::string("description")] = picojson::value(description); - data[std::string("sym")] = picojson::value(sym); - data[std::string("color")] = picojson::value(color_to_int(color)); - data[std::string("m1")] = picojson::value(m1); - data[std::string("m2")] = picojson::value(m2); - data[std::string("volume")] = picojson::value(volume); - data[std::string("weight")] = picojson::value(weight); - data[std::string("id")] = picojson::value(id); - data[std::string("melee_dam")] = picojson::value(melee_dam); - data[std::string("melee_cut")] = picojson::value(melee_cut); - data[std::string("m_to_hit")] = picojson::value(m_to_hit); - - std::vector tags_json; - for(std::set::iterator it = item_tags.begin(); - it != item_tags.end(); ++it) - { - tags_json.push_back(picojson::value(*it)); - } - data[std::string("item_flags")] = picojson::value(tags_json); - - std::vector techniques_json; - for(std::set::iterator it = techniques.begin(); - it != techniques.end(); ++it) - { - techniques_json.push_back(picojson::value(*it)); - } - data[std::string("techniques")] = - picojson::value(techniques_json); - - // armor data - data[std::string("covers")] = picojson::value(covers); - data[std::string("encumber")] = picojson::value(encumber); - data[std::string("coverage")] = picojson::value(coverage); - data[std::string("material_thickness")] = picojson::value(thickness); - data[std::string("env_resist")] = picojson::value(env_resist); - data[std::string("warmth")] = picojson::value(warmth); - data[std::string("storage")] = picojson::value(storage); - data[std::string("power_armor")] = picojson::value(power_armor); - - // artifact data - std::vector effects_worn_json; - for(std::vector::iterator it = effects_worn.begin(); - it != effects_worn.end(); ++it) - { - effects_worn_json.push_back(picojson::value(*it)); - } - data[std::string("effects_worn")] = - picojson::value(effects_worn_json); - - return picojson::value(data); - } - - it_artifact_armor() :it_armor() - { - price = 0; - }; - - it_artifact_armor(std::string pid, unsigned int pprice, std::string pname, - std::string pdes, char psym, nc_color pcolor, std::string pm1, - std::string pm2, unsigned short pvolume, unsigned int pweight, - signed char pmelee_dam, signed char pmelee_cut, - signed char pm_to_hit, std::set pitem_tags, - - unsigned char pcovers, signed char pencumber, - unsigned char pcoverage, unsigned char pthickness, - unsigned char penv_resist, signed char pwarmth, - unsigned char pstorage) -:it_armor(pid, pprice, pname, pdes, psym, pcolor, pm1, pm2, - pvolume, pweight, pmelee_dam, pmelee_cut, pm_to_hit, - pcovers, pencumber, pcoverage, pthickness, penv_resist, pwarmth, - pstorage) - { - item_tags = pitem_tags; - artifact_itype_ids.push_back(pid); - }; -}; - #endif diff --git a/itypedef.cpp b/itypedef.cpp index 8169d1225e394..71c1c02cee661 100644 --- a/itypedef.cpp +++ b/itypedef.cpp @@ -59,72 +59,72 @@ void game::init_itypes () "A fake item. If you are reading this it's a bug! (itypdef:apparatus)", '$', c_red, "null", "null", PNULL, 0, 0, 0, 0, 0); -#define VAR_VEH_PART(id, name,price,sym,color,mat1,mat2,volume,wgt,dam,cut,to_hit,\ - flags, bigmin, bigmax, bigaspect, des)\ -itypes[id]=new it_var_veh_part(id,price,name,des,sym,\ -color,mat1,mat2,volume,wgt,dam,cut,to_hit,flags, bigmin, bigmax, bigaspect) +#define VAR_VEH_PART(id, name, price, sym, color, mat1, mat2, volume, wgt,\ + dam, cut, to_hit, bigmin, bigmax, bigaspect, des)\ +itypes[id]=new it_var_veh_part(id, price, name, des, sym, color, mat1, mat2,\ + volume, wgt, dam, cut, to_hit, bigmin, bigmax, bigaspect) //"wheel", "wheel_wide", "wheel_bicycle", "wheel_motorbike", "wheel_small", // NAME RAR PRC SYM COLOR MAT1 MAT2 VAR_VEH_PART("wheel", _("wheel"), 100, ']', c_dkgray, "steel", "plastic", -// VOL WGT DAM CUT HIT FLAGS BIGNESS_MIN BIGNESS_MAX BIGNESS_ASPECT - 40, 8845, 12, 0, -1, 0, 13, 20, BIGNESS_WHEEL_DIAMETER, _("\ -A car wheel")); +// VOL WGT DAM CUT HIT BIGNESS_MIN BIGNESS_MAX BIGNESS_ASPECT + 40, 8845, 12, 0, -1, 13, 20, BIGNESS_WHEEL_DIAMETER, + _("A car wheel")); // NAME RAR PRC SYM COLOR MAT1 MAT2 VAR_VEH_PART("wheel_wide", _("wide wheel"), 340, ']', c_dkgray, "steel", "plastic", -// VOL WGT DAM CUT HIT FLAGS BIGNESS_MIN BIGNESS_MAX ASPECT - 70,22600, 17, 0, -1, 0, 17, 36, BIGNESS_WHEEL_DIAMETER, _("\ -A wide wheel. \\o/ This wide.")); +// VOL WGT DAM CUT HIT BIGNESS_MIN BIGNESS_MAX BIGNESS_ASPECT + 70,22600, 17, 0, -1, 17, 36, BIGNESS_WHEEL_DIAMETER, + _("A wide wheel. \\o/ This wide.")); // NAME RAR PRC SYM COLOR MAT1 MAT2 VAR_VEH_PART("wheel_bicycle", _("bicycle wheel"), 40, ']', c_dkgray, "steel", "plastic", -// VOL WGT DAM CUT HIT FLAGS BIGNESS_MIN BIGNESS_MAX ASPECT - 28,1500, 8, 0, -1, 0, 9, 18, BIGNESS_WHEEL_DIAMETER, _("\ -A bicycle wheel")); +// VOL WGT DAM CUT HIT BIGNESS_MIN BIGNESS_MAX BIGNESS_ASPECT + 28,1500, 8, 0, -1, 9, 18, BIGNESS_WHEEL_DIAMETER, + _("A bicycle wheel")); // NAME RAR PRC SYM COLOR MAT1 MAT2 VAR_VEH_PART("wheel_motorbike", _("motorbike wheel"), 140, ']', c_dkgray, "steel", "plastic", -// VOL WGT DAM CUT HIT FLAGS BIGNESS_MIN BIGNESS_MAX ASPECT - 33,5443, 10, 0, -1, 0, 9, 14, BIGNESS_WHEEL_DIAMETER, _("\ -A motorbike wheel")); +// VOL WGT DAM CUT HIT BIGNESS_MIN BIGNESS_MAX BIGNESS_ASPECT + 33,5443, 10, 0, -1, 9, 14, BIGNESS_WHEEL_DIAMETER, + _("A motorbike wheel")); // NAME RAR PRC SYM COLOR MAT1 MAT2 VAR_VEH_PART("wheel_small", _("small wheel"),140, ']', c_dkgray, "steel", "plastic", -// VOL WGT DAM CUT HIT FLAGS BIGNESS_MIN BIGNESS_MAX ASPECT - 9, 2722, 10, 0, -1, 0, 6, 14, BIGNESS_WHEEL_DIAMETER, _("\ -A pretty small wheel. Probably from one of those segway things.\ +// VOL WGT DAM CUT HIT BIGNESS_MIN BIGNESS_MAX BIGNESS_ASPECT + 9, 2722, 10, 0, -1, 6, 14, BIGNESS_WHEEL_DIAMETER, + _("A pretty small wheel. Probably from one of those segway things.\ It is not very menacing.")); VAR_VEH_PART("wheel_caster", _("casters"),140, ']', c_dkgray, "steel", "plastic", -// VOL WGT DAM CUT HIT FLAGS BIGNESS_MIN BIGNESS_MAX ASPECT - 5, 1500, 6, 0, -1, 0, 4, 6, BIGNESS_WHEEL_DIAMETER, _("\ -A set of casters, like on a shopping cart.")); +// VOL WGT DAM CUT HIT BIGNESS_MIN BIGNESS_MAX BIGNESS_ASPECT + 5, 1500, 6, 0, -1, 4, 6, BIGNESS_WHEEL_DIAMETER, + _("A set of casters, like on a shopping cart.")); // NAME RAR PRC SYM COLOR MAT1 MAT2 VAR_VEH_PART("1cyl_combustion", _("1-cylinder engine"), 100, ':', c_ltcyan, "iron", "null", -// VOL WGT DAM CUT HIT FLAGS 0BIGNESS_MIN BIGNESS_MAX ASPECT - 6, 20000, 4, 0, -1, 0, 28, 75, BIGNESS_ENGINE_DISPLACEMENT, _("\ +// VOL WGT DAM CUT HIT BIGNESS_MIN BIGNESS_MAX BIGNESS_ASPECT + 6, 20000, 4, 0, -1, 28, 75, BIGNESS_ENGINE_DISPLACEMENT, _("\ A single-cylinder 4-stroke combustion engine.")); // NAME RAR PRC SYM COLOR MAT1 MAT2 VAR_VEH_PART("v2_combustion", _("V-twin engine"), 100, ':', c_ltcyan, "iron", "null", -// VOL WGT DAM CUT HIT FLAGS BIGNESS_MIN BIGNESS_MAX ASPECT - 6, 45000, 4, 0, -1, 0, 65, 260, BIGNESS_ENGINE_DISPLACEMENT, _("\ +// VOL WGT DAM CUT HIT BIGNESS_MIN BIGNESS_MAX BIGNESS_ASPECT + 6, 45000, 4, 0, -1, 65, 260, BIGNESS_ENGINE_DISPLACEMENT, _("\ A 2-cylinder 4-stroke combustion engine.")); // NAME RAR PRC SYM COLOR MAT1 MAT2 VAR_VEH_PART("i4_combustion", _("Inline-4 engine"), 150, ':', c_ltcyan, "iron", "null", -// VOL WGT DAM CUT HIT FLAGS BIGNESS_MIN BIGNESS_MAX ASPECT - 6, 70000, 8, 0, -2, 0, 220, 350, BIGNESS_ENGINE_DISPLACEMENT, _("\ +// VOL WGT DAM CUT HIT BIGNESS_MIN BIGNESS_MAX BIGNESS_ASPECT + 6, 70000, 8, 0, -2, 220, 350, BIGNESS_ENGINE_DISPLACEMENT, _("\ A small, yet powerful 4-cylinder combustion engine.")); // NAME RAR PRC SYM COLOR MAT1 MAT2 VAR_VEH_PART("v6_combustion", _("V6 engine"), 180, ':', c_ltcyan, "iron", "null", -// VOL WGT DAM CUT HIT FLAGS BIGNESS_MIN BIGNESS_MAX ASPECT - 14,100000, 12, 0, -3, 0, 250, 520, BIGNESS_ENGINE_DISPLACEMENT, _("\ -A powerful 6-cylinder combustion engine.")); +// VOL WGT DAM CUT HIT BIGNESS_MIN BIGNESS_MAX BIGNESS_ASPECT + 14,100000, 12, 0, -3, 250, 520, BIGNESS_ENGINE_DISPLACEMENT, + _("A powerful 6-cylinder combustion engine.")); // NAME RAR PRC SYM COLOR MAT1 MAT2 VAR_VEH_PART("v8_combustion", _("V8 engine"), 250, ':', c_ltcyan, "iron", "null", -// VOL WGT DAM CUT HIT FLAGS BIGNESS_MIN BIGNESS_MAX ASPECT - 25,144000, 15, 0, -5, 0, 380, 700, BIGNESS_ENGINE_DISPLACEMENT, _("\ -A large and very powerful 8-cylinder combustion engine.")); +// VOL WGT DAM CUT HIT BIGNESS_MIN BIGNESS_MAX BIGNESS_ASPECT + 25,144000, 15, 0, -5, 380, 700, BIGNESS_ENGINE_DISPLACEMENT, + _("A large and very powerful 8-cylinder combustion engine.")); // GUNS // ammo_type matches one of the ammo_types above. diff --git a/iuse.cpp b/iuse.cpp index f25c4e900142d..5e85fe5537b8d 100644 --- a/iuse.cpp +++ b/iuse.cpp @@ -27,6 +27,7 @@ // Return false if we weren't able to use the item. static bool use_fire(game *g, player *p, item *it) { + (void)it; //unused if (!p->use_charges_if_avail("fire", 1)) { g->add_msg_if_player(p, _("You need a source of flame!")); @@ -38,6 +39,7 @@ static bool use_fire(game *g, player *p, item *it) static bool item_inscription( game *g, player *p, item *cut, std::string verb, std::string gerund, bool carveable) { + (void)p; //unused if (!cut->made_of(SOLID)) { std::string lower_verb = verb; std::transform(lower_verb.begin(), lower_verb.end(), lower_verb.begin(), ::tolower); @@ -127,7 +129,7 @@ int iuse::sewage(game *g, player *p, item *it, bool t) int iuse::honeycomb(game *g, player *p, item *it, bool t) { - g->m.spawn_item(p->posx, p->posy, "wax",0, 2); + g->m.spawn_item(p->posx, p->posy, "wax", 2); return it->type->charges_to_use(); } @@ -629,7 +631,7 @@ int iuse::fungicide(game *g, player *p, item *it, bool t) { g->add_msg(_("The %s is covered in tiny spores!"), g->zombie(zid).name().c_str()); } - if (!g->zombie(zid).make_fungus(g)) { + if (!g->zombie(zid).make_fungus()) { g->kill_mon(zid); } } else { @@ -1494,8 +1496,8 @@ int iuse::hammer(game *g, player *p, item *it, bool t) return 0; } p->moves -= 500; - g->m.spawn_item(p->posx, p->posy, "nail", 0, 0, nails); - g->m.spawn_item(p->posx, p->posy, "2x4", 0, boards); + g->m.spawn_item(p->posx, p->posy, "nail", 0, nails); + g->m.spawn_item(p->posx, p->posy, "2x4", boards); g->m.ter_set(x, y, newter); return it->type->charges_to_use(); } @@ -2379,8 +2381,8 @@ int iuse::crowbar(game *g, player *p, item *it, bool t) p->practice(g->turn, "carpentry", 1); } p->moves -= 500; - g->m.spawn_item(p->posx, p->posy, "nail", 0, 0, nails); - g->m.spawn_item(p->posx, p->posy, "2x4", 0, boards); + g->m.spawn_item(p->posx, p->posy, "nail", 0, nails); + g->m.spawn_item(p->posx, p->posy, "2x4", boards); g->m.ter_set(dirx, diry, newter); return it->type->charges_to_use(); } @@ -2399,7 +2401,7 @@ int iuse::crowbar(game *g, player *p, item *it, bool t) g->sound(dirx, diry, 12, _("crunch!")); } if ( type == t_manhole_cover ) { - g->m.spawn_item(dirx, diry, "manhole_cover", 0); + g->m.spawn_item(dirx, diry, "manhole_cover"); } if ( type == t_door_locked_alarm ) { g->u.add_memorial_log(_("Set off an alarm.")); @@ -2415,9 +2417,9 @@ int iuse::crowbar(game *g, player *p, item *it, bool t) g->add_msg_if_player(p,_("You break the glass.")); g->sound(dirx, diry, 24, _("glass breaking!")); g->m.ter_set(dirx, diry, t_window_frame); - g->m.spawn_item(dirx, diry, "sheet", 0, 2); - g->m.spawn_item(dirx, diry, "stick", 0); - g->m.spawn_item(dirx, diry, "string_36", 0); + g->m.spawn_item(dirx, diry, "sheet", 2); + g->m.spawn_item(dirx, diry, "stick"); + g->m.spawn_item(dirx, diry, "string_36"); return it->type->charges_to_use(); } } @@ -4759,8 +4761,8 @@ int iuse::hacksaw(game *g, player *p, item *it, bool t) p->moves -= 500; g->m.furn_set(dirx, diry, f_null); g->sound(dirx, diry, 15,_("grnd grnd grnd")); - g->m.spawn_item(p->posx, p->posy, "pipe", 0, rng(1, 3)); - g->m.spawn_item(p->posx, p->posy, "steel_chunk", 0); + g->m.spawn_item(p->posx, p->posy, "pipe", rng(1, 3)); + g->m.spawn_item(p->posx, p->posy, "steel_chunk"); return it->type->charges_to_use(); } @@ -4772,15 +4774,15 @@ int iuse::hacksaw(game *g, player *p, item *it, bool t) p->moves -= 500; g->m.ter_set(dirx, diry, t_dirt); g->sound(dirx, diry, 15,_("grnd grnd grnd")); - g->m.spawn_item(dirx, diry, "pipe", 0, 6); - g->m.spawn_item(dirx, diry, "wire", 0, 20); + g->m.spawn_item(dirx, diry, "pipe", 6); + g->m.spawn_item(dirx, diry, "wire", 20); break; case old_t_chainfence_posts: p->moves -= 500; g->m.ter_set(dirx, diry, t_dirt); g->sound(dirx, diry, 15,_("grnd grnd grnd")); - g->m.spawn_item(dirx, diry, "pipe", 0, 6); + g->m.spawn_item(dirx, diry, "pipe", 6); break; case old_t_bars: @@ -4790,12 +4792,12 @@ int iuse::hacksaw(game *g, player *p, item *it, bool t) g->m.ter_set(dirx, diry, t_sewage); p->moves -= 1000; g->sound(dirx, diry, 15,_("grnd grnd grnd")); - g->m.spawn_item(p->posx, p->posy, "pipe", 0, 3); + g->m.spawn_item(p->posx, p->posy, "pipe", 3); } else if (g->m.ter(p->posx, p->posy)){ g->m.ter_set(dirx, diry, t_floor); p->moves -= 500; g->sound(dirx, diry, 15,_("grnd grnd grnd")); - g->m.spawn_item(p->posx, p->posy, "pipe", 0, 3); + g->m.spawn_item(p->posx, p->posy, "pipe", 3); } break; @@ -5295,12 +5297,12 @@ if (dirx == p->posx && diry == p->posy) { p->moves -= 100; g->m.ter_set(dirx, diry, t_chaingate_c); g->sound(dirx, diry, 5, _("Gachunk!")); - g->m.spawn_item(p->posx, p->posy, "scrap", 0, 3); + g->m.spawn_item(p->posx, p->posy, "scrap", 3); } else if (g->m.ter(dirx, diry) == t_chainfence_v || g->m.ter(dirx, diry) == t_chainfence_h) { p->moves -= 500; g->m.ter_set(dirx, diry, t_chainfence_posts); g->sound(dirx, diry, 5,_("Snick, snick, gachunk!")); - g->m.spawn_item(dirx, diry, "wire", 0, 20); + g->m.spawn_item(dirx, diry, "wire", 20); } else { g->add_msg(_("You can't cut that.")); return 0; @@ -5779,7 +5781,7 @@ int iuse::spray_can(game *g, player *p, item *it, bool t) } else { - if(g->m.add_graffiti(g, p->posx, p->posy, message)) + if(g->m.add_graffiti(p->posx, p->posy, message)) { g->add_msg( ismarker? diff --git a/json.cpp b/json.cpp index 0f62bdc4bc302..3758253a25326 100644 --- a/json.cpp +++ b/json.cpp @@ -11,6 +11,8 @@ #include #include #include +#include // ensure user's locale doesn't interfere with output + #define STRICT_JSON true /* JSON parsing and serialization tools for Cataclysm-DDA @@ -139,6 +141,16 @@ bool JsonObject::has_member(const std::string &name) return (bool)verify_position(name, false); } +std::set JsonObject::get_member_names() +{ + std::set ret; + for (std::map::iterator it = positions.begin(); + it != positions.end(); ++it) { + ret.insert(it->first); + } + return ret; +} + std::string JsonObject::line_number() { jsin->seek(start); @@ -223,6 +235,26 @@ JsonArray JsonObject::get_array(const std::string &name) return JsonArray(jsin); } +std::vector JsonObject::get_int_array(const std::string &name) +{ + JsonArray ja = get_array(name); + std::vector ret; + while (ja.has_more()) { + ret.push_back(ja.next_int()); + } + return ret; +} + +std::vector JsonObject::get_string_array(const std::string &name) +{ + JsonArray ja = get_array(name); + std::vector ret; + while (ja.has_more()) { + ret.push_back(ja.next_string()); + } + return ret; +} + JsonObject JsonObject::get_object(const std::string &name) { int pos = verify_position(name); @@ -394,6 +426,13 @@ JsonArray::JsonArray(const JsonArray &ja) strict = ja.strict; } +void JsonArray::finish() +{ + if (jsin && jsin->good()) { + jsin->seek(end); + } +} + bool JsonArray::has_more() { return (index >= 0 && index < positions.size()); @@ -1298,3 +1337,182 @@ std::string JsonIn::line_number(int offset_modifier) ret << "line " << line << ":" << (offset + offset_modifier); return ret.str(); } + + +/* class JsonOut + * represents an ostream of JSON data, + * allowing easy serialization of c++ datatypes. + */ +JsonOut::JsonOut(std::ostream *s) +{ + stream = s; + need_separator = false; + // ensure user's locale doesn't interfere with number format + stream->imbue(std::locale::classic()); + // scientific format for floating-point numbers + stream->setf(std::ostream::scientific, std::ostream::floatfield); + // it's already decimal, but set it anyway + stream->setf(std::ostream::dec, std::ostream::basefield); + // could also set showbase and showpoint, + // but it currently doesn't matter. +} + +void JsonOut::write_separator() +{ + stream->put(','); + need_separator = false; +} + +void JsonOut::write_member_separator() +{ + stream->put(':'); + need_separator = false; +} + +void JsonOut::start_object() +{ + if (need_separator) { + write_separator(); + } + stream->put('{'); + need_separator = false; +} + +void JsonOut::end_object() +{ + stream->put('}'); + need_separator = true; +} + +void JsonOut::start_array() +{ + if (need_separator) { + write_separator(); + } + stream->put('['); + need_separator = false; +} + +void JsonOut::end_array() +{ + stream->put(']'); + need_separator = true; +} + +void JsonOut::write_null() +{ + if (need_separator) { + write_separator(); + } + stream->write("null", 4); + need_separator = true; +} + +void JsonOut::write(const bool &b) +{ + if (need_separator) { + write_separator(); + } + if (b) { + stream->write("true", 4); + } else { + stream->write("false", 5); + } + need_separator = true; +} + +void JsonOut::write(const int &i) +{ + if (need_separator) { + write_separator(); + } + // format specified in constructor, let's hope it hasn't changed + *stream << i; + need_separator = true; +} + +void JsonOut::write(const unsigned &u) +{ + if (need_separator) { + write_separator(); + } + // format specified in constructor, let's hope it hasn't changed + *stream << u; + need_separator = true; +} + +void JsonOut::write(const double &f) +{ + if (need_separator) { + write_separator(); + } + // format specified in constructor, let's hope it hasn't changed + *stream << f; + need_separator = true; +} + +void JsonOut::write(const std::string &s) +{ + if (need_separator) { + write_separator(); + } + unsigned char ch; + stream->put('"'); + for (int i = 0; i < s.size(); ++i) { + ch = s[i]; + if (ch == '"') { + stream->write("\\\"", 2); + } else if (ch == '\\') { + stream->write("\\\\", 2); + } else if (ch == '/') { + // don't technically need to escape this + stream->put('/'); + } else if (ch == '\b') { + stream->write("\\b", 2); + } else if (ch == '\f') { + stream->write("\\f", 2); + } else if (ch == '\n') { + stream->write("\\n", 2); + } else if (ch == '\r') { + stream->write("\\r", 2); + } else if (ch == '\t') { + stream->write("\\t", 2); + } else if (ch < 0x20) { + // convert to "\uxxxx" unicode escape + stream->write("\\u00", 4); + stream->put((ch < 0x10) ? '0' : '1'); + char remainder = ch & 0x0F; + if (remainder < 0x0A) { + stream->put('0' + remainder); + } else { + stream->put('A' + (remainder - 0x0A)); + } + } else { + stream->put(ch); + } + } + stream->put('"'); + need_separator = true; +} + +void JsonOut::write(const JsonSerializer &thing) +{ + if (need_separator) { + write_separator(); + } + thing.serialize(*this); + need_separator = true; +} + +void JsonOut::member(const std::string &name) +{ + write(name); + write_member_separator(); +} + +void JsonOut::null_member(const std::string &name) +{ + member(name); + write_null(); +} + diff --git a/json.h b/json.h index d4a9e7eccd77b..282e79acacb2e 100644 --- a/json.h +++ b/json.h @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include @@ -108,7 +110,7 @@ * and calling the correct JsonIn method to read the value from the stream. * * As such, when processing items using a JsonIn, - * care must be taken to move the stream offset to the end of the item + * care should be taken to move the stream offset to the end of the item * after usage has finished. * This can be done by calling the .finish() method, * after the item has been dealt with, and before the stream continues. @@ -198,8 +200,11 @@ class JsonIn; class JsonObject; class JsonArray; +class JsonOut; +class JsonSerializer; +class JsonDeserializer; -bool is_whitespace(char ch); +bool is_whitespace(char ch); // TODO: move this elsewhere class JsonObject { private: @@ -213,10 +218,12 @@ class JsonObject { public: JsonObject(JsonIn *jsin); JsonObject(const JsonObject &jsobj); + ~JsonObject() { finish(); } void finish(); // moves the stream to the end of the object bool has_member(const std::string &name); // true iff named member exists + std::set get_member_names(); // variants with no fallback throw an error if the name is not found. // variants with a fallback return the fallback value in stead. @@ -231,6 +238,8 @@ class JsonObject { // note: returns empty array if not found JsonArray get_array(const std::string &name); + std::vector get_int_array(const std::string &name); + std::vector get_string_array(const std::string &name); // note: throws exception if not found (can change behaviour if desirable) JsonObject get_object(const std::string &name); // note: returns empty set if not found @@ -270,6 +279,9 @@ class JsonArray { JsonArray(JsonIn *jsin); JsonArray(const JsonArray &jsarr); JsonArray() : positions(), start(0), index(0), jsin(NULL) {}; + ~JsonArray() { finish(); } + + void finish(); // move the stream position to the end of the array bool has_more(); // true iff more elements may be retrieved with next_* int size(); @@ -319,7 +331,6 @@ class JsonArray { class JsonIn { private: - std::istream *stream; public: @@ -381,4 +392,92 @@ class JsonIn { void read(char * str, int len); }; +class JsonOut { +private: + std::ostream *stream; + bool need_separator; + +public: + JsonOut(std::ostream *stream); // TODO: pretty-printing + + // punctuation + void write_separator(); + void write_member_separator(); + void start_object(); + void end_object(); + void start_array(); + void end_array(); + + // write data to the output stream as JSON + void write_null(); + void write(const bool &b); + void write(const int &i); + void write(const unsigned &u); + void write(const double &f); + void write(const std::string &s); + void write(const char *cstr) { write(std::string(cstr)); } + void write(const JsonSerializer &thing); + // vector ~> array + template void write(const std::vector &v) + { + start_array(); + for (int i = 0; i < v.size(); ++i) { + write(v[i]); + } + end_array(); + } + // set ~> array + template void write(const std::set &v) + { + start_array(); + typename std::set::iterator it; + for (it = v.begin(); it != v.end(); ++it) { + write(*it); + } + end_array(); + } + + // convenience methods for writing named object members + void member(const std::string &name); // TODO: enforce value after + void null_member(const std::string &name); + template void member(const std::string &name, const T &value) + { + member(name); + write(value); + } + // map ~> object? +}; + + +// inheritable interface classes for easy serialization + +class JsonSerializer { +public: + virtual void serialize(JsonOut &jsout) const = 0; + std::string serialize() const { + std::ostringstream s; + serialize(s); + return s.str(); + } + void serialize(std::ostream &o) const { + JsonOut jout(&o); + serialize(jout); + } +}; + +class JsonDeserializer { +public: + virtual void deserialize(JsonObject &jsobj) = 0; + void deserialize(const std::string &json_object_string) { + // note: object string must include starting and ending braces {} + std::istringstream s(json_object_string); + deserialize(s); + } + void deserialize(std::istream &i) { + JsonIn jin(&i); + JsonObject jo = jin.get_object(); + deserialize(jo); + } +}; + #endif // _JSON_H_ diff --git a/main_menu.cpp b/main_menu.cpp index f9897b4afa4ed..248ea2de971ab 100644 --- a/main_menu.cpp +++ b/main_menu.cpp @@ -348,7 +348,8 @@ bool game::opening_screen() werase(w_background); wrefresh(w_background); - load_artifacts(world->world_name); + load_artifacts(world->world_path + "/artifacts.gsav", + itypes); MAPBUFFER.load(world->world_name); start_game(world->world_name); start = true; @@ -511,7 +512,8 @@ bool game::opening_screen() delwin(w_open); return (opening_screen()); } - load_artifacts(world->world_name); + load_artifacts(world->world_path + "/artifacts.gsav", + itypes); MAPBUFFER.load(world->world_name); start = true; @@ -556,7 +558,8 @@ bool game::opening_screen() WORLDPTR world = world_generator->all_worlds[world_generator->all_worldnames[sel2]]; world_generator->set_active_world(world); - load_artifacts(world->world_name); + load_artifacts(world->world_path + "/artifacts.gsav", + itypes); MAPBUFFER.load(world->world_name); setup(); @@ -688,7 +691,8 @@ bool game::opening_screen() werase(w_background); wrefresh(w_background); - load_artifacts(world_generator->active_world->world_name); + std::string artfilename = world_generator->active_world->world_path + "/artifacts.gsav"; + load_artifacts(artfilename, itypes); MAPBUFFER.load(world_generator->active_world->world_name); start_game(world_generator->active_world->world_name); diff --git a/map.cpp b/map.cpp index 9d507f5a8a399..aa30ff11fe3a3 100644 --- a/map.cpp +++ b/map.cpp @@ -232,7 +232,7 @@ void map::board_vehicle(game *g, int x, int y, player *p) g->update_map(x, y); } -void map::unboard_vehicle(game *g, const int x, const int y) +void map::unboard_vehicle(const int x, const int y) { int part = 0; vehicle *veh = veh_at(x, y, part); @@ -739,7 +739,7 @@ bool map::vehproceed(game* g){ g->add_msg(_("%s is hurled from the %s's seat by the power of the impact!"), psg->name.c_str(), veh->name.c_str()); } - g->m.unboard_vehicle(g, x + veh->parts[ppl[ps]].precalc_dx[0], + g->m.unboard_vehicle(x + veh->parts[ppl[ps]].precalc_dx[0], y + veh->parts[ppl[ps]].precalc_dy[0]); g->fling_player_or_monster(psg, 0, mdir.dir() + rng(0, 60) - 30, (vel1 - psg->str_cur < 10 ? 10 : @@ -1422,9 +1422,9 @@ if ( bash != NULL && bash->num_tests > 0 && bash->str_min != -1 ) { for (int i = -1; i <= 1; i++) for (int j = -1; j <= 1; j++) { if (furn(tentx + i, tenty + j) == f_groundsheet) - spawn_item(tentx + i, tenty + j, "broketent", 0); + spawn_item(tentx + i, tenty + j, "broketent"); if (furn(tentx + i, tenty + j) == f_skin_groundsheet) - spawn_item(tentx + i, tenty + j, "damaged_shelter_kit", 0); + spawn_item(tentx + i, tenty + j, "damaged_shelter_kit"); furn_set(tentx + i, tenty + j, f_null); } @@ -1459,8 +1459,8 @@ void map::destroy(game *g, const int x, const int y, const bool makesound) for (int i = x - 2; i <= x + 2; i++) { for (int j = y - 2; j <= y + 2; j++) { if(move_cost(i, j) == 0) continue; - if (one_in(3)) spawn_item(i, j, "gasoline", 0); - if (one_in(6)) spawn_item(i, j, "steel_chunk", 0, 0, 3); + if (one_in(3)) spawn_item(i, j, "gasoline"); + if (one_in(6)) spawn_item(i, j, "steel_chunk", 0, 3); } } } @@ -1475,8 +1475,8 @@ void map::destroy(game *g, const int x, const int y, const bool makesound) for (int i = x - 2; i <= x + 2; i++) { for (int j = y - 2; j <= y + 2; j++) { if(move_cost(i, j) == 0) continue; - if (one_in(6)) spawn_item(i, j, "2x4", 0); - if (one_in(6)) spawn_item(i, j, "nail", 0, 0, 3); + if (one_in(6)) spawn_item(i, j, "2x4"); + if (one_in(6)) spawn_item(i, j, "nail", 0, 3); } } break; @@ -1487,7 +1487,7 @@ void map::destroy(game *g, const int x, const int y, const bool makesound) for (int i = x - 2; i <= x + 2; i++) { for (int j = y - 2; j <= y + 2; j++) { if (move_cost(i, j) > 0 && one_in(5)) - spawn_item(i, j, "rock", 0); + spawn_item(i, j, "rock"); ter_set(x, y, t_rubble); } } @@ -1498,9 +1498,9 @@ void map::destroy(game *g, const int x, const int y, const bool makesound) for (int i = x - 2; i <= x + 2; i++) { for (int j = y - 2; j <= y + 2; j++) { if(move_cost(i, j) == 0) continue; - if (one_in(5)) { spawn_item(i, j, "splinter", 0); } - if (one_in(6)) { spawn_item(i, j, "nail", 0, 0, 3); } - if (one_in(100)) { spawn_item(x, y, "cu_pipe", 0); } + if (one_in(5)) { spawn_item(i, j, "splinter"); } + if (one_in(6)) { spawn_item(i, j, "nail", 0, 3); } + if (one_in(100)) { spawn_item(x, y, "cu_pipe"); } } } ter_set(x, y, t_rubble); @@ -1544,10 +1544,10 @@ void map::destroy(game *g, const int x, const int y, const bool makesound) for (int i = x - 2; i <= x + 2; i++) { for (int j = y - 2; j <= y + 2; j++) { if(move_cost(i, j) == 0) continue; - if (one_in(5)) spawn_item(i, j, "rock", 0); - if (one_in(4)) spawn_item(i, j, "splinter", 0); - if (one_in(3)) spawn_item(i, j, "rebar", 0); - if (one_in(6)) spawn_item(i, j, "nail", 0, 0, 3); + if (one_in(5)) spawn_item(i, j, "rock"); + if (one_in(4)) spawn_item(i, j, "splinter"); + if (one_in(3)) spawn_item(i, j, "rebar"); + if (one_in(6)) spawn_item(i, j, "nail", 0, 3); } } ter_set(x, y, t_rubble); @@ -1595,11 +1595,11 @@ void map::destroy(game *g, const int x, const int y, const bool makesound) for (int j = y - 1; j <= y + 1; j++) { if(move_cost(i, j) == 0) continue; - if (one_in(3)) spawn_item(i, j, "rope_6", 0); - if (one_in(2)) spawn_item(i, j, "splinter", 0); - if (one_in(3)) spawn_item(i, j, "stick", 0); - if (one_in(6)) spawn_item(i, j, "2x4", 0); - if (one_in(9)) spawn_item(i, j, "log", 0); + if (one_in(3)) spawn_item(i, j, "rope_6"); + if (one_in(2)) spawn_item(i, j, "splinter"); + if (one_in(3)) spawn_item(i, j, "stick"); + if (one_in(6)) spawn_item(i, j, "2x4"); + if (one_in(9)) spawn_item(i, j, "log"); } } ter_set(x, y, t_dirt); @@ -1694,9 +1694,9 @@ void map::shoot(game *g, const int x, const int y, int &dam, { g->sound(x, y, 16, _("glass breaking!")); ter_set(x, y, t_window_frame); - spawn_item(x, y, "sheet", 0, 1); - spawn_item(x, y, "stick", 0); - spawn_item(x, y, "string_36", 0); + spawn_item(x, y, "sheet", 1); + spawn_item(x, y, "stick"); + spawn_item(x, y, "string_36"); } } break; @@ -1797,7 +1797,7 @@ void map::shoot(game *g, const int x, const int y, int &dam, for (int j = y - 2; j <= y + 2; j++) { if (move_cost(i, j) > 0 && one_in(3)) - spawn_item(i, j, "gasoline", 0); + spawn_item(i, j, "gasoline"); } } g->sound(x, y, 10, _("smash!")); @@ -2133,6 +2133,7 @@ item map::water_from(const int x, const int y) item map::acid_from(const int x, const int y) { + (void)x; (void)y; //all acid is acid, i guess? item ret(item_controller->find_template("water_acid"), 0); return ret; } @@ -2165,8 +2166,8 @@ point map::find_item(const item *it) return ret; } -void map::spawn_item(const int x, const int y, item new_item, const int birthday, - const int quantity, const int charges, const int damlevel) +void map::spawn_item(const int x, const int y, item new_item, + const int charges, const int damlevel) { if (charges && new_item.charges > 0) { @@ -2207,20 +2208,25 @@ void map::spawn_artifact(const int x, const int y, itype* type, const int bday) //New spawn_item method, using item factory // added argument to spawn at various damage levels -void map::spawn_item(const int x, const int y, std::string type_id, const int birthday, - const int quantity, const int charges, const int damlevel) +void map::spawn_item(const int x, const int y, const std::string &type_id, + const unsigned quantity, const int charges, + const unsigned birthday, const int damlevel) { - item new_item = item_controller->create(type_id, birthday); + // recurse to spawn (quantity - 1) items for(int i = 1; i < quantity; i++) { - spawn_item(x, y, type_id, birthday, 0, charges); + spawn_item(x, y, type_id, 1, charges, birthday, damlevel); } - spawn_item( x, y, new_item, birthday, quantity, charges, damlevel ); + // spawn the item + item new_item = item_controller->create(type_id, birthday); + spawn_item(x, y, new_item, charges, damlevel); } // stub for now, could vary by ter type -int map::max_volume(const int x, const int y) { - return MAX_VOLUME_IN_SQUARE; +int map::max_volume(const int x, const int y) +{ + (void)x; (void)y; //stub + return MAX_VOLUME_IN_SQUARE; } // total volume of all the things @@ -2654,7 +2660,7 @@ void map::disarm_trap(game *g, const int x, const int y) std::vector comp = g->traps[tr_at(x, y)]->components; for (int i = 0; i < comp.size(); i++) { if (comp[i] != "null") - spawn_item(x, y, comp[i], 0, 0, 1); + spawn_item(x, y, comp[i], 1, 1); } if (tr_at(x, y) == tr_engine) { for (int i = -1; i <= 1; i++) { @@ -2861,17 +2867,17 @@ bool map::allow_camp(const int x, const int y, const int radius) return camp_at(x, y, radius) == NULL; } +// locate the nearest camp in some radius (default CAMPSIZE) basecamp* map::camp_at(const int x, const int y, const int radius) { - // locate the nearest camp in a CAMPSIZE radius if (!INBOUNDS(x, y)) { return NULL; } - const int sx = std::max(0, x / SEEX - CAMPSIZE); - const int sy = std::max(0, y / SEEY - CAMPSIZE); - const int ex = std::min(MAPSIZE - 1, x / SEEX + CAMPSIZE); - const int ey = std::min(MAPSIZE - 1, y / SEEY + CAMPSIZE); + const int sx = std::max(0, x / SEEX - radius); + const int sy = std::max(0, y / SEEY - radius); + const int ex = std::min(MAPSIZE - 1, x / SEEX + radius); + const int ey = std::min(MAPSIZE - 1, y / SEEY + radius); for (int ly = sy; ly < ey; ++ly) { for (int lx = sx; lx < ex; ++lx) { @@ -3804,7 +3810,7 @@ bool map::inbounds(const int x, const int y) return (x >= 0 && x < SEEX * my_MAPSIZE && y >= 0 && y < SEEY * my_MAPSIZE); } -bool map::add_graffiti(game *g, int x, int y, std::string contents) +bool map::add_graffiti(int x, int y, std::string contents) { int nx = x; int ny = y; diff --git a/map.h b/map.h index 3a4fee1f128a3..11968d7b15ec5 100644 --- a/map.h +++ b/map.h @@ -191,7 +191,7 @@ class map // put player on vehicle at x,y void board_vehicle(game *g, int x, int y, player *p); - void unboard_vehicle(game *g, const int x, const int y);//remove player from vehicle at x,y + void unboard_vehicle(const int x, const int y);//remove player from vehicle at x,y void update_vehicle_cache(vehicle *, const bool brand_new = false); void reset_vehicle_cache(); void clear_vehicle_cache(); @@ -283,7 +283,9 @@ class map void i_rem(const int x, const int y, const int index); point find_item(const item *it); void spawn_artifact(const int x, const int y, itype* type, int bday); - void spawn_item(const int x, const int y, std::string itype_id, int birthday, int quantity = 0, int charges = 0, int damlevel = 0); + void spawn_item(const int x, const int y, const std::string &itype_id, + const unsigned quantity=1, const int charges=0, + const unsigned birthday=0, const int damlevel=0); int max_volume(const int x, const int y); int free_volume(const int x, const int y); int stored_volume(const int x, const int y); @@ -333,7 +335,7 @@ class map // Graffiti graffiti graffiti_at(int x, int y); - bool add_graffiti(game *g, int x, int y, std::string contents); + bool add_graffiti(int x, int y, std::string contents); // mapgen.cpp functions void generate(game *g, overmap *om, const int x, const int y, const int z, const int turn); @@ -346,8 +348,8 @@ class map const int x2, const int y2, bool ongrass, const int turn); // put_items_from puts exactly num items, based on chances void put_items_from(items_location loc, const int num, const int x, const int y, const int turn = 0, const int quantity = 0, const int charges = 0, const int damlevel = 0); - void spawn_item(const int x, const int y, item new_item, const int birthday, - const int quantity, const int charges, const int damlevel); + void spawn_item(const int x, const int y, item new_item, + const int charges, const int damlevel); void add_spawn(std::string type, const int count, const int x, const int y, bool friendly = false, const int faction_id = -1, const int mission_id = -1, std::string name = "NONE"); diff --git a/mapgen.cpp b/mapgen.cpp index 517b7b4477efc..c139c61cf6fe8 100644 --- a/mapgen.cpp +++ b/mapgen.cpp @@ -898,7 +898,7 @@ void map::draw_map(const oter_id terrain_type, const oter_id t_north, const oter break; case ot_s_lot: - mapgen_parking_lot(this, terrain_type, facing_data, turn); + mapgen_parking_lot(this, facing_data, turn); break; case ot_pool: @@ -913,7 +913,7 @@ void map::draw_map(const oter_id terrain_type, const oter_id t_north, const oter case ot_s_gas_east: case ot_s_gas_south: case ot_s_gas_west: - mapgen_gas_station(this, terrain_type, turn, density); + mapgen_gas_station(this, terrain_type, density); break; case ot_s_pharm_north: @@ -1796,7 +1796,7 @@ ssssssssssssssssssssssss\n\ ...DEEE|.R.|..|.....V%ss\n", mapf::basic_bind("E > R # X G C , _ r V H 6 x % ^ . - | t + = D w T S e o h c d l s", t_elevator, t_stairs_down, t_railing_v, t_rock, t_door_metal_locked, t_door_glass_c, t_floor, t_pavement_y, t_pavement, t_floor, t_wall_glass_v, t_wall_glass_h, t_console, t_console_broken, t_shrub, t_floor, t_floor, t_wall_h, t_wall_v, t_floor, t_door_c, t_door_locked, t_door_locked_alarm, t_window, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_sidewalk), mapf::basic_bind("E > R # X G C , _ r V H 6 x % ^ . - | t + = D w T S e o h c d l s", f_null, f_null, f_null, f_null, f_null, f_null, f_crate_c, f_null, f_null, f_rack, f_null, f_null, f_null, f_null, f_null, f_indoor_plant, f_null, f_null, f_null, f_table, f_null, f_null, f_null, f_null, f_toilet, f_sink, f_fridge, f_bookcase, f_chair, f_counter, f_desk, f_locker, f_null)); - spawn_item(18, 15, "record_accounting", 0); + spawn_item(18, 15, "record_accounting"); place_items("cleaning", 75, 3, 5, 5, 5, false, 0); place_items("office", 75, 10, 7, 16, 8, false, 0); place_items("cubical_office", 75, 15, 15, 19, 15, false, 0); @@ -2090,8 +2090,8 @@ case ot_church_west:{ ^^ ss ^^ s \n", mapf::basic_bind("O 6 ^ . - | # t + = D w T S e o h c d l s", t_column, t_console, t_shrub, t_floor, t_wall_h, t_wall_v, t_floor, t_floor, t_door_c, t_door_locked_alarm, t_door_locked, t_window, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_sidewalk), mapf::basic_bind("O 6 ^ . - | # t + = D w T S e o h c d l s", f_null, f_null, f_null, f_null, f_null, f_null, f_bench, f_table, f_null, f_null, f_null, f_null, f_toilet, f_sink, f_fridge, f_bookcase, f_chair, f_counter, f_desk, f_locker, f_null)); - spawn_item(9, 6, "brazier", 0); - spawn_item(14, 6, "brazier", 0); + spawn_item(9, 6, "brazier"); + spawn_item(14, 6, "brazier"); place_items("church", 40, 5, 5, 8, 16, false, 0); place_items("church", 40, 5, 5, 8, 16, false, 0); place_items("church", 85, 12, 2, 14, 2, false, 0); @@ -2132,8 +2132,8 @@ s WWWWW ss WWWWW s\n\ ssssssssssssssssssssssss\n", mapf::basic_bind("C V G B W R r 6 $ . - | # t + g T S h c l s", t_floor, t_window_stained_red, t_window_stained_green, t_window_stained_blue, t_rock, t_railing_v, t_railing_h, t_console, t_shrub, t_rock_floor, t_wall_h, t_wall_v, t_rock_floor, t_rock_floor, t_door_c, t_door_glass_c, t_rock_floor, t_rock_floor, t_rock_floor, t_rock_floor, t_rock_floor, t_sidewalk), mapf::basic_bind("C V G B W R r 6 $ . - | # t + g T S h c l s", f_crate_c, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_bench, f_table, f_null, f_null, f_toilet, f_sink, f_chair, f_counter, f_locker, f_null)); - spawn_item(8, 4, "brazier", 0); - spawn_item(15, 4, "brazier", 0); + spawn_item(8, 4, "brazier"); + spawn_item(15, 4, "brazier"); place_items("church", 70, 6, 7, 17, 16, false, 0); place_items("church", 70, 6, 7, 17, 16, false, 0); place_items("church", 60, 6, 7, 17, 16, false, 0); @@ -2245,7 +2245,7 @@ ss w...........\n\ ss #bbbb...bbbb\n", mapf::basic_bind("b E > < R # X G C , _ r V H 6 x % ^ . - | t + = D w T S e o h c d l s", t_floor, t_elevator, t_stairs_down, t_stairs_up, t_railing_v, t_rock, t_door_metal_locked, t_door_glass_c, t_floor, t_pavement_y, t_pavement, t_railing_h, t_wall_glass_v, t_wall_glass_h, t_console, t_console_broken, t_shrub, t_floor, t_floor, t_wall_h, t_wall_v, t_floor, t_door_c, t_door_locked, t_door_locked_interior, t_window_stained_red, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_sidewalk), mapf::basic_bind("b E > < R # X G C , _ r V H 6 x % ^ . - | t + = D w T S e o h c d l s", f_bench, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_crate_c, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_indoor_plant, f_null, f_null, f_null, f_table, f_null, f_null, f_null, f_null, f_toilet, f_sink, f_fridge, f_bookcase, f_chair, f_counter, f_desk, f_locker, f_null)); - spawn_item(20, 2, "brazier", 0); + spawn_item(20, 2, "brazier"); for (int i = 0; i <= 23; i++) { for (int j = 0; j <= 23; j++) { if (this->furn(i,j) == f_bench) @@ -2361,7 +2361,7 @@ bbb...bbbbwsssssssssssss\n\ bbb...bbbb# ss\n", mapf::basic_bind("b E > < R # X G C , _ r V H 6 x % ^ . - | t + = D w T S e o h c d l s", t_floor, t_elevator, t_stairs_down, t_stairs_up, t_railing_v, t_rock, t_door_metal_locked, t_door_glass_c, t_floor, t_pavement_y, t_pavement, t_railing_h, t_wall_glass_v, t_wall_glass_h, t_console, t_console_broken, t_shrub, t_floor, t_floor, t_wall_h, t_wall_v, t_floor, t_door_c, t_door_locked, t_door_locked_interior, t_window_stained_red, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_sidewalk), mapf::basic_bind("b E > < R # X G C , _ r V H 6 x % ^ . - | t + = D w T S e o h c d l s", f_bench, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_crate_c, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_indoor_plant, f_null, f_null, f_null, f_table, f_null, f_null, f_null, f_null, f_toilet, f_sink, f_fridge, f_bookcase, f_chair, f_counter, f_desk, f_locker, f_null)); - spawn_item(2, 2, "brazier", 0); + spawn_item(2, 2, "brazier"); for (int i = 0; i <= 23; i++) { for (int j = 0; j <= 23; j++) { if (this->furn(i,j) == f_bench) @@ -2580,7 +2580,7 @@ C..C..C...|hhh|#########\n\ .+........|#############\n", mapf::basic_bind("O E > < # X G C , _ r V H 6 x ^ . - | t + = D w T S e o h c d l s", t_floor, t_elevator, t_stairs_down, t_stairs_up, t_rock, t_door_metal_locked, t_door_glass_c, t_floor, t_pavement_y, t_pavement, t_floor, t_wall_glass_v, t_wall_glass_h, t_console, t_console_broken, t_floor, t_floor, t_wall_h, t_wall_v, t_floor, t_door_c, t_door_locked, t_door_locked_interior, t_window_stained_red, t_floor, t_floor, t_floor, t_column, t_floor, t_floor, t_floor, t_floor, t_sidewalk), mapf::basic_bind("O E > < # X G C , _ r V H 6 x ^ . - | t + = D w T S e o h c d l s", f_oven, f_null, f_null, f_null, f_null, f_null, f_null, f_makeshift_bed, f_null, f_null, f_rack, f_null, f_null, f_null, f_null, f_indoor_plant, f_null, f_null, f_null, f_table, f_null, f_null, f_null, f_null, f_toilet, f_sink, f_fridge, f_null, f_chair, f_counter, f_desk, f_locker, f_null)); - spawn_item(0, 3, "small_relic", 0); + spawn_item(0, 3, "small_relic"); add_spawn("mon_blank", rng(1,3), 0, 5); if (t_west == ot_cathedral_b && t_north == ot_cathedral_b) rotate(1); @@ -4127,7 +4127,7 @@ ff.......|....|WWWWWWWW|\n\ add_item(17, 15, body); add_item(8, 3, body); add_item(10, 3, body); - spawn_item(18, 15, "ax", 0); + spawn_item(18, 15, "ax"); } else{ //analyzer @@ -4306,16 +4306,16 @@ ff.......|....|WWWWWWWW|\n\ add_trap(SEEX + 1, SEEY + 1, tr_dissector); if (!one_in(3)) { rn = dice(4, 3); - spawn_item(SEEX - 1, SEEY - 1, "laser_pack", 0, rn); - spawn_item(SEEX + 1, SEEY - 1, "UPS_off", 0, rn); - spawn_item(SEEX - 1, SEEY , "v29", 0); - spawn_item(SEEX + 1, SEEY , "ftk93", 0); + spawn_item(SEEX - 1, SEEY - 1, "laser_pack", rn); + spawn_item(SEEX + 1, SEEY - 1, "UPS_off", rn); + spawn_item(SEEX - 1, SEEY , "v29"); + spawn_item(SEEX + 1, SEEY , "ftk93"); } else if (!one_in(3)) { rn = dice(3, 6); - spawn_item(SEEX - 1, SEEY - 1, "mininuke", 0, rn); - spawn_item(SEEX , SEEY - 1, "mininuke", 0, rn); - spawn_item(SEEX - 1, SEEY , "mininuke", 0, rn); - spawn_item(SEEX , SEEY , "mininuke", 0, rn); + spawn_item(SEEX - 1, SEEY - 1, "mininuke", rn); + spawn_item(SEEX , SEEY - 1, "mininuke", rn); + spawn_item(SEEX - 1, SEEY , "mininuke", rn); + spawn_item(SEEX , SEEY , "mininuke", rn); } else { furn_set(SEEX - 2, SEEY - 1, f_rack); furn_set(SEEX - 1, SEEY - 1, f_rack); @@ -4642,7 +4642,7 @@ ff.......|....|WWWWWWWW|\n\ place_items("mil_rifles", 30, rnx, rny, rnx, rny, true, 0); place_items("mil_armor", 70, rnx, rny, rnx, rny, true, 0); place_items("mil_food", 40, rnx, rny, rnx, rny, true, 0); - spawn_item(rnx, rny, "id_military", 0); + spawn_item(rnx, rny, "id_military"); } else if (one_in(20)) rough_circle(this, t_rubble, rnx, rny, rng(3, 6)); } @@ -4945,8 +4945,8 @@ ff.......|....|WWWWWWWW|\n\ square(this, t_rock_floor, SEEX - 1, 1, SEEX + 2, 4); square(this, t_rock_floor, SEEX, 5, SEEX + 1, SEEY * 2 - 1); line(this, t_stairs_up, SEEX, SEEY * 2 - 1, SEEX + 1, SEEY * 2 - 1); - spawn_artifact(rng(SEEX, SEEX + 1), rng(2, 3), g->new_artifact(), 0); - spawn_artifact(rng(SEEX, SEEX + 1), rng(2, 3), g->new_artifact(), 0); + spawn_artifact(rng(SEEX, SEEX + 1), rng(2, 3), new_artifact(g->itypes), 0); + spawn_artifact(rng(SEEX, SEEX + 1), rng(2, 3), new_artifact(g->itypes), 0); return; case ot_sewage_treatment: @@ -5558,7 +5558,7 @@ ff.......|....|WWWWWWWW|\n\ case 1: { // Wyrms int x = rng(SEEX, SEEX + 1), y = rng(SEEY, SEEY + 1); ter_set(x, y, t_pedestal_wyrm); - spawn_item(x, y, "petrified_eye", 0); + spawn_item(x, y, "petrified_eye"); } break; // That's it! game::examine handles the pedestal/wyrm spawns case 2: { // The Thing dog @@ -5571,7 +5571,7 @@ ff.......|....|WWWWWWWW|\n\ place_items("mine_equipment", 60, x, y, x, y, false, 0); } add_spawn("mon_dog_thing", 1, rng(SEEX, SEEX + 1), rng(SEEX, SEEX + 1), true); - spawn_artifact(rng(SEEX, SEEX + 1), rng(SEEY, SEEY + 1), g->new_artifact(), 0); + spawn_artifact(rng(SEEX, SEEX + 1), rng(SEEY, SEEY + 1), new_artifact(g->itypes), 0); } break; case 3: { // Spiral down @@ -5757,7 +5757,7 @@ ff.......|....|WWWWWWWW|\n\ mapf::basic_bind(". - | 6 a r + = D W w t S e o h c d x l F f _ & G s", f_null, f_null, f_null, f_null, f_armchair, f_trashcan, f_null, f_null, f_null, f_null, f_null, f_toilet, f_sink, f_fridge, f_bookcase, f_chair, f_counter, f_desk, f_null, f_locker, f_null, f_null, f_null, f_null, f_null, f_null)); tmpcomp = add_computer(17, 13, _("Broadcasting Control"), 0); tmpcomp->add_option(_("ERROR: SIGNAL DISCONNECT"), COMPACT_TOWER_UNRESPONSIVE, 0); - spawn_item(18, 13, "record_weather", 0); + spawn_item(18, 13, "record_weather"); place_items("novels", 70, 5, 12, 6, 12, false, 0); place_items("novels", 70, 2, 21, 2, 19, false, 0); place_items("novels", 70, 12, 19, 12, 20, false, 0); @@ -5854,13 +5854,13 @@ case ot_public_works:{ mapf::basic_bind("P C G , _ r f F 6 x $ ^ . - | t + = D w T S e o h c d l s", f_pool_table, f_crate_c, f_null, f_null, f_null, f_rack, f_null, f_null, f_null, f_null, f_null, f_indoor_plant, f_null, f_null, f_null, f_table, f_null, f_null, f_null, f_null, f_toilet, f_sink, f_fridge, f_bookcase, f_chair, f_counter, f_desk, f_locker, f_null)); place_items("hardware", 85, 2, 3, 2, 8, false, 0); place_items("hardware", 85, 6, 2, 13, 2, false, 0); - spawn_item(21, 2, "log", 0, rng(1, 3)); - spawn_item(15, 2, "pipe", 0, rng(1, 10)); - spawn_item(4, 2, "glass_sheet", 0, rng(1, 7)); - spawn_item(16, 5, "2x4", 0, rng(1, 20)); - spawn_item(16, 7, "2x4", 0, rng(1, 20)); - spawn_item(12, 2, "nail", 0); - spawn_item(13, 2, "nail", 0); + spawn_item(21, 2, "log", rng(1, 3)); + spawn_item(15, 2, "pipe", rng(1, 10)); + spawn_item(4, 2, "glass_sheet", rng(1, 7)); + spawn_item(16, 5, "2x4", rng(1, 20)); + spawn_item(16, 7, "2x4", rng(1, 20)); + spawn_item(12, 2, "nail"); + spawn_item(13, 2, "nail"); place_spawns(g, "GROUP_PUBLICWORKERS", 1, 0, 0, SEEX * 2 - 1, SEEX * 2 - 1, 0.1); if (t_west == ot_public_works_entrance) rotate(1); @@ -5951,7 +5951,7 @@ __________ f \n", place_items("mechanics", 85, 14, 9, 16, 9, false, 0); place_items("electronics", 80, 16, 2, 18, 2, false, 0); place_items("cleaning", 85, 12, 2, 13, 2, false, 0); - spawn_item(3, 2, "log", 0, rng(1, 3)); + spawn_item(3, 2, "log", rng(1, 3)); place_spawns(g, "GROUP_PUBLICWORKERS", 1, 0, 0, SEEX * 2 - 1, SEEX * 2 - 1, 0.1); if (t_west == ot_public_works && t_north == ot_public_works){ rotate(1); @@ -6345,7 +6345,7 @@ w \n\ add_spawn("mon_zombie_child", rng(0, 4), SEEX, SEEY); add_spawn("mon_zombie", rng(0, 1), SEEX, SEEY); place_items("cleaning", 80, 22, 23, 23, 23, false, 0); - spawn_item(12, 15, "american_flag", 0); + spawn_item(12, 15, "american_flag"); if (t_north == ot_school_5) rotate(2); else if (t_east == ot_school_5) @@ -7145,7 +7145,7 @@ h,h,g,,,|###############\n\ ####|,,|################\n", mapf::basic_bind("D W # t g r + = h c l w s _ o d x T b G . , B - | % f F S", t_floor, t_floor, t_rock, t_floor, t_reinforced_glass_v, t_floor, t_door_locked_interior, t_door_c, t_floor, t_floor, t_floor, t_window, t_sidewalk, t_pavement, t_floor, t_floor, t_console_broken, t_floor, t_floor, t_door_bar_locked, t_grass, t_floor, t_bars, t_concrete_h, t_concrete_v, t_fence_barbed, t_chainfence_h, t_chainfence_v, t_floor), mapf::basic_bind("D W # t g r + = h c l w s _ o d x T b G . , B - | % f F S", f_dryer, f_washer, f_null, f_table, f_null, f_rack, f_null, f_null, f_chair, f_counter, f_locker, f_null, f_null, f_null, f_bookcase, f_desk, f_null, f_toilet, f_bed, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_sink)); - spawn_item(7, 11, "visions_solitude", 0); + spawn_item(7, 11, "visions_solitude"); add_spawn("mon_zombie_brute", 1, 6, 13); for (int i = 0; i <= 23; i++) { for (int j = 0; j <= 23; j++) { @@ -7307,9 +7307,9 @@ ee|,,,,,,r|#############\n\ } if (this->furn(i,j) == f_washer || this->furn(i,j) == f_dryer){ if (one_in(4)) - spawn_item(i, j, "blanket", 0, 3); + spawn_item(i, j, "blanket", 3); else if (one_in(3)) - spawn_item(i, j, "jumpsuit", 0, 3); + spawn_item(i, j, "jumpsuit", 3); } } } @@ -7892,9 +7892,7 @@ tth.............^|..|###\n\ place_items("home_hw", 80, i, j, i, j, false, 0); if (this->furn(i,j) == f_washer || this->furn(i,j) == f_dryer){ if (x_in_y(1,2)){ - spawn_item(i, j, "blanket", 0); - spawn_item(i, j, "blanket", 0); - spawn_item(i, j, "blanket", 0); + spawn_item(i, j, "blanket", 3); } else if (x_in_y(1,3)) place_items("dresser", 80, i, j, i, j, false, 0); @@ -7957,7 +7955,7 @@ tth.............^|..|###\n\ tmpcomp->add_failure(COMPFAIL_SHUTDOWN); tmpcomp->add_failure(COMPFAIL_ALARM); - if (one_in(2)) spawn_item(7, 6, "record_patient", 0); + if (one_in(2)) spawn_item(7, 6, "record_patient"); place_items("dissection", 60, 4, 9, 4, 11, false, 0); place_items("dissection", 60, 9, 9, 10, 9, false, 0); place_items("dissection", 60, 20, 11, 20, 13, false, 0); @@ -8002,7 +8000,7 @@ tth.............^|..|###\n\ line_furn(this, f_counter, buildx - 3, buildy - 3, buildx + 3, buildy - 3); place_items("toxic_dump_equipment", 80, buildx - 3, buildy - 3, buildx + 3, buildy - 3, false, 0); - spawn_item(buildx, buildy, "id_military", 0); + spawn_item(buildx, buildy, "id_military"); ter_set(buildx, buildy + 4, t_door_locked); rotate(rng(0, 3)); @@ -8039,7 +8037,7 @@ case ot_haz_sar_entrance:{ _______ \n", mapf::basic_bind("1 & V C G 5 % Q E , _ r X f F 6 x $ ^ . - | # t + = D w T S e o h c d l s", t_sewage_pipe, t_sewage_pump, t_vat, t_floor, t_grate, t_wall_glass_h, t_wall_glass_v, t_sewage, t_elevator, t_pavement_y, t_pavement, t_floor, t_door_metal_locked, t_chainfence_v, t_chainfence_h, t_console, t_console_broken, t_shrub, t_floor, t_floor, t_wall_h, t_wall_v, t_rock, t_floor, t_door_c, t_door_metal_c, t_door_locked, t_window, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_sidewalk), mapf::basic_bind("1 & V C G 5 % Q E , _ r X f F 6 x $ ^ . - | # t + = D w T S e o h c d l s", f_null, f_null, f_null, f_crate_c, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_rack, f_null, f_null, f_null, f_null, f_null, f_null, f_indoor_plant, f_null, f_null, f_null, f_null, f_table, f_null, f_null, f_null, f_null, f_toilet, f_sink, f_fridge, f_bookcase, f_chair, f_counter, f_desk, f_locker, f_null)); - spawn_item(19, 3, "cleansuit", 0); + spawn_item(19, 3, "cleansuit"); place_items("office", 80, 4, 19, 6, 19, false, 0); place_items("cleaning", 90, 7, 3, 7, 5, false, 0); place_items("toxic_dump_equipment", 85, 19, 1, 19, 3, false, 0); @@ -8092,7 +8090,7 @@ case ot_haz_sar:{ f |_________%..r| |^\n", mapf::basic_bind("1 & V C G 5 % Q E , _ r X f F 6 x $ ^ . - | # t + = D w T S e o h c d l s", t_sewage_pipe, t_sewage_pump, t_vat, t_floor, t_grate, t_wall_glass_h, t_wall_glass_v, t_sewage, t_elevator, t_pavement_y, t_pavement, t_floor, t_door_metal_locked, t_chainfence_v, t_chainfence_h, t_console, t_console_broken, t_shrub, t_floor, t_floor, t_wall_h, t_wall_v, t_rock, t_floor, t_door_c, t_door_metal_c, t_door_locked, t_window, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_sidewalk), mapf::basic_bind("1 & V C G 5 % Q E , _ r X f F 6 x $ ^ . - | # t + = D w T S e o h c d l s", f_null, f_null, f_null, f_crate_c, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_rack, f_null, f_null, f_null, f_null, f_null, f_null, f_indoor_plant, f_null, f_null, f_null, f_null, f_table, f_null, f_null, f_null, f_null, f_toilet, f_sink, f_fridge, f_bookcase, f_chair, f_counter, f_desk, f_locker, f_null)); - spawn_item(19, 22, "cleansuit", 0); + spawn_item(19, 22, "cleansuit"); place_items("cleaning", 85, 6, 11, 6, 14, false, 0); place_items("tools", 85, 10, 6, 13, 6, false, 0); place_items("toxic_dump_equipment", 85, 22, 14, 23, 15, false, 0); @@ -8148,7 +8146,7 @@ FFFFFFFFFFFFFFFFFFFFFFf \n\ \n", mapf::basic_bind("1 & V C G 5 % Q E , _ r X f F V H 6 x $ ^ . - | # t + = D w T S e o h c d l s", t_sewage_pipe, t_sewage_pump, t_vat, t_floor, t_grate, t_wall_glass_h, t_wall_glass_v, t_sewage, t_elevator, t_pavement_y, t_pavement, t_floor, t_door_metal_locked, t_chainfence_v, t_chainfence_h, t_wall_glass_v, t_wall_glass_h, t_console, t_console_broken, t_shrub, t_floor, t_floor, t_wall_h, t_wall_v, t_rock, t_floor, t_door_c, t_door_locked_alarm, t_door_locked, t_window, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_floor, t_sidewalk), mapf::basic_bind("1 & V C G 5 % Q E , _ r X f F V H 6 x $ ^ . - | # t + = D w T S e o h c d l s", f_null, f_null, f_null, f_crate_c, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_rack, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_indoor_plant, f_null, f_null, f_null, f_null, f_table, f_null, f_null, f_null, f_null, f_toilet, f_sink, f_fridge, f_bookcase, f_chair, f_counter, f_desk, f_locker, f_null)); - spawn_item(1, 2, "id_military", 0); + spawn_item(1, 2, "id_military"); place_items("office", 85, 1, 1, 1, 3, false, 0); place_items("office", 85, 11, 3, 13, 3, false, 0); place_items("office", 85, 17, 3, 19, 3, false, 0); @@ -8453,7 +8451,7 @@ case ot_haz_sar_b1:{ $$$$-|-|=HH-|-HHHH-|####\n", mapf::basic_bind("= + E & 6 H V c h d r M _ $ | - # . , l S T", t_door_metal_c, t_door_metal_o, t_elevator, t_elevator_control_off, t_console, t_reinforced_glass_h, t_reinforced_glass_v, t_floor, t_floor, t_floor, t_floor, t_gates_control_concrete, t_sewage, t_door_metal_locked, t_concrete_v, t_concrete_h, t_rock, t_rock_floor, t_metal_floor, t_floor, t_floor, t_floor), mapf::basic_bind("= + E & 6 H V c h d r M _ $ | - # . , l S T", f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_counter, f_chair, f_desk, f_rack, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_null, f_locker, f_sink, f_toilet)); - spawn_item(3, 16, "sarcophagus_access_code", 0); + spawn_item(3, 16, "sarcophagus_access_code"); for (int i = 0; i <= 23; i++) { for (int j = 0; j <= 23; j++) { if (this->furn(i,j) == f_locker) @@ -8969,9 +8967,9 @@ case ot_cabin: ########################\n", mapf::basic_bind("G A b C . - | t + = D o h c d r < # T", t_door_bar_locked, t_dirtfloor, t_dirtfloor, t_column, t_dirtfloor, t_wall_h, t_wall_v, t_dirtfloor, t_door_c, t_door_boarded, t_door_locked_interior, t_dirtfloor, t_dirtfloor, t_floor, t_dirtfloor, t_dirtfloor, t_stairs_up, t_rock, t_dirtfloor), mapf::basic_bind("G A b C . - | t + = D o h c d r < # T", f_null, f_armchair, f_bed, f_null, f_null, f_null, f_null, f_table, f_null, f_null, f_null, f_bookcase, f_chair, f_crate_o, f_desk, f_rack, f_null, f_null, f_toilet)); - spawn_item(2, 17, "brazier", 0); - spawn_item(6, 17, "brazier", 0); - spawn_item(4, 17, "etched_skull", 0); + spawn_item(2, 17, "brazier"); + spawn_item(6, 17, "brazier"); + spawn_item(4, 17, "etched_skull"); for (int i = 0; i <= 23; i++) { for (int j = 0; j <= 23; j++) { if (this->furn(i,j) == f_crate_c) @@ -9315,7 +9313,7 @@ case ot_farm_field: for (int i = 0; i <= 23; i++) { for (int j = 0; j <= 23; j++) { if (this->ter(i,j) == t_floor && one_in(80)) - spawn_item(i, j, "badge_deputy", 0); + spawn_item(i, j, "badge_deputy"); } } @@ -9987,7 +9985,7 @@ case ot_farm_field: square_furn(this, f_counter, 5, 4, 6, 8); place_items("hospital_lab", 74, 5, 4, 6, 8, false, 0); square_furn(this, f_counter, 10, 4, 11, 8); - spawn_item(5, 17, "record_patient", 0); + spawn_item(5, 17, "record_patient"); place_items("hospital_lab", 74, 10, 4, 11, 8, false, 0); square_furn(this, f_counter, 15, 4, 16, 8); place_items("hospital_lab", 74, 15, 4, 16, 8, false, 0); @@ -11208,7 +11206,7 @@ case ot_farm_field: int num_weed = rng(0, 4) * rng(0, 1); for (int n = 0; n < num_weed; n++) { int x = rng(i, i + 2), y = rng(j, j + 2); - spawn_item(x, y, one_in(5)?"seed_weed":"weed", 0); + spawn_item(x, y, one_in(5)?"seed_weed":"weed"); } } } @@ -11650,19 +11648,19 @@ case ot_farm_field: ter_set(3, 2, t_water_sh); ter_set(3, 3, t_water_sh); } else { - spawn_item( 5, SEEY + 1, "helmet_bike", 0); - spawn_item( 4, SEEY + 1, "backpack", 0); - spawn_item( 3, SEEY + 1, "pants_cargo", 0); - spawn_item( 7, SEEY * 2 - 4, "machete", 0); - spawn_item( 7, SEEY * 2 - 4, "9mm", 0); - spawn_item( 7, SEEY * 2 - 4, "9mmP", 0); - spawn_item( 7, SEEY * 2 - 4, "uzi", 0); - spawn_item(SEEX * 2 - 2, SEEY + 5, "bubblewrap", 0); - spawn_item(SEEX * 2 - 2, SEEY + 6, "grenade", 0); - spawn_item(SEEX * 2 - 3, SEEY + 6, "flashlight", 0); - spawn_item(SEEX * 2 - 2, SEEY + 7, "cig", 0); - spawn_item(SEEX * 2 - 2, SEEY + 7, "codeine", 0); - spawn_item(SEEX * 2 - 3, SEEY + 7, "water", 0); + spawn_item( 5, SEEY + 1, "helmet_bike"); + spawn_item( 4, SEEY + 1, "backpack"); + spawn_item( 3, SEEY + 1, "pants_cargo"); + spawn_item( 7, SEEY * 2 - 4, "machete"); + spawn_item( 7, SEEY * 2 - 4, "9mm"); + spawn_item( 7, SEEY * 2 - 4, "9mmP"); + spawn_item( 7, SEEY * 2 - 4, "uzi"); + spawn_item(SEEX * 2 - 2, SEEY + 5, "bubblewrap"); + spawn_item(SEEX * 2 - 2, SEEY + 6, "grenade"); + spawn_item(SEEX * 2 - 3, SEEY + 6, "flashlight"); + spawn_item(SEEX * 2 - 2, SEEY + 7, "cig"); + spawn_item(SEEX * 2 - 2, SEEY + 7, "codeine"); + spawn_item(SEEX * 2 - 3, SEEY + 7, "water"); ter_set(SEEX - 2, SEEY + 2, t_stairs_down); } break; @@ -11728,11 +11726,11 @@ case ot_farm_field: y = rng(0, SEEY * 2 - 1); } while (move_cost(x, y) == 0); if (!one_in(3)) - spawn_item(x, y, "jackhammer", 0); + spawn_item(x, y, "jackhammer"); if (one_in(3)) - spawn_item(x, y, "mask_dust", 0); + spawn_item(x, y, "mask_dust"); if (one_in(2)) - spawn_item(x, y, "hat_hard", 0); + spawn_item(x, y, "hat_hard"); while (!one_in(3)){ put_items_from("cannedfood", 3, x,y, 0, 0, 0); } @@ -11930,7 +11928,7 @@ void map::place_spawns(game *g, std::string group, const int chance, } while( move_cost(x, y) == 0 && tries ); // Pick a monster type - MonsterGroupResult spawn_details = MonsterGroupManager::GetResultFromGroup( group, &g->mtypes, &num ); + MonsterGroupResult spawn_details = MonsterGroupManager::GetResultFromGroup( group, &num ); add_spawn(spawn_details.name, spawn_details.pack_size, x, y); } @@ -11977,14 +11975,14 @@ int map::place_items(items_location loc, int chance, int x1, int y1, (!ongrass && !terlist[ter(px, py)].has_flag("FLAT") )) && tries < 20); if (tries < 20) { - spawn_item(px, py, selected_item, turn); + spawn_item(px, py, selected_item, 1, 0, turn); item_num++; // Guns in the home and behind counters are generated with their ammo // TODO: Make this less of a hack if (item_controller->find_template(selected_item)->is_gun() && (loc == "homeguns" || loc == "behindcounter")) { it_gun* tmpgun = dynamic_cast (item_controller->find_template(selected_item)); - spawn_item(px, py, default_ammo(tmpgun->ammo), turn); + spawn_item(px, py, default_ammo(tmpgun->ammo), 1, 0, turn); } } } @@ -11995,7 +11993,7 @@ void map::put_items_from(items_location loc, int num, int x, int y, int turn, in { for (int i = 0; i < num; i++) { Item_tag selected_item = item_controller->id_from(loc); - spawn_item(x, y, selected_item, turn, quantity, charges, damlevel); + spawn_item(x, y, selected_item, quantity, charges, turn, damlevel); } } @@ -13450,27 +13448,27 @@ x: %d - %d, dx: %d cx: %d/%d", x1, x2, dx, cx_low, cx_hi, if (one_in(6)) { // Suits of armor int start = y1 + rng(2, 4), end = y2 - rng(0, 4), step = rng(3, 6); for (int y = start; y <= end; y += step) { - m->spawn_item(x1 + 1, y, "helmet_plate", 0); - m->spawn_item(x1 + 1, y, "armor_plate", 0); + m->spawn_item(x1 + 1, y, "helmet_plate"); + m->spawn_item(x1 + 1, y, "armor_plate"); if (one_in(2)) - m->spawn_item(x1 + 1, y, "pike", 0); + m->spawn_item(x1 + 1, y, "pike"); else if (one_in(3)) - m->spawn_item(x1 + 1, y, "broadsword", 0); + m->spawn_item(x1 + 1, y, "broadsword"); else if (one_in(6)) - m->spawn_item(x1 + 1, y, "mace", 0); + m->spawn_item(x1 + 1, y, "mace"); else if (one_in(6)) - m->spawn_item(x1 + 1, y, "morningstar", 0); + m->spawn_item(x1 + 1, y, "morningstar"); - m->spawn_item(x2 - 1, y, "helmet_plate", 0); - m->spawn_item(x2 - 1, y, "armor_plate", 0); + m->spawn_item(x2 - 1, y, "helmet_plate"); + m->spawn_item(x2 - 1, y, "armor_plate"); if (one_in(2)) - m->spawn_item(x2 - 1, y, "pike", 0); + m->spawn_item(x2 - 1, y, "pike"); else if (one_in(3)) - m->spawn_item(x2 - 1, y, "broadsword", 0); + m->spawn_item(x2 - 1, y, "broadsword"); else if (one_in(6)) - m->spawn_item(x2 - 1, y, "mace", 0); + m->spawn_item(x2 - 1, y, "mace"); else if (one_in(6)) - m->spawn_item(x2 - 1, y, "morningstar", 0); + m->spawn_item(x2 - 1, y, "morningstar"); } } break; @@ -13771,7 +13769,7 @@ void map::add_extra(map_extra type, game *g) } } - spawn_item(rng(5,18), rng(5,18), "black_box", 0); + spawn_item(rng(5,18), rng(5,18), "black_box"); place_items("helicopter", 90, cx - 4, cy - 4, cx + 4, cy + 4, true, 0); place_items("helicopter", 20, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0); items_location extra_items = "helicopter"; @@ -13801,7 +13799,7 @@ void map::add_extra(map_extra type, game *g) add_item(x, y, body); place_items("military", 86, x, y, x, y, true, 0); if (one_in(8)) - spawn_item(x, y, "id_military", 0); + spawn_item(x, y, "id_military"); } } place_spawns(g, "GROUP_MAYBE_MIL", 2, 0, 0, SEEX * 2 - 1, SEEX * 2 - 1, 0.1f);//0.1 = 1-5 @@ -13822,7 +13820,7 @@ void map::add_extra(map_extra type, game *g) if (tries < 10) { // We found a valid spot! add_item(x, y, body); - spawn_item(x, y, "id_science", 0); + spawn_item(x, y, "id_science"); place_items("science", 84, x, y, x, y, true, 0); } } @@ -13941,7 +13939,7 @@ void map::add_extra(map_extra type, game *g) drugs_placed = num_drugs; num_drugs = 0; } - spawn_item(x, y, drugtype, 0, 0, drugs_placed); + spawn_item(x, y, drugtype, 0, drugs_placed); } } } @@ -13975,7 +13973,7 @@ void map::add_extra(map_extra type, game *g) drugs_placed = num_drugs; num_drugs = 0; } - spawn_item(x, y, drugtype, 0, 0, drugs_placed); + spawn_item(x, y, drugtype, 0, drugs_placed); } } } @@ -14105,7 +14103,7 @@ void map::add_extra(map_extra type, game *g) artifact_natural_property prop = artifact_natural_property(rng(ARTPROP_NULL + 1, ARTPROP_MAX - 1)); create_anomaly(center.x, center.y, prop); - spawn_artifact(center.x, center.y, g->new_natural_artifact(prop), 0); + spawn_artifact(center.x, center.y, new_natural_artifact(g->itypes, prop), 0); } break; default: break; @@ -14123,7 +14121,7 @@ void map::create_anomaly(int cx, int cy, artifact_natural_property prop) if (ter(i, j) == t_rubble) { add_field(NULL, i, j, fd_push_items, 1); if (one_in(3)) - spawn_item(i, j, "rock", 0); + spawn_item(i, j, "rock"); } } } diff --git a/mapgenformat.h b/mapgenformat.h index 5a64b1bad2e8b..4d118ff5eb38c 100644 --- a/mapgenformat.h +++ b/mapgenformat.h @@ -57,29 +57,33 @@ namespace internal virtual int operator ()(map* m, const int x, const int y) = 0; }; - class statically_determine_terrain : public determine_terrain - { - private: - int id; - public: - statically_determine_terrain():id(0) {} - statically_determine_terrain(int pid):id(pid) {} - virtual ~statically_determine_terrain() {} - virtual int operator ()(map* m, const int x, const int y){return id;} - }; - - class determine_terrain_with_simple_method : public determine_terrain - { - public: - typedef ter_id (*ter_id_func)(); - private: - ter_id_func f; - public: - determine_terrain_with_simple_method():f(NULL) {} - determine_terrain_with_simple_method(ter_id_func pf):f(pf) {} - virtual ~determine_terrain_with_simple_method() {} - virtual int operator ()(map* m, const int x, const int y){return f();} - }; + class statically_determine_terrain : public determine_terrain + { + private: + int id; + public: + statically_determine_terrain() : id(0) {} + statically_determine_terrain(int pid) : id(pid) {} + virtual ~statically_determine_terrain() {} + virtual int operator ()(map *, const int /*x*/, const int /*y*/) { + return id; + } + }; + + class determine_terrain_with_simple_method : public determine_terrain + { + public: + typedef ter_id (*ter_id_func)(); + private: + ter_id_func f; + public: + determine_terrain_with_simple_method() : f(NULL) {} + determine_terrain_with_simple_method(ter_id_func pf) : f(pf) {} + virtual ~determine_terrain_with_simple_method() {} + virtual int operator ()(map *, const int /*x*/, const int /*y*/) { + return f(); + } + }; //TODO: make use of this class determine_terrain_with_complex_method : public determine_terrain diff --git a/martialarts.cpp b/martialarts.cpp index f7aca8ee10c92..06da666987923 100644 --- a/martialarts.cpp +++ b/martialarts.cpp @@ -321,8 +321,10 @@ int ma_buff::block_bonus(player& u) { u.int_cur*block_int + u.per_cur*block_per; } -int ma_buff::speed_bonus(player& u) { - return speed; +int ma_buff::speed_bonus(player& u) +{ + (void)u; //unused + return speed; } float ma_buff::bash_mult() { return bash_stat_mult; diff --git a/material.cpp b/material.cpp index a7bcdc540793f..e99e0b227f7c3 100644 --- a/material.cpp +++ b/material.cpp @@ -36,7 +36,7 @@ material_type::material_type(std::string ident, std::string name, _bash_resist = bash_resist; _cut_resist = cut_resist; _bash_dmg_verb = bash_dmg_verb; - _cut_dmg_verb = bash_dmg_verb; + _cut_dmg_verb = cut_dmg_verb; _dmg_adj[0] = dmg_adj[0]; _dmg_adj[1] = dmg_adj[1]; _dmg_adj[2] = dmg_adj[2]; diff --git a/melee.cpp b/melee.cpp index 524ac0e1b769a..50ef92ebc479f 100644 --- a/melee.cpp +++ b/melee.cpp @@ -14,7 +14,7 @@ void player_hit_message(game* g, player* attacker, std::string message, std::string target_name, int dam, bool crit); void melee_practice(const calendar& turn, player &u, bool hit, bool unarmed, bool bashing, bool cutting, bool stabbing); -int attack_speed(player &u, bool missed); +int attack_speed(player &u); int stumble(player &u); std::string melee_message(matec_id tech, player &p, int bash_dam, int cut_dam, int stab_dam); @@ -142,7 +142,7 @@ int player::hit_mon(game *g, monster *z, bool allow_grab) // defaults to true bool missed = (hit_roll() < mondodge || one_in(4 + dex_cur + weapon.type->m_to_hit)); - int move_cost = attack_speed(*this, missed); + int move_cost = attack_speed(*this); if (missed) { int stumble_pen = stumble(*this); @@ -242,7 +242,7 @@ void player::hit_player(game *g, player &p, bool allow_grab) int hit_value = hit_roll() - target_dodge; bool missed = (hit_roll() <= 0); - int move_cost = attack_speed(*this, missed); + int move_cost = attack_speed(*this); if (missed) { int stumble_pen = stumble(*this); @@ -683,10 +683,10 @@ int player::roll_stab_damage(monster *z, bool crit) // Weapons can have a "low_stick" flag indicating they // Have a feature to prevent sticking, such as a spear with a crossbar, // Or a stabbing blade designed to resist sticking. -int player::roll_stuck_penalty(monster *z, bool stabbing) +int player::roll_stuck_penalty(bool stabbing) { // The cost of the weapon getting stuck, in units of move points. - const int weapon_speed = attack_speed( *this, false ); + const int weapon_speed = attack_speed(*this); int stuck_cost = weapon_speed; const int attack_skill = stabbing ? skillLevel("stabbing") : skillLevel("cutting"); const float cut_damage = weapon.damage_cut(); @@ -742,6 +742,8 @@ int player::roll_stuck_penalty(monster *z, bool stabbing) matec_id player::pick_technique(game *g, monster *z, player *p, bool crit, bool allowgrab) { + (void)allowgrab; //FIXME: is this supposed to be being used for something? + if (z == NULL && p == NULL) return "tec_none"; @@ -817,7 +819,7 @@ matec_id player::pick_technique(game *g, monster *z, player *p, } bool player::has_technique(matec_id id) { - return weapon.has_technique(id, this) || + return weapon.has_technique(id) || martialarts[style_selected].has_technique(*this, id); } @@ -825,6 +827,9 @@ void player::perform_technique(ma_technique technique, game *g, monster *z, player *p, int &bash_dam, int &cut_dam, int &stab_dam, int &pain) { + (void)cut_dam; //FIXME: this should probably be being used for something + (void)stab_dam; //FIXME: this should probably be being used for something + const bool mon = (z != NULL); const bool npc = (p != NULL && p->is_npc()); const bool you = (p == &(g->u)); @@ -842,7 +847,7 @@ void player::perform_technique(ma_technique technique, game *g, monster *z, int tarx = (mon ? z->posx() : p->posx), tary = (mon ? z->posy() : p->posy); if (technique.quick) { - moves += int( attack_speed(*this, false) / 2); + moves += int(attack_speed(*this) / 2); return; } // The rest affect our target, and thus depend on z vs. p @@ -937,25 +942,27 @@ void player::perform_technique(ma_technique technique, game *g, monster *z, // this would be i2amroy's fix, but it's kinda handy bool player::can_weapon_block() { - return (weapon.has_technique("WBLOCK_1", this) || - weapon.has_technique("WBLOCK_2", this) || - weapon.has_technique("WBLOCK_3", this)); + return (weapon.has_technique("WBLOCK_1") || + weapon.has_technique("WBLOCK_2") || + weapon.has_technique("WBLOCK_3")); } bool player::block_hit(game *g, monster *z, player *p, body_part &bp_hit, int &side, int &bash_dam, int &cut_dam, int &stab_dam) { + (void)z; //FIXME: this should probably be being used for something + (void)p; //FIXME: this should probably be being used for something if (blocks_left <= 0) return false; // if weapon, then extra reduction if (!unarmed_attack() && (can_arm_block() || can_weapon_block())) { float mult = 1.0f; - if (weapon.has_technique("WBLOCK_1",this)) { + if (weapon.has_technique("WBLOCK_1")) { mult = 0.4; - } else if (weapon.has_technique("WBLOCK_2",this)) { + } else if (weapon.has_technique("WBLOCK_2")) { mult = 0.15; - } else if (weapon.has_technique("WBLOCK_3",this)) { + } else if (weapon.has_technique("WBLOCK_3")) { mult = 0.05; } else { mult = 0.5; // always at least as good as unarmed @@ -1200,7 +1207,7 @@ void player::melee_special_effects(game *g, monster *z, player *p, bool crit, } // Getting your weapon stuck - int cutting_penalty = roll_stuck_penalty(z, stab_dam > cut_dam); + int cutting_penalty = roll_stuck_penalty(stab_dam > cut_dam); if (weapon.has_flag("MESSY")) { // e.g. chainsaws cutting_penalty /= 6; // Harder to get stuck for (int x = tarposx - 1; x <= tarposx + 1; x++) { @@ -1622,7 +1629,7 @@ void melee_practice(const calendar& turn, player &u, bool hit, bool unarmed, if (!third.empty()) u.practice(turn, third, rng(min, max)); } -int attack_speed(player &u, bool missed) +int attack_speed(player &u) { int move_cost = u.weapon.attack_time() + 20 * u.encumb(bp_torso); if (u.has_trait("LIGHT_BONES")) diff --git a/mission.h b/mission.h index 857b21c6687b4..88c238dd24208 100644 --- a/mission.h +++ b/mission.h @@ -7,8 +7,9 @@ #include "omdata.h" #include "itype.h" #include "npc.h" +#include "json.h" -struct mission; +class mission; class game; enum talk_topic; @@ -72,8 +73,8 @@ enum mission_goal { }; struct mission_place { // Return true if [posx,posy] is valid in overmap - bool never (game *g, int posx, int posy) { return false; } - bool always (game *g, int posx, int posy) { return true; } + bool never (game *, int, int) { return false; } + bool always (game *, int, int) { return true; } bool near_town (game *g, int posx, int posy); }; @@ -164,7 +165,9 @@ struct mission_type { mission create(game *g, int npc_id = -1); // Create a mission }; -struct mission { +class mission : public JsonSerializer, public JsonDeserializer +{ +public: mission_type *type; std::string description;// Basic descriptive text bool failed; // True if we've failed it! @@ -185,12 +188,13 @@ struct mission { int step; // How much have we completed? mission_id follow_up; // What mission do we get after this succeeds? - std::string name(); - std::string save_info(); - void load_info(game *g, std::ifstream &info); - - void json_load(picojson::value parsed, game * g); - picojson::value json_save(bool save_contents = false); + std::string name(); + std::string save_info(); + void load_info(game *g, std::ifstream &info); + using JsonSerializer::serialize; + void serialize(JsonOut &jsout) const; + using JsonDeserializer::deserialize; + void deserialize(JsonObject &jsobj); mission() { diff --git a/mission_start.cpp b/mission_start.cpp index dacf12a0981fa..9003987219c0a 100644 --- a/mission_start.cpp +++ b/mission_start.cpp @@ -8,7 +8,7 @@ * updating *miss with the target and any other important information. */ -void mission_start::standard(game *g, mission *miss) +void mission_start::standard(game *, mission *) { } @@ -285,7 +285,7 @@ void mission_start::place_priest_diary(game *g, mission *miss) comppoint = point( rng(6, SEEX * 2 - 7), rng(6, SEEY * 2 - 7) ); else comppoint = valid[rng(0, valid.size() - 1)]; - compmap.spawn_item(comppoint.x, comppoint.y, "priest_diary", 0); + compmap.spawn_item(comppoint.x, comppoint.y, "priest_diary"); compmap.save(g->cur_om, int(g->turn), place.x * 2, place.y * 2, 0); } @@ -331,7 +331,7 @@ void mission_start::place_deposit_box(game *g, mission *miss) comppoint = point( rng(6, SEEX * 2 - 7), rng(6, SEEY * 2 - 7) ); else comppoint = valid[rng(0, valid.size() - 1)]; -compmap.spawn_item(comppoint.x, comppoint.y, "safe_box", 0); +compmap.spawn_item(comppoint.x, comppoint.y, "safe_box"); compmap.save(g->cur_om, int(g->turn), site.x * 2, site.y * 2, 0); } @@ -476,6 +476,6 @@ for (int x = site.x - 2; x <= site.x + 2; x++) { g->cur_om->npcs.push_back(temp); } -void mission_start::place_book(game *g, mission *miss) +void mission_start::place_book(game *, mission *) { } diff --git a/monattack.cpp b/monattack.cpp index ef95449314b12..47139bfa900c9 100644 --- a/monattack.cpp +++ b/monattack.cpp @@ -58,7 +58,7 @@ void mattack::antqueen(game *g, monster *z) } else if (egg_points.size() == 0) { // There's no eggs nearby--lay one. if (g->u_see(z->posx(), z->posy())) g->add_msg(_("The %s lays an egg!"), z->name().c_str()); - g->m.spawn_item(z->posx(), z->posy(), "ant_egg", g->turn); + g->m.spawn_item(z->posx(), z->posy(), "ant_egg", 1, 0, g->turn); } else { // There are eggs nearby. Let's hatch some. z->moves -= 20 * egg_points.size(); // It takes a while if (g->u_see(z->posx(), z->posy())) @@ -693,7 +693,7 @@ void mattack::fungus(game *g, monster *z) g->add_msg(_("The %s is covered in tiny spores!"), g->zombie(mondex).name().c_str()); } - if (!g->zombie(mondex).make_fungus(g)) { + if (!g->zombie(mondex).make_fungus()) { g->kill_mon(mondex, (z->friendly != 0)); } } else if (g->u.posx == sporex && g->u.posy == sporey) { @@ -901,7 +901,8 @@ void mattack::plant(game *g, monster *z) void mattack::disappear(game *g, monster *z) { - z->hp = 0; + (void)g; //unused + z->hp = 0; } void mattack::formblob(game *g, monster *z) diff --git a/monattack.h b/monattack.h index cd264e38a63b0..ae72946876399 100644 --- a/monattack.h +++ b/monattack.h @@ -12,7 +12,7 @@ struct SpeechBubble { class mattack { public: - void none (game *g, monster *z){}; + void none (game *, monster *) {}; void antqueen (game *g, monster *z); void shriek (game *g, monster *z); void rattle (game *g, monster *z); diff --git a/mondeath.cpp b/mondeath.cpp index c7450e1c56242..db197577dad6f 100644 --- a/mondeath.cpp +++ b/mondeath.cpp @@ -174,7 +174,7 @@ void mdeath::fungus(game *g, monster *z) { g->add_msg(_("The %s is covered in tiny spores!"), g->zombie(mondex).name().c_str()); } - if (!g->zombie(mondex).make_fungus(g)) { + if (!g->zombie(mondex).make_fungus()) { g->kill_mon(mondex, (z->friendly != 0)); } } else if (g->u.posx == sporex && g->u.posy == sporey) { @@ -282,7 +282,7 @@ void mdeath::guilt(game *g, monster *z) { } void mdeath::blobsplit(game *g, monster *z) { int speed = z->speed - rng(30, 50); - g->m.spawn_item(z->posx(), z->posy(), "slime_scrap", g->turn, 0, 0, rng(5,10)); + g->m.spawn_item(z->posx(), z->posy(), "slime_scrap", 1, 0, g->turn, rng(5,10)); if (speed <= 0) { if (g->u_see(z)) { // TODO: Add vermin-tagged tiny versions of the splattered blob :) @@ -339,7 +339,7 @@ void mdeath::amigara(game *g, monster *z) { if (count <= 1) { // We're the last! g->u.rem_disease("amigara"); g->add_msg(_("Your obsession with the fault fades away...")); - item art(g->new_artifact(), g->turn); + item art(new_artifact(g->itypes), g->turn); g->m.add_item_or_charges(z->posx(), z->posy(), art); } normal(g, z); @@ -471,7 +471,7 @@ void mdeath::zombie(game *g, monster *z) { break; case 4: // mon_zombie_hulk - g->m.spawn_item(z->posx(), z->posy(), "rag", g->turn, 0, 0, rng(5,10)); + g->m.spawn_item(z->posx(), z->posy(), "rag", 1, 0, g->turn, rng(5,10)); g->m.put_items_from("pants", 1, z->posx(), z->posy(), g->turn, 0, 0, rng(1,4)); break; @@ -493,7 +493,9 @@ void mdeath::gameover(game *g, monster *z) { g->u.hp_cur[hp_torso] = 0; } -void mdeath::kill_breathers(game *g, monster *z) { +void mdeath::kill_breathers(game *g, monster *z) +{ + (void)z; //unused for (int i = 0; i < g->num_zombies(); i++) { const std::string monID = g->zombie(i).type->id; if (monID == "mon_breather_hub " || monID == "mon_breather") { diff --git a/mongroup.h b/mongroup.h index 010621021a56d..35eebff19b6ff 100644 --- a/mongroup.h +++ b/mongroup.h @@ -88,8 +88,8 @@ struct mongroup { class MonsterGroupManager { public: static void LoadMonsterGroup(JsonObject &jo); - static MonsterGroupResult GetResultFromGroup(std::string, std::vector *, - int *quantity = 0, int turn = -1); + static MonsterGroupResult GetResultFromGroup(std::string, + int *quantity = 0, int turn = -1); static bool IsMonsterInGroup(std::string, std::string); static std::string Monster2Group(std::string); static std::vector GetMonstersFromGroup(std::string); diff --git a/mongroupdef.cpp b/mongroupdef.cpp index f5f062a78fe5e..0326d9caa8398 100644 --- a/mongroupdef.cpp +++ b/mongroupdef.cpp @@ -30,8 +30,8 @@ std::map MonsterGroupManager::monsterGroupMap; //Quantity is adjusted directly as a side effect of this function -MonsterGroupResult MonsterGroupManager::GetResultFromGroup( std::string group_name, std::vector *mtypes, - int *quantity, int turn ) +MonsterGroupResult MonsterGroupManager::GetResultFromGroup( + std::string group_name, int *quantity, int turn ) { int spawn_chance = rng(1, 1000); MonsterGroup group = monsterGroupMap[group_name]; diff --git a/monster.cpp b/monster.cpp index 567fb4ebacf31..4bcbbb7622833 100644 --- a/monster.cpp +++ b/monster.cpp @@ -342,7 +342,7 @@ bool monster::made_of(phase_id p) return false; } -void monster::load_info(std::string data, std::vector *mtypes) +void monster::load_info(std::string data) { std::stringstream dump; dump << data; @@ -353,11 +353,11 @@ void monster::load_info(std::string data, std::vector *mtypes) if ( ! jsonerr.empty() ) { debugmsg("Bad monster json\n%s", jsonerr.c_str() ); } else { - json_load(pdata, mtypes); + json_load(pdata); } return; } else { - load_legacy(mtypes, dump); + load_legacy(dump); } } @@ -809,7 +809,7 @@ void monster::drop_items_on_death(game *g) // We have selected a string representing an item group, now // get a random item tag from it and spawn it. Item_tag selected_item = item_controller->id_from(it[selected_location].loc); - g->m.spawn_item(_posx, _posy, selected_item, 0); + g->m.spawn_item(_posx, _posy, selected_item); if (type->item_chance < 0) { @@ -883,7 +883,7 @@ void monster::process_effects(game *g) } } -bool monster::make_fungus(game *g) +bool monster::make_fungus() { char polypick = 0; std::string tid = type->id; diff --git a/monster.h b/monster.h index 69153ecacc1a3..41ddd8862e379 100644 --- a/monster.h +++ b/monster.h @@ -73,10 +73,10 @@ class monster { int vision_range(int x, int y); // Returns monster vision range, x and y are the target spot bool made_of(std::string m); // Returns true if it's made of m bool made_of(phase_id p); // Returns true if its phase is p - bool json_load(picojson::value parsed, std::vector *mtypes); + bool json_load(picojson::value parsed); void json_load(picojson::value parsed, game * g); - void load_legacy(std::vector *mtypes, std::stringstream & dump); - void load_info(std::string data, std::vector *mtypes); + void load_legacy(std::stringstream & dump); + void load_info(std::string data); virtual picojson::value json_save(bool save_contents = false); std::string save_info(); // String of all data, for save files @@ -184,7 +184,7 @@ class monster { bool has_effect(monster_effect_type effect); // True if we have the effect void rem_effect(monster_effect_type effect); // Remove a given effect void process_effects(game *g); // Process long-term effects - bool make_fungus(game *g); // Makes this monster into a fungus version + bool make_fungus(); // Makes this monster into a fungus version // Returns false if no such monster exists void make_friendly(); void add_item(item it); // Add an item to inventory diff --git a/msvc100/Cataclysm.vcxproj b/msvc100/Cataclysm.vcxproj index ae669a54030e3..8a667c606f5f5 100644 --- a/msvc100/Cataclysm.vcxproj +++ b/msvc100/Cataclysm.vcxproj @@ -872,7 +872,6 @@ - diff --git a/msvc100/Cataclysm.vcxproj.filters b/msvc100/Cataclysm.vcxproj.filters index 6445e24117dab..25fbe95835263 100644 --- a/msvc100/Cataclysm.vcxproj.filters +++ b/msvc100/Cataclysm.vcxproj.filters @@ -374,9 +374,6 @@ Header Files - - Header Files - Header Files diff --git a/msvc110/Cataclysm.vcxproj b/msvc110/Cataclysm.vcxproj index 79cde4aacb396..7f9063ef20103 100644 --- a/msvc110/Cataclysm.vcxproj +++ b/msvc110/Cataclysm.vcxproj @@ -964,7 +964,6 @@ - diff --git a/msvc110/Cataclysm.vcxproj.filters b/msvc110/Cataclysm.vcxproj.filters index 0d93c86e8d223..a6218d2b2fe88 100644 --- a/msvc110/Cataclysm.vcxproj.filters +++ b/msvc110/Cataclysm.vcxproj.filters @@ -386,9 +386,6 @@ Header Files - - Header Files - Header Files diff --git a/msvc120/Cataclysm.vcxproj b/msvc120/Cataclysm.vcxproj index 43de506f8d9a4..19fd17434f398 100644 --- a/msvc120/Cataclysm.vcxproj +++ b/msvc120/Cataclysm.vcxproj @@ -1098,7 +1098,6 @@ - diff --git a/msvc120/Cataclysm.vcxproj.filters b/msvc120/Cataclysm.vcxproj.filters index c2a64c9a1899b..bcfa3b8b03d89 100644 --- a/msvc120/Cataclysm.vcxproj.filters +++ b/msvc120/Cataclysm.vcxproj.filters @@ -353,9 +353,6 @@ Header Files - - Header Files - Header Files diff --git a/npc.cpp b/npc.cpp index ca31c1be1e508..98a7f7059cb38 100644 --- a/npc.cpp +++ b/npc.cpp @@ -1923,7 +1923,7 @@ void npc::die(game *g, bool your_fault) dead = true; if (in_vehicle) { - g->m.unboard_vehicle(g, posx, posy); + g->m.unboard_vehicle(posx, posy); } if (g->u_see(posx, posy)) { diff --git a/npc.h b/npc.h index 53b418b76ce2a..785313ce130c0 100644 --- a/npc.h +++ b/npc.h @@ -5,6 +5,8 @@ #include "monster.h" #include "overmap.h" #include "faction.h" +#include "json.h" + #include #include #include @@ -126,22 +128,28 @@ enum npc_favor_type { NUM_FAVOR_TYPES }; -struct npc_favor +class npc_favor : public JsonSerializer, public JsonDeserializer { - npc_favor_type type; - int value; - itype_id item_id; - Skill *skill; - - npc_favor() { - type = FAVOR_NULL; - value = 0; - item_id = "null"; - skill = NULL; - }; - picojson::value json_save(); - bool json_load(std::map & data); - +public: + npc_favor_type type; + int value; + itype_id item_id; + Skill *skill; + + npc_favor() { + type = FAVOR_NULL; + value = 0; + item_id = "null"; + skill = NULL; + }; + + bool json_load(std::map & data); + picojson::value json_save(); + + using JsonSerializer::serialize; + using JsonDeserializer::deserialize; + void serialize(JsonOut &json) const; + void deserialize(JsonObject &jo); }; struct npc_personality { diff --git a/npcmove.cpp b/npcmove.cpp index f45a4d2ef7c43..fa57fc9900c2d 100644 --- a/npcmove.cpp +++ b/npcmove.cpp @@ -990,7 +990,7 @@ void npc::move_to(game *g, int x, int y) } else { if (in_vehicle) { // TODO: handle this nicely - npcs should not jump from moving vehicles - g->m.unboard_vehicle(g, posx, posy); + g->m.unboard_vehicle(posx, posy); } else { diff --git a/omdata.h b/omdata.h index 05a97dedaf615..92ff968e3a864 100644 --- a/omdata.h +++ b/omdata.h @@ -187,8 +187,8 @@ NUM_OMS_FLAGS struct omspec_place { // Able functions - true if p is valid - bool never (overmap *om, unsigned long f, tripoint p) { return false; } - bool always (overmap *om, unsigned long f, tripoint p) { return true; } + bool never (overmap *, unsigned long, tripoint) { return false; } + bool always (overmap *, unsigned long, tripoint) { return true; } bool water (overmap *om, unsigned long f, tripoint p); // Only on rivers bool land (overmap *om, unsigned long f, tripoint p); // Only on land (no rivers) bool forest (overmap *om, unsigned long f, tripoint p); // Forest diff --git a/output.h b/output.h index 13c35684dad3a..2ae170b86d135 100644 --- a/output.h +++ b/output.h @@ -90,6 +90,7 @@ int compare_split_screen_popup(int iLeft, int iWidth, int iHeight, std::string s char rand_char(); long special_symbol (long sym); +// TODO: move these elsewhere // string manipulations. std::string from_sentence_case (const std::string &kingston); std::string string_format(std::string pattern, ...); diff --git a/player.h b/player.h index 15f201bb9d3b0..fa3fbdd057cc9 100644 --- a/player.h +++ b/player.h @@ -21,7 +21,7 @@ class monster; class game; struct trap; -struct mission; +class mission; class profession; struct special_attack @@ -193,7 +193,7 @@ class player { int roll_bash_damage(monster *z, bool crit); int roll_cut_damage(monster *z, bool crit); int roll_stab_damage(monster *z, bool crit); - int roll_stuck_penalty(monster *z, bool stabbing); + int roll_stuck_penalty(bool stabbing); std::vector get_all_techniques(); diff --git a/savegame_json.cpp b/savegame_json.cpp index 531d67e72f26f..4a055c4b68d66 100644 --- a/savegame_json.cpp +++ b/savegame_json.cpp @@ -31,6 +31,7 @@ #include #include "picofunc.h" +#include "json.h" #include "debug.h" #define dbg(x) dout((DebugLevel)(x),D_GAME) << __FILE__ << ":" << __LINE__ << ": " @@ -858,6 +859,31 @@ picojson::value npc_favor::json_save() { return pv( data ); } +void npc_favor::deserialize(JsonObject &jo) +{ + type = npc_favor_type(jo.get_int("type")); + value = jo.get_int("value"); + item_id = jo.get_string("itype_id"); + skill = NULL; + if (jo.has_int("skill_id")) { + skill = Skill::skill(jo.get_int("skill_id")); + } else if (jo.has_string("skill_id")) { + skill = Skill::skill(jo.get_string("skill_id")); + } +} + +void npc_favor::serialize(JsonOut &json) const +{ + json.start_object(); + json.member("type", (int)type); + json.member("value", value); + json.member("itype_id", (std::string)item_id); + if (skill != NULL) { + json.member("skill_id", skill->ident()); + } + json.end_object(); +} + /* * load npc */ @@ -1077,7 +1103,7 @@ void inventory::json_load_items(picojson::value & parsed, game * g) { //////////////////////////////////////////////////////////////////////////////////////////////////// ///// monster.h -bool monster::json_load(picojson::value parsed, std::vector *mtypes) +bool monster::json_load(picojson::value parsed) { const picojson::object &data = parsed.get(); @@ -1141,9 +1167,9 @@ bool monster::json_load(picojson::value parsed, std::vector *mtypes) return true; } -void monster::json_load(picojson::value parsed, game * g) { - std::vector *mt=&(g->mtypes); - json_load(parsed, mt); +void monster::json_load(picojson::value parsed, game * g) +{ + json_load(parsed); } /* @@ -1551,125 +1577,117 @@ picojson::value vehicle::json_save( bool save_contents ) { ////////////////// mission.h //// -void mission::json_load(picojson::value parsed, game * g) { - if ( ! parsed.is() ) { - debugmsg("mission::json_load: bad json:\n%s",parsed.serialize().c_str() ); - } - picojson::object &data = parsed.get(); - int type_id, tmpfollow; - std::string rew_item, itemid; - // todo; if( picostring(data, "type_id", .... - picoint(data, "type_id", type_id); - type = &(g->mission_types[type_id]); - picostring(data, "description", description); - picobool(data, "failed", failed); - picoint(data, "value", value); - picojson::object * pobj=pgetmap(data,"reward"); - - if ( pobj != NULL ) { - reward.json_load( *pobj ); - } - - picoint(data, "uid", uid ); - picopoint(data, "target", target); - picoint(data, "follow_up", tmpfollow ); - follow_up = mission_id(tmpfollow); - picostring(data, "item_id", itemid); - item_id = itype_id(itemid); - picoint(data, "deadline", deadline ); - picoint(data, "step", step ); - picoint(data, "count", count ); - picoint(data, "npc_id", npc_id ); - picoint(data, "good_fac_id", good_fac_id ); - picoint(data, "bad_fac_id", bad_fac_id ); +void mission::deserialize(JsonObject &jo) +{ + if (jo.has_member("type_id")) { + type = &(g->mission_types[jo.get_int("type_id")]); + } + description = jo.get_string("description", description); + failed = jo.get_bool("failed", failed); + value = jo.get_int("value", value); + if (jo.has_object("reward")) { + JsonObject rew = jo.get_object("reward"); + reward.deserialize(rew); + } + uid = jo.get_int("uid", uid ); + JsonArray ja = jo.get_array("target"); + if (ja.size() == 2) { + target.x = ja.get_int(0); + target.y = ja.get_int(1); + } + follow_up = mission_id(jo.get_int("follow_up", follow_up)); + item_id = itype_id(jo.get_string("item_id", item_id)); + deadline = jo.get_int("deadline", deadline ); + step = jo.get_int("step", step ); + count = jo.get_int("count", count ); + npc_id = jo.get_int("npc_id", npc_id ); + good_fac_id = jo.get_int("good_fac_id", good_fac_id ); + bad_fac_id = jo.get_int("bad_fac_id", bad_fac_id ); } -picojson::value mission::json_save(bool save_contents) { - std::map data; - data["type_id"] = pv(type == NULL ? -1 : (int)type->id); - data["description"] = pv ( description ); - data["failed"] = pv( failed ); - data["value"] = pv( value ); - data["reward"] = pv( reward.json_save() ); - data["uid"] = pv( uid ); - std::vector ptmp; - ptmp.push_back( pv( target.x ) ); - ptmp.push_back( pv( target.y ) ); - data["target"] = pv ( ptmp ); - data["count"] = pv( count ); - data["deadline"] = pv( deadline ); - data["npc_id"] = pv( npc_id ); - data["good_fac_id"] = pv( good_fac_id ); - data["bad_fac_id"] = pv( bad_fac_id ); - data["step"] = pv( step ); - data["follow_up"] = pv( (int)follow_up ); - return pv( data ); +void mission::serialize(JsonOut &json) const +{ + json.start_object(); + + json.member("type_id", type == NULL ? -1 : (int)type->id); + json.member("description", description); + json.member("failed", failed); + json.member("value", value); + json.member("reward", reward); + json.member("uid", uid); + + json.member("target"); + json.start_array(); + json.write(target.x); + json.write(target.y); + json.end_array(); + + json.member("count", count); + json.member("deadline", deadline); + json.member("npc_id", npc_id); + json.member("good_fac_id", good_fac_id); + json.member("bad_fac_id", bad_fac_id); + json.member("step", step); + json.member("follow_up", (int)follow_up); + + json.end_object(); } ////////////////// faction.h //// -void faction::json_load(picojson::value parsed, game * g) { - if ( ! parsed.is() ) { - debugmsg("mission::json_load: bad json:\n%s",parsed.serialize().c_str() ); - } - picojson::object &data = parsed.get(); - int valuetmp, goaltmp, jobtmp1, jobtmp2; - picoint(data, "id", id); - picoint(data, "goal", goaltmp ); - picoint(data, "values", valuetmp ); - picoint(data, "job1", jobtmp1 ); - picoint(data, "job2", jobtmp2 ); - values = valuetmp; - goal = faction_goal(goaltmp); - job1 = faction_job(jobtmp1); - job2 = faction_job(jobtmp2); - picoint(data, "likes_u", likes_u); - picoint(data, "respects_u", respects_u); - picobool(data, "known_by_u", known_by_u); - - picoint(data, "strength", strength); - picoint(data, "sneak", sneak); - picoint(data, "crime", crime); - picoint(data, "cult", cult); - picoint(data, "good", good); - picoint(data, "omx", omx); - picoint(data, "omy", omy); - picoint(data, "mapx", mapx); - picoint(data, "mapy", mapy); - picoint(data, "size", size); - picoint(data, "power", power); - picojson::array * parray = pgetarray(data,"opinion_of"); - for( picojson::array::iterator pt = parray->begin(); pt != parray->end(); ++pt) { - if ( (*pt).is() ) { - opinion_of.push_back( (int)(*pt).get() ); - } +void faction::deserialize(JsonObject &jo) +{ + id = jo.get_int("id", id); + name = jo.get_string("name", name); + goal = faction_goal(jo.get_int("goal", goal)); + values = jo.get_int("values", values); + job1 = faction_job(jo.get_int("job1", job1)); + job2 = faction_job(jo.get_int("job2", job2)); + likes_u = jo.get_int("likes_u", likes_u); + respects_u = jo.get_int("respects_u", respects_u); + known_by_u = jo.get_int("known_by_u", known_by_u); + strength = jo.get_int("strength", strength); + sneak = jo.get_int("sneak", sneak); + crime = jo.get_int("crime", crime); + cult = jo.get_int("cult", cult); + good = jo.get_int("good", good); + omx = jo.get_int("omx", omx); + omy = jo.get_int("omy", omy); + mapx = jo.get_int("mapx", mapx); + mapy = jo.get_int("mapy", mapy); + size = jo.get_int("size", size); + power = jo.get_int("power", power); + if (jo.has_array("opinion_of")) { + opinion_of = jo.get_int_array("opinion_of"); } - picostring(data,"name",name); } -picojson::value faction::json_save(bool save_contents) { - std::map data; - data["id"] = pv( id ); - data["values"] = pv( (int)values ); - data["goal"] = pv( goal ); - data["job1"] = pv( job1 ); - data["job2"] = pv( job2 ); - data["likes_u"] = pv( likes_u ); - data["respects_u"] = pv( respects_u ); - data["known_by_u"] = pv( known_by_u ); - data["strength"] = pv( strength ); - data["sneak"] = pv( sneak ); - data["crime"] = pv( crime ); - data["cult"] = pv( cult ); - data["good"] = pv( good ); - data["omx"] = pv( omx ); - data["omy"] = pv( omy ); - data["mapx"] = pv( mapx ); - data["mapy"] = pv( mapy ); - data["size"] = pv( size ); - data["power"] = pv( power ); - data["opinion_of"] = json_wrapped_vector( opinion_of ); - data["name"] = pv (name); - return pv( data ); +void faction::serialize(JsonOut &json) const +{ + json.start_object(); + + json.member("id", id); + json.member("name", name); + json.member("values", values); + json.member("goal", goal); + json.member("job1", job1); + json.member("job2", job2); + json.member("likes_u", likes_u); + json.member("respects_u", respects_u); + json.member("known_by_u", known_by_u); + json.member("strength", strength); + json.member("sneak", sneak); + json.member("crime", crime); + json.member("cult", cult); + json.member("good", good); + json.member("omx", omx); + json.member("omy", omy); + json.member("mapx", mapx); + json.member("mapy", mapy); + json.member("size", size); + json.member("power", power); + json.member("opinion_of", opinion_of); + + json.end_object(); } diff --git a/savegame_legacy.cpp b/savegame_legacy.cpp index f0aa8b23dc374..68af8e64f14f0 100644 --- a/savegame_legacy.cpp +++ b/savegame_legacy.cpp @@ -25,7 +25,6 @@ #include #include #include "debug.h" -#include "artifactdata.h" #include "weather.h" #include "monstergenerator.h" // for legacy classdata loaders @@ -135,7 +134,7 @@ bool game::unserialize_legacy(std::ifstream & fin) { for (int i = 0; i < nummon; i++) { getline(fin, data); - montmp.load_info(data, &mtypes); + montmp.load_info(data); add_zombie(montmp); } @@ -225,7 +224,7 @@ bool game::unserialize_legacy(std::ifstream & fin) { for (int i = 0; i < nummon; i++) { getline(fin, data); - montmp.load_info(data, &mtypes); + montmp.load_info(data); fin >> num_items; // Chomp the endline after number of items. @@ -341,7 +340,7 @@ bool game::unserialize_legacy(std::ifstream & fin) { for (int i = 0; i < nummon; i++) { getline(fin, data); - montmp.load_info(data, &mtypes); + montmp.load_info(data); fin >> num_items; // Chomp the endline after number of items. @@ -453,7 +452,7 @@ original 'structure', which globs game/weather/location & killcount/player data fin.get(junk); // Chomp that pesky endline for (int i = 0; i < nummon; i++) { getline(fin, data); - montmp.load_info(data, &mtypes); + montmp.load_info(data); fin >> num_items; // Chomp the endline after number of items. @@ -1068,14 +1067,14 @@ std::istream& operator>>(std::istream& is, SkillLevel& obj) { ///// monster.h -void monster::load_legacy(std::vector *mtypes, std::stringstream & dump) { +void monster::load_legacy(std::stringstream & dump) { int idtmp, plansize; dump >> idtmp >> _posx >> _posy >> wandx >> wandy >> wandf >> moves >> speed >> hp >> sp_timeout >> plansize >> friendly >> faction_id >> mission_id >> no_extra_death_drops >> dead >> anger >> morale; // load->int->str->int (possibly shifted) - type = (*mtypes)[ monster_ints[ legacy_mon_id[ idtmp ] ] ]; + type = GetMType( legacy_mon_id[idtmp] ); point ptmp; plans.clear(); diff --git a/settlement.h b/settlement.h index 7a05f0fc13bcb..3d75a18097e27 100644 --- a/settlement.h +++ b/settlement.h @@ -11,7 +11,7 @@ struct settlement { settlement(int mapx, int mapy); void pick_faction(game *g, int omx, int omy); void set_population(); - void populate(game *g) { }; + void populate(game *) { }; int num(oter_id ter); void add_building(oter_id ter); diff --git a/trap.h b/trap.h index 81101f1597ca0..52676e4664286 100644 --- a/trap.h +++ b/trap.h @@ -56,12 +56,11 @@ enum trap_id { struct trap; struct trapfunc { - void none (game *g, int x, int y) { }; + void none (game *, int , int) {}; void bubble (game *g, int x, int y); void beartrap (game *g, int x, int y); void snare_light (game *g, int x, int y); void snare_heavy (game *g, int x, int y); - void snare (game *g, int x, int y) { }; void board (game *g, int x, int y); void caltrops (game *g, int x, int y); void tripwire (game *g, int x, int y); @@ -76,7 +75,7 @@ struct trapfunc { void pit (game *g, int x, int y); void pit_spikes (game *g, int x, int y); void lava (game *g, int x, int y); - void portal (game *g, int x, int y) { }; + void portal (game *g, int x, int y); void ledge (game *g, int x, int y); void boobytrap (game *g, int x, int y); void temple_flood (game *g, int x, int y); @@ -89,7 +88,7 @@ struct trapfunc { }; struct trapfuncm { - void none (game *g, monster *z, int x, int y) { }; + void none (game *, monster *, int , int ) {}; void bubble (game *g, monster *z, int x, int y); void cot (game *g, monster *z, int x, int y); void beartrap (game *g, monster *z, int x, int y); @@ -101,16 +100,15 @@ struct trapfuncm { void blade (game *g, monster *z, int x, int y); void snare_light (game *g, monster *z, int x, int y); void snare_heavy (game *g, monster *z, int x, int y); - void snare (game *g, monster *z, int x, int y) { }; void landmine (game *g, monster *z, int x, int y); void telepad (game *g, monster *z, int x, int y); void goo (game *g, monster *z, int x, int y); void dissector (game *g, monster *z, int x, int y); - void sinkhole (game *g, monster *z, int x, int y) { }; + void sinkhole (game *g, monster *z, int x, int y); void pit (game *g, monster *z, int x, int y); void pit_spikes (game *g, monster *z, int x, int y); void lava (game *g, monster *z, int x, int y); - void portal (game *g, monster *z, int x, int y) { }; + void portal (game *g, monster *z, int x, int y); void ledge (game *g, monster *z, int x, int y); void boobytrap (game *g, monster *z, int x, int y); void glow (game *g, monster *z, int x, int y); @@ -146,29 +144,29 @@ struct trap { std::string id; */ - trap(int pid, std::string string_id, std::string pname, nc_color pcolor, char psym, - int pvisibility, int pavoidance, int pdifficulty, - void (trapfunc::*pact)(game *, int x, int y), - void (trapfuncm::*pactm)(game *, monster *, int x, int y), - std::vector keys) { - //string_id is ignored at the moment, will later replace the id - id = pid; - sym = psym; - color = pcolor; - name = pname; - visibility = pvisibility; - avoidance = pavoidance; - difficulty = pdifficulty; - act = pact; - actm = pactm; + trap(int pid, std::string /*string_id*/, std::string pname, nc_color pcolor, + char psym, int pvisibility, int pavoidance, int pdifficulty, + void (trapfunc::*pact)(game *, int x, int y), + void (trapfuncm::*pactm)(game *, monster *, int x, int y), + std::vector keys) { + //string_id is ignored at the moment, will later replace the id + id = pid; + sym = psym; + color = pcolor; + name = pname; + visibility = pvisibility; + avoidance = pavoidance; + difficulty = pdifficulty; + act = pact; + actm = pactm; - components.insert(components.end(), keys.begin(), keys.end()); + components.insert(components.end(), keys.begin(), keys.end()); - // It's a traaaap! So default; - benign = false; - // Traps are not typically funnels - funnel_radius_mm = 0; - }; + // It's a traaaap! So default; + benign = false; + // Traps are not typically funnels + funnel_radius_mm = 0; + }; }; trap_id trap_id_from_string(std::string trap_name); diff --git a/trapdef.cpp b/trapdef.cpp index 8e96fa396ef5d..b79d2aae94363 100644 --- a/trapdef.cpp +++ b/trapdef.cpp @@ -76,13 +76,6 @@ traps.push_back(new trap(id, "BEARTRAP_BURIED", _("buried bear trap"), c_blue, ' // Name Symbol Color Vis Avd Diff -keys.clear(); -id++; -keys.push_back("stick"); -keys.push_back("string_36"); -traps.push_back(new trap(id, "SNARE", _("rabbit snare"), c_brown, '\\', 5, 10, - 2, &trapfunc::snare, &trapfuncm::snare, keys));; - keys.clear(); id++; keys.push_back("board_trap"); diff --git a/trapfunc.cpp b/trapfunc.cpp index 5259709833afc..9b23cfe671f07 100644 --- a/trapfunc.cpp +++ b/trapfunc.cpp @@ -53,7 +53,7 @@ void trapfunc::beartrap(game *g, int x, int y) g->u.hit(g, bp_legs, random_side(bp_legs), 10, 16); g->u.add_disease("beartrap", 1, true); g->m.remove_trap(x, y); - g->m.spawn_item(x, y, "beartrap", g->turn); + g->m.spawn_item(x, y, "beartrap"); } void trapfuncm::beartrap(game *g, monster *z, int x, int y) @@ -65,7 +65,7 @@ void trapfuncm::beartrap(game *g, monster *z, int x, int y) g->sound(x, y, 8, _("SNAP!")); if (z->hurt(35)) { g->kill_mon(g->mon_at(x, y)); - g->m.spawn_item(x, y, "beartrap", 0); + g->m.spawn_item(x, y, "beartrap"); } else { z->moves = 0; z->add_effect(ME_BEARTRAP, rng(8, 15)); @@ -178,10 +178,10 @@ void trapfunc::crossbow(game *g, int x, int y) } else g->add_msg(_("You dodge the shot!")); g->m.remove_trap(x, y); - g->m.spawn_item(x, y, "crossbow", 0); - g->m.spawn_item(x, y, "string_6", 0); + g->m.spawn_item(x, y, "crossbow"); + g->m.spawn_item(x, y, "string_6"); if (add_bolt) - g->m.spawn_item(x, y, "bolt_steel", 0, 0, 1); + g->m.spawn_item(x, y, "bolt_steel", 1, 1); } void trapfuncm::crossbow(game *g, monster *z, int x, int y) @@ -210,10 +210,10 @@ void trapfuncm::crossbow(game *g, monster *z, int x, int y) else if (seen) g->add_msg(_("A bolt shoots out, but misses the %s."), z->name().c_str()); g->m.remove_trap(x, y); - g->m.spawn_item(x, y, "crossbow", 0); - g->m.spawn_item(x, y, "string_6", 0); + g->m.spawn_item(x, y, "crossbow"); + g->m.spawn_item(x, y, "string_6"); if (add_bolt) - g->m.spawn_item(x, y, "bolt_steel", 0, 0, 1); + g->m.spawn_item(x, y, "bolt_steel", 1, 1); } void trapfunc::shotgun(game *g, int x, int y) @@ -243,8 +243,8 @@ void trapfunc::shotgun(game *g, int x, int y) } else g->add_msg(_("You dodge the shot!")); if (shots == 2 || g->m.tr_at(x, y) == tr_shotgun_1) { - g->m.spawn_item(x, y, "shotgun_sawn", 0); - g->m.spawn_item(x, y, "string_6", 0); + g->m.spawn_item(x, y, "shotgun_sawn"); + g->m.spawn_item(x, y, "string_6"); g->m.remove_trap(x, y); } else g->m.add_trap(x, y, tr_shotgun_1); @@ -270,10 +270,10 @@ void trapfuncm::shotgun(game *g, monster *z, int x, int y) g->kill_mon(g->mon_at(x, y)); if (shots == 2 || g->m.tr_at(x, y) == tr_shotgun_1) { g->m.remove_trap(x, y); - g->m.spawn_item(x, y, "shotgun_sawn", 0); - g->m.spawn_item(x, y, "string_6", 0); - g->m.spawn_item(x, y, "shotgun_sawn", 0); - g->m.spawn_item(x, y, "string_6", 0); + g->m.spawn_item(x, y, "shotgun_sawn"); + g->m.spawn_item(x, y, "string_6"); + g->m.spawn_item(x, y, "shotgun_sawn"); + g->m.spawn_item(x, y, "string_6"); } else g->m.add_trap(x, y, tr_shotgun_1); } @@ -307,8 +307,8 @@ void trapfunc::snare_light(game *g, int x, int y) g->u.add_memorial_log(_("Triggered a light snare.")); g->u.add_disease("lightsnare", rng(10, 20)); g->m.remove_trap(x, y); - g->m.spawn_item(x, y, "string_36", 0); - g->m.spawn_item(x, y, "snare_trigger", 0); + g->m.spawn_item(x, y, "string_36"); + g->m.spawn_item(x, y, "snare_trigger"); } void trapfuncm::snare_light(game *g, monster *z, int x, int y) @@ -352,8 +352,8 @@ void trapfuncm::snare_light(game *g, monster *z, int x, int y) break; } g->m.remove_trap(x, y); - g->m.spawn_item(x, y, "string_36", 0); - g->m.spawn_item(x, y, "snare_trigger", 0); + g->m.spawn_item(x, y, "string_36"); + g->m.spawn_item(x, y, "snare_trigger"); } void trapfunc::snare_heavy(game *g, int x, int y) @@ -366,8 +366,8 @@ void trapfunc::snare_heavy(game *g, int x, int y) g->u.hit(g, bp_legs, side, 15, 20); g->u.add_disease("heavysnare", rng(20, 30)); g->m.remove_trap(x, y); - g->m.spawn_item(x, y, "rope_6", 0); - g->m.spawn_item(x, y, "snare_trigger", 0); + g->m.spawn_item(x, y, "rope_6"); + g->m.spawn_item(x, y, "snare_trigger"); } void trapfuncm::snare_heavy(game *g, monster *z, int x, int y) @@ -422,8 +422,8 @@ void trapfuncm::snare_heavy(game *g, monster *z, int x, int y) break; } g->m.remove_trap(x, y); - g->m.spawn_item(x, y, "snare_trigger", 0); - g->m.spawn_item(x, y, "rope_6", 0); + g->m.spawn_item(x, y, "snare_trigger"); + g->m.spawn_item(x, y, "rope_6"); } void trapfunc::landmine(game *g, int x, int y) @@ -623,7 +623,7 @@ void trapfunc::pit_spikes(game *g, int x, int y) g->m.add_trap(x, y, tr_pit); for (int i = 0; i < 4; i++) { // 4 spears to a pit if (one_in(3)) { - g->m.spawn_item(x, y, "spear_wood", g->turn); + g->m.spawn_item(x, y, "spear_wood"); } } } @@ -655,7 +655,7 @@ void trapfuncm::pit_spikes(game *g, monster *z, int x, int y) g->m.add_trap(x, y, tr_pit); for (int i = 0; i < 4; i++) { // 4 spears to a pit if (one_in(3)) { - g->m.spawn_item(x, y, "spear_wood", g->turn); + g->m.spawn_item(x, y, "spear_wood"); } } } @@ -696,6 +696,24 @@ void trapfuncm::lava(game *g, monster *z, int x, int y) z->hurt(dam); } +// STUB +void trapfunc::portal(game *g, int x, int y) +{ + // TODO: make this do something? + (void)g; + (void)x; + (void)y; +} + +// STUB +void trapfuncm::portal(game *g, monster *z, int x, int y) +{ + // TODO: make this do something? + (void)g; + (void)z; + (void)x; + (void)y; +} void trapfunc::sinkhole(game *g, int x, int y) { @@ -720,8 +738,7 @@ void trapfunc::sinkhole(game *g, int x, int y) if (safe.empty()) { g->add_msg(_("There's nowhere to pull yourself to, and you sink!")); g->u.use_amount("rope_30", 1); - g->m.spawn_item(g->u.posx + rng(-1, 1), g->u.posy + rng(-1, 1), - "rope_30", g->turn); + g->m.spawn_item(g->u.posx + rng(-1, 1), g->u.posy + rng(-1, 1), "rope_30"); g->m.add_trap(g->u.posx, g->u.posy, tr_pit); g->vertical_move(-1, true); } else { @@ -736,16 +753,14 @@ void trapfunc::sinkhole(game *g, int x, int y) g->add_msg(_("You're not strong enough to pull yourself out...")); g->u.moves -= 100; g->u.use_amount("rope_30", 1); - g->m.spawn_item(g->u.posx + rng(-1, 1), g->u.posy + rng(-1, 1), - "rope_30", g->turn); + g->m.spawn_item(g->u.posx + rng(-1, 1), g->u.posy + rng(-1, 1), "rope_30"); g->vertical_move(-1, true); } } else { g->add_msg(_("Your throw misses completely, and you sink!")); if (one_in((g->u.str_cur + g->u.dex_cur) / 3)) { g->u.use_amount("rope_30", 1); - g->m.spawn_item(g->u.posx + rng(-1, 1), g->u.posy + rng(-1, 1), - "rope_30", g->turn); + g->m.spawn_item(g->u.posx + rng(-1, 1), g->u.posy + rng(-1, 1), "rope_30"); } g->m.add_trap(g->u.posx, g->u.posy, tr_pit); g->vertical_move(-1, true); @@ -756,6 +771,16 @@ void trapfunc::sinkhole(game *g, int x, int y) } } +// STUB +void trapfuncm::sinkhole(game *g, monster *z, int x, int y) +{ + // TODO: make something exciting happen here + (void)g; + (void)z; + (void)x; + (void)y; +} + void trapfunc::ledge(game *g, int x, int y) { g->add_msg(_("You fall down a level!")); diff --git a/ui.h b/ui.h index 37e9413052f16..6d3abea52a7b9 100644 --- a/ui.h +++ b/ui.h @@ -89,10 +89,12 @@ class uimenu_callback { void setptr(void * ptr) { myptr = ptr; } - virtual void select(int entnum, uimenu * menu) {}; - virtual bool key(int key, int entnum, uimenu * menu) { return false; }; - virtual void refresh(uimenu * menu) {}; - virtual void redraw(uimenu * menu) {}; + virtual void select(int /*entnum*/, uimenu *) {}; + virtual bool key(int /*key*/, int /*entnum*/, uimenu *) { + return false; + }; + virtual void refresh(uimenu *) {}; + virtual void redraw(uimenu *) {}; virtual ~uimenu_callback() {}; }; /* diff --git a/uistate.h b/uistate.h index 4161324fc30ca..0dfc631808db7 100644 --- a/uistate.h +++ b/uistate.h @@ -1,11 +1,13 @@ #ifndef _UISTATE_H_ #define _UISTATE_H_ -#include "picofunc.h" +#include "json.h" /* centralized depot for trivial ui data such as sorting, string_input_popup history, etc. To use this, see the ****notes**** below */ -struct uistatedata { +class uistatedata : public JsonSerializer, public JsonDeserializer +{ +public: /**** declare your variable here. It can be anything, really *****/ int wishitem_selected; int wishmutate_selected; @@ -38,7 +40,6 @@ struct uistatedata { bool _testing_save; bool _really_testing_save; - std::string errdump; uistatedata() { /**** this will set a default value on startup, however to save, see below ****/ @@ -66,7 +67,6 @@ struct uistatedata { // internal stuff _testing_save = true; // internal: whine on json errors. set false if no complaints in 2 weeks. _really_testing_save = false; // internal: spammy - errdump = ""; // also internal: log errors en masse }; std::vector * gethistory(std::string id) { @@ -78,87 +78,67 @@ struct uistatedata { return it->second; } - virtual picojson::value save_data() { - const int input_history_save_max = 25; - std::map data; - + using JsonSerializer::serialize; + void serialize(JsonOut &json) const + { + const int input_history_save_max = 25; + json.start_object(); + /**** if you want to save whatever so it's whatever when the game is started next, declare here and.... ****/ - data[std::string("adv_inv_leftsort")] = picojson::value(adv_inv_leftsort); - data[std::string("adv_inv_rightsort")] = picojson::value(adv_inv_rightsort); - data[std::string("adv_inv_leftarea")] = picojson::value(adv_inv_leftarea); - data[std::string("adv_inv_rightarea")] = picojson::value(adv_inv_rightarea); - data[std::string("adv_inv_last_popup_dest")] = picojson::value(adv_inv_last_popup_dest); - data[std::string("editmap_nsa_viewmode")] = picojson::value(editmap_nsa_viewmode); - data[std::string("list_item_mon")] = picojson::value(list_item_mon); + json.member("adv_inv_leftsort", adv_inv_leftsort); + json.member("adv_inv_rightsort", adv_inv_rightsort); + json.member("adv_inv_leftarea", adv_inv_leftarea); + json.member("adv_inv_rightarea", adv_inv_rightarea); + json.member("adv_inv_last_popup_dest", adv_inv_last_popup_dest); + json.member("editmap_nsa_viewmode", editmap_nsa_viewmode); + json.member("list_item_mon", list_item_mon); - std::map histmap; - for(std::map*>::iterator it = input_history.begin(); it != input_history.end(); ++it ) { - if(it->second != NULL ) { - std::vector hist; - int save_start=0; - if ( it->second->size() > input_history_save_max ) { - save_start = it->second->size() - input_history_save_max; - } - for(std::vector::iterator hit = it->second->begin()+save_start; hit != it->second->end(); ++hit ) { - hist.push_back(picojson::value( *hit )); - } - histmap[std::string(it->first)] = picojson::value(hist); - } - } - data[std::string("input_history")] = picojson::value(histmap); - return picojson::value(data); - }; + json.member("input_history"); + json.start_object(); + std::map*>::const_iterator it; + for (it = input_history.begin(); it != input_history.end(); ++it) { + if (it->second == NULL) { + continue; + } + json.member(it->first); + json.start_array(); + int save_start = 0; + if (it->second->size() > input_history_save_max) { + save_start = it->second->size() - input_history_save_max; + } + for (std::vector::const_iterator hit = it->second->begin()+save_start; hit != it->second->end(); ++hit ) { + json.write(*hit); + } + json.end_array(); + } + json.end_object(); // input_history - bool load(picojson::value parsed) { - if(parsed.is() ) { - const picojson::object& data = parsed.get(); + json.end_object(); + }; + void deserialize(JsonObject &jo) + { /**** here ****/ - picoint(data,"adv_inv_leftsort", adv_inv_leftsort); - picoint(data,"adv_inv_rightsort", adv_inv_rightsort); - picoint(data,"adv_inv_leftarea", adv_inv_leftarea); - picoint(data,"adv_inv_rightarea", adv_inv_rightarea); - picoint(data,"adv_inv_last_popup_dest", adv_inv_last_popup_dest); - picobool(data,"editmap_nsa_viewmode", editmap_nsa_viewmode); - picoint(data,"list_item_mon", list_item_mon); + adv_inv_leftsort = jo.get_int("adv_inv_leftsort", adv_inv_leftsort); + adv_inv_rightsort = jo.get_int("adv_inv_rightsort", adv_inv_rightsort); + adv_inv_leftarea = jo.get_int("adv_inv_leftarea", adv_inv_leftarea); + adv_inv_rightarea = jo.get_int("adv_inv_rightarea", adv_inv_rightarea); + adv_inv_last_popup_dest = jo.get_int("adv_inv_last_popup_dest", adv_inv_last_popup_dest); + editmap_nsa_viewmode = jo.get_bool("editmap_nsa_viewmode", editmap_nsa_viewmode); + list_item_mon = jo.get_int("list_item_mon", list_item_mon); - picojson::object::const_iterator hmit = data.find("input_history"); - if ( ! picoverify() ) return false; - if ( hmit != data.end() ) { - if ( hmit->second.is() ) { - const picojson::object& hmdata = hmit->second.get(); - for (picojson::object::const_iterator hit = hmdata.begin(); hit != hmdata.end(); ++hit) { - if ( hit->second.is() ) { - std::string hkey=hit->first; - std::vector * v = gethistory(hkey); - const picojson::array& ht = hit->second.get(); - if(!picoverify()) continue; - v->clear(); - for (picojson::array::const_iterator hent=ht.begin(); hent != ht.end(); ++hent) { - if( (*hent).is() ) { - std::string tmpstr=(*hent).get(); - if(!picoverify()) continue; - v->push_back(tmpstr); - } - } - } - } - return true; - } else { - errdump += "\ninput_history is not an object"; - - return false; + JsonObject inhist = jo.get_object("input_history"); + std::set inhist_members = inhist.get_member_names(); + for (std::set::iterator it = inhist_members.begin(); + it != inhist_members.end(); ++it) { + JsonArray ja = inhist.get_array(*it); + std::vector *v = gethistory(*it); + v->clear(); + while (ja.has_more()) { + v->push_back(ja.next_string()); } - } - return true; - } - return false; - }; - - std::string save() { - return this->save_data().serialize(); - }; - + } + }; }; extern uistatedata uistate; #endif diff --git a/veh_interact.cpp b/veh_interact.cpp index 61bd0bbcff962..005ed5ab423b4 100644 --- a/veh_interact.cpp +++ b/veh_interact.cpp @@ -1170,6 +1170,7 @@ void complete_vehicle (game *g) case 'r': if (veh->parts[vehicle_part].hp <= 0) { + veh->break_part_into_pieces(vehicle_part, g->u.posx, g->u.posy); used_item = consume_vpart_item (g, veh->parts[vehicle_part].id); veh->parts[vehicle_part].bigness = used_item.bigness; tools.push_back(component("wrench", -1)); @@ -1210,6 +1211,8 @@ void complete_vehicle (game *g) { g->u.practice (g->turn, "mechanics", 2 * 5 + 20); } + } else { + veh->break_part_into_pieces(vehicle_part, g->u.posx, g->u.posy); } if (veh->parts.size() < 2) { diff --git a/veh_type.h b/veh_type.h index 8765e7d95ff6d..02d6035b9ee1d 100644 --- a/veh_type.h +++ b/veh_type.h @@ -4,6 +4,15 @@ #include "color.h" #include "itype.h" +/** + * Represents an entry in the breaks_into list. + */ +struct break_entry { + std::string item_id; + int min; + int max; +}; + /* Flag info: * INTERNAL - Can be mounted inside other parts * ANCHOR_POINT - Allows secure seatbelt attachment @@ -33,6 +42,7 @@ struct vpart_info int difficulty; // installation difficulty (mechanics requirement) std::string location; //Where in the vehicle this part goes std::set flags; // flags + std::vector breaks_into; int z_order; // z-ordering, inferred from location, cached here diff --git a/veh_typedef.cpp b/veh_typedef.cpp index 3cfeb528de907..8038460f49cba 100644 --- a/veh_typedef.cpp +++ b/veh_typedef.cpp @@ -87,6 +87,22 @@ void game::load_vehiclepart(JsonObject &jo) next_part.flags.insert(jarr.next_string()); } + JsonArray breaks_into = jo.get_array("breaks_into"); + while(breaks_into.has_more()) { + JsonObject next_entry = breaks_into.next_object(); + break_entry next_break_entry; + next_break_entry.item_id = next_entry.get_string("item"); + next_break_entry.min = next_entry.get_int("min"); + next_break_entry.max = next_entry.get_int("max"); + //Sanity check + if(next_break_entry.max < next_break_entry.min) { + debugmsg("For vehicle part %s: breaks_into item '%s' has min (%d) > max (%d)!", + next_part.name.c_str(), next_break_entry.item_id.c_str(), + next_break_entry.min, next_break_entry.max); + } + next_part.breaks_into.push_back(next_break_entry); + } + //Plating shouldn't actually be shown; another part will be. //Calculate and cache z-ordering based off of location if(next_part.has_flag("ARMOR")) { diff --git a/vehicle.cpp b/vehicle.cpp index 3efaa6dd1f103..8f16ffc9768e2 100644 --- a/vehicle.cpp +++ b/vehicle.cpp @@ -845,6 +845,26 @@ void vehicle::remove_part (int p) insides_dirty = true; } +/** + * Breaks the specified part into the pieces defined by its breaks_into entry. + * @param p The index of the part to break. + * @param x The map x-coordinate to place pieces at (give or take). + * @param y The map y-coordinate to place pieces at (give or take). + * @param scatter If true, pieces are scattered near the target square. + */ +void vehicle::break_part_into_pieces(int p, int x, int y, bool scatter) { + std::vector break_info = part_info(p).breaks_into; + for(int index = 0; index < break_info.size(); index++) { + int quantity = rng(break_info[index].min, break_info[index].max); + for(int num = 0; num < quantity; num++) { + const int actual_x = scatter ? x + rng(-SCATTER_DISTANCE, SCATTER_DISTANCE) : x; + const int actual_y = scatter ? y + rng(-SCATTER_DISTANCE, SCATTER_DISTANCE) : y; + item piece(g->itypes[break_info[index].item_id], g->turn); + g->m.add_item_or_charges(actual_x, actual_y, piece); + } + } +} + item vehicle::item_from_part( int part ) { itype_id itm = part_info(part).item; @@ -2236,7 +2256,7 @@ void vehicle::handle_trap (int x, int y, int part) snd = _("SNAP!"); wreckit = true; g->m.remove_trap(x, y); - g->m.spawn_item(x, y, "beartrap", 0); + g->m.spawn_item(x, y, "beartrap"); break; case tr_nailboard: wreckit = true; @@ -2252,10 +2272,10 @@ void vehicle::handle_trap (int x, int y, int part) snd = _("Clank!"); wreckit = true; g->m.remove_trap(x, y); - g->m.spawn_item(x, y, "crossbow", 0); - g->m.spawn_item(x, y, "string_6", 0); + g->m.spawn_item(x, y, "crossbow"); + g->m.spawn_item(x, y, "string_6"); if (!one_in(10)) - g->m.spawn_item(x, y, "bolt_steel", 0); + g->m.spawn_item(x, y, "bolt_steel"); break; case tr_shotgun_2: case tr_shotgun_1: @@ -2268,8 +2288,8 @@ void vehicle::handle_trap (int x, int y, int part) else { g->m.remove_trap(x, y); - g->m.spawn_item(x, y, "shotgun_sawn", 0); - g->m.spawn_item(x, y, "string_6", 0); + g->m.spawn_item(x, y, "shotgun_sawn"); + g->m.spawn_item(x, y, "string_6"); } break; case tr_landmine_buried: @@ -2624,8 +2644,8 @@ void vehicle::unboard_all () { std::vector bp = boarded_parts (); for (int i = 0; i < bp.size(); i++) { - g->m.unboard_vehicle (g, global_x() + parts[bp[i]].precalc_dx[0], global_y() + - parts[bp[i]].precalc_dy[0]); + g->m.unboard_vehicle (global_x() + parts[bp[i]].precalc_dx[0], + global_y() + parts[bp[i]].precalc_dy[0]); } } @@ -2681,11 +2701,59 @@ void vehicle::damage_all (int dmg1, int dmg2, int type, const point &impact) int vehicle::damage_direct (int p, int dmg, int type) { - if (parts[p].hp <= 0) + if (parts[p].hp <= 0) { + /* Already-destroyed part - chance it could be torn off into pieces. + * Chance increases with damage, and decreases with part max durability + * (so lights, etc are easily removed; frames and plating not so much) */ + if(rng(0, part_info(p).durability / 10) < dmg) { + int x_pos = global_x() + parts[p].precalc_dx[0]; + int y_pos = global_y() + parts[p].precalc_dy[0]; + if(part_info(p).location == "structure") { + //For structural parts, remove other parts first + std::vector parts_in_square = parts_at_relative(parts[p].mount_dx, parts[p].mount_dy); + for(int index = parts_in_square.size() - 1; index >= 0; index--) { + //Ignore the frame being destroyed + if(parts_in_square[index] != p) { + if(g->u_see(x_pos, y_pos)) { + g->add_msg(_("The %s's %s is torn off!"), name.c_str(), + part_info(parts_in_square[index]).name.c_str()); + } + item part_as_item = item_from_part(parts_in_square[index]); + g->m.add_item_or_charges(x_pos, y_pos, part_as_item, true); + remove_part(parts_in_square[index]); + } + /* After clearing the frame, remove it if normally legal to + * do so (it's not (0, 0) and not holding the vehicle + * together). At a later date, some more complicated system + * (such as actually making two vehicles from the split + * parts) would be ideal. */ + if(can_unmount(p)) { + if(g->u_see(x_pos, y_pos)) { + g->add_msg(_("The %s's %s is destroyed!"), + name.c_str(), part_info(p).name.c_str()); + } + break_part_into_pieces(p, x_pos, y_pos, true); + remove_part(p); + } + } + } else { + //Just break it off + if(g->u_see(x_pos, y_pos)) { + g->add_msg(_("The %s's %s is destroyed!"), + name.c_str(), part_info(p).name.c_str()); + } + break_part_into_pieces(p, x_pos, y_pos, true); + remove_part(p); + } + insides_dirty = true; + } return dmg; + } + int tsh = part_info(p).durability / 10; - if (tsh > 20) + if (tsh > 20) { tsh = 20; + } int dres = dmg; if (dmg >= tsh || type != 1) { @@ -2720,7 +2788,7 @@ int vehicle::damage_direct (int p, int dmg, int type) { g->m.spawn_item(global_x() + parts[p].precalc_dx[0], global_y() + parts[p].precalc_dy[0], - part_info(p).item, g->turn); + part_info(p).item, 1, 0, g->turn); remove_part (p); } } @@ -2747,8 +2815,8 @@ void vehicle::leak_fuel (int p) parts[p].amount = 0; return; } - g->m.spawn_item(i, j, "gasoline", 0); - g->m.spawn_item(i, j, "gasoline", 0); + g->m.spawn_item(i, j, "gasoline"); + g->m.spawn_item(i, j, "gasoline"); parts[p].amount -= 100; } } diff --git a/vehicle.h b/vehicle.h index 4450f477a7924..1d165f2c228a9 100644 --- a/vehicle.h +++ b/vehicle.h @@ -17,6 +17,9 @@ class game; //collision factor for vehicle-vehicle collision; delta_v in mph float get_collision_factor(float delta_v); +//How far to scatter parts from a vehicle when the part is destroyed (+/-) +#define SCATTER_DISTANCE 3 + #define num_fuel_types 5 extern const ammotype fuel_types[num_fuel_types]; #define k_mvel 200 //adjust this to balance collision damage @@ -181,6 +184,10 @@ class vehicle bool is_connected(vehicle_part &to, vehicle_part &from, vehicle_part &excluded); void add_missing_frames(); + // direct damage to part (armor protection and internals are not counted) + // returns damage bypassed + int damage_direct (int p, int dmg, int type = 1); + public: vehicle (game *ag=0, std::string type_id = "null", int veh_init_fuel = -1, int veh_init_status = -1); ~vehicle (); @@ -227,6 +234,8 @@ class vehicle void remove_part (int p); + void break_part_into_pieces (int p, int x, int y, bool scatter = false); + // Generate the corresponding item from a vehicle part. // Still needs to be removed. item item_from_part( int part ); @@ -430,10 +439,6 @@ class vehicle // damage all parts (like shake from strong collision), range from dmg1 to dmg2 void damage_all (int dmg1, int dmg2, int type, const point &impact); - // direct damage to part (armor protection and internals are not counted) - // returns damage bypassed - int damage_direct (int p, int dmg, int type = 1); - void leak_fuel (int p); // fire the turret which is part p