various tweaks

This commit is contained in:
Alula 2020-09-29 02:43:55 +02:00
parent e54901077c
commit ac8d27197c
No known key found for this signature in database
GPG Key ID: 3E00485503A1D8BA
8 changed files with 100 additions and 69 deletions

View File

@ -44,6 +44,7 @@ impl LiveDebugger {
}
Window::new(im_str!("Debugger"))
.collapsed(true, Condition::FirstUseEver)
.position([5.0, 5.0], Condition::FirstUseEver)
.size([300.0, 120.0], Condition::FirstUseEver)
.build(ui, || {

View File

@ -101,14 +101,14 @@ impl Game {
for _ in 0..self.loops {
scene.tick(&mut self.state, ctx)?;
if self.state.speed_hack {
if self.state.settings.speed_hack {
scene.tick(&mut self.state, ctx)?;
}
}
}
TimingMode::FrameSynchronized => {
scene.tick(&mut self.state, ctx)?;
if self.state.speed_hack {
if self.state.settings.speed_hack {
scene.tick(&mut self.state, ctx)?;
}
}
@ -151,8 +151,8 @@ impl Game {
KeyCode::X => { state.key_state.set_fire(true) }
KeyCode::A => { state.key_state.set_weapon_prev(true) }
KeyCode::S => { state.key_state.set_weapon_next(true) }
KeyCode::F11 => { state.god_mode = !state.god_mode }
KeyCode::F12 => { state.set_speed_hack(!state.speed_hack) }
KeyCode::F11 => { state.settings.god_mode = !state.settings.god_mode }
KeyCode::F12 => { state.set_speed_hack(!state.settings.speed_hack) }
_ => {}
}
}

View File

@ -537,7 +537,7 @@ impl Player {
}
pub fn damage(&mut self, hp: isize, state: &mut SharedGameState) {
if state.god_mode || self.shock_counter > 0 {
if state.settings.god_mode || self.shock_counter > 0 {
return;
}

View File

@ -557,26 +557,14 @@ impl GameScene {
graphics::clear(ctx, Color::from_rgb(150, 150, 150));
{
if !self.player.cond.hidden() && self.inventory.get_current_weapon().is_some() {
let batch = state.texture_set.get_or_load_batch(ctx, &state.constants, "builtin/lightmap/direct")?;
let direction = if self.player.up {
Direction::Up
} else if self.player.down {
Direction::Bottom
} else {
self.player.direction
};
self.draw_directional_light(((self.player.x - self.frame.x) / 0x200) as f32,
((self.player.y - self.frame.y) / 0x200) as f32,
3.0, direction, (255, 255, 255), batch);
batch.draw_filtered(FilterMode::Linear, ctx)?;
}
let batch = state.texture_set.get_or_load_batch(ctx, &state.constants, "builtin/lightmap/spot")?;
if !self.player.cond.hidden() && self.inventory.get_current_weapon().is_some() {
self.draw_light(((self.player.x - self.frame.x) / 0x200) as f32,
((self.player.y - self.frame.y) / 0x200) as f32,
2.5, (255, 255, 255), batch);
}
for bullet in self.bullet_manager.bullets.iter() {
self.draw_light(((bullet.x - self.frame.x) / 0x200) as f32,
((bullet.y - self.frame.y) / 0x200) as f32,
@ -588,17 +576,7 @@ impl GameScene {
CaretType::ProjectileDissipation | CaretType::Shoot => {
self.draw_light(((caret.x - self.frame.x) / 0x200) as f32,
((caret.y - self.frame.y) / 0x200) as f32,
1.0, (200, 200, 200), batch);
}
CaretType::LevelUp if caret.direction == Direction::Left => {
self.draw_light(((caret.x - self.frame.x) / 0x200) as f32,
((caret.y - self.frame.y) / 0x200) as f32,
2.0, (0, 100, 160), batch);
}
CaretType::LevelUp if caret.direction == Direction::Right => {
self.draw_light(((caret.x - self.frame.x) / 0x200) as f32,
((caret.y - self.frame.y) / 0x200) as f32,
2.0, (255, 30, 30), batch);
4.0, (200, 200, 200), batch);
}
_ => {}
}
@ -1007,7 +985,7 @@ impl Scene for GameScene {
fn draw(&self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
self.draw_background(state, ctx)?;
self.draw_tiles(state, ctx, TileLayer::Background)?;
if state.enhanced_graphics {
if state.settings.enhanced_graphics {
self.draw_light_map(state, ctx)?;
}

View File

@ -31,6 +31,14 @@ impl Scene for LoadingScene {
let head_script = TextScript::load_from(head_tsc, &state.constants)?;
state.textscript_vm.set_global_script(head_script);
let arms_item_tsc = filesystem::open(ctx, [&state.base_path, "/ArmsItem.tsc"].join(""))?;
let arms_item_script = TextScript::load_from(arms_item_tsc, &state.constants)?;
state.textscript_vm.set_inventory_script(arms_item_script);
let stage_select_tsc = filesystem::open(ctx, [&state.base_path, "/StageSelect.tsc"].join(""))?;
let stage_select_script = TextScript::load_from(stage_select_tsc, &state.constants)?;
state.textscript_vm.set_stage_select_script(stage_select_script);
state.next_scene = Some(Box::new(TitleScene::new()));
}

View File

@ -4,6 +4,7 @@ use crate::ggez::graphics::{Color, FilterMode};
use crate::menu::{Menu, MenuEntry, MenuSelectionResult};
use crate::scene::Scene;
use crate::shared_game_state::{SharedGameState, TimingMode};
use crate::texture_set::TextureSet;
#[derive(PartialEq, Eq, Copy, Clone)]
#[repr(u8)]
@ -93,8 +94,13 @@ impl Scene for TitleScene {
self.option_menu.push_entry(MenuEntry::Toggle("50 FPS timing".to_string(), state.timing_mode == TimingMode::_50Hz));
self.option_menu.push_entry(MenuEntry::Toggle("Linear scaling".to_string(), ctx.filter_mode == FilterMode::Linear));
self.option_menu.push_entry(MenuEntry::Toggle("Enhanced graphics".to_string(), state.enhanced_graphics));
self.option_menu.push_entry(MenuEntry::Toggle("2x Speed hack".to_string(), state.speed_hack));
self.option_menu.push_entry(MenuEntry::Toggle("Enhanced graphics".to_string(), state.settings.enhanced_graphics));
if state.constants.is_cs_plus {
self.option_menu.push_entry(MenuEntry::Toggle("Original textures".to_string(), state.settings.original_textures));
} else {
self.option_menu.push_entry(MenuEntry::Disabled("Original textures".to_string()));
}
self.option_menu.push_entry(MenuEntry::Toggle("2x Speed hack".to_string(), state.settings.speed_hack));
self.option_menu.push_entry(MenuEntry::Active("Join our Discord".to_string()));
self.option_menu.push_entry(MenuEntry::Disabled(DISCORD_LINK.to_owned()));
self.option_menu.push_entry(MenuEntry::Active("Back".to_string()));
@ -155,24 +161,38 @@ impl Scene for TitleScene {
}
MenuSelectionResult::Selected(2, toggle) => {
if let MenuEntry::Toggle(_, value) = toggle {
state.enhanced_graphics = !state.enhanced_graphics;
state.settings.enhanced_graphics = !state.settings.enhanced_graphics;
*value = state.enhanced_graphics;
*value = state.settings.enhanced_graphics;
}
}
MenuSelectionResult::Selected(3, toggle) => {
if let MenuEntry::Toggle(_, value) = toggle {
state.set_speed_hack(!state.speed_hack);
state.settings.original_textures = !state.settings.original_textures;
*value = state.speed_hack;
let path = if state.settings.original_textures {
"/base/ogph/"
} else {
"/base/"
};
state.texture_set = TextureSet::new(path);
*value = state.settings.original_textures;
}
}
MenuSelectionResult::Selected(4, _) => {
MenuSelectionResult::Selected(4, toggle) => {
if let MenuEntry::Toggle(_, value) = toggle {
state.set_speed_hack(!state.settings.speed_hack);
*value = state.settings.speed_hack;
}
}
MenuSelectionResult::Selected(5, _) => {
if let Err(e) = webbrowser::open(DISCORD_LINK) {
log::warn!("Error opening web browser: {}", e);
}
}
MenuSelectionResult::Selected(6, _) | MenuSelectionResult::Canceled => {
MenuSelectionResult::Selected(7, _) | MenuSelectionResult::Canceled => {
self.current_menu = CurrentMenu::MainMenu;
}
_ => {}

View File

@ -37,6 +37,13 @@ impl TimingMode {
}
}
pub struct Settings {
pub god_mode: bool,
pub speed_hack: bool,
pub original_textures: bool,
pub enhanced_graphics: bool,
}
pub struct SharedGameState {
pub timing_mode: TimingMode,
pub control_flags: ControlFlags,
@ -54,12 +61,10 @@ pub struct SharedGameState {
pub npc_table: NPCTable,
pub stages: Vec<StageData>,
pub sound_manager: SoundManager,
pub settings: Settings,
pub constants: EngineConstants,
pub new_npcs: Vec<NPC>,
pub scale: f32,
pub god_mode: bool,
pub speed_hack: bool,
pub enhanced_graphics: bool,
pub lightmap_canvas: Canvas,
pub canvas_size: (f32, f32),
pub screen_size: (f32, f32),
@ -113,12 +118,15 @@ impl SharedGameState {
npc_table: NPCTable::new(),
stages: Vec::with_capacity(96),
sound_manager: SoundManager::new(ctx)?,
settings: Settings {
god_mode: false,
speed_hack: false,
original_textures: false,
enhanced_graphics: true,
},
constants,
new_npcs: Vec::with_capacity(8),
scale,
god_mode: false,
speed_hack: false,
enhanced_graphics: true,
lightmap_canvas: Canvas::with_window_size(ctx)?,
screen_size,
canvas_size,
@ -209,7 +217,7 @@ impl SharedGameState {
}
pub fn set_speed_hack(&mut self, toggle: bool) {
self.speed_hack = toggle;
self.settings.speed_hack = toggle;
if let Err(err) = self.sound_manager.set_speed(if toggle { 2.0 } else { 1.0 }) {
log::error!("Error while sending a message to sound manager: {}", err);

View File

@ -279,6 +279,10 @@ pub enum OpCode {
PSH,
/// <POP, Restores text script state from stack and resumes previous event.
POP,
/// <KE2, Seen in ArmsItem.tsc, unknown purpose, related to puppies
KE2,
/// <FR2, likely related to <KE2, seen at end of events using it
FR2,
// ---- Custom opcodes, for use by modders ----
}
@ -315,6 +319,14 @@ pub enum ConfirmSelection {
No,
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[repr(u8)]
pub enum ScriptMode {
Map,
Inventory,
StageSelect,
}
impl Not for ConfirmSelection {
type Output = ConfirmSelection;
@ -342,10 +354,11 @@ pub enum TextScriptExecutionState {
}
pub struct TextScriptVM {
pub scripts: TextScriptVMScripts,
pub scripts: Scripts,
pub state: TextScriptExecutionState,
pub stack: Vec<TextScriptExecutionState>,
pub flags: TextScriptFlags,
pub mode: ScriptMode,
/// Toggle for non-strict TSC parsing because English versions of CS+ (both AG and Nicalis release)
/// modified the events carelessly and since original Pixel's engine hasn't enforced constraints
/// while parsing no one noticed them.
@ -365,12 +378,18 @@ impl Default for TextScriptVM {
}
}
pub struct TextScriptVMScripts {
pub struct Scripts {
/// Head.tsc - shared part of map scripts
pub global_script: TextScript,
/// <Map>.tsc - map script
pub scene_script: TextScript,
/// ArmsItem.tsc - used by inventory
pub inventory_script: TextScript,
/// StageSelect.tsc - used by teleport target selector
pub stage_select_script: TextScript,
}
impl TextScriptVMScripts {
impl Scripts {
pub fn find_script(&self, event_num: u16) -> Option<&Vec<u8>> {
if let Some(tsc) = self.scene_script.event_map.get(&event_num) {
return Some(tsc);
@ -400,9 +419,11 @@ fn read_cur_varint(cursor: &mut Cursor<&Vec<u8>>) -> GameResult<i32> {
impl TextScriptVM {
pub fn new() -> Self {
Self {
scripts: TextScriptVMScripts {
scripts: Scripts {
global_script: TextScript::new(),
scene_script: TextScript::new(),
inventory_script: TextScript::new(),
stage_select_script: TextScript::new(),
},
state: TextScriptExecutionState::Ended,
stack: Vec::with_capacity(6),
@ -415,6 +436,7 @@ impl TextScriptVM {
line_1: Vec::with_capacity(24),
line_2: Vec::with_capacity(24),
line_3: Vec::with_capacity(24),
mode: ScriptMode::Map,
}
}
@ -428,20 +450,12 @@ impl TextScriptVM {
if !self.suspend { self.reset(); }
}
pub fn append_global_script(&mut self, script: TextScript) {
for (key, val) in script.event_map {
self.scripts.global_script.event_map.insert(key, val);
}
if !self.suspend { self.reset(); }
pub fn set_inventory_script(&mut self, script: TextScript) {
self.scripts.inventory_script = script;
}
pub fn append_scene_script(&mut self, script: TextScript) {
for (key, val) in script.event_map {
self.scripts.scene_script.event_map.insert(key, val);
}
if !self.suspend { self.reset(); }
pub fn set_stage_select_script(&mut self, script: TextScript) {
self.scripts.stage_select_script = script;
}
pub fn reset(&mut self) {
@ -459,6 +473,8 @@ impl TextScriptVM {
self.line_3.clear();
}
pub fn set_mode(&mut self, mode: ScriptMode) {}
pub fn start_script(&mut self, event_num: u16) {
self.reset();
self.state = TextScriptExecutionState::Running(event_num, 0);
@ -1232,9 +1248,9 @@ impl TextScriptVM {
}
// unimplemented opcodes
// Zero operands
OpCode::CAT | OpCode::CIL | OpCode::CPS |
OpCode::CAT | OpCode::CIL | OpCode::CPS | OpCode::KE2 |
OpCode::CRE | OpCode::CSS | OpCode::FLA | OpCode::MLP |
OpCode::SAT | OpCode::SLP | OpCode::SPS |
OpCode::SAT | OpCode::SLP | OpCode::SPS | OpCode::FR2 |
OpCode::STC | OpCode::SVP | OpCode::TUR | OpCode::HM2 => {
log::warn!("unimplemented opcode: {:?}", op);
@ -1513,7 +1529,7 @@ impl TextScript {
OpCode::MM0 | OpCode::MNA | OpCode::MS2 | OpCode::MS3 | OpCode::MSG | OpCode::NOD |
OpCode::PRI | OpCode::RMU | OpCode::SAT | OpCode::SLP | OpCode::SMC | OpCode::SPS |
OpCode::STC | OpCode::SVP | OpCode::TUR | OpCode::WAS | OpCode::ZAM | OpCode::HM2 |
OpCode::POP => {
OpCode::POP | OpCode::KE2 | OpCode::FR2 => {
TextScript::put_varint(instr as i32, out);
}
// One operand codes