mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2024-11-30 09:13:11 +00:00
fix TSC handling certain weapon opcodes improperly
This commit is contained in:
parent
36fd5f8879
commit
8a64cfc180
|
@ -84,24 +84,46 @@ impl Inventory {
|
|||
result
|
||||
}
|
||||
|
||||
pub fn add_weapon(&mut self, weapon_id: WeaponType, max_ammo: u16) -> &mut Weapon {
|
||||
pub fn add_weapon_data(&mut self, weapon_id: WeaponType, ammo: u16, max_ammo: u16, experience: u16, level: WeaponLevel) {
|
||||
let weapon = Weapon::new(
|
||||
weapon_id,
|
||||
level,
|
||||
experience,
|
||||
ammo,
|
||||
max_ammo,
|
||||
);
|
||||
|
||||
if !self.has_weapon(weapon_id) {
|
||||
self.weapons.push(weapon);
|
||||
} else {
|
||||
let w = self.get_weapon_by_type_mut(weapon_id);
|
||||
if let Some(w) = w {
|
||||
*w = weapon
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_weapon(&mut self, weapon_id: WeaponType, ammo: u16) {
|
||||
let w = self.get_weapon_by_type_mut(weapon_id);
|
||||
if let Some(w) = w {
|
||||
w.ammo += ammo;
|
||||
w.max_ammo += ammo;
|
||||
} else {
|
||||
self.weapons.push(Weapon::new(
|
||||
weapon_id,
|
||||
WeaponLevel::Level1,
|
||||
0,
|
||||
max_ammo,
|
||||
max_ammo,
|
||||
ammo,
|
||||
ammo,
|
||||
));
|
||||
}
|
||||
|
||||
self.weapons.iter_mut().find(|w| w.wtype == weapon_id).unwrap()
|
||||
}
|
||||
|
||||
pub fn trade_weapon(&mut self, old: Option<WeaponType>, new: WeaponType, max_ammo: u16) {
|
||||
if let Some(wtype) = old {
|
||||
if let Some(weapon) = self.get_weapon_by_type_mut(wtype) {
|
||||
*weapon = Weapon::new(new, WeaponLevel::Level1, 0, max_ammo, max_ammo);
|
||||
let ammo = if max_ammo == 0 { weapon.max_ammo } else { max_ammo };
|
||||
*weapon = Weapon::new(new, WeaponLevel::Level1, 0, ammo, ammo);
|
||||
} else {
|
||||
self.add_weapon(new, max_ammo);
|
||||
}
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
use std::io;
|
||||
|
||||
use byteorder::{BE, LE, ReadBytesExt, WriteBytesExt};
|
||||
use byteorder::{ReadBytesExt, WriteBytesExt, BE, LE};
|
||||
use num_traits::{clamp, FromPrimitive};
|
||||
|
||||
use crate::common::{Direction, FadeState};
|
||||
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameError::ResourceLoadError;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::player::ControlMode;
|
||||
use crate::scene::game_scene::GameScene;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::str;
|
||||
use crate::weapon::{WeaponLevel, WeaponType};
|
||||
use crate::framework::error::GameError::ResourceLoadError;
|
||||
|
||||
pub struct WeaponData {
|
||||
pub weapon_id: u32,
|
||||
|
@ -58,42 +57,67 @@ impl GameProfile {
|
|||
game_scene.inventory_player1.current_weapon = self.current_weapon as u16;
|
||||
game_scene.inventory_player1.current_item = self.current_item as u16;
|
||||
for weapon in self.weapon_data.iter() {
|
||||
if weapon.weapon_id == 0 { continue; }
|
||||
if weapon.weapon_id == 0 {
|
||||
continue;
|
||||
}
|
||||
let weapon_type: Option<WeaponType> = FromPrimitive::from_u8(weapon.weapon_id as u8);
|
||||
|
||||
if let Some(wtype) = weapon_type {
|
||||
let w = game_scene.inventory_player1.add_weapon(wtype, weapon.max_ammo as u16);
|
||||
w.ammo = weapon.ammo as u16;
|
||||
w.level = match weapon.level {
|
||||
2 => { WeaponLevel::Level2 }
|
||||
3 => { WeaponLevel::Level3 }
|
||||
_ => { WeaponLevel::Level1 }
|
||||
};
|
||||
w.experience = weapon.exp as u16;
|
||||
let w = game_scene.inventory_player1.add_weapon_data(
|
||||
wtype,
|
||||
weapon.ammo as u16,
|
||||
weapon.max_ammo as u16,
|
||||
weapon.exp as u16,
|
||||
match weapon.level {
|
||||
2 => WeaponLevel::Level2,
|
||||
3 => WeaponLevel::Level3,
|
||||
_ => WeaponLevel::Level1,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for item in self.items.iter().copied() {
|
||||
if item == 0 { break; }
|
||||
if item == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
game_scene.inventory_player1.add_item(item as u16);
|
||||
}
|
||||
|
||||
for slot in self.teleporter_slots.iter() {
|
||||
if slot.event_num == 0 { break; }
|
||||
if slot.event_num == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
state.teleporter_slots.push((slot.index as u16, slot.event_num as u16));
|
||||
}
|
||||
|
||||
for (idx, &flags) in self.flags.iter().enumerate() {
|
||||
if flags & 0b00000001 != 0 { state.game_flags.set(idx * 8, true); }
|
||||
if flags & 0b00000010 != 0 { state.game_flags.set(idx * 8 + 1, true); }
|
||||
if flags & 0b00000100 != 0 { state.game_flags.set(idx * 8 + 2, true); }
|
||||
if flags & 0b00001000 != 0 { state.game_flags.set(idx * 8 + 3, true); }
|
||||
if flags & 0b00010000 != 0 { state.game_flags.set(idx * 8 + 4, true); }
|
||||
if flags & 0b00100000 != 0 { state.game_flags.set(idx * 8 + 5, true); }
|
||||
if flags & 0b01000000 != 0 { state.game_flags.set(idx * 8 + 6, true); }
|
||||
if flags & 0b10000000 != 0 { state.game_flags.set(idx * 8 + 7, true); }
|
||||
if flags & 0b00000001 != 0 {
|
||||
state.game_flags.set(idx * 8, true);
|
||||
}
|
||||
if flags & 0b00000010 != 0 {
|
||||
state.game_flags.set(idx * 8 + 1, true);
|
||||
}
|
||||
if flags & 0b00000100 != 0 {
|
||||
state.game_flags.set(idx * 8 + 2, true);
|
||||
}
|
||||
if flags & 0b00001000 != 0 {
|
||||
state.game_flags.set(idx * 8 + 3, true);
|
||||
}
|
||||
if flags & 0b00010000 != 0 {
|
||||
state.game_flags.set(idx * 8 + 4, true);
|
||||
}
|
||||
if flags & 0b00100000 != 0 {
|
||||
state.game_flags.set(idx * 8 + 5, true);
|
||||
}
|
||||
if flags & 0b01000000 != 0 {
|
||||
state.game_flags.set(idx * 8 + 6, true);
|
||||
}
|
||||
if flags & 0b10000000 != 0 {
|
||||
state.game_flags.set(idx * 8 + 7, true);
|
||||
}
|
||||
}
|
||||
|
||||
game_scene.player1.equip.0 = self.equipment as u16;
|
||||
|
@ -101,7 +125,8 @@ impl GameProfile {
|
|||
game_scene.player1.x = self.pos_x;
|
||||
game_scene.player1.y = self.pos_y;
|
||||
|
||||
game_scene.player1.control_mode = if self.control_mode == 1 { ControlMode::IronHead } else { ControlMode::Normal };
|
||||
game_scene.player1.control_mode =
|
||||
if self.control_mode == 1 { ControlMode::IronHead } else { ControlMode::Normal };
|
||||
game_scene.player1.direction = self.direction;
|
||||
game_scene.player1.life = self.life;
|
||||
game_scene.player1.max_life = self.max_life;
|
||||
|
|
|
@ -626,9 +626,11 @@ impl TextScriptVM {
|
|||
TextScriptExecutionState::WaitTicks(event, ip, ticks) => {
|
||||
if ticks == 0 {
|
||||
state.textscript_vm.state = TextScriptExecutionState::Running(event, ip);
|
||||
} else {
|
||||
} else if ticks != 9999 {
|
||||
state.textscript_vm.state = TextScriptExecutionState::WaitTicks(event, ip, ticks - 1);
|
||||
break;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
TextScriptExecutionState::WaitConfirmation(event, ip, no_event, wait, selection) => {
|
||||
|
@ -891,7 +893,10 @@ impl TextScriptVM {
|
|||
|
||||
if flag_to >= flag_from {
|
||||
for flag in flag_from..=flag_to {
|
||||
state.game_flags.set(flag, false);
|
||||
if state.get_flag(flag) {
|
||||
state.game_flags.set(flag, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue