示例#1
0
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;
}
示例#2
0
// 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));

 }
}
示例#3
0
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);
}
示例#4
0
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);
}
示例#5
0
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);
}
示例#6
0
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;
}
示例#7
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);

}
示例#8
0
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));

 }
}
示例#9
0
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);
}
示例#10
0
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));
}
示例#11
0
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);
}
示例#12
0
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]);
}
示例#13
0
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));
}
示例#14
0
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)--;
   }
  }
 }
}
示例#15
0
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());
        }
    }

}
示例#16
0
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;
} 
示例#17
0
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));
}
示例#18
0
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);
 }
}
示例#19
0
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);
}
示例#20
0
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));
}
示例#21
0
/**
 * 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 );
}
示例#22
0
/**
 * 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 );
}
示例#23
0
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();
}
示例#24
0
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();
}
示例#25
0
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];}

}
示例#26
0
bool faction::has_value(faction_value v)
{
 return values & mfb(v);
}
示例#27
0
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);
 }
}
示例#28
0
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);
}
示例#29
0
bool monster::has_flag(m_flags f)
{
    return type->flags & mfb(f);
}
示例#30
0
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;
}