2022-04-24 17:48:45 +00:00
# include "nilrider.h"
# include "statues.cpp"
# include "timestamp.cpp"
# include "levels.cpp"
# include "level.cpp"
# include "planning.cpp"
2022-04-30 10:04:50 +00:00
# include "solver.cpp"
2022-04-24 17:48:45 +00:00
namespace nilrider {
/** is the game paused? */
bool paused = false ;
bool planning_mode = false ;
bool view_simulation = false ;
int simulation_start_tick ;
2022-05-01 10:12:04 +00:00
ld aimspeed_key_x = 1 , aimspeed_key_y = 1 , aimspeed_mouse_x = 1 , aimspeed_mouse_y = 1 ;
2022-04-24 17:48:45 +00:00
void frame ( ) {
if ( planning_mode & & ! view_simulation ) return ;
shiftmatrix V = ggmatrix ( cwt . at ) ;
curlev - > draw_level ( V ) ;
curlev - > current . draw_unilcycle ( V ) ;
}
bool turn ( int delta ) {
if ( planning_mode & & ! view_simulation ) return false ;
Uint8 * keystate = SDL_GetKeyState ( NULL ) ;
2022-05-01 10:12:04 +00:00
ld mul = 1 ;
if ( keystate [ SDLK_LCTRL ] ) mul / = 5 ;
2022-04-24 17:48:45 +00:00
2022-05-01 10:12:04 +00:00
if ( keystate [ SDLK_RIGHT ] & & ! paused ) curlev - > current . heading_angle - = aimspeed_key_x * mul * delta / 1000. ;
if ( keystate [ SDLK_LEFT ] & & ! paused ) curlev - > current . heading_angle + = aimspeed_key_x * mul * delta / 1000. ;
2022-04-24 17:48:45 +00:00
2022-05-01 10:12:04 +00:00
if ( keystate [ SDLK_UP ] & & ! paused ) min_gfx_slope - = aimspeed_key_y * mul * delta / 1000. ;
if ( keystate [ SDLK_DOWN ] & & ! paused ) min_gfx_slope + = aimspeed_key_y * mul * delta / 1000. ;
curlev - > current . heading_angle - = aimspeed_mouse_x * mouseaim_x * mul ;
min_gfx_slope + = aimspeed_mouse_y * mouseaim_y * mul ;
2022-04-24 17:48:45 +00:00
# if CAP_VR
if ( vrhr : : active ( ) ) {
2022-05-01 10:12:04 +00:00
curlev - > current . heading_angle - = aimspeed_mouse_x * vrhr : : vraim_x * mul * delta / 400 ;
min_gfx_slope - = aimspeed_mouse_y * vrhr : : vraim_y * mul * delta / 400 ;
2022-04-24 17:48:45 +00:00
}
# endif
if ( min_gfx_slope < - 90 * degree ) min_gfx_slope = - 90 * degree ;
if ( min_gfx_slope > + 90 * degree ) min_gfx_slope = + 90 * degree ;
if ( ! paused & & ! view_simulation ) for ( int i = 0 ; i < delta ; i + + ) {
curlev - > history . push_back ( curlev - > current ) ;
bool b = curlev - > current . tick ( curlev ) ;
if ( b ) timer + = 1. / tps ;
else curlev - > history . pop_back ( ) ;
}
if ( ! paused ) curlev - > current . centerview ( curlev ) ;
return false ;
}
void main_menu ( ) ;
void run ( ) {
cmode = sm : : MAP ;
clearMessages ( ) ;
dialog : : init ( ) ;
if ( view_simulation & & ! paused ) {
int ttick = gmod ( ticks - simulation_start_tick , isize ( curlev - > history ) ) ;
timer = ttick * 1. / tps ;
curlev - > current = curlev - > history [ ttick ] ;
curlev - > current . centerview ( curlev ) ;
}
2022-04-30 10:02:30 +00:00
if ( planning_mode & & ! view_simulation )
cmode | = sm : : SHOWCURSOR ;
2022-05-01 10:12:04 +00:00
if ( aimspeed_mouse_x = = 0 & & aimspeed_mouse_y = = 0 )
cmode | = sm : : SHOWCURSOR ;
2022-04-24 17:48:45 +00:00
gamescreen ( 0 ) ;
if ( planning_mode & & ! view_simulation ) {
curlev - > draw_planning_screen ( ) ;
if ( ! holdmouse ) {
auto t0 = SDL_GetTicks ( ) ;
while ( SDL_GetTicks ( ) < t0 + 100 ) {
if ( ! curlev - > simulate ( ) ) break ;
}
}
}
curlev - > current . draw_instruments ( timer ) ;
if ( paused & & ! planning_mode ) {
displayButton ( current_display - > xcenter , current_display - > ycenter , mousing ? XLAT ( " paused -- click to unpause " ) : XLAT ( " paused -- press p to continue " ) , ' p ' , 8 ) ;
}
int x = vid . fsize ;
auto show_button = [ & ] ( char c , string s , color_t col = dialog : : dialogcolor ) {
if ( displayButtonS ( x , vid . yres - vid . fsize , s , col , 0 , vid . fsize ) )
getcstat = c ;
x + = textwidth ( vid . fsize , s ) + vid . fsize ;
} ;
if ( planning_mode & & ! view_simulation ) {
for ( auto & b : buttons ) show_button ( b . first , b . second , planmode = = b . first ? 0xFFD500 : dialog : : dialogcolor ) ;
show_button ( ' s ' , " simulation " ) ;
}
if ( planning_mode & & view_simulation ) {
show_button ( ' s ' , " return " ) ;
show_button ( ' p ' , " pause " , paused ? 0xFF0000 : dialog : : dialogcolor ) ;
}
if ( ! planning_mode ) {
show_button ( ' p ' , " pause " , paused ? 0xFF0000 : dialog : : dialogcolor ) ;
}
show_button ( ' v ' , " menu " ) ;
dialog : : add_key_action ( ' v ' , [ ] {
paused = true ;
pushScreen ( main_menu ) ;
} ) ;
dialog : : add_key_action ( ' p ' , [ ] {
paused = ! paused ;
if ( view_simulation & & ! paused )
simulation_start_tick = ticks - timer * tps ;
} ) ;
dialog : : add_key_action ( ' - ' , [ ] {
paused = false ;
} ) ;
dialog : : add_key_action ( ' b ' , [ ] {
if ( planning_mode )
simulation_start_tick + = 500 ;
else {
for ( int i = 0 ; i < 500 ; i + + ) if ( ! curlev - > history . empty ( ) ) curlev - > history . pop_back ( ) ;
curlev - > current = curlev - > history . back ( ) ;
timer = isize ( curlev - > history ) * 1. / tps ;
}
} ) ;
if ( planning_mode ) dialog : : add_key_action ( ' s ' , [ ] {
view_simulation = ! view_simulation ;
paused = false ;
simulation_start_tick = ticks ;
} ) ;
dialog : : display ( ) ;
keyhandler = [ ] ( int sym , int uni ) {
if ( paused ) handlePanning ( sym , uni ) ;
if ( planning_mode & & ! view_simulation & & curlev - > handle_planning ( sym , uni ) ) return ;
dialog : : handleNavigation ( sym , uni ) ;
} ;
}
int speedlimit = 0 ;
vector < string > speedlimit_names = { " none " , " yellow " , " green " , " full " } ;
void pick_level ( ) {
clearMessages ( ) ;
dialog : : init ( XLAT ( " select the track " ) , 0xC0C0FFFF , 150 , 100 ) ;
for ( auto l : all_levels ) {
dialog : : addItem ( l - > name , l - > hotkey ) ;
dialog : : add_action ( [ l ] {
curlev = l ;
recompute_plan_transform = true ;
l - > init ( ) ;
popScreen ( ) ;
} ) ;
}
dialog : : addBreak ( 100 ) ;
dialog : : addBack ( ) ;
dialog : : display ( ) ;
}
void pick_game ( ) {
clearMessages ( ) ;
dialog : : init ( XLAT ( " how do you want to play? " ) , 0xC0C0FFFF , 150 , 100 ) ;
dialog : : addSelItem ( " selected track " , curlev - > name , ' t ' ) ;
dialog : : add_action_push ( pick_level ) ;
dialog : : addInfo ( curlev - > longdesc ) ;
dialog : : addBreak ( 100 ) ;
add_edit ( speedlimit ) ;
add_edit ( planning_mode ) ;
dialog : : addBreak ( 100 ) ;
dialog : : addBack ( ) ;
dialog : : display ( ) ;
}
void settings ( ) {
dialog : : init ( XLAT ( " settings " ) , 0xC0C0FFFF , 150 , 100 ) ;
2022-05-01 10:12:04 +00:00
add_edit ( aimspeed_key_x ) ;
add_edit ( aimspeed_key_y ) ;
add_edit ( aimspeed_mouse_x ) ;
add_edit ( aimspeed_mouse_y ) ;
2022-04-24 17:48:45 +00:00
dialog : : addItem ( " RogueViz settings " , ' r ' ) ;
dialog : : add_key_action ( ' r ' , [ ] {
pushScreen ( showSettings ) ;
} ) ;
dialog : : addBreak ( 100 ) ;
dialog : : display ( ) ;
dialog : : addBack ( ) ;
}
reaction_t on_quit = [ ] { exit ( 0 ) ; } ;
void main_menu ( ) {
clearMessages ( ) ;
dialog : : init ( XLAT ( " Nil Rider " ) , 0xC0C0FFFF , 150 , 100 ) ;
dialog : : addItem ( " continue " , ' c ' ) ;
dialog : : add_action ( popScreen ) ;
if ( ! planning_mode ) {
dialog : : addItem ( " restart " , ' r ' ) ;
dialog : : add_action ( [ ] {
curlev - > current = curlev - > start ;
timer = 0 ;
paused = false ;
popScreen ( ) ;
} ) ;
dialog : : addItem ( " view the replay " , ' v ' ) ;
dialog : : add_action ( [ ] {
} ) ;
dialog : : addItem ( " save the replay " , ' e ' ) ;
dialog : : add_action ( [ ] {
} ) ;
}
else {
dialog : : addItem ( " save this plan " , ' s ' ) ;
dialog : : add_action ( [ ] {
} ) ;
}
dialog : : addItem ( " change track or game settings " , ' t ' ) ;
dialog : : add_action_push ( pick_game ) ;
dialog : : addItem ( " change other settings " , ' o ' ) ;
dialog : : add_action_push ( settings ) ;
dialog : : addItem ( " quit " , ' q ' ) ;
dialog : : add_action ( [ ] {
on_quit ( ) ;
} ) ;
dialog : : display ( ) ;
}
bool on ;
void initialize ( ) {
check_cgi ( ) ;
cgi . prepare_shapes ( ) ;
init_statues ( ) ;
curlev - > init ( ) ;
param_enum ( planning_mode , " nil_planning " , " nil_planning " , false )
- > editable ( { { " manual " , " control the unicycle manually " } , { " planning " , " try to plan the optimal route! " } } , " game mode " , ' p ' ) ;
param_enum ( speedlimit , " nil_speedlimit " , " nil_speedlimit " , 0 )
- > editable ( {
{ " no limit " , " reach the goals as fast as you wan " } ,
{ " yellow " , " your speed must be in the yellow zone to collect " } ,
{ " green " , " your speed must be in the green zone to collect " } ,
{ " full " , " you must fully stop to collect " }
} , " speed limit " , ' s ' ) ;
rv_hook ( hooks_frame , 100 , frame ) ;
rv_hook ( shmup : : hooks_turn , 100 , turn ) ;
on = true ;
on_cleanup_or_next ( [ ] { on = false ; } ) ;
pushScreen ( run ) ;
}
auto celldemo = arg : : add3 ( " -unilcycle " , initialize ) + arg : : add3 ( " -unilplan " , [ ] { planning_mode = true ; } ) + arg : : add3 ( " -viewsim " , [ ] { view_simulation = true ; } )
+ arg : : add3 ( " -oqc " , [ ] { on_quit = popScreenAll ; } )
2022-04-30 10:04:50 +00:00
+ arg : : add3 ( " -nilsolve " , [ ] { curlev - > solve ( ) ; } )
2022-05-01 10:12:04 +00:00
+ addHook ( hooks_configfile , 100 , [ ] {
param_f ( aimspeed_key_x , " nilrider_key_x " )
- > editable ( - 5 , 5 , 0.1 , " navigation sensitivity (keyboard) " , " press Left/Right to navigate (lCtrl to fine-tune) " , ' n ' ) ;
param_f ( aimspeed_key_y , " nilrider_key_y " )
- > editable ( - 5 , 5 , 0.1 , " camera sensitivity (keyboard) " , " press Up/Down to set the camera angle (lCtrl to fine-tune) " , ' c ' ) ;
param_f ( aimspeed_mouse_x , " nilrider_mouse_x " )
- > editable ( - 5 , 5 , 0.1 , " navigation sensitivity (mouse/vr) " , " move mouse Left/Right to navigate (lCtrl to fine-tune) " , ' N ' ) ;
param_f ( aimspeed_mouse_y , " nilrider_mouse_y " )
- > editable ( - 5 , 5 , 0.1 , " camera sensitivity (mouse/vr) " , " move mouse Up/Down to set the camera angle (lCtrl to fine-tune) " , ' C ' ) ;
} )
2022-04-24 17:48:45 +00:00
+ arg : : add3 ( " -fullsim " , [ ] {
/* for animations */
popScreenAll ( ) ;
rv_hook ( anims : : hooks_anim , 100 , [ ] {
int ttick = ticks % isize ( curlev - > history ) ;
timer = ttick * 1. / tps ;
curlev - > current = curlev - > history [ ttick ] ;
curlev - > current . centerview ( curlev ) ;
anims : : moved ( ) ;
} ) ;
} ) + arg : : add3 ( " -unillevel " , [ ] {
arg : : shift ( ) ;
for ( auto l : all_levels ) if ( appears ( l - > name , arg : : args ( ) ) ) curlev = l ;
if ( on ) curlev - > init ( ) ;
} )
+ arg : : add3 ( " -simplemodel " , [ ] {
nisot : : geodesic_movement = false ;
pmodel = mdPerspective ;
pconf . rotational_nil = 0 ;
} ) ;
}