From d0c2c2a4e3aacf242645f32ab5efd5fde07df9da Mon Sep 17 00:00:00 2001 From: ymber Date: Mon, 23 Dec 2019 13:54:04 +0000 Subject: [PATCH 01/26] Add item optionals to monster --- src/monster.cpp | 22 ++++++++++++++++------ src/monster.h | 3 +++ src/savegame_json.cpp | 6 ++++++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/monster.cpp b/src/monster.cpp index 0c3e76417bc7f..cfaf03d0618bb 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -2166,12 +2166,22 @@ void monster::die( Creature *nkiller ) ch->rem_morale( MORALE_KILLER_NEED_TO_KILL ); } } - // We were tied up at the moment of death, add a short rope to inventory - if( has_effect( effect_tied ) ) { - if( tied_item ) { - add_item( *tied_item ); - tied_item = cata::nullopt; - } + // Drop items stored in optionals + if( tack_item ) { + add_item( *tack_item ); + tack_item = cata::nullopt; + } + if( armor_item ) { + add_item( *armor_item ); + armor_item = cata::nullopt; + } + if( storage_item ) { + add_item( *storage_item ); + storage_item = cata::nullopt; + } + if( tied_item ) { + add_item( *tied_item ); + tied_item = cata::nullopt; } if( has_effect( effect_lightsnare ) ) { add_item( item( "string_36", 0 ) ); diff --git a/src/monster.h b/src/monster.h index f1e13b3ed9a17..c2c6b6dcd10ec 100644 --- a/src/monster.h +++ b/src/monster.h @@ -437,6 +437,9 @@ class monster : public Creature character_id mounted_player_id; // id of player that is mounting this creature ( for save/load ) character_id dragged_foe_id; // id of character being dragged by the monster cata::optional tied_item; // item used to tie the monster + cata::optional tack_item; // item representing saddle and reins and such + cata::optional armor_item; // item of armor the monster may be wearing + cata::optional storage_item; // storage item for monster carrying items cata::optional battery_item; // item to power mechs // DEFINING VALUES int friendly; diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 3545b43368581..0a7fe9b88b57f 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -1820,6 +1820,9 @@ void monster::load( const JsonObject &data ) wander_pos.z = position.z; } data.read( "tied_item", tied_item ); + data.read( "tack_item", tack_item ); + data.read( "armor_item", armor_item ); + data.read( "storage_item", storage_item ); data.read( "hp", hp ); data.read( "battery_item", battery_item ); @@ -1955,6 +1958,9 @@ void monster::store( JsonOut &json ) const json.member( "hallucination", hallucination ); json.member( "stairscount", staircount ); json.member( "tied_item", tied_item ); + json.member( "tack_item", tack_item ); + json.member( "armor_item", armor_item ); + json.member( "storage_item", storage_item ); json.member( "battery_item", battery_item ); // Store the relative position of the goal so it loads correctly after a map shift. json.member( "destination", goal - pos() ); From d0e91d024a9a88dacbafb1c7bea4674d6d084047 Mon Sep 17 00:00:00 2001 From: ymber Date: Mon, 23 Dec 2019 15:26:39 +0000 Subject: [PATCH 02/26] Add monexamine::get_weight_on_monster --- src/monexamine.cpp | 19 +++++++++++++++++++ src/monexamine.h | 3 +++ 2 files changed, 22 insertions(+) diff --git a/src/monexamine.cpp b/src/monexamine.cpp index 8cbe1cdf03e96..be639681f0e03 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -26,6 +26,7 @@ #include "string_input_popup.h" #include "translations.h" #include "ui.h" +#include "units.h" #include "bodypart.h" #include "debug.h" #include "enums.h" @@ -250,6 +251,24 @@ bool monexamine::pet_menu( monster &z ) return true; } +units::mass monexamine::get_weight_on_monster( monster &z ) +{ + units::mass total_weight = 0_gram; + if( z.tack_item ) { + total_weight += z.tack_item->weight(); + } + if( z.storage_item ) { + total_weight += z.storage_item->weight(); + } + if( z.armor_item ) { + total_weight += z.armor_item->weight(); + } + for( const item &it : z.inv ) { + total_weight += it.weight(); + } + return total_weight; +} + int monexamine::pet_armor_pos( monster &z ) { auto filter = [z]( const item & it ) { diff --git a/src/monexamine.h b/src/monexamine.h index beae4f9d0017a..60b0ee7a2e410 100644 --- a/src/monexamine.h +++ b/src/monexamine.h @@ -2,6 +2,8 @@ #ifndef MONEXAMINE_H #define MONEXAMINE_H +#include "units.h" + class monster; namespace monexamine @@ -17,6 +19,7 @@ void rename_pet( monster &z ); void attach_bag_to( monster &z ); void dump_items( monster &z ); bool give_items_to( monster &z ); +units::mass get_weight_on_monster( monster &z ); int pet_armor_pos( monster &z ); bool add_armor( monster &z ); void remove_armor( monster &z ); From e7e710a028399c8b4aa5aad7a87b01006b18253e Mon Sep 17 00:00:00 2001 From: ymber Date: Mon, 23 Dec 2019 15:54:26 +0000 Subject: [PATCH 03/26] Use monster::armor_item for animal armor --- src/monexamine.cpp | 39 +++++++++++++-------------------------- src/monster.cpp | 9 +++------ 2 files changed, 16 insertions(+), 32 deletions(-) diff --git a/src/monexamine.cpp b/src/monexamine.cpp index be639681f0e03..80e7addba44ca 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -602,21 +602,18 @@ bool monexamine::add_armor( monster &z ) } item &armor = g->u.i_at( pos ); - units::mass max_weight = z.weight_capacity(); - for( auto &i : z.inv ) { - max_weight -= i.weight(); - } - if( max_weight <= 0_gram ) { + units::mass max_weight = z.weight_capacity() - get_weight_on_monster( z ); + if( max_weight <= armor.weight() ) { add_msg( _( "Your %1$s is too heavy for your %2$s." ), armor.tname( 1 ), pet_name ); return true; } armor.set_var( "pet_armor", "true" ); - z.add_item( armor ); - add_msg( _( "You put the %1$s on your %2$s, protecting it from future harm." ), - armor.display_name(), pet_name ); + z.armor_item = armor; + add_msg( _( "You put the %1$s on your %2$s." ), armor.display_name(), pet_name ); g->u.i_rem( pos ); z.add_effect( effect_monster_armor, 1_turns, num_bp, true ); + // TODO: armoring a horse takes a lot longer than 2 seconds. This should be a long action. g->u.moves -= 200; return true; } @@ -630,24 +627,14 @@ void monexamine::remove_harness( monster &z ) void monexamine::remove_armor( monster &z ) { std::string pet_name = z.get_name(); - bool found_armor = false; - int pos = 0; - for( auto &it : z.inv ) { - if( it.is_pet_armor( true ) ) { - found_armor = true; - it.erase_var( "pet_armor" ); - g->m.add_item_or_charges( z.pos(), it ); - //~ %1$s: armor name, %2$s: pet name - add_msg( m_info, pgettext( "pet armor", "You remove the %1$s from %2$s." ), it.tname( 1 ), - pet_name ); - z.inv.erase( z.inv.begin() + pos ); - g->u.moves -= 200; - break; - } else { - pos += 1; - } - } - if( !found_armor ) { + if( z.armor_item ) { + z.armor_item->erase_var( "pet_armor" ); + g->m.add_item_or_charges( z.pos(), z.armor_item.value() ); + add_msg( _( "You remove the %1$s from %2$s." ), z.armor_item->display_name(), pet_name ); + z.armor_item = cata::nullopt; + // TODO: removing armor from a horse takes a lot longer than 2 seconds. This should be a long action. + g->u.moves -= 200; + } else { add_msg( m_bad, _( "Your %1$s isn't wearing armor!" ), pet_name ); } z.remove_effect( effect_monster_armor ); diff --git a/src/monster.cpp b/src/monster.cpp index cfaf03d0618bb..e8ce5a4ec8bf0 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -1759,14 +1759,11 @@ std::string monster::get_effect_status() const int monster::get_worn_armor_val( damage_type dt ) const { - if( !has_effect( effect_monster_armor ) || inv.empty() ) { + if( !has_effect( effect_monster_armor ) ) { return 0; } - for( const item &armor : inv ) { - if( !armor.is_pet_armor( true ) ) { - continue; - } - return armor.damage_resist( dt ); + if( armor_item ) { + return armor_item->damage_resist( dt ); } return 0; } From 3111038d141ccefc809594add8df02949fcc35bb Mon Sep 17 00:00:00 2001 From: ymber Date: Mon, 23 Dec 2019 16:10:10 +0000 Subject: [PATCH 04/26] Use monster::tack_item for saddles --- src/monexamine.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/monexamine.cpp b/src/monexamine.cpp index 80e7addba44ca..af779c784a9d9 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -399,10 +399,11 @@ void monexamine::attach_or_remove_saddle( monster &z ) { if( z.has_effect( effect_saddled ) ) { z.remove_effect( effect_saddled ); - item riding_saddle( "riding_saddle", 0 ); - g->u.i_add( riding_saddle ); + z.tack_item = cata::nullopt; + g->u.i_add( item( "riding_saddle" ) ); } else { z.add_effect( effect_saddled, 1_turns, num_bp, true ); + z.tack_item = item( "riding_saddle" ); g->u.use_amount( "riding_saddle", 1 ); } } From ef292bdc6dbdd473ee56ed2315bfa02e90eea433 Mon Sep 17 00:00:00 2001 From: ymber Date: Mon, 23 Dec 2019 17:38:40 +0000 Subject: [PATCH 05/26] Move current weight calculator to monster --- src/monexamine.cpp | 20 +------------------- src/monexamine.h | 1 - src/monster.cpp | 17 +++++++++++++++++ src/monster.h | 2 ++ 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/monexamine.cpp b/src/monexamine.cpp index af779c784a9d9..b12b457c08c8e 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -251,24 +251,6 @@ bool monexamine::pet_menu( monster &z ) return true; } -units::mass monexamine::get_weight_on_monster( monster &z ) -{ - units::mass total_weight = 0_gram; - if( z.tack_item ) { - total_weight += z.tack_item->weight(); - } - if( z.storage_item ) { - total_weight += z.storage_item->weight(); - } - if( z.armor_item ) { - total_weight += z.armor_item->weight(); - } - for( const item &it : z.inv ) { - total_weight += it.weight(); - } - return total_weight; -} - int monexamine::pet_armor_pos( monster &z ) { auto filter = [z]( const item & it ) { @@ -603,7 +585,7 @@ bool monexamine::add_armor( monster &z ) } item &armor = g->u.i_at( pos ); - units::mass max_weight = z.weight_capacity() - get_weight_on_monster( z ); + units::mass max_weight = z.weight_capacity() - z.get_carried_weight(); if( max_weight <= armor.weight() ) { add_msg( _( "Your %1$s is too heavy for your %2$s." ), armor.tname( 1 ), pet_name ); return true; diff --git a/src/monexamine.h b/src/monexamine.h index 60b0ee7a2e410..3166295a5decf 100644 --- a/src/monexamine.h +++ b/src/monexamine.h @@ -19,7 +19,6 @@ void rename_pet( monster &z ); void attach_bag_to( monster &z ); void dump_items( monster &z ); bool give_items_to( monster &z ); -units::mass get_weight_on_monster( monster &z ); int pet_armor_pos( monster &z ); bool add_armor( monster &z ); void remove_armor( monster &z ); diff --git a/src/monster.cpp b/src/monster.cpp index e8ce5a4ec8bf0..acb657a178dc3 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -2646,6 +2646,23 @@ void monster::add_msg_player_or_npc( const game_message_type type, } } +units::mass monster::get_carried_weight() { + units::mass total_weight = 0_gram; + if( tack_item ) { + total_weight += tack_item->weight(); + } + if( storage_item ) { + total_weight += storage_item->weight(); + } + if( armor_item ) { + total_weight += armor_item->weight(); + } + for( const item &it : inv ) { + total_weight += it.weight(); + } + return total_weight; +} + bool monster::is_dead() const { return dead || is_dead_state(); diff --git a/src/monster.h b/src/monster.h index c2c6b6dcd10ec..987f68a865841 100644 --- a/src/monster.h +++ b/src/monster.h @@ -441,6 +441,8 @@ class monster : public Creature cata::optional armor_item; // item of armor the monster may be wearing cata::optional storage_item; // storage item for monster carrying items cata::optional battery_item; // item to power mechs + units::mass get_carried_weight(); + // DEFINING VALUES int friendly; int anger = 0; From 42fc875e470d7ed62bec867aaf3d7a5b2f060f98 Mon Sep 17 00:00:00 2001 From: ymber Date: Mon, 23 Dec 2019 20:14:08 +0000 Subject: [PATCH 06/26] Refactor bags on monsters --- src/activity_item_handling.cpp | 19 +++-- src/monexamine.cpp | 125 +++++++++++++++------------------ src/monexamine.h | 1 + 3 files changed, 64 insertions(+), 81 deletions(-) diff --git a/src/activity_item_handling.cpp b/src/activity_item_handling.cpp index 4d4bce6ced17d..8e138b0a1dfdc 100644 --- a/src/activity_item_handling.cpp +++ b/src/activity_item_handling.cpp @@ -220,24 +220,21 @@ static void pass_to_ownership_handling( item obj, player *p ) static void stash_on_pet( const std::list &items, monster &pet, player *p ) { // Add volume of the bag itself since it is going to be subtracted later in the for-each loop. - units::volume remaining_volume = pet.inv.empty() ? 0_ml : - pet.inv.front().get_storage() + pet.inv.front().volume(); - units::mass remaining_weight = pet.weight_capacity(); + units::volume remaining_volume = pet.storage_item.value().volume(); + units::mass remaining_weight = pet.weight_capacity() - pet.get_carried_weight(); - for( const auto &it : pet.inv ) { + for( const item &it : pet.inv ) { remaining_volume -= it.volume(); - remaining_weight -= it.weight(); } - for( auto &it : items ) { - pet.add_effect( effect_controlled, 5_turns ); + for( const item &it : items ) { if( it.volume() > remaining_volume ) { - add_msg( m_bad, _( "%1$s did not fit and fell to the %2$s." ), - it.display_name(), g->m.name( pet.pos() ) ); + add_msg( m_bad, _( "%1$s did not fit and fell to the %2$s." ), it.display_name(), + g->m.name( pet.pos() ) ); g->m.add_item_or_charges( pet.pos(), it ); } else if( it.weight() > remaining_weight ) { - add_msg( m_bad, _( "%1$s is too heavy and fell to the %2$s." ), - it.display_name(), g->m.name( pet.pos() ) ); + add_msg( m_bad, _( "%1$s is too heavy and fell to the %2$s." ), it.display_name(), + g->m.name( pet.pos() ) ); g->m.add_item_or_charges( pet.pos(), it ); } else { pet.add_item( it ); diff --git a/src/monexamine.cpp b/src/monexamine.cpp index b12b457c08c8e..19a763b7c8f82 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -59,6 +59,7 @@ bool monexamine::pet_menu( monster &z ) push_zlave, rename, attach_bag, + remove_bag, drop_all, give_items, mon_armor_add, @@ -89,12 +90,15 @@ bool monexamine::pet_menu( monster &z ) amenu.addentry( swap_pos, true, 's', _( "Swap positions" ) ); amenu.addentry( push_zlave, true, 'p', _( "Push %s" ), pet_name ); amenu.addentry( rename, true, 'e', _( "Rename" ) ); - if( z.has_effect( effect_has_bag ) || z.has_effect( effect_monster_armor ) ) { + if( z.has_effect( effect_has_bag ) ) { amenu.addentry( give_items, true, 'g', _( "Place items into bag" ) ); - amenu.addentry( drop_all, true, 'd', _( "Drop all items except armor" ) ); + amenu.addentry( remove_bag, true, 'b', _( "Remove bag from %s" ), pet_name ); + if( !z.inv.empty() ) { + amenu.addentry( drop_all, true, 'd', _( "Remove all items from bag" ) ); + } } if( !z.has_effect( effect_has_bag ) && !z.has_flag( MF_RIDEABLE_MECH ) ) { - amenu.addentry( attach_bag, true, 'b', _( "Attach bag" ) ); + amenu.addentry( attach_bag, true, 'b', _( "Attach bag to %s" ), pet_name ); } if( z.has_effect( effect_harnessed ) ) { amenu.addentry( mon_harness_remove, true, 'H', _( "Remove vehicle harness from %s" ), pet_name ); @@ -199,6 +203,9 @@ bool monexamine::pet_menu( monster &z ) case attach_bag: attach_bag_to( z ); break; + case remove_bag: + remove_bag_from( z ); + break; case drop_all: dump_items( z ); break; @@ -478,41 +485,39 @@ void monexamine::attach_bag_to( monster &z ) } item &it = *loc; - // force it to the front of the monster's inventory in case they have armor on - z.inv.insert( z.inv.begin(), it ); - add_msg( _( "You mount the %1$s on your %2$s, ready to store gear." ), - it.display_name(), pet_name ); - g->u.i_rem( &*loc ); + z.storage_item = it; + add_msg( _( "You mount the %1$s on your %2$s." ), it.display_name(), pet_name ); + g->u.i_rem( &it ); z.add_effect( effect_has_bag, 1_turns, num_bp, true ); // Update encumbrance in case we were wearing it g->u.flag_encumbrance(); g->u.moves -= 200; } -void monexamine::dump_items( monster &z ) +void monexamine::remove_bag_from( monster &z ) { std::string pet_name = z.get_name(); - int armor_index = 0; - bool found_armor = false; - for( auto &it : z.inv ) { - if( z.has_effect( effect_monster_armor ) && it.is_pet_armor( true ) ) { - found_armor = true; - } else { - armor_index += 1; - g->m.add_item_or_charges( z.pos(), it ); + if( z.storage_item ) { + if( !z.inv.empty() ) { + dump_items( z ); } + g->m.add_item_or_charges( g->u.pos(), z.storage_item.value() ); + add_msg( _( "You remove the %1$s from %2$s." ), z.storage_item->display_name(), pet_name ); + z.storage_item = cata::nullopt; + g->u.moves -= 200; + } else { + add_msg( m_bad, _( "Your %1$s doesn't have a bag!" ), pet_name ); } - item armor; - if( found_armor ) { - armor = z.inv[ armor_index ]; - } - - z.inv.clear(); z.remove_effect( effect_has_bag ); - if( found_armor ) { - armor.set_var( "pet_armor", "true" ); - z.add_item( armor ); +} + +void monexamine::dump_items( monster &z ) +{ + std::string pet_name = z.get_name(); + for( auto &it : z.inv ) { + g->m.add_item_or_charges( g->u.pos(), it ); } + z.inv.clear(); add_msg( _( "You dump the contents of the %s's bag on the ground." ), pet_name ); g->u.moves -= 200; } @@ -520,57 +525,37 @@ void monexamine::dump_items( monster &z ) bool monexamine::give_items_to( monster &z ) { std::string pet_name = z.get_name(); - if( z.inv.empty() ) { + if( !z.storage_item ) { add_msg( _( "There is no container on your %s to put things in!" ), pet_name ); return true; } - int armor_index = INT_MIN; - if( z.has_effect( effect_monster_armor ) ) { - armor_index = 0; - for( auto &it : z.inv ) { - if( it.is_pet_armor( true ) ) { - break; - } else { - armor_index += 1; - } - } - } - - // might be a bag, might be armor - item &storage = z.inv[0]; - units::volume max_cap = storage.get_storage(); - units::mass max_weight = z.weight_capacity() - storage.weight(); - if( armor_index != 0 && armor_index != INT_MIN ) { - item &armor = z.inv[armor_index]; - max_cap += armor.get_storage() + armor.volume(); - max_weight -= armor.weight(); - } - - if( z.inv.size() > 1 ) { - for( auto &i : z.inv ) { - max_cap -= i.volume(); - max_weight -= i.weight(); + item &storage = z.storage_item.value(); + units::mass max_weight = z.weight_capacity() - z.get_carried_weight(); + units::volume max_volume = storage.get_storage(); + for( const item &it : z.inv ) { + max_volume -= it.volume(); + } + + std::list> items = game_menus::inv::multidrop( g->u ); + std::list> to_move; + for( const std::pair &itq : items ) { + const item &it = g->u.i_at( itq.first ); + units::volume item_volume = it.volume() * itq.second; + units::mass item_weight = it.weight() * itq.second; + if( max_weight < item_weight ) { + add_msg( _( "The %1$s is too heavy for the %2$s to carry." ), it.tname(), pet_name ); + continue; + } else if( max_volume < item_volume ) { + add_msg( _( "The %1$s is too big to fit in the %2$s." ), it.tname(), storage.tname() ); + continue; + } else { + to_move.insert( to_move.end(), itq ); } } + z.add_effect( effect_controlled, 5_turns ); + g->u.drop( to_move, z.pos(), true ); - if( max_weight <= 0_gram ) { - add_msg( _( "%1$s is overburdened. You can't transfer your %2$s." ), - pet_name, storage.tname( 1 ) ); - return true; - } - if( max_cap <= 0_ml ) { - add_msg( _( "There's no room in your %1$s's %2$s for that, it's too bulky!" ), - pet_name, storage.tname( 1 ) ); - return true; - } - - const auto items_to_stash = game_menus::inv::multidrop( g->u ); - if( !items_to_stash.empty() ) { - g->u.drop( items_to_stash, z.pos(), true ); - z.add_effect( effect_controlled, 5_turns ); - return true; - } return false; } diff --git a/src/monexamine.h b/src/monexamine.h index 3166295a5decf..831c0dfccc6d7 100644 --- a/src/monexamine.h +++ b/src/monexamine.h @@ -17,6 +17,7 @@ void swap( monster &z ); void push( monster &z ); void rename_pet( monster &z ); void attach_bag_to( monster &z ); +void remove_bag_from( monster &z ); void dump_items( monster &z ); bool give_items_to( monster &z ); int pet_armor_pos( monster &z ); From dfa990199222cf6c77a19f929678f46d0067a5ab Mon Sep 17 00:00:00 2001 From: ymber Date: Mon, 23 Dec 2019 20:24:21 +0000 Subject: [PATCH 07/26] Misc updates to monexamine::pet_menu --- src/monexamine.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/monexamine.cpp b/src/monexamine.cpp index 19a763b7c8f82..da0436b6538e4 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -96,8 +96,7 @@ bool monexamine::pet_menu( monster &z ) if( !z.inv.empty() ) { amenu.addentry( drop_all, true, 'd', _( "Remove all items from bag" ) ); } - } - if( !z.has_effect( effect_has_bag ) && !z.has_flag( MF_RIDEABLE_MECH ) ) { + } else if( !z.has_flag( MF_RIDEABLE_MECH ) ) { amenu.addentry( attach_bag, true, 'b', _( "Attach bag to %s" ), pet_name ); } if( z.has_effect( effect_harnessed ) ) { @@ -153,13 +152,10 @@ bool monexamine::pet_menu( monster &z ) amenu.addentry( mount, false, 'r', _( "%s is too small to carry your weight" ), pet_name ); } else if( g->u.get_skill_level( skill_survival ) < 1 ) { amenu.addentry( mount, false, 'r', _( "You have no knowledge of riding at all" ) ); - } else if( g->u.get_weight() >= z.get_weight() / 5 ) { + } else if( g->u.get_weight() >= z.get_weight() * z.get_mountable_weight_ratio() ) { amenu.addentry( mount, false, 'r', _( "You are too heavy to mount %s" ), pet_name ); } else if( !z.has_effect( effect_saddled ) && g->u.get_skill_level( skill_survival ) < 4 ) { amenu.addentry( mount, false, 'r', _( "You are not skilled enough to ride without a saddle" ) ); - } else if( z.has_effect( effect_saddled ) && g->u.get_skill_level( skill_survival ) < 1 ) { - amenu.addentry( mount, false, 'r', _( "Despite the saddle, you still don't know how to ride %s" ), - pet_name ); } } else { const itype &type = *item::find_type( z.type->mech_battery ); From e5993361a2990e42e46c588244ddd8e85241395b Mon Sep 17 00:00:00 2001 From: ymber Date: Mon, 23 Dec 2019 21:41:00 +0000 Subject: [PATCH 08/26] Use TACK flag instead of hardcoded itype_id --- data/json/itemgroups/misc.json | 2 +- data/json/itemgroups/tools.json | 2 +- data/json/items/migration.json | 5 ++++ data/json/items/tools.json | 15 +++++------ .../isherwood_farms/cabin_isherwood.json | 2 +- .../isherwood_farm/NPC_Jesse_Isherwood.json | 4 +-- data/json/professions.json | 2 +- data/json/recipes/other/tool.json | 7 +++--- doc/JSON_FLAGS.md | 1 + src/monexamine.cpp | 25 +++++++++++++------ src/monexamine.h | 1 + src/monster.cpp | 13 +++------- 12 files changed, 46 insertions(+), 33 deletions(-) diff --git a/data/json/itemgroups/misc.json b/data/json/itemgroups/misc.json index 8b82da7eab8a3..690a78a1a51e5 100644 --- a/data/json/itemgroups/misc.json +++ b/data/json/itemgroups/misc.json @@ -147,6 +147,6 @@ "id": "horse_gear", "type": "item_group", "//": "Horse vehicle items", - "items": [ [ "riding_saddle", 50 ], [ "yoke_harness", 50 ] ] + "items": [ [ "horse_tack", 50 ], [ "yoke_harness", 50 ] ] } ] diff --git a/data/json/itemgroups/tools.json b/data/json/itemgroups/tools.json index 1fa7712c9e83a..e088682ea71fa 100644 --- a/data/json/itemgroups/tools.json +++ b/data/json/itemgroups/tools.json @@ -305,7 +305,7 @@ [ "chem_hexamine", 10 ], [ "esbit_stove", 15 ], [ "mess_tin", 5 ], - [ "riding_saddle", 3 ], + [ "horse_tack", 3 ], [ "saddlebag", 5 ], [ "lifestraw", 3 ], [ "acetylene_machine", 2 ] diff --git a/data/json/items/migration.json b/data/json/items/migration.json index ea376a7942e66..76198866d19ce 100644 --- a/data/json/items/migration.json +++ b/data/json/items/migration.json @@ -958,5 +958,10 @@ "id": "40mm_teargas", "type": "MIGRATION", "replace": "40x46mm_m651" + }, + { + "id": "riding_saddle", + "type": "MIGRATION", + "replace": "horse_tack" } ] diff --git a/data/json/items/tools.json b/data/json/items/tools.json index 772ffb8685549..747374b0f16b1 100644 --- a/data/json/items/tools.json +++ b/data/json/items/tools.json @@ -26,18 +26,19 @@ "flags": [ "RADIO_MODABLE", "RADIO_INVOKE_PROC", "BOMB", "GRENADE" ] }, { - "id": "riding_saddle", + "id": "horse_tack", "type": "TOOL", - "name": "riding saddle", - "description": "A saddle that can be placed on a tamed animal that is capable of being ridden.", - "weight": "800 g", - "volume": "2 L", + "name": "horse tack", + "description": "A saddle, bridle, and associated tack that can be placed on a tamed animal that is capable of being ridden.", + "weight": "2 kg", + "volume": "7 L", "price": 0, "to_hit": -1, "bashing": 5, - "material": [ "leather" ], + "material": [ "leather", "steel" ], "symbol": "M", - "color": "yellow" + "color": "yellow", + "flags": [ "TACK" ] }, { "id": "EMPbomb_act", diff --git a/data/json/mapgen/isherwood_farms/cabin_isherwood.json b/data/json/mapgen/isherwood_farms/cabin_isherwood.json index a9ce290580fd4..0efc2782ac4bb 100644 --- a/data/json/mapgen/isherwood_farms/cabin_isherwood.json +++ b/data/json/mapgen/isherwood_farms/cabin_isherwood.json @@ -159,7 +159,7 @@ "liquids": { "l": { "liquid": "water_clean", "amount": [ 0, 100 ] } }, "place_loot": [ { "item": "cattlefodder", "x": [ 17, 18 ], "y": [ 2, 4 ], "chance": 100 }, - { "item": "riding_saddle", "x": 15, "y": 2, "chance": 100 }, + { "item": "horse_tack", "x": 15, "y": 2, "chance": 100 }, { "item": "stepladder", "x": 15, "y": 4, "chance": 100 }, { "item": "straw_pile", "x": [ 17, 18 ], "y": [ 2, 4 ], "chance": 30, "repeat": [ 2, 4 ] } ], diff --git a/data/json/npcs/isherwood_farm/NPC_Jesse_Isherwood.json b/data/json/npcs/isherwood_farm/NPC_Jesse_Isherwood.json index 8beb529b3c52f..9869e402a3e7c 100644 --- a/data/json/npcs/isherwood_farm/NPC_Jesse_Isherwood.json +++ b/data/json/npcs/isherwood_farm/NPC_Jesse_Isherwood.json @@ -206,7 +206,7 @@ "success_lie": "Show me the bodies.", "failure": "It was a lost cause anyways..." }, - "end": { "opinion": { "trust": 1, "value": 1 }, "effect": [ { "u_buy_item": "riding_saddle", "count": 1 } ] } + "end": { "opinion": { "trust": 1, "value": 1 }, "effect": [ { "u_buy_item": "horse_tack", "count": 1 } ] } }, { "id": "MISSION_ISHERWOOD_JESSE_2", @@ -232,7 +232,7 @@ "success_lie": "Show me the bodies.", "failure": "It was a lost cause anyways..." }, - "end": { "opinion": { "trust": 1, "value": 1 }, "effect": [ { "u_buy_item": "riding_saddle", "count": 1 } ] } + "end": { "opinion": { "trust": 1, "value": 1 }, "effect": [ { "u_buy_item": "horse_tack", "count": 1 } ] } }, { "id": "MISSION_ISHERWOOD_JESSE_2", diff --git a/data/json/professions.json b/data/json/professions.json index b4eda0c9233a0..526e293de8856 100644 --- a/data/json/professions.json +++ b/data/json/professions.json @@ -3881,7 +3881,7 @@ "cowboy_hat", "boots_western", "wristwatch", - "riding_saddle", + "horse_tack", "pockknife", "cattlefodder", "cattlefodder", diff --git a/data/json/recipes/other/tool.json b/data/json/recipes/other/tool.json index b0af9744cae1d..ffd648c685eb8 100644 --- a/data/json/recipes/other/tool.json +++ b/data/json/recipes/other/tool.json @@ -209,16 +209,15 @@ ] }, { - "result": "riding_saddle", + "result": "horse_tack", "type": "recipe", "category": "CC_OTHER", "subcategory": "CSC_OTHER_TOOLS", - "skill_used": "tailor", - "difficulty": 4, + "skills_required": [ [ "fabrication", 3 ], [ "tailor", 4 ] ], "time": 300000, "book_learn": [ [ "textbook_tailor", 4 ], [ "manual_tailor", 5 ], [ "tailor_portfolio", 4 ] ], "using": [ [ "sewing_standard", 100 ], [ "cordage", 2 ] ], - "components": [ [ [ "leather", 30 ], [ "tanned_hide", 5 ], [ "fur", 30 ], [ "tanned_pelt", 5 ] ] ] + "components": [ [ [ "leather", 30 ], [ "tanned_hide", 5 ], [ "fur", 30 ], [ "tanned_pelt", 5 ] ], [ [ "wire", 2 ] ] ] }, { "result": "jack", diff --git a/doc/JSON_FLAGS.md b/doc/JSON_FLAGS.md index ebab90d2fffba..45ca1278ec746 100644 --- a/doc/JSON_FLAGS.md +++ b/doc/JSON_FLAGS.md @@ -679,6 +679,7 @@ List of known flags, used in both `terrain.json` and `furniture.json`. - ```REQUIRES_TINDER``` ... Requires tinder to be present on the tile this item tries to start a fire on. - ```SLEEP_AID``` ... This item helps in sleeping. - ```SLOW_WIELD``` ... Has an additional time penalty upon wielding. For melee weapons and guns this is offset by the relevant skill. Stacks with "NEEDS_UNFOLD". +- ```TACK``` ... Item can be used as tack for a mount. - ```TIE_UP``` ... Item can be used to tie up a creature. - ```TINDER``` ... This item can be used as tinder for lighting a fire with a REQUIRES_TINDER flagged firestarter. - ```TRADER_AVOID``` ... NPCs will not start with this item. Use this for active items (e.g. flashlight (on)), dangerous items (e.g. active bomb), fake item or unusual items (e.g. unique quest item). diff --git a/src/monexamine.cpp b/src/monexamine.cpp index da0436b6538e4..971942dc00a7e 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -132,12 +132,12 @@ bool monexamine::pet_menu( monster &z ) amenu.addentry( milk, true, 'm', _( "Milk %s" ), pet_name ); } if( z.has_flag( MF_PET_MOUNTABLE ) && !z.has_effect( effect_saddled ) && - g->u.has_amount( "riding_saddle", 1 ) && g->u.get_skill_level( skill_survival ) >= 1 ) { - amenu.addentry( attach_saddle, true, 'h', _( "Attach a saddle to %s" ), pet_name ); + g->u.has_item_with_flag( "TACK" ) && g->u.get_skill_level( skill_survival ) >= 1 ) { + amenu.addentry( attach_saddle, true, 'h', _( "Tack up %s" ), pet_name ); } else if( z.has_flag( MF_PET_MOUNTABLE ) && z.has_effect( effect_saddled ) ) { - amenu.addentry( remove_saddle, true, 'h', _( "Remove the saddle from %s" ), pet_name ); + amenu.addentry( remove_saddle, true, 'h', _( "Remove tack from %s" ), pet_name ); } else if( z.has_flag( MF_PET_MOUNTABLE ) && !z.has_effect( effect_saddled ) && - g->u.has_amount( "riding_saddle", 1 ) && g->u.get_skill_level( skill_survival ) < 1 ) { + g->u.has_item_with_flag( "TACK" ) && g->u.get_skill_level( skill_survival ) < 1 ) { amenu.addentry( remove_saddle, false, 'h', _( "You don't know how to saddle %s" ), pet_name ); } if( z.has_flag( MF_PAY_BOT ) ) { @@ -267,6 +267,17 @@ int monexamine::pet_armor_pos( monster &z ) return g->u.get_item_position( loc.get_item() ); } +int monexamine::tack_pos() +{ + auto filter = []( const item & it ) { + return it.has_flag( "TACK" ); + }; + + item_location loc = game_menus::inv::titled_filter_menu( filter, g->u, _( "Tack" ) ); + + return g->u.get_item_position( loc.get_item() ); +} + void monexamine::remove_battery( monster &z ) { g->m.add_item_or_charges( g->u.pos(), *z.battery_item ); @@ -384,12 +395,12 @@ void monexamine::attach_or_remove_saddle( monster &z ) { if( z.has_effect( effect_saddled ) ) { z.remove_effect( effect_saddled ); + g->u.i_add( z.tack_item.value() ); z.tack_item = cata::nullopt; - g->u.i_add( item( "riding_saddle" ) ); } else { z.add_effect( effect_saddled, 1_turns, num_bp, true ); - z.tack_item = item( "riding_saddle" ); - g->u.use_amount( "riding_saddle", 1 ); + z.tack_item = g->u.i_at( tack_pos() ); + g->u.use_amount( z.tack_item.value().typeId(), 1 ); } } diff --git a/src/monexamine.h b/src/monexamine.h index 831c0dfccc6d7..eea0062555786 100644 --- a/src/monexamine.h +++ b/src/monexamine.h @@ -21,6 +21,7 @@ void remove_bag_from( monster &z ); void dump_items( monster &z ); bool give_items_to( monster &z ); int pet_armor_pos( monster &z ); +int tack_pos(); bool add_armor( monster &z ); void remove_armor( monster &z ); void remove_harness( monster &z ); diff --git a/src/monster.cpp b/src/monster.cpp index acb657a178dc3..36edd30fb817e 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -2127,14 +2127,8 @@ void monster::die( Creature *nkiller ) return; } // We were carrying a creature, deposit the rider - if( has_effect( effect_ridden ) ) { - if( has_effect( effect_saddled ) ) { - item riding_saddle( "riding_saddle", 0 ); - g->m.add_item_or_charges( pos(), riding_saddle ); - } - if( mounted_player ) { - mounted_player->forced_dismount(); - } + if( has_effect( effect_ridden ) && mounted_player ) { + mounted_player->forced_dismount(); } g->set_critter_died(); dead = true; @@ -2646,7 +2640,8 @@ void monster::add_msg_player_or_npc( const game_message_type type, } } -units::mass monster::get_carried_weight() { +units::mass monster::get_carried_weight() +{ units::mass total_weight = 0_gram; if( tack_item ) { total_weight += tack_item->weight(); From 673868141c3044fb992a8976e8b376f0bae992c5 Mon Sep 17 00:00:00 2001 From: ymber Date: Mon, 23 Dec 2019 21:54:40 +0000 Subject: [PATCH 09/26] Remove obsolete comment --- src/activity_item_handling.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/activity_item_handling.cpp b/src/activity_item_handling.cpp index 8e138b0a1dfdc..8eb8061ff45d7 100644 --- a/src/activity_item_handling.cpp +++ b/src/activity_item_handling.cpp @@ -219,7 +219,6 @@ static void pass_to_ownership_handling( item obj, player *p ) static void stash_on_pet( const std::list &items, monster &pet, player *p ) { - // Add volume of the bag itself since it is going to be subtracted later in the for-each loop. units::volume remaining_volume = pet.storage_item.value().volume(); units::mass remaining_weight = pet.weight_capacity() - pet.get_carried_weight(); From 0a648b45340bf8d0d74d65ae273152db81120796 Mon Sep 17 00:00:00 2001 From: ymber Date: Mon, 23 Dec 2019 22:23:31 +0000 Subject: [PATCH 10/26] Update horse armors --- data/json/items/armor/pets_horse_armor.json | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/data/json/items/armor/pets_horse_armor.json b/data/json/items/armor/pets_horse_armor.json index 6e68706090474..f10431118b520 100644 --- a/data/json/items/armor/pets_horse_armor.json +++ b/data/json/items/armor/pets_horse_armor.json @@ -15,7 +15,7 @@ "bashing": 10, "to_hit": -3, "flags": [ "IS_PET_ARMOR", "NO_SALVAGE" ], - "material_thickness": 2, + "material_thickness": 10, "max_pet_vol": "1000000 ml", "min_pet_vol": "380000 ml", "pet_bodytype": "horse" @@ -37,7 +37,8 @@ "copy-from": "acidchitin_armor_horse", "name": "chitin horse body armor", "description": "A makeshift assembly of criniere, peytral and croupiere made from chitin fitted to a thin mesh. You could put this on a friendly horse.", - "relative": { "price": -15000, "price_postapoc": -1500, "environmental_protection": -3 }, + "proportional": { "price": 0.85, "price_postapoc": 0.85, "weight": 1.15 }, + "relative": { "environmental_protection": -3 }, "material": [ "chitin" ] }, { @@ -115,23 +116,12 @@ "relative": { "environmental_protection": 10, "material_thickness": -2 }, "material": [ "neoprene", "plastic" ] }, - { - "type": "PET_ARMOR", - "id": "superalloy_armor_horse", - "copy-from": "kevlar_armor_horse", - "color": "light_cyan", - "name": "superalloy crafted horse barding", - "description": "The latest fashion statement and protection for polo equestrians and ahistorical reenactor steeds alike, designed and manufactured by Land Dwarf Industries. You could put this on a friendly horse.", - "proportional": { "price": 100, "price_postapoc": 100, "min_pet_vol": 0.72, "weight": 0.72 }, - "relative": { "environmental_protection": 10, "storage": 32 }, - "material": [ "superalloy" ] - }, { "id": "saddlebag", "type": "ARMOR", "name": { "str": "pair of saddle bags", "str_pl": "pairs of saddle bags" }, "description": "A pair of covered pouches laid across the back of a horse behind the saddle.", - "weight": "1000 g", + "weight": "1 kg", "volume": "7500 ml", "price": 15000, "material": [ "leather" ], From 95e647c1eca275e7d74815ac57005b31f18f43f4 Mon Sep 17 00:00:00 2001 From: ymber Date: Tue, 24 Dec 2019 23:36:42 +0000 Subject: [PATCH 11/26] Fix monster storage check --- src/activity_item_handling.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/activity_item_handling.cpp b/src/activity_item_handling.cpp index 8eb8061ff45d7..6af8198998639 100644 --- a/src/activity_item_handling.cpp +++ b/src/activity_item_handling.cpp @@ -219,7 +219,7 @@ static void pass_to_ownership_handling( item obj, player *p ) static void stash_on_pet( const std::list &items, monster &pet, player *p ) { - units::volume remaining_volume = pet.storage_item.value().volume(); + units::volume remaining_volume = pet.storage_item.value().get_storage(); units::mass remaining_weight = pet.weight_capacity() - pet.get_carried_weight(); for( const item &it : pet.inv ) { From 645a5b2703d22cbb58165d89b734992bf465bd70 Mon Sep 17 00:00:00 2001 From: ymber Date: Wed, 25 Dec 2019 00:16:05 +0000 Subject: [PATCH 12/26] Clean includes --- src/monexamine.cpp | 1 - src/monexamine.h | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/monexamine.cpp b/src/monexamine.cpp index 971942dc00a7e..1321c80daa3dd 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -33,7 +33,6 @@ #include "player_activity.h" #include "rng.h" #include "string_formatter.h" -#include "units.h" #include "type_id.h" #include "pimpl.h" #include "point.h" diff --git a/src/monexamine.h b/src/monexamine.h index eea0062555786..8ce622b60ff30 100644 --- a/src/monexamine.h +++ b/src/monexamine.h @@ -2,8 +2,6 @@ #ifndef MONEXAMINE_H #define MONEXAMINE_H -#include "units.h" - class monster; namespace monexamine From 63d6758da31d7ca94d6487f761d60013c3e9e6f3 Mon Sep 17 00:00:00 2001 From: ymber Date: Wed, 25 Dec 2019 09:26:21 +0000 Subject: [PATCH 13/26] Add monster::move_special_item_to_inv --- src/monster.cpp | 29 +++++++++++++---------------- src/monster.h | 1 + 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/monster.cpp b/src/monster.cpp index 36edd30fb817e..e3dc88d2a6b34 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -2158,22 +2158,11 @@ void monster::die( Creature *nkiller ) } } // Drop items stored in optionals - if( tack_item ) { - add_item( *tack_item ); - tack_item = cata::nullopt; - } - if( armor_item ) { - add_item( *armor_item ); - armor_item = cata::nullopt; - } - if( storage_item ) { - add_item( *storage_item ); - storage_item = cata::nullopt; - } - if( tied_item ) { - add_item( *tied_item ); - tied_item = cata::nullopt; - } + move_special_item_to_inv( &tack_item ); + move_special_item_to_inv( &armor_item ); + move_special_item_to_inv( &storage_item ); + move_special_item_to_inv( &tied_item ); + if( has_effect( effect_lightsnare ) ) { add_item( item( "string_36", 0 ) ); add_item( item( "snare_trigger", 0 ) ); @@ -2658,6 +2647,14 @@ units::mass monster::get_carried_weight() return total_weight; } +void monster::move_special_item_to_inv( cata::optional *it ) +{ + if( *it ) { + add_item( **it ); + *it = cata::nullopt; + } +} + bool monster::is_dead() const { return dead || is_dead_state(); diff --git a/src/monster.h b/src/monster.h index 987f68a865841..235982853c310 100644 --- a/src/monster.h +++ b/src/monster.h @@ -442,6 +442,7 @@ class monster : public Creature cata::optional storage_item; // storage item for monster carrying items cata::optional battery_item; // item to power mechs units::mass get_carried_weight(); + void move_special_item_to_inv( cata::optional *it ); // DEFINING VALUES int friendly; From fdd2d80743c088829e82daf07c99b1dfe9e848dd Mon Sep 17 00:00:00 2001 From: ymber Date: Wed, 25 Dec 2019 09:49:52 +0000 Subject: [PATCH 14/26] Fix horse tack duplication --- src/monexamine.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/monexamine.cpp b/src/monexamine.cpp index 1321c80daa3dd..06b2b4acf562e 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -397,8 +397,14 @@ void monexamine::attach_or_remove_saddle( monster &z ) g->u.i_add( z.tack_item.value() ); z.tack_item = cata::nullopt; } else { + int pos = tack_pos(); + + if( pos == INT_MIN ) { + add_msg( _( "Never mind." ) ); + return; + } z.add_effect( effect_saddled, 1_turns, num_bp, true ); - z.tack_item = g->u.i_at( tack_pos() ); + z.tack_item = g->u.i_at( pos ); g->u.use_amount( z.tack_item.value().typeId(), 1 ); } } From 6aae703dccbc9a799c71f18888d8f942faf0b229 Mon Sep 17 00:00:00 2001 From: ymber Date: Wed, 25 Dec 2019 09:54:57 +0000 Subject: [PATCH 15/26] Access optionals by operator* --- src/activity_item_handling.cpp | 2 +- src/monexamine.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/activity_item_handling.cpp b/src/activity_item_handling.cpp index 6af8198998639..46909928ff912 100644 --- a/src/activity_item_handling.cpp +++ b/src/activity_item_handling.cpp @@ -219,7 +219,7 @@ static void pass_to_ownership_handling( item obj, player *p ) static void stash_on_pet( const std::list &items, monster &pet, player *p ) { - units::volume remaining_volume = pet.storage_item.value().get_storage(); + units::volume remaining_volume = ( *pet.storage_item ).get_storage(); units::mass remaining_weight = pet.weight_capacity() - pet.get_carried_weight(); for( const item &it : pet.inv ) { diff --git a/src/monexamine.cpp b/src/monexamine.cpp index 06b2b4acf562e..b76e23b0da9fa 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -394,7 +394,7 @@ void monexamine::attach_or_remove_saddle( monster &z ) { if( z.has_effect( effect_saddled ) ) { z.remove_effect( effect_saddled ); - g->u.i_add( z.tack_item.value() ); + g->u.i_add( *z.tack_item ); z.tack_item = cata::nullopt; } else { int pos = tack_pos(); @@ -405,7 +405,7 @@ void monexamine::attach_or_remove_saddle( monster &z ) } z.add_effect( effect_saddled, 1_turns, num_bp, true ); z.tack_item = g->u.i_at( pos ); - g->u.use_amount( z.tack_item.value().typeId(), 1 ); + g->u.use_amount( ( *z.tack_item ).typeId(), 1 ); } } @@ -513,7 +513,7 @@ void monexamine::remove_bag_from( monster &z ) if( !z.inv.empty() ) { dump_items( z ); } - g->m.add_item_or_charges( g->u.pos(), z.storage_item.value() ); + g->m.add_item_or_charges( g->u.pos(), *z.storage_item ); add_msg( _( "You remove the %1$s from %2$s." ), z.storage_item->display_name(), pet_name ); z.storage_item = cata::nullopt; g->u.moves -= 200; @@ -542,7 +542,7 @@ bool monexamine::give_items_to( monster &z ) return true; } - item &storage = z.storage_item.value(); + item &storage = *z.storage_item; units::mass max_weight = z.weight_capacity() - z.get_carried_weight(); units::volume max_volume = storage.get_storage(); for( const item &it : z.inv ) { @@ -609,7 +609,7 @@ void monexamine::remove_armor( monster &z ) std::string pet_name = z.get_name(); if( z.armor_item ) { z.armor_item->erase_var( "pet_armor" ); - g->m.add_item_or_charges( z.pos(), z.armor_item.value() ); + g->m.add_item_or_charges( z.pos(), *z.armor_item ); add_msg( _( "You remove the %1$s from %2$s." ), z.armor_item->display_name(), pet_name ); z.armor_item = cata::nullopt; // TODO: removing armor from a horse takes a lot longer than 2 seconds. This should be a long action. From e6f39c5ec436399fdc69dbe0f74002a9f142a57f Mon Sep 17 00:00:00 2001 From: ymber Date: Wed, 25 Dec 2019 10:58:24 +0000 Subject: [PATCH 16/26] Add translation context comments --- src/monexamine.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/monexamine.cpp b/src/monexamine.cpp index b76e23b0da9fa..c9b85f9467faa 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -584,13 +584,13 @@ bool monexamine::add_armor( monster &z ) item &armor = g->u.i_at( pos ); units::mass max_weight = z.weight_capacity() - z.get_carried_weight(); if( max_weight <= armor.weight() ) { - add_msg( _( "Your %1$s is too heavy for your %2$s." ), armor.tname( 1 ), pet_name ); + add_msg( pgettext( "pet armor", "Your %1$s is too heavy for your %2$s." ), armor.tname( 1 ), pet_name ); return true; } armor.set_var( "pet_armor", "true" ); z.armor_item = armor; - add_msg( _( "You put the %1$s on your %2$s." ), armor.display_name(), pet_name ); + add_msg( pgettext( "pet armor", "You put the %1$s on your %2$s." ), armor.display_name(), pet_name ); g->u.i_rem( pos ); z.add_effect( effect_monster_armor, 1_turns, num_bp, true ); // TODO: armoring a horse takes a lot longer than 2 seconds. This should be a long action. @@ -610,7 +610,7 @@ void monexamine::remove_armor( monster &z ) if( z.armor_item ) { z.armor_item->erase_var( "pet_armor" ); g->m.add_item_or_charges( z.pos(), *z.armor_item ); - add_msg( _( "You remove the %1$s from %2$s." ), z.armor_item->display_name(), pet_name ); + add_msg( pgettext( "pet armor", "You remove the %1$s from %2$s." ), z.armor_item->display_name(), pet_name ); z.armor_item = cata::nullopt; // TODO: removing armor from a horse takes a lot longer than 2 seconds. This should be a long action. g->u.moves -= 200; From e5d61410824ec75a418174782cf7c571af3df55d Mon Sep 17 00:00:00 2001 From: ymber Date: Wed, 25 Dec 2019 14:43:44 +0000 Subject: [PATCH 17/26] Update give item checks --- src/activity_item_handling.cpp | 6 +----- src/monexamine.cpp | 16 +++++++++------- src/monster.cpp | 9 +++++++++ src/monster.h | 1 + 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/activity_item_handling.cpp b/src/activity_item_handling.cpp index 46909928ff912..ee9ca74c0807b 100644 --- a/src/activity_item_handling.cpp +++ b/src/activity_item_handling.cpp @@ -219,13 +219,9 @@ static void pass_to_ownership_handling( item obj, player *p ) static void stash_on_pet( const std::list &items, monster &pet, player *p ) { - units::volume remaining_volume = ( *pet.storage_item ).get_storage(); + units::volume remaining_volume = ( *pet.storage_item ).get_storage() - pet.get_carried_volume(); units::mass remaining_weight = pet.weight_capacity() - pet.get_carried_weight(); - for( const item &it : pet.inv ) { - remaining_volume -= it.volume(); - } - for( const item &it : items ) { if( it.volume() > remaining_volume ) { add_msg( m_bad, _( "%1$s did not fit and fell to the %2$s." ), it.display_name(), diff --git a/src/monexamine.cpp b/src/monexamine.cpp index c9b85f9467faa..d7951d45bbb4f 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -544,10 +544,7 @@ bool monexamine::give_items_to( monster &z ) item &storage = *z.storage_item; units::mass max_weight = z.weight_capacity() - z.get_carried_weight(); - units::volume max_volume = storage.get_storage(); - for( const item &it : z.inv ) { - max_volume -= it.volume(); - } + units::volume max_volume = storage.get_storage() - z.get_carried_volume(); std::list> items = game_menus::inv::multidrop( g->u ); std::list> to_move; @@ -562,6 +559,8 @@ bool monexamine::give_items_to( monster &z ) add_msg( _( "The %1$s is too big to fit in the %2$s." ), it.tname(), storage.tname() ); continue; } else { + max_weight -= item_weight; + max_volume -= item_volume; to_move.insert( to_move.end(), itq ); } } @@ -584,13 +583,15 @@ bool monexamine::add_armor( monster &z ) item &armor = g->u.i_at( pos ); units::mass max_weight = z.weight_capacity() - z.get_carried_weight(); if( max_weight <= armor.weight() ) { - add_msg( pgettext( "pet armor", "Your %1$s is too heavy for your %2$s." ), armor.tname( 1 ), pet_name ); + add_msg( pgettext( "pet armor", "Your %1$s is too heavy for your %2$s." ), armor.tname( 1 ), + pet_name ); return true; } armor.set_var( "pet_armor", "true" ); z.armor_item = armor; - add_msg( pgettext( "pet armor", "You put the %1$s on your %2$s." ), armor.display_name(), pet_name ); + add_msg( pgettext( "pet armor", "You put the %1$s on your %2$s." ), armor.display_name(), + pet_name ); g->u.i_rem( pos ); z.add_effect( effect_monster_armor, 1_turns, num_bp, true ); // TODO: armoring a horse takes a lot longer than 2 seconds. This should be a long action. @@ -610,7 +611,8 @@ void monexamine::remove_armor( monster &z ) if( z.armor_item ) { z.armor_item->erase_var( "pet_armor" ); g->m.add_item_or_charges( z.pos(), *z.armor_item ); - add_msg( pgettext( "pet armor", "You remove the %1$s from %2$s." ), z.armor_item->display_name(), pet_name ); + add_msg( pgettext( "pet armor", "You remove the %1$s from %2$s." ), z.armor_item->display_name(), + pet_name ); z.armor_item = cata::nullopt; // TODO: removing armor from a horse takes a lot longer than 2 seconds. This should be a long action. g->u.moves -= 200; diff --git a/src/monster.cpp b/src/monster.cpp index e3dc88d2a6b34..399d1f1999730 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -2647,6 +2647,15 @@ units::mass monster::get_carried_weight() return total_weight; } +units::volume monster::get_carried_volume() +{ + units::volume total_volume = 0_ml; + for( const item &it : inv ) { + total_volume += it.volume(); + } + return total_volume; +} + void monster::move_special_item_to_inv( cata::optional *it ) { if( *it ) { diff --git a/src/monster.h b/src/monster.h index 235982853c310..c7afcc177d88d 100644 --- a/src/monster.h +++ b/src/monster.h @@ -442,6 +442,7 @@ class monster : public Creature cata::optional storage_item; // storage item for monster carrying items cata::optional battery_item; // item to power mechs units::mass get_carried_weight(); + units::volume get_carried_volume(); void move_special_item_to_inv( cata::optional *it ); // DEFINING VALUES From 237635070a3e0d6726a920af47ed627d316ef13b Mon Sep 17 00:00:00 2001 From: ymber Date: Thu, 26 Dec 2019 10:27:12 +0000 Subject: [PATCH 18/26] Use reference for move_special_item_to_inv --- src/monster.cpp | 16 ++++++++-------- src/monster.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/monster.cpp b/src/monster.cpp index 399d1f1999730..31515e038846f 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -2158,10 +2158,10 @@ void monster::die( Creature *nkiller ) } } // Drop items stored in optionals - move_special_item_to_inv( &tack_item ); - move_special_item_to_inv( &armor_item ); - move_special_item_to_inv( &storage_item ); - move_special_item_to_inv( &tied_item ); + move_special_item_to_inv( tack_item ); + move_special_item_to_inv( armor_item ); + move_special_item_to_inv( storage_item ); + move_special_item_to_inv( tied_item ); if( has_effect( effect_lightsnare ) ) { add_item( item( "string_36", 0 ) ); @@ -2656,11 +2656,11 @@ units::volume monster::get_carried_volume() return total_volume; } -void monster::move_special_item_to_inv( cata::optional *it ) +void monster::move_special_item_to_inv( cata::optional &it ) { - if( *it ) { - add_item( **it ); - *it = cata::nullopt; + if( it ) { + add_item( *it ); + it = cata::nullopt; } } diff --git a/src/monster.h b/src/monster.h index c7afcc177d88d..add5e33786176 100644 --- a/src/monster.h +++ b/src/monster.h @@ -443,7 +443,7 @@ class monster : public Creature cata::optional battery_item; // item to power mechs units::mass get_carried_weight(); units::volume get_carried_volume(); - void move_special_item_to_inv( cata::optional *it ); + void move_special_item_to_inv( cata::optional &it ); // DEFINING VALUES int friendly; From c04779208161f2e8aa8ee345ea8915309b6a8c55 Mon Sep 17 00:00:00 2001 From: ymber Date: Thu, 26 Dec 2019 10:28:23 +0000 Subject: [PATCH 19/26] Use proper access operator --- src/activity_item_handling.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/activity_item_handling.cpp b/src/activity_item_handling.cpp index ee9ca74c0807b..c3b006ef3f2ff 100644 --- a/src/activity_item_handling.cpp +++ b/src/activity_item_handling.cpp @@ -219,7 +219,7 @@ static void pass_to_ownership_handling( item obj, player *p ) static void stash_on_pet( const std::list &items, monster &pet, player *p ) { - units::volume remaining_volume = ( *pet.storage_item ).get_storage() - pet.get_carried_volume(); + units::volume remaining_volume = pet.storage_item->get_storage() - pet.get_carried_volume(); units::mass remaining_weight = pet.weight_capacity() - pet.get_carried_weight(); for( const item &it : items ) { From 925d5d0d5cfa2397128458ddb03180a2e82067a4 Mon Sep 17 00:00:00 2001 From: ymber Date: Thu, 26 Dec 2019 12:00:53 +0000 Subject: [PATCH 20/26] Replace item position ints with item_location --- src/monexamine.cpp | 28 ++++++++++++---------------- src/monexamine.h | 6 ++++-- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/monexamine.cpp b/src/monexamine.cpp index d7951d45bbb4f..1d5be0ba9e40f 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -253,7 +253,7 @@ bool monexamine::pet_menu( monster &z ) return true; } -int monexamine::pet_armor_pos( monster &z ) +item_location monexamine::pet_armor_loc( monster &z ) { auto filter = [z]( const item & it ) { return z.type->bodytype == it.get_pet_armor_bodytype() && @@ -261,20 +261,16 @@ int monexamine::pet_armor_pos( monster &z ) z.get_volume() <= it.get_pet_armor_max_vol(); }; - item_location loc = game_menus::inv::titled_filter_menu( filter, g->u, _( "Pet armor" ) ); - - return g->u.get_item_position( loc.get_item() ); + return game_menus::inv::titled_filter_menu( filter, g->u, _( "Pet armor" ) ); } -int monexamine::tack_pos() +item_location monexamine::tack_loc() { auto filter = []( const item & it ) { return it.has_flag( "TACK" ); }; - item_location loc = game_menus::inv::titled_filter_menu( filter, g->u, _( "Tack" ) ); - - return g->u.get_item_position( loc.get_item() ); + return game_menus::inv::titled_filter_menu( filter, g->u, _( "Tack" ) ); } void monexamine::remove_battery( monster &z ) @@ -397,15 +393,15 @@ void monexamine::attach_or_remove_saddle( monster &z ) g->u.i_add( *z.tack_item ); z.tack_item = cata::nullopt; } else { - int pos = tack_pos(); + item_location loc = tack_loc(); - if( pos == INT_MIN ) { + if( !loc ) { add_msg( _( "Never mind." ) ); return; } z.add_effect( effect_saddled, 1_turns, num_bp, true ); - z.tack_item = g->u.i_at( pos ); - g->u.use_amount( ( *z.tack_item ).typeId(), 1 ); + z.tack_item = *loc; + loc.remove_item(); } } @@ -573,14 +569,14 @@ bool monexamine::give_items_to( monster &z ) bool monexamine::add_armor( monster &z ) { std::string pet_name = z.get_name(); - int pos = pet_armor_pos( z ); + item_location loc = pet_armor_loc( z ); - if( pos == INT_MIN ) { + if( !loc ) { add_msg( _( "Never mind." ) ); return true; } - item &armor = g->u.i_at( pos ); + item &armor = *loc; units::mass max_weight = z.weight_capacity() - z.get_carried_weight(); if( max_weight <= armor.weight() ) { add_msg( pgettext( "pet armor", "Your %1$s is too heavy for your %2$s." ), armor.tname( 1 ), @@ -592,7 +588,7 @@ bool monexamine::add_armor( monster &z ) z.armor_item = armor; add_msg( pgettext( "pet armor", "You put the %1$s on your %2$s." ), armor.display_name(), pet_name ); - g->u.i_rem( pos ); + loc.remove_item(); z.add_effect( effect_monster_armor, 1_turns, num_bp, true ); // TODO: armoring a horse takes a lot longer than 2 seconds. This should be a long action. g->u.moves -= 200; diff --git a/src/monexamine.h b/src/monexamine.h index 8ce622b60ff30..70154a97ff452 100644 --- a/src/monexamine.h +++ b/src/monexamine.h @@ -2,6 +2,8 @@ #ifndef MONEXAMINE_H #define MONEXAMINE_H +#include "item_location.h" + class monster; namespace monexamine @@ -18,8 +20,8 @@ void attach_bag_to( monster &z ); void remove_bag_from( monster &z ); void dump_items( monster &z ); bool give_items_to( monster &z ); -int pet_armor_pos( monster &z ); -int tack_pos(); +item_location pet_armor_loc( monster &z ); +item_location tack_loc(); bool add_armor( monster &z ); void remove_armor( monster &z ); void remove_harness( monster &z ); From 0e17083332b067d046eadf25d714355ab385f3cb Mon Sep 17 00:00:00 2001 From: ymber Date: Thu, 26 Dec 2019 12:02:13 +0000 Subject: [PATCH 21/26] Remove space --- src/monexamine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/monexamine.cpp b/src/monexamine.cpp index 1d5be0ba9e40f..967fa0b7c0a62 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -579,7 +579,7 @@ bool monexamine::add_armor( monster &z ) item &armor = *loc; units::mass max_weight = z.weight_capacity() - z.get_carried_weight(); if( max_weight <= armor.weight() ) { - add_msg( pgettext( "pet armor", "Your %1$s is too heavy for your %2$s." ), armor.tname( 1 ), + add_msg( pgettext( "pet armor", "Your %1$s is too heavy for your %2$s." ), armor.tname( 1 ), pet_name ); return true; } From 187741e4e901b034d41f389a75e37cde5cc2c263 Mon Sep 17 00:00:00 2001 From: ymber Date: Thu, 26 Dec 2019 12:07:32 +0000 Subject: [PATCH 22/26] Remove helper functions from public interface --- src/monexamine.cpp | 4 ++-- src/monexamine.h | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/monexamine.cpp b/src/monexamine.cpp index 967fa0b7c0a62..f5fb2286847c6 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -253,7 +253,7 @@ bool monexamine::pet_menu( monster &z ) return true; } -item_location monexamine::pet_armor_loc( monster &z ) +static item_location pet_armor_loc( monster &z ) { auto filter = [z]( const item & it ) { return z.type->bodytype == it.get_pet_armor_bodytype() && @@ -264,7 +264,7 @@ item_location monexamine::pet_armor_loc( monster &z ) return game_menus::inv::titled_filter_menu( filter, g->u, _( "Pet armor" ) ); } -item_location monexamine::tack_loc() +static item_location tack_loc() { auto filter = []( const item & it ) { return it.has_flag( "TACK" ); diff --git a/src/monexamine.h b/src/monexamine.h index 70154a97ff452..2aff0fa186741 100644 --- a/src/monexamine.h +++ b/src/monexamine.h @@ -2,8 +2,6 @@ #ifndef MONEXAMINE_H #define MONEXAMINE_H -#include "item_location.h" - class monster; namespace monexamine @@ -20,8 +18,6 @@ void attach_bag_to( monster &z ); void remove_bag_from( monster &z ); void dump_items( monster &z ); bool give_items_to( monster &z ); -item_location pet_armor_loc( monster &z ); -item_location tack_loc(); bool add_armor( monster &z ); void remove_armor( monster &z ); void remove_harness( monster &z ); From 286408e48815128f530e4bfb8f625bf138693b8c Mon Sep 17 00:00:00 2001 From: ymber Date: Mon, 30 Dec 2019 11:42:49 +0000 Subject: [PATCH 23/26] Use new drop_locations in give_items_to --- src/monexamine.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/monexamine.cpp b/src/monexamine.cpp index f5fb2286847c6..9c650fc83182b 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -542,10 +542,10 @@ bool monexamine::give_items_to( monster &z ) units::mass max_weight = z.weight_capacity() - z.get_carried_weight(); units::volume max_volume = storage.get_storage() - z.get_carried_volume(); - std::list> items = game_menus::inv::multidrop( g->u ); - std::list> to_move; - for( const std::pair &itq : items ) { - const item &it = g->u.i_at( itq.first ); + drop_locations items = game_menus::inv::multidrop( g->u ); + drop_locations to_move; + for( const drop_location &itq : items ) { + const item &it = *itq.first; units::volume item_volume = it.volume() * itq.second; units::mass item_weight = it.weight() * itq.second; if( max_weight < item_weight ) { From b7e44a0da4a06ca35353b733563dbaf4a46826a1 Mon Sep 17 00:00:00 2001 From: ymber Date: Wed, 1 Jan 2020 11:47:01 +0000 Subject: [PATCH 24/26] Use cata::value_ptr for special items --- src/character.cpp | 2 +- src/creature.cpp | 3 ++- src/monexamine.cpp | 24 +++++++++---------- src/monster.cpp | 10 ++++---- src/monster.h | 13 +++++----- src/savegame_json.cpp | 55 +++++++++++++++++++++++++++++++++++-------- src/vehicle_use.cpp | 2 +- 7 files changed, 73 insertions(+), 36 deletions(-) diff --git a/src/character.cpp b/src/character.cpp index 1858a1f3c37b5..a778f03102c41 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -611,7 +611,7 @@ void Character::mount_creature( monster &z ) z.remove_effect( effect_tied ); if( z.tied_item ) { i_add( *z.tied_item ); - z.tied_item = cata::nullopt; + z.tied_item.reset(); } } z.mounted_player_id = getID(); diff --git a/src/creature.cpp b/src/creature.cpp index c3f49a6c13aad..f268e9578653b 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -685,7 +685,8 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack if( z ) { if( !proj.get_drop().is_null() ) { z->add_effect( effect_tied, 1_turns, num_bp, true ); - z->tied_item = proj.get_drop(); + item drop_item = proj.get_drop(); + z->tied_item = cata::make_value( proj.get_drop() ); } else { add_msg( m_debug, "projectile with TANGLE effect, but no drop item specified" ); } diff --git a/src/monexamine.cpp b/src/monexamine.cpp index 9c650fc83182b..66758d9ccdaf9 100644 --- a/src/monexamine.cpp +++ b/src/monexamine.cpp @@ -276,7 +276,7 @@ static item_location tack_loc() void monexamine::remove_battery( monster &z ) { g->m.add_item_or_charges( g->u.pos(), *z.battery_item ); - z.battery_item = cata::nullopt; + z.battery_item.reset(); } void monexamine::insert_battery( monster &z ) @@ -306,10 +306,10 @@ void monexamine::insert_battery( monster &z ) index > static_cast( bat_inv.size() ) ) { return; } - auto bat_item = bat_inv[index - 1]; + item *bat_item = bat_inv[index - 1]; int item_pos = g->u.get_item_position( bat_item ); if( item_pos != INT_MIN ) { - z.battery_item = *bat_item; + z.battery_item = cata::make_value( *bat_item ); g->u.i_rem( item_pos ); } } @@ -391,7 +391,7 @@ void monexamine::attach_or_remove_saddle( monster &z ) if( z.has_effect( effect_saddled ) ) { z.remove_effect( effect_saddled ); g->u.i_add( *z.tack_item ); - z.tack_item = cata::nullopt; + z.tack_item.reset(); } else { item_location loc = tack_loc(); @@ -400,7 +400,7 @@ void monexamine::attach_or_remove_saddle( monster &z ) return; } z.add_effect( effect_saddled, 1_turns, num_bp, true ); - z.tack_item = *loc; + z.tack_item = cata::make_value( *loc.get_item() ); loc.remove_item(); } } @@ -493,7 +493,7 @@ void monexamine::attach_bag_to( monster &z ) } item &it = *loc; - z.storage_item = it; + z.storage_item = cata::make_value( it ); add_msg( _( "You mount the %1$s on your %2$s." ), it.display_name(), pet_name ); g->u.i_rem( &it ); z.add_effect( effect_has_bag, 1_turns, num_bp, true ); @@ -511,7 +511,7 @@ void monexamine::remove_bag_from( monster &z ) } g->m.add_item_or_charges( g->u.pos(), *z.storage_item ); add_msg( _( "You remove the %1$s from %2$s." ), z.storage_item->display_name(), pet_name ); - z.storage_item = cata::nullopt; + z.storage_item.reset(); g->u.moves -= 200; } else { add_msg( m_bad, _( "Your %1$s doesn't have a bag!" ), pet_name ); @@ -585,7 +585,7 @@ bool monexamine::add_armor( monster &z ) } armor.set_var( "pet_armor", "true" ); - z.armor_item = armor; + z.armor_item = cata::make_value( armor ); add_msg( pgettext( "pet armor", "You put the %1$s on your %2$s." ), armor.display_name(), pet_name ); loc.remove_item(); @@ -609,7 +609,7 @@ void monexamine::remove_armor( monster &z ) g->m.add_item_or_charges( z.pos(), *z.armor_item ); add_msg( pgettext( "pet armor", "You remove the %1$s from %2$s." ), z.armor_item->display_name(), pet_name ); - z.armor_item = cata::nullopt; + z.armor_item.reset(); // TODO: removing armor from a horse takes a lot longer than 2 seconds. This should be a long action. g->u.moves -= 200; } else { @@ -646,7 +646,7 @@ void monexamine::tie_or_untie( monster &z ) z.remove_effect( effect_tied ); if( z.tied_item ) { g->u.i_add( *z.tied_item ); - z.tied_item = cata::nullopt; + z.tied_item.reset(); } } else { std::vector rope_inv = g->u.items_with( []( const item & itm ) { @@ -669,10 +669,10 @@ void monexamine::tie_or_untie( monster &z ) index > static_cast( rope_inv.size() ) ) { return; } - auto rope_item = rope_inv[index - 1]; + item *rope_item = rope_inv[index - 1]; int item_pos = g->u.get_item_position( rope_item ); if( item_pos != INT_MIN ) { - z.tied_item = *rope_item; + z.tied_item = cata::make_value( *rope_item ); g->u.i_rem( item_pos ); z.add_effect( effect_tied, 1_turns, num_bp, true ); } diff --git a/src/monster.cpp b/src/monster.cpp index 31515e038846f..90ab9aed4c6ae 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -234,7 +234,7 @@ monster::monster( const mtype_id &id ) : monster() int max_charge = type.magazine->capacity; item mech_bat_item = item( mech_bat, 0 ); mech_bat_item.ammo_consume( rng( 0, max_charge ), tripoint_zero ); - battery_item = mech_bat_item; + battery_item = cata::make_value( mech_bat_item ); } } @@ -1620,7 +1620,7 @@ bool monster::move_effects( bool ) add_msg( _( "The %s easily slips out of its bonds." ), name() ); } g->m.add_item_or_charges( pos(), *tied_item ); - tied_item = cata::nullopt; + tied_item.reset(); } } else { if( tied_item ) { @@ -1629,7 +1629,7 @@ bool monster::move_effects( bool ) if( !broken ) { g->m.add_item_or_charges( pos(), *tied_item ); } - tied_item = cata::nullopt; + tied_item.reset(); if( u_see_me ) { if( broken ) { add_msg( _( "The %s snaps the bindings holding it down." ), name() ); @@ -2656,11 +2656,11 @@ units::volume monster::get_carried_volume() return total_volume; } -void monster::move_special_item_to_inv( cata::optional &it ) +void monster::move_special_item_to_inv( cata::value_ptr &it ) { if( it ) { add_item( *it ); - it = cata::nullopt; + it.reset(); } } diff --git a/src/monster.h b/src/monster.h index add5e33786176..015db45b55a8d 100644 --- a/src/monster.h +++ b/src/monster.h @@ -27,6 +27,7 @@ #include "type_id.h" #include "units.h" #include "point.h" +#include "value_ptr.h" class JsonObject; class JsonIn; @@ -436,14 +437,14 @@ class monster : public Creature Character *mounted_player = nullptr; // player that is mounting this creature character_id mounted_player_id; // id of player that is mounting this creature ( for save/load ) character_id dragged_foe_id; // id of character being dragged by the monster - cata::optional tied_item; // item used to tie the monster - cata::optional tack_item; // item representing saddle and reins and such - cata::optional armor_item; // item of armor the monster may be wearing - cata::optional storage_item; // storage item for monster carrying items - cata::optional battery_item; // item to power mechs + cata::value_ptr tied_item; // item used to tie the monster + cata::value_ptr tack_item; // item representing saddle and reins and such + cata::value_ptr armor_item; // item of armor the monster may be wearing + cata::value_ptr storage_item; // storage item for monster carrying items + cata::value_ptr battery_item; // item to power mechs units::mass get_carried_weight(); units::volume get_carried_volume(); - void move_special_item_to_inv( cata::optional &it ); + void move_special_item_to_inv( cata::value_ptr &it ); // DEFINING VALUES int friendly; diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 0a7fe9b88b57f..32b243b4e46b4 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -1819,12 +1819,37 @@ void monster::load( const JsonObject &data ) if( data.read( "wandz", wander_pos.z ) ) { wander_pos.z = position.z; } - data.read( "tied_item", tied_item ); - data.read( "tack_item", tack_item ); - data.read( "armor_item", armor_item ); - data.read( "storage_item", storage_item ); + if( data.has_object( "tied_item" ) ) { + JsonIn *tied_item_json = data.get_raw( "tied_item" ); + item newitem; + newitem.deserialize( *tied_item_json ); + tied_item = cata::make_value( newitem ); + } + if( data.has_object( "tack_item" ) ) { + JsonIn *tack_item_json = data.get_raw( "tack_item" ); + item newitem; + newitem.deserialize( *tack_item_json ); + tack_item = cata::make_value( newitem ); + } + if( data.has_object( "armor_item" ) ) { + JsonIn *armor_item_json = data.get_raw( "armor_item" ); + item newitem; + newitem.deserialize( *armor_item_json ); + armor_item = cata::make_value( newitem ); + } + if( data.has_object( "storage_item" ) ) { + JsonIn *storage_item_json = data.get_raw( "storage_item" ); + item newitem; + newitem.deserialize( *storage_item_json ); + storage_item = cata::make_value( newitem ); + } + if( data.has_object( "battery_item" ) ) { + JsonIn *battery_item_json = data.get_raw( "battery_item" ); + item newitem; + newitem.deserialize( *battery_item_json ); + battery_item = cata::make_value( newitem ); + } data.read( "hp", hp ); - data.read( "battery_item", battery_item ); // sp_timeout indicates an old save, prior to the special_attacks refactor if( data.has_array( "sp_timeout" ) ) { @@ -1957,11 +1982,21 @@ void monster::store( JsonOut &json ) const json.member( "morale", morale ); json.member( "hallucination", hallucination ); json.member( "stairscount", staircount ); - json.member( "tied_item", tied_item ); - json.member( "tack_item", tack_item ); - json.member( "armor_item", armor_item ); - json.member( "storage_item", storage_item ); - json.member( "battery_item", battery_item ); + if( tied_item ) { + json.member( "tied_item", *tied_item ); + } + if( tack_item ) { + json.member( "tack_item", *tack_item ); + } + if( armor_item ) { + json.member( "armor_item", *armor_item ); + } + if( storage_item ) { + json.member( "storage_item", *storage_item ); + } + if( battery_item ) { + json.member( "battery_item", *battery_item ); + } // Store the relative position of the goal so it loads correctly after a map shift. json.member( "destination", goal - pos() ); json.member( "ammo", ammo ); diff --git a/src/vehicle_use.cpp b/src/vehicle_use.cpp index 5fa06a8184dd1..49b7008dbdf69 100644 --- a/src/vehicle_use.cpp +++ b/src/vehicle_use.cpp @@ -1739,7 +1739,7 @@ void vehicle::use_harness( int part, const tripoint &pos ) m.remove_effect( effect_tied ); if( m.tied_item ) { g->u.i_add( *m.tied_item ); - m.tied_item = cata::nullopt; + m.tied_item.reset(); } } } From f68b570b93ec74a5a264ae78a2665daefa9f4eac Mon Sep 17 00:00:00 2001 From: ymber Date: Wed, 1 Jan 2020 13:13:11 +0000 Subject: [PATCH 25/26] Show armor valuse for monster armor --- src/item.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/item.h | 2 ++ 2 files changed, 57 insertions(+) diff --git a/src/item.cpp b/src/item.cpp index 7c41ae4cbda6a..0c46d8302f240 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -2200,6 +2200,60 @@ void item::armor_info( std::vector &info, const iteminfo_query *parts, } } +void item::animal_armor_info( std::vector &info, const iteminfo_query *parts, int /* batch */, + bool /* debug */ ) const +{ + if( !is_pet_armor() ) { + return; + } + + const std::string space = " "; + + int converted_storage_scale = 0; + const double converted_storage = round_up( convert_volume( get_storage().value(), + &converted_storage_scale ), 2 ); + if( parts->test( iteminfo_parts::ARMOR_STORAGE ) && converted_storage > 0 ) { + const iteminfo::flags f = converted_storage_scale == 0 ? iteminfo::no_flags : iteminfo::is_decimal; + info.push_back( iteminfo( "ARMOR", space + _( "Storage: " ), + string_format( " %s", volume_units_abbr() ), + f, converted_storage ) ); + } + + // Whatever the last entry was, we want a newline at this point + info.back().bNewLine = true; + + if( parts->test( iteminfo_parts::ARMOR_PROTECTION ) ) { + info.push_back( iteminfo( "ARMOR", _( "Protection: Bash: " ), "", + iteminfo::no_newline, bash_resist() ) ); + info.push_back( iteminfo( "ARMOR", space + _( "Cut: " ), cut_resist() ) ); + info.push_back( iteminfo( "ARMOR", space + _( "Acid: " ), "", + iteminfo::no_newline, acid_resist() ) ); + info.push_back( iteminfo( "ARMOR", space + _( "Fire: " ), "", + iteminfo::no_newline, fire_resist() ) ); + info.push_back( iteminfo( "ARMOR", space + _( "Environmental: " ), + get_base_env_resist( *this ) ) ); + if( type->can_use( "GASMASK" ) || type->can_use( "DIVE_TANK" ) ) { + info.push_back( iteminfo( "ARMOR", + _( "Protection when active: " ) ) ); + info.push_back( iteminfo( "ARMOR", space + _( "Acid: " ), "", + iteminfo::no_newline, + acid_resist( false, get_base_env_resist_w_filter() ) ) ); + info.push_back( iteminfo( "ARMOR", space + _( "Fire: " ), "", + iteminfo::no_newline, + fire_resist( false, get_base_env_resist_w_filter() ) ) ); + info.push_back( iteminfo( "ARMOR", space + _( "Environmental: " ), + get_env_resist( get_base_env_resist_w_filter() ) ) ); + } + + if( damage() > 0 ) { + info.push_back( iteminfo( "ARMOR", + _( "Protection values are reduced by damage and " + "you may be able to improve them by repairing this " + "item." ) ) ); + } + } +} + void item::book_info( std::vector &info, const iteminfo_query *parts, int /* batch */, bool /* debug */ ) const { @@ -3299,6 +3353,7 @@ std::string item::info( std::vector &info, const iteminfo_query *parts gunmod_info( info, parts, batch, debug ); armor_info( info, parts, batch, debug ); + animal_armor_info( info, parts, batch, debug ); book_info( info, parts, batch, debug ); container_info( info, parts, batch, debug ); battery_info( info, parts, batch, debug ); diff --git a/src/item.h b/src/item.h index b1a5017b510bc..705b26342a9be 100644 --- a/src/item.h +++ b/src/item.h @@ -399,6 +399,8 @@ class item : public visitable bool debug ) const; void armor_info( std::vector &info, const iteminfo_query *parts, int batch, bool debug ) const; + void animal_armor_info( std::vector &info, const iteminfo_query *parts, int batch, + bool debug ) const; void book_info( std::vector &info, const iteminfo_query *parts, int batch, bool debug ) const; void battery_info( std::vector &info, const iteminfo_query *parts, int batch, From 15f7170ae003f399a29c402e6097f4fcb4c260b6 Mon Sep 17 00:00:00 2001 From: ymber Date: Wed, 1 Jan 2020 13:58:11 +0000 Subject: [PATCH 26/26] Astyle, update horse armor data --- data/json/items/armor/pets_horse_armor.json | 109 ++++++++++++-------- src/item.cpp | 5 +- src/item.h | 4 +- 3 files changed, 73 insertions(+), 45 deletions(-) diff --git a/data/json/items/armor/pets_horse_armor.json b/data/json/items/armor/pets_horse_armor.json index f10431118b520..af1d6a32e9c34 100644 --- a/data/json/items/armor/pets_horse_armor.json +++ b/data/json/items/armor/pets_horse_armor.json @@ -1,66 +1,85 @@ [ { + "abstract": "horse_armor", "type": "PET_ARMOR", - "id": "kevlar_armor_horse", + "name": "horse armor", "symbol": "[", - "looks_like": "hsurvivor_suit", + "min_pet_vol": "380 L", + "max_pet_vol": "1000 L", + "pet_bodytype": "horse", + "flags": [ "IS_PET_ARMOR" ] + }, + { + "type": "PET_ARMOR", + "id": "kevlar_armor_horse", + "copy-from": "horse_armor", "color": "yellow", - "name": "Kevlar-lined horse peto", + "name": { "str": "Kevlar-lined horse peto" }, "description": "A heavy mattress-like armor of cloth, leather and thick linings of Kevlar, originally used as protection in bullfighting. You could put this on a friendly horse.", "price": 50000, "price_postapoc": 5000, - "material": [ "kevlar" ], - "weight": "30000 g", + "material": [ "cotton", "leather", "kevlar" ], + "weight": "30 kg", "volume": "150 L", - "bashing": 10, - "to_hit": -3, - "flags": [ "IS_PET_ARMOR", "NO_SALVAGE" ], - "material_thickness": 10, - "max_pet_vol": "1000000 ml", - "min_pet_vol": "380000 ml", - "pet_bodytype": "horse" + "material_thickness": 10 }, { "type": "PET_ARMOR", "id": "acidchitin_armor_horse", - "copy-from": "kevlar_armor_horse", + "copy-from": "horse_armor", "color": "green", - "name": "biosilicified chitin horse body armor", + "name": { "str": "biosilicified chitin horse armor" }, "description": "A makeshift assembly of criniere, peytral and croupiere made from biosilicified chitin fitted to a thin mesh. You could put this on a friendly horse.", - "proportional": { "price": 1.67, "price_postapoc": 1.67, "weight": 1.15 }, - "relative": { "environmental_protection": 7 }, - "material": [ "acidchitin" ] + "price": 120000, + "price_postapoc": 12000, + "material": [ "acidchitin", "steel" ], + "weight": "35 kg", + "volume": "150 L", + "material_thickness": 6, + "environmental_protection": 7 }, { "type": "PET_ARMOR", "id": "chitin_armor_horse", - "copy-from": "acidchitin_armor_horse", - "name": "chitin horse body armor", + "copy-from": "horse_armor", + "color": "green", + "name": { "str": "chitin horse armor" }, "description": "A makeshift assembly of criniere, peytral and croupiere made from chitin fitted to a thin mesh. You could put this on a friendly horse.", - "proportional": { "price": 0.85, "price_postapoc": 0.85, "weight": 1.15 }, - "relative": { "environmental_protection": -3 }, - "material": [ "chitin" ] + "price": 100000, + "price_postapoc": 10000, + "material": [ "chitin", "steel" ], + "weight": "35 kg", + "volume": "150 L", + "material_thickness": 6, + "environmental_protection": 4 }, { "type": "PET_ARMOR", "id": "chainmail_armor_horse", - "copy-from": "kevlar_armor_horse", - "color": "light_red", - "name": "chainmail horse coat", + "copy-from": "horse_armor", + "color": "green", + "name": { "str": "chainmail horse armor" }, "description": "A heavy covering of chainmail, suitably made for horses as protection. You could put this on a friendly horse.", - "proportional": { "price": 0.83, "price_postapoc": 0.83, "weight": 1.3 }, - "relative": { "material_thickness": -2 }, - "material": [ "iron", "budget_steel" ] + "price": 40000, + "price_postapoc": 4000, + "material": [ "steel", "leather" ], + "weight": "40 kg", + "volume": "150 L", + "material_thickness": 6 }, { "type": "PET_ARMOR", "id": "leather_armor_horse", - "copy-from": "kevlar_armor_horse", - "color": "brown", - "name": "boiled leather horse barding with caparison", + "copy-from": "horse_armor", + "color": "green", + "name": { "str": "boiled leather horse barding with caprison" }, "description": "A full barding for horses consisting of boiled leather and cloth undercovering. This caparison is depicting a battle between a monstrous dragon and regal griffin. You could put this on a friendly horse.", - "proportional": { "price": 0.58, "price_postapoc": 0.58, "weight": 0.5 }, + "price": 30000, + "price_postapoc": 3000, "material": [ "cotton", "leather" ], + "weight": "15 kg", + "volume": "150 L", + "material_thickness": 6, "snippet_category": [ { "id": "battle", @@ -99,22 +118,30 @@ { "type": "PET_ARMOR", "id": "leatherbone_armor_horse", - "copy-from": "leather_armor_horse", + "copy-from": "horse_armor", + "color": "green", "name": { "str": "boiled leather horse barding with bones", "str_pl": "boiled leather horse bardings with bones" }, "description": "Decorative bones affixed to leather horse barding to invoke fear in bandits and raiders and traders all! You could put this on a friendly horse.", - "relative": { "price": 1500, "price_postapoc": 150, "weight": 500 }, - "material": [ "bone", "leather" ] + "price": 45000, + "price_postapoc": 4500, + "material": [ "bone", "leather" ], + "weight": "17 kg", + "volume": "150 L", + "material_thickness": 6 }, { "type": "PET_ARMOR", "id": "rubber_armor_horse", - "copy-from": "kevlar_armor_horse", - "color": "dark_gray", - "name": "horse rain sheet", + "copy-from": "horse_armor", + "color": "green", + "name": { "str": "horse rain sheet" }, "description": "A thin plastic covering adapted for horses to protect from acid rain and other caustic sources. You could put this on a friendly horse.", - "proportional": { "price": 0.34, "price_postapoc": 0.34, "min_pet_vol": 0.6, "weight": 0.45 }, - "relative": { "environmental_protection": 10, "material_thickness": -2 }, - "material": [ "neoprene", "plastic" ] + "price": 15000, + "price_postapoc": 1500, + "material": [ "neoprene", "plastic" ], + "weight": "14 kg", + "volume": "150 L", + "material_thickness": 3 }, { "id": "saddlebag", diff --git a/src/item.cpp b/src/item.cpp index 0c46d8302f240..8583acb7052a0 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -2200,8 +2200,9 @@ void item::armor_info( std::vector &info, const iteminfo_query *parts, } } -void item::animal_armor_info( std::vector &info, const iteminfo_query *parts, int /* batch */, - bool /* debug */ ) const +void item::animal_armor_info( std::vector &info, const iteminfo_query *parts, + int /* batch */, + bool /* debug */ ) const { if( !is_pet_armor() ) { return; diff --git a/src/item.h b/src/item.h index 705b26342a9be..ad07cac0c3f68 100644 --- a/src/item.h +++ b/src/item.h @@ -399,8 +399,8 @@ class item : public visitable bool debug ) const; void armor_info( std::vector &info, const iteminfo_query *parts, int batch, bool debug ) const; - void animal_armor_info( std::vector &info, const iteminfo_query *parts, int batch, - bool debug ) const; + void animal_armor_info( std::vector &info, const iteminfo_query *parts, int batch, + bool debug ) const; void book_info( std::vector &info, const iteminfo_query *parts, int batch, bool debug ) const; void battery_info( std::vector &info, const iteminfo_query *parts, int batch,