Esempio n. 1
0
std::string weather_forecast(game *g, radio_tower tower)
{
    std::stringstream weather_report;
    // Local conditions
    city *closest_city = &g->cur_om->cities[g->cur_om->closest_city(point(tower.x, tower.y))];
    // Current time
    weather_report << string_format(
        _("The current time is %s Eastern Standard Time.  At %s in %s, it was %s. The temperature was %s"),
        g->turn.print_time().c_str(), g->turn.print_time(true).c_str(), closest_city->name.c_str(),
        weather_data[g->weather].name.c_str(), print_temperature(g->temperature).c_str()
    );

    //weather_report << ", the dewpoint ???, and the relative humidity ???.  ";
    //weather_report << "The wind was <direction> at ? mi/km an hour.  ";
    //weather_report << "The pressure was ??? in/mm and steady/rising/falling.";

    // Regional conditions (simulated by chosing a random range containing the current conditions).
    // Adjusted for weather volatility based on how many weather changes are coming up.
    //weather_report << "Across <region>, skies ranged from <cloudiest> to <clearest>.  ";
    // TODO: Add fake reports for nearby cities

    // TODO: weather forecast
    // forecasting periods are divided into 12-hour periods, day (6-18) and night (19-5)
    // Accumulate percentages for each period of various weather statistics, and report that
    // (with fuzz) as the weather chances.
    int weather_proportions[NUM_WEATHER_TYPES] = {0};
    signed char high = 0;
    signed char low = 0;
    calendar start_time = g->turn;
    int period_start = g->turn.hours();
    // TODO wind direction and speed
    for(std::map<int, weather_segment>::iterator it = g->weather_log.lower_bound( int(g->turn) ); it != g->weather_log.end(); ++it ) {
        weather_segment * period = &(it->second);
        int period_deadline = period->deadline.hours();
        signed char period_temperature = period->temperature;
        weather_type period_weather = period->weather;
        bool start_day = period_start >= 6 && period_start <= 18;
        bool end_day = period_deadline >= 6 && period_deadline <= 18;

        high = std::max(high, period_temperature);
        low = std::min(low, period_temperature);

        if(start_day != end_day) // Assume a period doesn't last over 12 hrs?
        {
            weather_proportions[period_weather] += end_day ? 6 : 18 - period_start;
            int weather_duration = 0;
            int predominant_weather = 0;
            std::string day;
            if( g->turn.days() == period->deadline.days() )
            {
                if( start_day )
                {
                    day = _("Today");
                }
                else
                {
                    day = _("Tonight");
                }
            }
            else
            {
                std::string dayofweak = start_time.day_of_week();
                if( !start_day )
                {
                    day = rmp_format(_("<Mon Night>%s Night"), dayofweak.c_str());
                }
                else
                {
                    day = dayofweak;
                }
            }
            for( int i = WEATHER_CLEAR; i < NUM_WEATHER_TYPES; i++)
            {
                if( weather_proportions[i] > weather_duration)
                {
                    weather_duration = weather_proportions[i];
                    predominant_weather = i;
                }
            }
            // Print forecast
            weather_report << string_format(
                _("%s...%s. Highs of %s. Lows of %s. "),
                day.c_str(), weather_data[predominant_weather].name.c_str(),
                print_temperature(high).c_str(), print_temperature(low).c_str()
            );
            low = period_temperature;
            high = period_temperature;
            weather_proportions[period_weather] += end_day ? 6 : 18 - period_start;
        } else {
            weather_proportions[period_weather] += period_deadline - period_start;
        }
        start_time = period->deadline;
        period_start = period_deadline;
    }
    return weather_report.str();
}
Esempio n. 2
0
itype* new_natural_artifact(itypemap &itypes, artifact_natural_property prop)
{
// Natural artifacts are always tools.
 it_artifact_tool *art = new it_artifact_tool();
// Pick a form
 artifact_natural_shape shape =
               artifact_natural_shape(rng(ARTSHAPE_NULL + 1, ARTSHAPE_MAX - 1));
 artifact_shape_datum *shape_data = &(artifact_shape_data[shape]);
// Pick a property
 artifact_natural_property property = (prop > ARTPROP_NULL ? prop :
             artifact_natural_property(rng(ARTPROP_NULL + 1, ARTPROP_MAX - 1)));
 artifact_property_datum *property_data = &(artifact_property_data[property]);

 art->sym = ':';
 art->color = c_yellow;
 art->m1 = "stone";
 art->m2 = "null";
 art->volume = rng(shape_data->volume_min, shape_data->volume_max);
 art->weight = rng(shape_data->weight_min, shape_data->weight_max);
 art->melee_dam = 0;
 art->melee_cut = 0;
 art->m_to_hit = 0;

 art->name = rmp_format(_("<artifact_name>%1$s %2$s"), property_data->name.c_str(), shape_data->name.c_str());
 art->description = rmp_format(_("<artifact_desc>This %1$s %2$s."), shape_data->desc.c_str(), property_data->desc.c_str());

// Add line breaks to the description as necessary
/*
 size_t pos = 76;
 while (art->description.length() - pos >= 76) {
  pos = art->description.find_last_of(' ', pos);
  if (pos == std::string::npos)
   pos = art->description.length();
  else {
   art->description[pos] = '\n';
   pos += 76;
  }
 }*/

// Three possibilities: good passive + bad passive, good active + bad active,
// and bad passive + good active
 bool good_passive = false, bad_passive = false,
      good_active  = false, bad_active  = false;
 switch (rng(1, 3)) {
  case 1:
   good_passive = true;
   bad_passive  = true;
   break;
  case 2:
   good_active = true;
   bad_active  = true;
   break;
  case 3:
   bad_passive = true;
   good_active = true;
   break;
 }

 int value_to_reach = 0; // This is slowly incremented, allowing for better arts
 int value = 0;
 art_effect_passive aep_good = AEP_NULL, aep_bad = AEP_NULL;
 art_effect_active  aea_good = AEA_NULL, aea_bad = AEA_NULL;

 do {
  if (good_passive) {
   aep_good = property_data->passive_good[ rng(0, 3) ];
   if (aep_good == AEP_NULL || one_in(4))
    aep_good = art_effect_passive(rng(AEP_NULL + 1, AEP_SPLIT - 1));
  }
  if (bad_passive) {
   aep_bad = property_data->passive_bad[ rng(0, 3) ];
   if (aep_bad == AEP_NULL || one_in(4))
    aep_bad = art_effect_passive(rng(AEP_SPLIT + 1, NUM_AEAS - 1));
  }
  if (good_active) {
   aea_good = property_data->active_good[ rng(0, 3) ];
   if (aea_good == AEA_NULL || one_in(4))
    aea_good = art_effect_active(rng(AEA_NULL + 1, AEA_SPLIT - 1));
  }
  if (bad_active) {
   aea_bad = property_data->active_bad[ rng(0, 3) ];
   if (aea_bad == AEA_NULL || one_in(4))
    aea_bad = art_effect_active(rng(AEA_SPLIT + 1, NUM_AEAS - 1));
  }

  value = passive_effect_cost[aep_good] + passive_effect_cost[aep_bad] +
          active_effect_cost[aea_good] +  active_effect_cost[aea_bad];
  value_to_reach++; // Yes, it is intentional that this is 1 the first check
 } while (value > value_to_reach);

 if (aep_good != AEP_NULL)
  art->effects_carried.push_back(aep_good);
 if (aep_bad != AEP_NULL)
  art->effects_carried.push_back(aep_bad);
 if (aea_good != AEA_NULL)
  art->effects_activated.push_back(aea_good);
 if (aea_bad != AEA_NULL)
  art->effects_activated.push_back(aea_bad);

// Natural artifacts ALWAYS can recharge
// (When "implanting" them in a mundane item, this ability may be lost
 if (!art->effects_activated.empty()) {
  art->max_charges = rng(1, 4);
  art->def_charges = art->max_charges;
  art->rand_charges.push_back(art->max_charges);
  art->charge_type = art_charge( rng(ARTC_NULL + 1, NUM_ARTCS - 1) );
 }
 artifact_itype_ids.push_back(art->id);
 itypes[art->id] = art;
 return art;
}
Esempio n. 3
0
int vehicle::automatic_fire_turret( vehicle_part &pt )
{
    item &gun = pt.base;
    tripoint pos = global_part_pos3( pt );

    npc tmp;
    tmp.set_fake( true );
    tmp.add_effect( effect_on_roof, 1 );
    tmp.name = rmp_format( _( "<veh_player>The %s" ), pt.name().c_str() );
    tmp.set_skill_level( gun.gun_skill(), 8 );
    tmp.set_skill_level( skill_id( "gun" ), 4 );
    tmp.recoil = abs( velocity ) / 100 / 4;
    tmp.setpos( pos );
    tmp.str_cur = 16;
    tmp.dex_cur = 8;
    tmp.per_cur = 12;
    // Assume vehicle turrets are defending the player.
    tmp.attitude = NPCATT_DEFEND;

    int area = aoe_size( gun.ammo_effects() );
    if( area > 0 ) {
        area += area == 1 ? 1 : 2; // Pad a bit for less friendly fire
    }

    tripoint targ = pos;
    auto &target = pt.target;
    if( target.first == target.second ) {
        // Manual target not set, find one automatically
        const bool u_see = g->u.sees( pos );
        int boo_hoo;

        // @todo calculate chance to hit and cap range based upon this
        int range = std::min( gun.gun_range(), 12 );
        Creature *auto_target = tmp.auto_find_hostile_target( range, boo_hoo, area );
        if( auto_target == nullptr ) {
            if( u_see && boo_hoo ) {
                add_msg( m_warning, ngettext( "%s points in your direction and emits an IFF warning beep.",
                                              "%s points in your direction and emits %d annoyed sounding beeps.",
                                              boo_hoo ),
                         tmp.name.c_str(), boo_hoo );
            }
            return 0;
        }

        targ = auto_target->pos();
    } else if( target.first != target.second ) {
        // Target set manually
        // Make sure we didn't move between aiming and firing (it's a bug if we did)
        if( targ != target.first ) {
            target.second = target.first;
            return 0;
        }

        targ = target.second;
        // Remove the target
        target.second = target.first;
    } else {
        // Shouldn't happen
        target.first = target.second;
        return 0;
    }

    // notify player if player can see the shot
    if( g->u.sees( pos ) ) {
        add_msg( _( "The %1$s fires its %2$s!" ), name.c_str(), pt.name().c_str() );
    }

    auto mode = gun.gun_current_mode();
    return tmp.fire_gun( targ, mode.qty, *mode );
}
Esempio n. 4
0
/**
 * Generate textual weather forecast for the specified radio tower.
 */
std::string weather_forecast( point const &abs_sm_pos )
{
    std::ostringstream weather_report;
    // Local conditions
    const auto cref = overmap_buffer.closest_city( tripoint( abs_sm_pos, 0 ) );
    const std::string city_name = cref ? cref.city->name : std::string( _( "middle of nowhere" ) );
    // Current time
    weather_report << string_format(
                       _("The current time is %s Eastern Standard Time.  At %s in %s, it was %s. The temperature was %s. "),
                       calendar::turn.print_time().c_str(), calendar::turn.print_time(true).c_str(),
                       city_name.c_str(),
                       weather_data(g->weather).name.c_str(), print_temperature(g->temperature).c_str()
                   );

    //weather_report << ", the dewpoint ???, and the relative humidity ???.  ";
    //weather_report << "The wind was <direction> at ? mi/km an hour.  ";
    //weather_report << "The pressure was ??? in/mm and steady/rising/falling.";

    // Regional conditions (simulated by choosing a random range containing the current conditions).
    // Adjusted for weather volatility based on how many weather changes are coming up.
    //weather_report << "Across <region>, skies ranged from <cloudiest> to <clearest>.  ";
    // TODO: Add fake reports for nearby cities

    // TODO: weather forecast
    // forecasting periods are divided into 12-hour periods, day (6-18) and night (19-5)
    // Accumulate percentages for each period of various weather statistics, and report that
    // (with fuzz) as the weather chances.
    // int weather_proportions[NUM_WEATHER_TYPES] = {0};
    double high = -100.0;
    double low = 100.0;
    point const abs_ms_pos = overmapbuffer::sm_to_ms_copy( abs_sm_pos );
    // TODO wind direction and speed
    int last_hour = calendar::turn - ( calendar::turn % HOURS(1) );
    for(int d = 0; d < 6; d++) {
        weather_type forecast = WEATHER_NULL;
        for(calendar i(last_hour + 7200 * d); i < last_hour + 7200 * (d + 1); i += 600) {
            w_point w = g->weather_gen->get_weather( abs_ms_pos, i );
            forecast = std::max(forecast, g->weather_gen->get_weather_conditions(w));
            high = std::max(high, w.temperature);
            low = std::min(low, w.temperature);
        }
        std::string day;
        bool started_at_night;
        calendar c(last_hour + 7200 * d);
        if(d == 0 && c.is_night()) {
            day = _("Tonight");
            started_at_night = true;
        } else {
            day = _("Today");
            started_at_night = false;
        }
        if(d > 0 && ((started_at_night && !(d % 2)) || (!started_at_night && d % 2))) {
            day = rmp_format(_("<Mon Night>%s Night"), c.day_of_week().c_str());
        } else {
            day = c.day_of_week();
        }
        weather_report << string_format(
                           _("%s... %s. Highs of %s. Lows of %s. "),
                           day.c_str(), weather_data(forecast).name.c_str(),
                           print_temperature(high).c_str(), print_temperature(low).c_str()
                       );
    }
    return weather_report.str();
}
Esempio n. 5
0
std::string new_natural_artifact(artifact_natural_property prop)
{
    // Natural artifacts are always tools.
    it_artifact_tool *art = new it_artifact_tool();
    // Pick a form
    artifact_natural_shape shape =
        artifact_natural_shape(rng(ARTSHAPE_NULL + 1, ARTSHAPE_MAX - 1));
    artifact_shape_datum *shape_data = &(artifact_shape_data[shape]);
    // Pick a property
    artifact_natural_property property = (prop > ARTPROP_NULL ? prop :
                                          artifact_natural_property(rng(ARTPROP_NULL + 1,
                                                  ARTPROP_MAX - 1)));
    artifact_property_datum *property_data = &(artifact_property_data[property]);

    art->sym = ':';
    art->color = c_yellow;
    art->materials.push_back("stone");
    art->volume = rng(shape_data->volume_min, shape_data->volume_max);
    art->weight = rng(shape_data->weight_min, shape_data->weight_max);
    art->melee_dam = 0;
    art->melee_cut = 0;
    art->m_to_hit = 0;

    art->create_name(property_data->name, shape_data->name);
    art->description = rmp_format(_("<artifact_desc>This %1$s %2$s."), shape_data->desc.c_str(),
                                  property_data->desc.c_str());

    // Three possibilities: good passive + bad passive, good active + bad active,
    // and bad passive + good active
    bool good_passive = false, bad_passive = false,
         good_active  = false, bad_active  = false;
    switch (rng(1, 3)) {
    case 1:
        good_passive = true;
        bad_passive  = true;
        break;
    case 2:
        good_active = true;
        bad_active  = true;
        break;
    case 3:
        bad_passive = true;
        good_active = true;
        break;
    }

    int value_to_reach = 0; // This is slowly incremented, allowing for better arts
    int value = 0;
    art_effect_passive aep_good = AEP_NULL, aep_bad = AEP_NULL;
    art_effect_active  aea_good = AEA_NULL, aea_bad = AEA_NULL;

    do {
        if (good_passive) {
            aep_good = property_data->passive_good[ rng(0, 3) ];
            if (aep_good == AEP_NULL || one_in(4)) {
                aep_good = art_effect_passive(rng(AEP_NULL + 1, AEP_SPLIT - 1));
            }
        }
        if (bad_passive) {
            aep_bad = property_data->passive_bad[ rng(0, 3) ];
            if (aep_bad == AEP_NULL || one_in(4)) {
                aep_bad = art_effect_passive(rng(AEP_SPLIT + 1, NUM_AEAS - 1));
            }
        }
        if (good_active) {
            aea_good = property_data->active_good[ rng(0, 3) ];
            if (aea_good == AEA_NULL || one_in(4)) {
                aea_good = art_effect_active(rng(AEA_NULL + 1, AEA_SPLIT - 1));
            }
        }
        if (bad_active) {
            aea_bad = property_data->active_bad[ rng(0, 3) ];
            if (aea_bad == AEA_NULL || one_in(4)) {
                aea_bad = art_effect_active(rng(AEA_SPLIT + 1, NUM_AEAS - 1));
            }
        }

        value = passive_effect_cost[aep_good] + passive_effect_cost[aep_bad] +
                active_effect_cost[aea_good] +  active_effect_cost[aea_bad];
        value_to_reach++; // Yes, it is intentional that this is 1 the first check
    } while (value > value_to_reach);

    if (aep_good != AEP_NULL) {
        art->effects_carried.push_back(aep_good);
    }
    if (aep_bad != AEP_NULL) {
        art->effects_carried.push_back(aep_bad);
    }
    if (aea_good != AEA_NULL) {
        art->effects_activated.push_back(aea_good);
    }
    if (aea_bad != AEA_NULL) {
        art->effects_activated.push_back(aea_bad);
    }

    // Natural artifacts ALWAYS can recharge
    // (When "implanting" them in a mundane item, this ability may be lost
    if (!art->effects_activated.empty()) {
        art->max_charges = rng(1, 4);
        art->def_charges = art->max_charges;
        art->rand_charges.push_back(art->max_charges);
        art->charge_type = art_charge( rng(ARTC_NULL + 1, NUM_ARTCS - 1) );
    }
    item_controller->add_item_type( art );
    return art->id;
}
Esempio n. 6
0
void it_artifact_tool::create_name(const std::string &property_name, const std::string &shape_name)
{
    name = rmp_format(_("<artifact_name>%1$s %2$s"), property_name.c_str(),
                      shape_name.c_str());
    name_plural = name;
}