diff --git a/rsrc/dialogs/edit-terrain.xml b/rsrc/dialogs/edit-terrain.xml
index fceb3fc5..9e93ba8c 100644
--- a/rsrc/dialogs/edit-terrain.xml
+++ b/rsrc/dialogs/edit-terrain.xml
@@ -67,11 +67,11 @@
Call special when step
Reserved
Is a container
- Waterfall
- Conveyor belt
- Reserved
- Reserved
- Reserved
+ Wilderness (Caves)
+ Wilderness (Surface)
+ Waterfall (Caves)
+ Waterfall (Surface)
+ Conveyor Belt
Blocked to monsters
Town entrance
Change when used
diff --git a/rsrc/strings/ter-flag1.txt b/rsrc/strings/ter-flag1.txt
index 15331ea7..9c831a13 100644
--- a/rsrc/strings/ter-flag1.txt
+++ b/rsrc/strings/ter-flag1.txt
@@ -13,11 +13,11 @@ Unused
Number of special to call
Unused
Unused
+Unused
+Unused
+Direction
Direction
Direction
-Unused
-Unused
-Unused
Unused
Terrain type if hidden
Terrain to change to when used
diff --git a/src/boe.actions.cpp b/src/boe.actions.cpp
index 5f00bbf7..20d83301 100644
--- a/src/boe.actions.cpp
+++ b/src/boe.actions.cpp
@@ -2492,32 +2492,27 @@ void increase_age() {
}
void handle_hunting() {
- short i,pic;
- ter_num_t ter;
-
if(!is_out())
return;
+ if(flying())
+ return;
+ ter_num_t ter = univ.out[univ.party.p_loc.x][univ.party.p_loc.y];
+ if(!wilderness_lore_present(ter))
+ return;
+ eTrait trait = eTrait::PACIFIST;
+ if(univ.scenario.ter_types[ter].special == eTerSpec::WILDERNESS_CAVE)
+ trait = eTrait::CAVE_LORE;
+ else if(univ.scenario.ter_types[ter].special == eTerSpec::WILDERNESS_SURFACE)
+ trait = eTrait::WOODSMAN;
+ if(trait == eTrait::PACIFIST)
+ return;
- // TODO: Resupport this!
- ter = univ.out[univ.party.p_loc.x][univ.party.p_loc.y];
- pic = univ.scenario.ter_types[ter].picture;
- for(i = 0; i < 6; i++)
- if(univ.party[i].main_status == eMainStatus::ALIVE && univ.party[i].traits[eTrait::CAVE_LORE] && get_ran(1,0,12) == 5
- && (((pic >= 0) && (pic <= 1)) || ((pic >= 70) && (pic <= 76))) ) {
+ for(int i = 0; i < 6; i++)
+ if(univ.party[i].is_alive() && univ.party[i].traits[trait] && get_ran(1,0,12) == 5) {
univ.party.food += get_ran(2,1,6);
add_string_to_buf(univ.party[i].name + "hunts.");
put_pc_screen();
}
- for(i = 0; i < 6; i++)
- if(
- univ.party[i].main_status == eMainStatus::ALIVE && univ.party[i].traits[eTrait::WOODSMAN] && get_ran(1,0,12) == 5
- && (((pic >= 2) && (pic <= 4)) || ((pic >= 79) && (pic <= 84)))) {
- univ.party.food += get_ran(2,1,6);
- add_string_to_buf(univ.party[i].name + "hunts.");
- put_pc_screen();
- }
-
-
}
void switch_pc(short which) {
@@ -2676,10 +2671,12 @@ static eDirection find_waterfall(short x, short y, short mode){
bool to_dir[8];
for(eDirection i = DIR_N; i < DIR_HERE; i++){
if(mode == 0){
- to_dir[i] = univ.scenario.ter_types[univ.town->terrain(x + dir_x_dif[i],y + dir_y_dif[i])].special == eTerSpec::WATERFALL;
+ eTerSpec spec = univ.scenario.ter_types[univ.town->terrain(x + dir_x_dif[i],y + dir_y_dif[i])].special;
+ to_dir[i] = spec == eTerSpec::WATERFALL_CAVE || spec == eTerSpec::WATERFALL_SURFACE;
if(univ.scenario.ter_types[univ.town->terrain(x + dir_x_dif[i],y + dir_y_dif[i])].flag1.u != i) to_dir[i] = false;
}else{
- to_dir[i] = univ.scenario.ter_types[univ.out[x + dir_x_dif[i]][y + dir_y_dif[i]]].special == eTerSpec::WATERFALL;
+ eTerSpec spec = univ.scenario.ter_types[univ.out[x + dir_x_dif[i]][y + dir_y_dif[i]]].special;
+ to_dir[i] = spec == eTerSpec::WATERFALL_CAVE || spec == eTerSpec::WATERFALL_SURFACE;
if(univ.scenario.ter_types[univ.out[x + dir_x_dif[i]][y + dir_y_dif[i]]].flag1.u != i) to_dir[i] = false;
}
}
@@ -2726,7 +2723,7 @@ static void run_waterfalls(short mode){ // mode 0 - town, 1 - outdoors
}
draw_terrain();
print_buf();
- if((wilderness_lore_present() > 0) && (get_ran(1,0,1) == 0))
+ if(wilderness_lore_present(coord_to_ter(x - dir_x_dif[dir], y - dir_y_dif[dir]) > 0) && get_ran(1,0,1) == 0)
add_string_to_buf(" (No supplies lost.)");
else if(univ.party.food > 1800){
add_string_to_buf(" (Many supplies lost.)");
diff --git a/src/boe.monster.cpp b/src/boe.monster.cpp
index 20a9ea51..acfd4dcd 100644
--- a/src/boe.monster.cpp
+++ b/src/boe.monster.cpp
@@ -1032,7 +1032,8 @@ bool monst_check_special_terrain(location where_check,short mode,short which_mon
case eTerSpec::BLOCKED_TO_MONSTERS:
case eTerSpec::TOWN_ENTRANCE:
- case eTerSpec::WATERFALL:
+ case eTerSpec::WATERFALL_CAVE:
+ case eTerSpec::WATERFALL_SURFACE:
can_enter = false;
break;
diff --git a/src/boe.party.cpp b/src/boe.party.cpp
index d1479a10..e25f28df 100644
--- a/src/boe.party.cpp
+++ b/src/boe.party.cpp
@@ -2806,11 +2806,13 @@ short race_present(eRace which_race) {
return ret;
}
-short wilderness_lore_present() {
- // TODO: Add contional statement to choose between these
- // (Probably requires something added to terrain types to specify that it's cave/surface wilderness.)
- return trait_present(eTrait::CAVE_LORE); // Cave Lore
- return trait_present(eTrait::WOODSMAN); // Woodsman
+short wilderness_lore_present(ter_num_t ter_type) {
+ cTerrain& ter = univ.scenario.ter_types[ter_type];
+ if(ter.special == eTerSpec::WILDERNESS_CAVE || ter.special == eTerSpec::WATERFALL_CAVE)
+ return trait_present(eTrait::CAVE_LORE);
+ else if(ter.special == eTerSpec::WILDERNESS_SURFACE || ter.special == eTerSpec::WATERFALL_SURFACE)
+ return trait_present(eTrait::WOODSMAN);
+ return false;
}
short party_size(bool only_living) {
diff --git a/src/boe.party.h b/src/boe.party.h
index bc154d0c..6e470dca 100644
--- a/src/boe.party.h
+++ b/src/boe.party.h
@@ -43,7 +43,7 @@ void set_pc_moves();
void take_ap(short num);
short trait_present(eTrait which_trait);
short race_present(eRace which_race);
-short wilderness_lore_present();
+short wilderness_lore_present(ter_num_t ter);
void print_spell_cast(eSpell spell,eSkill which);
void put_party_in_scen(std::string scen_name);
short party_size(bool only_living);
diff --git a/src/boe.specials.cpp b/src/boe.specials.cpp
index 00576846..e4dcab60 100644
--- a/src/boe.specials.cpp
+++ b/src/boe.specials.cpp
@@ -445,6 +445,10 @@ bool check_special_terrain(location where_check,eSpecCtx mode,cPlayer& which_pc,
else bash_door(where_check,door_pc);
}
break;
+ case eTerSpec::WILDERNESS_CAVE:
+ case eTerSpec::WILDERNESS_SURFACE:
+ handle_hunting();
+ break;
}
// Action may change terrain, so update what's been seen
diff --git a/src/classes/simpletypes.h b/src/classes/simpletypes.h
index 8c0da6ad..ea1a01d2 100644
--- a/src/classes/simpletypes.h
+++ b/src/classes/simpletypes.h
@@ -220,11 +220,11 @@ enum class eTerSpec {
CALL_SPECIAL = 12, // formerly "call local special"
UNUSED3 = 13, // formerly "call scenario special"
IS_A_CONTAINER = 14,
- WATERFALL = 15,
- CONVEYOR = 16, // formerly "conveyor north"
- UNUSED4 = 17, // formerly "conveyor east"
- UNUSED5 = 18, // formerly "conveyor south"
- UNUSED6 = 19, // formerly "conveyor west"
+ WILDERNESS_CAVE = 15,
+ WILDERNESS_SURFACE = 16, // formerly "conveyor north"
+ WATERFALL_CAVE = 17, // formerly "conveyor east"
+ WATERFALL_SURFACE = 18, // formerly "conveyor south"
+ CONVEYOR = 19, // formerly "conveyor west"
BLOCKED_TO_MONSTERS = 20,
TOWN_ENTRANCE = 21,
CHANGE_WHEN_USED = 22,
diff --git a/src/classes/terrain.cpp b/src/classes/terrain.cpp
index aac4d350..d0dca6bd 100644
--- a/src/classes/terrain.cpp
+++ b/src/classes/terrain.cpp
@@ -208,7 +208,7 @@ void cTerrain::append(legacy::terrain_type_type& old){
flag3.u = 0;
break;
case 15:
- special = eTerSpec::WATERFALL;
+ special = eTerSpec::WATERFALL_CAVE;
flag1.u = DIR_S;
flag3.u = 0;
break;
diff --git a/src/scenedit/scen.graphics.cpp b/src/scenedit/scen.graphics.cpp
index 240ce057..7eb45d1a 100644
--- a/src/scenedit/scen.graphics.cpp
+++ b/src/scenedit/scen.graphics.cpp
@@ -230,7 +230,8 @@ static short get_small_icon(ter_num_t ter){
case eTerSpec::IS_A_CONTAINER:
icon = 36;
break;
- case eTerSpec::WATERFALL:
+ case eTerSpec::WATERFALL_CAVE:
+ case eTerSpec::WATERFALL_SURFACE:
icon = -1;
break;
case eTerSpec::CONVEYOR: