mirror of
https://github.com/redstrate/Kawari.git
synced 2025-07-10 07:57:46 +00:00
Extend the Lua API:
-Implement GM command collect (subtracts gil from player), but the ingame command's params are unknown, Lua only -Implement GM command inspect, but the IPC opcode for it is different than GMCommand and is thus far unimplemented, Lua only -The Lua API can now access all of the player's inventory (read-only)
This commit is contained in:
parent
877ec335a9
commit
3b6fcb7ba1
6 changed files with 193 additions and 3 deletions
|
@ -12,6 +12,8 @@ GM_EXP = 104
|
|||
GM_ORCHESTRION = 116
|
||||
GM_GIVE_ITEM = 200
|
||||
GM_GIL = 201
|
||||
GM_COLLECT = 202
|
||||
GM_INSPECT = 422
|
||||
GM_WIREFRAME = 550
|
||||
GM_TERRITORY = 600
|
||||
GM_TERRITORY_INFO = 605
|
||||
|
@ -20,11 +22,15 @@ registerGMCommand(GM_SET_LEVEL, GM_DIR.."SetLevel.lua")
|
|||
registerGMCommand(GM_CHANGE_WEATHER, GM_DIR.."ChangeWeather.lua")
|
||||
registerGMCommand(GM_SPEED, GM_DIR.."SetSpeed.lua")
|
||||
registerGMCommand(GM_INVISIBILITY, GM_DIR.."ToggleInvisibility.lua")
|
||||
-- TODO: Implement the GMInspect IPC opcode, it's completely different than the normal GMCommand opcode
|
||||
--registerGMCommand(GM_INSPECT, GM_DIR.."InspectPlayer.lua")
|
||||
registerGMCommand(GM_AETHERYTE, GM_DIR.."UnlockAetheryte.lua")
|
||||
registerGMCommand(GM_EXP, GM_DIR.."Exp.lua")
|
||||
registerGMCommand(GM_ORCHESTRION, GM_DIR.."Orchestrion.lua")
|
||||
registerGMCommand(GM_GIVE_ITEM, GM_DIR.."GiveItem.lua")
|
||||
registerGMCommand(GM_GIL, GM_DIR.."Gil.lua")
|
||||
-- TODO: Figure out how the //gm collect command works ingame, its parameters are not the same as //gm gil
|
||||
--registerGMCommand(GM_COLLECT, GM_DIR.."Collect.lua")
|
||||
registerGMCommand(GM_WIREFRAME, GM_DIR.."ToggleWireframe.lua")
|
||||
registerGMCommand(GM_TERRITORY, GM_DIR.."ChangeTerritory.lua")
|
||||
registerGMCommand(GM_TERRITORY_INFO, GM_DIR.."TerritoryInfo.lua")
|
||||
|
@ -33,7 +39,9 @@ registerGMCommand(GM_TERRITORY_INFO, GM_DIR.."TerritoryInfo.lua")
|
|||
-- Please keep these in alphabetical order!
|
||||
|
||||
registerCommand("classjob", DBG_DIR.."ClassJob.lua")
|
||||
registerCommand("collect", GM_DIR.."Collect.lua") -- TODO: remove this once we figure out the //gm collect command's parameters (see comments above)
|
||||
registerCommand("festival", DBG_DIR.."Festival.lua")
|
||||
registerCommand("inspect", GM_DIR.."InspectPlayer.lua") -- TODO: remove this once we figure out the GMInspect IPC opcode
|
||||
registerCommand("nudge", DBG_DIR.."Nudge.lua")
|
||||
registerCommand("ost", DBG_DIR.."OnScreenTest.lua")
|
||||
registerCommand("permtest", DBG_DIR.."PermissionTest.lua")
|
||||
|
|
12
resources/scripts/commands/gm/Collect.lua
Normal file
12
resources/scripts/commands/gm/Collect.lua
Normal file
|
@ -0,0 +1,12 @@
|
|||
required_rank = GM_RANK_DEBUG
|
||||
command_sender = "[collect] "
|
||||
|
||||
function onCommand(args, player)
|
||||
local amount = tonumber(args[1])
|
||||
if player.gil >= amount then
|
||||
player:remove_gil(amount)
|
||||
printf(player, "Collected %s gil.", amount)
|
||||
else
|
||||
printf(player, "Player does not have that much gil to take! They only possess %s.", player.gil)
|
||||
end
|
||||
end
|
79
resources/scripts/commands/gm/InspectPlayer.lua
Normal file
79
resources/scripts/commands/gm/InspectPlayer.lua
Normal file
|
@ -0,0 +1,79 @@
|
|||
required_rank = GM_RANK_DEBUG
|
||||
command_sender = "[inspect] "
|
||||
|
||||
function getItemCondition(condition)
|
||||
return (condition / 30000) * 100
|
||||
end
|
||||
|
||||
function onCommand(args, player)
|
||||
info = "\z
|
||||
--- Info for player ---\n\z
|
||||
Current region: %s\n\z
|
||||
Current zone: %s (%s, %s)\n\z
|
||||
Position: %.3f %.3f %.3f\n\z
|
||||
Rotation: %.3f\n\z
|
||||
--- Currency ---\n\z
|
||||
Gil: %s\n\z
|
||||
--- Equipped items ---\n\z
|
||||
Main hand: (id: %s, condition: %s%%)\n\z
|
||||
Off hand: (id: %s, condition: %s%%)\n\z
|
||||
Head: (id: %s, condition: %s%%)\n\z
|
||||
Body: (id: %s, condition: %s%%)\n\z
|
||||
Hands: (id: %s, condition: %s%%)\n\z
|
||||
Legs: (id: %s, condition: %s%%)\n\z
|
||||
Feet: (id: %s, condition: %s%%)\n\z
|
||||
Ears: (id: %s, condition: %s%%)\n\z
|
||||
Neck: (id: %s, condition: %s%%)\n\z
|
||||
Wrists: (id: %s, condition: %s%%)\n\z
|
||||
Right Ring: (id: %s, condition: %s%%)\n\z
|
||||
Left Ring: (id: %s, condition: %s%%)\n\z
|
||||
Soul Crystal: (id: %s, condition: %s%%)\z
|
||||
"
|
||||
-- Skipping belts because they don't exist anymore.
|
||||
main_hand = player.inventory.equipped.main_hand
|
||||
off_hand = player.inventory.equipped.off_hand
|
||||
head = player.inventory.equipped.head
|
||||
body = player.inventory.equipped.body
|
||||
hands = player.inventory.equipped.hands
|
||||
legs = player.inventory.equipped.legs
|
||||
feet = player.inventory.equipped.feet
|
||||
ears = player.inventory.equipped.ears
|
||||
neck = player.inventory.equipped.neck
|
||||
wrists = player.inventory.equipped.wrists
|
||||
rring = player.inventory.equipped.right_ring
|
||||
lring = player.inventory.equipped.left_ring
|
||||
scrystal = player.inventory.equipped.soul_crystal
|
||||
|
||||
printf(player, info,
|
||||
player.zone.region_name, player.zone.place_name, player.zone.internal_name, player.zone.id,
|
||||
player.position.x, player.position.y, player.position.z,
|
||||
player.rotation, player.gil,
|
||||
main_hand.id, getItemCondition(main_hand.condition),
|
||||
off_hand.id, getItemCondition(off_hand.condition),
|
||||
head.id, getItemCondition(head.condition),
|
||||
body.id, getItemCondition(body.condition),
|
||||
hands.id, getItemCondition(hands.condition),
|
||||
legs.id, getItemCondition(legs.condition),
|
||||
feet.id, getItemCondition(feet.condition),
|
||||
ears.id, getItemCondition(ears.condition),
|
||||
neck.id, getItemCondition(neck.condition),
|
||||
wrists.id, getItemCondition(wrists.condition),
|
||||
lring.id, getItemCondition(lring.condition),
|
||||
rring.id, getItemCondition(rring.condition),
|
||||
scrystal.id, getItemCondition(scrystal.condition)
|
||||
)
|
||||
|
||||
local NO_ITEM <const> = 0
|
||||
|
||||
command_sender = "" -- hush further sender printfs, it looks ugly here
|
||||
printf(player, "--- Player's inventory ---")
|
||||
|
||||
for page_num, page in pairs(player.inventory.pages) do
|
||||
printf(player, "--- Page %s ---", page_num)
|
||||
for slot_num, slot in pairs(page.slots) do
|
||||
if slot.id ~= NO_ITEM then
|
||||
printf(player, "slot %s: (id: %s, condition: %s%%)", slot_num, slot.id, getItemCondition(slot.condition))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -745,6 +745,10 @@ impl ZoneConnection {
|
|||
self.player_data.inventory.currency.get_slot_mut(0).quantity += *amount;
|
||||
self.send_inventory(false).await;
|
||||
}
|
||||
Task::RemoveGil { amount } => {
|
||||
self.player_data.inventory.currency.get_slot_mut(0).quantity -= *amount;
|
||||
self.send_inventory(false).await;
|
||||
}
|
||||
Task::UnlockOrchestrion { id, on } => {
|
||||
// id == 0 means "all"
|
||||
if *id == 0 {
|
||||
|
|
|
@ -6,6 +6,7 @@ use crate::{
|
|||
write_quantized_rotation,
|
||||
},
|
||||
config::get_config,
|
||||
inventory::{CurrencyStorage, EquippedStorage, GenericStorage, Inventory, Item},
|
||||
ipc::zone::{
|
||||
ActionEffect, ActorControlCategory, ActorControlSelf, DamageElement, DamageKind,
|
||||
DamageType, EffectKind, EventScene, ServerZoneIpcData, ServerZoneIpcSegment, Warp,
|
||||
|
@ -32,6 +33,7 @@ pub enum Task {
|
|||
SetLevel { level: i32 },
|
||||
ChangeWeather { id: u16 },
|
||||
AddGil { amount: u32 },
|
||||
RemoveGil { amount: u32 },
|
||||
UnlockOrchestrion { id: u16, on: bool },
|
||||
AddItem { id: u32 },
|
||||
}
|
||||
|
@ -353,6 +355,10 @@ impl LuaPlayer {
|
|||
self.queued_tasks.push(Task::AddGil { amount });
|
||||
}
|
||||
|
||||
fn remove_gil(&mut self, amount: u32) {
|
||||
self.queued_tasks.push(Task::RemoveGil { amount });
|
||||
}
|
||||
|
||||
fn unlock_orchestrion(&mut self, unlocked: u32, id: u16) {
|
||||
self.queued_tasks.push(Task::UnlockOrchestrion {
|
||||
id,
|
||||
|
@ -478,6 +484,10 @@ impl UserData for LuaPlayer {
|
|||
this.add_gil(amount);
|
||||
Ok(())
|
||||
});
|
||||
methods.add_method_mut("remove_gil", |_, this, amount: u32| {
|
||||
this.remove_gil(amount);
|
||||
Ok(())
|
||||
});
|
||||
methods.add_method_mut("unlock_orchestrion", |_, this, (unlock, id): (u32, u16)| {
|
||||
this.unlock_orchestrion(unlock, id);
|
||||
Ok(())
|
||||
|
@ -501,7 +511,14 @@ impl UserData for LuaPlayer {
|
|||
});
|
||||
fields.add_field_method_get("rotation", |_, this| Ok(this.player_data.rotation));
|
||||
fields.add_field_method_get("position", |_, this| Ok(this.player_data.position));
|
||||
fields.add_field_method_get("inventory", |_, this| {
|
||||
Ok(this.player_data.inventory.clone())
|
||||
});
|
||||
fields.add_field_method_get("zone", |_, this| Ok(this.zone_data.clone()));
|
||||
// Helper method to reduce the amount of typing for gil
|
||||
fields.add_field_method_get("gil", |_, this| {
|
||||
Ok(this.player_data.inventory.currency.gil.quantity)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -519,6 +536,76 @@ impl UserData for Position {
|
|||
}
|
||||
}
|
||||
|
||||
impl UserData for Inventory {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("equipped", |_, this| Ok(this.equipped));
|
||||
fields.add_field_method_get("pages", |_, this| Ok(this.pages.clone()));
|
||||
fields.add_field_method_get("armoury_main_hand", |_, this| {
|
||||
Ok(this.armoury_main_hand.clone())
|
||||
});
|
||||
fields.add_field_method_get("armoury_head", |_, this| Ok(this.armoury_head.clone()));
|
||||
fields.add_field_method_get("armoury_body", |_, this| Ok(this.armoury_body.clone()));
|
||||
fields.add_field_method_get("armoury_hands", |_, this| Ok(this.armoury_hands.clone()));
|
||||
fields.add_field_method_get("armoury_legs", |_, this| Ok(this.armoury_legs.clone()));
|
||||
fields.add_field_method_get("armoury_feet", |_, this| Ok(this.armoury_feet.clone()));
|
||||
fields.add_field_method_get("armoury_off_hand", |_, this| {
|
||||
Ok(this.armoury_off_hand.clone())
|
||||
});
|
||||
fields.add_field_method_get("armoury_earring", |_, this| {
|
||||
Ok(this.armoury_earring.clone())
|
||||
});
|
||||
fields.add_field_method_get("armoury_necklace", |_, this| {
|
||||
Ok(this.armoury_necklace.clone())
|
||||
});
|
||||
fields.add_field_method_get("armoury_bracelet", |_, this| Ok(this.armoury_body.clone()));
|
||||
fields.add_field_method_get("armoury_rings", |_, this| Ok(this.armoury_rings.clone()));
|
||||
fields.add_field_method_get("armoury_soul_crystal", |_, this| {
|
||||
Ok(this.armoury_soul_crystal.clone())
|
||||
});
|
||||
fields.add_field_method_get("currency", |_, this| Ok(this.currency));
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for Item {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("quantity", |_, this| Ok(this.quantity));
|
||||
fields.add_field_method_get("id", |_, this| Ok(this.id));
|
||||
fields.add_field_method_get("condition", |_, this| Ok(this.condition));
|
||||
fields.add_field_method_get("glamour_catalog_id", |_, this| Ok(this.condition));
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for CurrencyStorage {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("gil", |_, this| Ok(this.gil));
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> UserData for GenericStorage<N> {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("slots", |_, this| Ok(this.slots.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for EquippedStorage {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("main_hand", |_, this| Ok(this.main_hand));
|
||||
fields.add_field_method_get("off_hand", |_, this| Ok(this.off_hand));
|
||||
fields.add_field_method_get("head", |_, this| Ok(this.head));
|
||||
fields.add_field_method_get("body", |_, this| Ok(this.body));
|
||||
fields.add_field_method_get("hands", |_, this| Ok(this.hands));
|
||||
fields.add_field_method_get("belt", |_, this| Ok(this.belt));
|
||||
fields.add_field_method_get("legs", |_, this| Ok(this.legs));
|
||||
fields.add_field_method_get("feet", |_, this| Ok(this.feet));
|
||||
fields.add_field_method_get("ears", |_, this| Ok(this.ears));
|
||||
fields.add_field_method_get("neck", |_, this| Ok(this.neck));
|
||||
fields.add_field_method_get("wrists", |_, this| Ok(this.wrists));
|
||||
fields.add_field_method_get("right_ring", |_, this| Ok(this.right_ring));
|
||||
fields.add_field_method_get("left_ring", |_, this| Ok(this.left_ring));
|
||||
fields.add_field_method_get("soul_crystal", |_, this| Ok(this.soul_crystal));
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for ObjectTypeId {}
|
||||
|
||||
impl FromLua for ObjectTypeId {
|
||||
|
|
Loading…
Add table
Reference in a new issue