mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2025-12-02 01:18:37 +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
|
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) {
|
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(
|
self.weapons.push(Weapon::new(
|
||||||
weapon_id,
|
weapon_id,
|
||||||
WeaponLevel::Level1,
|
WeaponLevel::Level1,
|
||||||
0,
|
0,
|
||||||
max_ammo,
|
ammo,
|
||||||
max_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) {
|
pub fn trade_weapon(&mut self, old: Option<WeaponType>, new: WeaponType, max_ammo: u16) {
|
||||||
if let Some(wtype) = old {
|
if let Some(wtype) = old {
|
||||||
if let Some(weapon) = self.get_weapon_by_type_mut(wtype) {
|
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 {
|
} else {
|
||||||
self.add_weapon(new, max_ammo);
|
self.add_weapon(new, max_ammo);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,17 @@
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use byteorder::{BE, LE, ReadBytesExt, WriteBytesExt};
|
use byteorder::{ReadBytesExt, WriteBytesExt, BE, LE};
|
||||||
use num_traits::{clamp, FromPrimitive};
|
use num_traits::{clamp, FromPrimitive};
|
||||||
|
|
||||||
use crate::common::{Direction, FadeState};
|
use crate::common::{Direction, FadeState};
|
||||||
|
|
||||||
use crate::framework::context::Context;
|
use crate::framework::context::Context;
|
||||||
|
use crate::framework::error::GameError::ResourceLoadError;
|
||||||
use crate::framework::error::GameResult;
|
use crate::framework::error::GameResult;
|
||||||
use crate::player::ControlMode;
|
use crate::player::ControlMode;
|
||||||
use crate::scene::game_scene::GameScene;
|
use crate::scene::game_scene::GameScene;
|
||||||
use crate::shared_game_state::SharedGameState;
|
use crate::shared_game_state::SharedGameState;
|
||||||
use crate::str;
|
use crate::str;
|
||||||
use crate::weapon::{WeaponLevel, WeaponType};
|
use crate::weapon::{WeaponLevel, WeaponType};
|
||||||
use crate::framework::error::GameError::ResourceLoadError;
|
|
||||||
|
|
||||||
pub struct WeaponData {
|
pub struct WeaponData {
|
||||||
pub weapon_id: u32,
|
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_weapon = self.current_weapon as u16;
|
||||||
game_scene.inventory_player1.current_item = self.current_item as u16;
|
game_scene.inventory_player1.current_item = self.current_item as u16;
|
||||||
for weapon in self.weapon_data.iter() {
|
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);
|
let weapon_type: Option<WeaponType> = FromPrimitive::from_u8(weapon.weapon_id as u8);
|
||||||
|
|
||||||
if let Some(wtype) = weapon_type {
|
if let Some(wtype) = weapon_type {
|
||||||
let w = game_scene.inventory_player1.add_weapon(wtype, weapon.max_ammo as u16);
|
let w = game_scene.inventory_player1.add_weapon_data(
|
||||||
w.ammo = weapon.ammo as u16;
|
wtype,
|
||||||
w.level = match weapon.level {
|
weapon.ammo as u16,
|
||||||
2 => { WeaponLevel::Level2 }
|
weapon.max_ammo as u16,
|
||||||
3 => { WeaponLevel::Level3 }
|
weapon.exp as u16,
|
||||||
_ => { WeaponLevel::Level1 }
|
match weapon.level {
|
||||||
};
|
2 => WeaponLevel::Level2,
|
||||||
w.experience = weapon.exp as u16;
|
3 => WeaponLevel::Level3,
|
||||||
|
_ => WeaponLevel::Level1,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for item in self.items.iter().copied() {
|
for item in self.items.iter().copied() {
|
||||||
if item == 0 { break; }
|
if item == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
game_scene.inventory_player1.add_item(item as u16);
|
game_scene.inventory_player1.add_item(item as u16);
|
||||||
}
|
}
|
||||||
|
|
||||||
for slot in self.teleporter_slots.iter() {
|
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));
|
state.teleporter_slots.push((slot.index as u16, slot.event_num as u16));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (idx, &flags) in self.flags.iter().enumerate() {
|
for (idx, &flags) in self.flags.iter().enumerate() {
|
||||||
if flags & 0b00000001 != 0 { state.game_flags.set(idx * 8, true); }
|
if flags & 0b00000001 != 0 {
|
||||||
if flags & 0b00000010 != 0 { state.game_flags.set(idx * 8 + 1, true); }
|
state.game_flags.set(idx * 8, 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 & 0b00000010 != 0 {
|
||||||
if flags & 0b00010000 != 0 { state.game_flags.set(idx * 8 + 4, true); }
|
state.game_flags.set(idx * 8 + 1, 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 & 0b00000100 != 0 {
|
||||||
if flags & 0b10000000 != 0 { state.game_flags.set(idx * 8 + 7, true); }
|
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;
|
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.x = self.pos_x;
|
||||||
game_scene.player1.y = self.pos_y;
|
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.direction = self.direction;
|
||||||
game_scene.player1.life = self.life;
|
game_scene.player1.life = self.life;
|
||||||
game_scene.player1.max_life = self.max_life;
|
game_scene.player1.max_life = self.max_life;
|
||||||
|
|
|
||||||
|
|
@ -626,9 +626,11 @@ impl TextScriptVM {
|
||||||
TextScriptExecutionState::WaitTicks(event, ip, ticks) => {
|
TextScriptExecutionState::WaitTicks(event, ip, ticks) => {
|
||||||
if ticks == 0 {
|
if ticks == 0 {
|
||||||
state.textscript_vm.state = TextScriptExecutionState::Running(event, ip);
|
state.textscript_vm.state = TextScriptExecutionState::Running(event, ip);
|
||||||
} else {
|
} else if ticks != 9999 {
|
||||||
state.textscript_vm.state = TextScriptExecutionState::WaitTicks(event, ip, ticks - 1);
|
state.textscript_vm.state = TextScriptExecutionState::WaitTicks(event, ip, ticks - 1);
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TextScriptExecutionState::WaitConfirmation(event, ip, no_event, wait, selection) => {
|
TextScriptExecutionState::WaitConfirmation(event, ip, no_event, wait, selection) => {
|
||||||
|
|
@ -891,7 +893,10 @@ impl TextScriptVM {
|
||||||
|
|
||||||
if flag_to >= flag_from {
|
if flag_to >= flag_from {
|
||||||
for flag in flag_from..=flag_to {
|
for flag in flag_from..=flag_to {
|
||||||
|
if state.get_flag(flag) {
|
||||||
state.game_flags.set(flag, false);
|
state.game_flags.set(flag, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue