diff --git a/data/changelog.txt b/data/changelog.txt index 4a8aa37914890..116d83a68c9c0 100755 --- a/data/changelog.txt +++ b/data/changelog.txt @@ -35,6 +35,7 @@ Added fur scarf, fur gloves, fur trenchcoat, fur pants, fur boots (all craft onl All tailoring items that use fur require survival as secondary skill. Added crafting recipes for bandana, blanket, house coat, cloak. Weather radio +Radios are tuneable, so you can receive from more than one station without moving. New item that doubles battery capacity of tools, recipe learn from certain electronics books. Bugfix: reduced chance of "Tried to kill monster" debug spam. Bugfix: reduced chance of "Stopping out-of-map vehicle" spam. diff --git a/iuse.cpp b/iuse.cpp index 49038012e8bb4..289f32279fb6f 100644 --- a/iuse.cpp +++ b/iuse.cpp @@ -1430,55 +1430,124 @@ void iuse::radio_off(game *g, player *p, item *it, bool t) } } -void iuse::radio_on(game *g, player *p, item *it, bool t) +static radio_tower *find_radio_station( game *g, int frequency ) { - if (t) { // Normal use - int best_signal = 0; - std::string message = "Radio: Kssssssssssssh."; - for (int k = 0; k < g->cur_om.radios.size(); k++) { - int signal = g->cur_om.radios[k].strength - - rl_dist(g->cur_om.radios[k].x, g->cur_om.radios[k].y, - g->levx, g->levy); - if (signal > best_signal) { - best_signal = signal; - if( g->cur_om.radios[k].type == MESSAGE_BROADCAST ) { - message = g->cur_om.radios[k].message; - } else if (g->cur_om.radios[k].type == WEATHER_RADIO) { - message = weather_forecast(g, g->cur_om.radios[k]); - } - } - } - if (best_signal > 0) { - for (int j = 0; j < message.length(); j++) { - if (dice(10, 100) > dice(10, best_signal * 3)) { - if (!one_in(10)) - message[j] = '#'; - else - message[j] = char(rng('a', 'z')); + radio_tower *tower = NULL; + for (int k = 0; k < g->cur_om.radios.size(); k++) + { + tower = &g->cur_om.radios[k]; + if( 0 < tower->strength - rl_dist(tower->x, tower->y, g->levx, g->levy) && + tower->frequency == frequency ) + { + return tower; + } } - } + return NULL; +} - std::vector segments; - while (message.length() > RADIO_PER_TURN) { - int spot = message.find_last_of(' ', RADIO_PER_TURN); - if (spot == std::string::npos) - spot = RADIO_PER_TURN; - segments.push_back( message.substr(0, spot) ); - message = message.substr(spot + 1); - } - segments.push_back(message); - int index = g->turn % (segments.size()); - std::stringstream messtream; - messtream << "radio: " << segments[index]; - message = messtream.str(); - } - point p = g->find_item(it); - g->sound(p.x, p.y, 6, message.c_str()); - } else { // Turning it off - g->add_msg_if_player(p,"The radio dies."); - it->make(g->itypes["radio"]); - it->active = false; - } +void iuse::radio_on(game *g, player *p, item *it, bool t) +{ + if (t) + { // Normal use + std::string message = "Radio: Kssssssssssssh."; + radio_tower *selected_tower = find_radio_station( g, it->mode ); + if( selected_tower != NULL ) + { + if( selected_tower->type == MESSAGE_BROADCAST ) + { + message = selected_tower->message; + } + else if (selected_tower->type == WEATHER_RADIO) + { + message = weather_forecast(g, *selected_tower); + } + + int signal_strength = selected_tower->strength - + rl_dist(selected_tower->x, selected_tower->y, g->levx, g->levy); + + for (int j = 0; j < message.length(); j++) + { + if (dice(10, 100) > dice(10, signal_strength * 3)) + { + if (!one_in(10)) + { + message[j] = '#'; + } + else + { + message[j] = char(rng('a', 'z')); + } + } + } + + std::vector segments; + while (message.length() > RADIO_PER_TURN) + { + int spot = message.find_last_of(' ', RADIO_PER_TURN); + if (spot == std::string::npos) + { + spot = RADIO_PER_TURN; + } + segments.push_back( message.substr(0, spot) ); + message = message.substr(spot + 1); + } + segments.push_back(message); + int index = g->turn % (segments.size()); + std::stringstream messtream; + messtream << "radio: " << segments[index]; + message = messtream.str(); + } + point p = g->find_item(it); + g->sound(p.x, p.y, 6, message.c_str()); + } else { // Activated + int ch = menu( true, "Radio:", "Scan", "Turn off", NULL ); + switch (ch) + { + case 1: + { + int old_frequency = it->mode; + radio_tower *tower = NULL; + radio_tower *lowest_tower = NULL; + radio_tower *lowest_larger_tower = NULL; + + for (int k = 0; k < g->cur_om.radios.size(); k++) + { + tower = &g->cur_om.radios[k]; + + if( 0 < tower->strength - rl_dist(tower->x, tower->y, g->levx, g->levy) && + tower->frequency != old_frequency ) + { + if( tower->frequency > old_frequency && + (lowest_larger_tower == NULL || + tower->frequency < lowest_larger_tower->frequency) ) + { + lowest_larger_tower = tower; + } + else if( lowest_tower == NULL || + tower->frequency < lowest_tower->frequency ) + { + lowest_tower = tower; + } + } + } + if( lowest_larger_tower != NULL ) + { + it->mode = lowest_larger_tower->frequency; + } + else if( lowest_tower != NULL ) + { + it->mode = lowest_tower->frequency; + } + } + break; + case 2: + g->add_msg_if_player(p,"The radio dies."); + it->make(g->itypes["radio"]); + it->active = false; + break; + case 3: break; + } + } } void iuse::noise_emitter_off(game *g, player *p, item *it, bool t) diff --git a/overmap.cpp b/overmap.cpp index 8f3a87cf9dbc6..e847ad8bbd468 100644 --- a/overmap.cpp +++ b/overmap.cpp @@ -2602,14 +2602,14 @@ void overmap::place_radios() case 0: snprintf( message, sizeof(message), "This is emergency broadcast station %d%d.\ Please proceed quickly and calmly to your designated evacuation point.", i, j); - radios.push_back(radio_tower(i*2, j*2, rng(80, 200), message)); + radios.push_back(radio_tower(i*2, j*2, rng(RADIO_MIN_STRENGTH, RADIO_MAX_STRENGTH), message)); break; case 1: - radios.push_back(radio_tower(i*2, j*2, rng(80, 200), + radios.push_back(radio_tower(i*2, j*2, rng(RADIO_MIN_STRENGTH, RADIO_MAX_STRENGTH), "Head West. All survivors, head West. Help is waiting.")); break; case 2: - radios.push_back(radio_tower(i*2, j*2, rng(80, 200), "", WEATHER_RADIO)); + radios.push_back(radio_tower(i*2, j*2, rng(RADIO_MIN_STRENGTH, RADIO_MAX_STRENGTH), "", WEATHER_RADIO)); break; } } @@ -2617,13 +2617,13 @@ void overmap::place_radios() case ot_lmoe: snprintf( message, sizeof(message), "This is automated emergency shelter beacon %d%d.\ Supplies, amenities and shelter are stocked.", i, j); - radios.push_back(radio_tower(i*2, j*2, rng(40, 100), message)); + radios.push_back(radio_tower(i*2, j*2, rng(RADIO_MIN_STRENGTH, RADIO_MAX_STRENGTH) / 2, message)); break; case ot_fema_entrance: snprintf( message, sizeof(message), "This is FEMA camp %d%d.\ Supplies are limited, please bring supplemental food, water, and bedding.\ This is FEMA camp %d%d. A designated long-term emergency shelter.", i, j, i, j); - radios.push_back(radio_tower(i*2, j*2, rng(80, 200), message)); + radios.push_back(radio_tower(i*2, j*2, rng(RADIO_MIN_STRENGTH, RADIO_MAX_STRENGTH), message)); break; } } diff --git a/overmap.h b/overmap.h index 492998c1d52a3..53a20b7c29775 100644 --- a/overmap.h +++ b/overmap.h @@ -44,6 +44,8 @@ enum radio_type { WEATHER_RADIO }; +#define RADIO_MIN_STRENGTH 80 +#define RADIO_MAX_STRENGTH 200 struct radio_tower { int x; @@ -51,9 +53,10 @@ struct radio_tower { int strength; radio_type type; std::string message; + int frequency; radio_tower(int X = -1, int Y = -1, int S = -1, std::string M = "", radio_type T = MESSAGE_BROADCAST) : - x (X), y (Y), strength (S), type (T), message (M) {} + x (X), y (Y), strength (S), type (T), message (M) {frequency = rand();} }; struct map_layer {