Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Bigger active maps. Lots of efficiency changes.

  • Loading branch information...
commit fadac131e3c29b88d8dc6d2df1ab8bc6b76f647b 1 parent 0f9e9bf
@Whales authored
View
143 artifact.cpp
@@ -66,7 +66,7 @@ It may have unknown powers; use 'a' to activate them.";
while (!good_effects.empty() && !bad_effects.empty() &&
(num_good < 1 || num_bad < 1 || one_in(num_good + 1) ||
one_in(num_bad + 1) || value > 1)) {
- if (one_in(2)) { // Good
+ if (value < 1 && one_in(2)) { // Good
int index = rng(0, good_effects.size() - 1);
passive_tmp = good_effects[index];
good_effects.erase(good_effects.begin() + index);
@@ -89,7 +89,7 @@ It may have unknown powers; use 'a' to activate them.";
while (one_in(2) && !good_effects.empty() && !bad_effects.empty() &&
((num_good > 2 && one_in(num_good + 1)) || num_bad < 1 ||
one_in(num_bad + 1) || value > 1)) {
- if (one_in(3)) { // Good
+ if (value < 1 && one_in(3)) { // Good
int index = rng(0, good_effects.size() - 1);
passive_tmp = good_effects[index];
good_effects.erase(good_effects.begin() + index);
@@ -218,9 +218,9 @@ It may have unknown powers; use 'a' to activate them.";
std::vector<art_effect_passive> bad_effects = fill_bad_passive();
while (!good_effects.empty() && !bad_effects.empty() &&
- (num_good < 1 || one_in(num_good) || !one_in(3 - num_bad) ||
- value > 1)) {
- if (one_in(2)) { // Good effect
+ (num_good < 1 || one_in(num_good * 2) || value > 1 ||
+ (num_bad < 3 && !one_in(3 - num_bad)))) {
+ if (value < 1 && one_in(2)) { // Good effect
int index = rng(0, good_effects.size() - 1);
passive_tmp = good_effects[index];
good_effects.erase(good_effects.begin() + index);
@@ -304,26 +304,27 @@ void game::process_artifact(item *it, player *p, bool wielded)
if (it->charges < tool->max_charges) {
switch (tool->charge_type) {
case ARTC_TIME:
- if (int(turn) % 300 == 0)
+ if (turn.second == 0 && turn.minute == 0) // Once per hour
it->charges++;
break;
case ARTC_SOLAR:
- if (int(turn) % 100 == 0 && is_in_sunlight(p->posx, p->posy))
+ if (turn.second == 0 && turn.minute % 10 == 0 &&
+ is_in_sunlight(p->posx, p->posy))
it->charges++;
break;
case ARTC_PAIN:
- if (int(turn) % 50 == 0) {
+ if (turn.second == 0) {
add_msg("You suddenly feel sharp pain for no reason.");
p->pain += 3 * rng(1, 3);
it->charges++;
}
break;
case ARTC_HP:
- if (int(turn) % 50 == 0) {
+ if (turn.second == 0) {
add_msg("You feel your body decaying.");
p->hurtall(1);
+ it->charges++;
}
- it->charges++;
break;
}
}
@@ -368,6 +369,29 @@ void game::process_artifact(item *it, player *p, bool wielded)
case AEP_SNAKES:
break; // Handled in player::hit()
+ case AEP_EXTINGUISH:
+ for (int x = p->posx - 1; x <= p->posx + 1; x++) {
+ for (int y = p->posy - 1; y <= p->posy + 1; y++) {
+ if (m.field_at(x, y).type == fd_fire) {
+ if (m.field_at(x, y).density == 0)
+ m.field_at(x, y) = field();
+ else
+ m.field_at(x, y).density--;
+ }
+ }
+ }
+ break;
+
+ case AEP_HUNGER:
+ if (one_in(100))
+ p->hunger++;
+ break;
+
+ case AEP_THIRST:
+ if (one_in(120))
+ p->thirst++;
+ break;
+
case AEP_EVIL:
if (one_in(150)) { // Once every 15 minutes, on average
p->add_disease(DI_EVIL, 300, this);
@@ -413,3 +437,102 @@ void game::process_artifact(item *it, player *p, bool wielded)
}
}
}
+
+void game::add_artifact_messages(std::vector<art_effect_passive> effects)
+{
+ int net_str = 0, net_dex = 0, net_per = 0, net_int = 0, net_speed = 0;
+ for (int i = 0; i < effects.size(); i++) {
+ switch (effects[i]) {
+ case AEP_STR_UP: net_str += 4; break;
+ case AEP_DEX_UP: net_dex += 4; break;
+ case AEP_PER_UP: net_per += 4; break;
+ case AEP_INT_UP: net_int += 4; break;
+ case AEP_ALL_UP: net_str += 2;
+ net_dex += 2;
+ net_per += 2;
+ net_int += 2; break;
+ case AEP_STR_DOWN: net_str -= 3; break;
+ case AEP_DEX_DOWN: net_dex -= 3; break;
+ case AEP_PER_DOWN: net_per -= 3; break;
+ case AEP_INT_DOWN: net_int -= 3; break;
+ case AEP_ALL_DOWN: net_str -= 2;
+ net_dex -= 2;
+ net_per -= 2;
+ net_int -= 2; break;
+
+ case AEP_SPEED_UP: net_speed += 20; break;
+ case AEP_SPEED_DOWN: net_speed -= 20; break;
+
+ case AEP_IODINE:
+ break; // No message
+
+ case AEP_SNAKES:
+ add_msg("Your skin feels slithery.");
+ break;
+
+ case AEP_INVISIBLE:
+ add_msg("You fade into invisibility!");
+ break;
+
+ case AEP_CLAIRVOYANCE:
+ add_msg("You can see through walls!");
+ break;
+
+ case AEP_STEALTH:
+ add_msg("Your steps stop making noise.");
+ break;
+
+ case AEP_GLOW:
+ add_msg("A glow of light forms around you.");
+ break;
+
+ case AEP_PSYSHIELD:
+ add_msg("Your mental state feels protected.");
+ break;
+
+ case AEP_HUNGER:
+ add_msg("You feel hungry.");
+ break;
+
+ case AEP_THIRST:
+ add_msg("You feel thirsty.");
+ break;
+
+ case AEP_EVIL:
+ add_msg("You feel an evil presence...");
+ break;
+
+ case AEP_SCHIZO:
+ add_msg("You feel a tickle of insanity.");
+ break;
+
+ case AEP_RADIOACTIVE:
+ add_msg("Your skin prickles with radiation.");
+ break;
+
+ case AEP_MUTAGENIC:
+ add_msg("You feel your genetic makeup degrading.");
+ break;
+
+ case AEP_ATTENTION:
+ add_msg("You feel an otherworldly attention upon you...");
+ break;
+ }
+ }
+
+ std::stringstream stat_info;
+ if (net_str != 0)
+ stat_info << "Str " << (net_str > 0 ? "+" : "") << net_str << "! ";
+ if (net_dex != 0)
+ stat_info << "Dex " << (net_dex > 0 ? "+" : "") << net_dex << "! ";
+ if (net_int != 0)
+ stat_info << "Int " << (net_int > 0 ? "+" : "") << net_int << "! ";
+ if (net_per != 0)
+ stat_info << "Per " << (net_per > 0 ? "+" : "") << net_per << "! ";
+
+ if (stat_info.str().length() > 0)
+ add_msg(stat_info.str().c_str());
+
+ if (net_speed != 0)
+ add_msg("Speed %s%d", (net_speed > 0 ? "+" : ""), net_speed);
+}
View
6 artifact.h
@@ -17,9 +17,15 @@ enum art_effect_passive {
AEP_SNAKES, // Summons friendly snakes when you're hit
AEP_INVISIBLE, // Makes you invisible
AEP_CLAIRVOYANCE, // See through walls
+ AEP_STEALTH, // Your steps are quieted
+ AEP_EXTINGUISH, // May extinguish nearby flames
+ AEP_GLOW, // Four-tile light source
+ AEP_PSYSHIELD, // Protection from stare attacks
// Splits good from bad
AEP_SPLIT,
// Bad
+ AEP_HUNGER, // Increases hunger
+ AEP_THIRST, // Increases thirst
AEP_SMOKE, // Emits smoke occasionally
AEP_EVIL, // Addiction to the power
AEP_SCHIZO, // Mimicks schizophrenia
View
6 artifactdata.h
@@ -18,9 +18,15 @@ int passive_effect_cost[NUM_AEPS] = {
4, // AEP_SNAKES
7, // AEP_INVISIBLE
5, // AEP_CLAIRVOYANCE
+2, // AEP_STEALTH
+2, // AEP_EXTINGUISH
+1, // AEP_GLOW
+1, // AEP_PSYSHIELD
0, // AEP_SPLIT
+-2, // AEP_HUNGER
+-2, // AEP_THIRST
-1, // AEP_SMOKE
-6, // AEP_EVIL
-4, // AEP_SCHIZO
View
52 computer.cpp
@@ -246,8 +246,8 @@ void computer::activate_function(game *g, computer_action action)
break;
case COMPACT_SAMPLE:
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEY * 3; y++) {
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++) {
if (g->m.ter(x, y) == t_sewage_pump) {
for (int x1 = x - 1; x1 <= x + 1; x1++) {
for (int y1 = y - 1; y1 <= y + 1; y1++ ) {
@@ -280,8 +280,8 @@ void computer::activate_function(game *g, computer_action action)
break;
case COMPACT_TERMINATE:
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEY * 3; y++) {
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++) {
int mondex = g->mon_at(x, y);
if (mondex != -1 &&
((g->m.ter(x, y - 1) == t_reinforced_glass_h &&
@@ -295,8 +295,8 @@ void computer::activate_function(game *g, computer_action action)
break;
case COMPACT_PORTAL:
- for (int i = 0; i < SEEX * 3; i++) {
- for (int j = 0; j < SEEY * 3; j++) {
+ for (int i = 0; i < SEEX * MAPSIZE; i++) {
+ for (int j = 0; j < SEEY * MAPSIZE; j++) {
int numtowers = 0;
for (int xt = i - 2; xt <= i + 2; xt++) {
for (int yt = j - 2; yt <= j + 2; yt++) {
@@ -399,15 +399,14 @@ void computer::activate_function(game *g, computer_action action)
if (maxx >= OMAPX) maxx = OMAPX - 1;
if (miny < 0) miny = 0;
if (maxy >= OMAPY) maxy = OMAPY - 1;
- overmap tmp(g, g->cur_om.posx, g->cur_om.posy, g->cur_om.posz);
for (int i = minx; i <= maxx; i++) {
for (int j = miny; j <= maxy; j++)
- if ((tmp.ter(i, j) >= ot_sewer_ns && tmp.ter(i, j) <= ot_sewer_nesw) ||
- (tmp.ter(i, j) >= ot_sewage_treatment &&
- tmp.ter(i, j) <= ot_sewage_treatment_under))
- tmp.seen(i, j) = true;
+ if ((g->cur_om.ter(i, j) >= ot_sewer_ns &&
+ g->cur_om.ter(i, j) <= ot_sewer_nesw) ||
+ (g->cur_om.ter(i, j) >= ot_sewage_treatment &&
+ g->cur_om.ter(i, j) <= ot_sewage_treatment_under))
+ g->cur_om.seen(i, j) = true;
}
- tmp.save(g->u.name, g->cur_om.posx, g->cur_om.posy, 0);
print_line("Sewage map data downloaded.");
} break;
@@ -422,7 +421,7 @@ void computer::activate_function(game *g, computer_action action)
}
// Figure out where the glass wall is...
int wall_spot = 0;
- for (int i = 0; i < SEEX * 3 && wall_spot == 0; i++) {
+ for (int i = g->u.posx; i < g->u.posx + SEEX * 2 && wall_spot == 0; i++) {
if (g->m.ter(i, 10) == t_wall_glass_v)
wall_spot = i;
}
@@ -455,8 +454,8 @@ void computer::activate_function(game *g, computer_action action)
case COMPACT_LIST_BIONICS: {
std::vector<std::string> names;
int more = 0;
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEY * 3; y++) {
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++) {
for (int i = 0; i < g->m.i_at(x, y).size(); i++) {
if (g->m.i_at(x, y)[i].is_bionic()) {
if (names.size() < 9)
@@ -474,8 +473,8 @@ void computer::activate_function(game *g, computer_action action)
} break;
case COMPACT_ELEVATOR_ON:
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEY * 3; y++) {
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++) {
if (g->m.ter(x, y) == t_elevator_control_off)
g->m.ter(x, y) = t_elevator_control;
}
@@ -570,7 +569,8 @@ INITIATING STANDARD TREMOR TEST...");
case COMPACT_AMIGARA_START:
g->add_event(EVENT_AMIGARA, int(g->turn) + 10, 0, 0, 0);
- g->u.add_disease(DI_AMIGARA, -1, g);
+ if (!g->u.has_artifact_with(AEP_PSYSHIELD))
+ g->u.add_disease(DI_AMIGARA, -1, g);
break;
} // switch (action)
@@ -591,8 +591,8 @@ void computer::activate_failure(game *g, computer_failure fail)
break; // Do nothing. Why was this even called >:|
case COMPFAIL_SHUTDOWN:
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEY * 3; y++) {
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++) {
if (g->m.has_flag(console, x, y))
g->m.ter(x, y) = t_console_broken;
}
@@ -648,8 +648,8 @@ void computer::activate_failure(game *g, computer_failure fail)
case COMPFAIL_PUMP_EXPLODE:
g->add_msg("The pump explodes!");
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEY * 3; y++) {
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++) {
if (g->m.ter(x, y) == t_sewage_pump) {
g->m.ter(x, y) = t_rubble;
g->explosion(x, y, 10, 0, false);
@@ -660,8 +660,8 @@ void computer::activate_failure(game *g, computer_failure fail)
case COMPFAIL_PUMP_LEAK:
g->add_msg("Sewage leaks!");
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEY * 3; y++) {
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++) {
if (g->m.ter(x, y) == t_sewage_pump) {
point p(x, y);
int leak_size = rng(4, 10);
@@ -691,8 +691,8 @@ void computer::activate_failure(game *g, computer_failure fail)
case COMPFAIL_AMIGARA:
g->add_event(EVENT_AMIGARA, int(g->turn) + 5, 0, 0, 0);
g->u.add_disease(DI_AMIGARA, -1, g);
- g->explosion(rng(0, SEEX * 3), rng(0, SEEY * 3), 10, 10, false);
- g->explosion(rng(0, SEEX * 3), rng(0, SEEY * 3), 10, 10, false);
+ g->explosion(rng(0, SEEX * MAPSIZE), rng(0, SEEY * MAPSIZE), 10, 10, false);
+ g->explosion(rng(0, SEEX * MAPSIZE), rng(0, SEEY * MAPSIZE), 10, 10, false);
break;
}// switch (fail)
}
View
16 construction.cpp
@@ -10,7 +10,8 @@
#define PICKUP_RANGE 2
-bool will_flood_stop(map *m, bool fill[SEEX * 3][SEEY *3], int x, int y);
+bool will_flood_stop(map *m, bool fill[SEEX * MAPSIZE][SEEY * MAPSIZE],
+ int x, int y);
void game::init_construction()
{
@@ -64,7 +65,7 @@ void game::init_construction()
&construct::done_window_pane);
STAGE(t_window_empty, 10);
TOOL(itm_hammer, itm_rock, itm_hatchet, NULL);
- TOOL(itm_screwdriver, itm_knife_butter, NULL);
+ TOOL(itm_screwdriver, itm_knife_butter, itm_toolset, NULL);
CONSTRUCT("Repair Door", 1, &construct::able_door_broken,
&construct::done_nothing);
@@ -509,9 +510,9 @@ bool construct::able_wall_wood(game *g, point p)
bool construct::able_between_walls(game *g, point p)
{
- bool fill[SEEX * 3][SEEY * 3];
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEY * 3; y++)
+ bool fill[SEEX * MAPSIZE][SEEY * MAPSIZE];
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++)
fill[x][y] = false;
}
@@ -528,9 +529,10 @@ bool construct::able_pit(game *g, point p)
return (g->m.ter(p.x, p.y) == t_pit);//|| g->m.ter(p.x, p.y) == t_pit_shallow);
}
-bool will_flood_stop(map *m, bool fill[SEEX * 3][SEEY * 3], int x, int y)
+bool will_flood_stop(map *m, bool fill[SEEX * MAPSIZE][SEEY * MAPSIZE],
+ int x, int y)
{
- if (x == 0 || y == 0 || x == SEEX * 3 - 1 || y == SEEY * 3 - 1)
+ if (x == 0 || y == 0 || x == SEEX * MAPSIZE - 1 || y == SEEY * MAPSIZE - 1)
return false;
fill[x][y] = true;
View
12 crafting.cpp
@@ -102,7 +102,7 @@ recipes.push_back( recipe(id, result, category, skill1, skill2, difficulty, \
RECIPE(itm_smg_9mm, CC_WEAPON, sk_mechanics, sk_gun, 5, 18000);
TOOL(itm_hacksaw, -1, itm_toolset, -1, NULL);
TOOL(itm_screwdriver, -1, itm_toolset, -1, NULL);
- TOOL(itm_hammer, -1, itm_rock, -1, itm_hatchet, -1, itm_toolset, -1, NULL);
+ TOOL(itm_hammer, -1, itm_rock, -1, itm_hatchet, -1, NULL);
COMP(itm_pipe, 1, NULL);
COMP(itm_2x4, 2, NULL);
COMP(itm_nail, 4, NULL);
@@ -110,7 +110,7 @@ recipes.push_back( recipe(id, result, category, skill1, skill2, difficulty, \
RECIPE(itm_smg_45, CC_WEAPON, sk_mechanics, sk_gun, 5, 20000);
TOOL(itm_hacksaw, -1, itm_toolset, -1, NULL);
TOOL(itm_screwdriver, -1, itm_toolset, -1, NULL);
- TOOL(itm_hammer, -1, itm_rock, -1, itm_hatchet, -1, itm_toolset, -1, NULL);
+ TOOL(itm_hammer, -1, itm_rock, -1, itm_hatchet, -1, NULL);
COMP(itm_pipe, 1, NULL);
COMP(itm_2x4, 2, NULL);
COMP(itm_nail, 4, NULL);
@@ -144,7 +144,7 @@ recipes.push_back( recipe(id, result, category, skill1, skill2, difficulty, \
RECIPE(itm_chainsaw_off, CC_WEAPON, sk_mechanics, sk_null, 4, 20000);
TOOL(itm_screwdriver, -1, itm_toolset, -1, NULL);
- TOOL(itm_hammer, -1, itm_hatchet, -1, itm_toolset, -1, NULL);
+ TOOL(itm_hammer, -1, itm_hatchet, -1, NULL);
TOOL(itm_wrench, -1, itm_toolset, -1, NULL);
COMP(itm_motor, 1, NULL);
COMP(itm_chain, 1, NULL);
@@ -227,11 +227,13 @@ RECIPE(itm_c4, CC_WEAPON, sk_mechanics, sk_electronics, 4, 8000);
TOOL(itm_hotplate, 2, itm_toolset, 1, itm_fire, -1, NULL);
TOOL(itm_pot, -1, NULL);
COMP(itm_tea_raw, 1, NULL);
+ COMP(itm_water, 1, NULL);
RECIPE(itm_coffee, CC_FOOD, sk_cooking, sk_null, 0, 4000);
TOOL(itm_hotplate, 2, itm_toolset, 1, itm_fire, -1, NULL);
TOOL(itm_pot, -1, NULL);
COMP(itm_coffee_raw, 1, NULL);
+ COMP(itm_water, 1, NULL);
RECIPE(itm_oj, CC_FOOD, sk_cooking, sk_null, 1, 5000);
TOOL(itm_rock, -1, itm_toolset, -1, NULL);
@@ -480,11 +482,11 @@ RECIPE(itm_c4, CC_WEAPON, sk_mechanics, sk_electronics, 4, 8000);
RECIPE(itm_hoodie, CC_ARMOR, sk_tailor, sk_null, 3, 40000);
TOOL(itm_sewing_kit, 14, NULL);
- COMP(itm_rag, 8, NULL);
+ COMP(itm_rag, 12, NULL);
RECIPE(itm_trenchcoat, CC_ARMOR, sk_tailor, sk_null, 3, 42000);
TOOL(itm_sewing_kit, 24, NULL);
- COMP(itm_rag, 10, NULL);
+ COMP(itm_rag, 11, NULL);
RECIPE(itm_coat_fur, CC_ARMOR, sk_tailor, sk_null, 4, 100000);
TOOL(itm_sewing_kit, 20, NULL);
View
32 event.cpp
@@ -50,8 +50,8 @@ void event::actualize(game *g)
int tries = 0;
int monx = -1, mony = -1;
do {
- monx = rng(0, SEEX * 3);
- mony = rng(0, SEEY * 3);
+ monx = rng(0, SEEX * MAPSIZE);
+ mony = rng(0, SEEY * MAPSIZE);
tries++;
} while (tries < 10 && !g->is_empty(monx, mony) &&
rl_dist(g->u.posx, g->u.posx, monx, mony) <= 2);
@@ -68,8 +68,8 @@ void event::actualize(game *g)
int num_horrors = rng(3, 5);
int faultx = -1, faulty = -1;
bool horizontal;
- for (int x = 0; x < SEEX * 3 && faultx == -1; x++) {
- for (int y = 0; y < SEEY * 3 && faulty == -1; y++) {
+ for (int x = 0; x < SEEX * MAPSIZE && faultx == -1; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE && faulty == -1; y++) {
if (g->m.ter(x, y) == t_fault) {
faultx = x;
faulty = y;
@@ -87,13 +87,13 @@ void event::actualize(game *g)
do {
tries = 0;
if (horizontal) {
- monx = rng(0, SEEX * 3);
+ monx = rng(0, SEEX * MAPSIZE);
for (int n = -1; n <= 1; n++) {
if (g->m.ter(monx, faulty + n) == t_rock_floor)
mony = faulty + n;
}
} else { // Vertical fault
- mony = rng(0, SEEY * 3);
+ mony = rng(0, SEEY * MAPSIZE);
for (int n = -1; n <= 1; n++) {
if (g->m.ter(faultx + n, mony) == t_rock_floor)
monx = faultx + n;
@@ -107,8 +107,8 @@ void event::actualize(game *g)
} break;
case EVENT_ROOTS_DIE:
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEY * 3; y++) {
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++) {
if (g->m.ter(x, y) == t_root_wall && one_in(3))
g->m.ter(x, y) = t_underbrush;
}
@@ -117,8 +117,8 @@ void event::actualize(game *g)
case EVENT_TEMPLE_OPEN: {
bool saw_grate = false;
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEY * 3; y++) {
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++) {
if (g->m.ter(x, y) == t_grate) {
g->m.ter(x, y) = t_stairs_down;
int j;
@@ -134,12 +134,12 @@ void event::actualize(game *g)
case EVENT_TEMPLE_FLOOD: {
bool flooded = false;
map copy;
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEY * 3; y++)
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++)
copy.ter(x, y) = g->m.ter(x, y);
}
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEY * 3; y++) {
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++) {
if (g->m.ter(x, y) == t_water_sh) {
bool deepen = false;
for (int wx = x - 1; wx <= x + 1 && !deepen; wx++) {
@@ -179,8 +179,8 @@ void event::actualize(game *g)
}
}
// copy is filled with correct tiles; now copy them back to g->m
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEY * 3; y++)
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++)
g->m.ter(x, y) = copy.ter(x, y);
}
g->add_event(EVENT_TEMPLE_FLOOD, int(g->turn) + rng(2, 3));
View
6 field.cpp
@@ -9,8 +9,8 @@ bool map::process_fields(game *g)
bool found_field = false;
field *cur;
field_id curtype;
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEY * 3; y++) {
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++) {
cur = &field_at(x, y);
curtype = cur->type;
if (!found_field && curtype != fd_null)
@@ -202,7 +202,7 @@ bool map::process_fields(game *g)
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 (fx >= 0 && fy >= 0 && fx < SEEX * 3 && fy < SEEY * 3) {
+ if (fx >= 0 && fy >= 0 && fx < SEEX * MAPSIZE && fy < SEEY * MAPSIZE) {
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);
View
392 game.cpp
@@ -73,8 +73,8 @@ game::game()
for (int i = 0; i < num_monsters; i++) // Reset kill counts to 0
kills[i] = 0;
// Set the scent map to 0
- for (int i = 0; i < SEEX * 3; i++) {
- for (int j = 0; j < SEEX * 3; j++)
+ for (int i = 0; i < SEEX * MAPSIZE; i++) {
+ for (int j = 0; j < SEEX * MAPSIZE; j++)
grscent[i][j] = 0;
}
if (opening_screen()) {// Opening menu
@@ -384,6 +384,7 @@ void game::start_game()
cur_om = overmap(this, 0, 0, 0); // We start in the (0,0,0) overmap.
// Find a random house on the map, and set us there.
cur_om.first_house(levx, levy);
+ set_adjacent_overmaps(true);
levz = 0;
// Start the overmap out with none of it seen by the player...
for (int i = 0; i < OMAPX; i++) {
@@ -401,8 +402,8 @@ void game::start_game()
// Init the starting map at this location.
m.load(this, levx, levy);
// Start us off somewhere in the house.
- u.posx = SEEX + 4;
- u.posy = SEEY + 5;
+ u.posx = SEEX * int(MAPSIZE / 2) + 5;
+ u.posy = SEEY * int(MAPSIZE / 2) + 5;
u.str_cur = u.str_max;
u.per_cur = u.per_max;
u.int_cur = u.int_max;
@@ -424,8 +425,8 @@ void game::start_tutorial(tut_type type)
for (int i = 0; i < NUM_LESSONS; i++)
tutorials_seen[i] = false;
// Set the scent map to 0
- for (int i = 0; i < SEEX * 3; i++) {
- for (int j = 0; j < SEEX * 3; j++)
+ for (int i = 0; i < SEEX * MAPSIZE; i++) {
+ for (int j = 0; j < SEEX * MAPSIZE; j++)
grscent[i][j] = 0;
}
temperature = 65; // Kind of cool for June, but okay.
@@ -457,18 +458,18 @@ void game::start_tutorial(tut_type type)
// Init the starting map at this location.
m.load(this, levx, levy);
// Make sure the map is totally reset
- for (int i = 0; i < SEEX * 3; i++) {
- for (int j = 0; j < SEEY * 3; j++)
+ for (int i = 0; i < SEEX * MAPSIZE; i++) {
+ for (int j = 0; j < SEEY * MAPSIZE; j++)
m.i_at(i, j).clear();
}
// Special items for the tutorial.
m.add_item( 5, SEEY * 2 + 1, itypes[itm_helmet_bike], 0);
m.add_item( 4, SEEY * 2 + 1, itypes[itm_backpack], 0);
m.add_item( 3, SEEY * 2 + 1, itypes[itm_pants_cargo], 0);
- m.add_item( 7, SEEY * 3 - 4, itypes[itm_machete], 0);
- m.add_item( 7, SEEY * 3 - 4, itypes[itm_9mm], 0);
- m.add_item( 7, SEEY * 3 - 4, itypes[itm_9mmP], 0);
- m.add_item( 7, SEEY * 3 - 4, itypes[itm_uzi], 0);
+ m.add_item( 7, SEEY * MAPSIZE - 4, itypes[itm_machete], 0);
+ m.add_item( 7, SEEY * MAPSIZE - 4, itypes[itm_9mm], 0);
+ m.add_item( 7, SEEY * MAPSIZE - 4, itypes[itm_9mmP], 0);
+ m.add_item( 7, SEEY * MAPSIZE - 4, itypes[itm_uzi], 0);
m.add_item(SEEX * 2 - 2, SEEY * 2 + 5, itypes[itm_bubblewrap], 0);
m.add_item(SEEX * 2 - 2, SEEY * 2 + 6, itypes[itm_grenade], 0);
m.add_item(SEEX * 2 - 3, SEEY * 2 + 6, itypes[itm_flashlight], 0);
@@ -591,7 +592,7 @@ bool game::do_turn()
u.radiation--;
u.get_sick(this);
// Auto-save on the half-hour
- save();
+ //save();
}
// Update the weather, if it's time.
if (turn >= nextweather)
@@ -606,8 +607,6 @@ bool game::do_turn()
process_activity();
-
-
while (u.moves > 0) {
draw();
get_input();
@@ -1030,24 +1029,24 @@ void game::get_input()
help();
refresh_all();
} else if (ch == '"') {
- if(autorunmode){
- add_msg("Auto run mode OFF!");
- autorunmode = false;
- } else {
- add_msg("Auto run mode ON");
- autorunmode = true;
- }
+ if (autorunmode) {
+ add_msg("Auto run mode OFF!");
+ autorunmode = false;
+ } else {
+ add_msg("Auto run mode ON");
+ autorunmode = true;
+ }
} else if (ch == '\''){
- if(run_mode == 2){
- add_msg("Ignoring enemy!");
- run_mode = 1;
- }
+ if (run_mode == 2) {
+ add_msg("Ignoring enemy!");
+ run_mode = 1;
+ }
}
}
int& game::scent(int x, int y)
{
- if (x < 0 || x >= SEEX * 3 || y < 0 || y >= SEEY * 3) {
+ if (x < 0 || x >= SEEX * MAPSIZE || y < 0 || y >= SEEY * MAPSIZE) {
nulscent = 0;
return nulscent; // Out-of-bounds - null scent
}
@@ -1056,37 +1055,37 @@ int& game::scent(int x, int y)
void game::update_scent()
{
- signed int newscent[SEEX * 3][SEEY * 3];
- int x, y, i, j, squares_used;
+ signed int newscent[SEEX * MAPSIZE][SEEY * MAPSIZE];
if (!u.has_active_bionic(bio_scent_mask))
scent(u.posx, u.posy) = u.scent;
else
scent(u.posx, u.posy) = 0;
- for (x = 0; x < SEEX * 3; x++) {
- for (y = 0; y < SEEY * 3; y++) {
+ for (int x = u.posx - SEEX * 2; x <= u.posx + SEEX * 2; x++) {
+ for (int y = u.posy - SEEY * 2; y <= u.posy + SEEY * 2; y++) {
newscent[x][y] = 0;
- squares_used = 0;
- for (i = -1; i <= 1; i++) {
- for (j = -1; j <= 1; j++) {
- if ((m.move_cost(x, y) != 0 || m.has_flag(bashable, x, y)) &&
- scent(x, y) <= scent(x+i, y+j)) {
- newscent[x][y] += scent(x+i, y+j);
- squares_used++;
+ if (m.move_cost(x, y) != 0 || m.has_flag(bashable, x, y)) {
+ int squares_used = 0;
+ for (int i = -1; i <= 1; i++) {
+ for (int j = -1; j <= 1; j++) {
+ if (scent(x, y) <= scent(x+i, y+j)) {
+ newscent[x][y] += scent(x+i, y+j);
+ squares_used++;
+ }
}
}
- }
- newscent[x][y] /= (squares_used + 1);
- if (m.field_at(x, y).type == fd_slime &&
- newscent[x][y] < 10 * m.field_at(x, y).density)
- newscent[x][y] = 10 * m.field_at(x, y).density;
- if (newscent[x][y] > 10000) {
- debugmsg("Wacky scent at %d, %d (%d)", x, y, newscent[x][y]);
- newscent[x][y] = 0; // Scent should never be higher
+ newscent[x][y] /= (squares_used + 1);
+ if (m.field_at(x, y).type == fd_slime &&
+ newscent[x][y] < 10 * m.field_at(x, y).density)
+ newscent[x][y] = 10 * m.field_at(x, y).density;
+ if (newscent[x][y] > 10000) {
+ debugmsg("Wacky scent at %d, %d (%d)", x, y, newscent[x][y]);
+ newscent[x][y] = 0; // Scent should never be higher
+ }
}
}
}
- for (x = 0; x < SEEX * 3; x++) {
- for (y = 0; y < SEEY * 3; y++)
+ for (int x = u.posx - SEEX * 2; x <= u.posx + SEEX * 2; x++) {
+ for (int y = u.posy - SEEY * 2; y <= u.posy + SEEY * 2; y++)
scent(x, y) = newscent[x][y];
}
if (!u.has_active_bionic(bio_scent_mask))
@@ -1204,8 +1203,8 @@ void game::load(std::string name)
weather = weather_type(tmpweather);
temperature = tmptemp;
// Next, the scent map.
- for (int i = 0; i < SEEX * 3; i++) {
- for (int j = 0; j < SEEY * 3; j++)
+ for (int i = 0; i < SEEX * MAPSIZE; i++) {
+ for (int j = 0; j < SEEY * MAPSIZE; j++)
fin >> grscent[i][j];
}
// Now the number of monsters...
@@ -1273,8 +1272,8 @@ void game::save()
" " << levx << " " << levy << " " << levz << " " << cur_om.posx <<
" " << cur_om.posy << " " << std::endl;
// Next, the scent map.
- for (int i = 0; i < SEEX * 3; i++) {
- for (int j = 0; j < SEEY * 3; j++)
+ for (int i = 0; i < SEEX * MAPSIZE; i++) {
+ for (int j = 0; j < SEEY * MAPSIZE; j++)
fout << grscent[i][j] << " ";
}
// Now save all monsters.
@@ -1316,17 +1315,19 @@ void game::advance_nextinv()
void game::add_msg(const char* msg, ...)
{
- char buff[512];
+ char buff[1024];
va_list ap;
va_start(ap, msg);
vsprintf(buff, msg, ap);
va_end(ap);
+ std::string s(buff);
+ if (s.length() == 0)
+ return;
int maxlength = 80 - (SEEX * 2 + 10); // Matches write_msg() below
if (messages.size() == 256)
messages.erase(messages.begin());
curmes++;
- std::string s(buff);
size_t split;
while (s.length() > maxlength) {
split = s.find_last_of(' ', maxlength);
@@ -1381,8 +1382,8 @@ void game::debug()
if (tmp.x != -1) {
z.clear();
m.save(&cur_om, turn, levx, levy);
- levx = tmp.x * 2;
- levy = tmp.y * 2;
+ levx = tmp.x * 2 - int(MAPSIZE / 2);
+ levy = tmp.y * 2 - int(MAPSIZE / 2);
m.load(this, levx, levy);
}
} break;
@@ -1411,9 +1412,12 @@ void game::debug()
case 7:
popup_top("\
+Location %d:%d, %s\n\
Current turn: %d; Next spawn %d.\n\
%d monsters exist.\n\
-%d events planned.", int(turn), int(nextspawn), z.size(), events.size());
+%d events planned.", levx, levy,
+oterlist[cur_om.ter(levx / 2, levy / 2)].name.c_str(),
+int(turn), int(nextspawn), z.size(), events.size());
break;
case 8:
@@ -1775,7 +1779,8 @@ void game::draw()
// TODO: Allow for a 24-hour option--already supported by calendar turn
mvwprintz(w_status, 1, 41, c_white, turn.print_time().c_str());
- oter_id cur_ter = cur_om.ter((levx + 1) / 2, (levy + 1) / 2);
+ oter_id cur_ter = cur_om.ter((levx + int(MAPSIZE / 2)) / 2,
+ (levy + int(MAPSIZE / 2)) / 2);
std::string tername = oterlist[cur_ter].name;
if (tername.length() > 14)
tername = tername.substr(0, 14);
@@ -1815,7 +1820,7 @@ bool game::isBetween(int test, int down, int up)
void game::draw_ter()
{
int t = 0;
- m.draw(this, w_terrain);
+ m.draw(this, w_terrain);
// Draw monsters
int distx, disty;
@@ -1946,30 +1951,8 @@ void game::draw_minimap()
mvwputch(w_minimap, 6, i, c_white, LINE_OXOX);
}
- int cursx = (levx + 1) / 2;
- int cursy = (levy + 1) / 2;
-// Set up adjacent overmaps
- overmap hori, vert, diag;
- if (cursx < 5)
- hori = overmap(this, cur_om.posx - 1, cur_om.posy, cur_om.posz);
- if (cursx > OMAPX - 6)
- hori = overmap(this, cur_om.posx + 1, cur_om.posy, cur_om.posz);
- if (cursy < 5)
- vert = overmap(this, cur_om.posx, cur_om.posy - 1, cur_om.posz);
- if (cursy > OMAPY - 6)
- vert = overmap(this, cur_om.posx, cur_om.posy + 1, cur_om.posz);
-
- if (cursx < 5) {
- if (cursy < 5)
- diag = overmap(this, cur_om.posx - 1, cur_om.posy - 1, cur_om.posz);
- else if (cursy > OMAPY - 6)
- diag = overmap(this, cur_om.posx - 1, cur_om.posy + 1, cur_om.posz);
- } else if (cursx > OMAPX - 6) {
- if (cursy < 5)
- diag = overmap(this, cur_om.posx + 1, cur_om.posy - 1, cur_om.posz);
- else if (cursy > OMAPY - 6)
- diag = overmap(this, cur_om.posx + 1, cur_om.posy + 1, cur_om.posz);
- }
+ int cursx = (levx + int(MAPSIZE / 2)) / 2;
+ int cursy = (levy + int(MAPSIZE / 2)) / 2;
for (int i = -2; i <= 2; i++) {
for (int j = -2; j <= 2; j++) {
@@ -1985,18 +1968,18 @@ void game::draw_minimap()
else omx -= OMAPX;
if (omy < 0) omy += OMAPY;
else omy -= OMAPY;
- cur_ter = diag.ter(omx, omy);
- seen = diag.seen(omx, omy);
+ cur_ter = om_diag.ter(omx, omy);
+ seen = om_diag.seen(omx, omy);
} else if (omx < 0 || omx >= OMAPX) {
if (omx < 0) omx += OMAPX;
else omx -= OMAPX;
- cur_ter = hori.ter(omx, omy);
- seen = hori.seen(omx, omy);
+ cur_ter = om_hori.ter(omx, omy);
+ seen = om_hori.seen(omx, omy);
} else if (omy < 0 || omy >= OMAPY) {
if (omy < 0) omy += OMAPY;
else omy -= OMAPY;
- cur_ter = vert.ter(omx, omy);
- seen = vert.seen(omx, omy);
+ cur_ter = om_vert.ter(omx, omy);
+ seen = om_vert.seen(omx, omy);
} else
debugmsg("No data loaded! omx: %d omy: %d", omx, omy);
nc_color ter_color = oterlist[cur_ter].color;
@@ -2050,6 +2033,8 @@ unsigned char game::light_level()
}
if (ret < 8 && u.has_active_bionic(bio_flashlight))
ret = 8;
+ if (ret < 4 && u.has_artifact_with(AEP_GLOW))
+ ret = 4;
if (ret < 1)
ret = 1;
return ret;
@@ -2372,6 +2357,9 @@ void game::monmove()
debugmsg("Moving out of bounds monster! i %d, z.size() %d", i, z.size());
while (!z[i].can_move_to(m, z[i].posx, z[i].posy) && i < z.size()) {
// If we can't move to our current position, assign us to a new one
+ if (debugmon)
+ debugmsg("%s can't move to its location! (%d:%d), %s", z[i].name().c_str(),
+ z[i].posx, z[i].posy, m.tername(z[i].posx, z[i].posy).c_str());
bool okay = false;
int xdir = rng(1, 2) * 2 - 3, ydir = rng(1, 2) * 2 - 3; // -1 or 1
int startx = z[i].posx - 3 * xdir, endx = z[i].posx + 3 * xdir;
@@ -2399,6 +2387,7 @@ void game::monmove()
}
}
while (z[i].moves > 0 && !dead) {
+ z[i].made_footstep = false;
z[i].plan(this); // Formulate a path to follow
z[i].move(this); // Move one square, possibly hit u
m.mon_in_field(z[i].posx, z[i].posy, this, &(z[i]));
@@ -2423,8 +2412,8 @@ void game::monmove()
}
}
// We might have stumbled out of range of the player; if so, delete us
- if (z[i].posx < 0 - SEEX * 4 || z[i].posy < 0 - SEEX * 4 ||
- z[i].posx > SEEX * 5 || z[i].posy > SEEY * 5) {
+ if (z[i].posx < 0 - SEEX || z[i].posy < 0 - SEEX ||
+ z[i].posx > SEEX * (MAPSIZE + 1) || z[i].posy > SEEY * (MAPSIZE + 1)) {
int group = valid_group((mon_id)(z[i].type->id), levx, levy);
if (group != -1) {
cur_om.zg[group].population++;
@@ -3151,6 +3140,8 @@ void game::close()
else if (m.i_at(closex, closey).size() > 0)
add_msg("There's %s in the way!", m.i_at(closex, closey).size() == 1 ?
m.i_at(closex, closey)[0].tname(this).c_str() : "some stuff");
+ else if (closex == u.posx && closey == u.posy)
+ add_msg("There's some buffoon in the way!");
else
didit = m.close_door(closex, closey);
} else
@@ -3354,8 +3345,8 @@ void game::examine()
cur_om = overmap(this, cur_om.posx, cur_om.posy, cur_om.posz + movez);
m.load(this, levx, levy);
update_map(u.posx, u.posy);
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEY * 3; y++) {
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++) {
if (m.ter(x, y) == t_elevator) {
u.posx = x;
u.posy = y;
@@ -3436,7 +3427,7 @@ shape, but with long, twisted, distended limbs.");
query_yn("Flip the %s?", m.tername(examx, examy).c_str())) {
u.moves -= 100;
for (int y = examy; y <= examy + 5; y++) {
- for (int x = 0; x < SEEX * 3; x++) {
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
switch (m.ter(examx, examy)) {
case t_switch_rg:
if (m.ter(x, y) == t_rock_red)
@@ -4258,7 +4249,7 @@ void game::plfire(bool burst)
{
if (!u.weapon.is_gun())
return;
- if (u.weapon.charges == 0) {
+ if (u.weapon.charges == 0 && !u.weapon.has_flag(IF_RELOAD_AND_SHOOT)) {
add_msg("You need to reload!");
return;
}
@@ -4507,6 +4498,11 @@ void game::takeoff()
void game::reload()
{
if (u.weapon.is_gun()) {
+ if (u.weapon.has_flag(IF_RELOAD_AND_SHOOT)) {
+ add_msg("Your %s does not need to be reloaded; it reloads and fires in a \
+single action.");
+ return;
+ }
if (u.weapon.charges == u.weapon.clip_size()) {
add_msg("Your %s is fully loaded!", u.weapon.tname(this).c_str());
return;
@@ -4802,8 +4798,8 @@ void game::plmove(int x, int y)
// Otherwise, actual movement, zomg
if (u.has_disease(DI_AMIGARA)) {
int curdist = 999, newdist = 999;
- for (int cx = 0; cx < SEEX * 3; cx++) {
- for (int cy = 0; cy < SEEY * 3; cy++) {
+ for (int cx = 0; cx < SEEX * MAPSIZE; cx++) {
+ for (int cy = 0; cy < SEEY * MAPSIZE; cy++) {
if (m.ter(cx, cy) == t_fault) {
int dist = rl_dist(cx, cy, u.posx, u.posy);
if (dist < curdist)
@@ -4882,10 +4878,12 @@ void game::plmove(int x, int y)
u.hit(this, bp_torso, 0, 0, rng(1, 4));
}
}
- if (u.has_trait(PF_LIGHTSTEP))
- sound(x, y, 2, ""); // Sound of footsteps may awaken nearby monsters
- else
- sound(x, y, 6, ""); // Sound of footsteps may awaken nearby monsters
+ if (!u.has_artifact_with(AEP_STEALTH)) {
+ if (u.has_trait(PF_LIGHTSTEP))
+ sound(x, y, 2, ""); // Sound of footsteps may awaken nearby monsters
+ else
+ sound(x, y, 6, ""); // Sound of footsteps may awaken nearby monsters
+ }
// If we moved out of the nonant, we need update our map data
if (m.has_flag(swimmable, x, y) && u.has_disease(DI_ONFIRE)) {
add_msg("The water puts out the flames!");
@@ -4895,7 +4893,8 @@ void game::plmove(int x, int y)
z[mondex].move_to(this, u.posx, u.posy);
add_msg("You displace the %s.", z[mondex].name().c_str());
}
- if (x < SEEX || y < SEEY || x >= SEEX * 2 || y >= SEEY * 2)
+ if (x < SEEX * int(MAPSIZE / 2) || y < SEEY * int(MAPSIZE / 2) ||
+ x >= SEEX * (1 + int(MAPSIZE / 2)) || y >= SEEY * (1 + int(MAPSIZE / 2)))
update_map(x, y);
u.posx = x;
u.posy = y;
@@ -4980,7 +4979,8 @@ void game::plmove(int x, int y)
void game::plswim(int x, int y)
{
- if (x < SEEX || y < SEEY || x >= SEEX * 2 || y >= SEEY * 2)
+ if (x < SEEX * int(MAPSIZE / 2) || y < SEEY * int(MAPSIZE / 2) ||
+ x >= SEEX * (1 + int(MAPSIZE / 2)) || y >= SEEY * (1 + int(MAPSIZE / 2)))
update_map(x, y);
u.posx = x;
u.posy = y;
@@ -4994,7 +4994,7 @@ void game::plswim(int x, int y)
if (!u.underwater) {
add_msg("You sink%s!", (movecost >= 400 ? " like a rock" : ""));
u.underwater = true;
- u.oxygen = 20 + u.str_cur;
+ u.oxygen = 30 + 2 * u.str_cur;
}
}
if (u.oxygen <= 5 && u.underwater) {
@@ -5003,7 +5003,7 @@ void game::plswim(int x, int y)
else
popup("You need to breathe but you can't swim! Get to dry land, quick!");
}
- u.moves -= movecost;
+ u.moves -= (movecost > 200 ? 200 : movecost);
for (int i = 0; i < u.inv.size(); i++) {
if (u.inv[i].type->m1 == IRON && u.inv[i].damage < 5 && one_in(8))
u.inv[i].damage++;
@@ -5016,7 +5016,7 @@ void game::vertical_move(int movez, bool force)
if (m.move_cost(u.posx, u.posy) == 0 && m.has_flag(swimmable, u.posx, u.posy)){
if (movez == -1) {
u.underwater = true;
- u.oxygen = 20 + u.str_cur;
+ u.oxygen = 30 + 2 * u.str_cur;
add_msg("You dive underwater!");
} else {
if (u.swim_speed() < 500) {
@@ -5049,9 +5049,10 @@ void game::vertical_move(int movez, bool force)
stairx = u.posx;
stairy = u.posy;
} else { // We need to find the stairs.
- for (int i = 0; i < SEEX * 3 && stairx == -1; i++) {
- for (int j = 0; j < SEEX * 3 && stairx == -1; j++) {
- int sx = (i + u.posx) % (SEEX * 3), sy = (j + u.posy) % (SEEY * 3);
+ for (int i = 0; i < SEEX * MAPSIZE && stairx == -1; i++) {
+ for (int j = 0; j < SEEX * MAPSIZE && stairx == -1; j++) {
+ int sx = (i + u.posx) % (SEEX * MAPSIZE),
+ sy = (j + u.posy) % (SEEY * MAPSIZE);
if ((movez == -1 && tmpmap.has_flag(goes_up, sx, sy)) ||
(movez == 1 && (tmpmap.has_flag(goes_down, sx, sy) ||
tmpmap.ter(sx, sy) == t_manhole_cover))) {
@@ -5120,8 +5121,32 @@ void game::vertical_move(int movez, bool force)
}
z.clear();
+// Figure out where we know there are up/down connectors
+ std::vector<point> discover;
+ for (int x = 0; x < OMAPX; x++) {
+ for (int y = 0; y < OMAPY; y++) {
+ if (cur_om.seen(x, y) &&
+ ((movez == 1 && oterlist[ cur_om.ter(x, y) ].known_up) ||
+ (movez == -1 && oterlist[ cur_om.ter(x, y) ].known_down) ))
+ discover.push_back( point(x, y) );
+ }
+ }
+
// We moved! Load the new map.
cur_om = overmap(this, cur_om.posx, cur_om.posy, cur_om.posz + movez);
+
+// Fill in all the tiles we know about (e.g. subway stations)
+ for (int i = 0; i < discover.size(); i++) {
+ int x = discover[i].x, y = discover[i].y;
+ cur_om.seen(x, y) = true;
+ if (movez == 1 && !oterlist[ cur_om.ter(x, y) ].known_down &&
+ !cur_om.has_note(x, y))
+ cur_om.add_note(x, y, "AUTO: goes down");
+ if (movez == -1 && !oterlist[ cur_om.ter(x, y) ].known_up &&
+ !cur_om.has_note(x, y))
+ cur_om.add_note(x, y, "AUTO: goes up");
+ }
+
levz += movez;
u.moves -= 100;
m.load(this, levx, levy);
@@ -5166,26 +5191,24 @@ void game::vertical_move(int movez, bool force)
void game::update_map(int &x, int &y)
{
int shiftx = 0, shifty = 0;
- int group;
+ int group = 0;
int olevx = 0, olevy = 0;
- while (x < SEEX) {
+ while (x < SEEX * int(MAPSIZE / 2)) {
x += SEEX;
shiftx--;
}
- while (x >= SEEX * 2) {
+ while (x >= SEEX * (1 + int(MAPSIZE / 2))) {
x -= SEEX;
shiftx++;
}
- while (y < SEEY) {
+ while (y < SEEY * int(MAPSIZE / 2)) {
y += SEEY;
shifty--;
}
- while (y >= SEEY * 2) {
+ while (y >= SEEY * (1 + int(MAPSIZE / 2))) {
y -= SEEY;
shifty++;
}
-// Before we shift/save the map, check if we need to move monsters back to
-// their spawn locations.
m.shift(this, levx, levy, shiftx, shifty);
levx += shiftx;
levy += shifty;
@@ -5207,12 +5230,14 @@ void game::update_map(int &x, int &y)
cur_om.save(u.name);
cur_om = overmap(this, cur_om.posx + olevx, cur_om.posy + olevy, cur_om.posz);
}
+ set_adjacent_overmaps();
// Shift monsters
for (int i = 0; i < z.size(); i++) {
z[i].shift(shiftx, shifty);
- if (z[i].posx < 0 - SEEX * 3 || z[i].posy < 0 - SEEX * 3 ||
- z[i].posx > SEEX * 6 || z[i].posy > SEEY * 6 ) {
+ if (z[i].posx < 0 - SEEX || z[i].posy < 0 - SEEX ||
+ z[i].posx > SEEX * (MAPSIZE + 1) || z[i].posy > SEEY * (MAPSIZE + 1)) {
+// Despawn; we're out of bounds
if (z[i].spawnmapx != -1) { // Static spawn, move them back there
map tmp;
tmp.load(this, z[i].spawnmapx, z[i].spawnmapy);
@@ -5238,8 +5263,10 @@ void game::update_map(int &x, int &y)
// Shift NPCs
for (int i = 0; i < active_npc.size(); i++) {
active_npc[i].shift(shiftx, shifty);
- if (active_npc[i].posx < 0 - SEEX * 3 || active_npc[i].posy < 0 - SEEX * 3 ||
- active_npc[i].posx > SEEX * 6 || active_npc[i].posy > SEEY * 6) {
+ if (active_npc[i].posx < 0 - SEEX * MAPSIZE ||
+ active_npc[i].posy < 0 - SEEX * MAPSIZE ||
+ active_npc[i].posx > SEEX * MAPSIZE * 2 ||
+ active_npc[i].posy > SEEY * MAPSIZE * 2 ) {
cur_om.npcs.push_back(active_npc[i]);
active_npc.erase(active_npc.begin() + i);
i--;
@@ -5277,47 +5304,59 @@ void game::update_map(int &x, int &y)
if (turn >= nextspawn)
spawn_mon(shiftx, shifty);
// Shift scent
- unsigned int newscent[SEEX * 3][SEEY * 3];
- for (int i = 0; i < SEEX * 3; i++) {
- for (int j = 0; j < SEEY * 3; j++)
+ unsigned int newscent[SEEX * MAPSIZE][SEEY * MAPSIZE];
+ for (int i = 0; i < SEEX * MAPSIZE; i++) {
+ for (int j = 0; j < SEEY * MAPSIZE; j++)
newscent[i][j] = scent(i + (shiftx * SEEX), j + (shifty * SEEY));
}
- for (int i = 0; i < SEEX * 3; i++) {
- for (int j = 0; j < SEEY * 3; j++)
+ for (int i = 0; i < SEEX * MAPSIZE; i++) {
+ for (int j = 0; j < SEEY * MAPSIZE; j++)
scent(i, j) = newscent[i][j];
}
// Update what parts of the world map we can see
update_overmap_seen();
draw_minimap();
- save(); // We autosave every time the map gets updated.
+ //save(); // We autosave every time the map gets updated.
}
-void game::update_overmap_seen()
+void game::set_adjacent_overmaps(bool from_scratch)
{
- overmap hori, vert, diag;
- int omx = (levx + 1) / 2, omy = (levy + 1) / 2;
- if (omy < 40)
- vert = overmap(this, cur_om.posx, cur_om.posy - 1, cur_om.posz);
- if (omy > OMAPY - 41)
- vert = overmap(this, cur_om.posx, cur_om.posy + 1, cur_om.posz);
-
- if (omx < 40) {
- hori = overmap(this, cur_om.posx - 1, cur_om.posy, cur_om.posz);
- if (omy < 40)
- diag = overmap(this, cur_om.posx - 1, cur_om.posy - 1, cur_om.posz);
- else if (omy > OMAPY - 41)
- diag = overmap(this, cur_om.posx - 1, cur_om.posy + 1, cur_om.posz);
- } else if (omx > OMAPX - 41) {
- hori = overmap(this, cur_om.posx + 1, cur_om.posy, cur_om.posz);
- if (omy < 40)
- diag = overmap(this, cur_om.posx + 1, cur_om.posy - 1, cur_om.posz);
- else if (omy > OMAPY - 41)
- diag = overmap(this, cur_om.posx + 1, cur_om.posy + 1, cur_om.posz);
+ if (levx == OMAPX - 1 || levx == 0 || (from_scratch && levx <= OMAPX)) {
+ om_hori = overmap(this, cur_om.posx - 1, cur_om.posy, cur_om.posz);
+
+ if (levy == OMAPY - 1 || levy == 0 || (from_scratch && levy <= OMAPY))
+ om_diag = overmap(this, cur_om.posx - 1, cur_om.posy - 1, cur_om.posz);
+ else if (levy == OMAPY || levy == OMAPY * 2 - 1 ||
+ (from_scratch && levy > OMAPY))
+ om_diag = overmap(this, cur_om.posx - 1, cur_om.posy + 1, cur_om.posz);
+
+ } else if (levx == OMAPX || levx == OMAPX * 2 - 1 ||
+ (from_scratch && levx > OMAPX)) {
+ om_hori = overmap(this, cur_om.posx + 1, cur_om.posy, cur_om.posz);
+
+ if (levy == OMAPY - 1 || levy == 0 || (from_scratch && levy <= OMAPY))
+ om_diag = overmap(this, cur_om.posx + 1, cur_om.posy - 1, cur_om.posz);
+ else if (levy == OMAPY || levy == OMAPY * 2 - 1 ||
+ (from_scratch && levy > OMAPY))
+ om_diag = overmap(this, cur_om.posx + 1, cur_om.posy + 1, cur_om.posz);
+
}
+ if (levy == OMAPY - 1 || levy == 0 || (from_scratch && levy <= OMAPY))
+ om_vert = overmap(this, cur_om.posx , cur_om.posy - 1, cur_om.posz);
+ else if (levy == OMAPY || levy == OMAPY * 2 - 1 ||
+ (from_scratch && levy > OMAPY))
+ om_vert = overmap(this, cur_om.posx , cur_om.posy + 1, cur_om.posz);
+}
+
+void game::update_overmap_seen()
+{
+ int omx = (levx + int(MAPSIZE / 2)) / 2, omy = (levy + int(MAPSIZE / 2)) / 2;
int dist = u.overmap_sight_range(light_level());
cur_om.seen(omx, omy) = true; // We can always see where we're standing
- bool altered_vert = false, altered_diag = false, altered_hori = false;
+ if (dist == 0)
+ return; // No need to run the rest!
+ bool altered_om_vert = false, altered_om_diag = false, altered_om_hori = false;
for (int x = omx - dist; x <= omx + dist; x++) {
for (int y = omy - dist; y <= omy + dist; y++) {
std::vector<point> line = line_to(omx, omy, x, y, 0);
@@ -5332,15 +5371,15 @@ void game::update_overmap_seen()
else lx -= OMAPX;
if (ly < 0) ly += OMAPY;
else ly -= OMAPY;
- cost = oterlist[diag.ter(lx, ly)].see_cost;
+ cost = oterlist[om_diag.ter(lx, ly)].see_cost;
} else if (lx < 0 || lx >= OMAPX) {
if (lx < 0) lx += OMAPX;
else lx -= OMAPX;
- cost = oterlist[hori.ter(lx, ly)].see_cost;
+ cost = oterlist[om_hori.ter(lx, ly)].see_cost;
} else if (ly < 0 || ly >= OMAPY) {
if (ly < 0) ly += OMAPY;
else ly -= OMAPY;
- cost = oterlist[vert.ter(lx, ly)].see_cost;
+ cost = oterlist[om_vert.ter(lx, ly)].see_cost;
}
sight_points -= cost;
}
@@ -5353,28 +5392,28 @@ void game::update_overmap_seen()
else tmpx -= OMAPX;
if (tmpy < 0) tmpy += OMAPY;
else tmpy -= OMAPY;
- diag.seen(tmpx, tmpy) = true;
- altered_diag = true;
+ om_diag.seen(tmpx, tmpy) = true;
+ altered_om_diag = true;
} else if (tmpx < 0 || tmpx >= OMAPX) {
if (tmpx < 0) tmpx += OMAPX;
else tmpx -= OMAPX;
- hori.seen(tmpx, tmpy) = true;
- altered_hori = true;
+ om_hori.seen(tmpx, tmpy) = true;
+ altered_om_hori = true;
} else if (tmpy < 0 || tmpy >= OMAPY) {
if (tmpy < 0) tmpy += OMAPY;
else tmpy -= OMAPY;
- vert.seen(tmpx, tmpy) = true;
- altered_vert = true;
+ om_vert.seen(tmpx, tmpy) = true;
+ altered_om_vert = true;
}
}
}
}
- if (altered_vert)
- vert.save(u.name);
- if (altered_hori)
- hori.save(u.name);
- if (altered_diag)
- diag.save(u.name);
+ if (altered_om_vert)
+ om_vert.save(u.name);
+ if (altered_om_hori)
+ om_hori.save(u.name);
+ if (altered_om_diag)
+ om_diag.save(u.name);
}
void game::replace_stair_monsters()
@@ -5392,11 +5431,12 @@ void game::update_stair_monsters()
for (int i = 0; i < coming_to_stairs.size(); i++) {
coming_to_stairs[i].count--;
if (coming_to_stairs[i].count <= 0) {
- int startx = rng(0, SEEX * 3 - 1), starty = rng(0, SEEY * 3 - 1);
+ int startx = rng(0, SEEX * MAPSIZE - 1), starty = rng(0, SEEY * MAPSIZE - 1);
bool found_stairs = false;
- for (int x = 0; x < SEEX * 3 && !found_stairs; x++) {
- for (int y = 0; y < SEEY * 3 && !found_stairs; y++) {
- int sx = (startx + x) % (SEEX * 3), sy = (starty + y) % (SEEY * 3);
+ for (int x = 0; x < SEEX * MAPSIZE && !found_stairs; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE && !found_stairs; y++) {
+ int sx = (startx + x) % (SEEX * MAPSIZE),
+ sy = (starty + y) % (SEEY * MAPSIZE);
if (m.has_flag(goes_up, sx, sy) || m.has_flag(goes_down, sx, sy)) {
found_stairs = true;
int mposx = sx, mposy = sy;
@@ -5478,10 +5518,22 @@ void game::spawn_mon(int shiftx, int shifty)
zom = monster(mtypes[type]);
iter = 0;
do {
- monx = rng(0, SEEX * 3 - 1);
- mony = rng(0, SEEY * 3 - 1);
- if (shiftx == -1) monx = 0 - SEEX * 2; if (shiftx == 1) monx = SEEX * 4;
- if (shifty == -1) mony = 0 - SEEX * 2; if (shifty == 1) mony = SEEY * 4;
+ monx = rng(0, SEEX * MAPSIZE - 1);
+ mony = rng(0, SEEY * MAPSIZE - 1);
+ if (shiftx == 0 && shifty == 0) {
+ if (one_in(2))
+ shiftx = 1 - 2 * rng(0, 1);
+ else
+ shifty = 1 - 2 * rng(0, 1);
+ }
+ if (shiftx == -1)
+ monx = SEEX;
+ else if (shiftx == 1)
+ monx = SEEX * (MAPSIZE - 1);
+ if (shifty == -1)
+ mony = 0 - SEEX * 2;
+ if (shifty == 1)
+ mony = SEEY * (MAPSIZE - 1);
monx += rng(-5, 5);
mony += rng(-5, 5);
iter++;
View
6 game.h
@@ -19,6 +19,7 @@
#include "construction.h"
#include "calendar.h"
#include "posix_time.h"
+#include "artifact.h"
#include <vector>
#define LONG_RANGE 10
@@ -131,6 +132,7 @@ class game
itype* new_artifact();
void process_artifact(item *it, player *p, bool wielded = false);
+ void add_artifact_messages(std::vector<art_effect_passive> effects);
char inv(std::string title = "Inventory:");
std::vector<item> multidrop();
@@ -244,6 +246,7 @@ class game
mon_id valid_monster_from(std::vector<mon_id> group);
int valid_group(mon_id type, int x, int y);// Picks a group from cur_om
moncat_id mt_to_mc(mon_id type);// Monster type to monster category
+ void set_adjacent_overmaps(bool from_scratch = false);
// Routine loop functions, approximately in order of execution
void monmove(); // Monster movement
@@ -294,12 +297,13 @@ class game
calendar nextspawn; // The turn on which monsters will spawn next.
calendar nextweather; // The turn on which weather will shift next.
+ overmap om_hori, om_vert, om_diag; // Adjacent overmaps
int next_npc_id, next_faction_id, next_mission_id; // Keep track of UIDs
signed char temperature; // The air temperature
weather_type weather; // Weather pattern--SEE weather.h
std::vector <std::string> messages; // Messages to be printed
unsigned char curmes; // The last-seen message. Older than 256 is deleted.
- int grscent[SEEX * 3][SEEY * 3]; // The scent map
+ int grscent[SEEX * MAPSIZE][SEEY * MAPSIZE]; // The scent map
int nulscent; // Returned for OOB scent checks
std::vector<event> events; // Game events to be processed
int kills[num_monsters]; // Player's kill count
View
6 inventory_ui.cpp
@@ -142,6 +142,9 @@ char game::inv(std::string title)
wprintw(w_inv, " [%d]", u.inv.stack_at(cur_it).size());
if (u.inv[cur_it].charges > 0)
wprintw(w_inv, " (%d)", u.inv[cur_it].charges);
+ else if (u.inv[cur_it].contents.size() == 1 &&
+ u.inv[cur_it].contents[0].charges > 0)
+ wprintw(w_inv, " (%d)", u.inv[cur_it].contents[0].charges);
}
cur_line++;
}
@@ -217,6 +220,9 @@ std::vector<item> game::multidrop()
wprintz(w_inv, col, " [%d]", u.inv.stack_at(cur_it).size());
if (u.inv[cur_it].charges > 0)
wprintz(w_inv, col, " (%d)", u.inv[cur_it].charges);
+ else if (u.inv[cur_it].contents.size() == 1 &&
+ u.inv[cur_it].contents[0].charges > 0)
+ wprintw(w_inv, " (%d)", u.inv[cur_it].contents[0].charges);
}
cur_line++;
}
View
3  itype.h
@@ -42,7 +42,7 @@ itm_apple, itm_orange, itm_lemon, itm_chips, itm_pretzels, itm_chocolate,
itm_can_tuna, itm_can_catfood, itm_honeycomb, itm_royal_jelly, itm_fetus,
itm_arm, itm_leg, itm_ant_egg, itm_marloss_berry, itm_flour, itm_sugar,
itm_salt, itm_potato_raw, itm_potato_baked, itm_bread, itm_pie, itm_pizza,
- itm_mre, itm_tea_raw, itm_coffee_raw,
+ itm_mre_beef, itm_mre_veggy, itm_tea_raw, itm_coffee_raw,
// Medication
itm_bandages, itm_1st_aid, itm_vitamins, itm_aspirin, itm_caffeine,
itm_pills_sleep, itm_iodine, itm_dayquil, itm_nyquil, itm_inhaler, itm_codeine,
@@ -197,6 +197,7 @@ IF_STR_RELOAD, // Reloading time is reduced by Strength * 20
IF_STR8_DRAW, // Requires strength 8 to draw
IF_STR10_DRAW, // Requires strength 10 to draw
IF_USE_UPS, // Draws power from a UPS
+IF_RELOAD_AND_SHOOT, // Reloading and shooting is one action
IF_AMMO_FLAME, // Sets fire to terrain and monsters
IF_AMMO_INCENDIARY, // Sparks explosive terrain
View
13 itypedef.cpp
@@ -417,11 +417,16 @@ FOOD("pizza", 8, 80, c_ltred, VEGGY, itm_box_small,
A vegetarian pizza, with delicious tomato sauce and a fluffy crust. Its\n\
smell brings back great memories.");
-FOOD("MRE", 50,100, c_green, FLESH, itm_null,
+FOOD("MRE - beef", 50,100, c_green, FLESH, itm_null,
2, 1, 0, 50, 0, 0, 1, 0, 1, -4, &iuse::none, ADD_NULL, "\
Meal Ready to Eat. A military ration. Though not very tasty, it is very\n\
filling and will not spoil.");
+FOOD("MRE - vegetable", 50,100, c_green, VEGGY, itm_null,
+ 2, 1, 0, 40, 0, 0, 1, 0, 1, -4, &iuse::none, ADD_NULL, "\
+Meal Ready to Eat. A military ration. Though not very tasty, it is very\n\
+filling and will not spoil.");
+
FOOD("tea leaves", 10, 13, c_green, VEGGY, itm_bag_plastic,
2, 1, 0, 2, 0, 0, 0, 0, 5, -1, &iuse::none, ADD_NULL, "\
Dried leaves of a tropical plant. You cam boil them into tea, or you\n\
@@ -576,7 +581,7 @@ MELEE("syringe", 8, 25, ',', c_ltcyan, PLASTIC,MNULL,
A medical syringe. Used for administering heroin and other drugs.");
MELEE("rag", 72, 10, ';', c_dkgray, COTTON, MNULL,
- 2, 1,-10, 0, 0, 0, "\
+ 1, 1,-10, 0, 0, 0, "\
A small piece of cloth. Useful for making molotov cocktails and not much else."
);
@@ -1698,14 +1703,14 @@ GUN("compound bow", 2, 700,c_yellow, STEEL, PLASTIC,
A bow with wheels that fires high velocity arrows. Weaker people can use\n\
compound bows more easily. Arrows fired from this weapon have a good chance\n\
of remaining intact for re-use.",
-mfb(IF_STR8_DRAW));
+mfb(IF_STR8_DRAW)|mfb(IF_RELOAD_AND_SHOOT));
GUN("longbow", 5, 400,c_yellow, WOOD, MNULL,
sk_archery, AT_ARROW,8, 4, 10, 0, 0, 12, 0, 6, 0, 1, 400, "\
A six-foot wooden bow that fires feathered arrows. This takes a fair amount\n\
of strength to draw. Arrows fired from this weapon have a good chance of\n\
remaining intact for re-use.",
-mfb(IF_STR10_DRAW));
+mfb(IF_STR10_DRAW)|mfb(IF_RELOAD_AND_SHOOT));
GUN("pipe rifle: .22", 0, 400,c_ltblue, IRON, WOOD,
sk_rifle, AT_22, 9, 13, 10, 2, -2, 15, 2, 6, 0, 1, 250, "\
View
6 iuse.cpp
@@ -782,6 +782,7 @@ void iuse::scissors(game *g, player *p, item *it, bool t)
count -= rng(0, 2);
if (dice(3, 3) > p->dex_cur)
count -= rng(1, 3);
+
if (count <= 0) {
g->add_msg("You clumsily cut the %s into useless ribbons.",
cut->tname().c_str());
@@ -1878,6 +1879,8 @@ void iuse::mp3(game *g, player *p, item *it, bool t)
{
if (it->charges == 0)
g->add_msg("The mp3 player's batteries are dead.");
+ else if (p->has_active_item(itm_mp3_on))
+ g->add_msg("You are already listening to an mp3 player!");
else {
g->add_msg("You put in the earbuds and start listening to music.");
it->make(g->itypes[itm_mp3_on]);
@@ -2159,7 +2162,7 @@ void iuse::artifact(game *g, player *p, item *it, bool t)
empty.push_back( point(x, y) );
}
}
- if (empty.empty() == 0 || roll <= 4)
+ if (empty.empty() || roll <= 4)
g->add_msg("Flies buzz around you.");
else if (roll <= 7) {
g->add_msg("Giant flies appear!");
@@ -2176,6 +2179,7 @@ void iuse::artifact(game *g, player *p, item *it, bool t)
}
if (bug != mon_null) {
monster spawned(g->mtypes[bug]);
+ spawned.friendly = -1;
for (int i = 0; i < num && !empty.empty(); i++) {
int index = rng(0, empty.size() - 1);
point spawnp = empty[index];
View
7 line.cpp
@@ -25,13 +25,6 @@ std::vector <point> line_to(int x1, int y1, int x2, int y2, int t) {
xmax += abs(dx);
ymax += abs(dy);
-/*
- if (x1 < 0 - SEEX * 3 || x1 > SEEX * 6 ||
- y1 < 0 - SEEY * 3 || y1 > SEEY * 6 ||
- x2 < 0 - SEEX * 3 || x2 > SEEX * 6 ||
- y2 < 0 - SEEY * 3 || y2 > SEEY * 6 )
- debugmsg("there's gonna be trouble!");
-*/
if (ax == ay) {
do {
cur.y += sy;
View
222 map.cpp
@@ -31,10 +31,12 @@ map::map(std::vector<itype*> *itptr, std::vector<itype_id> (*miptr)[num_itloc],
itypes = itptr;
mapitems = miptr;
traps = trptr;
- for (int i = 0; i < SEEX * 3; i++) {
- for (int j = 0; j < SEEY * 3; j++) {
- tr_at(i, j) = tr_null;
- radiation(i, j) = 0;
+ for (int n = 0; n < MAPSIZE * MAPSIZE; n++) {
+ for (int x = 0; x < SEEX; x++) {
+ for (int y = 0; y < SEEY; y++) {
+ grid[n].trp[x][y] = tr_null;
+ grid[n].rad[x][y] = 0;
+ }
}
}
}
@@ -45,15 +47,18 @@ map::~map()
ter_id& map::ter(int x, int y)
{
- // 0 1 2
- // 3 4 5
- // 6 7 8
if (!inbounds(x, y)) {
nulter = t_null;
return nulter; // Out-of-bounds - null terrain
}
+/*
int nonant;
cast_to_nonant(x, y, nonant);
+*/
+ int nonant = int(x / SEEX) + int(y / SEEY) * MAPSIZE;
+
+ x %= SEEX;
+ y %= SEEY;
return grid[nonant].ter[x][y];
}
@@ -80,8 +85,6 @@ std::string map::features(int x, int y)
int map::move_cost(int x, int y)
{
- if (!inbounds(x, y))
- return 2; // Out of bounds terrain is assumed to be floor, mostly
return terlist[ter(x, y)].movecost;
}
@@ -90,8 +93,6 @@ 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]);
@@ -99,8 +100,6 @@ bool map::trans(int x, int y)
bool map::has_flag(t_flag flag, int x, int y)
{
- if (!inbounds(x, y))
- return (flag == diggable ? true : false); // For the sake of worms, etc.
return terlist[ter(x, y)].flags & mfb(flag);
}
@@ -145,8 +144,8 @@ bool map::flammable_items_at(int x, int y)
point map::random_outdoor_tile()
{
std::vector<point> options;
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEX * 3; y++) {
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++) {
if (is_outside(x, y))
options.push_back(point(x, y));
}
@@ -644,8 +643,8 @@ void map::translate(ter_id from, ter_id to)
terlist[from].name.c_str());
return;
}
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEY * 3; y++) {
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++) {
if (ter(x, y) == from)
ter(x, y) = to;
}
@@ -673,8 +672,14 @@ int& map::radiation(int x, int y)
nulrad = 0;
return nulrad;
}
+/*
int nonant;
cast_to_nonant(x, y, nonant);
+*/
+ int nonant = int(x / SEEX) + int(y / SEEY) * MAPSIZE;
+
+ x %= SEEX;
+ y %= SEEY;
return grid[nonant].rad[x][y];
}
@@ -684,8 +689,14 @@ std::vector<item>& map::i_at(int x, int y)
nulitems.clear();
return nulitems;
}
+/*
int nonant;
cast_to_nonant(x, y, nonant);
+*/
+ int nonant = int(x / SEEX) + int(y / SEEY) * MAPSIZE;
+
+ x %= SEEX;
+ y %= SEEY;
return grid[nonant].itm[x][y];
}
@@ -719,8 +730,8 @@ void map::i_clear(int x, int y)
point map::find_item(item *it)
{
point ret;
- for (ret.x = 0; ret.x < SEEX * 3; ret.x++) {
- for (ret.y = 0; ret.y < SEEY * 3; ret.y++) {
+ for (ret.x = 0; ret.x < SEEX * MAPSIZE; ret.x++) {
+ for (ret.y = 0; ret.y < SEEY * MAPSIZE; ret.y++) {
for (int i = 0; i < i_at(ret.x, ret.y).size(); i++) {
if (it == &i_at(ret.x, ret.y)[i])
return ret;
@@ -771,8 +782,14 @@ void map::add_item(int x, int y, item new_item)
add_item(choice.x, choice.y, new_item);
return;
}
+/*
int nonant;
cast_to_nonant(x, y, nonant);
+*/
+ int nonant = int(x / SEEX) + int(y / SEEY) * MAPSIZE;
+
+ x %= SEEX;
+ y %= SEEY;
grid[nonant].itm[x][y].push_back(new_item);
}
@@ -780,8 +797,8 @@ void map::process_active_items(game *g)
{
it_tool* tmp;
iuse use;
- for (int i = 0; i < SEEX * 3; i++) {
- for (int j = 0; j < SEEY * 3; j++) {
+ for (int i = 0; i < SEEX * MAPSIZE; i++) {
+ for (int j = 0; j < SEEY * MAPSIZE; j++) {
for (int n = 0; n < i_at(i, j).size(); n++) {
if (i_at(i, j)[n].active) {
tmp = dynamic_cast<it_tool*>(i_at(i, j)[n].type);
@@ -890,8 +907,14 @@ trap_id& map::tr_at(int x, int y)
nultrap = tr_null;
return nultrap; // Out-of-bounds, return our null trap
}
+/*
int nonant;
cast_to_nonant(x, y, nonant);
+*/
+ int nonant = int(x / SEEX) + int(y / SEEY) * MAPSIZE;
+
+ x %= SEEX;
+ y %= SEEY;
if (x < 0 || x >= SEEX || y < 0 || y >= SEEY) {
debugmsg("tr_at contained bad x:y %d:%d", x, y);
nultrap = tr_null;
@@ -903,8 +926,14 @@ trap_id& map::tr_at(int x, int y)
void map::add_trap(int x, int y, trap_id t)
{
+/*
int nonant;
cast_to_nonant(x, y, nonant);
+*/
+ int nonant = int(x / SEEX) + int(y / SEEY) * MAPSIZE;
+
+ x %= SEEX;
+ y %= SEEY;
grid[nonant].trp[x][y] = t;
}
@@ -942,8 +971,14 @@ field& map::field_at(int x, int y)
nulfield = field();
return nulfield;
}
+/*
int nonant;
cast_to_nonant(x, y, nonant);
+*/
+ int nonant = int(x / SEEX) + int(y / SEEY) * MAPSIZE;
+
+ x %= SEEX;
+ y %= SEEY;
return grid[nonant].fld[x][y];
}
@@ -970,8 +1005,14 @@ computer* map::computer_at(int x, int y)
{
if (!inbounds(x, y))
return NULL;
+/*
int nonant;
cast_to_nonant(x, y, nonant);
+*/
+ int nonant = int(x / SEEX) + int(y / SEEY) * MAPSIZE;
+
+ x %= SEEX;
+ y %= SEEY;
if (grid[nonant].comp.name == "")
return NULL;
return &(grid[nonant].comp);
@@ -1170,12 +1211,12 @@ std::vector<point> map::route(int Fx, int Fy, int Tx, int Ty, bool bash)
tername(Fx, Fy).c_str(), Tx, Ty);
*/
std::vector<point> open;
- astar_list list[SEEX * 3][SEEY * 3];
- int score [SEEX * 3][SEEY * 3];
- int gscore [SEEX * 3][SEEY * 3];
- point parent [SEEX * 3][SEEY * 3];
- for (int x = 0; x < SEEX * 3; x++) {
- for (int y = 0; y < SEEY * 3; y++) {
+ astar_list list[SEEX * MAPSIZE][SEEY * MAPSIZE];
+ int score [SEEX * MAPSIZE][SEEY * MAPSIZE];
+ int gscore [SEEX * MAPSIZE][SEEY * MAPSIZE];
+ point parent [SEEX * MAPSIZE][SEEY * MAPSIZE];
+ for (int x = 0; x < SEEX * MAPSIZE; x++) {
+ for (int y = 0; y < SEEY * MAPSIZE; y++) {
list [x][y] = ASL_NONE; // Init to not being on any list
score [x][y] = 0; // No score!
gscore[x][y] = 0; // No score!
@@ -1257,16 +1298,16 @@ std::vector<point> map::route(int Fx, int Fy, int Tx, int Ty, bool bash)
void map::save(overmap *om, unsigned int turn, int x, int y)
{
- for (int gridx = 0; gridx < 3; gridx++) {
- for (int gridy = 0; gridy < 3; gridy++)
+ for (int gridx = 0; gridx < MAPSIZE; gridx++) {
+ for (int gridy = 0; gridy < MAPSIZE; gridy++)
saven(om, turn, x, y, gridx, gridy);
}
}
void map::load(game *g, int wx, int wy)
{
- for (int gridx = 0; gridx < 3; gridx++) {
- for (int gridy = 0; gridy < 3; gridy++) {
+ for (int gridx = 0; gridx < MAPSIZE; gridx++) {
+ for (int gridy = 0; gridy < MAPSIZE; gridy++) {
if (!loadn(g, wx, wy, gridx, gridy))
loadn(g, wx, wy, gridx, gridy);
}
@@ -1276,20 +1317,63 @@ void map::load(game *g, int wx, int wy)
void map::shift(game *g, int wx, int wy, int sx, int sy)
{
- // Shift the map sx submaps to the right and sy submaps down.
- // sx and sy should never be bigger than +/-1.
- // wx and wy are out position in the world, for saving/loading purposes.
- // 0 1 2
- // 3 4 5
- // 6 7 8
- for (int gridx = 0; gridx < 3; gridx++) {
- for (int gridy = 0; gridy < 3; gridy++)
- saven(&(g->cur_om), g->turn, wx, wy, gridx, gridy);
+// Special case of 0-shift; refresh the map
+ if (sx == 0 && sy == 0) {
+ for (int gridx = 0; gridx < MAPSIZE; gridx++) {
+ for (int gridy = 0; gridy < MAPSIZE; gridy++) {
+ if (!loadn(g, wx+sx, wy+sy, gridx, gridy))
+ loadn(g, wx+sx, wy+sy, gridx, gridy);
+ }
+ }
+ return;
}
- for (int gridx = 0; gridx < 3; gridx++) {
- for (int gridy = 0; gridy < 3; gridy++) {
- if (!loadn(g, wx+sx, wy+sy, gridx, gridy))
- loadn(g, wx+sx, wy+sy, gridx, gridy);
+// Shift the map sx submaps to the right and sy submaps down.
+// sx and sy should never be bigger than +/-1.
+// wx and wy are our position in the world, for saving/loading purposes.
+
+ if (sx >= 0) {
+ for (int gridx = 0; gridx < MAPSIZE; gridx++) {
+ if (sy >= 0) {
+ for (int gridy = 0; gridy < MAPSIZE; gridy++) {
+ if (gridx < sx || gridy < sy)
+ saven(&(g->cur_om), g->turn, wx, wy, gridx, gridy);
+ if (gridx + sx < MAPSIZE && gridy + sy < MAPSIZE)
+ copy_grid(gridx + gridy * MAPSIZE, gridx + sx + (gridy + sy) * MAPSIZE);
+ else if (!loadn(g, wx + sx, wy + sy, gridx, gridy))
+ loadn(g, wx + sx, wy + sy, gridx, gridy);
+ }
+ } else { // sy < 0; work through it backwards
+ for (int gridy = MAPSIZE - 1; gridy >= 0; gridy--) {
+ if (gridx < sx || gridy - MAPSIZE >= sy)
+ saven(&(g->cur_om), g->turn, wx, wy, gridx, gridy);
+ if (gridx + sx < MAPSIZE && gridy + sy >= 0)
+ copy_grid(gridx + gridy * MAPSIZE, gridx + sx + (gridy + sy) * MAPSIZE);
+ else if (!loadn(g, wx + sx, wy + sy, gridx, gridy))
+ loadn(g, wx + sx, wy + sy, gridx, gridy);
+ }
+ }
+ }
+ } else { // sx < 0; work through it backwards
+ for (int gridx = MAPSIZE - 1; gridx >= 0; gridx--) {
+ if (sy >= 0) {
+ for (int gridy = 0; gridy < MAPSIZE; gridy++) {
+ if (gridx - MAPSIZE >= sx || gridy < sy)
+ saven(&(g->cur_om), g->turn, wx, wy, gridx, gridy);
+ if (gridx + sx >= 0 && gridy + sy < MAPSIZE)
+ copy_grid(gridx + gridy * MAPSIZE, gridx + sx + (gridy + sy) * MAPSIZE);
+ else if (!loadn(g, wx + sx, wy + sy, gridx, gridy))
+ loadn(g, wx + sx, wy + sy, gridx, gridy);
+ }
+ } else { // sy < 0; work through it backwards
+ for (int gridy = MAPSIZE - 1; gridy >= 0; gridy--) {
+ if (gridx - MAPSIZE >= sx || gridy - MAPSIZE >= sy)
+ saven(&(g->cur_om), g->turn, wx, wy, gridx, gridy);
+ if (gridx + sx >= 0 && gridy + sy >= 0)
+ copy_grid(gridx + gridy * MAPSIZE, gridx + sx + (gridy + sy) * MAPSIZE);
+ else if (!loadn(g, wx + sx, wy + sy, gridx, gridy))
+ loadn(g, wx + sx, wy + sy, gridx, gridy);
+ }
+ }
}
}
}
@@ -1303,7 +1387,7 @@ void map::shift(game *g, int wx, int wy, int sx, int sy)
void map::saven(overmap *om, unsigned int turn, int worldx, int worldy,
int gridx, int gridy)
{
- int n = gridx + gridy * 3;
+ int n = gridx + gridy * MAPSIZE;
// Open appropriate file.
char buff[32];
sprintf(buff, "save/m.%d.%d.%d", om->posx * OMAPX * 2 + worldx + gridx,
@@ -1385,8 +1469,8 @@ bool map::loadn(game *g, int worldx, int worldy, int gridx, int gridy)
{
char fname[32];
char line[SEEX];
- char ch;
- int gridn = gridx + gridy * 3;
+ char ch = 0;
+ int gridn = gridx + gridy * MAPSIZE;
int itx, ity, t, d, a, old_turn;
bool fields_here = false;
item it_tmp;
@@ -1486,11 +1570,33 @@ bool map::loadn(game *g, int worldx, int worldy, int gridx, int gridy)
return true;
}
+void map::copy_grid(int to, int from)
+{
+ if (from < 0 || from >= MAPSIZE * MAPSIZE ||
+ to < 0 || to >= MAPSIZE * MAPSIZE ) {
+ debugmsg("Attempted to copy grid %d to grid %d", from, to);
+ return;
+ }
+
+ for (int x = 0; x < SEEX; x++) {
+ for (int y = 0; y < SEEY; y++) {
+ grid[to].ter[x][y] = grid[from].ter[x][y];
+ grid[to].itm[x][y] = grid[from].itm[x][y];
+ grid[to].trp[x][y] = grid[from].trp[x][y];
+ grid[to].fld[x][y] = grid[from].fld[x][y];
+ grid[to].rad[x][y] = grid[from].rad[x][y];
+ }
+ }
+
+ grid[to].spawns = grid[from].spawns;
+ grid[to].comp = grid[from].comp;
+}
+
void map::spawn_monsters(game *g)
{
- for (int gx = 0; gx < 3; gx++) {
- for (int gy = 0; gy < 3; gy++) {
- int n = gx + gy * 3;
+ for (int gx = 0; gx < MAPSIZE; gx++) {
+ for (int gy = 0; gy < MAPSIZE; gy++) {
+ int n = gx + gy * MAPSIZE;
for (int i = 0; i < grid[n].spawns.size(); i++) {
for (int j = 0; j < grid[n].spawns[i].count; j++) {
int tries = 0;
@@ -1529,28 +1635,22 @@ void map::spawn_monsters(game *g)
bool inbounds(int x, int y)
{
- if (x < 0 || x >= SEEX * 3 || y < 0 || y >= SEEY * 3)
+ if (x < 0 || x >= SEEX * MAPSIZE || y < 0 || y >= SEEY * MAPSIZE)
return false;
return true;
}
void cast_to_nonant(int &x, int &y, int &n)
{
- if (x < 0 || x >= SEEX * 3 || y <