bool item::has_flag(item_flag f) const { bool ret = false; // first check for flags specific to item type // gun flags if (is_gun()) { if (mode == IF_MODE_AUX) { item const* gunmod = inspect_active_gunmod(); if( gunmod != NULL ) ret = gunmod->has_flag(f); if (ret) return ret; } else { for (int i = 0; i < contents.size(); i++) { // Don't report flags from active gunmods for the gun. if (contents[i].has_flag(f) && contents[i].has_flag(IF_MODE_AUX)) { ret = true; return ret; } } } } // other item type flags ret = type->item_flags & mfb(f); if (ret) return ret; // now check for item specific flags ret = item_flags & mfb(f); return ret; }
// MATERIALS-TODO: use fire resistance void game::hit_monster_with_flags(monster &z, unsigned int effects) { if (effects & mfb(AMMO_FLAME)) { if (z.made_of("veggy") || z.made_of("cotton") || z.made_of("wool") || z.made_of("paper") || z.made_of("wood")) z.add_effect(ME_ONFIRE, rng(8, 20)); else if (z.made_of("flesh")) z.add_effect(ME_ONFIRE, rng(5, 10)); } else if (effects & mfb(AMMO_INCENDIARY)) { if (z.made_of("veggy") || z.made_of("cotton") || z.made_of("wool") || z.made_of("paper") || z.made_of("wood")) z.add_effect(ME_ONFIRE, rng(2, 6)); else if (z.made_of("flesh") && one_in(4)) z.add_effect(ME_ONFIRE, rng(1, 4)); } else if (effects & mfb(AMMO_IGNITE)) { if (z.made_of("veggy") || z.made_of("cotton") || z.made_of("wool") || z.made_of("paper") || z.made_of("wood")) z.add_effect(ME_ONFIRE, rng(6, 6)); else if (z.made_of("flesh")) z.add_effect(ME_ONFIRE, rng(10, 10)); } }
void generic_very_wet(bool acid) { if ((!g->u.worn_with_flag("RAINPROOF") || one_in(25)) && (!g->u.weapon.has_flag("RAIN_PROTECT") || one_in(5)) && !g->u.has_trait("FEATHERS") && (g->u.warmth(bp_torso) * 4/5 + g->u.warmth(bp_head) / 5) < 60 && PLAYER_OUTSIDE) { g->u.drench(60 - (g->u.warmth(bp_torso) * 4/5 + g->u.warmth(bp_head) / 5), mfb(bp_torso)|mfb(bp_arms)|mfb(bp_head)); } fill_water_collectors(8, acid); decay_fire_and_scent(45); }
void generic_very_wet(game *g, bool acid) { if ((!g->u.is_wearing("coat_rain") || one_in(25)) && (!g->u.weapon.has_flag("RAIN_PROTECT") || one_in(5)) && !g->u.has_trait("FEATHERS") && (g->u.warmth(bp_torso) * 4/5 + g->u.warmth(bp_head) / 5) < 60 && PLAYER_OUTSIDE) { g->u.drench(g, 60 - (g->u.warmth(bp_torso) * 4/5 + g->u.warmth(bp_head) / 5), mfb(bp_torso)|mfb(bp_arms)|mfb(bp_head)); } fill_water_collectors(g, 8, acid); decay_fire_and_scent(g, 45); }
void generic_wet(bool acid) { if ((!g->u.worn_with_flag("RAINPROOF") || one_in(50)) && (!g->u.weapon.has_flag("RAIN_PROTECT") || one_in(10)) && !g->u.has_trait("FEATHERS") && (g->u.warmth(bp_torso) * 4/5 + g->u.warmth(bp_head) / 5) < 30 && PLAYER_OUTSIDE && one_in(2)) { g->u.drench(30 - (g->u.warmth(bp_torso) * 4/5 + g->u.warmth(bp_head) / 5), mfb(bp_torso)|mfb(bp_arms)|mfb(bp_head)); } fill_water_collectors(4, acid); // fixme; consolidate drench, this, and decay_fire_and_scent. decay_fire_and_scent(15); }
void faction::make_army() { name = "The army"; omx = 0; omy = 0; mapx = OMAPX / 2; mapy = OMAPY / 2; size = OMAPX * 2; power = OMAPX; goal = FACGOAL_DOMINANCE; job1 = FACJOB_MERCENARIES; job2 = FACJOB_NULL; if (one_in(4)) values |= mfb(FACVAL_CHARITABLE); if (!one_in(4)) values |= mfb(FACVAL_EXPLORATION); if (one_in(3)) values |= mfb(FACVAL_BIONICS); if (one_in(3)) values |= mfb(FACVAL_ROBOTS); if (one_in(4)) values |= mfb(FACVAL_TREACHERY); if (one_in(4)) values |= mfb(FACVAL_STRAIGHTEDGE); if (!one_in(3)) values |= mfb(FACVAL_LAWFUL); if (one_in(8)) values |= mfb(FACVAL_CRUELTY); id = 0; }
void ammo_effects(game *g, int x, int y, long effects) { if (effects & mfb(AMMO_EXPLOSIVE)) g->explosion(x, y, 24, 0, false); if (effects & mfb(AMMO_FRAG)) g->explosion(x, y, 12, 28, false); if (effects & mfb(AMMO_NAPALM)) g->explosion(x, y, 18, 0, true); if (effects & mfb(AMMO_EXPLOSIVE_BIG)) g->explosion(x, y, 40, 0, false); if (effects & mfb(AMMO_TEARGAS)) { for (int i = -2; i <= 2; i++) { for (int j = -2; j <= 2; j++) g->m.add_field(g, x + i, y + j, fd_tear_gas, 3); } } if (effects & mfb(AMMO_SMOKE)) { for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) g->m.add_field(g, x + i, y + j, fd_smoke, 3); } } if (effects & mfb(AMMO_FLASHBANG)) g->flashbang(x, y); if (effects & mfb(AMMO_FLAME)) g->explosion(x, y, 4, 0, true); }
void game::hit_monster_with_flags(monster &z, unsigned int effects) { if (effects & mfb(AMMO_FLAME)) { if (z.made_of(VEGGY) || z.made_of(COTTON) || z.made_of(WOOL) || z.made_of(PAPER) || z.made_of(WOOD)) z.add_effect(ME_ONFIRE, rng(8, 20)); else if (z.made_of(FLESH)) z.add_effect(ME_ONFIRE, rng(5, 10)); } else if (effects & mfb(AMMO_INCENDIARY)) { if (z.made_of(VEGGY) || z.made_of(COTTON) || z.made_of(WOOL) || z.made_of(PAPER) || z.made_of(WOOD)) z.add_effect(ME_ONFIRE, rng(2, 6)); else if (z.made_of(FLESH) && one_in(4)) z.add_effect(ME_ONFIRE, rng(1, 4)); } }
void generic_very_wet(bool acid) { if ((!g->u.worn_with_flag("RAINPROOF") || one_in(50)) && (!g->u.weapon.has_flag("RAIN_PROTECT") || one_in(10)) && !g->u.has_trait("FEATHERS") && (g->u.warmth(bp_torso) * 4/5 + g->u.warmth(bp_head) / 5) < 60 && PLAYER_OUTSIDE) { if (g->u.weapon.has_flag("RAIN_PROTECT")) { // Umbrellas tend to protect one's head and torso pretty well g->u.drench(60 - (g->u.warmth(bp_legs) * 4/5 + g->u.warmth(bp_feet) / 5), mfb(bp_legs)); } else { g->u.drench(60 - (g->u.warmth(bp_torso) * 4/5 + g->u.warmth(bp_head) / 5), mfb(bp_torso)|mfb(bp_arms)|mfb(bp_head)); } } fill_water_collectors(8, acid); decay_fire_and_scent(45); }
bool item::has_flag(item_flag f) { if (is_gun()) { for (int i = 0; i < contents.size(); i++) { if (contents[i].has_flag(f)) return true; } } return (type->item_flags & mfb(f)); }
void generic_wet(bool acid) { if ((!g->u.worn_with_flag("RAINPROOF") || one_in(100)) && (!g->u.weapon.has_flag("RAIN_PROTECT") || one_in(20)) && !g->u.has_trait("FEATHERS") && (g->u.warmth(bp_torso) * 4/5 + g->u.warmth(bp_head) / 5) < 30 && PLAYER_OUTSIDE && one_in(2)) { if (g->u.weapon.has_flag("RAIN_PROTECT")) { // Umbrellas tend to protect one's head and torso pretty well g->u.drench(30 - (g->u.warmth(bp_legs) * 4/5 + g->u.warmth(bp_feet) / 5), mfb(bp_legs)); } else { g->u.drench(30 - (g->u.warmth(bp_torso) * 4/5 + g->u.warmth(bp_head) / 5), mfb(bp_torso)|mfb(bp_arms)|mfb(bp_head)); } } fill_water_collectors(4, acid); // fixme; consolidate drench, this, and decay_fire_and_scent. decay_fire_and_scent(15); }
bool map::trans(int x, int y) { // Control statement is a problem. Normally returning false on an out-of-bounds // is how we stop rays from going on forever. Instead we'll have to include // this check in the ray loop. if (!inbounds(x, y)) return true; return terlist[ter(x, y)].flags & mfb(transparent) && (field_at(x, y).type == 0 || // Fields may obscure the view, too fieldlist[field_at(x, y).type].transparent[field_at(x, y).density - 1]); }
bool item::has_technique(technique_id tech, player *p) { if (is_style()) { it_style *style = dynamic_cast<it_style*>(type); for (int i = 0; i < style->moves.size(); i++) { if (style->moves[i].tech == tech && (p == NULL || p->sklevel[sk_unarmed] >= style->moves[i].level)) return true; } } return (type->techniques & mfb(tech)); }
void weather_effect::very_wet(game *g) { if ((!g->u.is_wearing("coat_rain") || one_in(25)) && (!g->u.weapon.has_flag("RAIN_PROTECT") || one_in(5)) && !g->u.has_trait("FEATHERS") && g->u.warmth(bp_torso) < 50 && PLAYER_OUTSIDE) { g->u.drench(g, 60 - g->u.warmth(bp_torso), mfb(bp_torso)|mfb(bp_arms)); } // Put out fires and reduce scent for (int x = g->u.posx - SEEX * 2; x <= g->u.posx + SEEX * 2; x++) { for (int y = g->u.posy - SEEY * 2; y <= g->u.posy + SEEY * 2; y++) { if (g->m.is_outside(x, y)) { field_entry *fd = g->m.field_at(x, y).findField(fd_fire); if (fd) fd->setFieldAge(fd->getFieldAge() + 45); if (g->scent(x, y) > 0) g->scent(x, y)--; } } } }
void Item_factory::set_flag_by_string(unsigned& cur_flags, const std::string & new_flag, const std::string & flag_type) { if( flag_type == "bodyparts" ) { // global defined in bodypart.h std::map<std::string, body_part>::const_iterator found_flag_iter = body_parts.find(new_flag); if(found_flag_iter != body_parts.end()) { cur_flags = cur_flags | mfb( (unsigned)found_flag_iter->second ); } else { debugmsg("Invalid item bodyparts flag: %s", new_flag.c_str()); } } }
bool npc::wear_if_wanted(item it) { if (!it.is_armor()) return false; it_armor* armor = dynamic_cast<it_armor*>(it.type); int max_encumb[num_bp] = {2, 3, 3, 4, 3, 3, 3, 2}; bool encumb_ok = true; for (int i = 0; i < num_bp && encumb_ok; i++) { if (armor->covers & mfb(i) && encumb(body_part(i)) + armor->encumber > max_encumb[i]) encumb_ok = false; } if (encumb_ok) { worn.push_back(it); return true; } // Otherwise, maybe we should take off one or more items and replace them std::vector<int> removal; for (int i = 0; i < worn.size(); i++) { for (int j = 0; j < num_bp; j++) { if (armor->covers & mfb(j) && dynamic_cast<it_armor*>(worn[i].type)->covers & mfb(j)) { removal.push_back(i); j = num_bp; } } } for (int i = 0; i < removal.size(); i++) { if (true) { // if (worn[removal[i]].value_to(this) < it.value_to(this)) { inv.push_back(worn[removal[i]]); worn.push_back(it); return true; } } return false; }
bool item::has_technique(technique_id tech, player *p) { if (is_style()) { it_style *style = dynamic_cast<it_style*>(type); for (int i = 0; i < style->moves.size(); i++) { if (style->moves[i].tech == tech && (!p || p->skillLevel("unarmed") >= style->moves[i].level)) return true; } } if( is_null() ) return false; return (type->techniques & mfb(tech)); }
item::item(itype* it, unsigned int turn) { if(!it) type = nullitem(); else type = it; bday = turn; name = ""; invlet = 0; damage = 0; burnt = 0; poison = 0; mode = IF_NULL; item_flags = 0; item_counter = 0; active = false; curammo = NULL; corpse = NULL; owned = -1; mission_id = -1; player_id = -1; if (it == NULL) return; if (it->is_gun()) charges = 0; else if (it->is_ammo()) { it_ammo* ammo = dynamic_cast<it_ammo*>(it); charges = ammo->count; } else if (it->is_food()) { it_comest* comest = dynamic_cast<it_comest*>(it); if (comest->charges == 1 && !made_of(LIQUID)) charges = -1; else charges = comest->charges; } else if (it->is_tool()) { it_tool* tool = dynamic_cast<it_tool*>(it); if (tool->max_charges == 0) charges = -1; else charges = tool->def_charges; } else if ((it->is_gunmod() && it->id == "spare_mag") || it->item_flags & mfb(IF_MODE_AUX)) { charges = 0; } else charges = -1; if(it->is_var_veh_part()){ it_var_veh_part* varcarpart = dynamic_cast<it_var_veh_part*>(it); bigness= rng( varcarpart->min_bigness, varcarpart->max_bigness); } }
void veh_interact::display_list (int pos) { werase (w_list); int page = pos / page_size; for (int i = page * page_size; i < (page + 1) * page_size && i < can_mount.size(); i++) { int y = i - page * page_size; itype_id itm = vpart_list[can_mount[i]].item; bool has_comps = crafting_inv.has_amount(itm, 1); bool has_skill = g->u.skillLevel("mechanics") >= vpart_list[can_mount[i]].difficulty; bool is_wheel = vpart_list[can_mount[i]].flags & mfb(vpf_wheel); nc_color col = has_comps && (has_skill || is_wheel) ? c_white : c_dkgray; mvwprintz(w_list, y, 3, pos == i? hilite (col) : col, vpart_list[can_mount[i]].name); mvwputch (w_list, y, 1, vpart_list[can_mount[i]].color, special_symbol (vpart_list[can_mount[i]].sym)); } wrefresh (w_list); }
bool item::has_flag(item_flag f) { if (is_gun()) { if (mode == IF_MODE_AUX) { item* gunmod = active_gunmod(); if( gunmod != NULL ) return gunmod->has_flag(f); } else { for (int i = 0; i < contents.size(); i++) { // Don't report flags from active gunmods for the gun. if (contents[i].has_flag(f) && contents[i].has_flag(IF_MODE_AUX)) return true; } } } if( is_null() ) return false; return (type->item_flags & mfb(f)); }
/** * Main routine for wet effects caused by weather. * Drenching the player is applied after checks against worn and held items. * * The warmth of armor is considered when determining how much drench happens. * * Note that this is not the only place where drenching can happen. For example, moving or swimming into water tiles will also cause drenching. * @see fill_water_collectors * @see map::decay_fields_and_scent * @see player::drench */ void generic_wet(bool acid) { if ((!g->u.worn_with_flag("RAINPROOF") || one_in(100)) && (!g->u.weapon.has_flag("RAIN_PROTECT") || one_in(20)) && !g->u.has_trait("FEATHERS") && (g->u.warmth(bp_torso) * 4 / 5 + g->u.warmth(bp_head) / 5) < 30 && PLAYER_OUTSIDE && one_in(2)) { if (g->u.weapon.has_flag("RAIN_PROTECT")) { // Umbrellas tend to protect one's head and torso pretty well g->u.drench(30 - (g->u.warmth(bp_leg_l) + (g->u.warmth(bp_leg_r)) * 2 / 5 + (g->u.warmth(bp_foot_l) + g->u.warmth(bp_foot_r)) / 10), mfb(bp_leg_l) | mfb(bp_leg_r), false ); } else { g->u.drench(30 - (g->u.warmth(bp_torso) * 4 / 5 + g->u.warmth(bp_head) / 5), mfb(bp_torso) | mfb(bp_arm_l) | mfb(bp_arm_r) | mfb(bp_head), false ); } } fill_water_collectors(4, acid); // fixme; consolidate drench and this. g->m.decay_fields_and_scent( 15 ); }
/** * Main routine for wet effects caused by weather. * Drenching the player is applied after checks against worn and held items. * * The warmth of armor is considered when determining how much drench happens per tick. * * Note that this is not the only place where drenching can happen. * For example, moving or swimming into water tiles will also cause drenching. * @see fill_water_collectors * @see map::decay_fields_and_scent * @see player::drench */ void wet_player( int amount ) { if( !PLAYER_OUTSIDE || g->u.has_trait("FEATHERS") || g->u.weapon.has_flag("RAIN_PROTECT") || ( !one_in(50) && g->u.worn_with_flag("RAINPROOF") ) ) { return; } if( rng( 0, 100 - amount + g->u.warmth( bp_torso ) * 4 / 5 + g->u.warmth( bp_head ) / 5 ) > 10 ) { // Thick clothing slows down (but doesn't cap) soaking return; } const auto &wet = g->u.body_wetness; const auto &capacity = g->u.drench_capacity; int drenched_parts = mfb(bp_torso) | mfb(bp_arm_l) | mfb(bp_arm_r) | mfb(bp_head); if( wet[bp_torso] * 100 >= capacity[bp_torso] * 50 ) { // Once upper body is 50%+ drenched, start soaking the legs too drenched_parts = drenched_parts | mfb(bp_leg_l) | mfb(bp_leg_r) ; } g->u.drench( amount, drenched_parts, false ); }
std::string item::info(bool showtext) { std::stringstream dump; if( !is_null() ) { dump << " Volume: " << volume() << " Weight: " << weight() << "\n" << " Bash: " << int(type->melee_dam) << (has_flag(IF_SPEAR) ? " Pierce: " : " Cut: ") << int(type->melee_cut) << " To-hit bonus: " << (type->m_to_hit > 0 ? "+" : "" ) << int(type->m_to_hit) << "\n" << " Moves per attack: " << attack_time() << "\n"; } if (is_food()) { it_comest* food = dynamic_cast<it_comest*>(type); dump << " Nutrition: " << int(food->nutr) << "\n Quench: " << int(food->quench) << "\n Enjoyability: " << int(food->fun); } else if (is_food_container()) { // added charge display for debugging it_comest* food = dynamic_cast<it_comest*>(contents[0].type); dump << " Nutrition: " << int(food->nutr) << "\n Quench: " << int(food->quench) << "\n Enjoyability: " << int(food->fun) << "\n Charges: " << int(contents[0].charges); } else if (is_ammo()) { // added charge display for debugging it_ammo* ammo = dynamic_cast<it_ammo*>(type); dump << " Type: " << ammo_name(ammo->type) << "\n Damage: " << int(ammo->damage) << "\n Armor-pierce: " << int(ammo->pierce) << "\n Range: " << int(ammo->range) << "\n Accuracy: " << int(100 - ammo->accuracy) << "\n Recoil: " << int(ammo->recoil) << "\n Count: " << int(ammo->count); } else if (is_ammo_container()) { it_ammo* ammo = dynamic_cast<it_ammo*>(contents[0].type); dump << " Type: " << ammo_name(ammo->type) << "\n Damage: " << int(ammo->damage) << "\n Armor-pierce: " << int(ammo->pierce) << "\n Range: " << int(ammo->range) << "\n Accuracy: " << int(100 - ammo->accuracy) << "\n Recoil: " << int(ammo->recoil) << "\n Count: " << int(contents[0].charges); } else if (is_gun()) { it_gun* gun = dynamic_cast<it_gun*>(type); int ammo_dam = 0, ammo_recoil = 0; bool has_ammo = (curammo != NULL && charges > 0); if (has_ammo) { ammo_dam = curammo->damage; ammo_recoil = curammo->recoil; } dump << " Skill used: " << skill_name(gun->skill_used) << "\n Ammunition: " << clip_size() << " rounds of " << ammo_name(ammo_type()); dump << "\n Damage: "; if (has_ammo) dump << ammo_dam; dump << (gun_damage(false) >= 0 ? "+" : "" ) << gun_damage(false); if (has_ammo) dump << " = " << gun_damage(); dump << "\n Accuracy: " << int(100 - accuracy()); dump << "\n Recoil: "; if (has_ammo) dump << ammo_recoil; dump << (recoil(false) >= 0 ? "+" : "" ) << recoil(false); if (has_ammo) dump << " = " << recoil(); dump << "\n Reload time: " << int(gun->reload_time); if (has_flag(IF_RELOAD_ONE)) dump << " per round"; if (burst_size() == 0) { if (gun->skill_used == sk_pistol && has_flag(IF_RELOAD_ONE)) dump << "\n Revolver."; else dump << "\n Semi-automatic."; } else dump << "\n Burst size: " << burst_size(); if (contents.size() > 0) dump << "\n"; for (int i = 0; i < contents.size(); i++) dump << "\n+" << contents[i].tname(); } else if (is_gunmod()) { it_gunmod* mod = dynamic_cast<it_gunmod*>(type); if (mod->accuracy != 0) dump << " Accuracy: " << (mod->accuracy > 0 ? "+" : "") << int(mod->accuracy); if (mod->damage != 0) dump << "\n Damage: " << (mod->damage > 0 ? "+" : "") << int(mod->damage); if (mod->clip != 0) dump << "\n Magazine: " << (mod->clip > 0 ? "+" : "") << int(mod->damage) << "%"; if (mod->recoil != 0) dump << "\n Recoil: " << int(mod->recoil); if (mod->burst != 0) dump << "\n Burst: " << (mod->clip > 0 ? "+" : "") << int(mod->clip); if (mod->newtype != AT_NULL) dump << "\n " << ammo_name(mod->newtype); dump << "\n Used on: "; if (mod->used_on_pistol) dump << "Pistols. "; if (mod->used_on_shotgun) dump << "Shotguns. "; if (mod->used_on_smg) dump << "SMGs. "; if (mod->used_on_rifle) dump << "Rifles."; } else if (is_armor()) { it_armor* armor = dynamic_cast<it_armor*>(type); dump << " Covers: "; if (armor->covers & mfb(bp_head)) dump << "The head. "; if (armor->covers & mfb(bp_eyes)) dump << "The eyes. "; if (armor->covers & mfb(bp_mouth)) dump << "The mouth. "; if (armor->covers & mfb(bp_torso)) dump << "The torso. "; if (armor->covers & mfb(bp_arms)) dump << "The arms. "; if (armor->covers & mfb(bp_hands)) dump << "The hands. "; if (armor->covers & mfb(bp_legs)) dump << "The legs. "; if (armor->covers & mfb(bp_feet)) dump << "The feet. "; dump << "\n Encumberment: " << int(armor->encumber) << "\n Bashing protection: " << int(armor->dmg_resist) << "\n Cut protection: " << int(armor->cut_resist) << "\n Environmental protection: " << int(armor->env_resist) << "\n Warmth: " << int(armor->warmth) << "\n Storage: " << int(armor->storage); } else if (is_book()) { it_book* book = dynamic_cast<it_book*>(type); if (book->type == sk_null) dump << " Just for fun.\n"; else { dump << " Can bring your " << skill_name(book->type) << " skill to " << int(book->level) << std::endl; if (book->req == 0) dump << " It can be understood by beginners.\n"; else dump << " Requires " << skill_name(book->type) << " level " << int(book->req) << " to understand.\n"; } dump << " Requires intelligence of " << int(book->intel) << " to easily read." << std::endl; if (book->fun != 0) dump << " Reading this book affects your morale by " << (book->fun > 0 ? "+" : "") << int(book->fun) << std::endl; dump << " This book takes " << int(book->time) << " minutes to read."; } else if (is_tool()) { it_tool* tool = dynamic_cast<it_tool*>(type); dump << " Maximum " << tool->max_charges << " charges"; if (tool->ammo == AT_NULL) dump << "."; else dump << " of " << ammo_name(tool->ammo) << "."; } else if (is_style()) { dump << "\n"; it_style* style = dynamic_cast<it_style*>(type); for (int i = 0; i < style->moves.size(); i++) { dump << default_technique_name(style->moves[i].tech) << ". Requires Unarmed Skill of " << style->moves[i].level << "\n"; } } else if (!is_null() && type->techniques != 0) { dump << "\n"; for (int i = 1; i < NUM_TECHNIQUES; i++) { if (type->techniques & mfb(i)) dump << default_technique_name( technique_id(i) ) << "; "; } } if ( showtext && !is_null() ) { dump << "\n\n" << type->description << "\n"; if (contents.size() > 0) { if (is_gun()) { for (int i = 0; i < contents.size(); i++) dump << "\n " << contents[i].type->description; } else dump << "\n " << contents[0].type->description; dump << "\n"; } } return dump.str(); }
void npc::randomize(game *g, npc_class type) { id = g->assign_npc_id(); str_max = dice(4, 3); dex_max = dice(4, 3); int_max = dice(4, 3); per_max = dice(4, 3); weapon.make(g->itypes[itm_null]); ret_null.make(g->itypes[itm_null]); inv.clear(); personality.aggression = rng(-10, 10); personality.bravery = rng(-10, 10); personality.collector = rng(-10, 10); personality.altruism = rng(-10, 10); cash = 100 * rng(0, 20) + 10 * rng(0, 30) + rng(0, 50); moves = 100; mission = NPC_MISSION_NULL; if (one_in(2)) male = true; else male = false; pick_name(); if (type == NC_NONE) type = npc_class(rng(0, NC_MAX - 1)); if (one_in(5)) type = NC_NONE; switch (type) { // Type of character case NC_NONE: // Untyped; no particular specialization for (int i = 1; i < num_skill_types; i++) sklevel[i] = dice(4, 2) - 4; break; case NC_DOCTOR: for (int i = 1; i < num_skill_types; i++) sklevel[i] = dice(3, 2) - 3; sklevel[sk_firstaid] += rng(2, 6); str_max -= rng(0, 2); int_max += rng(0, 2); per_max += rng(0, 1) * rng(0, 1); personality.aggression -= rng(0, 4); if (one_in(4)) flags |= mfb(NF_DRUGGIE); cash += 100 * rng(0, 3) * rng(0, 3); break; case NC_TRADER: for (int i = 1; i < num_skill_types; i++) sklevel[i] = dice(2, 2) - 2 + (rng(0, 1) * rng(0, 1)); sklevel[sk_mechanics] += rng(0, 2); sklevel[sk_electronics] += rng(0, 2); sklevel[sk_speech] += rng(0, 3); sklevel[sk_barter] += rng(2, 4); int_max += rng(0, 1) * rng(0, 1); per_max += rng(0, 1) * rng(0, 1); personality.collector += rng(1, 5); cash += 250 * rng(1, 10); break; case NC_NINJA: for (int i = 1; i < num_skill_types; i++) sklevel[i] = dice(2, 2) - 2; sklevel[sk_dodge] += rng(2, 4); sklevel[sk_melee] += rng(1, 4); sklevel[sk_unarmed] += rng(3, 5); sklevel[sk_throw] += rng(0, 2); str_max -= rng(0, 1); dex_max += rng(0, 2); per_max += rng(0, 2); personality.bravery += rng(0, 3); personality.collector -= rng(1, 6); break; case NC_COWBOY: for (int i = 1; i < num_skill_types; i++) { sklevel[i] = dice(3, 2) - 4; if (sklevel[i] < 0) sklevel[i] = 0; } sklevel[sk_gun] += rng(0, 2); sklevel[sk_pistol] += rng(1, 3); sklevel[sk_rifle] += rng(0, 2); int_max -= rng(0, 2); str_max += rng(0, 1); personality.aggression += rng(0, 2); personality.bravery += rng(1,5); break; case NC_SCIENTIST: for (int i = 1; i < num_skill_types; i++) { sklevel[i] = dice(3, 2) - 4; if (sklevel[i] < 0) sklevel[i] = 0; } sklevel[sk_computer] += rng(1, 4); sklevel[sk_electronics] += rng(1, 3); sklevel[sk_firstaid] += rng(0, 1); if (one_in(4)) flags |= mfb(NF_TECHNOPHILE); if (one_in(3)) flags |= mfb(NF_BOOKWORM); str_max -= rng(1, 3); dex_max -= rng(0, 1); int_max += rng(2, 5); personality.aggression -= rng(1, 5); personality.bravery -= rng(2, 8); personality.collector += rng (0, 2); break; case NC_BOUNTY_HUNTER: for (int i = 1; i < num_skill_types; i++) { sklevel[i] = dice(3, 2) - 3; if (sklevel[i] > 0 && one_in(3)) sklevel[i]--; } sklevel[sk_gun] += rng(2, 4); sklevel[rng(sk_pistol, sk_rifle)] += rng(3, 5); personality.aggression += rng(1, 6); personality.bravery += rng(0, 5); break; } for (int i = 0; i < num_hp_parts; i++) { hp_max[i] = 60 + str_max * 3; hp_cur[i] = hp_max[i]; } starting_weapon(g); worn = starting_clothes(type, male, g); inv = starting_inv(this, type, g); update_worst_item_value(); }
void game::init_artifacts() { artifact_shape_datum tmp_artifact_shape_data[ARTSHAPE_MAX] = { {"BUG", "BUG", 0, 0, 0, 0}, {_("sphere"), _("smooth sphere"), 2, 4, 0, 10}, {_("rod"), _("tapered rod"), 1, 7, 1, 7}, {_("teardrop"), _("teardrop-shaped stone"), 2, 6, 0, 8}, {_("lamp"), _("hollow, transparent cube"), 4, 9, 0, 3}, {_("snake"), _("winding, flexible rod"), 0, 8, 0, 8}, {_("disc"), _("smooth disc"), 4, 6, 2, 4}, {_("beads"), _("string of beads"), 3, 7, 0, 6}, {_("napkin"), _("very thin sheet"), 0, 3, 0, 3}, {_("urchin"), _("spiked sphere"), 3, 5, 2, 6}, {_("jelly"), _("malleable blob"), 2, 8, 2, 4}, {_("spiral"), _("spiraling rod"), 5, 6, 2, 3}, {_("pin"), _("pointed rod"), 1, 5, 1, 9}, {_("tube"), _("hollow tube"), 2, 5, 3, 6}, {_("pyramid"), _("regular tetrahedron"), 3, 7, 2, 4}, {_("crystal"), _("translucent crystal"), 1, 6, 2, 7}, {_("knot"), _("twisted, knotted cord"), 2, 6, 1, 7}, {_("crescent"), _("crescent-shaped stone"), 2, 6, 2, 6} }; for(int i=0;i<ARTSHAPE_MAX;i++) {artifact_shape_data[i]=tmp_artifact_shape_data[i];} artifact_property_datum tmp_artifact_property_data[ARTPROP_MAX] = { {"BUG", "BUG", {AEP_NULL, AEP_NULL, AEP_NULL, AEP_NULL}, {AEP_NULL, AEP_NULL, AEP_NULL, AEP_NULL}, {AEA_NULL, AEA_NULL, AEA_NULL, AEA_NULL}, {AEA_NULL, AEA_NULL, AEA_NULL, AEA_NULL} }, {_("wriggling"), _("is constantly wriggling"), {AEP_SPEED_UP, AEP_SNAKES, AEP_NULL, AEP_NULL}, {AEP_DEX_DOWN, AEP_FORCE_TELEPORT, AEP_SICK, AEP_NULL}, {AEA_TELEPORT, AEA_ADRENALINE, AEA_NULL, AEA_NULL}, {AEA_MUTATE, AEA_ATTENTION, AEA_VOMIT, AEA_NULL} }, {_("glowing"), _("glows faintly"), {AEP_INT_UP, AEP_GLOW, AEP_CLAIRVOYANCE, AEP_NULL}, {AEP_RADIOACTIVE, AEP_MUTAGENIC, AEP_ATTENTION, AEP_NULL}, {AEA_LIGHT, AEA_LIGHT, AEA_LIGHT, AEA_NULL}, {AEA_ATTENTION, AEA_TELEGLOW, AEA_FLASH, AEA_SHADOWS} }, {_("humming"), _("hums very quietly"), {AEP_ALL_UP, AEP_PSYSHIELD, AEP_NULL, AEP_NULL}, {AEP_SCHIZO, AEP_PER_DOWN, AEP_INT_DOWN, AEP_NULL}, {AEA_PULSE, AEA_ENTRANCE, AEA_NULL, AEA_NULL}, {AEA_NOISE, AEA_NOISE, AEA_SCREAM, AEA_NULL} }, {_("moving"), _("shifts from side to side slowly"), {AEP_STR_UP, AEP_DEX_UP, AEP_SPEED_UP, AEP_NULL}, {AEP_HUNGER, AEP_PER_DOWN, AEP_FORCE_TELEPORT, AEP_NULL}, {AEA_TELEPORT, AEA_TELEPORT, AEA_MAP, AEA_NULL}, {AEA_PARALYZE, AEA_VOMIT, AEA_VOMIT, AEA_NULL} }, {_("whispering"), _("makes very faint whispering sounds"), {AEP_CLAIRVOYANCE, AEP_EXTINGUISH, AEP_STEALTH, AEP_NULL}, {AEP_EVIL, AEP_SCHIZO, AEP_ATTENTION, AEP_NULL}, {AEA_FATIGUE, AEA_ENTRANCE, AEA_ENTRANCE, AEA_NULL}, {AEA_ATTENTION, AEA_SCREAM, AEA_SCREAM, AEA_SHADOWS} }, {_("breathing"), _("shrinks and grows very slightly with a regular pulse, as if breathing"), {AEP_SAP_LIFE, AEP_ALL_UP, AEP_SPEED_UP, AEP_CARRY_MORE}, {AEP_HUNGER, AEP_THIRST, AEP_SICK, AEP_BAD_WEATHER}, {AEA_ADRENALINE, AEA_HEAL, AEA_ENTRANCE, AEA_GROWTH}, {AEA_MUTATE, AEA_ATTENTION, AEA_SHADOWS, AEA_NULL} }, {_("dead"), _("is icy cold to the touch"), {AEP_INVISIBLE, AEP_CLAIRVOYANCE, AEP_EXTINGUISH, AEP_SAP_LIFE}, {AEP_HUNGER, AEP_EVIL, AEP_ALL_DOWN, AEP_SICK}, {AEA_BLOOD, AEA_HURTALL, AEA_NULL, AEA_NULL}, {AEA_PAIN, AEA_SHADOWS, AEA_DIM, AEA_VOMIT} }, {_("itchy"), _("makes your skin itch slightly when it is close"), {AEP_DEX_UP, AEP_SPEED_UP, AEP_PSYSHIELD, AEP_NULL}, {AEP_RADIOACTIVE, AEP_MUTAGENIC, AEP_SICK, AEP_NULL}, {AEA_ADRENALINE, AEA_BLOOD, AEA_HEAL, AEA_BUGS}, {AEA_RADIATION, AEA_PAIN, AEA_PAIN, AEA_VOMIT} }, {_("glittering"), _("glitters faintly under direct light"), {AEP_INT_UP, AEP_EXTINGUISH, AEP_GLOW, AEP_NULL}, {AEP_SMOKE, AEP_ATTENTION, AEP_NULL, AEP_NULL}, {AEA_MAP, AEA_LIGHT, AEA_CONFUSED, AEA_ENTRANCE}, {AEA_RADIATION, AEA_MUTATE, AEA_ATTENTION, AEA_FLASH} }, {_("electric"), _("very weakly shocks you when touched"), {AEP_RESIST_ELECTRICITY, AEP_DEX_UP, AEP_SPEED_UP, AEP_PSYSHIELD}, {AEP_THIRST, AEP_SMOKE, AEP_STR_DOWN, AEP_BAD_WEATHER}, {AEA_STORM, AEA_ADRENALINE, AEA_LIGHT, AEA_NULL}, {AEA_PAIN, AEA_PARALYZE, AEA_FLASH, AEA_FLASH} }, {_("slimy"), _("feels slimy"), {AEP_SNAKES, AEP_STEALTH, AEP_EXTINGUISH, AEP_SAP_LIFE}, {AEP_THIRST, AEP_DEX_DOWN, AEP_SPEED_DOWN, AEP_SICK}, {AEA_BLOOD, AEA_ACIDBALL, AEA_GROWTH, AEA_ACIDBALL}, {AEA_MUTATE, AEA_MUTATE, AEA_VOMIT, AEA_VOMIT} }, {_("engraved"), _("is covered with odd etchings"), {AEP_CLAIRVOYANCE, AEP_INVISIBLE, AEP_PSYSHIELD, AEP_SAP_LIFE}, {AEP_EVIL, AEP_ATTENTION, AEP_NULL, AEP_NULL}, {AEA_FATIGUE, AEA_TELEPORT, AEA_HEAL, AEA_FATIGUE}, {AEA_ATTENTION, AEA_ATTENTION, AEA_TELEGLOW, AEA_DIM} }, {_("crackling"), _("occasionally makes a soft crackling sound"), {AEP_EXTINGUISH, AEP_RESIST_ELECTRICITY, AEP_NULL, AEP_NULL}, {AEP_SMOKE, AEP_RADIOACTIVE, AEP_MOVEMENT_NOISE, AEP_NULL}, {AEA_STORM, AEA_FIREBALL, AEA_PULSE, AEA_NULL}, {AEA_PAIN, AEA_PARALYZE, AEA_NOISE, AEA_NOISE} }, {_("warm"), _("is warm to the touch"), {AEP_STR_UP, AEP_EXTINGUISH, AEP_GLOW, AEP_NULL}, {AEP_SMOKE, AEP_RADIOACTIVE, AEP_NULL, AEP_NULL}, {AEA_FIREBALL, AEA_FIREBALL, AEA_FIREBALL, AEA_LIGHT}, {AEA_FIRESTORM, AEA_FIRESTORM, AEA_TELEGLOW, AEA_NULL} }, {_("rattling"), _("makes a rattling sound when moved"), {AEP_DEX_UP, AEP_SPEED_UP, AEP_SNAKES, AEP_CARRY_MORE}, {AEP_ATTENTION, AEP_INT_DOWN, AEP_MOVEMENT_NOISE, AEP_MOVEMENT_NOISE}, {AEA_BLOOD, AEA_PULSE, AEA_BUGS, AEA_NULL}, {AEA_PAIN, AEA_ATTENTION, AEA_NOISE, AEA_NULL} }, {_("scaled"), _("has a surface reminiscent of reptile scales"), {AEP_SNAKES, AEP_SNAKES, AEP_SNAKES, AEP_STEALTH}, {AEP_THIRST, AEP_MUTAGENIC, AEP_SPEED_DOWN, AEP_NULL}, {AEA_ADRENALINE, AEA_BUGS, AEA_GROWTH, AEA_NULL}, {AEA_MUTATE, AEA_SCREAM, AEA_DIM, AEA_NULL} }, {_("fractal"), _("has a self-similar pattern which repeats until it is too small for you to see"), {AEP_ALL_UP, AEP_ALL_UP, AEP_CLAIRVOYANCE, AEP_PSYSHIELD}, {AEP_SCHIZO, AEP_ATTENTION, AEP_FORCE_TELEPORT, AEP_BAD_WEATHER}, {AEA_STORM, AEA_FATIGUE, AEA_TELEPORT, AEA_NULL}, {AEA_RADIATION, AEA_MUTATE, AEA_TELEGLOW, AEA_TELEGLOW} } }; for(int i=0;i<ARTPROP_MAX;i++) {artifact_property_data[i]=tmp_artifact_property_data[i];} artifact_tool_form_datum tmp_artifact_tool_form_data[NUM_ARTTOOLFORMS] = { {"", '*', c_white, "null", "null", 0, 0, 0, 0, ARTWEAP_BULK, {ARTWEAP_NULL, ARTWEAP_NULL, ARTWEAP_NULL}}, {_("Harp"), ';', c_yellow, "wood", "null", 20, 30, 10, 18, ARTWEAP_BULK, {ARTWEAP_SPEAR, ARTWEAP_SWORD, ARTWEAP_KNIFE}}, {_("Staff"), '/', c_brown, "wood", "null", 6, 12, 4, 10, ARTWEAP_CLUB, {ARTWEAP_BULK, ARTWEAP_SPEAR, ARTWEAP_KNIFE}}, {_("Sword"), '/', c_ltblue, "steel", "null", 8, 14, 8, 28, ARTWEAP_SWORD, {ARTWEAP_BULK, ARTWEAP_NULL, ARTWEAP_NULL}}, {_("Dagger"), ';', c_ltblue, "steel", "null", 1, 4, 1, 6, ARTWEAP_KNIFE, {ARTWEAP_NULL, ARTWEAP_NULL, ARTWEAP_NULL}}, {_("Cube"), '*', c_white, "steel", "null", 1, 3, 1, 20, ARTWEAP_BULK, {ARTWEAP_SPEAR, ARTWEAP_NULL, ARTWEAP_NULL}} }; for(int i=0;i<NUM_ARTTOOLFORMS;i++) {artifact_tool_form_data[i]=tmp_artifact_tool_form_data[i];} artifact_weapon_datum tmp_artifact_weapon_data[NUM_ARTWEAPS] = { {"", 0, 0, 0, 0, 0, 0, 0, 0, ""}, // Adjective Vol,wgt Bash Cut To-Hit tags {_("Heavy"), 0, 12, 10, 20, 0, 0, -2, 0, ""}, {_("Knobbed"), 1, 2, 14, 30, 0, 0, -1, 1, ""}, {_("Spiked"), 1, 1, 0, 0, 20, 40, -1, 1, "SPEAR"}, {_("Edged"), 2, 4, 0, 0, 20, 50, -1, 2, ""}, {_("Bladed"), 1, 2, 0, 0, 12, 30, -1, 1, "STAB"} }; for(int i=0;i<NUM_ARTWEAPS;i++) {artifact_weapon_data[i]=tmp_artifact_weapon_data[i];} artifact_armor_form_datum tmp_artifact_armor_form_data[NUM_ARTARMFORMS] = { {"", c_white, "null", "null", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL}}, // Name color Materials Vol Wgt Enc Cov Thk Env Wrm Sto Bsh Cut Hit {_("Robe"), c_red, "wool", "null", 6, 6, 1, 3, 3, 0, 2, 0, -8, 0, -3, mfb(bp_torso)|mfb(bp_legs), false, {ARMORMOD_LIGHT, ARMORMOD_BULKY, ARMORMOD_POCKETED, ARMORMOD_FURRED, ARMORMOD_PADDED}}, {_("Coat"), c_brown,"leather","null", 14, 14, 2, 3, 2, 1, 4, 4, -6, 0, -3, mfb(bp_torso), false, {ARMORMOD_LIGHT, ARMORMOD_POCKETED, ARMORMOD_FURRED, ARMORMOD_PADDED, ARMORMOD_PLATED}}, {_("Mask"), c_white, "wood", "null", 4, 1, 2, 2, 2, 1, 2, 0, 2, 0, -2, mfb(bp_eyes)|mfb(bp_mouth), false, {ARMORMOD_FURRED, ARMORMOD_FURRED, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL}}, // Name color Materials Vol Wgt Enc Cov Thk Env Wrm Sto Bsh Cut Hit {_("Helm"), c_dkgray, "silver", "null", 6, 6, 2, 3, 3, 0, 1, 0, 8, 0, -2, mfb(bp_head), false, {ARMORMOD_BULKY, ARMORMOD_FURRED, ARMORMOD_PADDED, ARMORMOD_PLATED, ARMORMOD_NULL}}, {_("Gloves"), c_ltblue,"leather","null", 2, 1, 1, 3, 3, 1, 2, 0, -4, 0, -2, mfb(bp_hands), true, {ARMORMOD_BULKY, ARMORMOD_FURRED, ARMORMOD_PADDED, ARMORMOD_PLATED, ARMORMOD_NULL}}, // Name color Materials Vol Wgt Enc Cov Thk Env Wrm Sto Bsh Cut Hit {_("Boots"), c_blue, "leather", "null", 6, 2, 1, 3, 3, 1, 3, 0, 4, 0, -1, mfb(bp_feet), true, {ARMORMOD_LIGHT, ARMORMOD_BULKY, ARMORMOD_PADDED, ARMORMOD_PLATED, ARMORMOD_NULL}}, {_("Ring"), c_ltgreen, "silver", "null", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true, {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL}} }; for(int i=0;i<NUM_ARTARMFORMS;i++) {artifact_armor_form_data[i]=tmp_artifact_armor_form_data[i];} artifact_armor_form_datum tmp_artifact_armor_mod_data[NUM_ARMORMODS] = { {"", c_white, "null", "null", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL}}, // Description; "It is ..." or "They are ..." {_("very thin and light."), c_white, "null", "null", // Vol Wgt Enc Cov Thk Env Wrm Sto -4, -8, -2, -1, -1, -1, -1, 0, 0, 0, 0, 0, false, {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL}}, {_("extremely bulky."), c_white, "null", "null", 8, 10, 2, 1, 1, 0, 1, 0, 0, 0, 0, 0, false, {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL}}, {_("covered in pockets."), c_white, "null", "null", 1, 1, 1, 0, 0, 0, 0, 16, 0, 0, 0, 0, false, {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL}}, {_("disgustingly furry."), c_white, "wool", "null", // Vol Wgt Enc Dmg Cut Env Wrm Sto 4, 2, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, false, {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL}}, {_("leather-padded."), c_white, "leather", "null", 4, 4, 1, 1, 1, 0, 1, -3, 0, 0, 0, 0, false, {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL}}, {_("plated in iron."), c_white, "iron", "null", 4, 12, 3, 2, 2, 0, 1, -4, 0, 0, 0, 0, false, {ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL, ARMORMOD_NULL}}, }; for(int i=0;i<NUM_ARMORMODS;i++) {artifact_armor_mod_data[i]=tmp_artifact_armor_mod_data[i];} std::string tmp_artifact_adj[NUM_ART_ADJS] = { _("Forbidden"), _("Unknown"), _("Forgotten"), _("Hideous"), _("Eldritch"), _("Gelatinous"), _("Ancient"), _("Cursed"), _("Bloody"), _("Undying"), _("Shadowy"), _("Silent"), _("Cyclopean"), _("Fungal"), _("Unspeakable"), _("Grotesque"), _("Frigid"), _("Shattered"), _("Sleeping"), _("Repellent") }; for(int i=0;i<NUM_ART_ADJS;i++) {artifact_adj[i]=tmp_artifact_adj[i];} std::string tmp_artifact_noun[NUM_ART_NOUNS] = { _("%s Technique"), _("%s Dreams"), _("%s Beasts"), _("%s Evil"), _("%s Miasma"), _("the %s Abyss"), _("the %s City"), _("%s Shadows"), _("%s Shade"), _("%s Illusion"), _("%s Justice"), _("the %s Necropolis"), _("%s Ichor"), _("the %s Monolith"), _("%s Aeons"), _("%s Graves"), _("%s Horrors"), _("%s Suffering"), _("%s Death"), _("%s Horror") }; for(int i=0;i<NUM_ART_NOUNS;i++) {artifact_noun[i]=tmp_artifact_noun[i];} }
bool faction::has_value(faction_value v) { return values & mfb(v); }
void faction::randomize() { // Set up values // TODO: Not always in overmap 0,0 omx = 0; omy = 0; mapx = rng(OMAPX / 10, OMAPX - OMAPX / 10); mapy = rng(OMAPY / 10, OMAPY - OMAPY / 10); // Pick an overall goal. goal = faction_goal(rng(1, NUM_FACGOALS - 1)); if (one_in(4)) goal = FACGOAL_NONE; // Slightly more likely to not have a real goal good = facgoal_data[goal].good; strength = facgoal_data[goal].strength; sneak = facgoal_data[goal].sneak; crime = facgoal_data[goal].crime; cult = facgoal_data[goal].cult; job1 = faction_job(rng(1, NUM_FACJOBS - 1)); do job2 = faction_job(rng(0, NUM_FACJOBS - 1)); while (job2 == job1); good += facjob_data[job1].good + facjob_data[job2].good; strength += facjob_data[job1].strength + facjob_data[job2].strength; sneak += facjob_data[job1].sneak + facjob_data[job2].sneak; crime += facjob_data[job1].crime + facjob_data[job2].crime; cult += facjob_data[job1].cult + facjob_data[job2].cult; int num_values = 0; int tries = 0; values = 0; do { int v = rng(1, NUM_FACVALS - 1); if (!has_value(faction_value(v)) && matches_us(faction_value(v))) { values |= mfb(v); tries = 0; num_values++; good += facval_data[v].good; strength += facval_data[v].strength; sneak += facval_data[v].sneak; crime += facval_data[v].crime; cult += facval_data[v].cult; } else tries++; } while((one_in(num_values) || one_in(num_values)) && tries < 15); std::string noun; int sel = 1, best = strength; if (sneak > best) { sel = 2; best = sneak; } if (crime > best) { sel = 3; best = crime; } if (cult > best) sel = 4; if (strength <= 0 && sneak <= 0 && crime <= 0 && cult <= 0) sel = 0; switch (sel) { case 1: noun = faction_noun_strong[rng(0, 14)]; power = dice(5, 20); size = dice(5, 6); break; case 2: noun = faction_noun_sneak [rng(0, 14)]; power = dice(5, 8); size = dice(5, 8); break; case 3: noun = faction_noun_crime [rng(0, 14)]; power = dice(5, 16); size = dice(5, 8); break; case 4: noun = faction_noun_cult [rng(0, 14)]; power = dice(8, 8); size = dice(4, 6); break; default: noun = faction_noun_none [rng(0, 14)]; power = dice(6, 8); size = dice(6, 6); } if (one_in(4)) { do name = "The " + noun + " of " + invent_name(); while (name.length() > MAX_FAC_NAME_SIZE); } else if (one_in(2)) { do name = "The " + invent_adj() + " " + noun; while (name.length() > MAX_FAC_NAME_SIZE); } else { do { std::string adj; if (good >= 3) adj = faction_adj_pos[rng(0, 14)]; else if (good <= -3) adj = faction_adj_bad[rng(0, 14)]; else adj = faction_adj_neu[rng(0, 14)]; name = "The " + adj + " " + noun; if (one_in(4)) name += " of " + invent_name(); } while (name.length() > MAX_FAC_NAME_SIZE); } }
void Item_factory::init(){ //Populate the iuse functions iuse_function_list["NONE"] = &iuse::none; iuse_function_list["SEWAGE"] = &iuse::sewage; iuse_function_list["HONEYCOMB"] = &iuse::honeycomb; iuse_function_list["ROYAL_JELLY"] = &iuse::royal_jelly; iuse_function_list["BANDAGE"] = &iuse::bandage; iuse_function_list["FIRSTAID"] = &iuse::firstaid; iuse_function_list["DISINFECTANT"] = &iuse::disinfectant; iuse_function_list["CAFF"] = &iuse::caff; iuse_function_list["ATOMIC_CAFF"] = &iuse::atomic_caff; iuse_function_list["ALCOHOL"] = &iuse::alcohol; iuse_function_list["ALCOHOL_WEAK"] = &iuse::alcohol_weak; iuse_function_list["PKILL"] = &iuse::pkill; iuse_function_list["XANAX"] = &iuse::xanax; iuse_function_list["CIG"] = &iuse::cig; iuse_function_list["ANTIBIOTIC"] = &iuse::antibiotic; iuse_function_list["FUNGICIDE"] = &iuse::fungicide; iuse_function_list["WEED"] = &iuse::weed; iuse_function_list["COKE"] = &iuse::coke; iuse_function_list["CRACK"] = &iuse::crack; iuse_function_list["GRACK"] = &iuse::grack; iuse_function_list["METH"] = &iuse::meth; iuse_function_list["VITAMINS"] = &iuse::vitamins; iuse_function_list["VACCINE"] = &iuse::vaccine; iuse_function_list["POISON"] = &iuse::poison; iuse_function_list["HALLU"] = &iuse::hallu; iuse_function_list["THORAZINE"] = &iuse::thorazine; iuse_function_list["PROZAC"] = &iuse::prozac; iuse_function_list["SLEEP"] = &iuse::sleep; iuse_function_list["IODINE"] = &iuse::iodine; iuse_function_list["FLUMED"] = &iuse::flumed; iuse_function_list["FLUSLEEP"] = &iuse::flusleep; iuse_function_list["INHALER"] = &iuse::inhaler; iuse_function_list["BLECH"] = &iuse::blech; iuse_function_list["CHEW"] = &iuse::chew; iuse_function_list["MUTAGEN"] = &iuse::mutagen; iuse_function_list["PURIFIER"] = &iuse::purifier; iuse_function_list["MARLOSS"] = &iuse::marloss; iuse_function_list["DOGFOOD"] = &iuse::dogfood; iuse_function_list["CATFOOD"] = &iuse::catfood; // TOOLS iuse_function_list["LIGHTER"] = &iuse::lighter; iuse_function_list["PRIMITIVE_FIRE"] = &iuse::primitive_fire; iuse_function_list["SEW"] = &iuse::sew; iuse_function_list["EXTRA_BATTERY"] = &iuse::extra_battery; iuse_function_list["SCISSORS"] = &iuse::scissors; iuse_function_list["EXTINGUISHER"] = &iuse::extinguisher; iuse_function_list["HAMMER"] = &iuse::hammer; iuse_function_list["LIGHT_OFF"] = &iuse::light_off; iuse_function_list["LIGHT_ON"] = &iuse::light_on; iuse_function_list["GASOLINE_LANTERN_OFF"] = &iuse::gasoline_lantern_off; iuse_function_list["GASOLINE_LANTERN_ON"] = &iuse::gasoline_lantern_on; iuse_function_list["LIGHTSTRIP"] = &iuse::lightstrip; iuse_function_list["LIGHTSTRIP_ACTIVE"] = &iuse::lightstrip_active; iuse_function_list["GLOWSTICK"] = &iuse::glowstick; iuse_function_list["GLOWSTICK_ACTIVE"] = &iuse::glowstick_active; iuse_function_list["DIRECTIONAL_ANTENNA"] = &iuse::directional_antenna; iuse_function_list["SOLDER_WELD"] = &iuse::solder_weld; iuse_function_list["WATER_PURIFIER"] = &iuse::water_purifier; iuse_function_list["TWO_WAY_RADIO"] = &iuse::two_way_radio; iuse_function_list["RADIO_OFF"] = &iuse::radio_off; iuse_function_list["RADIO_ON"] = &iuse::radio_on; iuse_function_list["HORN_BICYCLE"] = &iuse::horn_bicycle; iuse_function_list["NOISE_EMITTER_OFF"] = &iuse::noise_emitter_off; iuse_function_list["NOISE_EMITTER_ON"] = &iuse::noise_emitter_on; iuse_function_list["ROADMAP"] = &iuse::roadmap; iuse_function_list["SURVIVORMAP"] = &iuse::survivormap; iuse_function_list["MILITARYMAP"] = &iuse::militarymap; iuse_function_list["RESTAURANTMAP"] = &iuse::restaurantmap; iuse_function_list["TOURISTMAP"] = &iuse::touristmap; iuse_function_list["PICKLOCK"] = &iuse::picklock; iuse_function_list["CROWBAR"] = &iuse::crowbar; iuse_function_list["MAKEMOUND"] = &iuse::makemound; iuse_function_list["DIG"] = &iuse::dig; iuse_function_list["SIPHON"] = &iuse::siphon; iuse_function_list["CHAINSAW_OFF"] = &iuse::chainsaw_off; iuse_function_list["CHAINSAW_ON"] = &iuse::chainsaw_on; iuse_function_list["CARVER_OFF"] = &iuse::carver_off; iuse_function_list["CARVER_ON"] = &iuse::carver_on; iuse_function_list["SHISHKEBAB_OFF"] = &iuse::shishkebab_off; iuse_function_list["SHISHKEBAB_ON"] = &iuse::shishkebab_on; iuse_function_list["FIREMACHETE_OFF"] = &iuse::firemachete_off; iuse_function_list["FIREMACHETE_ON"] = &iuse::firemachete_on; iuse_function_list["BROADFIRE_OFF"] = &iuse::broadfire_off; iuse_function_list["BROADFIRE_ON"] = &iuse::broadfire_on; iuse_function_list["FIREKATANA_OFF"] = &iuse::firekatana_off; iuse_function_list["FIREKATANA_ON"] = &iuse::firekatana_on; iuse_function_list["ZWEIFIRE_OFF"] = &iuse::zweifire_off; iuse_function_list["ZWEIFIRE_ON"] = &iuse::zweifire_on; iuse_function_list["JACKHAMMER"] = &iuse::jackhammer; iuse_function_list["JACQUESHAMMER"] = &iuse::jacqueshammer; iuse_function_list["PICKAXE"] = &iuse::pickaxe; iuse_function_list["SET_TRAP"] = &iuse::set_trap; iuse_function_list["GEIGER"] = &iuse::geiger; iuse_function_list["TELEPORT"] = &iuse::teleport; iuse_function_list["CAN_GOO"] = &iuse::can_goo; iuse_function_list["PIPEBOMB"] = &iuse::pipebomb; iuse_function_list["PIPEBOMB_ACT"] = &iuse::pipebomb_act; iuse_function_list["GRENADE"] = &iuse::grenade; iuse_function_list["GRENADE_ACT"] = &iuse::grenade_act; iuse_function_list["GRANADE"] = &iuse::granade; iuse_function_list["GRANADE_ACT"] = &iuse::granade_act; iuse_function_list["FLASHBANG"] = &iuse::flashbang; iuse_function_list["FLASHBANG_ACT"] = &iuse::flashbang_act; iuse_function_list["C4"] = &iuse::c4; iuse_function_list["C4ARMED"] = &iuse::c4armed; iuse_function_list["EMPBOMB"] = &iuse::EMPbomb; iuse_function_list["EMPBOMB_ACT"] = &iuse::EMPbomb_act; iuse_function_list["SCRAMBLER"] = &iuse::scrambler; iuse_function_list["SCRAMBLER_ACT"] = &iuse::scrambler_act; iuse_function_list["GASBOMB"] = &iuse::gasbomb; iuse_function_list["GASBOMB_ACT"] = &iuse::gasbomb_act; iuse_function_list["SMOKEBOMB"] = &iuse::smokebomb; iuse_function_list["SMOKEBOMB_ACT"] = &iuse::smokebomb_act; iuse_function_list["ACIDBOMB"] = &iuse::acidbomb; iuse_function_list["ACIDBOMB_ACT"] = &iuse::acidbomb_act; iuse_function_list["ARROW_FLAMABLE"] = &iuse::arrow_flamable; iuse_function_list["MOLOTOV"] = &iuse::molotov; iuse_function_list["MOLOTOV_LIT"] = &iuse::molotov_lit; iuse_function_list["MATCHBOMB"] = &iuse::matchbomb; iuse_function_list["MATCHBOMB_ACT"] = &iuse::matchbomb_act; iuse_function_list["DYNAMITE"] = &iuse::dynamite; iuse_function_list["DYNAMITE_ACT"] = &iuse::dynamite_act; iuse_function_list["FIRECRACKER_PACK"] = &iuse::firecracker_pack; iuse_function_list["FIRECRACKER_PACK_ACT"] = &iuse::firecracker_pack_act; iuse_function_list["FIRECRACKER"] = &iuse::firecracker; iuse_function_list["FIRECRACKER_ACT"] = &iuse::firecracker_act; iuse_function_list["MININUKE"] = &iuse::mininuke; iuse_function_list["MININUKE_ACT"] = &iuse::mininuke_act; iuse_function_list["PHEROMONE"] = &iuse::pheromone; iuse_function_list["PORTAL"] = &iuse::portal; iuse_function_list["MANHACK"] = &iuse::manhack; iuse_function_list["TURRET"] = &iuse::turret; iuse_function_list["TURRET_LASER"] = &iuse::turret_laser; iuse_function_list["UPS_OFF"] = &iuse::UPS_off; iuse_function_list["UPS_ON"] = &iuse::UPS_on; iuse_function_list["adv_UPS_OFF"] = &iuse::adv_UPS_off; iuse_function_list["adv_UPS_ON"] = &iuse::adv_UPS_on; iuse_function_list["TAZER"] = &iuse::tazer; iuse_function_list["TAZER2"] = &iuse::tazer2; iuse_function_list["SHOCKTONFA_OFF"] = &iuse::shocktonfa_off; iuse_function_list["SHOCKTONFA_ON"] = &iuse::shocktonfa_on; iuse_function_list["MP3"] = &iuse::mp3; iuse_function_list["MP3_ON"] = &iuse::mp3_on; iuse_function_list["PORTABLE_GAME"] = &iuse::portable_game; iuse_function_list["VORTEX"] = &iuse::vortex; iuse_function_list["DOG_WHISTLE"] = &iuse::dog_whistle; iuse_function_list["VACUTAINER"] = &iuse::vacutainer; iuse_function_list["KNIFE"] = &iuse::knife; iuse_function_list["LUMBER"] = &iuse::lumber; iuse_function_list["HACKSAW"] = &iuse::hacksaw; iuse_function_list["TENT"] = &iuse::tent; iuse_function_list["SHELTER"] = &iuse::shelter; iuse_function_list["TORCH"] = &iuse::torch; iuse_function_list["TORCH_LIT"] = &iuse::torch_lit; iuse_function_list["HANDFLARE"] = &iuse::handflare; iuse_function_list["HANDFLARE_LIT"] = &iuse::handflare_lit; iuse_function_list["BATTLETORCH"] = &iuse::battletorch; iuse_function_list["BATTLETORCH_LIT"] = &iuse::battletorch_lit; iuse_function_list["CANDLE"] = &iuse::candle; iuse_function_list["CANDLE_LIT"] = &iuse::candle_lit; iuse_function_list["BULLET_PULLER"] = &iuse::bullet_puller; iuse_function_list["BOLTCUTTERS"] = &iuse::boltcutters; iuse_function_list["MOP"] = &iuse::mop; iuse_function_list["SPRAY_CAN"] = &iuse::spray_can; iuse_function_list["RAG"] = &iuse::rag; iuse_function_list["PDA"] = &iuse::pda; iuse_function_list["PDA_FLASHLIGHT"] = &iuse::pda_flashlight; iuse_function_list["LAW"] = &iuse::LAW; iuse_function_list["HEATPACK"] = &iuse::heatpack; iuse_function_list["DEJAR"] = &iuse::dejar; iuse_function_list["RAD_BADGE"] = &iuse::rad_badge; iuse_function_list["BOOTS"] = &iuse::boots; iuse_function_list["ABSORBENT"] = &iuse::towel; iuse_function_list["UNFOLD_BICYCLE"] = &iuse::unfold_bicycle; iuse_function_list["ADRENALINE_INJECTOR"] = &iuse::adrenaline_injector; iuse_function_list["JET_INJECTOR"] = &iuse::jet_injector; iuse_function_list["CONTACTS"] = &iuse::contacts; iuse_function_list["AIRHORN"] = &iuse::airhorn; iuse_function_list["HOTPLATE"] = &iuse::hotplate; iuse_function_list["DOLLCHAT"] = &iuse::talking_doll; // MACGUFFINS iuse_function_list["MCG_NOTE"] = &iuse::mcg_note; // ARTIFACTS // This function is used when an artifact is activated // It examines the item's artifact-specific properties // See artifact.h for a list iuse_function_list["ARTIFACT"] = &iuse::artifact; // Offensive Techniques techniques_list["PRECISE"] = "tec_precise"; techniques_list["RAPID"] = "tec_rapid"; bodyparts_list["TORSO"] = mfb(bp_torso); bodyparts_list["HEAD"] = mfb(bp_head); bodyparts_list["EYES"] = mfb(bp_eyes); bodyparts_list["MOUTH"] = mfb(bp_mouth); bodyparts_list["ARMS"] = mfb(bp_arms); bodyparts_list["HANDS"] = mfb(bp_hands); bodyparts_list["LEGS"] = mfb(bp_legs); bodyparts_list["FEET"] = mfb(bp_feet); }
bool monster::has_flag(m_flags f) { return type->flags & mfb(f); }
bool map::process_fields_in_submap(game *g, int gridn) { bool found_field = false; field *cur; field_id curtype; for (int locx = 0; locx < SEEX; locx++) { for (int locy = 0; locy < SEEY; locy++) { cur = &(grid[gridn].fld[locx][locy]); int x = locx + SEEX * (gridn % my_MAPSIZE), y = locy + SEEY * int(gridn / my_MAPSIZE); curtype = cur->type; if (!found_field && curtype != fd_null) found_field = true; if (cur->density > 3 || cur->density < 1) debugmsg("Whoooooa density of %d", cur->density); if (cur->age == 0) // Don't process "newborn" fields curtype = fd_null; int part; vehicle *veh; switch (curtype) { case fd_null: break; // Do nothing, obviously. OBVIOUSLY. case fd_blood: case fd_bile: if (has_flag(swimmable, x, y)) // Dissipate faster in water cur->age += 250; break; case fd_acid: if (has_flag(swimmable, x, y)) // Dissipate faster in water cur->age += 20; for (int i = 0; i < i_at(x, y).size(); i++) { item *melting = &(i_at(x, y)[i]); if (melting->made_of(LIQUID) || melting->made_of(VEGGY) || melting->made_of(FLESH) || melting->made_of(POWDER) || melting->made_of(COTTON) || melting->made_of(WOOL) || melting->made_of(PAPER) || melting->made_of(PLASTIC) || (melting->made_of(GLASS) && !one_in(3)) || one_in(4)) { // Acid destructable objects here melting->damage++; if (melting->damage >= 5 || (melting->made_of(PAPER) && melting->damage >= 3)) { cur->age += melting->volume(); for (int m = 0; m < i_at(x, y)[i].contents.size(); m++) i_at(x, y).push_back( i_at(x, y)[i].contents[m] ); i_at(x, y).erase(i_at(x, y).begin() + i); i--; } } } break; case fd_sap: break; // It doesn't do anything. case fd_fire: { // Consume items as fuel to help us grow/last longer. bool destroyed = false; int vol = 0, smoke = 0, consumed = 0; for (int i = 0; i < i_at(x, y).size() && consumed < cur->density * 2; i++) { destroyed = false; vol = i_at(x, y)[i].volume(); item *it = &(i_at(x, y)[i]); if (it->is_ammo() && it->ammo_type() != AT_BATT && it->ammo_type() != AT_NAIL && it->ammo_type() != AT_BB && it->ammo_type() != AT_BOLT && it->ammo_type() != AT_ARROW) { cur->age /= 2; cur->age -= 600; destroyed = true; smoke += 6; consumed++; } else if (it->made_of(PAPER)) { destroyed = it->burn(cur->density * 3); consumed++; if (cur->density == 1) cur->age -= vol * 10; if (vol >= 4) smoke++; } else if ((it->made_of(WOOD) || it->made_of(VEGGY))) { if (vol <= cur->density * 10 || cur->density == 3) { cur->age -= 4; destroyed = it->burn(cur->density); smoke++; consumed++; } else if (it->burnt < cur->density) { destroyed = it->burn(1); smoke++; } } else if ((it->made_of(COTTON) || it->made_of(WOOL))) { if (vol <= cur->density * 5 || cur->density == 3) { cur->age--; destroyed = it->burn(cur->density); smoke++; consumed++; } else if (it->burnt < cur->density) { destroyed = it->burn(1); smoke++; } } else if (it->made_of(FLESH)) { if (vol <= cur->density * 5 || (cur->density == 3 && one_in(vol / 20))) { cur->age--; destroyed = it->burn(cur->density); smoke += 3; consumed++; } else if (it->burnt < cur->density * 5 || cur->density >= 2) { destroyed = it->burn(1); smoke++; } } else if (it->made_of(LIQUID)) { switch (it->type->id) { // TODO: Make this be not a hack. case itm_whiskey: case itm_vodka: case itm_rum: case itm_tequila: cur->age -= 300; smoke += 6; break; default: cur->age += rng(80 * vol, 300 * vol); smoke++; } destroyed = true; consumed++; } else if (it->made_of(POWDER)) { cur->age -= vol; destroyed = true; smoke += 2; } else if (it->made_of(PLASTIC)) { smoke += 3; if (it->burnt <= cur->density * 2 || (cur->density == 3 && one_in(vol))) { destroyed = it->burn(cur->density); if (one_in(vol + it->burnt)) cur->age--; } } if (destroyed) { for (int m = 0; m < i_at(x, y)[i].contents.size(); m++) i_at(x, y).push_back( i_at(x, y)[i].contents[m] ); i_at(x, y).erase(i_at(x, y).begin() + i); i--; } } veh = &(veh_at(x, y, part)); if (veh->type != veh_null && (veh->parts[part].flags & VHP_FUEL_TANK) && veh->fuel_type == AT_GAS) { if (cur->density > 1 && one_in (8) && veh->fuel > 0) veh->explode (g, x, y); } // Consume the terrain we're on if (has_flag(explodes, x, y)) { ter(x, y) = ter_id(int(ter(x, y)) + 1); cur->age = 0; cur->density = 3; g->explosion(x, y, 40, 0, true); } else if (has_flag(inflammable, x, y) && one_in(32 - cur->density * 10)) { cur->age -= cur->density * cur->density * 40; smoke += 15; if (cur->density == 3) ter(x, y) = t_ash; } else if (has_flag(flammable, x, y) && one_in(32 - cur->density * 10)) { cur->age -= cur->density * cur->density * 40; smoke += 15; if (cur->density == 3) ter(x, y) = t_rubble; } else if (has_flag(meltable, x, y) && one_in(32 - cur->density * 10)) { cur->age -= cur->density * cur->density * 40; if (cur->density == 3) ter(x, y) = t_b_metal; } else if (terlist[ter(x, y)].flags & mfb(swimmable)) cur->age += 800; // Flames die quickly on water // If we consumed a lot, the flames grow higher while (cur->density < 3 && cur->age < 0) { cur->age += 300; cur->density++; } // If the flames are in a pit, it can't spread to non-pit bool in_pit = (ter(x, y) == t_pit); // If the flames are REALLY big, they contribute to adjacent flames if (cur->density == 3 && cur->age < 0) { // Randomly offset our x/y shifts by 0-2, to randomly pick a square to spread to int starti = rng(0, 2); int startj = rng(0, 2); for (int i = 0; i < 3 && cur->age < 0; i++) { for (int j = 0; j < 3 && cur->age < 0; j++) { int fx = x + ((i + starti) % 3) - 1, fy = y + ((j + startj) % 3) - 1; if (field_at(fx, fy).type == fd_fire && field_at(fx, fy).density < 3 && (!in_pit || ter(fx, fy) == t_pit)) { field_at(fx, fy).density++; field_at(fx, fy).age = 0; cur->age = 0; } } } } // Consume adjacent fuel / terrain to spread. // Randomly offset our x/y shifts by 0-2, to randomly pick a square to spread to int starti = rng(0, 2); int startj = rng(0, 2); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { int fx = x + ((i + starti) % 3) - 1, fy = y + ((j + startj) % 3) - 1; if (INBOUNDS(fx, fy)) { int spread_chance = 20 * (cur->density - 1) + 10 * smoke; if (has_flag(explodes, fx, fy) && one_in(8 - cur->density)) { ter(fx, fy) = ter_id(int(ter(fx, fy)) + 1); g->explosion(fx, fy, 40, 0, true); } else if ((i != 0 || j != 0) && rng(1, 100) < spread_chance && (!in_pit || ter(fx, fy) == t_pit) && ((cur->density == 3 && (has_flag(flammable, fx, fy) || one_in(20))) || flammable_items_at(fx, fy) || field_at(fx, fy).type == fd_web)) { if (field_at(fx, fy).type == fd_smoke || field_at(fx, fy).type == fd_web) field_at(fx, fy) = field(fd_fire, 1, 0); else add_field(g, fx, fy, fd_fire, 1); } else { bool nosmoke = true; for (int ii = -1; ii <= 1; ii++) { for (int jj = -1; jj <= 1; jj++) { if (field_at(x+ii, y+jj).type == fd_fire && field_at(x+ii, y+jj).density == 3) smoke++; else if (field_at(x+ii, y+jj).type == fd_smoke) nosmoke = false; } } // If we're not spreading, maybe we'll stick out some smoke, huh? if (move_cost(fx, fy) > 0 && (!one_in(smoke) || (nosmoke && one_in(40))) && rng(3, 35) < cur->density * 10 && cur->age < 1000) { smoke--; add_field(g, fx, fy, fd_smoke, rng(1, cur->density)); } } } } } } break; case fd_smoke: for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) g->scent(x+i, y+j) = 0; } if (is_outside(x, y)) cur->age += 50; if (one_in(2)) { std::vector <point> spread; for (int a = -1; a <= 1; a++) { for (int b = -1; b <= 1; b++) { if ((field_at(x+a, y+b).type == fd_smoke && field_at(x+a, y+b).density < 3 ) || (field_at(x+a, y+b).is_null() && move_cost(x+a, y+b) > 0)) spread.push_back(point(x+a, y+b)); } } if (cur->density > 0 && cur->age > 0 && spread.size() > 0) { point p = spread[rng(0, spread.size() - 1)]; if (field_at(p.x, p.y).type == fd_smoke && field_at(p.x, p.y).density < 3) { field_at(p.x, p.y).density++; cur->density--; } else if (cur->density > 0 && move_cost(p.x, p.y) > 0 && add_field(g, p.x, p.y, fd_smoke, 1)){ cur->density--; field_at(p.x, p.y).age = cur->age; } } } break; case fd_tear_gas: // Reset nearby scents to zero for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) g->scent(x+i, y+j) = 0; } if (is_outside(x, y)) cur->age += 30; // One in three chance that it spreads (less than smoke!) if (one_in(3)) { std::vector <point> spread; // Pick all eligible points to spread to for (int a = -1; a <= 1; a++) { for (int b = -1; b <= 1; b++) { if (((field_at(x+a, y+b).type == fd_smoke || field_at(x+a, y+b).type == fd_tear_gas) && field_at(x+a, y+b).density < 3 ) || (field_at(x+a, y+b).is_null() && move_cost(x+a, y+b) > 0)) spread.push_back(point(x+a, y+b)); } } // Then, spread to a nearby point if (cur->density > 0 && cur->age > 0 && spread.size() > 0) { point p = spread[rng(0, spread.size() - 1)]; // Nearby teargas grows thicker if (field_at(p.x, p.y).type == fd_tear_gas && field_at(p.x, p.y).density < 3) { field_at(p.x, p.y).density++; cur->density--; // Nearby smoke is converted into teargas } else if (field_at(p.x, p.y).type == fd_smoke) { field_at(p.x, p.y).type = fd_tear_gas; // Or, just create a new field. } else if (cur->density > 0 && move_cost(p.x, p.y) > 0 && add_field(g, p.x, p.y, fd_tear_gas, 1)) { cur->density--; field_at(p.x, p.y).age = cur->age; } } } break; case fd_toxic_gas: // Reset nearby scents to zero for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) g->scent(x+i, y+j) = 0; } if (is_outside(x, y)) cur->age += 40; if (one_in(2)) { std::vector <point> spread; // Pick all eligible points to spread to for (int a = -1; a <= 1; a++) { for (int b = -1; b <= 1; b++) { if (((field_at(x+a, y+b).type == fd_smoke || field_at(x+a, y+b).type == fd_tear_gas || field_at(x+a, y+b).type == fd_toxic_gas || field_at(x+a, y+b).type == fd_nuke_gas ) && field_at(x+a, y+b).density < 3 ) || (field_at(x+a, y+b).is_null() && move_cost(x+a, y+b) > 0)) spread.push_back(point(x+a, y+b)); } } // Then, spread to a nearby point if (cur->density > 0 && cur->age > 0 && spread.size() > 0) { point p = spread[rng(0, spread.size() - 1)]; // Nearby toxic gas grows thicker if (field_at(p.x, p.y).type == fd_toxic_gas && field_at(p.x, p.y).density < 3) { field_at(p.x, p.y).density++; cur->density--; // Nearby smoke & teargas is converted into toxic gas } else if (field_at(p.x, p.y).type == fd_smoke || field_at(p.x, p.y).type == fd_tear_gas) { field_at(p.x, p.y).type = fd_toxic_gas; // Or, just create a new field. } else if (cur->density > 0 && move_cost(p.x, p.y) > 0 && add_field(g, p.x, p.y, fd_toxic_gas, 1)) { cur->density--; field_at(p.x, p.y).age = cur->age; } } } break; case fd_nuke_gas: // Reset nearby scents to zero for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) g->scent(x+i, y+j) = 0; } if (is_outside(x, y)) cur->age += 40; // Increase long-term radiation in the land underneath radiation(x, y) += rng(0, cur->density); if (one_in(2)) { std::vector <point> spread; // Pick all eligible points to spread to for (int a = -1; a <= 1; a++) { for (int b = -1; b <= 1; b++) { if (((field_at(x+a, y+b).type == fd_smoke || field_at(x+a, y+b).type == fd_tear_gas || field_at(x+a, y+b).type == fd_toxic_gas || field_at(x+a, y+b).type == fd_nuke_gas ) && field_at(x+a, y+b).density < 3 ) || (field_at(x+a, y+b).is_null() && move_cost(x+a, y+b) > 0)) spread.push_back(point(x+a, y+b)); } } // Then, spread to a nearby point if (cur->density > 0 && cur->age > 0 && spread.size() > 0) { point p = spread[rng(0, spread.size() - 1)]; // Nearby nukegas grows thicker if (field_at(p.x, p.y).type == fd_nuke_gas && field_at(p.x, p.y).density < 3) { field_at(p.x, p.y).density++; cur->density--; // Nearby smoke, tear, and toxic gas is converted into nukegas } else if (field_at(p.x, p.y).type == fd_smoke || field_at(p.x, p.y).type == fd_toxic_gas || field_at(p.x, p.y).type == fd_tear_gas) { field_at(p.x, p.y).type = fd_nuke_gas; // Or, just create a new field. } else if (cur->density > 0 && move_cost(p.x, p.y) > 0 && add_field(g, p.x, p.y, fd_nuke_gas, 1)) { cur->density--; field_at(p.x, p.y).age = cur->age; } } } break; case fd_gas_vent: for (int i = x - 1; i <= x + 1; i++) { for (int j = y - 1; j <= y + 1; j++) { if (field_at(i, j).type == fd_toxic_gas && field_at(i, j).density < 3) field_at(i, j).density++; else add_field(g, i, j, fd_toxic_gas, 3); } } break; case fd_fire_vent: if (cur->density > 1) { if (one_in(3)) cur->density--; } else { cur->type = fd_flame_burst; cur->density = 3; } break; case fd_flame_burst: if (cur->density > 1) cur->density--; else { cur->type = fd_fire_vent; cur->density = 3; } break; case fd_electricity: if (!one_in(5)) { // 4 in 5 chance to spread std::vector<point> valid; if (move_cost(x, y) == 0 && cur->density > 1) { // We're grounded int tries = 0; while (tries < 10 && cur->age < 50) { int cx = x + rng(-1, 1), cy = y + rng(-1, 1); if (move_cost(cx, cy) != 0 && field_at(cx, cy).is_null()) { add_field(g, cx, cy, fd_electricity, 1); cur->density--; tries = 0; } else tries++; } } else { // We're not grounded; attempt to ground for (int a = -1; a <= 1; a++) { for (int b = -1; b <= 1; b++) { if (move_cost(x + a, y + b) == 0 && // Grounded tiles first field_at(x + a, y + b).is_null()) valid.push_back(point(x + a, y + b)); } } if (valid.size() == 0) { // Spread to adjacent space, then int px = x + rng(-1, 1), py = y + rng(-1, 1); if (move_cost(px, py) > 0 && field_at(px, py).type == fd_electricity && field_at(px, py).density < 3) field_at(px, py).density++; else if (move_cost(px, py) > 0) add_field(g, px, py, fd_electricity, 1); cur->density--; } while (valid.size() > 0 && cur->density > 0) { int index = rng(0, valid.size() - 1); add_field(g, valid[index].x, valid[index].y, fd_electricity, 1); cur->density--; valid.erase(valid.begin() + index); } } } break; case fd_fatigue: if (cur->density < 3 && int(g->turn) % 3600 == 0 && one_in(10)) cur->density++; else if (cur->density == 3 && one_in(600)) { // Spawn nether creature! mon_id type = mon_id(rng(mon_flying_polyp, mon_blank)); monster creature(g->mtypes[type]); creature.spawn(x + rng(-3, 3), y + rng(-3, 3)); g->z.push_back(creature); } break; } cur->age++; if (fieldlist[cur->type].halflife > 0) { if (cur->age > 0 && dice(3, cur->age) > dice(3, fieldlist[cur->type].halflife)) { cur->age = 0; cur->density--; } if (cur->density <= 0) { // Totally dissapated. grid[gridn].field_count--; grid[gridn].fld[locx][locy] = field(); } } } } return found_field; }