Skip to content

Commit

Permalink
[game,inventory] Sync inventory owner fid
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmytro Lysai authored and pingw33n committed Jul 2, 2020
1 parent c7dc372 commit c020363
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 48 deletions.
8 changes: 4 additions & 4 deletions src/asset/proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub use db::ProtoDb;

use super::*;
use crate::asset::EntityKind;
use crate::asset::frame::FrameId;
use crate::asset::frame::{FrameId, Idx};
use crate::asset::message::MessageId;
use crate::game::script::ScriptPid;
use crate::graphics::geometry::hex::TileGrid;
Expand Down Expand Up @@ -189,8 +189,8 @@ pub struct Armor {
pub damage_resistance: EnumMap<DamageKind, i32>,
pub damage_threshold: EnumMap<DamageKind, i32>,
pub perk: Option<Perk>,
pub male_fid: FrameId,
pub female_fid: FrameId,
pub male_fidx: Idx,
pub female_fidx: Idx,
}

impl Armor {
Expand Down Expand Up @@ -255,7 +255,7 @@ pub struct RangeInclusive<T> {
#[derive(Debug)]
pub struct Weapon {
pub attack_kinds: EnumMap<AttackGroup, AttackKind>,
pub animation_code: WeaponKind,
pub kind: WeaponKind,
// item_w_damage_min_max
pub damage: RangeInclusive<i32>,
pub damage_kind: DamageKind,
Expand Down
16 changes: 7 additions & 9 deletions src/asset/proto/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,25 +220,23 @@ impl ProtoDb {
fn read_armor(rd: &mut impl Read) -> io::Result<Armor> {
let armor_class = rd.read_i32::<BigEndian>()?;
let mut damage_resistance = EnumMap::new();
for d in 0..7 {
let dmg = DamageKind::from_usize(d).unwrap();
for &dmg in DamageKind::basic() {
damage_resistance[dmg] = rd.read_i32::<BigEndian>()?;
}
let mut damage_threshold = EnumMap::new();
for d in 0..7 {
let dmg = DamageKind::from_usize(d).unwrap();
for &dmg in DamageKind::basic() {
damage_threshold[dmg] = rd.read_i32::<BigEndian>()?;
}
let perk = read_opt_enum(rd, "invalid armor perk")?;
let male_fid = FrameId::read(rd)?;
let female_fid = FrameId::read(rd)?;
let male_fidx = FrameId::read(rd)?.idx();
let female_fidx = FrameId::read(rd)?.idx();
Ok(Armor {
armor_class,
damage_resistance,
damage_threshold,
perk,
male_fid,
female_fid,
male_fidx,
female_fidx,
})
}

Expand Down Expand Up @@ -353,7 +351,7 @@ impl ProtoDb {

Ok(Weapon {
attack_kinds,
animation_code,
kind: animation_code,
damage,
damage_kind,
max_ranges,
Expand Down
53 changes: 30 additions & 23 deletions src/game/inventory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::asset::*;
use crate::asset::frame::FrameId;
use crate::asset::message::{Messages, MessageId};
use crate::fs::FileSystem;
use crate::game::object::{self, EquipmentSlot, Object, InventoryItem};
use crate::game::object::{self, EquipmentSlot, Hand, Object, InventoryItem};
use crate::game::rpg::Rpg;
use crate::game::ui::action_menu::{self, Action};
use crate::game::ui::inventory_list::{self, InventoryList, Scroll, MouseMode};
Expand Down Expand Up @@ -85,8 +85,8 @@ impl Inventory {
}

fn show(&mut self, rpg: &Rpg, ui: &mut Ui) {
let obj = self.world.borrow().dude_obj().unwrap();
let internal = Internal::new(self.msgs.take().unwrap(), self.world.clone(), obj, ui);
let owner = self.world.borrow().dude_obj().unwrap();
let internal = Internal::new(self.msgs.take().unwrap(), self.world.clone(), owner, ui);
internal.sync_mouse_mode_to_ui(ui);
internal.sync_from_obj(rpg, ui);
assert!(self.internal.replace(internal).is_none());
Expand All @@ -108,7 +108,7 @@ enum Slot {
struct Internal {
msgs: Messages,
world: WorldRef,
obj: object::Handle,
owner: object::Handle,
win: ui::Handle,
mouse_mode: MouseMode,
list: ui::Handle,
Expand All @@ -129,7 +129,7 @@ struct Internal {
}

impl Internal {
fn new(msgs: Messages, world: WorldRef, obj: object::Handle, ui: &mut Ui) -> Self {
fn new(msgs: Messages, world: WorldRef, owner: object::Handle, ui: &mut Ui) -> Self {
let win = ui.new_window(Rect::with_size(80, 0, 499, 377),
Some(Sprite::new(FrameId::INVENTORY_WINDOW)));
ui.set_modal_window(Some(win));
Expand Down Expand Up @@ -220,7 +220,7 @@ impl Internal {
Self {
msgs,
world,
obj,
owner,
win,
mouse_mode: MouseMode::Drag,
list,
Expand Down Expand Up @@ -255,8 +255,8 @@ impl Internal {
right_hand.clear();

let world = self.world.borrow();
let obj = world.objects().get(self.obj);
for item in &obj.inventory.items {
let owner = world.objects().get(self.owner);
for item in &owner.inventory.items {
let item_obj = &world.objects().get(item.object);
let inv_list_item = Self::make_list_item(item, item_obj);
match () {
Expand Down Expand Up @@ -343,10 +343,10 @@ impl Internal {
// display_stats
fn update_stats(&self, rpg: &Rpg, ui: &Ui) {
let world = self.world.borrow();
let name = world.object_name(self.obj).unwrap();
let obj = &world.objects().get(self.obj);
let name = world.object_name(self.owner).unwrap();
let owner = &world.objects().get(self.owner);

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

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

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

let mut total_weight = BString::new();
if obj.kind() == EntityKind::Critter {
if owner.kind() == EntityKind::Critter {
let cw = stat(Stat::CarryWeight);
let w = obj.inventory.weight(world.objects());
let w = owner.inventory.weight(world.objects());
// Total Wt: 100/200
total_weight.push_str(msg(MSG_TOTAL_WEIGHT));
total_weight.push(b' ');
total_weight.push_str(w.to_bstring());
total_weight.push(b'/');
total_weight.push_str(cw.to_bstring());
}
let overloaded = obj.is_overloaded(rpg, world.objects());
let overloaded = owner.is_overloaded(rpg, world.objects());
{
let mut w = ui.widget_mut::<Panel>(self.total_weight);
let w = w.text_mut().unwrap();
Expand Down Expand Up @@ -562,8 +562,8 @@ impl Internal {
Some(match () {
_ if widget == self.list => Slot::Inventory,
_ if widget == self.wearing => Slot::Equipment(EquipmentSlot::Armor),
_ if widget == self.left_hand => Slot::Equipment(EquipmentSlot::LeftHand),
_ if widget == self.right_hand => Slot::Equipment(EquipmentSlot::RightHand),
_ if widget == self.left_hand => Slot::Equipment(EquipmentSlot::Hand(Hand::Left)),
_ if widget == self.right_hand => Slot::Equipment(EquipmentSlot::Hand(Hand::Right)),
_ => return None,
})
}
Expand All @@ -589,7 +589,7 @@ impl Internal {
let (bump, existing) = match target_slot {
Slot::Inventory => (Some(obj), None),
Slot::Equipment(eq_slot) => {
let v = world.objects().get(self.obj)
let v = world.objects().get(self.owner)
.equipment(eq_slot, world.objects());
(v, v)
}
Expand All @@ -609,8 +609,8 @@ impl Internal {

match target_slot {
EquipmentSlot::Armor => obj.flags.insert(Flag::Worn),
EquipmentSlot::LeftHand => obj.flags.insert(Flag::LeftHand),
EquipmentSlot::RightHand => obj.flags.insert(Flag::RightHand),
EquipmentSlot::Hand(Hand::Left) => obj.flags.insert(Flag::LeftHand),
EquipmentSlot::Hand(Hand::Right) => obj.flags.insert(Flag::RightHand),
}
}
Slot::Inventory => {}
Expand All @@ -621,7 +621,7 @@ impl Internal {

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

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

self.sync_from_obj(rpg, ui);
self.sync_owner_fid(rpg)
}

fn sync_owner_fid(&self, rpg: &Rpg) {
let world = self.world.borrow();
let mut owner = world.objects().get_mut(self.owner);
owner.fid = owner.equipped_fid(world.objects(), rpg);
}
}

Expand Down
53 changes: 46 additions & 7 deletions src/game/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::mem;
use std::rc::Rc;

use crate::asset::*;
use crate::asset::frame::{FrameId, FrameDb};
use crate::asset::frame::*;
use crate::asset::proto::*;
use crate::asset::script::ProgramId;
use crate::game::rpg::Rpg;
Expand Down Expand Up @@ -81,8 +81,13 @@ pub struct InventoryItem {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum EquipmentSlot {
Armor,
LeftHand,
RightHand,
Hand(Hand),
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Hand {
Left,
Right,
}

#[derive(Clone, Copy, Debug, Default)]
Expand Down Expand Up @@ -439,8 +444,8 @@ impl Object {
pub fn equipment(&self, slot: EquipmentSlot, objects: &Objects) -> Option<Handle> {
let flag = match slot {
EquipmentSlot::Armor => Flag::Worn,
EquipmentSlot::LeftHand => Flag::LeftHand,
EquipmentSlot::RightHand => Flag::RightHand,
EquipmentSlot::Hand(Hand::Left) => Flag::LeftHand,
EquipmentSlot::Hand(Hand::Right) => Flag::RightHand,
};
self.find_inventory_item(objects, |o| o.flags.contains(flag))
}
Expand Down Expand Up @@ -573,6 +578,38 @@ impl Object {
}
}

// adjust_fid
pub fn equipped_fid(&self, objects: &Objects, rpg: &Rpg) -> FrameId {
if self.proto().unwrap().kind() != ExactEntityKind::Critter {
return self.fid;
}
let dude = self.sub.as_critter().unwrap().try_dude();

let idx = self.equipment(EquipmentSlot::Armor, objects)
.map(|armor| {
let armor = objects.get(armor);
let armor = armor.proto().unwrap();
let armor = armor.sub.as_armor().unwrap();
if rpg.stat(Stat::Gender, self, objects) == 1 {
armor.female_fidx
} else {
armor.male_fidx
}
})
.or(dude.map(|d| d.naked_fidx))
.unwrap_or(self.fid.idx());

let active_hand = dude.map(|d| d.active_hand).unwrap_or(Hand::Left);
let weapon = self.equipment(EquipmentSlot::Hand(active_hand), objects)
.and_then(|item| {
objects.get(item).proto().unwrap().sub
.as_weapon().map(|w| w.kind)
})
.unwrap_or(WeaponKind::Unarmed);

FrameId::new_critter(Some(self.direction), CritterAnim::Stand, weapon, idx).unwrap()
}

fn find_inventory_item(&self, objects: &Objects, f: impl Fn(&Object) -> bool) -> Option<Handle> {
self.inventory.items.iter()
.map(|i| i.object)
Expand Down Expand Up @@ -1465,6 +1502,8 @@ pub enum SubObject {

#[derive(Debug)]
pub struct Dude {
pub naked_fidx: Idx,
pub active_hand: Hand,
}

#[derive(Debug)]
Expand Down Expand Up @@ -1502,11 +1541,11 @@ impl Critter {
}

pub fn try_dude(&self) -> Option<&Dude> {
self.dude.as_ref().map(|v| &**v)
self.dude.as_deref()
}

pub fn try_dude_mut(&mut self) -> Option<&mut Dude> {
self.dude.as_mut().map(|v| &mut **v)
self.dude.as_deref_mut()
}
}

Expand Down
8 changes: 3 additions & 5 deletions src/game/rpg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::io;
use crate::asset::{DamageKind, ExactEntityKind, Perk, PCStat, Skill, Stat, Trait};
use crate::asset::message::{Messages, MessageId};
use crate::asset::proto::ProtoId;
use crate::game::object::{DamageFlag, EquipmentSlot, Object, Objects};
use crate::game::object::{DamageFlag, EquipmentSlot, Hand, Object, Objects};
use crate::fs::FileSystem;
use crate::util::random::*;

Expand Down Expand Up @@ -225,8 +225,8 @@ impl Rpg {
Endurance => pei(GainEndurance),
Charisma => {
let wearing_shades = [
EquipmentSlot::LeftHand,
EquipmentSlot::RightHand
EquipmentSlot::Hand(Hand::Left),
EquipmentSlot::Hand(Hand::Right)
].iter()
.flat_map(|&s| obj.equipment(s, objs).into_iter())
.flat_map(|o| objs.get(o).proto_id().into_iter())
Expand Down Expand Up @@ -492,8 +492,6 @@ impl Rpg {
self.pc_stats[pc_stat] = value;
if pc_stat == PCStat::Experience {
// TODO statPCAddExperienceCheckPMs_(0, 1);
} else {

}
} else {
// TODO statPcResetExperience_(value)
Expand Down
2 changes: 2 additions & 0 deletions src/game/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ impl GameState {
poison: 0,
combat: Default::default(),
dude: Some(Box::new(Dude {
naked_fidx: 0x3e,
active_hand: Hand::Left,
})),
}));
self.world.borrow_mut().insert_object(dude_obj);
Expand Down

0 comments on commit c020363

Please sign in to comment.