From 397b68696b7197c7b7ea89342bab4c93f7084e2e Mon Sep 17 00:00:00 2001 From: jmd Date: Fri, 29 Nov 2024 20:12:50 -0800 Subject: [PATCH] [objects] add: Creature::update_appearance [rules] add: load size from appearance.2da [profiles] add: appearance constants --- lib/nw/objects/Appearance.cpp | 7 +- lib/nw/objects/Appearance.hpp | 3 +- lib/nw/objects/Creature.cpp | 25 +- lib/nw/objects/Creature.hpp | 3 + lib/nw/profiles/nwn1/constants.hpp | 406 +++++++++++++++++++++++++++++ lib/nw/rules/attributes.cpp | 1 + lib/nw/rules/attributes.hpp | 1 + tests/kernel_objects.cpp | 4 +- tests/objects_creature.cpp | 18 +- 9 files changed, 448 insertions(+), 20 deletions(-) diff --git a/lib/nw/objects/Appearance.cpp b/lib/nw/objects/Appearance.cpp index b7ecc8729..91f5bcd73 100644 --- a/lib/nw/objects/Appearance.cpp +++ b/lib/nw/objects/Appearance.cpp @@ -114,7 +114,10 @@ bool deserialize(CreatureAppearance& self, const GffStruct& archive) self.wings = old; } - archive.get_to("Appearance_Type", self.id); + uint16_t temp; + if (archive.get_to("Appearance_Type", temp)) { + self.id = Appearance::make(temp); + } archive.get_to("Portrait", self.portrait, false); archive.get_to("PortraitId", self.portrait_id, self.portrait.length() == 0); archive.get_to("Appearance_Head", self.body_parts.head, false); // Only in dynamic models @@ -187,7 +190,7 @@ bool serialize(const CreatureAppearance& self, GffBuilderStruct& archive) { archive.add_field("Tail_New", self.tail) .add_field("Wings_New", self.wings) - .add_field("Appearance_Type", self.id) + .add_field("Appearance_Type", uint16_t(*self.id)) .add_field("PortraitId", self.portrait_id) .add_field("Appearance_Head", uint8_t(self.body_parts.head)) .add_field("BodyPart_Belt", uint8_t(self.body_parts.belt)) diff --git a/lib/nw/objects/Appearance.hpp b/lib/nw/objects/Appearance.hpp index 1492630ac..90e41e0d1 100644 --- a/lib/nw/objects/Appearance.hpp +++ b/lib/nw/objects/Appearance.hpp @@ -1,5 +1,6 @@ #pragma once +#include "../rules/attributes.hpp" #include "../serialization/Serialization.hpp" namespace nw { @@ -45,7 +46,7 @@ struct CreatureAppearance { uint32_t tail = 0; uint32_t wings = 0; - uint16_t id = 0; + Appearance id = Appearance::invalid(); Resref portrait; uint16_t portrait_id = 0; diff --git a/lib/nw/objects/Creature.cpp b/lib/nw/objects/Creature.cpp index 77b6e46e7..bc7464200 100644 --- a/lib/nw/objects/Creature.cpp +++ b/lib/nw/objects/Creature.cpp @@ -119,16 +119,8 @@ void Creature::clear() bool Creature::instantiate() { if (instantiated_) return true; - auto tda = kernel::twodas().get("appearance"); - if (tda) { - if (tda->get_to(appearance.id, "SIZECATEGORY", size)) { - auto cresize = kernel::twodas().get("creaturesize"); - if (cresize) { - cresize->get_to(size, "ACATTACKMOD", combat_info.size_ab_modifier); - cresize->get_to(size, "ACATTACKMOD", combat_info.size_ac_modifier); - } - } - } + update_appearance(appearance.id); + nw::kernel::objects().run_instantiate_callback(this); instantiated_ = (inventory.instantiate() && equipment.instantiate()); size_t i = 0; @@ -206,6 +198,19 @@ AlignmentFlags Creature::alignment_flags() const noexcept return result; } +void Creature::update_appearance(Appearance id) +{ + auto app = kernel::rules().appearances.get(id); + if (!app) { return; } + + size = app->size; + auto cresize = kernel::twodas().get("creaturesize"); + if (cresize) { + cresize->get_to(size, "ACATTACKMOD", combat_info.size_ab_modifier); + cresize->get_to(size, "ACATTACKMOD", combat_info.size_ac_modifier); + } +} + bool Creature::deserialize(Creature* obj, const nlohmann::json& archive, SerializationProfile profile) { if (!obj) { diff --git a/lib/nw/objects/Creature.hpp b/lib/nw/objects/Creature.hpp index 2efc6dab3..109ff3fff 100644 --- a/lib/nw/objects/Creature.hpp +++ b/lib/nw/objects/Creature.hpp @@ -68,6 +68,9 @@ struct Creature : public ObjectBase { /// Gets alignment flags AlignmentFlags alignment_flags() const noexcept; + /// Update creatures appearance + void update_appearance(Appearance id); + Common common; CreatureAppearance appearance; CombatInfo combat_info; diff --git a/lib/nw/profiles/nwn1/constants.hpp b/lib/nw/profiles/nwn1/constants.hpp index 256553c92..67638d393 100644 --- a/lib/nw/profiles/nwn1/constants.hpp +++ b/lib/nw/profiles/nwn1/constants.hpp @@ -17,6 +17,412 @@ constexpr nw::Ability ability_intelligence = nw::Ability::make(3); constexpr nw::Ability ability_wisdom = nw::Ability::make(4); constexpr nw::Ability ability_charisma = nw::Ability::make(5); +constexpr nw::Appearance appearance_type_invalid = nw::Appearance::invalid(); +constexpr nw::Appearance appearance_type_allip = nw::Appearance::make(186); +constexpr nw::Appearance appearance_type_aranea = nw::Appearance::make(157); +constexpr nw::Appearance appearance_type_arch_target = nw::Appearance::make(200); +constexpr nw::Appearance appearance_type_aribeth = nw::Appearance::make(190); +constexpr nw::Appearance appearance_type_asabi_chieftain = nw::Appearance::make(353); +constexpr nw::Appearance appearance_type_asabi_shaman = nw::Appearance::make(354); +constexpr nw::Appearance appearance_type_asabi_warrior = nw::Appearance::make(355); +constexpr nw::Appearance appearance_type_badger = nw::Appearance::make(8); +constexpr nw::Appearance appearance_type_badger_dire = nw::Appearance::make(9); +constexpr nw::Appearance appearance_type_balor = nw::Appearance::make(38); +constexpr nw::Appearance appearance_type_bartender = nw::Appearance::make(234); +constexpr nw::Appearance appearance_type_basilisk = nw::Appearance::make(369); +constexpr nw::Appearance appearance_type_bat = nw::Appearance::make(10); +constexpr nw::Appearance appearance_type_bat_horror = nw::Appearance::make(11); +constexpr nw::Appearance appearance_type_bear_black = nw::Appearance::make(12); +constexpr nw::Appearance appearance_type_bear_brown = nw::Appearance::make(13); +constexpr nw::Appearance appearance_type_bear_dire = nw::Appearance::make(15); +constexpr nw::Appearance appearance_type_bear_kodiak = nw::Appearance::make(204); +constexpr nw::Appearance appearance_type_bear_polar = nw::Appearance::make(14); +constexpr nw::Appearance appearance_type_beetle_fire = nw::Appearance::make(18); +constexpr nw::Appearance appearance_type_beetle_slicer = nw::Appearance::make(17); +constexpr nw::Appearance appearance_type_beetle_stag = nw::Appearance::make(19); +constexpr nw::Appearance appearance_type_beetle_stink = nw::Appearance::make(20); +constexpr nw::Appearance appearance_type_begger = nw::Appearance::make(220); +constexpr nw::Appearance appearance_type_blood_sailer = nw::Appearance::make(221); +constexpr nw::Appearance appearance_type_boar = nw::Appearance::make(21); +constexpr nw::Appearance appearance_type_boar_dire = nw::Appearance::make(22); +constexpr nw::Appearance appearance_type_bodak = nw::Appearance::make(23); +constexpr nw::Appearance appearance_type_bugbear_a = nw::Appearance::make(29); +constexpr nw::Appearance appearance_type_bugbear_b = nw::Appearance::make(30); +constexpr nw::Appearance appearance_type_bugbear_chieftain_a = nw::Appearance::make(25); +constexpr nw::Appearance appearance_type_bugbear_chieftain_b = nw::Appearance::make(26); +constexpr nw::Appearance appearance_type_bugbear_shaman_a = nw::Appearance::make(27); +constexpr nw::Appearance appearance_type_bugbear_shaman_b = nw::Appearance::make(28); +constexpr nw::Appearance appearance_type_bulette = nw::Appearance::make(481); +constexpr nw::Appearance appearance_type_cat_cat_dire = nw::Appearance::make(95); +constexpr nw::Appearance appearance_type_cat_cougar = nw::Appearance::make(203); +constexpr nw::Appearance appearance_type_cat_crag_cat = nw::Appearance::make(94); +constexpr nw::Appearance appearance_type_cat_jaguar = nw::Appearance::make(98); +constexpr nw::Appearance appearance_type_cat_krenshar = nw::Appearance::make(96); +constexpr nw::Appearance appearance_type_cat_leopard = nw::Appearance::make(93); +constexpr nw::Appearance appearance_type_cat_lion = nw::Appearance::make(97); +constexpr nw::Appearance appearance_type_cat_mpanther = nw::Appearance::make(306); +constexpr nw::Appearance appearance_type_cat_panther = nw::Appearance::make(202); +constexpr nw::Appearance appearance_type_chicken = nw::Appearance::make(31); +constexpr nw::Appearance appearance_type_cockatrice = nw::Appearance::make(368); +constexpr nw::Appearance appearance_type_combat_dummy = nw::Appearance::make(201); +constexpr nw::Appearance appearance_type_convict = nw::Appearance::make(238); +constexpr nw::Appearance appearance_type_cow = nw::Appearance::make(34); +constexpr nw::Appearance appearance_type_cult_member = nw::Appearance::make(212); +constexpr nw::Appearance appearance_type_deer = nw::Appearance::make(35); +constexpr nw::Appearance appearance_type_deer_stag = nw::Appearance::make(37); +constexpr nw::Appearance appearance_type_devil = nw::Appearance::make(392); +constexpr nw::Appearance appearance_type_dog = nw::Appearance::make(176); +constexpr nw::Appearance appearance_type_dog_blinkdog = nw::Appearance::make(174); +constexpr nw::Appearance appearance_type_dog_dire_wolf = nw::Appearance::make(175); +constexpr nw::Appearance appearance_type_dog_fenhound = nw::Appearance::make(177); +constexpr nw::Appearance appearance_type_dog_hell_hound = nw::Appearance::make(179); +constexpr nw::Appearance appearance_type_dog_shadow_mastif = nw::Appearance::make(180); +constexpr nw::Appearance appearance_type_dog_winter_wolf = nw::Appearance::make(184); +constexpr nw::Appearance appearance_type_dog_wolf = nw::Appearance::make(181); +constexpr nw::Appearance appearance_type_dog_worg = nw::Appearance::make(185); +constexpr nw::Appearance appearance_type_doom_knight = nw::Appearance::make(40); +constexpr nw::Appearance appearance_type_dragon_black = nw::Appearance::make(41); +constexpr nw::Appearance appearance_type_dragon_blue = nw::Appearance::make(47); +constexpr nw::Appearance appearance_type_dragon_brass = nw::Appearance::make(42); +constexpr nw::Appearance appearance_type_dragon_bronze = nw::Appearance::make(45); +constexpr nw::Appearance appearance_type_dragon_copper = nw::Appearance::make(43); +constexpr nw::Appearance appearance_type_dragon_gold = nw::Appearance::make(46); +constexpr nw::Appearance appearance_type_dragon_green = nw::Appearance::make(48); +constexpr nw::Appearance appearance_type_dragon_red = nw::Appearance::make(49); +constexpr nw::Appearance appearance_type_dragon_silver = nw::Appearance::make(44); +constexpr nw::Appearance appearance_type_dragon_white = nw::Appearance::make(50); +constexpr nw::Appearance appearance_type_drow_cleric = nw::Appearance::make(215); +constexpr nw::Appearance appearance_type_drow_fighter = nw::Appearance::make(216); +constexpr nw::Appearance appearance_type_druegar_cleric = nw::Appearance::make(218); +constexpr nw::Appearance appearance_type_druegar_fighter = nw::Appearance::make(217); +constexpr nw::Appearance appearance_type_dryad = nw::Appearance::make(51); +constexpr nw::Appearance appearance_type_dwarf = nw::Appearance::make(0); +constexpr nw::Appearance appearance_type_dwarf_npc_female = nw::Appearance::make(248); +constexpr nw::Appearance appearance_type_dwarf_npc_male = nw::Appearance::make(249); +constexpr nw::Appearance appearance_type_elemental_air = nw::Appearance::make(52); +constexpr nw::Appearance appearance_type_elemental_air_elder = nw::Appearance::make(53); +constexpr nw::Appearance appearance_type_elemental_earth = nw::Appearance::make(56); +constexpr nw::Appearance appearance_type_elemental_earth_elder = nw::Appearance::make(57); +constexpr nw::Appearance appearance_type_elemental_fire = nw::Appearance::make(60); +constexpr nw::Appearance appearance_type_elemental_fire_elder = nw::Appearance::make(61); +constexpr nw::Appearance appearance_type_elemental_water = nw::Appearance::make(69); +constexpr nw::Appearance appearance_type_elemental_water_elder = nw::Appearance::make(68); +constexpr nw::Appearance appearance_type_elf = nw::Appearance::make(1); +constexpr nw::Appearance appearance_type_elf_npc_female = nw::Appearance::make(245); +constexpr nw::Appearance appearance_type_elf_npc_male_01 = nw::Appearance::make(246); +constexpr nw::Appearance appearance_type_elf_npc_male_02 = nw::Appearance::make(247); +constexpr nw::Appearance appearance_type_ettercap = nw::Appearance::make(166); +constexpr nw::Appearance appearance_type_ettin = nw::Appearance::make(72); +constexpr nw::Appearance appearance_type_faerie_dragon = nw::Appearance::make(374); +constexpr nw::Appearance appearance_type_fairy = nw::Appearance::make(55); +constexpr nw::Appearance appearance_type_falcon = nw::Appearance::make(144); +constexpr nw::Appearance appearance_type_female_01 = nw::Appearance::make(222); +constexpr nw::Appearance appearance_type_female_02 = nw::Appearance::make(223); +constexpr nw::Appearance appearance_type_female_03 = nw::Appearance::make(224); +constexpr nw::Appearance appearance_type_female_04 = nw::Appearance::make(225); +constexpr nw::Appearance appearance_type_formian_myrmarch = nw::Appearance::make(362); +constexpr nw::Appearance appearance_type_formian_queen = nw::Appearance::make(363); +constexpr nw::Appearance appearance_type_formian_warrior = nw::Appearance::make(361); +constexpr nw::Appearance appearance_type_formian_worker = nw::Appearance::make(360); +constexpr nw::Appearance appearance_type_gargoyle = nw::Appearance::make(73); +constexpr nw::Appearance appearance_type_ghast = nw::Appearance::make(74); +constexpr nw::Appearance appearance_type_ghoul = nw::Appearance::make(76); +constexpr nw::Appearance appearance_type_ghoul_lord = nw::Appearance::make(77); +constexpr nw::Appearance appearance_type_giant_fire = nw::Appearance::make(80); +constexpr nw::Appearance appearance_type_giant_fire_female = nw::Appearance::make(351); +constexpr nw::Appearance appearance_type_giant_frost = nw::Appearance::make(81); +constexpr nw::Appearance appearance_type_giant_frost_female = nw::Appearance::make(350); +constexpr nw::Appearance appearance_type_giant_hill = nw::Appearance::make(78); +constexpr nw::Appearance appearance_type_giant_mountain = nw::Appearance::make(79); +constexpr nw::Appearance appearance_type_gnoll_warrior = nw::Appearance::make(388); +constexpr nw::Appearance appearance_type_gnoll_wiz = nw::Appearance::make(389); +constexpr nw::Appearance appearance_type_gnome = nw::Appearance::make(2); +constexpr nw::Appearance appearance_type_gnome_npc_female = nw::Appearance::make(243); +constexpr nw::Appearance appearance_type_gnome_npc_male = nw::Appearance::make(244); +constexpr nw::Appearance appearance_type_goblin_a = nw::Appearance::make(86); +constexpr nw::Appearance appearance_type_goblin_b = nw::Appearance::make(87); +constexpr nw::Appearance appearance_type_goblin_chief_a = nw::Appearance::make(82); +constexpr nw::Appearance appearance_type_goblin_chief_b = nw::Appearance::make(83); +constexpr nw::Appearance appearance_type_goblin_shaman_a = nw::Appearance::make(84); +constexpr nw::Appearance appearance_type_goblin_shaman_b = nw::Appearance::make(85); +constexpr nw::Appearance appearance_type_golem_bone = nw::Appearance::make(24); +constexpr nw::Appearance appearance_type_golem_clay = nw::Appearance::make(91); +constexpr nw::Appearance appearance_type_golem_flesh = nw::Appearance::make(88); +constexpr nw::Appearance appearance_type_golem_iron = nw::Appearance::make(89); +constexpr nw::Appearance appearance_type_golem_stone = nw::Appearance::make(92); +constexpr nw::Appearance appearance_type_gorgon = nw::Appearance::make(367); +constexpr nw::Appearance appearance_type_gray_ooze = nw::Appearance::make(393); +constexpr nw::Appearance appearance_type_grey_render = nw::Appearance::make(205); +constexpr nw::Appearance appearance_type_gynosphinx = nw::Appearance::make(365); +constexpr nw::Appearance appearance_type_halfling = nw::Appearance::make(3); +constexpr nw::Appearance appearance_type_halfling_npc_female = nw::Appearance::make(250); +constexpr nw::Appearance appearance_type_halfling_npc_male = nw::Appearance::make(251); +constexpr nw::Appearance appearance_type_half_elf = nw::Appearance::make(4); +constexpr nw::Appearance appearance_type_half_orc = nw::Appearance::make(5); +constexpr nw::Appearance appearance_type_half_orc_npc_female = nw::Appearance::make(252); +constexpr nw::Appearance appearance_type_half_orc_npc_male_01 = nw::Appearance::make(253); +constexpr nw::Appearance appearance_type_half_orc_npc_male_02 = nw::Appearance::make(254); +constexpr nw::Appearance appearance_type_helmed_horror = nw::Appearance::make(100); +constexpr nw::Appearance appearance_type_heurodis_lich = nw::Appearance::make(370); +constexpr nw::Appearance appearance_type_hobgoblin_warrior = nw::Appearance::make(390); +constexpr nw::Appearance appearance_type_hobgoblin_wizard = nw::Appearance::make(391); +constexpr nw::Appearance appearance_type_hook_horror = nw::Appearance::make(102); +constexpr nw::Appearance appearance_type_house_guard = nw::Appearance::make(219); +constexpr nw::Appearance appearance_type_human = nw::Appearance::make(6); +constexpr nw::Appearance appearance_type_human_npc_female_01 = nw::Appearance::make(255); +constexpr nw::Appearance appearance_type_human_npc_female_02 = nw::Appearance::make(256); +constexpr nw::Appearance appearance_type_human_npc_female_03 = nw::Appearance::make(257); +constexpr nw::Appearance appearance_type_human_npc_female_04 = nw::Appearance::make(258); +constexpr nw::Appearance appearance_type_human_npc_female_05 = nw::Appearance::make(259); +constexpr nw::Appearance appearance_type_human_npc_female_06 = nw::Appearance::make(260); +constexpr nw::Appearance appearance_type_human_npc_female_07 = nw::Appearance::make(261); +constexpr nw::Appearance appearance_type_human_npc_female_08 = nw::Appearance::make(262); +constexpr nw::Appearance appearance_type_human_npc_female_09 = nw::Appearance::make(263); +constexpr nw::Appearance appearance_type_human_npc_female_10 = nw::Appearance::make(264); +constexpr nw::Appearance appearance_type_human_npc_female_11 = nw::Appearance::make(265); +constexpr nw::Appearance appearance_type_human_npc_female_12 = nw::Appearance::make(266); +constexpr nw::Appearance appearance_type_human_npc_male_01 = nw::Appearance::make(267); +constexpr nw::Appearance appearance_type_human_npc_male_02 = nw::Appearance::make(268); +constexpr nw::Appearance appearance_type_human_npc_male_03 = nw::Appearance::make(269); +constexpr nw::Appearance appearance_type_human_npc_male_04 = nw::Appearance::make(270); +constexpr nw::Appearance appearance_type_human_npc_male_05 = nw::Appearance::make(271); +constexpr nw::Appearance appearance_type_human_npc_male_06 = nw::Appearance::make(272); +constexpr nw::Appearance appearance_type_human_npc_male_07 = nw::Appearance::make(273); +constexpr nw::Appearance appearance_type_human_npc_male_08 = nw::Appearance::make(274); +constexpr nw::Appearance appearance_type_human_npc_male_09 = nw::Appearance::make(275); +constexpr nw::Appearance appearance_type_human_npc_male_10 = nw::Appearance::make(276); +constexpr nw::Appearance appearance_type_human_npc_male_11 = nw::Appearance::make(277); +constexpr nw::Appearance appearance_type_human_npc_male_12 = nw::Appearance::make(278); +constexpr nw::Appearance appearance_type_human_npc_male_13 = nw::Appearance::make(279); +constexpr nw::Appearance appearance_type_human_npc_male_14 = nw::Appearance::make(280); +constexpr nw::Appearance appearance_type_human_npc_male_15 = nw::Appearance::make(281); +constexpr nw::Appearance appearance_type_human_npc_male_16 = nw::Appearance::make(282); +constexpr nw::Appearance appearance_type_human_npc_male_17 = nw::Appearance::make(283); +constexpr nw::Appearance appearance_type_human_npc_male_18 = nw::Appearance::make(284); +constexpr nw::Appearance appearance_type_imp = nw::Appearance::make(105); +constexpr nw::Appearance appearance_type_inn_keeper = nw::Appearance::make(233); +constexpr nw::Appearance appearance_type_intellect_devourer = nw::Appearance::make(117); +constexpr nw::Appearance appearance_type_invisible_human_male = nw::Appearance::make(298); +constexpr nw::Appearance appearance_type_invisible_stalker = nw::Appearance::make(64); +constexpr nw::Appearance appearance_type_kid_female = nw::Appearance::make(242); +constexpr nw::Appearance appearance_type_kid_male = nw::Appearance::make(241); +constexpr nw::Appearance appearance_type_kobold_a = nw::Appearance::make(302); +constexpr nw::Appearance appearance_type_kobold_b = nw::Appearance::make(305); +constexpr nw::Appearance appearance_type_kobold_chief_a = nw::Appearance::make(300); +constexpr nw::Appearance appearance_type_kobold_chief_b = nw::Appearance::make(303); +constexpr nw::Appearance appearance_type_kobold_shaman_a = nw::Appearance::make(301); +constexpr nw::Appearance appearance_type_kobold_shaman_b = nw::Appearance::make(304); +constexpr nw::Appearance appearance_type_lantern_archon = nw::Appearance::make(103); +constexpr nw::Appearance appearance_type_lich = nw::Appearance::make(39); +constexpr nw::Appearance appearance_type_lizardfolk_a = nw::Appearance::make(134); +constexpr nw::Appearance appearance_type_lizardfolk_b = nw::Appearance::make(135); +constexpr nw::Appearance appearance_type_lizardfolk_shaman_a = nw::Appearance::make(132); +constexpr nw::Appearance appearance_type_lizardfolk_shaman_b = nw::Appearance::make(133); +constexpr nw::Appearance appearance_type_lizardfolk_warrior_a = nw::Appearance::make(130); +constexpr nw::Appearance appearance_type_lizardfolk_warrior_b = nw::Appearance::make(131); +constexpr nw::Appearance appearance_type_luskan_guard = nw::Appearance::make(211); +constexpr nw::Appearance appearance_type_male_01 = nw::Appearance::make(226); +constexpr nw::Appearance appearance_type_male_02 = nw::Appearance::make(227); +constexpr nw::Appearance appearance_type_male_03 = nw::Appearance::make(228); +constexpr nw::Appearance appearance_type_male_04 = nw::Appearance::make(229); +constexpr nw::Appearance appearance_type_male_05 = nw::Appearance::make(230); +constexpr nw::Appearance appearance_type_manticore = nw::Appearance::make(366); +constexpr nw::Appearance appearance_type_medusa = nw::Appearance::make(352); +constexpr nw::Appearance appearance_type_mephit_air = nw::Appearance::make(106); +constexpr nw::Appearance appearance_type_mephit_dust = nw::Appearance::make(107); +constexpr nw::Appearance appearance_type_mephit_earth = nw::Appearance::make(108); +constexpr nw::Appearance appearance_type_mephit_fire = nw::Appearance::make(109); +constexpr nw::Appearance appearance_type_mephit_ice = nw::Appearance::make(110); +constexpr nw::Appearance appearance_type_mephit_magma = nw::Appearance::make(114); +constexpr nw::Appearance appearance_type_mephit_ooze = nw::Appearance::make(112); +constexpr nw::Appearance appearance_type_mephit_salt = nw::Appearance::make(111); +constexpr nw::Appearance appearance_type_mephit_steam = nw::Appearance::make(113); +constexpr nw::Appearance appearance_type_mephit_water = nw::Appearance::make(115); +constexpr nw::Appearance appearance_type_minogon = nw::Appearance::make(119); +constexpr nw::Appearance appearance_type_minotaur = nw::Appearance::make(120); +constexpr nw::Appearance appearance_type_minotaur_chieftain = nw::Appearance::make(121); +constexpr nw::Appearance appearance_type_minotaur_shaman = nw::Appearance::make(122); +constexpr nw::Appearance appearance_type_mohrg = nw::Appearance::make(123); +constexpr nw::Appearance appearance_type_mummy_common = nw::Appearance::make(58); +constexpr nw::Appearance appearance_type_mummy_fighter_2 = nw::Appearance::make(59); +constexpr nw::Appearance appearance_type_mummy_greater = nw::Appearance::make(124); +constexpr nw::Appearance appearance_type_mummy_warrior = nw::Appearance::make(125); +constexpr nw::Appearance appearance_type_nwn_aarin = nw::Appearance::make(188); +constexpr nw::Appearance appearance_type_nwn_aribeth_evil = nw::Appearance::make(189); +constexpr nw::Appearance appearance_type_nwn_haedraline = nw::Appearance::make(191); +constexpr nw::Appearance appearance_type_nwn_maugrim = nw::Appearance::make(193); +constexpr nw::Appearance appearance_type_nwn_morag = nw::Appearance::make(192); +constexpr nw::Appearance appearance_type_nwn_nasher = nw::Appearance::make(296); +constexpr nw::Appearance appearance_type_nwn_sedos = nw::Appearance::make(297); +constexpr nw::Appearance appearance_type_nw_militia_member = nw::Appearance::make(210); +constexpr nw::Appearance appearance_type_nymph = nw::Appearance::make(126); +constexpr nw::Appearance appearance_type_ochre_jelly_large = nw::Appearance::make(394); +constexpr nw::Appearance appearance_type_ochre_jelly_medium = nw::Appearance::make(396); +constexpr nw::Appearance appearance_type_ochre_jelly_small = nw::Appearance::make(398); +constexpr nw::Appearance appearance_type_ogre = nw::Appearance::make(127); +constexpr nw::Appearance appearance_type_ogreb = nw::Appearance::make(207); +constexpr nw::Appearance appearance_type_ogre_chieftain = nw::Appearance::make(128); +constexpr nw::Appearance appearance_type_ogre_chieftainb = nw::Appearance::make(208); +constexpr nw::Appearance appearance_type_ogre_mage = nw::Appearance::make(129); +constexpr nw::Appearance appearance_type_ogre_mageb = nw::Appearance::make(209); +constexpr nw::Appearance appearance_type_old_man = nw::Appearance::make(239); +constexpr nw::Appearance appearance_type_old_woman = nw::Appearance::make(240); +constexpr nw::Appearance appearance_type_orc_a = nw::Appearance::make(140); +constexpr nw::Appearance appearance_type_orc_b = nw::Appearance::make(141); +constexpr nw::Appearance appearance_type_orc_chieftain_a = nw::Appearance::make(136); +constexpr nw::Appearance appearance_type_orc_chieftain_b = nw::Appearance::make(137); +constexpr nw::Appearance appearance_type_orc_shaman_a = nw::Appearance::make(138); +constexpr nw::Appearance appearance_type_orc_shaman_b = nw::Appearance::make(139); +constexpr nw::Appearance appearance_type_ox = nw::Appearance::make(142); +constexpr nw::Appearance appearance_type_parrot = nw::Appearance::make(7); +constexpr nw::Appearance appearance_type_penguin = nw::Appearance::make(206); +constexpr nw::Appearance appearance_type_plague_victim = nw::Appearance::make(231); +constexpr nw::Appearance appearance_type_prostitute_01 = nw::Appearance::make(236); +constexpr nw::Appearance appearance_type_prostitute_02 = nw::Appearance::make(237); +constexpr nw::Appearance appearance_type_pseudodragon = nw::Appearance::make(375); +constexpr nw::Appearance appearance_type_quasit = nw::Appearance::make(104); +constexpr nw::Appearance appearance_type_rakshasa_bear_male = nw::Appearance::make(294); +constexpr nw::Appearance appearance_type_rakshasa_tiger_female = nw::Appearance::make(290); +constexpr nw::Appearance appearance_type_rakshasa_tiger_male = nw::Appearance::make(293); +constexpr nw::Appearance appearance_type_rakshasa_wolf_male = nw::Appearance::make(295); +constexpr nw::Appearance appearance_type_rat = nw::Appearance::make(386); +constexpr nw::Appearance appearance_type_rat_dire = nw::Appearance::make(387); +constexpr nw::Appearance appearance_type_raven = nw::Appearance::make(145); +constexpr nw::Appearance appearance_type_sahuagin = nw::Appearance::make(65); +constexpr nw::Appearance appearance_type_sahuagin_leader = nw::Appearance::make(66); +constexpr nw::Appearance appearance_type_sahuagin_cleric = nw::Appearance::make(67); +constexpr nw::Appearance appearance_type_seagull_flying = nw::Appearance::make(291); +constexpr nw::Appearance appearance_type_seagull_walking = nw::Appearance::make(292); +constexpr nw::Appearance appearance_type_shadow = nw::Appearance::make(146); +constexpr nw::Appearance appearance_type_shadow_fiend = nw::Appearance::make(147); +constexpr nw::Appearance appearance_type_shark_mako = nw::Appearance::make(447); +constexpr nw::Appearance appearance_type_shark_hammerhead = nw::Appearance::make(448); +constexpr nw::Appearance appearance_type_shark_goblin = nw::Appearance::make(449); +constexpr nw::Appearance appearance_type_shield_guardian = nw::Appearance::make(90); +constexpr nw::Appearance appearance_type_shop_keeper = nw::Appearance::make(232); +constexpr nw::Appearance appearance_type_skeletal_devourer = nw::Appearance::make(36); +constexpr nw::Appearance appearance_type_skeleton_chieftain = nw::Appearance::make(182); +constexpr nw::Appearance appearance_type_skeleton_common = nw::Appearance::make(63); +constexpr nw::Appearance appearance_type_skeleton_mage = nw::Appearance::make(148); +constexpr nw::Appearance appearance_type_skeleton_priest = nw::Appearance::make(62); +constexpr nw::Appearance appearance_type_skeleton_warrior = nw::Appearance::make(150); +constexpr nw::Appearance appearance_type_skeleton_warrior_1 = nw::Appearance::make(70); +constexpr nw::Appearance appearance_type_skeleton_warrior_2 = nw::Appearance::make(71); +constexpr nw::Appearance appearance_type_slaad_blue = nw::Appearance::make(151); +constexpr nw::Appearance appearance_type_slaad_death = nw::Appearance::make(152); +constexpr nw::Appearance appearance_type_slaad_gray = nw::Appearance::make(153); +constexpr nw::Appearance appearance_type_slaad_green = nw::Appearance::make(154); +constexpr nw::Appearance appearance_type_slaad_red = nw::Appearance::make(155); +constexpr nw::Appearance appearance_type_spectre = nw::Appearance::make(156); +constexpr nw::Appearance appearance_type_sphinx = nw::Appearance::make(364); +constexpr nw::Appearance appearance_type_spider_dire = nw::Appearance::make(158); +constexpr nw::Appearance appearance_type_spider_giant = nw::Appearance::make(159); +constexpr nw::Appearance appearance_type_spider_phase = nw::Appearance::make(160); +constexpr nw::Appearance appearance_type_spider_sword = nw::Appearance::make(161); +constexpr nw::Appearance appearance_type_spider_wraith = nw::Appearance::make(162); +constexpr nw::Appearance appearance_type_stinger = nw::Appearance::make(356); +constexpr nw::Appearance appearance_type_stinger_chieftain = nw::Appearance::make(358); +constexpr nw::Appearance appearance_type_stinger_mage = nw::Appearance::make(359); +constexpr nw::Appearance appearance_type_stinger_warrior = nw::Appearance::make(357); +constexpr nw::Appearance appearance_type_succubus = nw::Appearance::make(163); +constexpr nw::Appearance appearance_type_troglodyte = nw::Appearance::make(451); +constexpr nw::Appearance appearance_type_troglodyte_warrior = nw::Appearance::make(452); +constexpr nw::Appearance appearance_type_troglodyte_cleric = nw::Appearance::make(453); +constexpr nw::Appearance appearance_type_troll = nw::Appearance::make(167); +constexpr nw::Appearance appearance_type_troll_chieftain = nw::Appearance::make(164); +constexpr nw::Appearance appearance_type_troll_shaman = nw::Appearance::make(165); +constexpr nw::Appearance appearance_type_umberhulk = nw::Appearance::make(168); +constexpr nw::Appearance appearance_type_uthgard_elk_tribe = nw::Appearance::make(213); +constexpr nw::Appearance appearance_type_uthgard_tiger_tribe = nw::Appearance::make(214); +constexpr nw::Appearance appearance_type_vampire_female = nw::Appearance::make(288); +constexpr nw::Appearance appearance_type_vampire_male = nw::Appearance::make(289); +constexpr nw::Appearance appearance_type_vrock = nw::Appearance::make(101); +constexpr nw::Appearance appearance_type_waitress = nw::Appearance::make(235); +constexpr nw::Appearance appearance_type_war_devourer = nw::Appearance::make(54); +constexpr nw::Appearance appearance_type_werecat = nw::Appearance::make(99); +constexpr nw::Appearance appearance_type_wererat = nw::Appearance::make(170); +constexpr nw::Appearance appearance_type_werewolf = nw::Appearance::make(171); +constexpr nw::Appearance appearance_type_wight = nw::Appearance::make(172); +constexpr nw::Appearance appearance_type_will_o_wisp = nw::Appearance::make(116); +constexpr nw::Appearance appearance_type_wraith = nw::Appearance::make(187); +constexpr nw::Appearance appearance_type_wyrmling_black = nw::Appearance::make(378); +constexpr nw::Appearance appearance_type_wyrmling_blue = nw::Appearance::make(377); +constexpr nw::Appearance appearance_type_wyrmling_brass = nw::Appearance::make(381); +constexpr nw::Appearance appearance_type_wyrmling_bronze = nw::Appearance::make(383); +constexpr nw::Appearance appearance_type_wyrmling_copper = nw::Appearance::make(382); +constexpr nw::Appearance appearance_type_wyrmling_gold = nw::Appearance::make(385); +constexpr nw::Appearance appearance_type_wyrmling_green = nw::Appearance::make(379); +constexpr nw::Appearance appearance_type_wyrmling_red = nw::Appearance::make(376); +constexpr nw::Appearance appearance_type_wyrmling_silver = nw::Appearance::make(384); +constexpr nw::Appearance appearance_type_wyrmling_white = nw::Appearance::make(380); +constexpr nw::Appearance appearance_type_yuan_ti = nw::Appearance::make(285); +constexpr nw::Appearance appearance_type_yuan_ti_chieften = nw::Appearance::make(286); +constexpr nw::Appearance appearance_type_yuan_ti_wizard = nw::Appearance::make(287); +constexpr nw::Appearance appearance_type_zombie = nw::Appearance::make(198); +constexpr nw::Appearance appearance_type_zombie_rotting = nw::Appearance::make(195); +constexpr nw::Appearance appearance_type_zombie_tyrant_fog = nw::Appearance::make(199); +constexpr nw::Appearance appearance_type_zombie_warrior_1 = nw::Appearance::make(196); +constexpr nw::Appearance appearance_type_zombie_warrior_2 = nw::Appearance::make(197); +constexpr nw::Appearance appearance_type_beholder = nw::Appearance::make(401); +constexpr nw::Appearance appearance_type_beholder_mage = nw::Appearance::make(402); +constexpr nw::Appearance appearance_type_beholder_eyeball = nw::Appearance::make(403); +constexpr nw::Appearance appearance_type_mephisto_big = nw::Appearance::make(404); +constexpr nw::Appearance appearance_type_dracolich = nw::Appearance::make(405); +constexpr nw::Appearance appearance_type_drider = nw::Appearance::make(406); +constexpr nw::Appearance appearance_type_drider_chief = nw::Appearance::make(407); +constexpr nw::Appearance appearance_type_drow_slave = nw::Appearance::make(408); +constexpr nw::Appearance appearance_type_drow_wizard = nw::Appearance::make(409); +constexpr nw::Appearance appearance_type_drow_matron = nw::Appearance::make(410); +constexpr nw::Appearance appearance_type_duergar_slave = nw::Appearance::make(411); +constexpr nw::Appearance appearance_type_duergar_chief = nw::Appearance::make(412); +constexpr nw::Appearance appearance_type_mindflayer = nw::Appearance::make(413); +constexpr nw::Appearance appearance_type_mindflayer_2 = nw::Appearance::make(414); +constexpr nw::Appearance appearance_type_mindflayer_alhoon = nw::Appearance::make(415); +constexpr nw::Appearance appearance_type_deep_rothe = nw::Appearance::make(416); +constexpr nw::Appearance appearance_type_dragon_shadow = nw::Appearance::make(418); +constexpr nw::Appearance appearance_type_harpy = nw::Appearance::make(419); +constexpr nw::Appearance appearance_type_golem_mithral = nw::Appearance::make(420); +constexpr nw::Appearance appearance_type_golem_adamantium = nw::Appearance::make(421); +constexpr nw::Appearance appearance_type_spider_demon = nw::Appearance::make(422); +constexpr nw::Appearance appearance_type_svirf_male = nw::Appearance::make(423); +constexpr nw::Appearance appearance_type_svirf_female = nw::Appearance::make(424); +constexpr nw::Appearance appearance_type_dragon_pris = nw::Appearance::make(425); +constexpr nw::Appearance appearance_type_slaad_black = nw::Appearance::make(426); +constexpr nw::Appearance appearance_type_slaad_white = nw::Appearance::make(427); +constexpr nw::Appearance appearance_type_azer_male = nw::Appearance::make(428); +constexpr nw::Appearance appearance_type_azer_female = nw::Appearance::make(429); +constexpr nw::Appearance appearance_type_demi_lich = nw::Appearance::make(430); +constexpr nw::Appearance appearance_type_object_chair = nw::Appearance::make(431); +constexpr nw::Appearance appearance_type_object_table = nw::Appearance::make(432); +constexpr nw::Appearance appearance_type_object_candle = nw::Appearance::make(433); +constexpr nw::Appearance appearance_type_object_chest = nw::Appearance::make(434); +constexpr nw::Appearance appearance_type_object_white = nw::Appearance::make(435); +constexpr nw::Appearance appearance_type_object_blue = nw::Appearance::make(436); +constexpr nw::Appearance appearance_type_object_cyan = nw::Appearance::make(437); +constexpr nw::Appearance appearance_type_object_green = nw::Appearance::make(438); +constexpr nw::Appearance appearance_type_object_yellow = nw::Appearance::make(439); +constexpr nw::Appearance appearance_type_object_orange = nw::Appearance::make(440); +constexpr nw::Appearance appearance_type_object_red = nw::Appearance::make(441); +constexpr nw::Appearance appearance_type_object_purple = nw::Appearance::make(442); +constexpr nw::Appearance appearance_type_object_flame_small = nw::Appearance::make(443); +constexpr nw::Appearance appearance_type_object_flame_medium = nw::Appearance::make(444); +constexpr nw::Appearance appearance_type_object_flame_large = nw::Appearance::make(445); +constexpr nw::Appearance appearance_type_drider_female = nw::Appearance::make(446); +constexpr nw::Appearance appearance_type_sea_hag = nw::Appearance::make(454); +constexpr nw::Appearance appearance_type_golem_demonflesh = nw::Appearance::make(468); +constexpr nw::Appearance appearance_type_animated_chest = nw::Appearance::make(469); +constexpr nw::Appearance appearance_type_gelatinous_cube = nw::Appearance::make(470); +constexpr nw::Appearance appearance_type_mephisto_norm = nw::Appearance::make(471); +constexpr nw::Appearance appearance_type_beholder_mother = nw::Appearance::make(472); +constexpr nw::Appearance appearance_type_object_boat = nw::Appearance::make(473); +constexpr nw::Appearance appearance_type_dwarf_golem = nw::Appearance::make(474); +constexpr nw::Appearance appearance_type_dwarf_halforc = nw::Appearance::make(475); +constexpr nw::Appearance appearance_type_drow_warrior_1 = nw::Appearance::make(476); +constexpr nw::Appearance appearance_type_drow_warrior_2 = nw::Appearance::make(477); +constexpr nw::Appearance appearance_type_drow_female_1 = nw::Appearance::make(478); +constexpr nw::Appearance appearance_type_drow_female_2 = nw::Appearance::make(479); +constexpr nw::Appearance appearance_type_drow_warrior_3 = nw::Appearance::make(480); + constexpr nw::ArmorClass ac_dodge = nw::ArmorClass::make(0); constexpr nw::ArmorClass ac_natural = nw::ArmorClass::make(1); constexpr nw::ArmorClass ac_armor = nw::ArmorClass::make(2); diff --git a/lib/nw/rules/attributes.cpp b/lib/nw/rules/attributes.cpp index bccc42d46..63e0e793b 100644 --- a/lib/nw/rules/attributes.cpp +++ b/lib/nw/rules/attributes.cpp @@ -45,6 +45,7 @@ AppearanceInfo::AppearanceInfo(const TwoDARowView& tda) tda.get_to("LABEL", label); tda.get_to("STRING_REF", string_ref); tda.get_to("RACE", model); + tda.get_to("SIZECATEGORY", size); } // -- PhenotypeInfo ----------------------------------------------------------- diff --git a/lib/nw/rules/attributes.hpp b/lib/nw/rules/attributes.hpp index af7ebce0a..8ff3f270a 100644 --- a/lib/nw/rules/attributes.hpp +++ b/lib/nw/rules/attributes.hpp @@ -82,6 +82,7 @@ struct AppearanceInfo { String label; uint32_t string_ref = std::numeric_limits::max(); String model; + int size = 0; bool valid() const noexcept { return string_ref != 0xFFFFFFFF || !label.empty(); } }; diff --git a/tests/kernel_objects.cpp b/tests/kernel_objects.cpp index 4a8e3fb29..f22038843 100644 --- a/tests/kernel_objects.cpp +++ b/tests/kernel_objects.cpp @@ -28,7 +28,7 @@ TEST(ObjectSystem, LoadCreature) EXPECT_EQ(ent->common.resref, "nw_chicken"); EXPECT_EQ(ent->stats.get_ability_score(nwn1::ability_dexterity), 7); EXPECT_EQ(ent->scripts.on_attacked, "nw_c2_default5"); - EXPECT_EQ(ent->appearance.id, 31); + EXPECT_EQ(*ent->appearance.id, 31); EXPECT_EQ(ent->gender, 1); auto ent2 = nwk::objects().get(ent->handle()); @@ -44,7 +44,7 @@ TEST(ObjectSystem, LoadCreature) EXPECT_EQ(ent3->common.resref, "pl_agent_001"); EXPECT_EQ(ent3->stats.get_ability_score(nwn1::ability_dexterity), 13); EXPECT_EQ(ent3->scripts.on_attacked, "mon_ai_5attacked"); - EXPECT_EQ(ent3->appearance.id, 6); + EXPECT_EQ(*ent3->appearance.id, 6); EXPECT_EQ(ent3->appearance.body_parts.shin_left, 1); EXPECT_EQ(ent3->soundset, 171); EXPECT_TRUE(nwn1::get_equipped_item(ent3, nw::EquipIndex::chest)); diff --git a/tests/objects_creature.cpp b/tests/objects_creature.cpp index fa1b7b1d4..f8a499f5b 100644 --- a/tests/objects_creature.cpp +++ b/tests/objects_creature.cpp @@ -40,7 +40,7 @@ TEST(Creature, GffDeserialize) EXPECT_EQ(obj1->common.resref, "nw_chicken"); EXPECT_EQ(obj1->stats.get_ability_score(nwn1::ability_dexterity), 7); EXPECT_EQ(obj1->scripts.on_attacked, "nw_c2_default5"); - EXPECT_EQ(obj1->appearance.id, 31); + EXPECT_EQ(*obj1->appearance.id, 31); EXPECT_EQ(obj1->gender, 1); EXPECT_EQ(obj1->alignment_flags(), nw::align_true_neutral); @@ -50,7 +50,7 @@ TEST(Creature, GffDeserialize) EXPECT_EQ(obj2->common.resref, "pl_agent_001"); EXPECT_EQ(obj2->stats.get_ability_score(nwn1::ability_dexterity), 13); EXPECT_EQ(obj2->scripts.on_attacked, "mon_ai_5attacked"); - EXPECT_EQ(obj2->appearance.id, 6); + EXPECT_EQ(*obj2->appearance.id, 6); EXPECT_EQ(obj2->appearance.body_parts.shin_left, 1); EXPECT_EQ(obj2->soundset, 171); EXPECT_TRUE(nwn1::get_equipped_item(obj2, nw::EquipIndex::chest)); @@ -343,6 +343,11 @@ TEST(Creature, AttackBonus) EXPECT_EQ(nwn1::get_ability_score(obj, nwn1::ability_strength), 16); EXPECT_EQ(nwn1::get_ability_modifier(obj, nwn1::ability_strength), 3); EXPECT_EQ(obj->combat_info.size_ab_modifier, 1); + obj->update_appearance(nwn1::appearance_type_human); + EXPECT_EQ(obj->combat_info.size_ab_modifier, 0); + obj->update_appearance(nwn1::appearance_type_halfling); + EXPECT_EQ(obj->combat_info.size_ab_modifier, 1); + EXPECT_EQ(29, nwn1::base_attack_bonus(obj)); EXPECT_EQ(45, nwn1::resolve_attack_bonus(obj, nwn1::attack_type_onhand)); @@ -425,11 +430,14 @@ TEST(Creature, AttackBonus) EXPECT_TRUE(obj4->stats.has_feat(nwn1::feat_weapon_finesse)); EXPECT_EQ(obj4->combat_info.combat_mode, nw::CombatMode::invalid()); - EXPECT_TRUE(nwn1::get_equipped_item(obj4, nw::EquipIndex::righthand)); - EXPECT_EQ(nwn1::get_equipped_item(obj4, nw::EquipIndex::righthand)->baseitem, nwn1::base_item_dagger); + auto item4 = nwn1::get_equipped_item(obj4, nw::EquipIndex::righthand); + EXPECT_TRUE(item4); + EXPECT_EQ(item4->baseitem, nwn1::base_item_dagger); EXPECT_EQ(nwn1::get_ability_modifier(obj4, nwn1::ability_strength), 1); EXPECT_EQ(nwn1::get_ability_modifier(obj4, nwn1::ability_dexterity), 11); EXPECT_EQ(25, nwn1::base_attack_bonus(obj4)); + EXPECT_EQ(obj4->combat_info.size_ab_modifier, 1); + EXPECT_TRUE(nwn1::weapon_is_finessable(obj4, item4)); EXPECT_EQ(40, nwn1::resolve_attack_bonus(obj4, nwn1::attack_type_onhand)); // Dual Wield @@ -835,7 +843,7 @@ TEST(Creature, JsonSerialization) EXPECT_TRUE(ent2); EXPECT_EQ(ent2->stats.get_ability_score(nwn1::ability_dexterity), 13); EXPECT_EQ(ent2->scripts.on_attacked, "mon_ai_5attacked"); - EXPECT_EQ(ent2->appearance.id, 6); + EXPECT_EQ(*ent2->appearance.id, 6); EXPECT_EQ(ent2->appearance.body_parts.shin_left, 1); EXPECT_EQ(ent2->soundset, 171); EXPECT_TRUE(nwn1::get_equipped_item(ent2, nw::EquipIndex::chest));