2021-06-27 21:14:36 +00:00
|
|
|
use std::io::Read;
|
|
|
|
|
2021-01-01 01:46:01 +00:00
|
|
|
use lua_ffi::ffi::luaL_Reg;
|
2021-02-12 10:05:28 +00:00
|
|
|
use lua_ffi::{c_int, LuaObject, State};
|
2021-01-01 01:46:01 +00:00
|
|
|
|
2021-06-27 21:14:36 +00:00
|
|
|
use crate::common::{Direction, Rect};
|
|
|
|
use crate::framework::filesystem;
|
|
|
|
use crate::rng::RNG;
|
|
|
|
use crate::scripting::{check_status, LuaScriptingState, DRS_RUNTIME_GLOBAL};
|
2021-08-16 17:12:00 +00:00
|
|
|
use crate::scene::game_scene::LightingMode;
|
2021-01-01 01:46:01 +00:00
|
|
|
|
|
|
|
pub struct Doukutsu {
|
|
|
|
pub ptr: *mut LuaScriptingState,
|
|
|
|
}
|
|
|
|
|
2021-02-10 11:53:49 +00:00
|
|
|
#[allow(unused)]
|
2021-01-01 01:46:01 +00:00
|
|
|
impl Doukutsu {
|
|
|
|
pub fn new(ptr: *mut LuaScriptingState) -> Doukutsu {
|
2021-02-12 10:05:28 +00:00
|
|
|
Doukutsu { ptr }
|
2021-01-01 01:46:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn lua_play_sfx(&self, state: &mut State) -> c_int {
|
|
|
|
if let Some(index) = state.to_int(2) {
|
|
|
|
let game_state = &mut (*(*self.ptr).state_ptr);
|
|
|
|
|
|
|
|
game_state.sound_manager.play_sfx(index as u8);
|
|
|
|
}
|
|
|
|
|
|
|
|
0
|
|
|
|
}
|
|
|
|
|
2021-06-27 21:14:36 +00:00
|
|
|
unsafe fn lua_play_sfx_loop(&self, state: &mut State) -> c_int {
|
|
|
|
if let Some(index) = state.to_int(2) {
|
|
|
|
let game_state = &mut (*(*self.ptr).state_ptr);
|
|
|
|
|
|
|
|
game_state.sound_manager.loop_sfx(index as u8);
|
|
|
|
}
|
|
|
|
|
|
|
|
0
|
|
|
|
}
|
|
|
|
|
2021-01-01 01:46:01 +00:00
|
|
|
unsafe fn lua_play_song(&self, state: &mut State) -> c_int {
|
|
|
|
if let Some(index) = state.to_int(2) {
|
|
|
|
let game_state = &mut (*(*self.ptr).state_ptr);
|
|
|
|
let ctx = &mut (*(*self.ptr).ctx_ptr);
|
|
|
|
|
2021-02-12 10:05:28 +00:00
|
|
|
let _ =
|
|
|
|
game_state.sound_manager.play_song(index as usize, &game_state.constants, &game_state.settings, ctx);
|
2021-01-01 01:46:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
0
|
|
|
|
}
|
|
|
|
|
2021-02-24 08:28:47 +00:00
|
|
|
unsafe fn lua_set_setting(&self, state: &mut State) -> c_int {
|
|
|
|
if let Some(index) = state.to_int(2) {
|
|
|
|
let game_state = &mut (*(*self.ptr).state_ptr);
|
|
|
|
|
|
|
|
state.push(game_state.get_flag(index.max(0) as usize));
|
|
|
|
} else {
|
|
|
|
state.push_nil();
|
|
|
|
}
|
|
|
|
|
|
|
|
1
|
|
|
|
}
|
|
|
|
|
2021-02-10 20:14:09 +00:00
|
|
|
unsafe fn lua_get_flag(&self, state: &mut State) -> c_int {
|
2021-01-01 01:46:01 +00:00
|
|
|
if let Some(index) = state.to_int(2) {
|
|
|
|
let game_state = &mut (*(*self.ptr).state_ptr);
|
|
|
|
|
2021-02-10 20:14:09 +00:00
|
|
|
state.push(game_state.get_flag(index.max(0) as usize));
|
2021-01-01 01:46:01 +00:00
|
|
|
} else {
|
|
|
|
state.push_nil();
|
|
|
|
}
|
|
|
|
|
|
|
|
1
|
|
|
|
}
|
2021-06-27 21:14:36 +00:00
|
|
|
|
|
|
|
unsafe fn lua_set_flag(&self, state: &mut State) -> c_int {
|
|
|
|
let flag_id = state.to_int(2);
|
|
|
|
let flag_val = state.to_bool(3);
|
|
|
|
|
|
|
|
if let (Some(flag_id), Some(flag_val)) = (flag_id, flag_val) {
|
|
|
|
let game_state = &mut (*(*self.ptr).state_ptr);
|
|
|
|
|
|
|
|
game_state.set_flag(flag_id.max(0) as usize, flag_val);
|
|
|
|
}
|
|
|
|
|
|
|
|
0
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn lua_get_skip_flag(&self, state: &mut State) -> c_int {
|
|
|
|
if let Some(index) = state.to_int(2) {
|
|
|
|
let game_state = &mut (*(*self.ptr).state_ptr);
|
|
|
|
|
|
|
|
state.push(game_state.get_skip_flag(index.max(0) as usize));
|
|
|
|
} else {
|
|
|
|
state.push_nil();
|
|
|
|
}
|
|
|
|
|
|
|
|
1
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn lua_set_skip_flag(&self, state: &mut State) -> c_int {
|
|
|
|
let flag_id = state.to_int(2);
|
|
|
|
let flag_val = state.to_bool(3);
|
|
|
|
|
|
|
|
if let (Some(flag_id), Some(flag_val)) = (flag_id, flag_val) {
|
|
|
|
let game_state = &mut (*(*self.ptr).state_ptr);
|
|
|
|
|
|
|
|
game_state.set_skip_flag(flag_id.max(0) as usize, flag_val);
|
|
|
|
}
|
|
|
|
|
|
|
|
0
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn lua_set_engine_constant(&self, state: &mut State) -> c_int {
|
|
|
|
if let Some(constant_id) = state.to_int(2) {
|
|
|
|
let game_state = &mut (*(*self.ptr).state_ptr);
|
|
|
|
|
|
|
|
match constant_id {
|
|
|
|
0x1000 => {
|
|
|
|
// intro event
|
|
|
|
if let Some(intro_event) = state.to_int(3) {
|
|
|
|
game_state.constants.game.intro_event = intro_event as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x1001 => {
|
|
|
|
// intro stage
|
|
|
|
if let Some(intro_stage) = state.to_int(3) {
|
|
|
|
game_state.constants.game.intro_stage = intro_stage as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x1002 => {
|
|
|
|
// intro pos
|
|
|
|
if let (Some(intro_x), Some(intro_y)) = (state.to_int(3), state.to_int(4)) {
|
|
|
|
game_state.constants.game.intro_player_pos = (intro_x as i16, intro_y as i16);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x1003 => {
|
|
|
|
// ng event
|
|
|
|
if let Some(ng_event) = state.to_int(3) {
|
|
|
|
game_state.constants.game.new_game_event = ng_event as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x1004 => {
|
|
|
|
// ng stage
|
|
|
|
if let Some(ng_stage) = state.to_int(3) {
|
|
|
|
game_state.constants.game.new_game_stage = ng_stage as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x1005 => {
|
|
|
|
// ng pos
|
|
|
|
if let (Some(ng_x), Some(ng_y)) = (state.to_int(3), state.to_int(4)) {
|
|
|
|
game_state.constants.game.new_game_player_pos = (ng_x as i16, ng_y as i16);
|
|
|
|
}
|
|
|
|
}
|
2021-08-16 17:12:00 +00:00
|
|
|
0x2000 => {
|
|
|
|
// font scale
|
|
|
|
if let Some(font_scale) = state.to_float(3) {
|
|
|
|
if font_scale > 0.0 {
|
|
|
|
game_state.constants.font_scale = font_scale;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-06-27 21:14:36 +00:00
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
0
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn lua_npc_command(&self, state: &mut State) -> c_int {
|
|
|
|
if (*self.ptr).game_scene.is_null() {
|
|
|
|
state.push_nil();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if let (Some(npc_id), Some(param_type)) = (state.to_int(2), state.to_int(3)) {
|
|
|
|
let game_scene = &mut *(*self.ptr).game_scene;
|
|
|
|
|
|
|
|
let npc = match game_scene.npc_list.get_npc(npc_id as usize) {
|
|
|
|
Some(npc) => npc,
|
|
|
|
None => {
|
|
|
|
state.push_nil();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
match param_type {
|
|
|
|
0x0e => state.push(npc.cond.0 as i32),
|
|
|
|
0x0f => state.push(npc.flags.0),
|
|
|
|
0x10 => state.push(npc.x as f32 / 512.0),
|
|
|
|
0x11 => state.push(npc.y as f32 / 512.0),
|
|
|
|
0x12 => state.push(npc.vel_x as f32 / 512.0),
|
|
|
|
0x13 => state.push(npc.vel_y as f32 / 512.0),
|
|
|
|
0x14 => state.push(npc.vel_x2 as f32 / 512.0),
|
|
|
|
0x15 => state.push(npc.vel_y2 as f32 / 512.0),
|
|
|
|
0x16 => state.push(npc.action_num as i32),
|
|
|
|
0x17 => state.push(npc.anim_num as i32),
|
|
|
|
0x18 => state.push(npc.action_counter as i32),
|
|
|
|
0x19 => state.push(npc.action_counter2 as i32),
|
|
|
|
0x1a => state.push(npc.action_counter3 as i32),
|
|
|
|
0x1b => state.push(npc.anim_counter as i32),
|
|
|
|
0x1c => state.push(npc.parent_id as i32),
|
|
|
|
0x1d => state.push(npc.npc_type as i32),
|
|
|
|
0x1e => state.push(npc.life as i32),
|
|
|
|
0x1f => state.push(npc.flag_num as i32),
|
|
|
|
0x20 => state.push(npc.event_num as i32),
|
|
|
|
0x21 => state.push(npc.direction as i32),
|
|
|
|
0x22 => state.push(npc.tsc_direction as i32),
|
|
|
|
0x10e => {
|
|
|
|
if let Some(v) = state.to_uint(4) {
|
|
|
|
npc.cond.0 = v as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x10f => {
|
|
|
|
if let Some(v) = state.to_uint(4) {
|
|
|
|
npc.flags.0 = v;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x110 => {
|
|
|
|
if let Some(v) = state.to_float(4) {
|
|
|
|
// set x
|
|
|
|
npc.x = (v * 512.0) as i32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x111 => {
|
|
|
|
if let Some(v) = state.to_float(4) {
|
|
|
|
// set y
|
|
|
|
npc.y = (v * 512.0) as i32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x112 => {
|
|
|
|
if let Some(v) = state.to_float(4) {
|
|
|
|
// set vel x
|
|
|
|
npc.vel_x = (v * 512.0) as i32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x113 => {
|
|
|
|
if let Some(v) = state.to_float(4) {
|
|
|
|
// set vel y
|
|
|
|
npc.vel_y = (v * 512.0) as i32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x114 => {
|
|
|
|
if let Some(v) = state.to_float(4) {
|
|
|
|
// set vel x 2
|
|
|
|
npc.vel_x2 = (v * 512.0) as i32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x115 => {
|
|
|
|
if let Some(v) = state.to_float(4) {
|
|
|
|
// set vel y 2
|
|
|
|
npc.vel_y2 = (v * 512.0) as i32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x116 => {
|
|
|
|
if let Some(v) = state.to_int(4) {
|
|
|
|
npc.action_num = v as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x117 => {
|
|
|
|
if let Some(v) = state.to_int(4) {
|
|
|
|
npc.anim_num = v as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x118 => {
|
|
|
|
if let Some(v) = state.to_int(4) {
|
|
|
|
npc.action_counter = v as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x119 => {
|
|
|
|
if let Some(v) = state.to_int(4) {
|
|
|
|
npc.action_counter2 = v as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x11a => {
|
|
|
|
if let Some(v) = state.to_int(4) {
|
|
|
|
npc.action_counter3 = v as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x11b => {
|
|
|
|
if let Some(v) = state.to_int(4) {
|
|
|
|
npc.anim_counter = v as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x11c => {
|
|
|
|
if let Some(v) = state.to_int(4) {
|
|
|
|
npc.parent_id = v as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x11d => {
|
|
|
|
if let Some(v) = state.to_int(4) {
|
|
|
|
npc.npc_type = v as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x11e => {
|
|
|
|
if let Some(v) = state.to_int(4) {
|
|
|
|
npc.life = v as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x11f => {
|
|
|
|
if let Some(v) = state.to_int(4) {
|
|
|
|
npc.flag_num = v as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x120 => {
|
|
|
|
if let Some(v) = state.to_int(4) {
|
|
|
|
npc.event_num = v as u16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x121 | 0x122 => {
|
|
|
|
if let Some(v) = state.to_int(4) {
|
|
|
|
npc.direction = Direction::from_int_facing(v as _).unwrap_or(Direction::Left);
|
|
|
|
npc.tsc_direction = v as _;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x200 => {
|
|
|
|
// get player idx
|
|
|
|
let index = npc.get_closest_player_idx_mut(&[&mut game_scene.player1, &mut game_scene.player2]);
|
|
|
|
state.push(index as i32);
|
|
|
|
}
|
|
|
|
0x201 => {
|
|
|
|
// random
|
|
|
|
if let (Some(min), Some(max)) = (state.to_int(4), state.to_int(5)) {
|
|
|
|
if max < min {
|
|
|
|
state.error("max < min");
|
|
|
|
} else {
|
|
|
|
state.push(npc.rng.range(min..max));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
state.error("Invalid parameters supplied.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x202 => {
|
|
|
|
// get anim rect
|
|
|
|
state.push(npc.anim_rect.left as i32);
|
|
|
|
state.push(npc.anim_rect.top as i32);
|
|
|
|
state.push(npc.anim_rect.right as i32);
|
|
|
|
state.push(npc.anim_rect.bottom as i32);
|
|
|
|
}
|
|
|
|
0x203 => {
|
|
|
|
// set anim rect
|
|
|
|
if let (Some(l), Some(t), Some(r), Some(b)) =
|
|
|
|
(state.to_int(4), state.to_int(5), state.to_int(6), state.to_int(7))
|
|
|
|
{
|
|
|
|
npc.anim_rect = Rect { left: l as u16, top: t as u16, right: r as u16, bottom: b as u16 };
|
|
|
|
} else {
|
|
|
|
state.error("Invalid parameters supplied.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => state.push_nil(),
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
state.push_nil()
|
|
|
|
}
|
|
|
|
|
|
|
|
1
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn lua_player_command(&self, state: &mut State) -> c_int {
|
|
|
|
if (*self.ptr).game_scene.is_null() {
|
|
|
|
state.push_nil();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if let (Some(player_id), Some(param_type)) = (state.to_int(2), state.to_int(3)) {
|
|
|
|
let game_scene = &mut *(*self.ptr).game_scene;
|
|
|
|
|
|
|
|
let player = match player_id {
|
|
|
|
0 => &mut game_scene.player1,
|
|
|
|
1 => &mut game_scene.player2,
|
|
|
|
_ => {
|
|
|
|
state.push_nil();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
match param_type {
|
|
|
|
0x0e => state.push(player.cond.0 as u32),
|
|
|
|
0x0f => state.push(player.flags.0),
|
|
|
|
0x10 => state.push(player.x as f32 / 512.0),
|
|
|
|
0x11 => state.push(player.y as f32 / 512.0),
|
|
|
|
0x12 => state.push(player.vel_x as f32 / 512.0),
|
|
|
|
0x13 => state.push(player.vel_y as f32 / 512.0),
|
|
|
|
0x110 => {
|
|
|
|
if let Some(v) = state.to_float(4) {
|
|
|
|
// set x
|
|
|
|
player.x = (v * 512.0) as i32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x111 => {
|
|
|
|
if let Some(v) = state.to_float(4) {
|
|
|
|
// set y
|
|
|
|
player.y = (v * 512.0) as i32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x112 => {
|
|
|
|
if let Some(v) = state.to_float(4) {
|
|
|
|
// set vel x
|
|
|
|
player.vel_x = (v * 512.0) as i32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x113 => {
|
|
|
|
if let Some(v) = state.to_float(4) {
|
|
|
|
// set vel y
|
|
|
|
player.vel_y = (v * 512.0) as i32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
0x200 => {
|
|
|
|
if let Some(points) = state.to_int(4) {
|
|
|
|
player.damage(points, &mut (*(*self.ptr).state_ptr), &game_scene.npc_list);
|
|
|
|
}
|
|
|
|
|
|
|
|
state.push_nil();
|
|
|
|
}
|
|
|
|
_ => state.push_nil(),
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
state.push_nil()
|
|
|
|
}
|
|
|
|
|
|
|
|
1
|
|
|
|
}
|
|
|
|
|
2021-08-16 17:12:00 +00:00
|
|
|
unsafe fn lua_stage_command(&self, state: &mut State) -> c_int {
|
|
|
|
if (*self.ptr).game_scene.is_null() {
|
|
|
|
state.push_nil();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(param_type) = state.to_int(2) {
|
|
|
|
let game_scene = &mut *(*self.ptr).game_scene;
|
|
|
|
let game_state = &mut *(*self.ptr).state_ptr;
|
|
|
|
|
|
|
|
match param_type {
|
|
|
|
0x01 => state.push(match game_scene.lighting_mode {
|
|
|
|
LightingMode::None => "none",
|
|
|
|
LightingMode::BackgroundOnly => "backgroundOnly",
|
|
|
|
LightingMode::Ambient => "ambient",
|
|
|
|
}),
|
|
|
|
0x02 => state.push(game_state.settings.shader_effects),
|
2021-10-08 02:41:31 +00:00
|
|
|
0x03 => state.push(game_scene.stage_id as u32),
|
2021-08-16 17:12:00 +00:00
|
|
|
0x101 => {
|
2021-10-08 02:41:31 +00:00
|
|
|
if let Some(v) = state.to_str(3) {
|
2021-08-16 17:12:00 +00:00
|
|
|
game_scene.lighting_mode = match v {
|
|
|
|
"none" => LightingMode::None,
|
|
|
|
"backgroundOnly" => LightingMode::BackgroundOnly,
|
|
|
|
"ambient" => LightingMode::Ambient,
|
|
|
|
_ => game_scene.lighting_mode,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
state.push_nil();
|
|
|
|
}
|
|
|
|
_ => state.push_nil(),
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
state.push_nil()
|
|
|
|
}
|
|
|
|
|
|
|
|
1
|
|
|
|
}
|
|
|
|
|
2021-06-27 21:14:36 +00:00
|
|
|
unsafe fn lua_load_script(&mut self, state: &mut State) -> c_int {
|
|
|
|
let lua_state = &mut (*self.ptr);
|
|
|
|
|
|
|
|
if let Some(name) = state.to_str(2) {
|
|
|
|
let name = name.to_string();
|
|
|
|
|
|
|
|
let ctx = &mut (*(*self.ptr).ctx_ptr);
|
|
|
|
|
|
|
|
let path = format!("/Scripts/{}.lua", name);
|
|
|
|
let lua_vfs_path = format!("@/Scripts/{}.lua", name);
|
|
|
|
|
|
|
|
fn raise_error(name: &str, state: &mut State, err: &str) {
|
|
|
|
let error_msg = format!("module '{}' not found: {}", name, err.to_string());
|
|
|
|
state.error(&error_msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
match filesystem::open(ctx, &path) {
|
|
|
|
Ok(mut file) => {
|
|
|
|
let mut buf = Vec::new();
|
|
|
|
if let Err(res) = file.read_to_end(&mut buf) {
|
|
|
|
raise_error(&name, state, &res.to_string());
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
let res = state.load_buffer(&buf, &lua_vfs_path);
|
|
|
|
if let Err(err) = check_status(res, state) {
|
|
|
|
raise_error(&name, state, &err.to_string());
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return match state.pcall(0, 1, 0) {
|
|
|
|
Ok(_) => 1,
|
|
|
|
Err((_, err)) => {
|
|
|
|
raise_error(&name, state, &err);
|
|
|
|
0
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
Err(err) => {
|
|
|
|
raise_error(&name, state, &err.to_string());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
0
|
|
|
|
}
|
2021-01-01 01:46:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl LuaObject for Doukutsu {
|
|
|
|
fn name() -> *const i8 {
|
2021-06-27 21:14:36 +00:00
|
|
|
c_str!("doukutsu-rs-internal")
|
2021-01-01 01:46:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn lua_fns() -> Vec<luaL_Reg> {
|
|
|
|
vec![
|
2021-02-24 08:28:47 +00:00
|
|
|
lua_method!("playSfx", Doukutsu, Doukutsu::lua_play_sfx),
|
|
|
|
lua_method!("playSong", Doukutsu, Doukutsu::lua_play_song),
|
|
|
|
lua_method!("getFlag", Doukutsu, Doukutsu::lua_get_flag),
|
2021-06-27 21:14:36 +00:00
|
|
|
lua_method!("setFlag", Doukutsu, Doukutsu::lua_set_flag),
|
|
|
|
lua_method!("getSkipFlag", Doukutsu, Doukutsu::lua_get_skip_flag),
|
|
|
|
lua_method!("setSkipFlag", Doukutsu, Doukutsu::lua_set_skip_flag),
|
|
|
|
lua_method!("setEngineConstant", Doukutsu, Doukutsu::lua_set_engine_constant),
|
|
|
|
lua_method!("playerCommand", Doukutsu, Doukutsu::lua_player_command),
|
|
|
|
lua_method!("npcCommand", Doukutsu, Doukutsu::lua_npc_command),
|
2021-08-16 17:12:00 +00:00
|
|
|
lua_method!("stageCommand", Doukutsu, Doukutsu::lua_stage_command),
|
2021-06-27 21:14:36 +00:00
|
|
|
lua_method!("loadScript", Doukutsu, Doukutsu::lua_load_script),
|
2021-01-01 01:46:01 +00:00
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
2021-06-27 21:14:36 +00:00
|
|
|
|
|
|
|
impl LuaScriptingState {
|
|
|
|
pub fn try_run_npc_hook(&mut self, npc_id: u16, npc_type: u16) -> bool {
|
|
|
|
let mut result = false;
|
|
|
|
|
|
|
|
if let Some(state) = self.state.as_mut() {
|
|
|
|
state.get_global(DRS_RUNTIME_GLOBAL);
|
|
|
|
state.get_field(-1, "_tryNPCHook");
|
|
|
|
|
|
|
|
state.push(npc_id as i32);
|
|
|
|
state.push(npc_type as i32);
|
|
|
|
|
|
|
|
if let Err((_, err)) = state.pcall(2, 1, 0) {
|
|
|
|
log::error!("npc_hook error: {}", err);
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(val) = state.to_bool(-1) {
|
|
|
|
result = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
state.pop(2);
|
|
|
|
}
|
|
|
|
|
|
|
|
result
|
|
|
|
}
|
|
|
|
}
|