From a0f160497501e7cb82cf4971f79f9e7fbcbbaa94 Mon Sep 17 00:00:00 2001 From: AluminumAlman Date: Sun, 7 Jan 2024 14:29:24 +0900 Subject: [PATCH 1/5] feat!: more lua bindings --- src/activity_type.cpp | 8 + src/activity_type.h | 3 + src/animation.cpp | 4 +- src/bionics.h | 3 + src/bodypart.cpp | 35 ++ src/catalua.cpp | 2 +- src/catalua_bindings.cpp | 350 ++++++++--- src/catalua_bindings.h | 13 +- src/catalua_bindings_creature.cpp | 942 ++++++++++++++++++++++++++++++ src/catalua_bindings_ids.cpp | 35 +- src/catalua_bindings_utils.h | 18 + src/catalua_luna.h | 43 +- src/catalua_luna_doc.h | 98 +++- src/creature.h | 14 - src/damage.cpp | 37 +- src/damage.h | 6 + src/disease.h | 3 + src/enum_conversions.cpp | 47 ++ src/enums.h | 24 +- src/flag.h | 4 + src/flag_trait.h | 3 + src/magic.cpp | 21 - src/martialarts.h | 3 + src/monfaction.cpp | 27 + src/monfaction.h | 14 +- src/monster.cpp | 36 +- src/monster.h | 7 +- src/monstergenerator.h | 3 + src/morale_types.cpp | 1 + src/morale_types.h | 3 + src/mutation.h | 7 +- src/mutation_data.cpp | 31 +- src/npc.cpp | 37 ++ src/npc.h | 13 +- src/pldata.h | 2 + src/safemode_ui.cpp | 3 + src/skill.h | 5 + src/sounds.cpp | 38 +- src/sounds.h | 6 + src/string_id_null_ids.cpp | 106 ++-- 40 files changed, 1840 insertions(+), 215 deletions(-) create mode 100644 src/catalua_bindings_creature.cpp create mode 100644 src/enum_conversions.cpp diff --git a/src/activity_type.cpp b/src/activity_type.cpp index 6edbbc50a511..b4635e901e70 100644 --- a/src/activity_type.cpp +++ b/src/activity_type.cpp @@ -33,6 +33,14 @@ const activity_type &string_id::obj() const return found->second; } +/** @relates string_id */ +template<> +bool string_id::is_valid() const +{ + const auto found = activity_type_all.find( *this ); + return found != activity_type_all.end(); +} + static const std::unordered_map< std::string, based_on_type > based_on_type_values = { { "time", based_on_type::TIME }, { "speed", based_on_type::SPEED }, diff --git a/src/activity_type.h b/src/activity_type.h index 3002c665b55d..45f15ea4d207 100644 --- a/src/activity_type.h +++ b/src/activity_type.h @@ -4,6 +4,7 @@ #include +#include "catalua_type_operators.h" #include "string_id.h" #include "translations.h" @@ -81,6 +82,8 @@ class activity_type static void load( const JsonObject &jo ); static void check_consistency(); static void reset(); + + LUA_TYPE_OPS( activity_type, id_ ); }; #endif // CATA_SRC_ACTIVITY_TYPE_H diff --git a/src/animation.cpp b/src/animation.cpp index 6fcb4d7217ad..e9288ae9171c 100644 --- a/src/animation.cpp +++ b/src/animation.cpp @@ -1,12 +1,13 @@ #include "animation.h" #include "avatar.h" +#include "cached_options.h" #include "character.h" #include "cursesdef.h" #include "enums.h" #include "explosion.h" -#include "game.h" #include "game_constants.h" +#include "game.h" #include "line.h" #include "map.h" #include "monster.h" @@ -22,7 +23,6 @@ #include "type_id.h" #include "ui_manager.h" #include "weather.h" -#include "cached_options.h" #if defined(TILES) #include diff --git a/src/bionics.h b/src/bionics.h index a44083bb74c4..78208bfb99c5 100644 --- a/src/bionics.h +++ b/src/bionics.h @@ -12,6 +12,7 @@ #include "bodypart.h" #include "calendar.h" +#include "catalua_type_operators.h" #include "flat_set.h" #include "translations.h" #include "type_id.h" @@ -150,6 +151,8 @@ struct bionic_data { void load( const JsonObject &obj, const std::string & ); void check() const; void finalize() const; + + LUA_TYPE_OPS( bionic_data, id ); }; struct bionic { diff --git a/src/bodypart.cpp b/src/bodypart.cpp index 70949c3ca246..f17a46135923 100644 --- a/src/bodypart.cpp +++ b/src/bodypart.cpp @@ -83,6 +83,41 @@ std::string enum_to_string( hp_part data ) abort(); } +template<> +std::string enum_to_string( body_part data ) +{ + switch( data ) { + case body_part::bp_torso: + return "TORSO"; + case body_part::bp_head: + return "HEAD"; + case body_part::bp_eyes: + return "EYES"; + case body_part::bp_mouth: + return "MOUTH"; + case body_part::bp_arm_l: + return "ARM_L"; + case body_part::bp_arm_r: + return "ARM_R"; + case body_part::bp_hand_l: + return "HAND_L"; + case body_part::bp_hand_r: + return "HAND_R"; + case body_part::bp_leg_l: + return "LEG_L"; + case body_part::bp_leg_r: + return "LEG_R"; + case body_part::bp_foot_l: + return "FOOT_L"; + case body_part::bp_foot_r: + return "FOOT_R"; + case body_part::num_bp: + break; + } + debugmsg( "Invalid body_part" ); + abort(); +} + } // namespace io namespace diff --git a/src/catalua.cpp b/src/catalua.cpp index 91da6fa170bc..5304c76aef40 100644 --- a/src/catalua.cpp +++ b/src/catalua.cpp @@ -2,7 +2,7 @@ #include "debug.h" -constexpr int LUA_API_VERSION = 1; +constexpr int LUA_API_VERSION = 2; #ifndef LUA diff --git a/src/catalua_bindings.cpp b/src/catalua_bindings.cpp index 30df6d2ff802..939ae192f447 100644 --- a/src/catalua_bindings.cpp +++ b/src/catalua_bindings.cpp @@ -5,29 +5,39 @@ #include "bodypart.h" #include "calendar.h" #include "catalua_bindings_utils.h" +#include "catalua.h" #include "catalua_impl.h" #include "catalua_log.h" #include "catalua_luna_doc.h" #include "catalua_luna.h" -#include "catalua.h" #include "character.h" #include "creature.h" +#include "damage.h" #include "distribution_grid.h" #include "enum_conversions.h" -#include "field_type.h" +#include "enums.h" #include "field.h" +#include "field_type.h" #include "game.h" #include "itype.h" #include "map.h" #include "messages.h" +#include "monfaction.h" #include "monster.h" +#include "mtype.h" #include "npc.h" #include "player.h" #include "popup.h" #include "rng.h" +#include "skill.h" +#include "sounds.h" #include "translations.h" #include "type_id.h" #include "ui.h" +#include "units_angle.h" +#include "units_energy.h" +#include "units_mass.h" +#include "units_volume.h" std::string_view luna::detail::current_comment; @@ -112,97 +122,189 @@ static auto item_stack_lua_pairs( item_stack &stk ) sol::lua_nil ); } -void cata::detail::reg_creature_family( sol::state &lua ) +void cata::detail::reg_units( sol::state &lua ) { { - // Specifying base classes here allows us to pass derived classes - // from Lua to C++ functions that expect base class. - sol::usertype ut = - luna::new_usertype( + sol::usertype ut = + luna::new_usertype( lua, luna::no_bases, luna::no_constructor ); - // TODO: typesafe coords - DOC( "Position within map" ); - luna::set_fx( ut, "get_pos_ms", &Creature::pos ); - - luna::set_fx( ut, "is_monster", &Creature::is_monster ); - luna::set_fx( ut, "as_monster", sol::resolve( &Creature::as_monster ) ); - luna::set_fx( ut, "is_npc", &Creature::is_npc ); - luna::set_fx( ut, "as_npc", sol::resolve( &Creature::as_npc ) ); - luna::set_fx( ut, "is_avatar", &Creature::is_avatar ); - luna::set_fx( ut, "as_avatar", sol::resolve( &Creature::as_avatar ) ); - - luna::set_fx( ut, "has_effect", []( const Creature & cr, const efftype_id & eff, - sol::optional bpid ) -> bool { - if( bpid.has_value() ) - { - return cr.has_effect( eff, *bpid ); - } else - { - return cr.has_effect( eff ); - } - } ); + luna::set_fx( ut, "from_radians", &units::from_radians ); + luna::set_fx( ut, "to_radians", &units::to_radians ); + luna::set_fx( ut, "from_degrees", &units::from_degrees ); + luna::set_fx( ut, "to_degrees", &units::to_degrees ); + luna::set_fx( ut, "from_arcmin", &units::from_arcmin ); + luna::set_fx( ut, "to_arcmin", &units::to_arcmin ); - luna::set_fx( ut, "get_effect_dur", []( const Creature & cr, const efftype_id & eff, - sol::optional bpid ) -> time_duration { - body_part bp = bpid ? ( *bpid ) -> token : num_bp; - return cr.get_effect_dur( eff, bp ); - } ); + luna::set_fx( ut, sol::meta_function::equal_to, &units::angle::operator== ); + luna::set_fx( ut, sol::meta_function::less_than, &units::angle::operator< ); + luna::set_fx( ut, sol::meta_function::less_than_or_equal_to, &units::angle::operator<= ); + } + { + sol::usertype ut = + luna::new_usertype( + lua, + luna::no_bases, + luna::no_constructor + ); - luna::set_fx( ut, "get_effect_int", []( const Creature & cr, const efftype_id & eff, - sol::optional bpid ) -> int { - body_part bp = bpid ? ( *bpid ) -> token : num_bp; - return cr.get_effect_int( eff, bp ); - } ); + luna::set_fx( ut, "from_joule", &units::from_joule ); + luna::set_fx( ut, "to_joule", &units::to_joule ); + luna::set_fx( ut, "from_kilojoule", &units::from_kilojoule ); + luna::set_fx( ut, "to_kilojoule", &units::to_kilojoule ); - DOC( "Effect type, duration, bodypart and intensity" ); - luna::set_fx( ut, "add_effect", []( Creature & cr, const efftype_id & eff, - const time_duration & dur, - sol::optional bpid, - sol::optional intensity - ) { - int eint = intensity ? *intensity : 0; - body_part bp = bpid ? ( *bpid ) -> token : num_bp; - cr.add_effect( eff, dur, bp, eint ); - } ); + luna::set_fx( ut, sol::meta_function::equal_to, &units::energy::operator== ); + luna::set_fx( ut, sol::meta_function::less_than, &units::energy::operator< ); + luna::set_fx( ut, sol::meta_function::less_than_or_equal_to, &units::energy::operator<= ); + } + { + sol::usertype ut = + luna::new_usertype( + lua, + luna::no_bases, + luna::no_constructor + ); - luna::set_fx( ut, "remove_effect", []( Creature & cr, const efftype_id & eff, - sol::optional bpid ) -> bool { - body_part bp = bpid ? ( *bpid ) -> token : num_bp; - return cr.remove_effect( eff, bp ); - } ); + luna::set_fx( ut, "from_milligram", &units::from_milligram ); + luna::set_fx( ut, "to_milligram", &units::to_milligram ); + luna::set_fx( ut, "from_gram", &units::from_gram ); + luna::set_fx( ut, "to_gram", &units::to_gram ); + luna::set_fx( ut, "from_kilogram", &units::from_kilogram ); + luna::set_fx( ut, "to_kilogram", &units::to_kilogram ); + luna::set_fx( ut, "from_newton", &units::from_newton ); + luna::set_fx( ut, "to_newton", &units::to_newton ); + + luna::set_fx( ut, sol::meta_function::equal_to, &units::mass::operator== ); + luna::set_fx( ut, sol::meta_function::less_than, &units::mass::operator< ); + luna::set_fx( ut, sol::meta_function::less_than_or_equal_to, &units::mass::operator<= ); + } + { + sol::usertype ut = + luna::new_usertype( + lua, + luna::no_bases, + luna::no_constructor + ); + + luna::set_fx( ut, "from_milliliter", &units::from_milliliter ); + luna::set_fx( ut, "from_liter", &units::from_liter ); + luna::set_fx( ut, "to_milliliter", &units::to_milliliter ); + luna::set_fx( ut, "to_liter", &units::to_liter ); + + luna::set_fx( ut, sol::meta_function::equal_to, &units::volume::operator== ); + luna::set_fx( ut, sol::meta_function::less_than, &units::volume::operator< ); + luna::set_fx( ut, sol::meta_function::less_than_or_equal_to, &units::volume::operator<= ); } +} +void cata::detail::reg_skill_level_map( sol::state &lua ) +{ { - luna::new_usertype( - lua, - luna::bases(), - luna::no_constructor - ); - luna::new_usertype( - lua, - luna::bases(), - luna::no_constructor - ); - luna::new_usertype( + sol::usertype ut = + luna::new_usertype( + lua, + luna::no_bases, + luna::no_constructor + ); + + luna::set_fx( ut, "is_training", &SkillLevel::isTraining ); + luna::set_fx( ut, "level", sol::resolve( &SkillLevel::level ) ); + luna::set_fx( ut, "highest_level", &SkillLevel::highestLevel ); + luna::set_fx( ut, "train", &SkillLevel::train ); + luna::set_fx( ut, "can_train", &SkillLevel::can_train ); + } + { + sol::usertype ut = + luna::new_usertype( + lua, + luna::bases>(), + luna::no_constructor + ); + luna::set_fx( ut, "mod_skill_level", &SkillLevelMap::mod_skill_level ); + luna::set_fx( ut, "get_skill_level", + sol::resolve + ( &SkillLevelMap::get_skill_level ) ); + luna::set_fx( ut, "get_skill_level_object", + sol::resolve + ( &SkillLevelMap::get_skill_level_object ) ); + } +} + +void cata::detail::reg_damage_instance( sol::state &lua ) +{ +#define UT_CLASS damage_unit + { + DOC( "Represents a damage amount" ); + DOC( "Constructors are:" ); + DOC( "new()" ); + DOC( "new(damageType, amount, armorPen, remainingArmorMultiplier, damageMultiplier)" ); + sol::usertype ut = + luna::new_usertype( lua, - luna::bases(), - luna::no_constructor + luna::no_bases, + luna::constructors < + UT_CLASS( damage_type, float, float, float, float ) + > () ); - luna::new_usertype( + + SET_MEMB( type ); + SET_MEMB( amount ); + SET_MEMB( res_pen ); + SET_MEMB( res_mult ); + SET_MEMB( damage_multiplier ); + + luna::set_fx( ut, sol::meta_function::equal_to, &UT_CLASS::operator== ); + + } +#undef UT_CLASS // #define UT_CLASS damage_unit +#define UT_CLASS damage_instance + { + DOC( "Represents a bunch of damage amounts" ); + DOC( "Constructors are:" ); + DOC( "new(damageType, amount, armorPen, remainingArmorMultiplier, damageMultiplier)" ); + sol::usertype ut = + luna::new_usertype( lua, - luna::bases(), - luna::no_constructor + luna::no_bases, + luna::constructors < + UT_CLASS(), + UT_CLASS( damage_type, float, float, float, float ) + > () ); - luna::new_usertype( + + SET_MEMB( damage_units ); + + SET_FX( mult_damage ); + SET_FX( type_damage ); + SET_FX( total_damage ); + SET_FX( clear ); + SET_FX( empty ); + SET_FX( add_damage ); + SET_FX_T( add, void( const damage_unit & ) ); + + luna::set_fx( ut, sol::meta_function::equal_to, &UT_CLASS::operator== ); + } +#undef UT_CLASS // #define UT_CLASS damage_instance +#define UT_CLASS dealt_damage_instance + { + DOC( "Represents the final dealt damage" ); + sol::usertype ut = + luna::new_usertype( lua, - luna::bases(), + luna::no_bases, luna::no_constructor ); + + SET_MEMB( dealt_dams ); + SET_MEMB( bp_hit ); + + SET_FX( type_damage ); + SET_FX( total_damage ); } +#undef UT_CLASS // #define UT_CLASS dealt_damage_instance } void cata::detail::reg_item( sol::state &lua ) @@ -501,9 +603,6 @@ void cata::detail::reg_game_api( sol::state &lua ) luna::set_fx( lib, "get_avatar", &get_avatar ); luna::set_fx( lib, "get_map", &get_map ); luna::set_fx( lib, "get_distribution_grid_tracker", &get_distribution_grid_tracker ); - luna::set_fx( lib, "get_character_name", []( const Character & you ) -> std::string { - return you.name; - } ); luna::set_fx( lib, "add_msg", sol::overload( add_msg_lua, []( sol::variadic_args va ) { @@ -532,6 +631,94 @@ void cata::detail::reg_game_api( sol::state &lua ) hooks.push_back( on_every_x_hooks{ interval, vec } ); } ); + luna::set_fx( lib, "get_creature_at", []( const tripoint & p, + sol::optional allow_hallucination ) -> Creature * { + if( allow_hallucination.has_value() ) + { + return g->critter_at( p, *allow_hallucination ); + } + return g->critter_at( p ); + } ); + luna::set_fx( lib, "get_monster_at", []( const tripoint & p, + sol::optional allow_hallucination ) -> monster * { + if( allow_hallucination.has_value() ) + { + return g->critter_at( p, *allow_hallucination ); + } + return g->critter_at( p ); + } ); + luna::set_fx( lib, "get_character_at", []( const tripoint & p, + sol::optional allow_hallucination ) -> Character * { + if( allow_hallucination.has_value() ) + { + return g->critter_at( p, *allow_hallucination ); + } + return g->critter_at( p ); + } ); + luna::set_fx( lib, "get_npc_at", []( const tripoint & p, + sol::optional allow_hallucination ) -> npc * { + if( allow_hallucination.has_value() ) + { + return g->critter_at( p, *allow_hallucination ); + } + return g->critter_at( p ); + } ); + + luna::set_fx( lib, "choose_adjacent", []( const std::string & message, + sol::optional allow_vertical ) -> sol::optional { + std::optional stdOpt; + if( allow_vertical.has_value() ) + { + stdOpt = choose_adjacent( message, *allow_vertical ); + } else + { + stdOpt = choose_adjacent( message ); + } + if( stdOpt.has_value() ) + { + return sol::optional( *stdOpt ); + } + return sol::optional(); + } ); + luna::set_fx( lib, "choose_direction", []( const std::string & message, + sol::optional allow_vertical ) -> sol::optional { + std::optional stdOpt; + if( allow_vertical.has_value() ) + { + stdOpt = choose_direction( message, *allow_vertical ); + } else + { + stdOpt = choose_direction( message ); + } + if( stdOpt.has_value() ) + { + return sol::optional( *stdOpt ); + } + return sol::optional(); + } ); + luna::set_fx( lib, "look_around", []() { + auto result = g->look_around(); + if( result.has_value() ) { + return sol::optional( *result ); + } + return sol::optional(); + } ); + + luna::set_fx( lib, "play_variant_sound", + sol::overload( + sol::resolve( &sfx::play_variant_sound ), + sol::resolve( &sfx::play_variant_sound ) + ) ); + luna::set_fx( lib, "play_ambient_variant_sound", &sfx::play_ambient_variant_sound ); + + luna::set_fx( lib, "add_npc_follower", []( npc & p ) { + g->add_npc_follower( p.getID() ); + } ); + luna::set_fx( lib, "remove_npc_follower", []( npc & p ) { + g->remove_npc_follower( p.getID() ); + } ); + luna::finalize_lib( lib ); } @@ -598,7 +785,19 @@ void cata::detail::reg_colors( sol::state &lua ) void cata::detail::reg_enums( sol::state &lua ) { + reg_enum( lua ); + reg_enum( lua ); + reg_enum( lua ); + reg_enum( lua ); + reg_enum( lua ); reg_enum( lua ); + reg_enum( lua ); + reg_enum( lua ); + reg_enum( lua ); + reg_enum( lua ); + reg_enum( lua ); + reg_enum( lua ); + reg_enum( lua ); } void cata::detail::reg_hooks_examples( sol::state &lua ) @@ -800,6 +999,9 @@ void cata::reg_all_bindings( sol::state &lua ) reg_debug_api( lua ); reg_game_api( lua ); reg_locale_api( lua ); + reg_units( lua ); + reg_skill_level_map( lua ); + reg_damage_instance( lua ); reg_creature_family( lua ); reg_point_tripoint( lua ); reg_item( lua ); diff --git a/src/catalua_bindings.h b/src/catalua_bindings.h index 1ae582075ca4..8002e55ea943 100644 --- a/src/catalua_bindings.h +++ b/src/catalua_bindings.h @@ -14,24 +14,33 @@ std::string fmt_lua_va( sol::variadic_args va ); void override_default_print( sol::state &lua ); void forbid_unsafe_functions( sol::state &lua ); +void reg_avatar( sol::state &lua ); +void reg_character( sol::state &lua ); void reg_colors( sol::state &lua ); void reg_constants( sol::state &lua ); void reg_coords_library( sol::state &lua ); void reg_creature_family( sol::state &lua ); +void reg_creature( sol::state &lua ); +void reg_damage_instance( sol::state &lua ); void reg_debug_api( sol::state &lua ); void reg_distribution_grid( sol::state &lua ); void reg_enums( sol::state &lua ); void reg_game_api( sol::state &lua ); -void reg_locale_api( sol::state &lua ); +void reg_game_ids( sol::state &lua ); void reg_hooks_examples( sol::state &lua ); void reg_item( sol::state &lua ); +void reg_locale_api( sol::state &lua ); void reg_map( sol::state &lua ); +void reg_monster( sol::state &lua ); +void reg_npc( sol::state &lua ); +void reg_player( sol::state &lua ); void reg_point_tripoint( sol::state &lua ); +void reg_skill_level_map( sol::state &lua ); void reg_testing_library( sol::state &lua ); void reg_time_types( sol::state &lua ); -void reg_game_ids( sol::state &lua ); void reg_types( sol::state &lua ); void reg_ui_elements( sol::state &lua ); +void reg_units( sol::state &lua ); } // namespace detail diff --git a/src/catalua_bindings_creature.cpp b/src/catalua_bindings_creature.cpp new file mode 100644 index 000000000000..e87ca33fedf2 --- /dev/null +++ b/src/catalua_bindings_creature.cpp @@ -0,0 +1,942 @@ +#ifdef LUA +#include "catalua_bindings.h" + +#include "activity_type.h" +#include "avatar.h" +#include "bionics.h" +#include "bodypart.h" +#include "catalua.h" +#include "catalua_bindings_utils.h" +#include "catalua_impl.h" +#include "catalua_log.h" +#include "catalua_luna.h" +#include "catalua_luna_doc.h" +#include "character.h" +#include "creature.h" +#include "damage.h" +#include "disease.h" +#include "enums.h" +#include "field.h" +#include "field_type.h" +#include "flag.h" +#include "flag_trait.h" +#include "monfaction.h" +#include "monster.h" +#include "morale_types.h" +#include "mutation.h" +#include "npc.h" +#include "player.h" +#include "pldata.h" +#include "recipe.h" +#include "skill.h" +#include "type_id.h" + +void cata::detail::reg_creature_family( sol::state &lua ) +{ + reg_creature( lua ); + reg_monster( lua ); + reg_character( lua ); + reg_player( lua ); + reg_npc( lua ); + reg_avatar( lua ); +} + +void cata::detail::reg_creature( sol::state &lua ) +{ +#define UT_CLASS Creature + { + sol::usertype ut = + luna::new_usertype( + lua, + luna::no_bases, + luna::no_constructor + ); + + // Methods + SET_FX_T( get_name, std::string() const ); + SET_FX_T( disp_name, std::string( bool, bool ) const ); + SET_FX_T( skin_name, std::string() const ); + SET_FX_T( get_grammatical_genders, std::vector() const ); + + SET_FX_T( is_avatar, bool() const ); + SET_FX_T( is_npc, bool() const ); + SET_FX_T( is_monster, bool() const ); + SET_FX_T( as_monster, monster * () ); + SET_FX_T( as_npc, npc * () ); + SET_FX_T( as_character, Character * () ); + SET_FX_T( as_avatar, avatar * () ); + + SET_FX_T( hit_roll, float() const ); + SET_FX_T( dodge_roll, float() ); + SET_FX_T( stability_roll, float() const ); + + SET_FX_T( attitude_to, Attitude( const Creature & ) const ); + + SET_FX_T( sees, bool( const Creature & ) const ); + + SET_FX_T( sight_range, int( int ) const ); + + SET_FX_T( power_rating, float() const ); + + SET_FX_T( speed_rating, float() const ); + + SET_FX_T( ranged_target_size, double() const ); + + SET_FX_T( knock_back_to, void( const tripoint & ) ); + + SET_FX_T( deal_damage, dealt_damage_instance( Creature * source, bodypart_id bp, + const damage_instance & dam ) ); + + SET_FX_T( apply_damage, void( Creature * source, bodypart_id bp, int amount, + bool bypass_med ) ); + + SET_FX_T( size_melee_penalty, int() const ); + + SET_FX_T( digging, bool() const ); + SET_FX_T( is_on_ground, bool() const ); + SET_FX_T( is_underwater, bool() const ); + SET_FX_T( set_underwater, void( bool x ) ); + SET_FX_T( is_warm, bool() const ); + SET_FX_T( in_species, bool( const species_id & ) const ); + + SET_FX_T( has_weapon, bool() const ); + SET_FX_T( is_hallucination, bool() const ); + SET_FX_N_T( is_dead_state, "is_dead", bool() const ); + + SET_FX_T( is_elec_immune, bool() const ); + SET_FX_T( is_immune_effect, bool( const efftype_id & ) const ); + SET_FX_T( is_immune_damage, bool( damage_type ) const ); + + SET_FX_N_T( pos, "get_pos_ms", const tripoint & () const ); + + SET_FX_N_T( setpos, "set_pos_ms", void( const tripoint & ) ); + + luna::set_fx( ut, "has_effect", []( const Creature & cr, const efftype_id & eff, + sol::optional bpid ) -> bool { + if( bpid.has_value() ) + { + return cr.has_effect( eff, *bpid ); + } else + { + return cr.has_effect( eff ); + } + } ); + + luna::set_fx( ut, "has_effect_with_flag", []( const Creature & cr, + const flag_id & flag, sol::optional bpid ) -> bool { + body_part bp = bpid ? ( *bpid ) -> token : num_bp; + return cr.has_effect_with_flag( flag, bp ); + } ); + + luna::set_fx( ut, "get_effect_dur", []( const Creature & cr, const efftype_id & eff, + sol::optional bpid ) -> time_duration { + body_part bp = bpid ? ( *bpid ) -> token : num_bp; + return cr.get_effect_dur( eff, bp ); + } ); + + luna::set_fx( ut, "get_effect_int", []( const Creature & cr, const efftype_id & eff, + sol::optional bpid ) -> int { + body_part bp = bpid ? ( *bpid ) -> token : num_bp; + return cr.get_effect_int( eff, bp ); + } ); + + DOC( "Effect type, duration, bodypart and intensity" ); + luna::set_fx( ut, "add_effect", []( Creature & cr, const efftype_id & eff, + const time_duration & dur, + sol::optional bpid, + sol::optional intensity + ) + { + int eint = intensity ? *intensity : 0; + body_part bp = bpid ? ( *bpid ) -> token : num_bp; + cr.add_effect( eff, dur, bp, eint ); + } ); + + luna::set_fx( ut, "remove_effect", []( Creature & cr, const efftype_id & eff, + sol::optional bpid ) -> bool { + body_part bp = bpid ? ( *bpid ) -> token : num_bp; + return cr.remove_effect( eff, bp ); + } ); + + SET_FX_T( clear_effects, void() ); + + SET_FX_T( set_value, void( const std::string &, const std::string & ) ); + SET_FX_T( remove_value, void( const std::string & ) ); + SET_FX_T( get_value, std::string( const std::string & ) const ); + + SET_FX_T( get_weight, units::mass() const ); + + SET_FX_T( has_trait, bool( const trait_id & ) const ); + + SET_FX_T( mod_pain, void( int ) ); + SET_FX_T( mod_pain_noresist, void( int ) ); + SET_FX_T( set_pain, void( int ) ); + SET_FX_T( get_pain, int() const ); + SET_FX_T( get_perceived_pain, int() const ); + + SET_FX_T( get_moves, int() const ); + SET_FX_T( mod_moves, void( int ) ); + SET_FX_T( set_moves, void( int ) ); + + SET_FX_T( get_num_blocks, int() const ); + SET_FX_T( get_num_dodges, int() const ); + + SET_FX_T( get_env_resist, int( bodypart_id ) const ); + + SET_FX_T( get_armor_bash, int( bodypart_id ) const ); + SET_FX_T( get_armor_cut, int( bodypart_id ) const ); + SET_FX_T( get_armor_bullet, int( bodypart_id ) const ); + SET_FX_T( get_armor_bash_base, int( bodypart_id ) const ); + SET_FX_T( get_armor_cut_base, int( bodypart_id ) const ); + SET_FX_T( get_armor_bullet_base, int( bodypart_id ) const ); + SET_FX_T( get_armor_bash_bonus, int() const ); + SET_FX_T( get_armor_cut_bonus, int() const ); + SET_FX_T( get_armor_bullet_bonus, int() const ); + + SET_FX_T( get_armor_type, int( damage_type, bodypart_id ) const ); + + SET_FX_T( get_dodge, float() const ); + + SET_FX_T( get_melee, float() const ); + SET_FX_T( get_hit, float() const ); + + SET_FX_T( get_speed, int() const ); + SET_FX_T( get_size, m_size() const ); + luna::set_fx( ut, "get_hp", []( const Creature & cr, + sol::optional bpid ) -> int { + if( bpid.has_value() ) + { + return cr.get_hp( *bpid ); + } else + { + return cr.get_hp(); + } + } ); + luna::set_fx( ut, "get_hp_max", []( const Creature & cr, + sol::optional bpid ) -> int { + if( bpid.has_value() ) + { + return cr.get_hp_max( *bpid ); + } else + { + return cr.get_hp_max(); + } + } ); + + SET_FX_T( hp_percentage, int() const ); + SET_FX_T( has_flag, bool( const m_flag ) const ); + + SET_FX_T( get_part_hp_cur, int( const bodypart_id & ) const ); + SET_FX_T( get_part_hp_max, int( const bodypart_id & ) const ); + + SET_FX_T( get_part_healed_total, int( const bodypart_id & ) const ); + + SET_FX_T( set_part_hp_cur, void( const bodypart_id &, int ) ); + SET_FX_T( set_part_hp_max, void( const bodypart_id &, int ) ); + SET_FX_T( mod_part_hp_cur, void( const bodypart_id &, int ) ); + SET_FX_T( mod_part_hp_max, void( const bodypart_id &, int ) ); + + SET_FX_T( set_all_parts_hp_cur, void( int ) ); + SET_FX_T( set_all_parts_hp_to_max, void() ); + + SET_FX_T( get_speed_base, int() const ); + SET_FX_T( get_speed_bonus, int() const ); + SET_FX_T( get_speed_mult, float() const ); + SET_FX_T( get_block_bonus, int() const ); + + SET_FX_T( get_dodge_base, float() const ); + SET_FX_T( get_hit_base, float() const ); + SET_FX_T( get_dodge_bonus, float() const ); + SET_FX_T( get_hit_bonus, float() const ); + + SET_FX_T( has_grab_break_tec, bool() const ); + + luna::set_fx( ut, "get_weight_capacity", []( UT_CLASS & cr ) -> std::int64_t { + return cr.weight_capacity().value(); + } ); + } +#undef UT_CLASS // #define UT_CLASS Creature +} + +void cata::detail::reg_monster( sol::state &lua ) +{ +#define UT_CLASS monster + { + sol::usertype ut = + luna::new_usertype( + lua, + luna::bases(), + luna::no_constructor + ); + + // Members + SET_MEMB( friendly ); + SET_MEMB( anger ); + SET_MEMB( morale ); + SET_MEMB( faction ); + SET_MEMB( death_drops ); + SET_MEMB( unique_name ); + + // Methods + SET_FX_T( can_upgrade, bool() const ); + SET_FX_T( hasten_upgrade, void() ); + SET_FX_T( get_upgrade_time, int() const ); + SET_FX_T( try_upgrade, void( bool ) ); + SET_FX_T( try_reproduce, void() ); + SET_FX_T( refill_udders, void() ); + SET_FX_T( spawn, void( const tripoint & ) ); + + SET_FX_T( name, std::string( unsigned int ) const ); + SET_FX_T( name_with_armor, std::string() const ); + + SET_FX_T( can_see, bool() const ); + SET_FX_T( can_hear, bool() const ); + SET_FX_T( can_submerge, bool() const ); + SET_FX_T( can_drown, bool() const ); + SET_FX_T( can_climb, bool() const ); + SET_FX_T( can_dig, bool() const ); + SET_FX_T( digs, bool() const ); + SET_FX_T( flies, bool() const ); + SET_FX_T( climbs, bool() const ); + SET_FX_T( swims, bool() const ); + + SET_FX_T( move_target, tripoint() ); + SET_FX_N_T( wander, "is_wandering", bool() ); + + SET_FX_T( wander_to, void( const tripoint & p, int f ) ); + SET_FX_T( move_to, bool( const tripoint & p, bool force, bool step_on_critter, + float stagger_adjustment ) ); + + SET_FX_T( attitude, monster_attitude( const Character * ) const ); + + SET_FX_T( heal, int( int, bool ) ); + + SET_FX_T( set_hp, void( int ) ); + + SET_FX_T( make_fungus, bool() ); + SET_FX_T( make_friendly, void() ); + + SET_FX_T( make_ally, void( const monster & ) ); + } +#undef UT_CLASS // #define UT_CLASS monster +} + +void cata::detail::reg_character( sol::state &lua ) +{ +#define UT_CLASS Character + { + sol::usertype ut = + luna::new_usertype( + lua, + luna::bases(), + luna::no_constructor + ); + + // Members + SET_MEMB( name ); + SET_MEMB( male ); + + SET_MEMB( focus_pool ); + SET_MEMB( cash ); + SET_MEMB( follower_ids ); + + SET_MEMB( mutation_category_level ); + + // Methods + SET_FX_T( getID, character_id() const ); + + SET_FX_T( setID, void( character_id, bool ) ); + + SET_FX_T( get_str, int() const ); + SET_FX_T( get_dex, int() const ); + SET_FX_T( get_per, int() const ); + SET_FX_T( get_int, int() const ); + + SET_FX_T( get_str_base, int() const ); + SET_FX_T( get_dex_base, int() const ); + SET_FX_T( get_per_base, int() const ); + SET_FX_T( get_int_base, int() const ); + + SET_FX_T( get_str_bonus, int() const ); + SET_FX_T( get_dex_bonus, int() const ); + SET_FX_T( get_per_bonus, int() const ); + SET_FX_T( get_int_bonus, int() const ); + + SET_FX_T( set_str_bonus, void( int ) ); + SET_FX_T( set_dex_bonus, void( int ) ); + SET_FX_T( set_per_bonus, void( int ) ); + SET_FX_T( set_int_bonus, void( int ) ); + SET_FX_T( mod_str_bonus, void( int ) ); + SET_FX_T( mod_dex_bonus, void( int ) ); + SET_FX_T( mod_per_bonus, void( int ) ); + SET_FX_T( mod_int_bonus, void( int ) ); + + SET_FX_T( get_healthy, int() const ); + SET_FX_T( get_healthy_mod, int() const ); + + SET_FX_T( mod_healthy, void( int ) ); + SET_FX_T( mod_healthy_mod, void( int, int ) ); + + SET_FX_T( set_healthy, void( int ) ); + SET_FX_T( set_healthy_mod, void( int ) ); + + SET_FX_T( get_stored_kcal, int() const ); + + SET_FX_T( max_stored_kcal, int() const ); + SET_FX_T( get_kcal_percent, float() const ); + SET_FX_T( get_thirst, int() const ); + SET_FX_T( get_fatigue, int() const ); + SET_FX_T( get_sleep_deprivation, int() const ); + + SET_FX_T( mod_stored_kcal, void( int ) ); + SET_FX_T( mod_thirst, void( int ) ); + SET_FX_T( mod_fatigue, void( int ) ); + SET_FX_T( mod_sleep_deprivation, void( int ) ); + + SET_FX_T( set_stored_kcal, void( int ) ); + SET_FX_T( set_thirst, void( int ) ); + SET_FX_T( set_fatigue, void( int ) ); + SET_FX_T( set_sleep_deprivation, void( int ) ); + + luna::set_fx( ut, "get_faction_id", []( const UT_CLASS & charac ) -> faction_id { + faction *fac = charac.get_faction(); + return fac == nullptr ? faction_id::NULL_ID() : fac->id; + } ); + luna::set_fx( ut, "set_faction_id", []( UT_CLASS & charac, faction_id id ) + { + charac.set_fac_id( id.str() ); + } ); + + SET_FX_T( sight_impaired, bool() const ); + + SET_FX_T( has_alarm_clock, bool() const ); + + SET_FX_T( has_watch, bool() const ); + + SET_FX_T( blood_loss, int( const bodypart_id & bp ) const ); + + SET_FX_N_T( encumb, "get_part_encumbrance", int( body_part bp ) const ); + + SET_FX_T( is_wearing_power_armor, bool( bool * ) const ); + + SET_FX_T( is_wearing_active_power_armor, bool() const ); + + SET_FX_T( is_wearing_active_optcloak, bool() const ); + + SET_FX_T( in_climate_control, bool() ); + + SET_FX_T( is_blind, bool() const ); + + SET_FX_T( is_invisible, bool() const ); + + SET_FX_T( get_movement_mode, character_movemode() const ); + + SET_FX_T( set_movement_mode, void( character_movemode ) ); + + SET_FX_T( expose_to_disease, void( diseasetype_id ) ); + + SET_FX_T( is_quiet, bool() const ); + + SET_FX_T( is_stealthy, bool() const ); + + SET_FX_T( cough, void( bool harmful, int loudness ) ); + + SET_FX_T( bionic_armor_bonus, float( const bodypart_id &, damage_type ) const ); + + SET_FX_T( mabuff_armor_bonus, int( damage_type ) const ); + + SET_FX_T( has_base_trait, bool( const trait_id & b ) const ); + + SET_FX_T( has_trait_flag, bool( const trait_flag_str_id & b ) const ); + + SET_FX_T( has_opposite_trait, bool( const trait_id & flag ) const ); + + SET_FX_T( set_mutation, void( const trait_id & ) ); + SET_FX_T( unset_mutation, void( const trait_id & ) ); + + SET_FX_T( can_mount, bool( const monster & critter ) const ); + SET_FX_T( mount_creature, void( monster & z ) ); + SET_FX_T( is_mounted, bool() const ); + SET_FX_T( check_mount_will_move, bool( const tripoint & dest_loc ) ); + SET_FX_T( check_mount_is_spooked, bool() ); + SET_FX_T( dismount, void() ); + SET_FX_T( forced_dismount, void() ); + + SET_FX_T( is_deaf, bool() const ); + + SET_FX_T( has_two_arms, bool() const ); + + SET_FX_T( get_working_arm_count, int() const ); + + SET_FX_T( get_working_leg_count, int() const ); + + SET_FX_T( is_limb_disabled, bool( const bodypart_id & ) const ); + + SET_FX_T( is_limb_broken, bool( const bodypart_id & ) const ); + + SET_FX_T( can_run, bool() ); + + SET_FX_T( hurtall, void( int dam, Creature * source, bool ) ); + + SET_FX_T( hitall, int( int dam, int vary, Creature * source ) ); + + SET_FX_T( heal, void( const bodypart_id &, int ) ); + + SET_FX_T( healall, void( int dam ) ); + + SET_FX_T( global_square_location, tripoint() const ); + + SET_FX_T( global_sm_location, tripoint() const ); + + SET_FX_T( has_mabuff, bool( const mabuff_id & ) const ); + + SET_FX_T( mabuff_tohit_bonus, float() const ); + + SET_FX_T( mabuff_dodge_bonus, float() const ); + + SET_FX_T( mabuff_block_bonus, int() const ); + + SET_FX_T( mabuff_speed_bonus, int() const ); + + SET_FX_T( mabuff_arpen_bonus, int( damage_type ) const ); + + SET_FX_T( mabuff_damage_mult, float( damage_type ) const ); + + SET_FX_T( mabuff_damage_bonus, int( damage_type ) const ); + + SET_FX_T( mabuff_attack_cost_penalty, int() const ); + + SET_FX_T( mabuff_attack_cost_mult, float() const ); + + SET_FX_T( mutation_effect, void( const trait_id & ) ); + + SET_FX_T( mutation_loss_effect, void( const trait_id & ) ); + + SET_FX_T( has_active_mutation, bool( const trait_id & ) const ); + + SET_FX_T( mutate, void() ); + + SET_FX_T( mutation_ok, bool( const trait_id &, bool, bool ) const ); + + SET_FX_T( mutate_category, void( const mutation_category_id & ) ); + + SET_FX_T( mutate_towards, bool( std::vector, int ) ); + + SET_FX_T( mutate_towards, bool( const trait_id & ) ); + + SET_FX_T( remove_mutation, void( const trait_id &, bool ) ); + + SET_FX_T( has_child_flag, bool( const trait_id & flag ) const ); + + SET_FX_T( remove_child_flag, void( const trait_id & flag ) ); + + SET_FX_T( get_highest_category, mutation_category_id() const ); + + SET_FX_T( is_weak_to_water, bool() const ); + + SET_FX_T( mutation_armor, float( bodypart_id, damage_type ) const ); + + SET_FX_T( get_bionics, std::vector() const ); + + SET_FX_T( has_bionic, bool( const bionic_id & b ) const ); + + SET_FX_T( has_active_bionic, bool( const bionic_id & b ) const ); + + SET_FX_T( has_any_bionic, bool() const ); + + SET_FX_T( has_bionics, bool() const ); + + SET_FX_T( clear_bionics, void() ); + SET_FX_T( get_used_bionics_slots, int( const bodypart_id & ) const ); + SET_FX_T( get_total_bionics_slots, int( const bodypart_id & ) const ); + SET_FX_T( get_free_bionics_slots, int( const bodypart_id & ) const ); + + SET_FX_T( remove_bionic, void( const bionic_id & ) ); + + SET_FX_T( add_bionic, void( const bionic_id & ) ); + + SET_FX_T( get_power_level, units::energy() const ); + SET_FX_T( get_max_power_level, units::energy() const ); + SET_FX_T( mod_power_level, void( const units::energy & ) ); + SET_FX_T( mod_max_power_level, void( const units::energy & ) ); + SET_FX_T( set_power_level, void( const units::energy & ) ); + SET_FX_T( set_max_power_level, void( const units::energy & ) ); + SET_FX_T( is_max_power, bool() const ); + SET_FX_T( has_power, bool() const ); + SET_FX_T( has_max_power, bool() const ); + + SET_FX_T( is_worn, bool( const item & ) const ); + + SET_FX_T( weight_carried, units::mass() const ); + SET_FX_T( volume_carried, units::volume() const ); + + SET_FX_T( volume_capacity, units::volume() const ); + + SET_FX_T( can_pick_volume, bool( units::volume ) const ); + SET_FX_T( can_pick_weight, bool( units::mass, bool ) const ); + + SET_FX_T( is_armed, bool() const ); + + luna::set_fx( ut, "can_wield", []( const UT_CLASS & utObj, const item & i ) -> bool { + const auto result = utObj.can_wield( i ); + return !result.success() ? result.success() : result.value(); + } ); + + SET_FX_T( wield, bool( item & target ) ); + + luna::set_fx( ut, "can_unwield", []( const UT_CLASS & utObj, const item & i ) -> bool { + const auto result = utObj.can_unwield( i ); + return !result.success() ? result.success() : result.value(); + } ); + + SET_FX_T( unwield, bool() ); + + SET_FX_T( is_wielding, bool( const item & ) const ); + + SET_FX_T( is_wearing, bool( const item & ) const ); + + SET_FX_T( is_wearing_on_bp, bool( const itype_id &, const bodypart_id & ) const ); + + SET_FX_T( worn_with_flag, bool( const flag_id &, const bodypart_id & ) const ); + + SET_FX_T( item_worn_with_flag, + const item * ( const flag_id &, const bodypart_id & ) const ); + + SET_FX_T( get_skill_level, int( const skill_id & ) const ); + + SET_FX_T( get_all_skills, const SkillLevelMap & () const ); + SET_FX_T( get_skill_level_object, SkillLevel & ( const skill_id & ident ) ); + + SET_FX_T( set_skill_level, void( const skill_id &, int ) ); + SET_FX_T( mod_skill_level, void( const skill_id &, int ) ); + + SET_FX_T( rust_rate, int() const ); + + SET_FX_T( practice, void( const skill_id &, int, int, bool ) ); + + SET_FX_T( read_speed, int( bool ) const ); + + SET_FX_T( get_time_died, time_point() const ); + + SET_FX_T( is_rad_immune, bool() const ); + + SET_FX_T( is_throw_immune, bool() const ); + + SET_FX_T( rest_quality, float() const ); + + SET_FX_T( healing_rate, float( float ) const ); + + SET_FX_T( healing_rate_medicine, float( float, const bodypart_id & ) const ); + + SET_FX_T( mutation_value, float( const std::string & ) const ); + + SET_FX_T( get_base_traits, std::vector() const ); + + SET_FX_T( get_mutations, std::vector( bool ) const ); + + SET_FX_T( clear_skills, void() ); + + SET_FX_T( clear_mutations, void() ); + + SET_FX_T( crossed_threshold, bool() const ); + + SET_FX_T( add_addiction, void( add_type, int ) ); + SET_FX_T( rem_addiction, void( add_type ) ); + SET_FX_T( has_addiction, bool( add_type ) const ); + SET_FX_T( addiction_level, int( add_type ) const ); + + SET_FX_T( is_hauling, bool() const ); + + SET_FX_T( has_item_with_flag, bool( const flag_id & flag, bool need_charges ) const ); + SET_FX_T( all_items_with_flag, + std::vector( const flag_id & flag ) const ); + + SET_FX_T( assign_activity, + void( const activity_id &, int, int, int, const std::string & ) ); + + SET_FX_T( has_activity, bool( const activity_id & type ) const ); + + SET_FX_T( cancel_activity, void() ); + + SET_FX_T( metabolic_rate, float() const ); + + SET_FX_T( base_age, int() const ); + SET_FX_T( set_base_age, void( int ) ); + SET_FX_T( mod_base_age, void( int ) ); + + SET_FX_T( age, int() const ); + + SET_FX_T( base_height, int() const ); + SET_FX_T( set_base_height, void( int ) ); + SET_FX_T( mod_base_height, void( int ) ); + + SET_FX_T( height, int() const ); + + SET_FX_T( bodyweight, units::mass() const ); + + SET_FX_T( bionics_weight, units::mass() const ); + + SET_FX_T( get_armor_acid, int( bodypart_id bp ) const ); + + SET_FX_T( get_stim, int() const ); + SET_FX_T( set_stim, void( int ) ); + SET_FX_T( mod_stim, void( int ) ); + + SET_FX_T( get_rad, int() const ); + SET_FX_T( set_rad, void( int ) ); + SET_FX_T( mod_rad, void( int ) ); + + SET_FX_T( get_stamina, int() const ); + SET_FX_T( get_stamina_max, int() const ); + SET_FX_T( set_stamina, void( int ) ); + SET_FX_T( mod_stamina, void( int ) ); + + SET_FX_T( wake_up, void() ); + + SET_FX_T( get_shout_volume, int() const ); + + SET_FX_T( shout, void( std::string, bool ) ); + + SET_FX_T( vomit, void() ); + + SET_FX_T( restore_scent, void() ); + + SET_FX_T( mod_painkiller, void( int ) ); + + SET_FX_T( set_painkiller, void( int ) ); + + SET_FX_T( get_painkiller, int() const ); + + SET_FX_T( spores, void() ); + SET_FX_T( blossoms, void() ); + + SET_FX_T( rooted, void() ); + + SET_FX_T( fall_asleep, void() ); + SET_FX_T( fall_asleep, void( const time_duration & duration ) ); + + SET_FX_T( get_hostile_creatures, std::vector( int ) const ); + + SET_FX_T( get_visible_creatures, std::vector( int ) const ); + + SET_FX_T( wearing_something_on, bool( const bodypart_id & ) const ); + + SET_FX_T( is_wearing_helmet, bool() const ); + + SET_FX_T( get_morale_level, int() const ); + SET_FX_T( add_morale, + void( const morale_type &, int, int, const time_duration &, const time_duration &, + bool, const itype * ) ); + SET_FX_T( has_morale, bool( const morale_type & ) const ); + SET_FX_T( get_morale, int( const morale_type & ) const ); + SET_FX_T( rem_morale, void( const morale_type & ) ); + SET_FX_T( clear_morale, void() ); + SET_FX_T( has_morale_to_read, bool() const ); + SET_FX_T( has_morale_to_craft, bool() const ); + + luna::set_fx( ut, "knows_recipe", []( const UT_CLASS & utObj, const recipe_id & rec ) -> bool { + return utObj.knows_recipe( &( rec.obj() ) ); + } ); + luna::set_fx( ut, "learn_recipe", []( UT_CLASS & utObj, const recipe_id & rec ) -> void { + utObj.learn_recipe( &( rec.obj() ) ); + } ); + + SET_FX_T( suffer, void() ); + + SET_FX_T( irradiate, bool( float rads, bool bypass ) ); + + SET_FX_T( can_hear, bool( const tripoint & source, int volume ) const ); + + SET_FX_T( hearing_ability, float() const ); + + SET_FX_T( get_lowest_hp, int() const ); + + SET_FX( bodypart_exposure ); + + } +#undef UT_CLASS // #define UT_CLASS Character + +#define UT_CLASS character_id + { + sol::usertype ut = + luna::new_usertype( + lua, + luna::no_bases, + luna::constructors < + UT_CLASS(), + UT_CLASS( int ) + > () + ); + + SET_FX( is_valid ); + SET_FX( get_value ); + } +#undef UT_CLASS // #define UT_CLASS character_id +} + +void cata::detail::reg_player( sol::state &lua ) +{ + { + // Note(AluminumAlman): skipping binding members and methods of this class because + // most of the methods and members are already binded through Character. + sol::usertype ut = + luna::new_usertype( + lua, + luna::bases(), + luna::no_constructor + ); + } +} + +void cata::detail::reg_npc( sol::state &lua ) +{ +#define UT_CLASS npc + { + sol::usertype ut = + luna::new_usertype( + lua, + luna::bases(), + luna::no_constructor + ); + + // Members + SET_MEMB( current_activity_id ); + SET_MEMB( personality ); + SET_MEMB( op_of_u ); + SET_MEMB( patience ); + SET_MEMB( marked_for_death ); + SET_MEMB( hit_by_player ); + SET_MEMB( needs ); + + // Methods + SET_FX_N_T( set_fac, "set_faction_id", void( const faction_id & id ) ); + + SET_FX_T( turned_hostile, bool() const ); + + SET_FX_T( hostile_anger_level, int() const ); + + SET_FX_T( make_angry, void() ); + + SET_FX_T( is_enemy, bool() const ); + + SET_FX_T( is_following, bool() const ); + SET_FX_T( is_obeying, bool( const Character & p ) const ); + + SET_FX_T( is_friendly, bool( const Character & p ) const ); + + SET_FX_T( is_leader, bool() const ); + + SET_FX_T( is_walking_with, bool() const ); + + SET_FX_T( is_ally, bool( const Character & p ) const ); + + SET_FX_T( is_player_ally, bool() const ); + + SET_FX_T( is_stationary, bool( bool include_guards ) const ); + + SET_FX_T( is_guarding, bool() const ); + + SET_FX_T( is_patrolling, bool() const ); + SET_FX_T( within_boundaries_of_camp, bool() const ); + + SET_FX_T( has_player_activity, bool() const ); + SET_FX_T( is_travelling, bool() const ); + + SET_FX_T( is_minion, bool() const ); + + SET_FX_T( guaranteed_hostile, bool() const ); + + SET_FX_T( mutiny, void() ); + + SET_FX_T( get_monster_faction, mfaction_id() const ); + + SET_FX_T( follow_distance, int() const ); + + SET_FX_T( current_target, Creature * () ); + SET_FX_T( current_ally, Creature * () ); + + SET_FX_T( danger_assessment, float() ); + + luna::set_fx( ut, "say", &UT_CLASS::say<> ); + + SET_FX_T( smash_ability, int() const ); + + luna::set_fx( ut, "complain_about", []( UT_CLASS & npchar, const std::string & issue, + const time_duration & dur, const std::string & speech, sol::optional force ) -> bool { + return npchar.complain_about( issue, dur, speech, force ? *force : false ); + } ); + + SET_FX_T( warn_about, + void( const std::string & type, const time_duration &, const std::string &, + int, const tripoint & ) ); + + SET_FX_T( complain, bool() ); + + SET_FX_T( evaluate_enemy, float( const Creature & ) const ); + + SET_FX_T( can_open_door, bool( const tripoint &, bool ) const ); + SET_FX_T( can_move_to, bool( const tripoint &, bool ) const ); + + SET_FX_T( saw_player_recently, bool() const ); + + SET_FX_T( has_omt_destination, bool() const ); + + SET_FX_T( get_attitude, npc_attitude() const ); + SET_FX_T( set_attitude, void( npc_attitude new_attitude ) ); + SET_FX_T( has_activity, bool() const ); + SET_FX_T( has_job, bool() const ); + } +#undef UT_CLASS // #define UT_CLASS npc + +#define UT_CLASS npc_personality + { + sol::usertype ut = + luna::new_usertype( + lua, + luna::no_bases, + luna::constructors < + UT_CLASS() + > () + ); + SET_MEMB( aggression ); + SET_MEMB( bravery ); + SET_MEMB( collector ); + SET_MEMB( altruism ); + } +#undef UT_CLASS // #define UT_CLASS npc_personality + +#define UT_CLASS npc_opinion + { + sol::usertype ut = + luna::new_usertype( + lua, + luna::no_bases, + luna::constructors < + UT_CLASS(), + UT_CLASS( int, int, int, int, int ) + > () + ); + SET_MEMB( trust ); + SET_MEMB( fear ); + SET_MEMB( value ); + SET_MEMB( anger ); + SET_MEMB( owed ); + } +#undef UT_CLASS // #define UT_CLASS npc_opinion +} + +void cata::detail::reg_avatar( sol::state &lua ) +{ + { + // Note(AluminumAlman): skipping binding members and methods of this class because + // most of the methods and members are already binded through Character. + sol::usertype ut = + luna::new_usertype( + lua, + luna::bases(), + luna::no_constructor + ); + } +} + +#endif // #ifdef LUA diff --git a/src/catalua_bindings_ids.cpp b/src/catalua_bindings_ids.cpp index 058615b2978b..10240c6c67b3 100644 --- a/src/catalua_bindings_ids.cpp +++ b/src/catalua_bindings_ids.cpp @@ -1,18 +1,29 @@ #ifdef LUA #include "catalua_bindings.h" +#include "activity_type.h" +#include "bionics.h" #include "bodypart.h" #include "catalua_luna_doc.h" #include "catalua_luna.h" +#include "disease.h" #include "effect.h" #include "faction.h" #include "field_type.h" +#include "flag.h" +#include "flag_trait.h" #include "itype.h" #include "json.h" #include "mapdata.h" +#include "martialarts.h" +#include "monfaction.h" +#include "monstergenerator.h" +#include "morale_types.h" +#include "mutation.h" +#include "recipe.h" +#include "skill.h" #include "type_id.h" - template void reg_id( sol::state &lua ) { @@ -93,13 +104,27 @@ void cata::detail::reg_game_ids( sol::state &lua ) // Some already may have them, but for the rest you can do it // with LUA_TYPE_OPS macro. - reg_id( lua ); - reg_id( lua ); - reg_id( lua ); - reg_id( lua ); + reg_id( lua ); + reg_id( lua ); reg_id( lua ); + reg_id( lua ); reg_id( lua ); + reg_id( lua ); reg_id( lua ); + reg_id( lua ); + reg_id( lua ); + reg_id( lua ); + reg_id( lua ); + reg_id( lua ); + reg_id( lua ); + reg_id( lua ); + reg_id( lua ); + reg_id( lua ); + reg_id( lua ); + reg_id( lua ); + reg_id( lua ); + reg_id( lua ); + } void cata::detail::reg_types( sol::state &lua ) diff --git a/src/catalua_bindings_utils.h b/src/catalua_bindings_utils.h index 82313bb2829a..071df434d671 100644 --- a/src/catalua_bindings_utils.h +++ b/src/catalua_bindings_utils.h @@ -14,4 +14,22 @@ void reg_serde_functions( sol::usertype &ut ) #define DOC( x ) luna::doc( x ) +// Utility macros for binding C++ to Lua for a predefined C++ class. +// Use by defining UT_CLASS in a code block. Once done, undefine UT_CLASS. +// Example use is in catalua_bindings_creature.cpp +// SET MEMBer +#define SET_MEMB(prop_name) luna::set( ut, #prop_name, &UT_CLASS::prop_name ) +// SET MEMBer with Name +//#define SET_MEMB_N(prop_name, lua_name_str) luna::set( ut, lua_name_str, &UT_CLASS::prop_name ) +// SET FX (function) +#define SET_FX(func_name) luna::set_fx ( ut, #func_name, &UT_CLASS::func_name) +// SET FX (function) with Type +#define SET_FX_T(func_name, func_type) luna::set_fx( ut, #func_name, \ + sol::resolve< func_type >( &UT_CLASS::func_name)) +// SET FX (function) with Name +//#define SET_FX_N(func_name, lua_name_str) luna::set_fx ( ut, lua_name_str, &UT_CLASS::func_name) +// SET FX (function) with Name and Type +#define SET_FX_N_T(func_name, lua_name_str, func_type) luna::set_fx( ut, lua_name_str, \ + sol::resolve< func_type >( &UT_CLASS::func_name)) + #endif // CATA_SRC_CATALUA_BINDINGS_UTILS_H diff --git a/src/catalua_luna.h b/src/catalua_luna.h index b70165b8fb2d..d1c0858a5938 100644 --- a/src/catalua_luna.h +++ b/src/catalua_luna.h @@ -2,7 +2,10 @@ #ifndef CATA_SRC_CATALUA_LUNA_H #define CATA_SRC_CATALUA_LUNA_H +#include #include +#include +#include #include #include #include @@ -141,9 +144,45 @@ std::string doc_value( sol::types> ) template std::string doc_value( sol::types> ) { - std::string ret = "Opt("; + std::string ret = "Opt( "; ret += doc_value( sol::types() ); - return ret + ")"; + return ret + " )"; +} + +template +std::string doc_value( sol::types> ) +{ + std::string ret = "Array( "; + ret += doc_value( sol::types() ); + ret += ", "; + ret += std::to_string( N ); + return ret + " )"; +} + +template +std::string doc_value( sol::types> ) +{ + std::string ret = "Vector( "; + ret += doc_value( sol::types() ); + return ret + " )"; +} + +template +std::string doc_value( sol::types> ) +{ + std::string ret = "Set( "; + ret += doc_value( sol::types() ); + return ret + " )"; +} + +template +std::string doc_value( sol::types> ) +{ + std::string ret = "Map( "; + ret += doc_value( sol::types() ); + ret += ", "; + ret += doc_value( sol::types() ); + return ret + " )"; } template diff --git a/src/catalua_luna_doc.h b/src/catalua_luna_doc.h index 31af5e440dbd..c5c4c942bf9b 100644 --- a/src/catalua_luna_doc.h +++ b/src/catalua_luna_doc.h @@ -5,41 +5,89 @@ #include "catalua_luna.h" #include "type_id.h" +enum Attitude : int; +enum body_part : int; +enum character_movemode : int; +enum class add_type : int; enum color_id : int; +enum damage_type : int; enum game_message_type : int; +enum m_flag : int; +enum m_size : int; +enum mf_attitude : int; +enum monster_attitude : int; +enum npc_attitude : int; +enum npc_need : int; +namespace sfx +{ +enum class channel : int; +} class avatar; class Character; +class character_id; class Creature; -class distribution_grid_tracker; class distribution_grid; +class distribution_grid_tracker; class effect_type; -class item_stack; class item; -class map_stack; +class item_stack; +class ma_buff; class map; +class map_stack; class monster; class npc; class player; class query_popup; +class recipe; +class Skill; +class SkillLevel; +class SkillLevelMap; class time_duration; class time_point; class tinymap; class uilist; struct body_part_type; +struct damage_instance; +struct damage_unit; +struct dealt_damage_instance; struct field_type; +struct npc_opinion; +struct npc_personality; struct point; +struct species_type; struct tripoint; +namespace units +{ +template +class quantity; + +class angle_in_radians_tag; +using angle = quantity; + +class energy_in_joule_tag; +using energy = quantity; + +class mass_in_milligram_tag; +using mass = quantity; + +class volume_in_milliliter_tag; +using volume = quantity; +} // These definitions help the doc generator LUNA_DOC( bool, "bool" ); LUNA_DOC( int, "int" ); +LUNA_DOC( unsigned int, "int" ); +LUNA_DOC( std::int64_t, "int" ); LUNA_DOC( size_t, "int" ); LUNA_DOC( float, "double" ); LUNA_DOC( double, "double" ); LUNA_DOC( void, "nil" ); LUNA_DOC( char, "char" ); +LUNA_DOC( signed char, "char" ); +LUNA_DOC( unsigned char, "char" ); LUNA_DOC( const char *, "string" ); LUNA_DOC( std::string, "string" ); LUNA_DOC( std::string_view, "string" ); @@ -52,38 +100,74 @@ LUNA_DOC( sol::protected_function, "function" ); // These definitions are for the bindings generator LUNA_VAL( avatar, "Avatar" ); LUNA_VAL( Character, "Character" ); +LUNA_VAL( character_id, "CharacterId" ); LUNA_VAL( color_id, "Color" ); LUNA_VAL( Creature, "Creature" ); -LUNA_VAL( distribution_grid_tracker, "DistributionGridTracker" ); +LUNA_VAL( damage_instance, "DamageInstance" ); +LUNA_VAL( damage_unit, "DamageUnit" ); +LUNA_VAL( dealt_damage_instance, "DealtDamageInstance" ); LUNA_VAL( distribution_grid, "DistributionGrid" ); -LUNA_VAL( item_stack, "ItemStack" ); +LUNA_VAL( distribution_grid_tracker, "DistributionGridTracker" ); LUNA_VAL( item, "Item" ); -LUNA_VAL( map_stack, "MapStack" ); +LUNA_VAL( item_stack, "ItemStack" ); LUNA_VAL( map, "Map" ); +LUNA_VAL( map_stack, "MapStack" ); LUNA_VAL( monster, "Monster" ); LUNA_VAL( npc, "Npc" ); +LUNA_VAL( npc_opinion, "NpcOpinion" ); +LUNA_VAL( npc_personality, "NpcPersonality" ); LUNA_VAL( player, "Player" ); LUNA_VAL( point, "Point" ); LUNA_VAL( query_popup, "QueryPopup" ); +LUNA_VAL( SkillLevelMap, "SkillLevelMap" ); +LUNA_VAL( SkillLevel, "SkillLevel" ); LUNA_VAL( time_duration, "TimeDuration" ); LUNA_VAL( time_point, "TimePoint" ); LUNA_VAL( tinymap, "Tinymap" ); LUNA_VAL( tripoint, "Tripoint" ); LUNA_VAL( uilist, "UiList" ); +LUNA_VAL( units::angle, "Angle" ); +LUNA_VAL( units::energy, "Energy" ); +LUNA_VAL( units::mass, "Mass" ); +LUNA_VAL( units::volume, "Volume" ); // Ids for in-game objects +LUNA_ID( activity_type, "ActivityType" ) +LUNA_ID( bionic_data, "BionicData" ) LUNA_ID( body_part_type, "BodyPartType" ) +LUNA_ID( disease_type, "DiseaseType" ) LUNA_ID( effect_type, "EffectType" ) LUNA_ID( faction, "Faction" ) LUNA_ID( field_type, "FieldType" ) LUNA_ID( furn_t, "Furn" ) LUNA_ID( itype, "Itype" ) +LUNA_ID( json_flag, "JsonFlag" ) +LUNA_ID( json_trait_flag, "JsonTraitFlag" ) +LUNA_ID( ma_buff, "MartialArtsBuff" ) +LUNA_ID( monfaction, "MonsterFaction" ) +LUNA_ID( morale_type_data, "MoraleTypeData" ) +LUNA_ID( mutation_branch, "MutationBranch" ) +LUNA_ID( mutation_category_trait, "MutationCategoryTrait" ) +LUNA_ID( recipe, "Recipe" ) +LUNA_ID( Skill, "Skill" ) +LUNA_ID( species_type, "SpeciesType" ) LUNA_ID( ter_t, "Ter" ) - // Enums +LUNA_ENUM( add_type, "AddictionType" ) +LUNA_ENUM( Attitude, "Attitude" ) +LUNA_ENUM( body_part, "BodyPart" ) +LUNA_ENUM( character_movemode, "CharacterMoveMode" ) +LUNA_ENUM( damage_type, "DamageType" ) LUNA_ENUM( game_message_type, "MsgType" ) +LUNA_ENUM( mf_attitude, "MonsterFactionAttitude" ) +LUNA_ENUM( m_flag, "MonsterFlag" ) +LUNA_ENUM( monster_attitude, "MonsterAttitude" ) +LUNA_ENUM( m_size, "MonsterSize" ) +LUNA_ENUM( npc_attitude, "NpcAttitude" ) +LUNA_ENUM( npc_need, "NpcNeed" ) +LUNA_ENUM( sfx::channel, "SfxChannel" ) #endif // CATA_SRC_CATALUA_LUNA_DOC_H diff --git a/src/creature.h b/src/creature.h index 7fabd81841b5..0e69a7597b57 100644 --- a/src/creature.h +++ b/src/creature.h @@ -55,20 +55,6 @@ struct trap; template struct enum_traits; -enum m_size : int { - MS_TINY = 0, // Squirrel - MS_SMALL, // Dog - MS_MEDIUM, // Human - MS_LARGE, // Cow - MS_HUGE, // TAAAANK - num_m_size // last -}; - -template<> -struct enum_traits { - static constexpr m_size last = m_size::num_m_size; -}; - enum FacingDirection { FD_NONE = 0, FD_LEFT = 1, diff --git a/src/damage.cpp b/src/damage.cpp index 845007f344d4..5309d408ba69 100644 --- a/src/damage.cpp +++ b/src/damage.cpp @@ -6,13 +6,14 @@ #include #include +#include "cata_utility.h" #include "debug.h" +#include "enum_conversions.h" #include "item.h" #include "json.h" #include "monster.h" #include "mtype.h" #include "translations.h" -#include "cata_utility.h" bool damage_unit::operator==( const damage_unit &other ) const { @@ -231,6 +232,40 @@ resistances &resistances::operator+=( const resistances &other ) return *this; } +template<> +std::string io::enum_to_string( damage_type dt ) +{ + // Using a switch instead of name_by_dt because otherwise the game freezes during launch + switch( dt ) { + case DT_NULL: + return "DT_NULL"; + case DT_TRUE: + return "DT_TRUE"; + case DT_BIOLOGICAL: + return "DT_BIOLOGICAL"; + case DT_BASH: + return "DT_BASH"; + case DT_CUT: + return "DT_CUT"; + case DT_ACID: + return "DT_ACID"; + case DT_STAB: + return "DT_STAB"; + case DT_HEAT: + return "DT_HEAT"; + case DT_COLD: + return "DT_COLD"; + case DT_ELECTRIC: + return "DT_ELECTRIC"; + case DT_BULLET: + return "DT_BULLET"; + case NUM_DT: + break; + } + debugmsg( "Invalid damage_type" ); + abort(); +} + static const std::map dt_map = { { translate_marker_context( "damage type", "true" ), DT_TRUE }, { translate_marker_context( "damage type", "biological" ), DT_BIOLOGICAL }, diff --git a/src/damage.h b/src/damage.h index d6eae2d0afff..ba98cdac0be5 100644 --- a/src/damage.h +++ b/src/damage.h @@ -7,6 +7,7 @@ #include #include +#include "enum_traits.h" #include "type_id.h" class item; @@ -32,6 +33,11 @@ enum damage_type : int { NUM_DT }; +template<> +struct enum_traits { + static constexpr damage_type last = NUM_DT; +}; + struct damage_unit { damage_type type; float amount; diff --git a/src/disease.h b/src/disease.h index ad66ed16724a..6418675af23e 100644 --- a/src/disease.h +++ b/src/disease.h @@ -9,6 +9,7 @@ #include "bodypart.h" #include "calendar.h" +#include "catalua_type_operators.h" #include "type_id.h" class JsonObject; @@ -34,5 +35,7 @@ class disease_type /**effect applied by this disease*/ efftype_id symptoms; + LUA_TYPE_OPS( disease_type, id ); + }; #endif // CATA_SRC_DISEASE_H diff --git a/src/enum_conversions.cpp b/src/enum_conversions.cpp new file mode 100644 index 000000000000..f258ef10cc2b --- /dev/null +++ b/src/enum_conversions.cpp @@ -0,0 +1,47 @@ +/// +/// A place for enum conversions which don't fit anywhere else +/// +#include "enum_conversions.h" + +#include "enums.h" + +template<> +std::string io::enum_to_string( Attitude att ) +{ + switch( att ) { + case Attitude::A_HOSTILE: + return "Hostile"; + case Attitude::A_NEUTRAL: + return "Neutral"; + case Attitude::A_FRIENDLY: + return "Friendly"; + case Attitude::A_ANY: + return "Any"; + case Attitude::NUM_A: + break; + } + debugmsg( "Invalid Attitude" ); + abort(); +} + +template<> +std::string io::enum_to_string( m_size data ) +{ + switch( data ) { + case m_size::MS_TINY: + return "TINY"; + case m_size::MS_SMALL: + return "SMALL"; + case m_size::MS_MEDIUM: + return "MEDIUM"; + case m_size::MS_LARGE: + return "LARGE"; + case m_size::MS_HUGE: + return "HUGE"; + case m_size::num_m_size: + break; + } + debugmsg( "Invalid body_size value: %d", static_cast( data ) ); + abort(); +} + diff --git a/src/enums.h b/src/enums.h index 78d606d48275..da4806916927 100644 --- a/src/enums.h +++ b/src/enums.h @@ -2,6 +2,8 @@ #ifndef CATA_SRC_ENUMS_H #define CATA_SRC_ENUMS_H +#include "enum_traits.h" + template struct enum_traits; template @@ -21,7 +23,13 @@ enum Attitude : int { A_HOSTILE, A_NEUTRAL, A_FRIENDLY, - A_ANY + A_ANY, + NUM_A +}; + +template<> +struct enum_traits { + static constexpr Attitude last = Attitude::NUM_A; }; enum class bionic_ui_sort_mode : int { @@ -53,6 +61,20 @@ struct enum_traits { static constexpr holiday last = holiday::num_holiday; }; +enum m_size : int { + MS_TINY = 0, // Squirrel + MS_SMALL, // Dog + MS_MEDIUM, // Human + MS_LARGE, // Cow + MS_HUGE, // TAAAANK + num_m_size // last +}; + +template<> +struct enum_traits { + static constexpr m_size last = m_size::num_m_size; +}; + enum class temperature_flag : int { TEMP_NORMAL = 0, TEMP_HEATER, diff --git a/src/flag.h b/src/flag.h index f598ff336b9d..533b099cb078 100644 --- a/src/flag.h +++ b/src/flag.h @@ -5,8 +5,10 @@ #include #include +#include "catalua_type_operators.h" #include "translations.h" #include "type_id.h" + class JsonObject; extern const flag_id flag_NULL; @@ -413,6 +415,8 @@ class json_flag static const std::vector &get_all(); + LUA_TYPE_OPS( json_flag, id ); + private: translation info_; translation restriction_; diff --git a/src/flag_trait.h b/src/flag_trait.h index 68cb479f6ef1..620e23b6bdf0 100644 --- a/src/flag_trait.h +++ b/src/flag_trait.h @@ -5,6 +5,7 @@ #include #include +#include "catalua_type_operators.h" #include "type_id.h" class JsonObject; @@ -34,6 +35,8 @@ class json_trait_flag static const std::vector &get_all(); + LUA_TYPE_OPS( json_trait_flag, id ); + private: std::set conflicts_; diff --git a/src/magic.cpp b/src/magic.cpp index 390a806ae576..df85a0d5e2e8 100644 --- a/src/magic.cpp +++ b/src/magic.cpp @@ -75,27 +75,6 @@ std::string enum_to_string( valid_target data ) abort(); } template<> -std::string enum_to_string( body_part data ) -{ - switch( data ) { - case body_part::bp_torso: return "TORSO"; - case body_part::bp_head: return "HEAD"; - case body_part::bp_eyes: return "EYES"; - case body_part::bp_mouth: return "MOUTH"; - case body_part::bp_arm_l: return "ARM_L"; - case body_part::bp_arm_r: return "ARM_R"; - case body_part::bp_hand_l: return "HAND_L"; - case body_part::bp_hand_r: return "HAND_R"; - case body_part::bp_leg_l: return "LEG_L"; - case body_part::bp_leg_r: return "LEG_R"; - case body_part::bp_foot_l: return "FOOT_L"; - case body_part::bp_foot_r: return "FOOT_R"; - case body_part::num_bp: break; - } - debugmsg( "Invalid body_part" ); - abort(); -} -template<> std::string enum_to_string( spell_flag data ) { switch( data ) { diff --git a/src/martialarts.h b/src/martialarts.h index 1418cc4db9e9..fe5268269597 100644 --- a/src/martialarts.h +++ b/src/martialarts.h @@ -10,6 +10,7 @@ #include "bonuses.h" #include "calendar.h" +#include "catalua_type_operators.h" #include "input.h" #include "translations.h" #include "type_id.h" @@ -222,6 +223,8 @@ class ma_buff bool stealthy = false; // do we make less noise when moving? void load( const JsonObject &jo, const std::string &src ); + + LUA_TYPE_OPS( ma_buff, id ); }; class martialart diff --git a/src/monfaction.cpp b/src/monfaction.cpp index 4e316db37332..6fb75fefe084 100644 --- a/src/monfaction.cpp +++ b/src/monfaction.cpp @@ -9,6 +9,7 @@ #include #include "debug.h" +#include "enum_conversions.h" #include "int_id.h" #include "json.h" #include "string_id.h" @@ -59,6 +60,13 @@ const monfaction &string_id::obj() const return id().obj(); } +/** @relates int_id */ +template<> +bool int_id::is_valid() const +{ + return faction_map.count( this->id() ) > 0; +} + /** @relates string_id */ template<> bool string_id::is_valid() const @@ -229,6 +237,25 @@ void add_to_attitude_map( const std::set< std::string > &keys, mfaction_att_map } } +template<> +std::string io::enum_to_string( mf_attitude att ) +{ + switch( att ) { + case MFA_BY_MOOD: + return "ByMood"; + case MFA_NEUTRAL: + return "Neutral"; + case MFA_FRIENDLY: + return "Friendly"; + case MFA_HATE: + return "Hate"; + case NUM_MFA: + break; + } + debugmsg( "Invalid mf_attitude" ); + abort(); +} + void monfactions::load_monster_faction( const JsonObject &jo ) { // Factions inherit values from their parent factions - this is set during finalization diff --git a/src/monfaction.h b/src/monfaction.h index 73b87ffcdb98..43f736e4de6b 100644 --- a/src/monfaction.h +++ b/src/monfaction.h @@ -4,15 +4,23 @@ #include +#include "catalua_type_operators.h" +#include "enum_traits.h" #include "type_id.h" class JsonObject; -enum mf_attitude { +enum mf_attitude : int { MFA_BY_MOOD = 0, // Hostile if angry MFA_NEUTRAL, // Neutral even when angry MFA_FRIENDLY, // Friendly - MFA_HATE // Attacks on sight + MFA_HATE, // Attacks on sight + NUM_MFA // Count of attitudes +}; + +template<> +struct enum_traits { + static constexpr mf_attitude last = NUM_MFA; }; using mfaction_att_map = std::unordered_map< mfaction_id, mf_attitude >; @@ -35,6 +43,8 @@ class monfaction mfaction_att_map attitude_map; mf_attitude attitude( const mfaction_id &other ) const; + + LUA_TYPE_OPS( monfaction, id ); }; #endif // CATA_SRC_MONFACTION_H diff --git a/src/monster.cpp b/src/monster.cpp index 7c39f490191d..5cadb78107fb 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -14,23 +14,24 @@ #include "cursesdef.h" #include "debug.h" #include "effect.h" -#include "event.h" +#include "enums.h" #include "event_bus.h" +#include "event.h" #include "explosion.h" #include "field_type.h" #include "flat_set.h" -#include "game.h" #include "game_constants.h" +#include "game.h" #include "int_id.h" -#include "item.h" #include "item_group.h" +#include "item.h" #include "itype.h" #include "line.h" #include "locations.h" #include "make_static.h" +#include "mapdata.h" #include "map.h" #include "map_iterator.h" -#include "mapdata.h" #include "mattack_common.h" #include "melee.h" #include "messages.h" @@ -1267,6 +1268,33 @@ Attitude monster::attitude_to( const Creature &other ) const return Attitude::A_NEUTRAL; } +template<> +std::string io::enum_to_string( monster_attitude att ) +{ + switch( att ) { + case MATT_NULL: + return "MATT_NULL"; + case MATT_FRIEND: + return "MATT_FRIEND"; + case MATT_FPASSIVE: + return "MATT_FPASSIVE"; + case MATT_FLEE: + return "MATT_FLEE"; + case MATT_IGNORE: + return "MATT_IGNORE"; + case MATT_FOLLOW: + return "MATT_FOLLOW"; + case MATT_ATTACK: + return "MATT_ATTACK"; + case MATT_ZLAVE: + return "MATT_ZLAVE"; + case NUM_MONSTER_ATTITUDES: + break; + } + debugmsg( "Invalid monster_attitude" ); + abort(); +} + monster_attitude monster::attitude( const Character *u ) const { if( friendly != 0 ) { diff --git a/src/monster.h b/src/monster.h index 383c8d89b8b1..d5c7328dfe84 100644 --- a/src/monster.h +++ b/src/monster.h @@ -59,7 +59,7 @@ class mon_special_attack // deserialize inline in monster::load due to backwards/forwards compatibility concerns }; -enum monster_attitude { +enum monster_attitude : int { MATT_NULL = 0, MATT_FRIEND, MATT_FPASSIVE, @@ -71,6 +71,11 @@ enum monster_attitude { NUM_MONSTER_ATTITUDES }; +template<> +struct enum_traits { + static constexpr monster_attitude last = monster_attitude::NUM_MONSTER_ATTITUDES; +}; + enum monster_effect_cache_fields { MOVEMENT_IMPAIRED = 0, FLEEING, diff --git a/src/monstergenerator.h b/src/monstergenerator.h index b5ccd80cbae3..945c78b6edbe 100644 --- a/src/monstergenerator.h +++ b/src/monstergenerator.h @@ -7,6 +7,7 @@ #include #include +#include "catalua_type_operators.h" #include "enum_bitset.h" #include "enums.h" #include "mattack_common.h" @@ -45,6 +46,8 @@ struct species_type { } void load( const JsonObject &jo, const std::string &src ); + + LUA_TYPE_OPS( species_type, id ); }; class MonsterGenerator diff --git a/src/morale_types.cpp b/src/morale_types.cpp index 70f3a9919479..3bf77d6486c7 100644 --- a/src/morale_types.cpp +++ b/src/morale_types.cpp @@ -101,6 +101,7 @@ const morale_type_data &morale_type::obj() const return morale_data.obj( *this ); } +/** @relates string_id */ template<> bool morale_type::is_valid() const { diff --git a/src/morale_types.h b/src/morale_types.h index b218dcbce3a4..f43305fb8b3a 100644 --- a/src/morale_types.h +++ b/src/morale_types.h @@ -4,6 +4,7 @@ #include +#include "catalua_type_operators.h" #include "translations.h" #include "type_id.h" @@ -34,6 +35,8 @@ class morale_type_data static void load_type( const JsonObject &jo, const std::string &src ); static void check_all(); static void reset(); + + LUA_TYPE_OPS( morale_type_data, id ); }; // Legacy crap - get rid of it when possible diff --git a/src/mutation.h b/src/mutation.h index 3b6a9dc2a16d..b71e9d5e5862 100644 --- a/src/mutation.h +++ b/src/mutation.h @@ -13,12 +13,13 @@ #include "bodypart.h" #include "calendar.h" +#include "catalua_type_operators.h" #include "creature.h" #include "damage.h" #include "hash_utils.h" #include "memory_fast.h" -#include "point.h" #include "pldata.h" +#include "point.h" #include "translations.h" #include "type_id.h" #include "value_ptr.h" @@ -399,6 +400,8 @@ struct mutation_branch { * Return the idents of all trait groups that are known. */ static std::vector get_all_group_names(); + + LUA_TYPE_OPS( mutation_branch, id ); }; struct mutation_category_trait { @@ -465,6 +468,8 @@ struct mutation_category_trait { static void check_consistency(); static void load( const JsonObject &jsobj ); + + LUA_TYPE_OPS( mutation_category_trait, id ); }; void load_mutation_type( const JsonObject &jsobj ); diff --git a/src/mutation_data.cpp b/src/mutation_data.cpp index c760a34023ac..49616c05357b 100644 --- a/src/mutation_data.cpp +++ b/src/mutation_data.cpp @@ -30,31 +30,6 @@ using trait_reader = auto_flags_reader; TraitSet trait_blacklist; TraitGroupMap trait_groups; -namespace io -{ -template<> -std::string enum_to_string( m_size data ) -{ - switch( data ) { - case m_size::MS_TINY: - return "TINY"; - case m_size::MS_SMALL: - return "SMALL"; - case m_size::MS_MEDIUM: - return "MEDIUM"; - case m_size::MS_LARGE: - return "LARGE"; - case m_size::MS_HUGE: - return "HUGE"; - case m_size::num_m_size: - return "num_m_size"; - break; - } - debugmsg( "Invalid body_size value for mutation: %d", static_cast( data ) ); - abort(); -} -} // namespace io - namespace { generic_factory trait_factory( "trait" ); @@ -896,6 +871,12 @@ std::vector mutation_branch::get_all_group_names() return rval; } +template<> +const mutation_category_trait &string_id::obj() const +{ + return mutation_category_traits.find( *this )->second; +} + bool mutation_category_is_valid( const mutation_category_id &cat ) { return mutation_category_traits.count( cat ); diff --git a/src/npc.cpp b/src/npc.cpp index d76f9a7e501e..185c252ad926 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -2628,6 +2628,16 @@ std::string npc_attitude_id( npc_attitude att ) return iter->second; } +template<> +std::string io::enum_to_string( npc_attitude att ) +{ + std::string result = npc_attitude_id( att ); + if( result == "NPCATT_INVALID" ) { + abort(); + } + return result; +} + std::string npc_attitude_name( npc_attitude att ) { switch( att ) { @@ -2952,6 +2962,33 @@ std::array, npc_need::num_needs> } }; +template<> +std::string io::enum_to_string( npc_need need ) +{ + // Thought about using npc::need_data, however, + // 'Accessing a nonexistent element through [] operator is undefined behavior.' + switch( need ) { + case need_none: + return "need_none"; + case need_ammo: + return "need_ammo"; + case need_weapon: + return "need_weapon"; + case need_gun: + return "need_gun"; + case need_food: + return "need_food"; + case need_drink: + return "need_drink"; + case need_safety: + return "need_safety"; + case num_needs: + break; + } + debugmsg( "Invalid npc_need" ); + abort(); +} + std::string npc::get_need_str_id( const npc_need &need ) { return need_data[static_cast( need )].first; diff --git a/src/npc.h b/src/npc.h index d5f61f34b599..de26ec2cd4da 100644 --- a/src/npc.h +++ b/src/npc.h @@ -24,6 +24,7 @@ #include "creature.h" #include "cursesdef.h" #include "enums.h" +#include "enum_traits.h" #include "faction.h" #include "game_constants.h" #include "int_id.h" @@ -103,6 +104,11 @@ enum npc_attitude : int { std::string npc_attitude_id( npc_attitude ); std::string npc_attitude_name( npc_attitude ); +template<> +struct enum_traits { + static constexpr npc_attitude last = NPCATT_END; +}; + // Attitudes are grouped by overall behavior towards player enum class attitude_group : int { neutral = 0, // Doesn't particularly mind the player @@ -165,13 +171,18 @@ std::string npc_class_name_str( const npc_class_id & ); enum npc_action : int; -enum npc_need { +enum npc_need : int { need_none, need_ammo, need_weapon, need_gun, need_food, need_drink, need_safety, num_needs }; +template<> +struct enum_traits { + static constexpr npc_need last = num_needs; +}; + // TODO: Turn the personality struct into a vector/map? enum npc_personality_type : int { NPE_AGGRESSION, diff --git a/src/pldata.h b/src/pldata.h index 22406c964414..9d39ddd56ac9 100644 --- a/src/pldata.h +++ b/src/pldata.h @@ -3,6 +3,8 @@ #define CATA_SRC_PLDATA_H #include "calendar.h" +#include "enum_conversions.h" +#include "enum_traits.h" class JsonIn; class JsonOut; diff --git a/src/safemode_ui.cpp b/src/safemode_ui.cpp index 690a48167ab9..350c3fb29764 100644 --- a/src/safemode_ui.cpp +++ b/src/safemode_ui.cpp @@ -401,6 +401,9 @@ void safemode::show( const std::string &custom_name_in, bool is_safemode_in ) break; case Attitude::A_ANY: attitude = Attitude::A_HOSTILE; + break; + case Attitude::NUM_A: + attitude = Attitude::A_NEUTRAL; } } else if( column == COLUMN_PROXIMITY && ( current_tab[line].category == SOUND || !current_tab[line].whitelist ) ) { diff --git a/src/skill.h b/src/skill.h index ccb2b217013d..6bb509a6bbaa 100644 --- a/src/skill.h +++ b/src/skill.h @@ -101,6 +101,11 @@ class Skill bool is_combat_skill() const; bool is_contextual_skill() const; + + // Required for LUA + inline bool operator<( const Skill &rhs ) const { + return _ident < rhs._ident; + } }; class SkillLevel diff --git a/src/sounds.cpp b/src/sounds.cpp index 8c3a624f3d7d..bed0803fd618 100644 --- a/src/sounds.cpp +++ b/src/sounds.cpp @@ -131,7 +131,43 @@ std::string enum_to_string( sounds::sound_t data ) case sounds::sound_t::order: return "order"; case sounds::sound_t::_LAST: break; } - debugmsg( "Invalid valid_target" ); + debugmsg( "Invalid sound_t" ); + abort(); +} + +template<> +std::string enum_to_string( sfx::channel chan ) +{ + switch ( chan ) { + case sfx::channel::any: return "any"; + case sfx::channel::daytime_outdoors_env: return "daytime_outdoors_env"; + case sfx::channel::nighttime_outdoors_env: return "nighttime_outdoors_env"; + case sfx::channel::underground_env: return "underground_env"; + case sfx::channel::indoors_env: return "indoors_env"; + case sfx::channel::indoors_rain_env: return "indoors_rain_env"; + case sfx::channel::outdoors_snow_env: return "outdoors_snow_env"; + case sfx::channel::outdoors_flurry_env: return "outdoors_flurry_env"; + case sfx::channel::outdoors_thunderstorm_env: return "outdoors_thunderstorm_env"; + case sfx::channel::outdoors_rain_env: return "outdoors_rain_env"; + case sfx::channel::outdoors_drizzle_env: return "outdoors_drizzle_env"; + case sfx::channel::outdoor_blizzard: return "outdoor_blizzard"; + case sfx::channel::deafness_tone: return "deafness_tone"; + case sfx::channel::danger_extreme_theme: return "danger_extreme_theme"; + case sfx::channel::danger_high_theme: return "danger_high_theme"; + case sfx::channel::danger_medium_theme: return "danger_medium_theme"; + case sfx::channel::danger_low_theme: return "danger_low_theme"; + case sfx::channel::stamina_75: return "stamina_75"; + case sfx::channel::stamina_50: return "stamina_50"; + case sfx::channel::stamina_35: return "stamina_35"; + case sfx::channel::idle_chainsaw: return "idle_chainsaw"; + case sfx::channel::chainsaw_theme: return "chainsaw_theme"; + case sfx::channel::player_activities: return "player_activities"; + case sfx::channel::exterior_engine_sound: return "exterior_engine_sound"; + case sfx::channel::interior_engine_sound: return "interior_engine_sound"; + case sfx::channel::radio: return "radio"; + case sfx::channel::MAX_CHANNEL: break; + } + debugmsg( "Invalid sound channel" ); abort(); } // *INDENT-ON* diff --git a/src/sounds.h b/src/sounds.h index 2552797460f7..0427e8eb04df 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -6,6 +6,7 @@ #include #include +#include "enum_traits.h" #include "units_angle.h" class Creature; @@ -165,4 +166,9 @@ void do_fatigue(); void do_obstacle( const std::string &obst = "" ); } // namespace sfx +template<> +struct enum_traits { + static constexpr auto last = sfx::channel::MAX_CHANNEL; +}; + #endif // CATA_SRC_SOUNDS_H diff --git a/src/string_id_null_ids.cpp b/src/string_id_null_ids.cpp index 4bd9362c6cb5..4d4cf454d525 100644 --- a/src/string_id_null_ids.cpp +++ b/src/string_id_null_ids.cpp @@ -3,67 +3,73 @@ // These are centralized in this file because they must appear in one and only one compilation unit, // and it's problematic to define them in the respective cpp files for each class. // Very repetitious, so define them with a macro. -#define MAKE_NULL_ID( type, ... ) \ +#define MAKE_CLASS_NULL_ID( type, ... ) \ class type; \ template<> const string_id &string_id::NULL_ID() { \ static string_id id = string_id( __VA_ARGS__ ); \ return id; \ } -MAKE_NULL_ID( activity_type, "ACT_NULL" ) -MAKE_NULL_ID( harvest_list, "null" ) -MAKE_NULL_ID( effect_type, "null" ) -MAKE_NULL_ID( material_type, "null" ) +MAKE_CLASS_NULL_ID( activity_type, "ACT_NULL" ) +MAKE_CLASS_NULL_ID( ammunition_type, "NULL" ) +MAKE_CLASS_NULL_ID( anatomy, "null_anatomy" ) +MAKE_CLASS_NULL_ID( disease_type, "null" ) +MAKE_CLASS_NULL_ID( effect_type, "null" ) +MAKE_CLASS_NULL_ID( emit, "null" ) +MAKE_CLASS_NULL_ID( faction, "NULL" ) +MAKE_CLASS_NULL_ID( harvest_list, "null" ) +MAKE_CLASS_NULL_ID( Item_group, "" ) +MAKE_CLASS_NULL_ID( json_flag, "null" ) +MAKE_CLASS_NULL_ID( json_trait_flag, "null" ) +MAKE_CLASS_NULL_ID( ma_buff, "null" ) +MAKE_CLASS_NULL_ID( map_extra, "" ) +MAKE_CLASS_NULL_ID( martialart, "style_none" ) +MAKE_CLASS_NULL_ID( material_type, "null" ) +MAKE_CLASS_NULL_ID( monfaction, "null" ) +MAKE_CLASS_NULL_ID( morale_type_data, "" ) +MAKE_CLASS_NULL_ID( npc_class, "NC_NONE" ) +MAKE_CLASS_NULL_ID( npc_template, "null" ) +MAKE_CLASS_NULL_ID( overmap_connection, "" ) +MAKE_CLASS_NULL_ID( overmap_land_use_code, "" ) +MAKE_CLASS_NULL_ID( overmap_special, "" ) +MAKE_CLASS_NULL_ID( recipe, "null" ) +MAKE_CLASS_NULL_ID( SkillDisplayType, "none" ) +MAKE_CLASS_NULL_ID( Skill, "none" ) +MAKE_CLASS_NULL_ID( ter_furn_transform, "null" ) +MAKE_CLASS_NULL_ID( translation, "null" ) +MAKE_CLASS_NULL_ID( VehicleGroup, "null" ) +MAKE_CLASS_NULL_ID( vpart_info, "null" ) +MAKE_CLASS_NULL_ID( zone_type, "null" ) -MAKE_NULL_ID( overmap_land_use_code, "" ) -MAKE_NULL_ID( overmap_special, "" ) -MAKE_NULL_ID( overmap_connection, "" ) -MAKE_NULL_ID( map_extra, "" ) -MAKE_NULL_ID( Skill, "none" ) -MAKE_NULL_ID( SkillDisplayType, "none" ) -MAKE_NULL_ID( npc_class, "NC_NONE" ) -MAKE_NULL_ID( npc_template, "null" ) -MAKE_NULL_ID( faction, "NULL" ) -MAKE_NULL_ID( ammunition_type, "NULL" ) -MAKE_NULL_ID( vpart_info, "null" ) -MAKE_NULL_ID( emit, "null" ) -MAKE_NULL_ID( anatomy, "null_anatomy" ) -MAKE_NULL_ID( martialart, "style_none" ) -MAKE_NULL_ID( recipe, "null" ) -MAKE_NULL_ID( ter_furn_transform, "null" ) -MAKE_NULL_ID( translation, "null" ) -MAKE_NULL_ID( Item_group, "" ) -MAKE_NULL_ID( morale_type_data, "" ) -MAKE_NULL_ID( json_trait_flag, "null" ) -MAKE_NULL_ID( VehicleGroup, "null" ) -MAKE_NULL_ID( zone_type, "null" ) -#define MAKE_NULL_ID2( type, ... ) \ + +#define MAKE_STRUCT_NULL_ID( type, ... ) \ struct type; \ template<> const string_id &string_id::NULL_ID() { \ static string_id id = string_id( __VA_ARGS__ ); \ return id; \ } -MAKE_NULL_ID2( itype, "null" ) -MAKE_NULL_ID2( mtype, "mon_null" ) -MAKE_NULL_ID2( oter_t, "" ) -MAKE_NULL_ID2( oter_type_t, "" ) -MAKE_NULL_ID2( overmap_location, "" ) -MAKE_NULL_ID2( ter_t, "t_null" ) -MAKE_NULL_ID2( trap, "tr_null" ) -MAKE_NULL_ID2( construction_category, "NULL" ) -MAKE_NULL_ID2( construction_group, "null" ) -MAKE_NULL_ID2( ammo_effect, "AE_NULL" ) -MAKE_NULL_ID2( field_type, "fd_null" ) -MAKE_NULL_ID2( furn_t, "f_null" ) -MAKE_NULL_ID2( MonsterGroup, "GROUP_NULL" ) -MAKE_NULL_ID2( mission_type, "MISSION_NULL" ) -MAKE_NULL_ID2( species_type, "spec_null" ) -MAKE_NULL_ID2( mutation_branch, "" ) -MAKE_NULL_ID2( requirement_data, "null" ) -MAKE_NULL_ID2( body_part_type, "num_bp" ) -MAKE_NULL_ID2( bionic_data, "" ) -MAKE_NULL_ID2( construction, "constr_null" ) -MAKE_NULL_ID2( vehicle_prototype, "null" ) -MAKE_NULL_ID2( weather_type, "null" ) +MAKE_STRUCT_NULL_ID( ammo_effect, "AE_NULL" ) +MAKE_STRUCT_NULL_ID( bionic_data, "" ) +MAKE_STRUCT_NULL_ID( body_part_type, "num_bp" ) +MAKE_STRUCT_NULL_ID( construction_category, "NULL" ) +MAKE_STRUCT_NULL_ID( construction, "constr_null" ) +MAKE_STRUCT_NULL_ID( construction_group, "null" ) +MAKE_STRUCT_NULL_ID( field_type, "fd_null" ) +MAKE_STRUCT_NULL_ID( furn_t, "f_null" ) +MAKE_STRUCT_NULL_ID( itype, "null" ) +MAKE_STRUCT_NULL_ID( mission_type, "MISSION_NULL" ) +MAKE_STRUCT_NULL_ID( MonsterGroup, "GROUP_NULL" ) +MAKE_STRUCT_NULL_ID( mtype, "mon_null" ) +MAKE_STRUCT_NULL_ID( mutation_branch, "" ) +MAKE_STRUCT_NULL_ID( mutation_category_trait, "null" ) +MAKE_STRUCT_NULL_ID( oter_t, "" ) +MAKE_STRUCT_NULL_ID( oter_type_t, "" ) +MAKE_STRUCT_NULL_ID( overmap_location, "" ) +MAKE_STRUCT_NULL_ID( requirement_data, "null" ) +MAKE_STRUCT_NULL_ID( species_type, "spec_null" ) +MAKE_STRUCT_NULL_ID( ter_t, "t_null" ) +MAKE_STRUCT_NULL_ID( trap, "tr_null" ) +MAKE_STRUCT_NULL_ID( vehicle_prototype, "null" ) +MAKE_STRUCT_NULL_ID( weather_type, "null" ) From 731343df8c6aeaf88c025480ed32e55c2285bb60 Mon Sep 17 00:00:00 2001 From: AluminumAlman Date: Sun, 7 Jan 2024 14:29:48 +0900 Subject: [PATCH 2/5] test: check lua bindings --- tests/catalua_test.cpp | 58 ++++++++++++++++++++++++++--- tests/lua/global_functions_test.lua | 32 ++++++++++++---- tests/lua/units_test.lua | 11 ++++++ 3 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 tests/lua/units_test.lua diff --git a/tests/catalua_test.cpp b/tests/catalua_test.cpp index a381c91365db..b8313055bd96 100644 --- a/tests/catalua_test.cpp +++ b/tests/catalua_test.cpp @@ -14,9 +14,13 @@ #include "mapdata.h" #include "options.h" #include "point.h" -#include "stringmaker.h" #include "string_formatter.h" +#include "stringmaker.h" #include "type_id.h" +#include "units_angle.h" +#include "units_energy.h" +#include "units_mass.h" +#include "units_volume.h" #include #include @@ -59,15 +63,23 @@ TEST_CASE( "lua_global_functions", "[lua]" ) // Randomize avatar name get_avatar().pick_name(); - std::string expected = get_avatar().name; + std::string expected_name = get_avatar().name; // Run Lua script run_lua_test_script( lua, "global_functions_test.lua" ); // Get test output - std::string res = test_data["out"]; - - REQUIRE( res == expected ); + std::string lua_avatar_name = test_data["avatar_name"]; + std::string lua_creature_avatar_name = test_data["creature_avatar_name"]; + std::string lua_monster_avatar_name = test_data["monster_avatar_name"]; + std::string lua_character_avatar_name = test_data["character_avatar_name"]; + std::string lua_npc_avatar_name = test_data["npc_avatar_name"]; + + REQUIRE( lua_avatar_name == expected_name ); + REQUIRE( lua_creature_avatar_name == expected_name ); + REQUIRE( lua_monster_avatar_name == "nil" ); + REQUIRE( lua_character_avatar_name == expected_name ); + REQUIRE( lua_npc_avatar_name == "nil" ); } TEST_CASE( "lua_called_from_cpp", "[lua]" ) @@ -722,4 +734,40 @@ TEST_CASE( "catalua_table_serde", "[lua]" ) } } +TEST_CASE( "lua_units_functions", "[lua]" ) +{ + sol::state lua = make_lua_state(); + + // Test variables + const double angle_degrees = 32.0; // Multiple of 2 in case of floating-point error + const int energy_kilojoules = 128; + const std::int64_t mass_kilograms = 64; + const int volume_liters = 16; + + // Create global table for test + sol::table test_data = lua.create_table(); + lua.globals()["test_data"] = test_data; + + // Set global table keys + test_data["angle_degrees"] = angle_degrees; + test_data["energy_kilojoules"] = energy_kilojoules; + test_data["mass_kilograms"] = mass_kilograms; + test_data["volume_liters"] = volume_liters; + + // Run Lua script + run_lua_test_script( lua, "units_test.lua" ); + + // Get test output + double lua_angle_arcmins = test_data["angle_arcmins"]; + int lua_energy_joules = test_data["energy_joules"]; + std::int64_t lua_mass_grams = test_data["mass_grams"]; + int lua_volume_milliliters = test_data["volume_milliliters"]; + + // Check if match + REQUIRE( lua_angle_arcmins == units::to_arcmin( units::from_degrees( angle_degrees ) ) ); + REQUIRE( lua_energy_joules == units::to_joule( units::from_kilojoule( energy_kilojoules ) ) ); + REQUIRE( lua_mass_grams == units::to_gram( units::from_kilogram( mass_kilograms ) ) ); + REQUIRE( lua_volume_milliliters == units::to_milliliter( units::from_liter( volume_liters ) ) ); +} + #endif diff --git a/tests/lua/global_functions_test.lua b/tests/lua/global_functions_test.lua index ce5ab4d55d7e..925c1d3d61bb 100644 --- a/tests/lua/global_functions_test.lua +++ b/tests/lua/global_functions_test.lua @@ -1,10 +1,28 @@ +local NIL_STRING = tostring(nil) + -- Get global avatar instance -local av = gapi.get_avatar() +local avatar = gapi.get_avatar() + +-- Get avatar name +local avatar_name = avatar.name +local avatar_pos = avatar:get_pos_ms() + +-- Run some global functions +local creature_avatar = gapi.get_creature_at(avatar_pos) +local creature_avatar_name = creature_avatar and creature_avatar:get_name() or NIL_STRING + +local monster_avatar = gapi.get_monster_at(avatar_pos) -- Should be nil +local monster_avatar_name = monster_avatar and monster_avatar.name or NIL_STRING + +local character_avatar = gapi.get_character_at(avatar_pos) +local character_avatar_name = character_avatar and character_avatar.name or NIL_STRING --- Get avatar name. --- Original C++ function accepts Character reference, --- but we don't need to care about that, inheritance works. -local av_name = gapi.get_character_name(av) +local npc_avatar = gapi.get_npc_at(avatar_pos) -- Should be nil +local npc_avatar_name = npc_avatar and npc_avatar.name or NIL_STRING --- We output single string as test result -test_data["out"] = av_name +-- Write to return table +test_data["avatar_name"] = avatar_name +test_data["creature_avatar_name"] = creature_avatar_name +test_data["monster_avatar_name"] = monster_avatar_name +test_data["character_avatar_name"] = character_avatar_name +test_data["npc_avatar_name"] = npc_avatar_name diff --git a/tests/lua/units_test.lua b/tests/lua/units_test.lua new file mode 100644 index 000000000000..da102a153fc5 --- /dev/null +++ b/tests/lua/units_test.lua @@ -0,0 +1,11 @@ +-- Get initial test data +local angle_degrees = test_data["angle_degrees"] +local energy_kilojoules = test_data["energy_kilojoules"] +local mass_kilograms = test_data["mass_kilograms"] +local volume_liters = test_data["volume_liters"] + +-- Set test results +test_data["angle_arcmins"] = Angle.from_degrees(angle_degrees):to_arcmin() +test_data["energy_joules"] = Energy.from_kilojoule(energy_kilojoules):to_joule() +test_data["mass_grams"] = Mass.from_kilogram(mass_kilograms):to_gram() +test_data["volume_milliliters"] = Volume.from_liter(volume_liters):to_milliliter() From 7ef7a962ad124ac79c4b24deaec056570b260b44 Mon Sep 17 00:00:00 2001 From: AluminumAlman Date: Sun, 7 Jan 2024 14:30:32 +0900 Subject: [PATCH 3/5] chore: bump `lua_api_version` to 2 for mods --- data/mods/saveload_lua_test/modinfo.json | 2 +- data/mods/smart_house_remotes/modinfo.json | 2 +- data/mods/teleportation_mod/modinfo.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/data/mods/saveload_lua_test/modinfo.json b/data/mods/saveload_lua_test/modinfo.json index ff7e2603b31d..3e889eb1e251 100644 --- a/data/mods/saveload_lua_test/modinfo.json +++ b/data/mods/saveload_lua_test/modinfo.json @@ -6,7 +6,7 @@ "authors": [ "Olanti" ], "description": "Mod for testing Lua save/load API.", "category": "content", - "lua_api_version": 1, + "lua_api_version": 2, "//": "It's not really obsolete, but it's useful only for devs and modders, and not for player.", "obsolete": true, "dependencies": [ "bn" ] diff --git a/data/mods/smart_house_remotes/modinfo.json b/data/mods/smart_house_remotes/modinfo.json index fbaa710560c0..1fd3b98bf622 100644 --- a/data/mods/smart_house_remotes/modinfo.json +++ b/data/mods/smart_house_remotes/modinfo.json @@ -7,7 +7,7 @@ "description": "Add remotes for controlling garage doors and window curtains.", "category": "content", "obsolete": true, - "lua_api_version": 1, + "lua_api_version": 2, "dependencies": [ "bn" ] } ] diff --git a/data/mods/teleportation_mod/modinfo.json b/data/mods/teleportation_mod/modinfo.json index 7f76dca3d9d5..615634870ef3 100644 --- a/data/mods/teleportation_mod/modinfo.json +++ b/data/mods/teleportation_mod/modinfo.json @@ -7,7 +7,7 @@ "description": "Add craftable and buildable teleporters.", "category": "content", "obsolete": false, - "lua_api_version": 1, + "lua_api_version": 2, "dependencies": [ "bn" ] } ] From 2e564f9fc2f14fd3a24736dea3f4bf68495325bd Mon Sep 17 00:00:00 2001 From: AluminumAlman Date: Sun, 7 Jan 2024 14:31:09 +0900 Subject: [PATCH 4/5] docs: lua bindings guide --- .../content/docs/en/mod/lua/guides/binding.md | 92 ++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/doc/src/content/docs/en/mod/lua/guides/binding.md b/doc/src/content/docs/en/mod/lua/guides/binding.md index 7c906863d029..fe60ff946a32 100644 --- a/doc/src/content/docs/en/mod/lua/guides/binding.md +++ b/doc/src/content/docs/en/mod/lua/guides/binding.md @@ -86,6 +86,88 @@ similar file. They are also spread out into functions, for the same reasons. Let 4. That's it. Your type is now visible in Lua under name `Horde`, and you can use the binded methods and members. +### Binding new type to Lua (using Neovim's regex) + +Binding classes/structs to Lua by hand can be quite tedious, which is why another way to bind a +class is by transforming its header file. For the third step of the second part from +[previously](#binding-new-type-to-lua), it's possible to use Neovim's built-in regex and C++ macros +to bind the class for us. + +1. Make a copy of the class definition. +2. Apply both: `%s@class \([^{]\)\+\n*{@private:@` `%s@struct \([^{]\)\+\n*{@public:@` +3. Manually remove the constructors/unwanted methods at the beginning. +4. Delete all `private`/`protected` methods: `%s@\(private:\|protected:\)\_.\{-}\(public:\|};\)@\2` +5. Remove `};` at the end of the class definition. +6. Delete `public` labels: `%s@ *public:\n@` +7. Delete comments: `%s@\( *\/\*\_.\{-}\*\/\n\{,1\}\)\|\( *\/\/\_.\{-}\(\n\)\)@\3@g` +8. Unindent until there is zero base indentation. +9. Turn method definitions into declarations: `%s@ *{\(}\|\_.\{-}\n^}\)@;` +10. Push most method declarations into a single line: `%s@\((\|,\)\n *@\1@g` +11. Remove default values: `%s@ *= *\_.\{-}\( )\|;\|,\)@\1@g` +12. Remove `overriden`/`static` methods/members and `using`s: + `%s@.*\(override\|static\|using\).*\n@@g` +13. Remove `template`s: `%s@^template<.*>\n.*\n@@g` +14. Remove `virtual` tag: `%s@^virtual *@` +15. Check if all lines end in a semicolon: `%s@\([^;]\)\n@\0@gn` +16. Count how many functions there are: `%s@\(.*(.*).*\)@@nc` +17. Push first found function to the end: `%s@\(.*(.*).*\)\n\(\n*\)\(\_.*\)@\3\1\2` +18. Now you'll want to repeat step 16 for the number of matches in step 15 minus one. For Neovim, + input the match count minus one, '@', then ':', e.g. '217@:' repeats the last command 217 times. +19. Clean up new lines: `%s@\n\{3,}@\r\r` +20. Wrap methods into a macro: `%s@\(.*\) \+\([^ ]\+\)\((.*\);@SET_FX_T( \2, \1\3 );` +21. Wrap members into a macro; make sure to select which lines to affect first: + `s@.\{-}\([^ ]\+\);@SET_MEMB( \1 );` +22. Make the previously multi-line method declarations span multiple lines again: + `%s@\(,\)\([^ ]\)@\1\r \2@g` + +Now what's left to do is to take the chunk of text and use it in a Lua binding. Continuing with the +horde example, this is how the code should look like with these macros: + +```cpp +#ifdef LUA +#include "catalua_bindings.h" +#include "catalua_bindings_utils.h" + +#include "horde.h" // Replace with the header where your type is defined + +void cata::detail::reg_horde( sol::state &lua ) +{ + #define UT_TYPE horde + sol::usertype ut = + luna::new_usertype( + lua, + luna::no_bases, + luna::constructors < + // Define your actual constructors here + UT_TYPE(), + UT_TYPE( const point & ), + UT_TYPE( int, int ) + > () + ); + + // Register all needed members + SET_MEMB( pos ); + SET_MEMB( size ); + + // Register all needed methods + SET_FX_T( move_to, ... ); // Instead of ..., there'd be the type declaration of the method. + SET_FX_T( update, ... ); + SET_FX_T( get_printable_name, ... ); + + // Add (de-)serialization functions so we can carry + // our horde over the save/load boundary + reg_serde_functions( ut ); + + // Add more stuff like arithmetic operators, to_string operator, etc. + // ... + #undef UT_TYPE // #define UT_TYPE horde +} +``` + +This method of binding to Lua lacks template method bindings and may be broken: compiler errors, +linker freezes, so it's best to assume these bindings will be broken by default, only needing slight +fixes / manual additions. + ### Binding new enum to Lua Binding enums is similar to binding types. Let's bind an imaginary `horde_type` enum here: @@ -143,11 +225,17 @@ Binding these can be done separately from binding `T` itself. 3. Ensure your type `T` implements operators `<` and `==`. It's usually easy implement them manually, and can be done semi-automatically with macro `LUA_TYPE_OPS` found in `catalua_type_operators.h`. -4. In `catalua_bindings_ids.cpp`, add the header where your type T is defined: +4. Ensure your type `T` has a null `string_id`. You can add one if it doesn't exist in + `string_id_null_ids.cpp`. Use the `MAKE_CLASS_NULL_ID` macro if `T` is defined as a class, + `MAKE_STRUCT_NULL_ID` macro otherwise. +5. Ensure your type's `T` `string_id` has `obj()` and `is_valid()` methods implemented. These + methods are implemented on a case-by-case basis. Checking other `string_id`s as example is + recommended. +6. In `catalua_bindings_ids.cpp`, add the header where your type T is defined: ```cpp #include "your_type_definition.h" ``` -5. In `reg_game_ids` function, register it like so: +7. In `reg_game_ids` function, register it like so: ```cpp reg_id( lua ); ``` From 03e79c2a667c93271b7f02e71cd09ca78a7413c2 Mon Sep 17 00:00:00 2001 From: nocontribute <> Date: Sun, 7 Jan 2024 14:32:00 +0900 Subject: [PATCH 5/5] docs: auto-generated lua docs --- .../content/docs/en/mod/lua/reference/lua.md | 3711 +++++++++++++++-- 1 file changed, 3410 insertions(+), 301 deletions(-) diff --git a/doc/src/content/docs/en/mod/lua/reference/lua.md b/doc/src/content/docs/en/mod/lua/reference/lua.md index b791c33cbd05..c9eb70a36216 100644 --- a/doc/src/content/docs/en/mod/lua/reference/lua.md +++ b/doc/src/content/docs/en/mod/lua/reference/lua.md @@ -16,6 +16,106 @@ edited directly. ::: +## ActivityTypeId + +### Bases + +No base classes. + +### Constructors + +#### `ActivityTypeId.new()` + +#### `ActivityTypeId.new( ActivityTypeId )` + +#### `ActivityTypeId.new( string )` + +### Members + +#### obj + +Function `( ActivityTypeId ) -> ActivityTypeRaw` + +#### implements_int_id + +Function `() -> bool` + +#### is_null + +Function `( ActivityTypeId ) -> bool` + +#### is_valid + +Function `( ActivityTypeId ) -> bool` + +#### str + +Function `( ActivityTypeId ) -> string` + +#### NULL_ID + +Function `() -> ActivityTypeId` + +#### __tostring + +Function `( ActivityTypeId ) -> string` + +#### serialize + +Function `( ActivityTypeId, )` + +#### deserialize + +Function `( ActivityTypeId, )` + +## Angle + +### Bases + +No base classes. + +### Constructors + +No constructors. + +### Members + +#### from_radians + +Function `( double ) -> Angle` + +#### to_radians + +Function `( Angle ) -> double` + +#### from_degrees + +Function `( double ) -> Angle` + +#### to_degrees + +Function `( Angle ) -> double` + +#### from_arcmin + +Function `( double ) -> Angle` + +#### to_arcmin + +Function `( Angle ) -> double` + +#### __eq + +Function `( Angle, Angle ) -> bool` + +#### __lt + +Function `( Angle, Angle ) -> bool` + +#### __le + +Function `( Angle, Angle ) -> bool` + ## Avatar ### Bases @@ -32,6 +132,58 @@ No constructors. No members. +## BionicDataId + +### Bases + +No base classes. + +### Constructors + +#### `BionicDataId.new()` + +#### `BionicDataId.new( BionicDataId )` + +#### `BionicDataId.new( string )` + +### Members + +#### obj + +Function `( BionicDataId ) -> BionicDataRaw` + +#### implements_int_id + +Function `() -> bool` + +#### is_null + +Function `( BionicDataId ) -> bool` + +#### is_valid + +Function `( BionicDataId ) -> bool` + +#### str + +Function `( BionicDataId ) -> string` + +#### NULL_ID + +Function `() -> BionicDataId` + +#### __tostring + +Function `( BionicDataId ) -> string` + +#### serialize + +Function `( BionicDataId, )` + +#### deserialize + +Function `( BionicDataId, )` + ## BodyPartTypeId ### Bases @@ -134,226 +286,2565 @@ No constructors. ### Members -No members. +#### name -## Creature +Variable of type `string` -### Bases +#### male -No base classes. +Variable of type `bool` -### Constructors +#### focus_pool -No constructors. +Variable of type `int` -### Members +#### cash -#### get_pos_ms +Variable of type `int` -Position within map Function `( Creature ) -> Tripoint` +#### follower_ids -#### is_monster +Variable of type `Set( CharacterId )` -Function `( Creature ) -> bool` +#### mutation_category_level -#### as_monster +Variable of type `Map( MutationCategoryTraitId, int )` -Function `( Creature ) -> Monster` +#### getID -#### is_npc +Function `( Character ) -> CharacterId` -Function `( Creature ) -> bool` +#### setID -#### as_npc +Function `( Character, CharacterId, bool )` -Function `( Creature ) -> Npc` +#### get_str -#### is_avatar +Function `( Character ) -> int` -Function `( Creature ) -> bool` +#### get_dex -#### as_avatar +Function `( Character ) -> int` -Function `( Creature ) -> Avatar` +#### get_per -#### has_effect +Function `( Character ) -> int` -Function `( Creature, EffectTypeId, Opt(BodyPartTypeId) ) -> bool` +#### get_int -#### get_effect_dur +Function `( Character ) -> int` -Function `( Creature, EffectTypeId, Opt(BodyPartTypeId) ) -> TimeDuration` +#### get_str_base -#### get_effect_int +Function `( Character ) -> int` -Function `( Creature, EffectTypeId, Opt(BodyPartTypeId) ) -> int` +#### get_dex_base -#### add_effect +Function `( Character ) -> int` -Effect type, duration, bodypart and intensity Function -`( Creature, EffectTypeId, TimeDuration, Opt(BodyPartTypeId), Opt(int) )` +#### get_per_base -#### remove_effect +Function `( Character ) -> int` -Function `( Creature, EffectTypeId, Opt(BodyPartTypeId) ) -> bool` +#### get_int_base -## DistributionGrid +Function `( Character ) -> int` -### Bases +#### get_str_bonus -No base classes. +Function `( Character ) -> int` -### Constructors +#### get_dex_bonus -No constructors. +Function `( Character ) -> int` -### Members +#### get_per_bonus -#### get_resource +Function `( Character ) -> int` -Boolean argument controls recursive behavior Function `( DistributionGrid, bool ) -> int` +#### get_int_bonus -#### mod_resource +Function `( Character ) -> int` -Boolean argument controls recursive behavior Function `( DistributionGrid, int, bool ) -> int` +#### set_str_bonus -## DistributionGridTracker +Function `( Character, int )` -### Bases +#### set_dex_bonus -No base classes. +Function `( Character, int )` -### Constructors +#### set_per_bonus -No constructors. +Function `( Character, int )` -### Members +#### set_int_bonus -#### get_grid_at_abs_ms +Function `( Character, int )` -Function `( DistributionGridTracker, Tripoint ) -> DistributionGrid` +#### mod_str_bonus -## EffectTypeId +Function `( Character, int )` -### Bases +#### mod_dex_bonus -No base classes. +Function `( Character, int )` -### Constructors +#### mod_per_bonus -#### `EffectTypeId.new()` +Function `( Character, int )` -#### `EffectTypeId.new( EffectTypeId )` +#### mod_int_bonus -#### `EffectTypeId.new( string )` +Function `( Character, int )` -### Members +#### get_healthy -#### obj +Function `( Character ) -> int` -Function `( EffectTypeId ) -> EffectTypeRaw` +#### get_healthy_mod -#### implements_int_id +Function `( Character ) -> int` -Function `() -> bool` +#### mod_healthy -#### is_null +Function `( Character, int )` -Function `( EffectTypeId ) -> bool` +#### mod_healthy_mod -#### is_valid +Function `( Character, int, int )` -Function `( EffectTypeId ) -> bool` +#### set_healthy -#### str +Function `( Character, int )` -Function `( EffectTypeId ) -> string` +#### set_healthy_mod -#### NULL_ID +Function `( Character, int )` -Function `() -> EffectTypeId` +#### get_stored_kcal -#### __tostring +Function `( Character ) -> int` -Function `( EffectTypeId ) -> string` +#### max_stored_kcal -#### serialize +Function `( Character ) -> int` -Function `( EffectTypeId, )` +#### get_kcal_percent -#### deserialize +Function `( Character ) -> double` -Function `( EffectTypeId, )` +#### get_thirst -## FactionId +Function `( Character ) -> int` -### Bases +#### get_fatigue -No base classes. +Function `( Character ) -> int` -### Constructors +#### get_sleep_deprivation -#### `FactionId.new()` +Function `( Character ) -> int` -#### `FactionId.new( FactionId )` +#### mod_stored_kcal -#### `FactionId.new( string )` +Function `( Character, int )` -### Members +#### mod_thirst -#### obj +Function `( Character, int )` -Function `( FactionId ) -> FactionRaw` +#### mod_fatigue -#### implements_int_id +Function `( Character, int )` -Function `() -> bool` +#### mod_sleep_deprivation -#### is_null +Function `( Character, int )` -Function `( FactionId ) -> bool` +#### set_stored_kcal + +Function `( Character, int )` + +#### set_thirst + +Function `( Character, int )` + +#### set_fatigue + +Function `( Character, int )` + +#### set_sleep_deprivation + +Function `( Character, int )` + +#### get_faction_id + +Function `( Character ) -> FactionId` + +#### set_faction_id + +Function `( Character, FactionId )` + +#### sight_impaired + +Function `( Character ) -> bool` + +#### has_alarm_clock + +Function `( Character ) -> bool` + +#### has_watch + +Function `( Character ) -> bool` + +#### blood_loss + +Function `( Character, BodyPartTypeIntId ) -> int` + +#### get_part_encumbrance + +Function `( Character, BodyPart ) -> int` + +#### is_wearing_power_armor + +Function `( Character, bool ) -> bool` + +#### is_wearing_active_power_armor + +Function `( Character ) -> bool` + +#### is_wearing_active_optcloak + +Function `( Character ) -> bool` + +#### in_climate_control + +Function `( Character ) -> bool` + +#### is_blind + +Function `( Character ) -> bool` + +#### is_invisible + +Function `( Character ) -> bool` + +#### get_movement_mode + +Function `( Character ) -> CharacterMoveMode` + +#### set_movement_mode + +Function `( Character, CharacterMoveMode )` + +#### expose_to_disease + +Function `( Character, DiseaseTypeId )` + +#### is_quiet + +Function `( Character ) -> bool` + +#### is_stealthy + +Function `( Character ) -> bool` + +#### cough + +Function `( Character, bool, int )` + +#### bionic_armor_bonus + +Function `( Character, BodyPartTypeIntId, DamageType ) -> double` + +#### mabuff_armor_bonus + +Function `( Character, DamageType ) -> int` + +#### has_base_trait + +Function `( Character, MutationBranchId ) -> bool` + +#### has_trait_flag + +Function `( Character, JsonTraitFlagId ) -> bool` + +#### has_opposite_trait + +Function `( Character, MutationBranchId ) -> bool` + +#### set_mutation + +Function `( Character, MutationBranchId )` + +#### unset_mutation + +Function `( Character, MutationBranchId )` + +#### can_mount + +Function `( Character, Monster ) -> bool` + +#### mount_creature + +Function `( Character, Monster )` + +#### is_mounted + +Function `( Character ) -> bool` + +#### check_mount_will_move + +Function `( Character, Tripoint ) -> bool` + +#### check_mount_is_spooked + +Function `( Character ) -> bool` + +#### dismount + +Function `( Character )` + +#### forced_dismount + +Function `( Character )` + +#### is_deaf + +Function `( Character ) -> bool` + +#### has_two_arms + +Function `( Character ) -> bool` + +#### get_working_arm_count + +Function `( Character ) -> int` + +#### get_working_leg_count + +Function `( Character ) -> int` + +#### is_limb_disabled + +Function `( Character, BodyPartTypeIntId ) -> bool` + +#### is_limb_broken + +Function `( Character, BodyPartTypeIntId ) -> bool` + +#### can_run + +Function `( Character ) -> bool` + +#### hurtall + +Function `( Character, int, Creature, bool )` + +#### hitall + +Function `( Character, int, int, Creature ) -> int` + +#### heal + +Function `( Character, BodyPartTypeIntId, int )` + +#### healall + +Function `( Character, int )` + +#### global_square_location + +Function `( Character ) -> Tripoint` + +#### global_sm_location + +Function `( Character ) -> Tripoint` + +#### has_mabuff + +Function `( Character, MartialArtsBuffId ) -> bool` + +#### mabuff_tohit_bonus + +Function `( Character ) -> double` + +#### mabuff_dodge_bonus + +Function `( Character ) -> double` + +#### mabuff_block_bonus + +Function `( Character ) -> int` + +#### mabuff_speed_bonus + +Function `( Character ) -> int` + +#### mabuff_arpen_bonus + +Function `( Character, DamageType ) -> int` + +#### mabuff_damage_mult + +Function `( Character, DamageType ) -> double` + +#### mabuff_damage_bonus + +Function `( Character, DamageType ) -> int` + +#### mabuff_attack_cost_penalty + +Function `( Character ) -> int` + +#### mabuff_attack_cost_mult + +Function `( Character ) -> double` + +#### mutation_effect + +Function `( Character, MutationBranchId )` + +#### mutation_loss_effect + +Function `( Character, MutationBranchId )` + +#### has_active_mutation + +Function `( Character, MutationBranchId ) -> bool` + +#### mutate + +Function `( Character )` + +#### mutation_ok + +Function `( Character, MutationBranchId, bool, bool ) -> bool` + +#### mutate_category + +Function `( Character, MutationCategoryTraitId )` + +#### mutate_towards + +Function `( Character, Vector( MutationBranchId ), int ) -> bool` + +#### mutate_towards + +Function `( Character, MutationBranchId ) -> bool` + +#### remove_mutation + +Function `( Character, MutationBranchId, bool )` + +#### has_child_flag + +Function `( Character, MutationBranchId ) -> bool` + +#### remove_child_flag + +Function `( Character, MutationBranchId )` + +#### get_highest_category + +Function `( Character ) -> MutationCategoryTraitId` + +#### is_weak_to_water + +Function `( Character ) -> bool` + +#### mutation_armor + +Function `( Character, BodyPartTypeIntId, DamageType ) -> double` + +#### get_bionics + +Function `( Character ) -> Vector( BionicDataId )` + +#### has_bionic + +Function `( Character, BionicDataId ) -> bool` + +#### has_active_bionic + +Function `( Character, BionicDataId ) -> bool` + +#### has_any_bionic + +Function `( Character ) -> bool` + +#### has_bionics + +Function `( Character ) -> bool` + +#### clear_bionics + +Function `( Character )` + +#### get_used_bionics_slots + +Function `( Character, BodyPartTypeIntId ) -> int` + +#### get_total_bionics_slots + +Function `( Character, BodyPartTypeIntId ) -> int` + +#### get_free_bionics_slots + +Function `( Character, BodyPartTypeIntId ) -> int` + +#### remove_bionic + +Function `( Character, BionicDataId )` + +#### add_bionic + +Function `( Character, BionicDataId )` + +#### get_power_level + +Function `( Character ) -> Energy` + +#### get_max_power_level + +Function `( Character ) -> Energy` + +#### mod_power_level + +Function `( Character, Energy )` + +#### mod_max_power_level + +Function `( Character, Energy )` + +#### set_power_level + +Function `( Character, Energy )` + +#### set_max_power_level + +Function `( Character, Energy )` + +#### is_max_power + +Function `( Character ) -> bool` + +#### has_power + +Function `( Character ) -> bool` + +#### has_max_power + +Function `( Character ) -> bool` + +#### is_worn + +Function `( Character, Item ) -> bool` + +#### weight_carried + +Function `( Character ) -> Mass` + +#### volume_carried + +Function `( Character ) -> Volume` + +#### volume_capacity + +Function `( Character ) -> Volume` + +#### can_pick_volume + +Function `( Character, Volume ) -> bool` + +#### can_pick_weight + +Function `( Character, Mass, bool ) -> bool` + +#### is_armed + +Function `( Character ) -> bool` + +#### can_wield + +Function `( Character, Item ) -> bool` + +#### wield + +Function `( Character, Item ) -> bool` + +#### can_unwield + +Function `( Character, Item ) -> bool` + +#### unwield + +Function `( Character ) -> bool` + +#### is_wielding + +Function `( Character, Item ) -> bool` + +#### is_wearing + +Function `( Character, Item ) -> bool` + +#### is_wearing_on_bp + +Function `( Character, ItypeId, BodyPartTypeIntId ) -> bool` + +#### worn_with_flag + +Function `( Character, JsonFlagId, BodyPartTypeIntId ) -> bool` + +#### item_worn_with_flag + +Function `( Character, JsonFlagId, BodyPartTypeIntId ) -> Item` + +#### get_skill_level + +Function `( Character, SkillId ) -> int` + +#### get_all_skills + +Function `( Character ) -> SkillLevelMap` + +#### get_skill_level_object + +Function `( Character, SkillId ) -> SkillLevel` + +#### set_skill_level + +Function `( Character, SkillId, int )` + +#### mod_skill_level + +Function `( Character, SkillId, int )` + +#### rust_rate + +Function `( Character ) -> int` + +#### practice + +Function `( Character, SkillId, int, int, bool )` + +#### read_speed + +Function `( Character, bool ) -> int` + +#### get_time_died + +Function `( Character ) -> TimePoint` + +#### is_rad_immune + +Function `( Character ) -> bool` + +#### is_throw_immune + +Function `( Character ) -> bool` + +#### rest_quality + +Function `( Character ) -> double` + +#### healing_rate + +Function `( Character, double ) -> double` + +#### healing_rate_medicine + +Function `( Character, double, BodyPartTypeIntId ) -> double` + +#### mutation_value + +Function `( Character, string ) -> double` + +#### get_base_traits + +Function `( Character ) -> Vector( MutationBranchId )` + +#### get_mutations + +Function `( Character, bool ) -> Vector( MutationBranchId )` + +#### clear_skills + +Function `( Character )` + +#### clear_mutations + +Function `( Character )` + +#### crossed_threshold + +Function `( Character ) -> bool` + +#### add_addiction + +Function `( Character, AddictionType, int )` + +#### rem_addiction + +Function `( Character, AddictionType )` + +#### has_addiction + +Function `( Character, AddictionType ) -> bool` + +#### addiction_level + +Function `( Character, AddictionType ) -> int` + +#### is_hauling + +Function `( Character ) -> bool` + +#### has_item_with_flag + +Function `( Character, JsonFlagId, bool ) -> bool` + +#### all_items_with_flag + +Function `( Character, JsonFlagId ) -> Vector( Item )` + +#### assign_activity + +Function `( Character, ActivityTypeId, int, int, int, string )` + +#### has_activity + +Function `( Character, ActivityTypeId ) -> bool` + +#### cancel_activity + +Function `( Character )` + +#### metabolic_rate + +Function `( Character ) -> double` + +#### base_age + +Function `( Character ) -> int` + +#### set_base_age + +Function `( Character, int )` + +#### mod_base_age + +Function `( Character, int )` + +#### age + +Function `( Character ) -> int` + +#### base_height + +Function `( Character ) -> int` + +#### set_base_height + +Function `( Character, int )` + +#### mod_base_height + +Function `( Character, int )` + +#### height + +Function `( Character ) -> int` + +#### bodyweight + +Function `( Character ) -> Mass` + +#### bionics_weight + +Function `( Character ) -> Mass` + +#### get_armor_acid + +Function `( Character, BodyPartTypeIntId ) -> int` + +#### get_stim + +Function `( Character ) -> int` + +#### set_stim + +Function `( Character, int )` + +#### mod_stim + +Function `( Character, int )` + +#### get_rad + +Function `( Character ) -> int` + +#### set_rad + +Function `( Character, int )` + +#### mod_rad + +Function `( Character, int )` + +#### get_stamina + +Function `( Character ) -> int` + +#### get_stamina_max + +Function `( Character ) -> int` + +#### set_stamina + +Function `( Character, int )` + +#### mod_stamina + +Function `( Character, int )` + +#### wake_up + +Function `( Character )` + +#### get_shout_volume + +Function `( Character ) -> int` + +#### shout + +Function `( Character, string, bool )` + +#### vomit + +Function `( Character )` + +#### restore_scent + +Function `( Character )` + +#### mod_painkiller + +Function `( Character, int )` + +#### set_painkiller + +Function `( Character, int )` + +#### get_painkiller + +Function `( Character ) -> int` + +#### spores + +Function `( Character )` + +#### blossoms + +Function `( Character )` + +#### rooted + +Function `( Character )` + +#### fall_asleep + +Function `( Character )` + +#### fall_asleep + +Function `( Character, TimeDuration )` + +#### get_hostile_creatures + +Function `( Character, int ) -> Vector( Creature )` + +#### get_visible_creatures + +Function `( Character, int ) -> Vector( Creature )` + +#### wearing_something_on + +Function `( Character, BodyPartTypeIntId ) -> bool` + +#### is_wearing_helmet + +Function `( Character ) -> bool` + +#### get_morale_level + +Function `( Character ) -> int` + +#### add_morale + +Function `( Character, MoraleTypeDataId, int, int, TimeDuration, TimeDuration, bool, ItypeRaw )` + +#### has_morale + +Function `( Character, MoraleTypeDataId ) -> bool` + +#### get_morale + +Function `( Character, MoraleTypeDataId ) -> int` + +#### rem_morale + +Function `( Character, MoraleTypeDataId )` + +#### clear_morale + +Function `( Character )` + +#### has_morale_to_read + +Function `( Character ) -> bool` + +#### has_morale_to_craft + +Function `( Character ) -> bool` + +#### knows_recipe + +Function `( Character, RecipeId ) -> bool` + +#### learn_recipe + +Function `( Character, RecipeId )` + +#### suffer + +Function `( Character )` + +#### irradiate + +Function `( Character, double, bool ) -> bool` + +#### can_hear + +Function `( Character, Tripoint, int ) -> bool` + +#### hearing_ability + +Function `( Character ) -> double` + +#### get_lowest_hp + +Function `( Character ) -> int` + +#### bodypart_exposure + +Function `( Character ) -> Map( BodyPartTypeIntId, double )` + +## CharacterId + +### Bases + +No base classes. + +### Constructors + +#### `CharacterId.new()` + +#### `CharacterId.new( int )` + +### Members + +#### is_valid + +Function `( CharacterId ) -> bool` + +#### get_value + +Function `( CharacterId ) -> int` + +## Creature + +### Bases + +No base classes. + +### Constructors + +No constructors. + +### Members + +#### get_name + +Function `( Creature ) -> string` + +#### disp_name + +Function `( Creature, bool, bool ) -> string` + +#### skin_name + +Function `( Creature ) -> string` + +#### get_grammatical_genders + +Function `( Creature ) -> Vector( string )` + +#### is_avatar + +Function `( Creature ) -> bool` + +#### is_npc + +Function `( Creature ) -> bool` + +#### is_monster + +Function `( Creature ) -> bool` + +#### as_monster + +Function `( Creature ) -> Monster` + +#### as_npc + +Function `( Creature ) -> Npc` + +#### as_character + +Function `( Creature ) -> Character` + +#### as_avatar + +Function `( Creature ) -> Avatar` + +#### hit_roll + +Function `( Creature ) -> double` + +#### dodge_roll + +Function `( Creature ) -> double` + +#### stability_roll + +Function `( Creature ) -> double` + +#### attitude_to + +Function `( Creature, Creature ) -> Attitude` + +#### sees + +Function `( Creature, Creature ) -> bool` + +#### sight_range + +Function `( Creature, int ) -> int` + +#### power_rating + +Function `( Creature ) -> double` + +#### speed_rating + +Function `( Creature ) -> double` + +#### ranged_target_size + +Function `( Creature ) -> double` + +#### knock_back_to + +Function `( Creature, Tripoint )` + +#### deal_damage + +Function `( Creature, Creature, BodyPartTypeIntId, DamageInstance ) -> DealtDamageInstance` + +#### apply_damage + +Function `( Creature, Creature, BodyPartTypeIntId, int, bool )` + +#### size_melee_penalty + +Function `( Creature ) -> int` + +#### digging + +Function `( Creature ) -> bool` + +#### is_on_ground + +Function `( Creature ) -> bool` + +#### is_underwater + +Function `( Creature ) -> bool` + +#### set_underwater + +Function `( Creature, bool )` + +#### is_warm + +Function `( Creature ) -> bool` + +#### in_species + +Function `( Creature, SpeciesTypeId ) -> bool` + +#### has_weapon + +Function `( Creature ) -> bool` + +#### is_hallucination + +Function `( Creature ) -> bool` + +#### is_dead + +Function `( Creature ) -> bool` + +#### is_elec_immune + +Function `( Creature ) -> bool` + +#### is_immune_effect + +Function `( Creature, EffectTypeId ) -> bool` + +#### is_immune_damage + +Function `( Creature, DamageType ) -> bool` + +#### get_pos_ms + +Function `( Creature ) -> Tripoint` + +#### set_pos_ms + +Function `( Creature, Tripoint )` + +#### has_effect + +Function `( Creature, EffectTypeId, Opt( BodyPartTypeId ) ) -> bool` + +#### has_effect_with_flag + +Function `( Creature, JsonFlagId, Opt( BodyPartTypeId ) ) -> bool` + +#### get_effect_dur + +Function `( Creature, EffectTypeId, Opt( BodyPartTypeId ) ) -> TimeDuration` + +#### get_effect_int + +Function `( Creature, EffectTypeId, Opt( BodyPartTypeId ) ) -> int` + +#### add_effect + +Effect type, duration, bodypart and intensity Function +`( Creature, EffectTypeId, TimeDuration, Opt( BodyPartTypeId ), Opt( int ) )` + +#### remove_effect + +Function `( Creature, EffectTypeId, Opt( BodyPartTypeId ) ) -> bool` + +#### clear_effects + +Function `( Creature )` + +#### set_value + +Function `( Creature, string, string )` + +#### remove_value + +Function `( Creature, string )` + +#### get_value + +Function `( Creature, string ) -> string` + +#### get_weight + +Function `( Creature ) -> Mass` + +#### has_trait + +Function `( Creature, MutationBranchId ) -> bool` + +#### mod_pain + +Function `( Creature, int )` + +#### mod_pain_noresist + +Function `( Creature, int )` + +#### set_pain + +Function `( Creature, int )` + +#### get_pain + +Function `( Creature ) -> int` + +#### get_perceived_pain + +Function `( Creature ) -> int` + +#### get_moves + +Function `( Creature ) -> int` + +#### mod_moves + +Function `( Creature, int )` + +#### set_moves + +Function `( Creature, int )` + +#### get_num_blocks + +Function `( Creature ) -> int` + +#### get_num_dodges + +Function `( Creature ) -> int` + +#### get_env_resist + +Function `( Creature, BodyPartTypeIntId ) -> int` + +#### get_armor_bash + +Function `( Creature, BodyPartTypeIntId ) -> int` + +#### get_armor_cut + +Function `( Creature, BodyPartTypeIntId ) -> int` + +#### get_armor_bullet + +Function `( Creature, BodyPartTypeIntId ) -> int` + +#### get_armor_bash_base + +Function `( Creature, BodyPartTypeIntId ) -> int` + +#### get_armor_cut_base + +Function `( Creature, BodyPartTypeIntId ) -> int` + +#### get_armor_bullet_base + +Function `( Creature, BodyPartTypeIntId ) -> int` + +#### get_armor_bash_bonus + +Function `( Creature ) -> int` + +#### get_armor_cut_bonus + +Function `( Creature ) -> int` + +#### get_armor_bullet_bonus + +Function `( Creature ) -> int` + +#### get_armor_type + +Function `( Creature, DamageType, BodyPartTypeIntId ) -> int` + +#### get_dodge + +Function `( Creature ) -> double` + +#### get_melee + +Function `( Creature ) -> double` + +#### get_hit + +Function `( Creature ) -> double` + +#### get_speed + +Function `( Creature ) -> int` + +#### get_size + +Function `( Creature ) -> MonsterSize` + +#### get_hp + +Function `( Creature, Opt( BodyPartTypeIntId ) ) -> int` + +#### get_hp_max + +Function `( Creature, Opt( BodyPartTypeIntId ) ) -> int` + +#### hp_percentage + +Function `( Creature ) -> int` + +#### has_flag + +Function `( Creature, MonsterFlag ) -> bool` + +#### get_part_hp_cur + +Function `( Creature, BodyPartTypeIntId ) -> int` + +#### get_part_hp_max + +Function `( Creature, BodyPartTypeIntId ) -> int` + +#### get_part_healed_total + +Function `( Creature, BodyPartTypeIntId ) -> int` + +#### set_part_hp_cur + +Function `( Creature, BodyPartTypeIntId, int )` + +#### set_part_hp_max + +Function `( Creature, BodyPartTypeIntId, int )` + +#### mod_part_hp_cur + +Function `( Creature, BodyPartTypeIntId, int )` + +#### mod_part_hp_max + +Function `( Creature, BodyPartTypeIntId, int )` + +#### set_all_parts_hp_cur + +Function `( Creature, int )` + +#### set_all_parts_hp_to_max + +Function `( Creature )` + +#### get_speed_base + +Function `( Creature ) -> int` + +#### get_speed_bonus + +Function `( Creature ) -> int` + +#### get_speed_mult + +Function `( Creature ) -> double` + +#### get_block_bonus + +Function `( Creature ) -> int` + +#### get_dodge_base + +Function `( Creature ) -> double` + +#### get_hit_base + +Function `( Creature ) -> double` + +#### get_dodge_bonus + +Function `( Creature ) -> double` + +#### get_hit_bonus + +Function `( Creature ) -> double` + +#### has_grab_break_tec + +Function `( Creature ) -> bool` + +#### get_weight_capacity + +Function `( Creature ) -> int` + +## DamageInstance + +new(damageType, amount, armorPen, remainingArmorMultiplier, damageMultiplier) + +### Bases + +No base classes. + +### Constructors + +#### `DamageInstance.new()` + +#### `DamageInstance.new( DamageType, double, double, double, double )` + +### Members + +#### damage_units + +Variable of type `Vector( DamageUnit )` + +#### mult_damage + +Function `( DamageInstance, double, bool )` + +#### type_damage + +Function `( DamageInstance, DamageType ) -> double` + +#### total_damage + +Function `( DamageInstance ) -> double` + +#### clear + +Function `( DamageInstance )` + +#### empty + +Function `( DamageInstance ) -> bool` + +#### add_damage + +Function `( DamageInstance, DamageType, double, double, double, double )` + +#### add + +Function `( DamageInstance, DamageUnit )` + +#### __eq + +Function `( DamageInstance, DamageInstance ) -> bool` + +## DamageUnit + +new(damageType, amount, armorPen, remainingArmorMultiplier, damageMultiplier) + +### Bases + +No base classes. + +### Constructors + +#### `DamageUnit.new( DamageType, double, double, double, double )` + +### Members + +#### type + +Variable of type `DamageType` + +#### amount + +Variable of type `double` + +#### res_pen + +Variable of type `double` + +#### res_mult + +Variable of type `double` + +#### damage_multiplier + +Variable of type `double` + +#### __eq + +Function `( DamageUnit, DamageUnit ) -> bool` + +## DealtDamageInstance + +Represents the final dealt damage + +### Bases + +No base classes. + +### Constructors + +No constructors. + +### Members + +#### dealt_dams + +Variable of type `Array( int, 11 )` + +#### bp_hit + +Variable of type `BodyPart` + +#### type_damage + +Function `( DealtDamageInstance, DamageType ) -> int` + +#### total_damage + +Function `( DealtDamageInstance ) -> int` + +## DiseaseTypeId + +### Bases + +No base classes. + +### Constructors + +#### `DiseaseTypeId.new()` + +#### `DiseaseTypeId.new( DiseaseTypeId )` + +#### `DiseaseTypeId.new( string )` + +### Members + +#### obj + +Function `( DiseaseTypeId ) -> DiseaseTypeRaw` + +#### implements_int_id + +Function `() -> bool` + +#### is_null + +Function `( DiseaseTypeId ) -> bool` + +#### is_valid + +Function `( DiseaseTypeId ) -> bool` + +#### str + +Function `( DiseaseTypeId ) -> string` + +#### NULL_ID + +Function `() -> DiseaseTypeId` + +#### __tostring + +Function `( DiseaseTypeId ) -> string` + +#### serialize + +Function `( DiseaseTypeId, )` + +#### deserialize + +Function `( DiseaseTypeId, )` + +## DistributionGrid + +### Bases + +No base classes. + +### Constructors + +No constructors. + +### Members + +#### get_resource + +Boolean argument controls recursive behavior Function `( DistributionGrid, bool ) -> int` + +#### mod_resource + +Boolean argument controls recursive behavior Function `( DistributionGrid, int, bool ) -> int` + +## DistributionGridTracker + +### Bases + +No base classes. + +### Constructors + +No constructors. + +### Members + +#### get_grid_at_abs_ms + +Function `( DistributionGridTracker, Tripoint ) -> DistributionGrid` + +## EffectTypeId + +### Bases + +No base classes. + +### Constructors + +#### `EffectTypeId.new()` + +#### `EffectTypeId.new( EffectTypeId )` + +#### `EffectTypeId.new( string )` + +### Members + +#### obj + +Function `( EffectTypeId ) -> EffectTypeRaw` + +#### implements_int_id + +Function `() -> bool` + +#### is_null + +Function `( EffectTypeId ) -> bool` + +#### is_valid + +Function `( EffectTypeId ) -> bool` + +#### str + +Function `( EffectTypeId ) -> string` + +#### NULL_ID + +Function `() -> EffectTypeId` + +#### __tostring + +Function `( EffectTypeId ) -> string` + +#### serialize + +Function `( EffectTypeId, )` + +#### deserialize + +Function `( EffectTypeId, )` + +## Energy + +### Bases + +No base classes. + +### Constructors + +No constructors. + +### Members + +#### from_joule + +Function `( int ) -> Energy` + +#### to_joule + +Function `( Energy ) -> int` + +#### from_kilojoule + +Function `( int ) -> Energy` + +#### to_kilojoule + +Function `( Energy ) -> int` + +#### __eq + +Function `( Energy, Energy ) -> bool` + +#### __lt + +Function `( Energy, Energy ) -> bool` + +#### __le + +Function `( Energy, Energy ) -> bool` + +## FactionId + +### Bases + +No base classes. + +### Constructors + +#### `FactionId.new()` + +#### `FactionId.new( FactionId )` + +#### `FactionId.new( string )` + +### Members + +#### obj + +Function `( FactionId ) -> FactionRaw` + +#### implements_int_id + +Function `() -> bool` + +#### is_null + +Function `( FactionId ) -> bool` + +#### is_valid + +Function `( FactionId ) -> bool` + +#### str + +Function `( FactionId ) -> string` + +#### NULL_ID + +Function `() -> FactionId` + +#### __tostring + +Function `( FactionId ) -> string` + +#### serialize + +Function `( FactionId, )` + +#### deserialize + +Function `( FactionId, )` + +## FactionRaw + +### Bases + +No base classes. + +### Constructors + +No constructors. + +### Members + +#### str_id + +Function `( FactionRaw ) -> FactionId` + +## FieldTypeId + +### Bases + +No base classes. + +### Constructors + +#### `FieldTypeId.new()` + +#### `FieldTypeId.new( FieldTypeId )` + +#### `FieldTypeId.new( FieldTypeIntId )` + +#### `FieldTypeId.new( string )` + +### Members + +#### obj + +Function `( FieldTypeId ) -> FieldTypeRaw` + +#### int_id + +Function `( FieldTypeId ) -> FieldTypeIntId` + +#### implements_int_id + +Function `() -> bool` + +#### is_null + +Function `( FieldTypeId ) -> bool` + +#### is_valid + +Function `( FieldTypeId ) -> bool` + +#### str + +Function `( FieldTypeId ) -> string` + +#### NULL_ID + +Function `() -> FieldTypeId` + +#### __tostring + +Function `( FieldTypeId ) -> string` + +#### serialize + +Function `( FieldTypeId, )` + +#### deserialize + +Function `( FieldTypeId, )` + +## FieldTypeIntId + +### Bases + +No base classes. + +### Constructors + +#### `FieldTypeIntId.new()` + +#### `FieldTypeIntId.new( FieldTypeIntId )` + +#### `FieldTypeIntId.new( FieldTypeId )` + +### Members + +#### obj + +Function `( FieldTypeIntId ) -> FieldTypeRaw` + +#### str_id + +Function `( FieldTypeIntId ) -> FieldTypeId` + +#### is_valid + +Function `( FieldTypeIntId ) -> bool` + +#### __tostring + +Function `( FieldTypeIntId ) -> string` + +## FurnId + +### Bases + +No base classes. + +### Constructors + +#### `FurnId.new()` + +#### `FurnId.new( FurnId )` + +#### `FurnId.new( FurnIntId )` + +#### `FurnId.new( string )` + +### Members + +#### obj + +Function `( FurnId ) -> FurnRaw` + +#### int_id + +Function `( FurnId ) -> FurnIntId` + +#### implements_int_id + +Function `() -> bool` + +#### is_null + +Function `( FurnId ) -> bool` + +#### is_valid + +Function `( FurnId ) -> bool` + +#### str + +Function `( FurnId ) -> string` + +#### NULL_ID + +Function `() -> FurnId` + +#### __tostring + +Function `( FurnId ) -> string` + +#### serialize + +Function `( FurnId, )` + +#### deserialize + +Function `( FurnId, )` + +## FurnIntId + +### Bases + +No base classes. + +### Constructors + +#### `FurnIntId.new()` + +#### `FurnIntId.new( FurnIntId )` + +#### `FurnIntId.new( FurnId )` + +### Members + +#### obj + +Function `( FurnIntId ) -> FurnRaw` + +#### str_id + +Function `( FurnIntId ) -> FurnId` + +#### is_valid + +Function `( FurnIntId ) -> bool` + +#### __tostring + +Function `( FurnIntId ) -> string` + +## FurnRaw + +### Bases + +No base classes. + +### Constructors + +No constructors. + +### Members + +#### str_id + +Function `( FurnRaw ) -> FurnId` + +#### int_id + +Function `( FurnRaw ) -> FurnIntId` + +#### open + +Variable of type `FurnId` + +#### close + +Variable of type `FurnId` + +#### transforms_into + +Variable of type `FurnId` + +## Item + +### Bases + +No base classes. + +### Constructors + +No constructors. + +### Members + +#### get_type + +Function `( Item ) -> ItypeId` + +#### has_var + +Check for variable of any type Function `( Item, string ) -> bool` + +#### erase_var + +Erase variable Function `( Item, string )` + +#### clear_vars + +Erase all variables Function `( Item )` + +#### get_var_str + +Get variable as string Function `( Item, string, string ) -> string` + +#### get_var_num + +Get variable as float number Function `( Item, string, double ) -> double` + +#### get_var_tri + +Get variable as tripoint Function `( Item, string, Tripoint ) -> Tripoint` + +#### set_var_str + +Function `( Item, string, string )` + +#### set_var_num + +Function `( Item, string, double )` + +#### set_var_tri + +Function `( Item, string, Tripoint )` + +## ItemStack + +Iterate over this using pairs() + +### Bases + +No base classes. + +### Constructors + +No constructors. + +### Members + +#### __pairs + +Function +`( ItemStack ) -> ( , , nil )` + +## ItypeId + +### Bases + +No base classes. + +### Constructors + +#### `ItypeId.new()` + +#### `ItypeId.new( ItypeId )` + +#### `ItypeId.new( string )` + +### Members + +#### obj + +Function `( ItypeId ) -> ItypeRaw` + +#### implements_int_id + +Function `() -> bool` + +#### is_null + +Function `( ItypeId ) -> bool` + +#### is_valid + +Function `( ItypeId ) -> bool` + +#### str + +Function `( ItypeId ) -> string` + +#### NULL_ID + +Function `() -> ItypeId` + +#### __tostring + +Function `( ItypeId ) -> string` + +#### serialize + +Function `( ItypeId, )` + +#### deserialize + +Function `( ItypeId, )` + +## JsonFlagId + +### Bases + +No base classes. + +### Constructors + +#### `JsonFlagId.new()` + +#### `JsonFlagId.new( JsonFlagId )` + +#### `JsonFlagId.new( string )` + +### Members + +#### obj + +Function `( JsonFlagId ) -> JsonFlagRaw` + +#### implements_int_id + +Function `() -> bool` + +#### is_null + +Function `( JsonFlagId ) -> bool` + +#### is_valid + +Function `( JsonFlagId ) -> bool` + +#### str + +Function `( JsonFlagId ) -> string` + +#### NULL_ID + +Function `() -> JsonFlagId` + +#### __tostring + +Function `( JsonFlagId ) -> string` + +#### serialize + +Function `( JsonFlagId, )` + +#### deserialize + +Function `( JsonFlagId, )` + +## JsonTraitFlagId + +### Bases + +No base classes. + +### Constructors + +#### `JsonTraitFlagId.new()` + +#### `JsonTraitFlagId.new( JsonTraitFlagId )` + +#### `JsonTraitFlagId.new( string )` + +### Members + +#### obj + +Function `( JsonTraitFlagId ) -> JsonTraitFlagRaw` + +#### implements_int_id + +Function `() -> bool` + +#### is_null + +Function `( JsonTraitFlagId ) -> bool` + +#### is_valid + +Function `( JsonTraitFlagId ) -> bool` + +#### str + +Function `( JsonTraitFlagId ) -> string` + +#### NULL_ID + +Function `() -> JsonTraitFlagId` + +#### __tostring + +Function `( JsonTraitFlagId ) -> string` + +#### serialize + +Function `( JsonTraitFlagId, )` + +#### deserialize + +Function `( JsonTraitFlagId, )` + +## Map + +### Bases + +No base classes. + +### Constructors + +No constructors. + +### Members + +#### get_abs_ms + +Convert local ms -> absolute ms Function `( Map, Tripoint ) -> Tripoint` + +#### get_local_ms + +Convert absolute ms -> local ms Function `( Map, Tripoint ) -> Tripoint` + +#### get_map_size_in_submaps + +Function `( Map ) -> int` + +#### get_map_size + +In map squares Function `( Map ) -> int` + +#### has_items_at + +Function `( Map, Tripoint ) -> bool` + +#### get_items_at + +Function `( Map, Tripoint ) -> ` + +#### get_ter_at + +Function `( Map, Tripoint ) -> TerIntId` + +#### set_ter_at + +Function `( Map, Tripoint, TerIntId ) -> bool` + +#### get_furn_at + +Function `( Map, Tripoint ) -> FurnIntId` + +#### set_furn_at + +Function `( Map, Tripoint, FurnIntId )` + +#### has_field_at + +Function `( Map, Tripoint, FieldTypeIntId ) -> bool` + +#### get_field_int_at + +Function `( Map, Tripoint, FieldTypeIntId ) -> int` + +#### get_field_age_at + +Function `( Map, Tripoint, FieldTypeIntId ) -> TimeDuration` + +#### mod_field_int_at + +Function `( Map, Tripoint, FieldTypeIntId, int ) -> int` + +#### mod_field_age_at + +Function `( Map, Tripoint, FieldTypeIntId, TimeDuration ) -> TimeDuration` + +#### set_field_int_at + +Function `( Map, Tripoint, FieldTypeIntId, int, bool ) -> int` + +#### set_field_age_at + +Function `( Map, Tripoint, FieldTypeIntId, TimeDuration, bool ) -> TimeDuration` + +#### add_field_at + +Function `( Map, Tripoint, FieldTypeIntId, int, TimeDuration ) -> bool` + +#### remove_field_at + +Function `( Map, Tripoint, FieldTypeIntId )` + +## MapStack + +### Bases + +- `ItemStack` + +### Constructors + +No constructors. + +### Members + +#### as_item_stack + +Function `( MapStack ) -> ItemStack` + +## MartialArtsBuffId + +### Bases + +No base classes. + +### Constructors + +#### `MartialArtsBuffId.new()` + +#### `MartialArtsBuffId.new( MartialArtsBuffId )` + +#### `MartialArtsBuffId.new( string )` + +### Members + +#### obj + +Function `( MartialArtsBuffId ) -> MartialArtsBuffRaw` + +#### implements_int_id + +Function `() -> bool` + +#### is_null + +Function `( MartialArtsBuffId ) -> bool` + +#### is_valid + +Function `( MartialArtsBuffId ) -> bool` + +#### str + +Function `( MartialArtsBuffId ) -> string` + +#### NULL_ID + +Function `() -> MartialArtsBuffId` + +#### __tostring + +Function `( MartialArtsBuffId ) -> string` + +#### serialize + +Function `( MartialArtsBuffId, )` + +#### deserialize + +Function `( MartialArtsBuffId, )` + +## Mass + +### Bases + +No base classes. + +### Constructors + +No constructors. + +### Members + +#### from_milligram + +Function `( int ) -> Mass` + +#### to_milligram + +Function `( Mass ) -> int` + +#### from_gram + +Function `( int ) -> Mass` + +#### to_gram + +Function `( Mass ) -> int` + +#### from_kilogram + +Function `( int ) -> Mass` + +#### to_kilogram + +Function `( Mass ) -> int` + +#### from_newton + +Function `( int ) -> Mass` + +#### to_newton + +Function `( Mass ) -> int` + +#### __eq + +Function `( Mass, Mass ) -> bool` + +#### __lt + +Function `( Mass, Mass ) -> bool` + +#### __le + +Function `( Mass, Mass ) -> bool` + +## Monster + +### Bases + +- `Creature` + +### Constructors + +No constructors. + +### Members + +#### friendly + +Variable of type `int` + +#### anger + +Variable of type `int` + +#### morale + +Variable of type `int` + +#### faction + +Variable of type `MonsterFactionIntId` + +#### death_drops + +Variable of type `bool` + +#### unique_name + +Variable of type `string` + +#### can_upgrade + +Function `( Monster ) -> bool` + +#### hasten_upgrade + +Function `( Monster )` + +#### get_upgrade_time + +Function `( Monster ) -> int` + +#### try_upgrade + +Function `( Monster, bool )` + +#### try_reproduce + +Function `( Monster )` + +#### refill_udders + +Function `( Monster )` + +#### spawn + +Function `( Monster, Tripoint )` + +#### name + +Function `( Monster, int ) -> string` + +#### name_with_armor + +Function `( Monster ) -> string` + +#### can_see + +Function `( Monster ) -> bool` + +#### can_hear + +Function `( Monster ) -> bool` + +#### can_submerge + +Function `( Monster ) -> bool` + +#### can_drown + +Function `( Monster ) -> bool` + +#### can_climb + +Function `( Monster ) -> bool` + +#### can_dig + +Function `( Monster ) -> bool` + +#### digs + +Function `( Monster ) -> bool` + +#### flies + +Function `( Monster ) -> bool` + +#### climbs + +Function `( Monster ) -> bool` + +#### swims + +Function `( Monster ) -> bool` -#### is_valid +#### move_target -Function `( FactionId ) -> bool` +Function `( Monster ) -> Tripoint` -#### str +#### is_wandering -Function `( FactionId ) -> string` +Function `( Monster ) -> bool` -#### NULL_ID +#### wander_to -Function `() -> FactionId` +Function `( Monster, Tripoint, int )` -#### __tostring +#### move_to -Function `( FactionId ) -> string` +Function `( Monster, Tripoint, bool, bool, double ) -> bool` -#### serialize +#### attitude -Function `( FactionId, )` +Function `( Monster, Character ) -> MonsterAttitude` -#### deserialize +#### heal -Function `( FactionId, )` +Function `( Monster, int, bool ) -> int` -## FactionRaw +#### set_hp -### Bases +Function `( Monster, int )` -No base classes. +#### make_fungus -### Constructors +Function `( Monster ) -> bool` -No constructors. +#### make_friendly -### Members +Function `( Monster )` -#### str_id +#### make_ally -Function `( FactionRaw ) -> FactionId` +Function `( Monster, Monster )` -## FieldTypeId +## MonsterFactionId ### Bases @@ -361,23 +2852,23 @@ No base classes. ### Constructors -#### `FieldTypeId.new()` +#### `MonsterFactionId.new()` -#### `FieldTypeId.new( FieldTypeId )` +#### `MonsterFactionId.new( MonsterFactionId )` -#### `FieldTypeId.new( FieldTypeIntId )` +#### `MonsterFactionId.new( MonsterFactionIntId )` -#### `FieldTypeId.new( string )` +#### `MonsterFactionId.new( string )` ### Members #### obj -Function `( FieldTypeId ) -> FieldTypeRaw` +Function `( MonsterFactionId ) -> MonsterFactionRaw` #### int_id -Function `( FieldTypeId ) -> FieldTypeIntId` +Function `( MonsterFactionId ) -> MonsterFactionIntId` #### implements_int_id @@ -385,33 +2876,33 @@ Function `() -> bool` #### is_null -Function `( FieldTypeId ) -> bool` +Function `( MonsterFactionId ) -> bool` #### is_valid -Function `( FieldTypeId ) -> bool` +Function `( MonsterFactionId ) -> bool` #### str -Function `( FieldTypeId ) -> string` +Function `( MonsterFactionId ) -> string` #### NULL_ID -Function `() -> FieldTypeId` +Function `() -> MonsterFactionId` #### __tostring -Function `( FieldTypeId ) -> string` +Function `( MonsterFactionId ) -> string` #### serialize -Function `( FieldTypeId, )` +Function `( MonsterFactionId, )` #### deserialize -Function `( FieldTypeId, )` +Function `( MonsterFactionId, )` -## FieldTypeIntId +## MonsterFactionIntId ### Bases @@ -419,31 +2910,31 @@ No base classes. ### Constructors -#### `FieldTypeIntId.new()` +#### `MonsterFactionIntId.new()` -#### `FieldTypeIntId.new( FieldTypeIntId )` +#### `MonsterFactionIntId.new( MonsterFactionIntId )` -#### `FieldTypeIntId.new( FieldTypeId )` +#### `MonsterFactionIntId.new( MonsterFactionId )` ### Members #### obj -Function `( FieldTypeIntId ) -> FieldTypeRaw` +Function `( MonsterFactionIntId ) -> MonsterFactionRaw` #### str_id -Function `( FieldTypeIntId ) -> FieldTypeId` +Function `( MonsterFactionIntId ) -> MonsterFactionId` #### is_valid -Function `( FieldTypeIntId ) -> bool` +Function `( MonsterFactionIntId ) -> bool` #### __tostring -Function `( FieldTypeIntId ) -> string` +Function `( MonsterFactionIntId ) -> string` -## FurnId +## MoraleTypeDataId ### Bases @@ -451,23 +2942,17 @@ No base classes. ### Constructors -#### `FurnId.new()` - -#### `FurnId.new( FurnId )` +#### `MoraleTypeDataId.new()` -#### `FurnId.new( FurnIntId )` +#### `MoraleTypeDataId.new( MoraleTypeDataId )` -#### `FurnId.new( string )` +#### `MoraleTypeDataId.new( string )` ### Members #### obj -Function `( FurnId ) -> FurnRaw` - -#### int_id - -Function `( FurnId ) -> FurnIntId` +Function `( MoraleTypeDataId ) -> MoraleTypeDataRaw` #### implements_int_id @@ -475,33 +2960,33 @@ Function `() -> bool` #### is_null -Function `( FurnId ) -> bool` +Function `( MoraleTypeDataId ) -> bool` #### is_valid -Function `( FurnId ) -> bool` +Function `( MoraleTypeDataId ) -> bool` #### str -Function `( FurnId ) -> string` +Function `( MoraleTypeDataId ) -> string` #### NULL_ID -Function `() -> FurnId` +Function `() -> MoraleTypeDataId` #### __tostring -Function `( FurnId ) -> string` +Function `( MoraleTypeDataId ) -> string` #### serialize -Function `( FurnId, )` +Function `( MoraleTypeDataId, )` #### deserialize -Function `( FurnId, )` +Function `( MoraleTypeDataId, )` -## FurnIntId +## MutationBranchId ### Bases @@ -509,31 +2994,51 @@ No base classes. ### Constructors -#### `FurnIntId.new()` +#### `MutationBranchId.new()` -#### `FurnIntId.new( FurnIntId )` +#### `MutationBranchId.new( MutationBranchId )` -#### `FurnIntId.new( FurnId )` +#### `MutationBranchId.new( string )` ### Members #### obj -Function `( FurnIntId ) -> FurnRaw` +Function `( MutationBranchId ) -> MutationBranchRaw` -#### str_id +#### implements_int_id -Function `( FurnIntId ) -> FurnId` +Function `() -> bool` + +#### is_null + +Function `( MutationBranchId ) -> bool` #### is_valid -Function `( FurnIntId ) -> bool` +Function `( MutationBranchId ) -> bool` + +#### str + +Function `( MutationBranchId ) -> string` + +#### NULL_ID + +Function `() -> MutationBranchId` #### __tostring -Function `( FurnIntId ) -> string` +Function `( MutationBranchId ) -> string` -## FurnRaw +#### serialize + +Function `( MutationBranchId, )` + +#### deserialize + +Function `( MutationBranchId, )` + +## MutationCategoryTraitId ### Bases @@ -541,35 +3046,57 @@ No base classes. ### Constructors -No constructors. +#### `MutationCategoryTraitId.new()` + +#### `MutationCategoryTraitId.new( MutationCategoryTraitId )` + +#### `MutationCategoryTraitId.new( string )` ### Members -#### str_id +#### obj -Function `( FurnRaw ) -> FurnId` +Function `( MutationCategoryTraitId ) -> MutationCategoryTraitRaw` -#### int_id +#### implements_int_id -Function `( FurnRaw ) -> FurnIntId` +Function `() -> bool` -#### open +#### is_null -Variable of type `FurnId` +Function `( MutationCategoryTraitId ) -> bool` -#### close +#### is_valid -Variable of type `FurnId` +Function `( MutationCategoryTraitId ) -> bool` -#### transforms_into +#### str -Variable of type `FurnId` +Function `( MutationCategoryTraitId ) -> string` -## Item +#### NULL_ID + +Function `() -> MutationCategoryTraitId` + +#### __tostring + +Function `( MutationCategoryTraitId ) -> string` + +#### serialize + +Function `( MutationCategoryTraitId, )` + +#### deserialize + +Function `( MutationCategoryTraitId, )` + +## Npc ### Bases -No base classes. +- `Player` +- `Character` +- `Creature` ### Constructors @@ -577,250 +3104,255 @@ No constructors. ### Members -#### get_type +#### current_activity_id -Function `( Item ) -> ItypeId` +Variable of type `ActivityTypeId` -#### has_var +#### personality -Check for variable of any type Function `( Item, string ) -> bool` +Variable of type `NpcPersonality` -#### erase_var +#### op_of_u -Erase variable Function `( Item, string )` +Variable of type `NpcOpinion` -#### clear_vars +#### patience -Erase all variables Function `( Item )` +Variable of type `int` -#### get_var_str +#### marked_for_death -Get variable as string Function `( Item, string, string ) -> string` +Variable of type `bool` -#### get_var_num +#### hit_by_player -Get variable as float number Function `( Item, string, double ) -> double` +Variable of type `bool` -#### get_var_tri +#### needs -Get variable as tripoint Function `( Item, string, Tripoint ) -> Tripoint` +Variable of type `Vector( NpcNeed )` -#### set_var_str +#### set_faction_id -Function `( Item, string, string )` +Function `( Npc, FactionId )` -#### set_var_num +#### turned_hostile -Function `( Item, string, double )` +Function `( Npc ) -> bool` -#### set_var_tri +#### hostile_anger_level -Function `( Item, string, Tripoint )` +Function `( Npc ) -> int` -## ItemStack +#### make_angry -Iterate over this using pairs() +Function `( Npc )` -### Bases +#### is_enemy -No base classes. +Function `( Npc ) -> bool` -### Constructors +#### is_following -No constructors. +Function `( Npc ) -> bool` -### Members +#### is_obeying -#### __pairs +Function `( Npc, Character ) -> bool` -Function -`( ItemStack ) -> ( , , nil )` +#### is_friendly -## ItypeId +Function `( Npc, Character ) -> bool` -### Bases +#### is_leader -No base classes. +Function `( Npc ) -> bool` -### Constructors +#### is_walking_with -#### `ItypeId.new()` +Function `( Npc ) -> bool` -#### `ItypeId.new( ItypeId )` +#### is_ally -#### `ItypeId.new( string )` +Function `( Npc, Character ) -> bool` -### Members +#### is_player_ally -#### obj +Function `( Npc ) -> bool` -Function `( ItypeId ) -> ItypeRaw` +#### is_stationary -#### implements_int_id +Function `( Npc, bool ) -> bool` -Function `() -> bool` +#### is_guarding -#### is_null +Function `( Npc ) -> bool` -Function `( ItypeId ) -> bool` +#### is_patrolling -#### is_valid +Function `( Npc ) -> bool` -Function `( ItypeId ) -> bool` +#### within_boundaries_of_camp -#### str +Function `( Npc ) -> bool` -Function `( ItypeId ) -> string` +#### has_player_activity -#### NULL_ID +Function `( Npc ) -> bool` -Function `() -> ItypeId` +#### is_travelling -#### __tostring +Function `( Npc ) -> bool` -Function `( ItypeId ) -> string` +#### is_minion -#### serialize +Function `( Npc ) -> bool` -Function `( ItypeId, )` +#### guaranteed_hostile -#### deserialize +Function `( Npc ) -> bool` -Function `( ItypeId, )` +#### mutiny -## Map +Function `( Npc )` -### Bases +#### get_monster_faction -No base classes. +Function `( Npc ) -> MonsterFactionIntId` -### Constructors +#### follow_distance -No constructors. +Function `( Npc ) -> int` -### Members +#### current_target -#### get_abs_ms +Function `( Npc ) -> Creature` -Convert local ms -> absolute ms Function `( Map, Tripoint ) -> Tripoint` +#### current_ally -#### get_local_ms +Function `( Npc ) -> Creature` -Convert absolute ms -> local ms Function `( Map, Tripoint ) -> Tripoint` +#### danger_assessment -#### get_map_size_in_submaps +Function `( Npc ) -> double` -Function `( Map ) -> int` +#### say -#### get_map_size +Function `( Npc, string )` -In map squares Function `( Map ) -> int` +#### smash_ability -#### has_items_at +Function `( Npc ) -> int` -Function `( Map, Tripoint ) -> bool` +#### complain_about -#### get_items_at +Function `( Npc, string, TimeDuration, string, Opt( bool ) ) -> bool` -Function `( Map, Tripoint ) -> ` +#### warn_about -#### get_ter_at +Function `( Npc, string, TimeDuration, string, int, Tripoint )` -Function `( Map, Tripoint ) -> TerIntId` +#### complain -#### set_ter_at +Function `( Npc ) -> bool` -Function `( Map, Tripoint, TerIntId ) -> bool` +#### evaluate_enemy -#### get_furn_at +Function `( Npc, Creature ) -> double` -Function `( Map, Tripoint ) -> FurnIntId` +#### can_open_door -#### set_furn_at +Function `( Npc, Tripoint, bool ) -> bool` -Function `( Map, Tripoint, FurnIntId )` +#### can_move_to -#### has_field_at +Function `( Npc, Tripoint, bool ) -> bool` -Function `( Map, Tripoint, FieldTypeIntId ) -> bool` +#### saw_player_recently -#### get_field_int_at +Function `( Npc ) -> bool` -Function `( Map, Tripoint, FieldTypeIntId ) -> int` +#### has_omt_destination -#### get_field_age_at +Function `( Npc ) -> bool` -Function `( Map, Tripoint, FieldTypeIntId ) -> TimeDuration` +#### get_attitude -#### mod_field_int_at +Function `( Npc ) -> NpcAttitude` -Function `( Map, Tripoint, FieldTypeIntId, int ) -> int` +#### set_attitude -#### mod_field_age_at +Function `( Npc, NpcAttitude )` -Function `( Map, Tripoint, FieldTypeIntId, TimeDuration ) -> TimeDuration` +#### has_activity -#### set_field_int_at +Function `( Npc ) -> bool` -Function `( Map, Tripoint, FieldTypeIntId, int, bool ) -> int` +#### has_job -#### set_field_age_at +Function `( Npc ) -> bool` -Function `( Map, Tripoint, FieldTypeIntId, TimeDuration, bool ) -> TimeDuration` +## NpcOpinion -#### add_field_at +### Bases -Function `( Map, Tripoint, FieldTypeIntId, int, TimeDuration ) -> bool` +No base classes. -#### remove_field_at +### Constructors -Function `( Map, Tripoint, FieldTypeIntId )` +#### `NpcOpinion.new()` -## MapStack +#### `NpcOpinion.new( int, int, int, int, int )` -### Bases +### Members -- `ItemStack` +#### trust -### Constructors +Variable of type `int` -No constructors. +#### fear -### Members +Variable of type `int` -#### as_item_stack +#### value -Function `( MapStack ) -> ItemStack` +Variable of type `int` -## Monster +#### anger + +Variable of type `int` + +#### owed + +Variable of type `int` + +## NpcPersonality ### Bases -- `Creature` +No base classes. ### Constructors -No constructors. +#### `NpcPersonality.new()` ### Members -No members. +#### aggression -## Npc +Variable of type `char` -### Bases +#### bravery -- `Player` -- `Character` -- `Creature` +Variable of type `char` -### Constructors +#### collector -No constructors. +Variable of type `char` -### Members +#### altruism -No members. +Variable of type `char` ## Player @@ -941,6 +3473,218 @@ Set whether to allow any key Function `( QueryPopup, bool )` Returns selected action Function `( QueryPopup ) -> string` +## RecipeId + +### Bases + +No base classes. + +### Constructors + +#### `RecipeId.new()` + +#### `RecipeId.new( RecipeId )` + +#### `RecipeId.new( string )` + +### Members + +#### obj + +Function `( RecipeId ) -> RecipeRaw` + +#### implements_int_id + +Function `() -> bool` + +#### is_null + +Function `( RecipeId ) -> bool` + +#### is_valid + +Function `( RecipeId ) -> bool` + +#### str + +Function `( RecipeId ) -> string` + +#### NULL_ID + +Function `() -> RecipeId` + +#### __tostring + +Function `( RecipeId ) -> string` + +#### serialize + +Function `( RecipeId, )` + +#### deserialize + +Function `( RecipeId, )` + +## SkillId + +### Bases + +No base classes. + +### Constructors + +#### `SkillId.new()` + +#### `SkillId.new( SkillId )` + +#### `SkillId.new( string )` + +### Members + +#### obj + +Function `( SkillId ) -> SkillRaw` + +#### implements_int_id + +Function `() -> bool` + +#### is_null + +Function `( SkillId ) -> bool` + +#### is_valid + +Function `( SkillId ) -> bool` + +#### str + +Function `( SkillId ) -> string` + +#### NULL_ID + +Function `() -> SkillId` + +#### __tostring + +Function `( SkillId ) -> string` + +#### serialize + +Function `( SkillId, )` + +#### deserialize + +Function `( SkillId, )` + +## SkillLevel + +### Bases + +No base classes. + +### Constructors + +No constructors. + +### Members + +#### is_training + +Function `( SkillLevel ) -> bool` + +#### level + +Function `( SkillLevel ) -> int` + +#### highest_level + +Function `( SkillLevel ) -> int` + +#### train + +Function `( SkillLevel, int, bool )` + +#### can_train + +Function `( SkillLevel ) -> bool` + +## SkillLevelMap + +### Bases + +- `Map( SkillId, SkillLevel )` + +### Constructors + +No constructors. + +### Members + +#### mod_skill_level + +Function `( SkillLevelMap, SkillId, int )` + +#### get_skill_level + +Function `( SkillLevelMap, SkillId ) -> int` + +#### get_skill_level_object + +Function `( SkillLevelMap, SkillId ) -> SkillLevel` + +## SpeciesTypeId + +### Bases + +No base classes. + +### Constructors + +#### `SpeciesTypeId.new()` + +#### `SpeciesTypeId.new( SpeciesTypeId )` + +#### `SpeciesTypeId.new( string )` + +### Members + +#### obj + +Function `( SpeciesTypeId ) -> SpeciesTypeRaw` + +#### implements_int_id + +Function `() -> bool` + +#### is_null + +Function `( SpeciesTypeId ) -> bool` + +#### is_valid + +Function `( SpeciesTypeId ) -> bool` + +#### str + +Function `( SpeciesTypeId ) -> string` + +#### NULL_ID + +Function `() -> SpeciesTypeId` + +#### __tostring + +Function `( SpeciesTypeId ) -> string` + +#### serialize + +Function `( SpeciesTypeId, )` + +#### deserialize + +Function `( SpeciesTypeId, )` + ## TerId ### Bases @@ -1380,8 +4124,101 @@ Return value, text Function `( UiList, int, string )` Returns retval for selected entry, or a negative number on fail/cancel Function `( UiList ) -> int` +## Volume + +### Bases + +No base classes. + +### Constructors + +No constructors. + +### Members + +#### from_milliliter + +Function `( int ) -> Volume` + +#### from_liter + +Function `( int ) -> Volume` + +#### to_milliliter + +Function `( Volume ) -> int` + +#### to_liter + +Function `( Volume ) -> double` + +#### __eq + +Function `( Volume, Volume ) -> bool` + +#### __lt + +Function `( Volume, Volume ) -> bool` + +#### __le + +Function `( Volume, Volume ) -> bool` + # Enums +## AddictionType + +### Entries + +- `NONE` = `0` +- `CAFFEINE` = `1` +- `ALCOHOL` = `2` +- `SLEEP` = `3` +- `PKILLER` = `4` +- `SPEED` = `5` +- `CIG` = `6` +- `COKE` = `7` +- `CRACK` = `8` +- `MUTAGEN` = `9` +- `DIAZEPAM` = `10` +- `MARLOSS_R` = `11` +- `MARLOSS_B` = `12` +- `MARLOSS_Y` = `13` + +## Attitude + +### Entries + +- `Hostile` = `0` +- `Neutral` = `1` +- `Friendly` = `2` +- `Any` = `3` + +## BodyPart + +### Entries + +- `TORSO` = `0` +- `HEAD` = `1` +- `EYES` = `2` +- `MOUTH` = `3` +- `ARM_L` = `4` +- `ARM_R` = `5` +- `HAND_L` = `6` +- `HAND_R` = `7` +- `LEG_L` = `8` +- `LEG_R` = `9` +- `FOOT_L` = `10` +- `FOOT_R` = `11` + +## CharacterMoveMode + +### Entries + +- `walk` = `0` +- `run` = `1` +- `crouch` = `2` + ## Color ### Entries @@ -1532,6 +4369,172 @@ Returns retval for selected entry, or a negative number on fail/cancel Function - `c_cyan_cyan` = `143` - `c_light_cyan_cyan` = `144` +## DamageType + +### Entries + +- `DT_NULL` = `0` +- `DT_TRUE` = `1` +- `DT_BIOLOGICAL` = `2` +- `DT_BASH` = `3` +- `DT_CUT` = `4` +- `DT_ACID` = `5` +- `DT_STAB` = `6` +- `DT_HEAT` = `7` +- `DT_COLD` = `8` +- `DT_ELECTRIC` = `9` +- `DT_BULLET` = `10` + +## MonsterAttitude + +### Entries + +- `MATT_NULL` = `0` +- `MATT_FRIEND` = `1` +- `MATT_FPASSIVE` = `2` +- `MATT_FLEE` = `3` +- `MATT_IGNORE` = `4` +- `MATT_FOLLOW` = `5` +- `MATT_ATTACK` = `6` +- `MATT_ZLAVE` = `7` + +## MonsterFactionAttitude + +### Entries + +- `ByMood` = `0` +- `Neutral` = `1` +- `Friendly` = `2` +- `Hate` = `3` + +## MonsterFlag + +### Entries + +- `SEES` = `0` +- `HEARS` = `1` +- `GOODHEARING` = `2` +- `SMELLS` = `3` +- `KEENNOSE` = `4` +- `STUMBLES` = `5` +- `WARM` = `6` +- `NOHEAD` = `7` +- `HARDTOSHOOT` = `8` +- `GRABS` = `9` +- `BASHES` = `10` +- `DESTROYS` = `11` +- `BORES` = `12` +- `POISON` = `13` +- `VENOM` = `14` +- `BADVENOM` = `15` +- `PARALYZEVENOM` = `16` +- `BLEED` = `17` +- `WEBWALK` = `18` +- `DIGS` = `19` +- `CAN_DIG` = `20` +- `FLIES` = `21` +- `AQUATIC` = `22` +- `SWIMS` = `23` +- `ATTACKMON` = `24` +- `ANIMAL` = `25` +- `PLASTIC` = `26` +- `SUNDEATH` = `27` +- `ELECTRIC` = `28` +- `ACIDPROOF` = `29` +- `ACIDTRAIL` = `30` +- `SHORTACIDTRAIL` = `31` +- `FIREPROOF` = `32` +- `SLUDGEPROOF` = `33` +- `SLUDGETRAIL` = `34` +- `COLDPROOF` = `35` +- `BIOPROOF` = `36` +- `FIREY` = `37` +- `QUEEN` = `38` +- `ELECTRONIC` = `39` +- `FUR` = `40` +- `LEATHER` = `41` +- `WOOL` = `42` +- `FEATHER` = `43` +- `BONES` = `44` +- `FAT` = `45` +- `CONSOLE_DESPAWN` = `46` +- `IMMOBILE` = `47` +- `ID_CARD_DESPAWN` = `48` +- `RIDEABLE_MECH` = `49` +- `MILITARY_MECH` = `50` +- `MECH_RECON_VISION` = `51` +- `MECH_DEFENSIVE` = `52` +- `HIT_AND_RUN` = `53` +- `GUILT` = `54` +- `PAY_BOT` = `55` +- `HUMAN` = `56` +- `NO_BREATHE` = `57` +- `FLAMMABLE` = `58` +- `REVIVES` = `59` +- `CHITIN` = `60` +- `VERMIN` = `61` +- `NOGIB` = `62` +- `LARVA` = `63` +- `ARTHROPOD_BLOOD` = `64` +- `ACID_BLOOD` = `65` +- `BILE_BLOOD` = `66` +- `ABSORBS` = `67` +- `ABSORBS_SPLITS` = `68` +- `CBM_CIV` = `69` +- `CBM_POWER` = `70` +- `CBM_SCI` = `71` +- `CBM_OP` = `72` +- `CBM_TECH` = `73` +- `CBM_SUBS` = `74` +- `FILTHY` = `75` +- `FISHABLE` = `76` +- `GROUP_BASH` = `77` +- `SWARMS` = `78` +- `GROUP_MORALE` = `79` +- `INTERIOR_AMMO` = `80` +- `CLIMBS` = `81` +- `PACIFIST` = `82` +- `PUSH_MON` = `83` +- `PUSH_VEH` = `84` +- `NIGHT_INVISIBILITY` = `85` +- `REVIVES_HEALTHY` = `86` +- `NO_NECRO` = `87` +- `PATH_AVOID_DANGER_1` = `88` +- `PATH_AVOID_DANGER_2` = `89` +- `PATH_AVOID_FIRE` = `90` +- `PATH_AVOID_FALL` = `91` +- `PRIORITIZE_TARGETS` = `92` +- `NOT_HALLUCINATION` = `93` +- `CATFOOD` = `94` +- `CATTLEFODDER` = `95` +- `BIRDFOOD` = `96` +- `CANPLAY` = `97` +- `PET_MOUNTABLE` = `98` +- `PET_HARNESSABLE` = `99` +- `DOGFOOD` = `100` +- `MILKABLE` = `101` +- `SHEARABLE` = `102` +- `NO_BREED` = `103` +- `NO_FUNG_DMG` = `104` +- `PET_WONT_FOLLOW` = `105` +- `DRIPS_NAPALM` = `106` +- `DRIPS_GASOLINE` = `107` +- `ELECTRIC_FIELD` = `108` +- `LOUDMOVES` = `109` +- `CAN_OPEN_DOORS` = `110` +- `STUN_IMMUNE` = `111` +- `DROPS_AMMO` = `112` + +## MonsterSize + +### Entries + +- `TINY` = `0` +- `SMALL` = `1` +- `MEDIUM` = `2` +- `LARGE` = `3` +- `HUGE` = `4` + ## MsgType ### Entries @@ -1547,6 +4550,72 @@ Returns retval for selected entry, or a negative number on fail/cancel Function - `critical` = `8` - `grazing` = `9` +## NpcAttitude + +### Entries + +- `NPCATT_NULL` = `0` +- `NPCATT_TALK` = `1` +- `NPCATT_LEGACY_1` = `2` +- `NPCATT_FOLLOW` = `3` +- `NPCATT_LEGACY_2` = `4` +- `NPCATT_LEAD` = `5` +- `NPCATT_WAIT` = `6` +- `NPCATT_LEGACY_6` = `7` +- `NPCATT_MUG` = `8` +- `NPCATT_WAIT_FOR_LEAVE` = `9` +- `NPCATT_KILL` = `10` +- `NPCATT_FLEE` = `11` +- `NPCATT_LEGACY_3` = `12` +- `NPCATT_HEAL` = `13` +- `NPCATT_LEGACY_4` = `14` +- `NPCATT_LEGACY_5` = `15` +- `NPCATT_ACTIVITY` = `16` +- `NPCATT_FLEE_TEMP` = `17` +- `NPCATT_RECOVER_GOODS` = `18` + +## NpcNeed + +### Entries + +- `need_none` = `0` +- `need_ammo` = `1` +- `need_weapon` = `2` +- `need_gun` = `3` +- `need_food` = `4` +- `need_drink` = `5` +- `need_safety` = `6` + +## SfxChannel + +### Entries + +- `daytime_outdoors_env` = `0` +- `nighttime_outdoors_env` = `1` +- `underground_env` = `2` +- `indoors_env` = `3` +- `indoors_rain_env` = `4` +- `outdoors_snow_env` = `5` +- `outdoors_flurry_env` = `6` +- `outdoors_thunderstorm_env` = `7` +- `outdoors_rain_env` = `8` +- `outdoors_drizzle_env` = `9` +- `outdoor_blizzard` = `10` +- `deafness_tone` = `11` +- `danger_extreme_theme` = `12` +- `danger_high_theme` = `13` +- `danger_medium_theme` = `14` +- `danger_low_theme` = `15` +- `stamina_75` = `16` +- `stamina_50` = `17` +- `stamina_35` = `18` +- `idle_chainsaw` = `19` +- `chainsaw_theme` = `20` +- `player_activities` = `21` +- `exterior_engine_sound` = `22` +- `interior_engine_sound` = `23` +- `radio` = `24` + # Libraries ## const @@ -1599,15 +4668,15 @@ Function `( Tripoint ) -> ( Point, Tripoint )` #### sm_to_ms -Function `( Tripoint, Opt(Point) ) -> Tripoint` +Function `( Tripoint, Opt( Point ) ) -> Tripoint` #### omt_to_ms -Function `( Tripoint, Opt(Point) ) -> Tripoint` +Function `( Tripoint, Opt( Point ) ) -> Tripoint` #### om_to_ms -Function `( Point, Opt(Tripoint) ) -> Tripoint` +Function `( Point, Opt( Tripoint ) ) -> Tripoint` #### rl_dist @@ -1639,10 +4708,6 @@ Function `() -> Map` Function `() -> DistributionGridTracker` -#### get_character_name - -Function `( Character ) -> string` - #### add_msg Function `( MsgType, ... )` Function `( ... )` @@ -1671,6 +4736,50 @@ Function `( int, int ) -> int` Function `( TimeDuration, function )` +#### get_creature_at + +Function `( Tripoint, Opt( bool ) ) -> Creature` + +#### get_monster_at + +Function `( Tripoint, Opt( bool ) ) -> Monster` + +#### get_character_at + +Function `( Tripoint, Opt( bool ) ) -> Character` + +#### get_npc_at + +Function `( Tripoint, Opt( bool ) ) -> Npc` + +#### choose_adjacent + +Function `( string, Opt( bool ) ) -> Opt( Tripoint )` + +#### choose_direction + +Function `( string, Opt( bool ) ) -> Opt( Tripoint )` + +#### look_around + +Function `() -> Opt( Tripoint )` + +#### play_variant_sound + +Function `( string, string, int )` Function `( string, string, int, Angle, double, double )` + +#### play_ambient_variant_sound + +Function `( string, string, int, SfxChannel, int, double, int )` + +#### add_npc_follower + +Function `( Npc )` + +#### remove_npc_follower + +Function `( Npc )` + ## gdebug Debugging and logging API.