Skip to content

Commit c020363

Browse files
Dmytro Lysaipingw33n
authored andcommitted
[game,inventory] Sync inventory owner fid
1 parent c7dc372 commit c020363

File tree

6 files changed

+92
-48
lines changed

6 files changed

+92
-48
lines changed

src/asset/proto.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub use db::ProtoDb;
1111

1212
use super::*;
1313
use crate::asset::EntityKind;
14-
use crate::asset::frame::FrameId;
14+
use crate::asset::frame::{FrameId, Idx};
1515
use crate::asset::message::MessageId;
1616
use crate::game::script::ScriptPid;
1717
use crate::graphics::geometry::hex::TileGrid;
@@ -189,8 +189,8 @@ pub struct Armor {
189189
pub damage_resistance: EnumMap<DamageKind, i32>,
190190
pub damage_threshold: EnumMap<DamageKind, i32>,
191191
pub perk: Option<Perk>,
192-
pub male_fid: FrameId,
193-
pub female_fid: FrameId,
192+
pub male_fidx: Idx,
193+
pub female_fidx: Idx,
194194
}
195195

196196
impl Armor {
@@ -255,7 +255,7 @@ pub struct RangeInclusive<T> {
255255
#[derive(Debug)]
256256
pub struct Weapon {
257257
pub attack_kinds: EnumMap<AttackGroup, AttackKind>,
258-
pub animation_code: WeaponKind,
258+
pub kind: WeaponKind,
259259
// item_w_damage_min_max
260260
pub damage: RangeInclusive<i32>,
261261
pub damage_kind: DamageKind,

src/asset/proto/db.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -220,25 +220,23 @@ impl ProtoDb {
220220
fn read_armor(rd: &mut impl Read) -> io::Result<Armor> {
221221
let armor_class = rd.read_i32::<BigEndian>()?;
222222
let mut damage_resistance = EnumMap::new();
223-
for d in 0..7 {
224-
let dmg = DamageKind::from_usize(d).unwrap();
223+
for &dmg in DamageKind::basic() {
225224
damage_resistance[dmg] = rd.read_i32::<BigEndian>()?;
226225
}
227226
let mut damage_threshold = EnumMap::new();
228-
for d in 0..7 {
229-
let dmg = DamageKind::from_usize(d).unwrap();
227+
for &dmg in DamageKind::basic() {
230228
damage_threshold[dmg] = rd.read_i32::<BigEndian>()?;
231229
}
232230
let perk = read_opt_enum(rd, "invalid armor perk")?;
233-
let male_fid = FrameId::read(rd)?;
234-
let female_fid = FrameId::read(rd)?;
231+
let male_fidx = FrameId::read(rd)?.idx();
232+
let female_fidx = FrameId::read(rd)?.idx();
235233
Ok(Armor {
236234
armor_class,
237235
damage_resistance,
238236
damage_threshold,
239237
perk,
240-
male_fid,
241-
female_fid,
238+
male_fidx,
239+
female_fidx,
242240
})
243241
}
244242

@@ -353,7 +351,7 @@ impl ProtoDb {
353351

354352
Ok(Weapon {
355353
attack_kinds,
356-
animation_code,
354+
kind: animation_code,
357355
damage,
358356
damage_kind,
359357
max_ranges,

src/game/inventory.rs

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::asset::*;
66
use crate::asset::frame::FrameId;
77
use crate::asset::message::{Messages, MessageId};
88
use crate::fs::FileSystem;
9-
use crate::game::object::{self, EquipmentSlot, Object, InventoryItem};
9+
use crate::game::object::{self, EquipmentSlot, Hand, Object, InventoryItem};
1010
use crate::game::rpg::Rpg;
1111
use crate::game::ui::action_menu::{self, Action};
1212
use crate::game::ui::inventory_list::{self, InventoryList, Scroll, MouseMode};
@@ -85,8 +85,8 @@ impl Inventory {
8585
}
8686

8787
fn show(&mut self, rpg: &Rpg, ui: &mut Ui) {
88-
let obj = self.world.borrow().dude_obj().unwrap();
89-
let internal = Internal::new(self.msgs.take().unwrap(), self.world.clone(), obj, ui);
88+
let owner = self.world.borrow().dude_obj().unwrap();
89+
let internal = Internal::new(self.msgs.take().unwrap(), self.world.clone(), owner, ui);
9090
internal.sync_mouse_mode_to_ui(ui);
9191
internal.sync_from_obj(rpg, ui);
9292
assert!(self.internal.replace(internal).is_none());
@@ -108,7 +108,7 @@ enum Slot {
108108
struct Internal {
109109
msgs: Messages,
110110
world: WorldRef,
111-
obj: object::Handle,
111+
owner: object::Handle,
112112
win: ui::Handle,
113113
mouse_mode: MouseMode,
114114
list: ui::Handle,
@@ -129,7 +129,7 @@ struct Internal {
129129
}
130130

131131
impl Internal {
132-
fn new(msgs: Messages, world: WorldRef, obj: object::Handle, ui: &mut Ui) -> Self {
132+
fn new(msgs: Messages, world: WorldRef, owner: object::Handle, ui: &mut Ui) -> Self {
133133
let win = ui.new_window(Rect::with_size(80, 0, 499, 377),
134134
Some(Sprite::new(FrameId::INVENTORY_WINDOW)));
135135
ui.set_modal_window(Some(win));
@@ -220,7 +220,7 @@ impl Internal {
220220
Self {
221221
msgs,
222222
world,
223-
obj,
223+
owner,
224224
win,
225225
mouse_mode: MouseMode::Drag,
226226
list,
@@ -255,8 +255,8 @@ impl Internal {
255255
right_hand.clear();
256256

257257
let world = self.world.borrow();
258-
let obj = world.objects().get(self.obj);
259-
for item in &obj.inventory.items {
258+
let owner = world.objects().get(self.owner);
259+
for item in &owner.inventory.items {
260260
let item_obj = &world.objects().get(item.object);
261261
let inv_list_item = Self::make_list_item(item, item_obj);
262262
match () {
@@ -343,10 +343,10 @@ impl Internal {
343343
// display_stats
344344
fn update_stats(&self, rpg: &Rpg, ui: &Ui) {
345345
let world = self.world.borrow();
346-
let name = world.object_name(self.obj).unwrap();
347-
let obj = &world.objects().get(self.obj);
346+
let name = world.object_name(self.owner).unwrap();
347+
let owner = &world.objects().get(self.owner);
348348

349-
let stat = |stat| rpg.stat(stat, obj, world.objects());
349+
let stat = |stat| rpg.stat(stat, owner, world.objects());
350350
let msg = |id| &self.msgs.get(id).unwrap().text;
351351

352352
let mut cols = [BString::new(), BString::new(), BString::new(), BString::new()];
@@ -395,8 +395,8 @@ impl Internal {
395395
misc.push_str(name);
396396
misc.push_str("\n---------------------\n\n\n\n\n\n\n\n");
397397

398-
for &slot in &[EquipmentSlot::LeftHand, EquipmentSlot::RightHand] {
399-
let item = obj.equipment(slot, world.objects());
398+
for &slot in &[EquipmentSlot::Hand(Hand::Left), EquipmentSlot::Hand(Hand::Right)] {
399+
let item = owner.equipment(slot, world.objects());
400400
misc.push_str("---------------------\n");
401401
if let Some(item) = item {
402402
let item = &world.objects().get(item);
@@ -479,17 +479,17 @@ impl Internal {
479479
}
480480

481481
let mut total_weight = BString::new();
482-
if obj.kind() == EntityKind::Critter {
482+
if owner.kind() == EntityKind::Critter {
483483
let cw = stat(Stat::CarryWeight);
484-
let w = obj.inventory.weight(world.objects());
484+
let w = owner.inventory.weight(world.objects());
485485
// Total Wt: 100/200
486486
total_weight.push_str(msg(MSG_TOTAL_WEIGHT));
487487
total_weight.push(b' ');
488488
total_weight.push_str(w.to_bstring());
489489
total_weight.push(b'/');
490490
total_weight.push_str(cw.to_bstring());
491491
}
492-
let overloaded = obj.is_overloaded(rpg, world.objects());
492+
let overloaded = owner.is_overloaded(rpg, world.objects());
493493
{
494494
let mut w = ui.widget_mut::<Panel>(self.total_weight);
495495
let w = w.text_mut().unwrap();
@@ -562,8 +562,8 @@ impl Internal {
562562
Some(match () {
563563
_ if widget == self.list => Slot::Inventory,
564564
_ if widget == self.wearing => Slot::Equipment(EquipmentSlot::Armor),
565-
_ if widget == self.left_hand => Slot::Equipment(EquipmentSlot::LeftHand),
566-
_ if widget == self.right_hand => Slot::Equipment(EquipmentSlot::RightHand),
565+
_ if widget == self.left_hand => Slot::Equipment(EquipmentSlot::Hand(Hand::Left)),
566+
_ if widget == self.right_hand => Slot::Equipment(EquipmentSlot::Hand(Hand::Right)),
567567
_ => return None,
568568
})
569569
}
@@ -589,7 +589,7 @@ impl Internal {
589589
let (bump, existing) = match target_slot {
590590
Slot::Inventory => (Some(obj), None),
591591
Slot::Equipment(eq_slot) => {
592-
let v = world.objects().get(self.obj)
592+
let v = world.objects().get(self.owner)
593593
.equipment(eq_slot, world.objects());
594594
(v, v)
595595
}
@@ -609,8 +609,8 @@ impl Internal {
609609

610610
match target_slot {
611611
EquipmentSlot::Armor => obj.flags.insert(Flag::Worn),
612-
EquipmentSlot::LeftHand => obj.flags.insert(Flag::LeftHand),
613-
EquipmentSlot::RightHand => obj.flags.insert(Flag::RightHand),
612+
EquipmentSlot::Hand(Hand::Left) => obj.flags.insert(Flag::LeftHand),
613+
EquipmentSlot::Hand(Hand::Right) => obj.flags.insert(Flag::RightHand),
614614
}
615615
}
616616
Slot::Inventory => {}
@@ -621,7 +621,7 @@ impl Internal {
621621

622622
// Bump item: remove from slots and move to inventory top.
623623
if let Some(bump) = bump {
624-
let mut owner = world.objects().get_mut(self.obj);
624+
let mut owner = world.objects().get_mut(self.owner);
625625
world.objects().get_mut(bump)
626626
.flags.remove(Flag::Worn | Flag::LeftHand | Flag::RightHand);
627627
let i = owner.inventory.items.iter()
@@ -633,7 +633,7 @@ impl Internal {
633633
}
634634

635635
{
636-
let owner = &mut world.objects().get_mut(self.obj);
636+
let owner = &mut world.objects().get_mut(self.owner);
637637
if src_slot == Slot::Equipment(EquipmentSlot::Armor) {
638638
let old_armor = world.objects().get(obj);
639639
rpg.apply_armor_change(owner, None, Some(old_armor), world.objects());
@@ -645,6 +645,13 @@ impl Internal {
645645
}
646646

647647
self.sync_from_obj(rpg, ui);
648+
self.sync_owner_fid(rpg)
649+
}
650+
651+
fn sync_owner_fid(&self, rpg: &Rpg) {
652+
let world = self.world.borrow();
653+
let mut owner = world.objects().get_mut(self.owner);
654+
owner.fid = owner.equipped_fid(world.objects(), rpg);
648655
}
649656
}
650657

src/game/object.rs

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::mem;
99
use std::rc::Rc;
1010

1111
use crate::asset::*;
12-
use crate::asset::frame::{FrameId, FrameDb};
12+
use crate::asset::frame::*;
1313
use crate::asset::proto::*;
1414
use crate::asset::script::ProgramId;
1515
use crate::game::rpg::Rpg;
@@ -81,8 +81,13 @@ pub struct InventoryItem {
8181
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8282
pub enum EquipmentSlot {
8383
Armor,
84-
LeftHand,
85-
RightHand,
84+
Hand(Hand),
85+
}
86+
87+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
88+
pub enum Hand {
89+
Left,
90+
Right,
8691
}
8792

8893
#[derive(Clone, Copy, Debug, Default)]
@@ -439,8 +444,8 @@ impl Object {
439444
pub fn equipment(&self, slot: EquipmentSlot, objects: &Objects) -> Option<Handle> {
440445
let flag = match slot {
441446
EquipmentSlot::Armor => Flag::Worn,
442-
EquipmentSlot::LeftHand => Flag::LeftHand,
443-
EquipmentSlot::RightHand => Flag::RightHand,
447+
EquipmentSlot::Hand(Hand::Left) => Flag::LeftHand,
448+
EquipmentSlot::Hand(Hand::Right) => Flag::RightHand,
444449
};
445450
self.find_inventory_item(objects, |o| o.flags.contains(flag))
446451
}
@@ -573,6 +578,38 @@ impl Object {
573578
}
574579
}
575580

581+
// adjust_fid
582+
pub fn equipped_fid(&self, objects: &Objects, rpg: &Rpg) -> FrameId {
583+
if self.proto().unwrap().kind() != ExactEntityKind::Critter {
584+
return self.fid;
585+
}
586+
let dude = self.sub.as_critter().unwrap().try_dude();
587+
588+
let idx = self.equipment(EquipmentSlot::Armor, objects)
589+
.map(|armor| {
590+
let armor = objects.get(armor);
591+
let armor = armor.proto().unwrap();
592+
let armor = armor.sub.as_armor().unwrap();
593+
if rpg.stat(Stat::Gender, self, objects) == 1 {
594+
armor.female_fidx
595+
} else {
596+
armor.male_fidx
597+
}
598+
})
599+
.or(dude.map(|d| d.naked_fidx))
600+
.unwrap_or(self.fid.idx());
601+
602+
let active_hand = dude.map(|d| d.active_hand).unwrap_or(Hand::Left);
603+
let weapon = self.equipment(EquipmentSlot::Hand(active_hand), objects)
604+
.and_then(|item| {
605+
objects.get(item).proto().unwrap().sub
606+
.as_weapon().map(|w| w.kind)
607+
})
608+
.unwrap_or(WeaponKind::Unarmed);
609+
610+
FrameId::new_critter(Some(self.direction), CritterAnim::Stand, weapon, idx).unwrap()
611+
}
612+
576613
fn find_inventory_item(&self, objects: &Objects, f: impl Fn(&Object) -> bool) -> Option<Handle> {
577614
self.inventory.items.iter()
578615
.map(|i| i.object)
@@ -1465,6 +1502,8 @@ pub enum SubObject {
14651502

14661503
#[derive(Debug)]
14671504
pub struct Dude {
1505+
pub naked_fidx: Idx,
1506+
pub active_hand: Hand,
14681507
}
14691508

14701509
#[derive(Debug)]
@@ -1502,11 +1541,11 @@ impl Critter {
15021541
}
15031542

15041543
pub fn try_dude(&self) -> Option<&Dude> {
1505-
self.dude.as_ref().map(|v| &**v)
1544+
self.dude.as_deref()
15061545
}
15071546

15081547
pub fn try_dude_mut(&mut self) -> Option<&mut Dude> {
1509-
self.dude.as_mut().map(|v| &mut **v)
1548+
self.dude.as_deref_mut()
15101549
}
15111550
}
15121551

src/game/rpg.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::io;
1212
use crate::asset::{DamageKind, ExactEntityKind, Perk, PCStat, Skill, Stat, Trait};
1313
use crate::asset::message::{Messages, MessageId};
1414
use crate::asset::proto::ProtoId;
15-
use crate::game::object::{DamageFlag, EquipmentSlot, Object, Objects};
15+
use crate::game::object::{DamageFlag, EquipmentSlot, Hand, Object, Objects};
1616
use crate::fs::FileSystem;
1717
use crate::util::random::*;
1818

@@ -225,8 +225,8 @@ impl Rpg {
225225
Endurance => pei(GainEndurance),
226226
Charisma => {
227227
let wearing_shades = [
228-
EquipmentSlot::LeftHand,
229-
EquipmentSlot::RightHand
228+
EquipmentSlot::Hand(Hand::Left),
229+
EquipmentSlot::Hand(Hand::Right)
230230
].iter()
231231
.flat_map(|&s| obj.equipment(s, objs).into_iter())
232232
.flat_map(|o| objs.get(o).proto_id().into_iter())
@@ -492,8 +492,6 @@ impl Rpg {
492492
self.pc_stats[pc_stat] = value;
493493
if pc_stat == PCStat::Experience {
494494
// TODO statPCAddExperienceCheckPMs_(0, 1);
495-
} else {
496-
497495
}
498496
} else {
499497
// TODO statPcResetExperience_(value)

src/game/state.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ impl GameState {
185185
poison: 0,
186186
combat: Default::default(),
187187
dude: Some(Box::new(Dude {
188+
naked_fidx: 0x3e,
189+
active_hand: Hand::Left,
188190
})),
189191
}));
190192
self.world.borrow_mut().insert_object(dude_obj);

0 commit comments

Comments
 (0)