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

[WIP] Jsonize Move Modes #38299

Closed
wants to merge 8 commits into from
Closed
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
57 changes: 57 additions & 0 deletions data/json/move_modes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
[
{
"id": "MM_NULL",
"type": "move_mode",
"name": "Null",
"flavor_text": "You should never see this."
},
{
"id": "MM_WALK",
"type": "move_mode",
"name": "Walk",
"can_haul": true,
"usable_while_mounted": true,
"speed": 1.0,
"display_colour": "light_gray",
"display_character": "W",
"minimum_required_legs": 0,
"flavor_text": "You start walking.",
Copy link
Contributor

Choose a reason for hiding this comment

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

Translatable strings in JSON require separate code in "lang/extract_json_strings.py" to extract them for translation.

"flavor_text_mount": "You nudge your steed into a steady trot.",
"flavor_text_mech": "You set your mech's leg power to a loping fast walk.",
"stamina_burn_multiplier": 1.0
},
{
"id": "MM_RUN",
"type": "move_mode",
"name": "Run",
"can_haul": false,
"usable_while_mounted": true,
"speed": 2.0,
"display_colour": "red",
"display_character": "R",
"minimum_required_legs": 2,
"flavor_text": "You start running.",
"flavor_text_mount": "You spur your steed into a gallop.",
"flavor_text_mech": "You set the power of your mech's leg servos to maximum.",
"stamina_burn_multiplier": 7.0,
"volume_multiplier": 1.5,
"swim_cost_modifier": -80
},
{
"id": "MM_CROUCH",
"type": "move_mode",
"name": "Crouch",
"can_haul": true,
"usable_while_mounted": true,
"speed": 0.5,
"display_colour": "light_blue",
"display_character": "C",
"minimum_required_legs": 0,
"flavor_text": "You start crouching.",
"flavor_text_mount": "You slow your steed to a walk.",
"flavor_text_mech": "You reduce the power of your mech's leg servos to minimum.",
"stamina_burn_multiplier": 1.0,
"volume_multiplier": 0.5,
"swim_cost_modifier": 50
}
]
5 changes: 3 additions & 2 deletions src/action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "map_iterator.h"
#include "mapdata.h"
#include "messages.h"
#include "move_mode.h"
#include "optional.h"
#include "options.h"
#include "output.h"
Expand Down Expand Up @@ -714,11 +715,11 @@ action_id handle_action_menu()
}

// If we're already running, make it simple to toggle running to off.
if( g->u.movement_mode_is( CMM_RUN ) ) {
if( g->u.movement_mode_is( MM_RUN ) ) {
action_weightings[ACTION_TOGGLE_RUN] = 300;
}
// If we're already crouching, make it simple to toggle crouching to off.
if( g->u.movement_mode_is( CMM_CROUCH ) ) {
if( g->u.movement_mode_is( MM_CROUCH ) ) {
action_weightings[ACTION_TOGGLE_CROUCH] = 300;
}

Expand Down
122 changes: 50 additions & 72 deletions src/avatar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "monstergenerator.h"
#include "morale.h"
#include "morale_types.h"
#include "move_mode.h"
#include "mutation.h"
#include "npc.h"
#include "options.h"
Expand Down Expand Up @@ -1357,102 +1358,79 @@ faction *avatar::get_faction() const
return g->faction_manager_ptr->get( faction_id( "your_followers" ) );
}

void avatar::set_movement_mode( character_movemode new_mode )
bool avatar::set_movement_mode( const move_mode_id &mode )
{
switch( new_mode ) {
case CMM_WALK: {
if( is_mounted() ) {
if( mounted_creature->has_flag( MF_RIDEABLE_MECH ) ) {
add_msg( _( "You set your mech's leg power to a loping fast walk." ) );
} else {
add_msg( _( "You nudge your steed into a steady trot." ) );
}
} else {
add_msg( _( "You start walking." ) );
}
break;
}
case CMM_RUN: {
if( can_run() ) {
if( is_hauling() ) {
stop_hauling();
}
if( is_mounted() ) {
if( mounted_creature->has_flag( MF_RIDEABLE_MECH ) ) {
add_msg( _( "You set the power of your mech's leg servos to maximum." ) );
} else {
add_msg( _( "You spur your steed into a gallop." ) );
}
} else {
add_msg( _( "You start running." ) );
}
} else {
if( is_mounted() ) {
// mounts dont currently have stamina, but may do in future.
add_msg( m_bad, _( "Your steed is too tired to go faster." ) );
} else if( get_working_leg_count() < 2 ) {
add_msg( m_bad, _( "You need two functional legs to run." ) );
} else {
add_msg( m_bad, _( "You're too tired to run." ) );
}
return;
}
break;
}
case CMM_CROUCH: {
if( is_mounted() ) {
if( mounted_creature->has_flag( MF_RIDEABLE_MECH ) ) {
add_msg( _( "You reduce the power of your mech's leg servos to minimum." ) );
} else {
add_msg( _( "You slow your steed to a walk." ) );
}
} else {
add_msg( _( "You start crouching." ) );
}
break;
}
default: {
return;
move_mode new_mode = mode.obj();

if( new_mode.minimum_required_legs > get_working_leg_count() ) {
add_msg( m_bad, string_format( _( "You do not have enough functioning legs to %s." ),
Copy link
Contributor

@BevapDin BevapDin Feb 24, 2020

Choose a reason for hiding this comment

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

add_msg already does formatting, you should not do it yourself.

Same for more calls to add_msg below.

new_mode.name ) );
return false;
}

if( !new_mode.usable_while_mounted && is_mounted() ) {
add_msg( m_bad, string_format( _( "You cannot %s whilst mounted." ), new_mode.name ) );
return false;
}

if( !new_mode.can_haul && is_hauling() ) {
stop_hauling();
}

translation text_to_show = new_mode.flavor_text;
if( is_mounted() ) {
if( mounted_creature->has_flag( MF_RIDEABLE_MECH ) ) {
text_to_show = new_mode.flavor_text_mech;
} else {
text_to_show = new_mode.flavor_text_mount;
}
}
move_mode = new_mode;

add_msg( "%s", text_to_show.translated() );

current_move_mode = mode;

return true;
}

void avatar::toggle_run_mode()
{
if( move_mode == CMM_RUN ) {
set_movement_mode( CMM_WALK );
if( movement_mode_is( MM_RUN ) ) {
set_movement_mode( MM_WALK );
} else {
set_movement_mode( CMM_RUN );
set_movement_mode( MM_RUN );
}
}

void avatar::toggle_crouch_mode()
{
if( move_mode == CMM_CROUCH ) {
set_movement_mode( CMM_WALK );
if( movement_mode_is( MM_CROUCH ) ) {
set_movement_mode( MM_WALK );
} else {
set_movement_mode( CMM_CROUCH );
set_movement_mode( MM_CROUCH );
}
}

void avatar::reset_move_mode()
{
if( move_mode != CMM_WALK ) {
set_movement_mode( CMM_WALK );
if( !movement_mode_is( MM_WALK ) ) {
set_movement_mode( MM_WALK );
}
}

void avatar::cycle_move_mode()
{
unsigned char as_uchar = static_cast<unsigned char>( move_mode );
as_uchar = ( as_uchar + 1 + CMM_COUNT ) % CMM_COUNT;
set_movement_mode( static_cast<character_movemode>( as_uchar ) );
// if a movemode is disabled then just cycle to the next one
if( !movement_mode_is( static_cast<character_movemode>( as_uchar ) ) ) {
as_uchar = ( as_uchar + 1 + CMM_COUNT ) % CMM_COUNT;
set_movement_mode( static_cast<character_movemode>( as_uchar ) );
}
move_mode_str_id current_mm = get_current_movement_mode().id();
auto it = std::find_if( move_modes::get_all().begin(),
move_modes::get_all().end(), [&]( const move_mode & mm ) {
return mm.id == get_current_movement_mode().id();
} );
do {
it++;
if( it == move_modes::get_all().end() ) {
it = move_modes::get_all().begin();
}
} while( ( it->id == MM_NULL.id() ) || !set_movement_mode( it->id ) );
}

bool avatar::wield( item &target )
Expand Down
2 changes: 1 addition & 1 deletion src/avatar.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ class avatar : public player
// Set in npc::talk_to_you for use in further NPC interactions
bool dialogue_by_radio = false;

void set_movement_mode( character_movemode mode ) override;
bool set_movement_mode( const move_mode_id &mode ) override;

// Cycles to the next move mode.
void cycle_move_mode();
Expand Down
7 changes: 4 additions & 3 deletions src/avatar_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "map_iterator.h"
#include "messages.h"
#include "monster.h"
#include "move_mode.h"
#include "npc.h"
#include "options.h"
#include "output.h"
Expand Down Expand Up @@ -104,9 +105,9 @@ bool avatar_action::move( avatar &you, map &m, int dx, int dy, int dz )
}

// by this point we're either walking, running, crouching, or attacking, so update the activity level to match
if( you.movement_mode_is( CMM_WALK ) ) {
if( you.movement_mode_is( MM_WALK ) ) {
you.increase_activity_level( LIGHT_EXERCISE );
} else if( you.movement_mode_is( CMM_CROUCH ) ) {
} else if( you.movement_mode_is( MM_CROUCH ) ) {
you.increase_activity_level( MODERATE_EXERCISE );
} else {
you.increase_activity_level( ACTIVE_EXERCISE );
Expand Down Expand Up @@ -344,7 +345,7 @@ bool avatar_action::move( avatar &you, map &m, int dx, int dy, int dz )
// open it if we are walking
// vault over it if we are running
if( m.passable_ter_furn( dest_loc )
&& you.movement_mode_is( CMM_WALK )
&& you.movement_mode_is( MM_WALK )
&& m.open_door( dest_loc, !m.is_outside( you.pos() ) ) ) {
you.moves -= 100;
// if auto-move is on, continue moving next turn
Expand Down
49 changes: 21 additions & 28 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "monster.h"
#include "morale.h"
#include "morale_types.h"
#include "move_mode.h"
#include "mtype.h"
#include "mutation.h"
#include "options.h"
Expand Down Expand Up @@ -118,7 +119,7 @@ Character::Character() :

*path_settings = pathfinding_settings{ 0, 1000, 1000, 0, true, true, true, false };

move_mode = CMM_WALK;
current_move_mode = MM_WALK;

temp_cur.fill( BODYTEMP_NORM );
frostbite_timer.fill( 0 );
Expand Down Expand Up @@ -604,7 +605,7 @@ void Character::forced_dismount()
add_msg( m_warning, _( "You let go of the grabbed object." ) );
g->u.grab( OBJECT_NONE );
}
set_movement_mode( CMM_WALK );
set_movement_mode( MM_WALK );
g->update_map( g->u );
}
moves -= 150;
Expand Down Expand Up @@ -638,7 +639,7 @@ void Character::dismount()
setpos( *pnt );
g->refresh_all();
mod_moves( -100 );
set_movement_mode( CMM_WALK );
set_movement_mode( MM_WALK );
}
}

Expand Down Expand Up @@ -702,7 +703,8 @@ bool Character::is_limb_broken( hp_part limb ) const

bool Character::can_run()
{
return get_stamina() > 0 && !has_effect( effect_winded ) && get_working_leg_count() >= 2;
return get_stamina() > 0 && !has_effect( effect_winded ) &&
get_working_leg_count() >= current_move_mode.obj().minimum_required_legs;
}

bool Character::move_effects( bool attacking )
Expand Down Expand Up @@ -922,9 +924,14 @@ bool Character::move_effects( bool attacking )
return true;
}

bool Character::movement_mode_is( const character_movemode mode ) const
bool Character::movement_mode_is( const move_mode_id &mode ) const
{
return move_mode == mode;
return current_move_mode->id == mode->id;
}

move_mode_id Character::get_current_movement_mode()
{
return current_move_mode;
}

void Character::add_effect( const efftype_id &eff_id, const time_duration &dur, body_part bp,
Expand Down Expand Up @@ -2385,8 +2392,9 @@ std::vector<std::string> Character::get_overlay_ids() const
rval.push_back( "wielded_" + weapon.typeId() );
}

if( move_mode != CMM_WALK ) {
rval.push_back( character_movemode_str[ move_mode ] );
if( !movement_mode_is( MM_WALK ) ) {
translation name = current_move_mode->name;
rval.push_back( name.translated() );
}
return rval;
}
Expand Down Expand Up @@ -6445,10 +6453,9 @@ void Character::burn_move_stamina( int moves )
}
}
burn_ratio += overburden_percentage;
if( move_mode == CMM_RUN ) {
burn_ratio = burn_ratio * 7;
}
mod_stamina( -( ( moves * burn_ratio ) / 100.0 ) * stamina_move_cost_modifier() );
burn_ratio = burn_ratio * current_move_mode->stamina_burn_multiplier;

mod_stamina( -( ( moves * burn_ratio ) / 100.0 ) * current_move_mode->stamina_burn_multiplier );
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
mod_stamina( -( ( moves * burn_ratio ) / 100.0 ) * current_move_mode->stamina_burn_multiplier );
mod_stamina( -moves * burn_ratio / 100.0 * current_move_mode->stamina_burn_multiplier );

add_msg( m_debug, "Stamina burn: %d", -( ( moves * burn_ratio ) / 100 ) );
// Chance to suffer pain if overburden and stamina runs out or has trait BADBACK
// Starts at 1 in 25, goes down by 5 for every 50% more carried
Expand All @@ -6462,21 +6469,6 @@ void Character::burn_move_stamina( int moves )
}
}

float Character::stamina_move_cost_modifier() const
{
// Both walk and run speed drop to half their maximums as stamina approaches 0.
// Convert stamina to a float first to allow for decimal place carrying
float stamina_modifier = ( static_cast<float>( get_stamina() ) / get_stamina_max() + 1 ) / 2;
if( move_mode == CMM_RUN && get_stamina() > 0 ) {
// Rationale: Average running speed is 2x walking speed. (NOT sprinting)
stamina_modifier *= 2.0;
}
if( move_mode == CMM_CROUCH ) {
stamina_modifier *= 0.5;
}
return stamina_modifier;
}

void Character::update_stamina( int turns )
{
const int current_stim = get_stim();
Expand Down Expand Up @@ -6519,7 +6511,8 @@ void Character::update_stamina( int turns )
}
}

mod_stamina( roll_remainder( stamina_recovery * turns / stamina_move_cost_modifier() ) );
mod_stamina( roll_remainder( stamina_recovery * turns /
current_move_mode->stamina_burn_multiplier ) );
add_msg( m_debug, "Stamina recovery: %d", roll_remainder( stamina_recovery * turns ) );
// Cap at max
set_stamina( std::min( std::max( get_stamina(), 0 ), max_stam ) );
Expand Down
Loading