Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework the waiting menu and fix 'calendar::print_duration()' #17116

Merged
merged 10 commits into from
Jun 18, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 39 additions & 15 deletions src/calendar.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
#include <cmath>
#include <sstream>
#include <limits>

#include "calendar.h"
#include "output.h"
#include "options.h"
#include "translations.h"
#include "game.h"
#include "debug.h"

// Divided by 100 to prevent overflowing when converted to moves
const int calendar::INDEFINITELY_LONG( std::numeric_limits<int>::max() / 100 );

calendar calendar::start;
calendar calendar::turn;
season_type calendar::initial_season;
Expand All @@ -25,6 +30,25 @@ bool calendar::eternal_season = false;
// How long, in seconds, does sunrise/sunset last?
#define TWILIGHT_SECONDS (60 * 60)

constexpr int FULL_SECONDS_IN( int n )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get the function name. Full seconds in what?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh, in the argument?

{
return n * 6;
}

constexpr int FULL_MINUTES_IN( int n )
{
return n / MINUTES( 1 );
}

constexpr int FULL_HOURS_IN( int n )
{
return n / HOURS( 1 );
}

constexpr int FULL_DAYS_IN( int n )
{
return n / DAYS( 1 );
}

calendar::calendar()
{
Expand Down Expand Up @@ -262,31 +286,31 @@ std::string calendar::print_duration( int turns )
{
std::string res;

if( turns < MINUTES( 1 ) ) {
int sec = std::max( 1, turns * 6 );
if( turns <= MINUTES( 1 ) ) {
const int sec = FULL_SECONDS_IN( turns );
res += string_format( ngettext( "%d second", "%d seconds", sec ), sec );

} else if( turns < HOURS( 1 ) ) {
int min = turns / MINUTES( 1 );
int sec = turns % MINUTES( 1 );
} else if( turns <= HOURS( 1 ) ) {
const int min = FULL_MINUTES_IN( turns );
const int sec = FULL_SECONDS_IN( turns % MINUTES( 1 ) );
res += string_format( ngettext( "%d minute", "%d minutes", min ), min );
if( sec ) {
if( sec != 0 ) {
res += string_format( ngettext( " and %d second", " and %d seconds", sec ), sec );
}

} else if( turns < DAYS( 1 ) ) {
int hour = turns / HOURS( 1 );
int min = turns % HOURS( 1 );
} else if( turns <= DAYS( 1 ) ) {
const int hour = FULL_HOURS_IN( turns );
const int min = FULL_MINUTES_IN( turns % HOURS( 1 ) );
res += string_format( ngettext( "%d hour", "%d hours", hour ), hour );
if( min ) {
if( min != 0 ) {
res += string_format( ngettext( " and %d minute", " and %d minutes", min ), min );
}

} else {
int day = turns / DAYS( 1 );
int hour = turns % DAYS( 1 );
const int day = FULL_DAYS_IN( turns );
const int hour = FULL_HOURS_IN( turns % DAYS( 1 ) );
res += string_format( ngettext( "%d day", "%d days", day ), day );
if( hour ) {
if( hour != 0 ) {
res += string_format( ngettext( " and %d hour", " and %d hours", hour ), hour );
}
}
Expand Down Expand Up @@ -450,8 +474,8 @@ int calendar::day_of_year() const

int calendar::diurnal_time_before( int turn ) const
{
const int remainder = turn - get_turn() % DAYS( 1 );
return ( remainder >= 0 ) ? remainder : DAYS( 1 ) + remainder;
const int remainder = turn % DAYS( 1 ) - get_turn() % DAYS( 1 );
return ( remainder > 0 ) ? remainder : DAYS( 1 ) + remainder;
}

void calendar::sync()
Expand Down
10 changes: 9 additions & 1 deletion src/calendar.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@

#include <string>

constexpr int SECONDS( int n )
{
return n / 6;
}

constexpr int MINUTES( int n )
{
return n * 10;
Expand Down Expand Up @@ -128,7 +133,10 @@ class calendar
*/
static bool once_every( int event_frequency );

// Season and year length stuff
public:
// Used for durations
static const int INDEFINITELY_LONG;

static int year_turns() {
return DAYS( year_length() );
}
Expand Down
87 changes: 35 additions & 52 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13879,72 +13879,55 @@ void game::spawn_mon(int /*shiftx*/, int /*shifty*/)
}
}

// Helper function for game::wait().
static int convert_wait_chosen_to_turns( int choice ) {
switch( choice ) {
case 1:
return MINUTES( 5 );
case 2:
return MINUTES( 30 );
case 3:
return HOURS( 1 );
case 4:
return HOURS( 2 );
case 5:
return HOURS( 3 );
case 6:
return HOURS( 6 );
case 7:
return calendar::turn.diurnal_time_before( calendar::turn.sunrise() );
case 8:
return calendar::turn.diurnal_time_before( HOURS( 12 ) );
case 9:
return calendar::turn.diurnal_time_before( calendar::turn.sunset() );
case 10:
return calendar::turn.diurnal_time_before( HOURS( 0 ) );
case 11:
default:
return 999999999;
}
}

void game::wait()
{
const bool bHasWatch = u.has_watch();

std::map<int, int> durations;
uimenu as_m;
as_m.text = _("Wait for how long?");
as_m.return_invalid = true;
as_m.entries.push_back(uimenu_entry(1, true, '1',
(bHasWatch) ? _("5 Minutes") : _("Wait 300 heartbeats")));
as_m.entries.push_back(uimenu_entry(2, true, '2',
(bHasWatch) ? _("30 Minutes") : _("Wait 1800 heartbeats")));

if (bHasWatch) {
as_m.entries.push_back(uimenu_entry(3, true, '3', _("1 hour")));
as_m.entries.push_back(uimenu_entry(4, true, '4', _("2 hours")));
as_m.entries.push_back(uimenu_entry(5, true, '5', _("3 hours")));
as_m.entries.push_back(uimenu_entry(6, true, '6', _("6 hours")));
const bool has_watch = u.has_watch();
const auto add_menu_item = [ &as_m, &durations, has_watch ]
( int retval, int hotkey, const std::string &caption = "", int duration = calendar::INDEFINITELY_LONG ) {

std::string text( caption );

if( has_watch && duration != calendar::INDEFINITELY_LONG ) {
const std::string dur_str( calendar::print_duration( duration ) );
text += ( text.empty() ? dur_str : string_format( " (%s)", dur_str.c_str() ) );
}
as_m.addentry( retval, true, hotkey, text );
durations[retval] = duration;
};

add_menu_item( 1, '1', !has_watch ? _( "Wait 300 heartbeats" ) : "", MINUTES( 5 ) );
add_menu_item( 2, '2', !has_watch ? _( "Wait 1800 heartbeats" ) : "", MINUTES( 30 ) );

if( has_watch ) {
add_menu_item( 3, '3', "", HOURS( 1 ) );
add_menu_item( 4, '4', "", HOURS( 2 ) );
add_menu_item( 5, '5', "", HOURS( 3 ) );
add_menu_item( 6, '6', "", HOURS( 6 ) );
}

as_m.entries.push_back(uimenu_entry(7, true, 'd', _("Wait till dawn")));
as_m.entries.push_back(uimenu_entry(8, true, 'n', _("Wait till noon")));
as_m.entries.push_back(uimenu_entry(9, true, 'k', _("Wait till dusk")));
as_m.entries.push_back(uimenu_entry(10, true, 'm', _("Wait till midnight")));
as_m.entries.push_back(uimenu_entry(11, true, 'w', _("Wait till weather changes")));
add_menu_item( 7, 'd', _( "Wait till dawn" ), calendar::turn.diurnal_time_before( calendar::turn.sunrise() ) );
add_menu_item( 8, 'n', _( "Wait till noon" ), calendar::turn.diurnal_time_before( HOURS( 12 ) ) );
add_menu_item( 9, 'k', _( "Wait till dusk" ), calendar::turn.diurnal_time_before( calendar::turn.sunset() ) );
add_menu_item( 10, 'm', _( "Wait till midnight" ), calendar::turn.diurnal_time_before( HOURS( 0 ) ) );
add_menu_item( 11, 'w', _( "Wait till weather changes" ) );
add_menu_item( 12, 'q', _( "Exit" ) );

as_m.entries.push_back(uimenu_entry(12, true, 'q', _("Exit")));
as_m.text = ( has_watch ) ? string_format( _( "It's %s now. " ), calendar::turn.print_time().c_str() ) : "";
as_m.text += _( "Wait for how long?" );
as_m.return_invalid = true;
as_m.query(); /* calculate key and window variables, generate window, and loop until we get a valid answer */

if( as_m.ret < 1 || as_m.ret > 11 ) {
if( as_m.ret == 12 || durations.count( as_m.ret ) == 0 ) {
return;
}

int chosen_turns = convert_wait_chosen_to_turns( as_m.ret );
activity_type actType = ( as_m.ret == 11 ) ? ACT_WAIT_WEATHER : ACT_WAIT;

constexpr int turns_to_moves = 100;
player_activity new_act( actType, chosen_turns * turns_to_moves, 0 );
player_activity new_act( actType, 100 * ( durations[as_m.ret] - 1 ), 0 );

u.assign_activity( new_act, false );
u.rooted_message();
}
Expand Down