From 01d113b20234f196742587563d5cc264c37148ad Mon Sep 17 00:00:00 2001 From: OzoneH3 Date: Fri, 1 Mar 2013 11:57:37 +0100 Subject: [PATCH 01/14] Added Option (safemodeproximity) for safemode, at what distance to hostiles safemode should kick in Also added an option after how many turns autosafemode reenables safemode if there are no hostiles in safemodeproximity range --- game.cpp | 14 +++++++++----- options.cpp | 26 ++++++++++++++++++++++++-- options.h | 2 ++ 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/game.cpp b/game.cpp index 7bd6d4cc32850..3f4450cb849cf 100644 --- a/game.cpp +++ b/game.cpp @@ -3335,6 +3335,7 @@ void game::mon_info() werase(w_moninfo); int buff; int newseen = 0; + const int iProxyDist = (OPTIONS[OPT_SAFEMODEPROXIMITY] <= 0) ? 60 : OPTIONS[OPT_SAFEMODEPROXIMITY]; // 7 0 1 unique_types uses these indices; // 6 8 2 0-7 are provide by direction_from() // 5 4 3 8 is used for local monsters (for when we explain them below) @@ -3350,7 +3351,9 @@ void game::mon_info() bool mon_dangerous = false; if (z[i].attitude(&u) == MATT_ATTACK || z[i].attitude(&u) == MATT_FOLLOW) { mon_dangerous = true; - newseen++; + + if (rl_dist(u.posx, u.posy, z[i].posx, z[i].posy) <= iProxyDist) + newseen++; } dir_to_mon = direction_from(u.posx + u.view_offset_x, u.posy + u.view_offset_y, @@ -3368,7 +3371,9 @@ void game::mon_info() for (int i = 0; i < active_npc.size(); i++) { if (u_see(active_npc[i].posx, active_npc[i].posy, buff)) { // TODO: NPC invis if (active_npc[i].attitude == NPCATT_KILL) - newseen++; + if (rl_dist(u.posx, u.posy, active_npc[i].posx, active_npc[i].posy) <= iProxyDist) + newseen++; + point npcp(active_npc[i].posx, active_npc[i].posy); dir_to_npc = direction_from ( u.posx + u.view_offset_x, u.posy + u.view_offset_y, npcp.x, npcp.y ); @@ -3387,13 +3392,12 @@ void game::mon_info() turnssincelastmon = 0; if (run_mode == 1) run_mode = 2; // Stop movement! - } else if (autosafemode) { // Auto-safemode + } else if (autosafemode && newseen == 0) { // Auto-safemode turnssincelastmon++; - if(turnssincelastmon >= 50 && run_mode == 0) + if(turnssincelastmon >= OPTIONS[OPT_AUTOSAFEMODETURNS] && run_mode == 0) run_mode = 1; } - mostseen = newseen; nc_color tmpcol; // Print the direction headings diff --git a/options.cpp b/options.cpp index 6ded462e25df5..4241dcc784d35 100644 --- a/options.cpp +++ b/options.cpp @@ -72,8 +72,12 @@ option_key lookup_option_key(std::string id) return OPT_SNAP_TO_TARGET; if (id == "safemode") return OPT_SAFEMODE; + if (id == "safemodeproximity") + return OPT_SAFEMODEPROXIMITY; if (id == "autosafemode") return OPT_AUTOSAFEMODE; + if (id == "autosafemodeturns") + return OPT_AUTOSAFEMODETURNS; if (id == "autosave") return OPT_AUTOSAVE; if (id == "gradual_night_light") @@ -105,7 +109,9 @@ std::string option_string(option_key key) case OPT_24_HOUR: return "24_hour"; case OPT_SNAP_TO_TARGET: return "snap_to_target"; case OPT_SAFEMODE: return "safemode"; + case OPT_SAFEMODEPROXIMITY: return "safemodeproximity"; case OPT_AUTOSAFEMODE: return "autosafemode"; + case OPT_AUTOSAFEMODETURNS: return "autosafemodeturns"; case OPT_AUTOSAVE: return "autosave"; case OPT_GRADUAL_NIGHT_LIGHT: return "gradual_night_light"; case OPT_QUERY_DISASSEMBLE: return "query_disassemble"; @@ -130,7 +136,9 @@ std::string option_desc(option_key key) case OPT_24_HOUR: return "If true, use military time, not AM/PM"; case OPT_SNAP_TO_TARGET: return "If true, automatically follow the\ncrosshair when firing/throwing"; case OPT_SAFEMODE: return "If true, safemode will be on after\nstarting a new game or loading"; + case OPT_SAFEMODEPROXIMITY: return "If safemode is enabled,\ndistance to hostiles when safemode\nshould show a warning (0=Viewdistance)"; case OPT_AUTOSAFEMODE: return "If true, auto-safemode will be on\nafter starting a new game or loading"; + case OPT_AUTOSAFEMODETURNS: return "Number of turns after safemode\nis reenabled if no hostiles are\nin safemodeproximity distance"; case OPT_AUTOSAVE: return "If true, game will periodically\nsave the map"; case OPT_GRADUAL_NIGHT_LIGHT: return "If true will add nice gradual-lighting\n(should only make a difference @night)"; case OPT_QUERY_DISASSEMBLE: return "If true, will query before disassembling\nitems"; @@ -155,7 +163,9 @@ std::string option_name(option_key key) case OPT_24_HOUR: return "24 Hour Time"; case OPT_SNAP_TO_TARGET: return "Snap to Target"; case OPT_SAFEMODE: return "Safemode on by default"; + case OPT_SAFEMODEPROXIMITY: return "Safemode proximity distance"; case OPT_AUTOSAFEMODE: return "Auto-Safemode on by default"; + case OPT_AUTOSAFEMODETURNS: return "Turns to reenable safemode"; case OPT_AUTOSAVE: return "Periodically Autosave"; case OPT_GRADUAL_NIGHT_LIGHT: return "Gradual night light"; case OPT_QUERY_DISASSEMBLE: return "Query on disassembly"; @@ -173,6 +183,8 @@ std::string option_name(option_key key) bool option_is_bool(option_key id) { switch (id) { + case OPT_SAFEMODEPROXIMITY: + case OPT_AUTOSAFEMODETURNS: case OPT_SKILL_RUST: case OPT_DROP_EMPTY: case OPT_DELETE_WORLD: @@ -195,6 +207,12 @@ char option_max_options(option_key id) else switch (id) { + case OPT_SAFEMODEPROXIMITY: + ret = 61; + break; + case OPT_AUTOSAFEMODETURNS: + ret = 51; + break; case OPT_INITIAL_POINTS: ret = 25; break; @@ -205,8 +223,8 @@ char option_max_options(option_key id) break; case OPT_VIEWPORT_X: case OPT_VIEWPORT_Y: - ret = 61; // TODO Set up min/max values so weird numbers don't have to be used. - break; + ret = 61; // TODO Set up min/max values so weird numbers don't have to be used. + break; default: ret = 2; break; @@ -236,8 +254,12 @@ no_bright_backgrounds F\n\ snap_to_target F\n\ # If true, safemode will be on after starting a new game or loading\n\ safemode T\n\ +# If safemode is enabled, distance to hostiles when safemode should show a warning (0=Viewdistance)\n\ +safemodeproximity 0\n\ # If true, auto-safemode will be on after starting a new game or loading\n\ autosafemode F\n\ +# Number of turns after safemode is reenabled when no zombies are in safemodeproximity distance\n\ +autosafemodeturns 50\n\ # If true, game will periodically save the map\n\ autosave F\n\ # If true will add nice gradual-lighting (should only make a difference @night)\n\ diff --git a/options.h b/options.h index aa9f6a12d8a46..6e6d7b91c5a47 100644 --- a/options.h +++ b/options.h @@ -12,7 +12,9 @@ OPT_NO_CBLINK, // No bright backgrounds OPT_24_HOUR, // 24 hour time OPT_SNAP_TO_TARGET, // game::firing snaps to target OPT_SAFEMODE, // Safemode on by default? +OPT_SAFEMODEPROXIMITY, //Range after which safemode kicks in OPT_AUTOSAFEMODE, // Autosafemode on by default? +OPT_AUTOSAFEMODETURNS, //Number of turns untill safemode kicks back in OPT_AUTOSAVE, // Automatically save the game on intervals. OPT_GRADUAL_NIGHT_LIGHT, // be so cool at night :) OPT_QUERY_DISASSEMBLE, // Query before disassembling items From 1f0c27ff6f07c1ff37a62c233b4402962140057e Mon Sep 17 00:00:00 2001 From: OzoneH3 Date: Fri, 1 Mar 2013 12:04:50 +0100 Subject: [PATCH 02/14] Fix: Show new skill percentage when reading a book --- game.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/game.cpp b/game.cpp index 3f4450cb849cf..abbc7979c85bb 100644 --- a/game.cpp +++ b/game.cpp @@ -991,7 +991,6 @@ void game::process_activity() } if (u.skillLevel(reading->type) < reading->level) { - add_msg("You learn a little about %s! (%d%%%%)", reading->type->name().c_str(), u.skillLevel(reading->type).exercise()); int min_ex = reading->time / 10 + u.int_cur / 4, max_ex = reading->time / 5 + u.int_cur / 2 - u.skillLevel(reading->type).level(); if (min_ex < 1) @@ -1004,6 +1003,8 @@ void game::process_activity() int originalSkillLevel = u.skillLevel(reading->type).level(); u.skillLevel(reading->type).readBook(min_ex, max_ex, reading->level); + add_msg("You learn a little about %s! (%d%%%%)", reading->type->name().c_str(), u.skillLevel(reading->type).exercise()); + if (u.skillLevel(reading->type) > originalSkillLevel) add_msg("You increase %s to level %d.", reading->type->name().c_str(), From 41b6f12f891bdb54fdaca615f77b4feba6cf765a Mon Sep 17 00:00:00 2001 From: OzoneH3 Date: Fri, 1 Mar 2013 12:47:01 +0100 Subject: [PATCH 03/14] If Ausosafemode is on, color SAFE green if no hostiles are in proximity range, otherwise color it red Added progressbar like coloring of SAFE while autosafemode is powering up. --- game.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/game.cpp b/game.cpp index abbc7979c85bb..1209c0c66576f 100644 --- a/game.cpp +++ b/game.cpp @@ -2816,8 +2816,13 @@ void game::draw() mvwprintz(w_status, 0, 41, c_white, "%s, day %d", season_name[turn.season].c_str(), turn.day + 1); - if (run_mode != 0) - mvwprintz(w_status, 2, 51, c_red, "SAFE"); + if (run_mode != 0 || autosafemode != 0) { + int iPercent = ((turnssincelastmon*100)/OPTIONS[OPT_AUTOSAFEMODETURNS]); + mvwprintz(w_status, 2, 51, (run_mode == 0) ? ((iPercent >= 25) ? c_green : c_red): c_green, "S"); + wprintz(w_status, (run_mode == 0) ? ((iPercent >= 50) ? c_green : c_red): c_green, "A"); + wprintz(w_status, (run_mode == 0) ? ((iPercent >= 75) ? c_green : c_red): c_green, "F"); + wprintz(w_status, (run_mode == 0) ? ((iPercent == 100) ? c_green : c_red): c_green, "E"); + } wrefresh(w_status); // Draw messages write_msg(); From 4864d3064b93de10479db6d35506464f8708bb08 Mon Sep 17 00:00:00 2001 From: OzoneH3 Date: Fri, 1 Mar 2013 13:24:05 +0100 Subject: [PATCH 04/14] Added normal 24h time display to time options --- calendar.cpp | 9 ++++++--- options.cpp | 8 ++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/calendar.cpp b/calendar.cpp index 3b8d8e5e9d01f..da4b719f368ef 100644 --- a/calendar.cpp +++ b/calendar.cpp @@ -355,12 +355,15 @@ std::string calendar::print_time(bool twentyfour) ret << "0"; ret << minute; } else { - if (OPTIONS[OPT_24_HOUR]) { + if (OPTIONS[OPT_24_HOUR] == 1) { int hours = hour % 24; if (hours < 10) ret << "0"; ret << hours; - } else { + } else if (OPTIONS[OPT_24_HOUR] == 2) { + int hours = hour % 24; + ret << hours << ":"; + }else { int hours = hour % 12; if (hours == 0) hours = 12; @@ -369,7 +372,7 @@ std::string calendar::print_time(bool twentyfour) if (minute < 10) ret << "0"; ret << minute; - if (!OPTIONS[OPT_24_HOUR]) { + if (OPTIONS[OPT_24_HOUR] == 0) { if (hour < 12) ret << " AM"; else diff --git a/options.cpp b/options.cpp index 4241dcc784d35..52539657ad21d 100644 --- a/options.cpp +++ b/options.cpp @@ -183,6 +183,7 @@ std::string option_name(option_key key) bool option_is_bool(option_key id) { switch (id) { + case OPT_24_HOUR: case OPT_SAFEMODEPROXIMITY: case OPT_AUTOSAFEMODETURNS: case OPT_SKILL_RUST: @@ -207,6 +208,9 @@ char option_max_options(option_key id) else switch (id) { + case OPT_24_HOUR: + ret = 3; + break; case OPT_SAFEMODEPROXIMITY: ret = 61; break; @@ -248,8 +252,8 @@ use_metric_system F\n\ force_capital_yn T\n\ # If true, bright backgrounds are not used--some consoles are not compatible\n\ no_bright_backgrounds F\n\ -# If true, use military time, not AM/PM\n\ -24_hour F\n\ +# 12h/24h Time: 0 = AM/PM, 1 = 24h military, 2 = 24h normal\n\ +24_hour 0\n\ # If true, automatically follow the crosshair when firing/throwing\n\ snap_to_target F\n\ # If true, safemode will be on after starting a new game or loading\n\ From 6d4b6b2ad53d40a0f2dd93663691576139958f1e Mon Sep 17 00:00:00 2001 From: OzoneH3 Date: Fri, 1 Mar 2013 13:41:49 +0100 Subject: [PATCH 05/14] Made the Help menu a bit more 80x25 friendly --- help.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/help.cpp b/help.cpp index c93275d77673e..7922b2288c34f 100644 --- a/help.cpp +++ b/help.cpp @@ -26,21 +26,14 @@ void game::help() Please press one of the following for help on that topic:\n\ Press q or ESC to return to the game.\n\ \n\ -a: Introduction\n\ -b: Movement\n\ -c: Viewing\n\ -d: Hunger, Thirst, and Sleep\n\ -e: Pain and Stimulants\n\ -f: Addiction\n\ -g: Morale and XP\n\ +a: Introduction i: Bionics\n\ +b: Movement j: Crafting\n\ +c: Viewing k: Traps\n\ +d: Hunger, Thirst, and Sleep l: Items overview\n\ +e: Pain and Stimulants m: Combat\n\ +f: Addiction n: Unarmed Styles\n\ +g: Morale and XP o: Survival tips\n\ h: Radioactivity and Mutation\n\ -i: Bionics\n\ -j: Crafting\n\ -k: Traps\n\ -l: Items overview\n\ -m: Combat\n\ -n: Unarmed Styles\n\ -o: Survival tips\n\ \n\ 1: List of all commands (you can change key commands here)\n\ 2: List of all options (you can change options here)\n\ @@ -335,6 +328,10 @@ Bashing damage is universally effective, but is capped by low strength.\n\ Cutting damage is a guaranteed increase in damage, but it may be reduced by\n\ a monster's natural armor.\n\ \n\ +Press any key for more..."); + getch(); + erase(); +mvprintz(0, 0, c_white, "\ To wield an item as a weapon, press 'w' then the proper letter. Pressing '-'\n\ in lieu of a letter will make you wield nothing. A wielded weapon will not\n\ contribute to your volume carried, so holding a large item in your hands may\n\ @@ -428,6 +425,10 @@ Irregular terrain, like forests, may help you lose monsters.\n\ Firearms are the easiest way to kill an enemy, but the sound will attract\n\ unwanted attention. Save the guns for emergencies, and melee when you can.\n\ \n\ +Press any key for more..."); + getch(); + erase(); +mvprintz(0, 0, c_white, "\ Try to keep your inventory as full as possible without being overloaded. You\n\ never know when you might need an item, most are good to sell, and you can\n\ easily drop unwanted items on the floor.\n\ From 9549305c8df7af978c5ab0bf599e0fa062cfca40 Mon Sep 17 00:00:00 2001 From: OzoneH3 Date: Fri, 1 Mar 2013 14:38:40 +0100 Subject: [PATCH 06/14] 12/24 hour time text update --- options.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/options.cpp b/options.cpp index 52539657ad21d..4a2742218d6a7 100644 --- a/options.cpp +++ b/options.cpp @@ -133,7 +133,7 @@ std::string option_desc(option_key key) case OPT_USE_METRIC_SYS: return "If true, use Km/h not mph"; case OPT_FORCE_YN: return "If true, y/n prompts are case-sensitive\nand y and n are not accepted"; case OPT_NO_CBLINK: return "If true, bright backgrounds are not\nused--some consoles are not compatible"; - case OPT_24_HOUR: return "If true, use military time, not AM/PM"; + case OPT_24_HOUR: return "12h/24h Time:\n0 - AM/PM\n1 - 24h military\n2 - 24h normal"; case OPT_SNAP_TO_TARGET: return "If true, automatically follow the\ncrosshair when firing/throwing"; case OPT_SAFEMODE: return "If true, safemode will be on after\nstarting a new game or loading"; case OPT_SAFEMODEPROXIMITY: return "If safemode is enabled,\ndistance to hostiles when safemode\nshould show a warning (0=Viewdistance)"; From 6f8a1ed478e8085f10404867d0c42b41de39f155 Mon Sep 17 00:00:00 2001 From: OzoneH3 Date: Fri, 1 Mar 2013 16:06:48 +0100 Subject: [PATCH 07/14] Fixed broken overmap Notes not being displayed and added custom note symbol with X:TEXT --- overmap.cpp | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/overmap.cpp b/overmap.cpp index d3889ed824971..1773dab305e18 100644 --- a/overmap.cpp +++ b/overmap.cpp @@ -615,7 +615,7 @@ void overmap::generate_sub(overmap* above) else if (above->ter(i, j) == ot_shelter) shelter_points.push_back( point(i, j) ); - + else if (above->ter(i, j) == ot_lmoe) lmoe_points.push_back( point(i, j) ); @@ -907,7 +907,8 @@ void overmap::draw(WINDOW *w, game *g, int &cursx, int &cursy, if (omx >= 0 && omx < OMAPX && omy >= 0 && omy < OMAPY) { // It's in-bounds cur_ter = ter(omx, omy); see = seen(omx, omy); - if (note_here == has_note(omx, omy)) + note_here = has_note(omx, omy); + if (note_here) note_text = note(omx, omy); for (unsigned int n = 0; n < npcs.size(); n++) { if ((npcs[n].mapx + 1) / 2 == omx && (npcs[n].mapy + 1) / 2 == omy) { @@ -926,12 +927,14 @@ void overmap::draw(WINDOW *w, game *g, int &cursx, int &cursy, omy += (omy < 0 ? OMAPY : 0 - OMAPY); cur_ter = diag.ter(omx, omy); see = diag.seen(omx, omy); - if ((note_here == diag.has_note(omx, omy))) + note_here = diag.has_note(omx, omy); + if (note_here) note_text = diag.note(omx, omy); } else { cur_ter = hori.ter(omx, omy); see = hori.seen(omx, omy); - if (note_here = hori.has_note(omx, omy)) + note_here = hori.has_note(omx, omy); + if (note_here) note_text = hori.note(omx, omy); } } else if (omx >= OMAPX) { @@ -940,25 +943,29 @@ void overmap::draw(WINDOW *w, game *g, int &cursx, int &cursy, omy += (omy < 0 ? OMAPY : 0 - OMAPY); cur_ter = diag.ter(omx, omy); see = diag.seen(omx, omy); - if (note_here == diag.has_note(omx, omy)) + note_here = diag.has_note(omx, omy); + if (note_here) note_text = diag.note(omx, omy); } else { cur_ter = hori.ter(omx, omy); see = hori.seen(omx, omy); - if ((note_here = hori.has_note(omx, omy))) + note_here = hori.has_note(omx, omy); + if (note_here) note_text = hori.note(omx, omy); } } else if (omy < 0) { omy += OMAPY; cur_ter = vert.ter(omx, omy); see = vert.seen(omx, omy); - if ((note_here = vert.has_note(omx, omy))) + note_here = vert.has_note(omx, omy); + if (note_here) note_text = vert.note(omx, omy); } else if (omy >= OMAPY) { omy -= OMAPY; cur_ter = vert.ter(omx, omy); see = vert.seen(omx, omy); - if ((note_here = vert.has_note(omx, omy))) + note_here = vert.has_note(omx, omy); + if (note_here) note_text = vert.note(omx, omy); } else debugmsg("No data loaded! omx: %d omy: %d", omx, omy); @@ -966,7 +973,10 @@ void overmap::draw(WINDOW *w, game *g, int &cursx, int &cursy, if (see) { if (note_here && blink) { ter_color = c_yellow; - ter_sym = 'N'; + if (note_text[1] == ':') + ter_sym = note_text[0]; + else + ter_sym = 'N'; } else if (omx == origx && omy == origy && blink) { ter_color = g->u.color(); ter_sym = '@'; @@ -1017,6 +1027,8 @@ void overmap::draw(WINDOW *w, game *g, int &cursx, int &cursy, } if (has_note(cursx, cursy)) { note_text = note(cursx, cursy); + if (note_text[1] == ':') + note_text = note_text.substr(2, note_text.size()); for (unsigned int i = 0; i < note_text.length(); i++) mvwputch(w, 1, i, c_white, LINE_OXOX); mvwputch(w, 1, note_text.length(), c_white, LINE_XOOX); @@ -1095,7 +1107,7 @@ point overmap::choose_point(game *g) ret = point(-1, -1); else if (ch == 'N') { timeout(-1); - add_note(cursx, cursy, string_input_popup("Enter note", 49)); // 49 char max + add_note(cursx, cursy, string_input_popup("Note: (X:TEXT for custom symbol)", 49, note(cursx, cursy))); // 49 char max timeout(BLINK_SPEED); } else if(ch == 'D'){ timeout(-1); From 2984403382e9d74c3ebe62453e002e70bc171129 Mon Sep 17 00:00:00 2001 From: OzoneH3 Date: Fri, 1 Mar 2013 22:38:43 +0100 Subject: [PATCH 08/14] Inventory, add menu to choose what to do with the selected item. Reload/Unload may follow, but its complicated ... --- game.cpp | 123 ++++++++++++++++++++++++++++++++++++++--------- game.h | 16 +++--- inventory_ui.cpp | 50 ++++++++----------- output.cpp | 56 +-------------------- 4 files changed, 130 insertions(+), 115 deletions(-) diff --git a/game.cpp b/game.cpp index 1209c0c66576f..974f239f65e52 100644 --- a/game.cpp +++ b/game.cpp @@ -1608,12 +1608,50 @@ input_ret game::get_input(int timeout_ms) case ACTION_INVENTORY: { bool has = false; - do { - char ch = inv(); - has = u.has_item(ch); - if (has) - full_screen_popup(u.i_at(ch).info(true).c_str()); - } while (has); + //do { + const std::string sSpaces = " "; + char chItem = inv(); + has = u.has_item(chItem); + if (has) { + std::string sItemName = u.i_at(chItem).tname(this); + int iMenu = menu(("Item: " + sItemName + sSpaces.substr(sItemName.size(), sSpaces.size())).c_str(), + "Examine", "Use/Read", "Eat", "Wear", "Wield", "Take off", "Drop", "Cancel", NULL); //"Unload", "Reload" + + switch(iMenu) { + case 1: + full_screen_popup(u.i_at(chItem).info(true).c_str()); + break; + case 2: + use_item(chItem); + break; + case 3: + eat(chItem); + break; + case 4: + wear(chItem); + break; + case 5: + wield(chItem); + break; + case 6: + takeoff(chItem); + break; + case 7: + drop(chItem); + break; + case 8: + //unload(chItem); + break; + case 9: + //reload(chItem); + break; + case 0: + break; + default: + break; + } + } + //} while (has); refresh_all(); } break; @@ -4412,9 +4450,14 @@ void game::smash() add_msg("There's nothing there!"); } -void game::use_item() +void game::use_item(char chInput) { - char ch = inv("Use item:"); + char ch; + if (chInput == '.') + ch = inv("Use item:"); + else + ch = chInput; + if (ch == KEY_ESCAPE) { add_msg("Never mind."); return; @@ -6271,9 +6314,22 @@ bool game::handle_liquid(item &liquid, bool from_ground, bool infinite) return true; } -void game::drop() +void game::drop(char chInput) { - std::vector dropped = multidrop(); + std::vector dropped; + + if (chInput == '.') + dropped = multidrop(); + else { + int index = u.inv.index_by_letter(chInput); + + if (index == -1) { + dropped.push_back(u.i_rem(chInput)); + } else { + dropped.push_back(u.inv.remove_item(index)); + } + } + if (dropped.size() == 0) { add_msg("Never mind."); return; @@ -6772,8 +6828,9 @@ void game::forage() } } -void game::eat() +void game::eat(char chInput) { + char ch; if (u.has_trait(PF_RUMINANT) && m.ter(u.posx, u.posy) == t_underbrush && query_yn("Eat underbrush?")) { u.moves -= 400; @@ -6782,11 +6839,16 @@ void game::eat() add_msg("You eat the underbrush."); return; } - char ch = inv_type("Consume item:", IC_COMESTIBLE); + if (chInput == '.') + ch = inv_type("Consume item:", IC_COMESTIBLE); + else + ch = chInput; + if (ch == KEY_ESCAPE) { add_msg("Never mind."); return; } + if (!u.has_item(ch)) { add_msg("You don't have item '%c'!", ch); return; @@ -6794,9 +6856,14 @@ void game::eat() u.eat(this, u.lookup_item(ch)); } -void game::wear() +void game::wear(char chInput) { - char ch = inv_type("Wear item:", IC_ARMOR); + char ch; + if (chInput == '.') + ch = inv_type("Wear item:", IC_ARMOR); + else + ch = chInput; + if (ch == KEY_ESCAPE) { add_msg("Never mind."); return; @@ -6804,15 +6871,21 @@ void game::wear() u.wear(this, ch); } -void game::takeoff() +void game::takeoff(char chInput) { - if (u.takeoff(this, inv_type("Take off item:", IC_NULL))) + char ch; + if (chInput == '.') + ch = inv_type("Take off item:", IC_NULL); + else + ch = chInput; + + if (u.takeoff(this, ch)) u.moves -= 250; // TODO: Make this variable else add_msg("Invalid selection."); } -void game::reload() +void game::reload(char chInput) { if (u.weapon.is_gun()) { if (u.weapon.has_flag(IF_RELOAD_AND_SHOOT)) { @@ -6869,7 +6942,7 @@ single action.", u.weapon.tname().c_str()); // Unload a containter, gun, or tool // If it's a gun, some gunmods can also be loaded -void game::unload() +void game::unload(char chInput) { if (!u.weapon.is_gun() && u.weapon.contents.size() == 0 && (!u.weapon.is_tool() || u.weapon.ammo_type() == AT_NULL)) { @@ -6993,7 +7066,7 @@ void game::unload() weapon->curammo = NULL; } -void game::wield() +void game::wield(char chInput) { if (u.weapon.has_flag(IF_NO_UNWIELD)) { // Bionics can't be unwielded @@ -7001,10 +7074,14 @@ void game::wield() return; } char ch; - if (u.styles.empty()) - ch = inv("Wield item:"); - else - ch = inv("Wield item: Press - to choose a style"); + if (chInput == '.') { + if (u.styles.empty()) + ch = inv("Wield item:"); + else + ch = inv("Wield item: Press - to choose a style"); + } else + ch = chInput; + bool success = false; if (ch == '-') success = u.wield(this, -3); diff --git a/game.h b/game.h index c971d27a5ed6e..8d67fae84818b 100644 --- a/game.h +++ b/game.h @@ -319,20 +319,20 @@ class game // Pick where to put liquid; false if it's left where it was bool handle_liquid(item &liquid, bool from_ground, bool infinite); void compare(int iCompareX = -999, int iCompareY = -999); // Compare two Items 'I' - void drop(); // Drop an item 'd' + void drop(char chInput = '.'); // Drop an item 'd' void drop_in_direction(); // Drop w/ direction 'D' void reassign_item(); // Reassign the letter of an item '=' void butcher(); // Butcher a corpse 'B' void complete_butcher(int index); // Finish the butchering process void forage(); // Foraging ('a' on underbrush) - void eat(); // Eat food or fuel 'E' (or 'a') - void use_item();// Use item; also tries E,R,W 'a' + void eat(char chInput = '.'); // Eat food or fuel 'E' (or 'a') + void use_item(char chInput = '.');// Use item; also tries E,R,W 'a' void use_wielded_item(); - void wear(); // Wear armor 'W' (or 'a') - void takeoff(); // Remove armor 'T' - void reload(); // Reload a wielded gun/tool 'r' - void unload(); // Unload a wielded gun/tool 'U' - void wield(); // Wield a weapon 'w' + void wear(char chInput = '.'); // Wear armor 'W' (or 'a') + void takeoff(char chInput = '.'); // Remove armor 'T' + void reload(char chInput = '.'); // Reload a wielded gun/tool 'r' + void unload(char chInput = '.'); // Unload a wielded gun/tool 'U' + void wield(char chInput = '.'); // Wield a weapon 'w' void read(); // Read a book 'R' (or 'a') void chat(); // Talk to a nearby NPC 'C' void plthrow(); // Throw an item 't' diff --git a/inventory_ui.cpp b/inventory_ui.cpp index be553d3563bf5..74edfe188765a 100644 --- a/inventory_ui.cpp +++ b/inventory_ui.cpp @@ -437,40 +437,32 @@ std::vector game::multidrop() int max_size = u.inv.size(); for (int i = 0; i < max_size; i++) { - if (dropping[i] == -1) // drop whole stack of charges - { - ret.push_back(u.inv.remove_item(current_stack)); - current_stack--; + if (dropping[i] == -1) { // drop whole stack of charges + ret.push_back(u.inv.remove_item(current_stack)); + current_stack--; } - for (int j = 0; j < dropping[i]; j++) { + for (int j = 0; j < dropping[i]; j++) { + if (u.inv.stack_at(current_stack)[0].count_by_charges()) { // dropping parts of stacks + int tmpcount = dropping[i]; - if (u.inv.stack_at(current_stack)[0].count_by_charges()) // dropping parts of stacks - { - int tmpcount = dropping[i]; - - if (tmpcount >= u.inv.stack_at(current_stack)[0].charges) - { - ret.push_back(u.inv.remove_item(current_stack)); - current_stack--; - } - else - { - u.inv.stack_at(current_stack)[0].charges -= tmpcount; - ret.push_back(u.inv.remove_item_by_quantity(current_stack, tmpcount)); - } - j = dropping[i]; + if (tmpcount >= u.inv.stack_at(current_stack)[0].charges) { + ret.push_back(u.inv.remove_item(current_stack)); + current_stack--; + } else { + u.inv.stack_at(current_stack)[0].charges -= tmpcount; + ret.push_back(u.inv.remove_item_by_quantity(current_stack, tmpcount)); } - else - { - if (current_stack >= 0) { - if (u.inv.stack_at(current_stack).size() == 1) { - ret.push_back(u.inv.remove_item(current_stack)); - current_stack--; - } else - ret.push_back(u.inv.remove_item(current_stack)); - } + j = dropping[i]; + } else { + if (current_stack >= 0) { + if (u.inv.stack_at(current_stack).size() == 1) { + ret.push_back(u.inv.remove_item(current_stack)); + current_stack--; + } else + ret.push_back(u.inv.remove_item(current_stack)); } + } } current_stack++; } diff --git a/output.cpp b/output.cpp index 0af72ce1638b7..fcf92f0d50bcc 100644 --- a/output.cpp +++ b/output.cpp @@ -486,7 +486,7 @@ int menu_vec(const char *mes, std::vector options) if (options[i].length() + 6 > width) width = options[i].length() + 6; } - WINDOW* w = newwin(height, width, 1, 10); + WINDOW* w = newwin(height, width, 12-height/2, 40-width/2); wattron(w, c_white); wborder(w, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX, LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX ); @@ -810,60 +810,6 @@ void compare_split_screen_popup(bool bLeft, std::string sItemName, std::vector 36) - { - std::string sTemp; - do - { - sTemp += line; - tmp = tmp.substr(pos + 1); - pos = tmp.find_first_of('\n'); - line = " " + tmp.substr(0, pos); - } while (pos != std::string::npos); - sTemp += line; - while (sTemp.size() > 0) - { - size_t iPos = sTemp.find_last_of(' ', 36); - if (iPos == 0) - iPos = sTemp.size(); - mvwprintz(w, line_num, 2, c_white, (sTemp.substr(0, iPos)).c_str()); - line_num++; - sTemp = sTemp.substr(iPos+1, sTemp.size()); - } - } - else - { - mvwprintz(w, line_num, 2, c_white, (line).c_str()); - } - tmp = tmp.substr(pos + 1); - pos = tmp.find_first_of('\n'); - } - line_num++; - mvwprintz(w, line_num, 2, c_white, tmp.c_str()); - wrefresh(w); - if (!bLeft) - { - char ch; - do - ch = getch(); - while(ch != ' ' && ch != '\n' && ch != KEY_ESCAPE); - werase(w); - wrefresh(w); - delwin(w); - refresh(); - } - */ } char rand_char() From a3e1be9e8dba79e9dbbd19092e9c93b3e86f9dca Mon Sep 17 00:00:00 2001 From: OzoneH3 Date: Sat, 2 Mar 2013 21:16:26 +0100 Subject: [PATCH 09/14] Added unload items from inventory menu --- game.cpp | 36 ++++++++++++++++++++++++++++++++---- game.h | 5 +++-- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/game.cpp b/game.cpp index 974f239f65e52..fe43202a0a3ed 100644 --- a/game.cpp +++ b/game.cpp @@ -1612,10 +1612,11 @@ input_ret game::get_input(int timeout_ms) const std::string sSpaces = " "; char chItem = inv(); has = u.has_item(chItem); + if (has) { std::string sItemName = u.i_at(chItem).tname(this); int iMenu = menu(("Item: " + sItemName + sSpaces.substr(sItemName.size(), sSpaces.size())).c_str(), - "Examine", "Use/Read", "Eat", "Wear", "Wield", "Take off", "Drop", "Cancel", NULL); //"Unload", "Reload" + "Examine", "Use/Read", "Eat", "Wear", "Wield", "Take off", "Drop", "Unload", "Cancel", NULL); //"Reload", switch(iMenu) { case 1: @@ -1640,10 +1641,10 @@ input_ret game::get_input(int timeout_ms) drop(chItem); break; case 8: - //unload(chItem); + unload(chItem); break; case 9: - //reload(chItem); + //reload(); break; case 0: break; @@ -6885,7 +6886,7 @@ void game::takeoff(char chInput) add_msg("Invalid selection."); } -void game::reload(char chInput) +void game::reload() { if (u.weapon.is_gun()) { if (u.weapon.has_flag(IF_RELOAD_AND_SHOOT)) { @@ -6943,6 +6944,33 @@ single action.", u.weapon.tname().c_str()); // Unload a containter, gun, or tool // If it's a gun, some gunmods can also be loaded void game::unload(char chInput) +{ + //Quick and dirty hack + //Save old weapon in temp variable + //Wield item that should be unloaded + //Unload weapon + //Put unloaded item back into inventory + //Wield old weapon + bool bSwitch = false; + item oTempWeapon; + int iItemIndex = u.inv.index_by_letter(chInput); + + if (u.weapon.invlet != chInput && iItemIndex != -1) { + oTempWeapon = u.weapon; + u.weapon = u.inv[iItemIndex]; + u.inv.remove_item(iItemIndex); + bSwitch = true; + } + + unload(); + + if (bSwitch) { + u.inv.push_back(u.weapon); + u.weapon = oTempWeapon; + } +} + +void game::unload() { if (!u.weapon.is_gun() && u.weapon.contents.size() == 0 && (!u.weapon.is_tool() || u.weapon.ammo_type() == AT_NULL)) { diff --git a/game.h b/game.h index 8d67fae84818b..18eb9d7b1d3de 100644 --- a/game.h +++ b/game.h @@ -330,8 +330,9 @@ class game void use_wielded_item(); void wear(char chInput = '.'); // Wear armor 'W' (or 'a') void takeoff(char chInput = '.'); // Remove armor 'T' - void reload(char chInput = '.'); // Reload a wielded gun/tool 'r' - void unload(char chInput = '.'); // Unload a wielded gun/tool 'U' + void reload(); // Reload a wielded gun/tool 'r' + void unload(); // Unload a wielded gun/tool 'U' + void unload(char chInput); void wield(char chInput = '.'); // Wield a weapon 'w' void read(); // Read a book 'R' (or 'a') void chat(); // Talk to a nearby NPC 'C' From e978f250eb66f2b79abd63bd4db19488e471e251 Mon Sep 17 00:00:00 2001 From: OzoneH3 Date: Sat, 2 Mar 2013 21:41:04 +0100 Subject: [PATCH 10/14] Fix inventory menu unload, dont unload held weapon if selected item is worn item --- game.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/game.cpp b/game.cpp index fe43202a0a3ed..9de91972caff4 100644 --- a/game.cpp +++ b/game.cpp @@ -6962,7 +6962,9 @@ void game::unload(char chInput) bSwitch = true; } - unload(); + if (bSwitch || u.weapon.invlet == chInput) { + unload(); + } if (bSwitch) { u.inv.push_back(u.weapon); From 6a0bf4c865b7851f263d3006f9536e932824b83c Mon Sep 17 00:00:00 2001 From: OzoneH3 Date: Sat, 2 Mar 2013 23:16:34 +0100 Subject: [PATCH 11/14] Added inventory menu option to reload item --- game.cpp | 35 +++++++++++++++++++++++++++++++++-- game.h | 1 + 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/game.cpp b/game.cpp index 9de91972caff4..732a835e0b6aa 100644 --- a/game.cpp +++ b/game.cpp @@ -1616,7 +1616,7 @@ input_ret game::get_input(int timeout_ms) if (has) { std::string sItemName = u.i_at(chItem).tname(this); int iMenu = menu(("Item: " + sItemName + sSpaces.substr(sItemName.size(), sSpaces.size())).c_str(), - "Examine", "Use/Read", "Eat", "Wear", "Wield", "Take off", "Drop", "Unload", "Cancel", NULL); //"Reload", + "Examine", "Use/Read", "Eat", "Wear", "Wield", "Take off", "Drop", "Unload", "Reload", "Cancel", NULL); switch(iMenu) { case 1: @@ -1644,7 +1644,7 @@ input_ret game::get_input(int timeout_ms) unload(chItem); break; case 9: - //reload(); + reload(chItem); break; case 0: break; @@ -6886,6 +6886,37 @@ void game::takeoff(char chInput) add_msg("Invalid selection."); } +void game::reload(char chInput) +{ + //Quick and dirty hack + //Save old weapon in temp variable + //Wield item that should be unloaded + //Reload weapon + //Put unloaded item back into inventory + //Wield old weapon + bool bSwitch = false; + item oTempWeapon; + int iItemIndex = u.inv.index_by_letter(chInput); + + if (u.weapon.invlet != chInput && iItemIndex != -1) { + oTempWeapon = u.weapon; + u.weapon = u.inv[iItemIndex]; + u.inv.remove_item(iItemIndex); + bSwitch = true; + } + + if (bSwitch || u.weapon.invlet == chInput) { + reload(); + u.activity.moves_left = 0; //Not entirely sure how this effects other actions + process_activity(); + } + + if (bSwitch) { + u.inv.push_back(u.weapon); + u.weapon = oTempWeapon; + } +} + void game::reload() { if (u.weapon.is_gun()) { diff --git a/game.h b/game.h index 18eb9d7b1d3de..6ac4f59a734d7 100644 --- a/game.h +++ b/game.h @@ -331,6 +331,7 @@ class game void wear(char chInput = '.'); // Wear armor 'W' (or 'a') void takeoff(char chInput = '.'); // Remove armor 'T' void reload(); // Reload a wielded gun/tool 'r' + void reload(char chInput); void unload(); // Unload a wielded gun/tool 'U' void unload(char chInput); void wield(char chInput = '.'); // Wield a weapon 'w' From 4c9ced093f8dd2394125add4852d6ea215f8adcb Mon Sep 17 00:00:00 2001 From: OzoneH3 Date: Sun, 3 Mar 2013 00:19:08 +0100 Subject: [PATCH 12/14] Fixed freeze when options get changed from bool to int --- options.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/options.cpp b/options.cpp index 4a2742218d6a7..f85b98a126168 100644 --- a/options.cpp +++ b/options.cpp @@ -1,6 +1,7 @@ #include "options.h" #include "output.h" +#include #include #include @@ -45,8 +46,15 @@ void load_options() else OPTIONS[key] = 0.; } else { + std::string check; double val; - fin >> val; + fin >> check; + + if (check == "T" || check == "F") + val = (check == "T") ? 1.: 0.; + else + val = atoi(check.c_str()); + OPTIONS[key] = val; } } From 1e34693f74bbd3e517458f9bc4366758cb4e6c01 Mon Sep 17 00:00:00 2001 From: OzoneH3 Date: Sun, 3 Mar 2013 12:42:38 +0100 Subject: [PATCH 13/14] Added numpad keys to input.cpp --- input.cpp | 20 ++++++++++++++------ overmap.cpp | 6 +++--- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/input.cpp b/input.cpp index 10742a9ff138b..e7d6951567b1a 100644 --- a/input.cpp +++ b/input.cpp @@ -4,32 +4,40 @@ /* TODO Replace the hardcoded values with an abstraction layer. * Lower redundancy across the methods. */ -InputEvent get_input(int ch) +InputEvent get_input(int ch) { if (ch == '\0') ch = getch(); switch(ch) { - case 'k': - case KEY_UP: + case 'k': + case '8': + case KEY_UP: return DirectionN; case 'j': - case KEY_DOWN: + case '2': + case KEY_DOWN: return DirectionS; case 'l': - case KEY_RIGHT: + case '6': + case KEY_RIGHT: return DirectionE; case 'h': - case KEY_LEFT: + case '4': + case KEY_LEFT: return DirectionW; case 'y': + case '7': return DirectionNW; case 'u': + case '9': return DirectionNE; case 'b': + case '1': return DirectionSW; case 'n': + case '3': return DirectionSE; case '.': return DirectionNone; diff --git a/overmap.cpp b/overmap.cpp index eda8766d4fd68..9102533e3bd53 100644 --- a/overmap.cpp +++ b/overmap.cpp @@ -615,7 +615,7 @@ void overmap::generate_sub(overmap* above) else if (above->ter(i, j) == ot_shelter) shelter_points.push_back( point(i, j) ); - + else if (above->ter(i, j) == ot_lmoe) lmoe_points.push_back( point(i, j) ); @@ -1067,7 +1067,7 @@ void overmap::draw(WINDOW *w, game *g, int &cursx, int &cursy, mvwprintz(w, 18, om_map_width + 1, c_magenta, "0 - Center map on character"); mvwprintz(w, 19, om_map_width + 1, c_magenta, "t - Toggle legend "); mvwprintz(w, 20, om_map_width + 1, c_magenta, "/ - Search "); - mvwprintz(w, 21, om_map_width + 1, c_magenta, "N - Add a note "); + mvwprintz(w, 21, om_map_width + 1, c_magenta, "N - Add/Edit a note "); mvwprintz(w, 22, om_map_width + 1, c_magenta, "D - Delete a note "); mvwprintz(w, 23, om_map_width + 1, c_magenta, "L - List notes "); mvwprintz(w, 24, om_map_width + 1, c_magenta, "Esc or q - Return to game "); @@ -1107,7 +1107,7 @@ point overmap::choose_point(game *g) ret = point(-1, -1); else if (ch == 'N') { timeout(-1); - add_note(cursx, cursy, string_input_popup("Note: (X:TEXT for custom symbol)", 49, note(cursx, cursy))); // 49 char max + add_note(cursx, cursy, string_input_popup("Note (X:TEXT for custom symbol):", 49, note(cursx, cursy))); // 49 char max timeout(BLINK_SPEED); } else if(ch == 'D'){ timeout(-1); From ed91287ad4f98fb48b737bc680cdc285fe6de7c2 Mon Sep 17 00:00:00 2001 From: OzoneH3 Date: Sun, 3 Mar 2013 14:26:32 +0100 Subject: [PATCH 14/14] Added missing key for numpad support --- input.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/input.cpp b/input.cpp index e7d6951567b1a..a2ca8348b19a3 100644 --- a/input.cpp +++ b/input.cpp @@ -40,6 +40,7 @@ InputEvent get_input(int ch) case '3': return DirectionSE; case '.': + case '5': return DirectionNone; case '>': return DirectionDown;