Weapon control

From Wiki G1R-MP G1 Remake Multiplayer
Revision as of 13:42, 20 September 2026 by QCherry (talk | contribs) (Clarify 0.1.4 weapon clearing, manual equipment and confirmation APIs)
Jump to navigation Jump to search

Weapon control

Confirmation APIs and corrected weapon request handling: since 0.1.4 (in development). Public 0.1.3 does not expose these additions. Use the matching client and server.

Requests versus completed equipment

setPlayerWeapon(playerId, itemKey) still returns boolean queue acceptance, not native completion. Melee and ranged slots are independent. A request for the already equipped item is idempotent. "none" requests clearing both slots without deleting inventory. Ownership and native equipment requirements apply; the function does not grant ammunition, bypass stats, draw a weapon or change armor.

getPlayerWeapon remains the legacy single scripted choice and is not a complete or confirmed two-slot loadout. Failed requests do not roll back that legacy choice. Use getPlayerWeaponState and onPlayerWeaponChangeResult when saving equipment or sequencing changes.

Confirmed state

getPlayerWeaponState(playerId) returns false if unavailable, otherwise a table:

  • supported: the client has sent the new native report.
  • known: both native slots could be resolved. Unknown is not an empty slot.
  • fresh: a known observation no older than 3 seconds while the character is alive.
  • melee, ranged: catalog keys; "" means an observed empty slot.
  • pending: array of {requestId, itemKey}. Clear requests use "none".

The owning resource receives onPlayerWeaponChangeResult(playerId, itemKey, ok, reason, requestId). Completion checks actual native readback, ownership, request identity, current life revision and deadline. New requests supersede conflicting requests; opposite slots are independent. Result events are not ordinary remotely callable Lua events.

addEventHandler("onPlayerWeaponChangeResult", resourceRoot,
    function(playerId, itemKey, ok, reason, requestId)
        local state = getPlayerWeaponState(playerId)
        if ok and state and state.fresh then
            -- Persist state.melee and state.ranged in your own database schema.
        end
    end)
setPlayerWeapon(playerId, "bow_small_01") -- must already be owned

Clearing weapons and manual changes

setPlayerWeapon(playerId, "none")

This requests removal from both equipped weapon slots, not deletion of the owned items. The client waits for a settled, idle local character with weapons sheathed and no active interaction. Successful clear requires both native slots to be empty and the associated melee/ranged carry visuals to be cleared. The native carry lifecycle also removes the ranged ammunition presentation. Stats, armor and identity are not changed.

After a valid clear confirmation, the server commits empty equipment and ranged state, including the state used when another player joins or enters relevance. This prevents an earlier equipment observation from retaining the old weapon in the server's saved replication state. It is a one-time commit, not a permanent equipment lock: subsequent manual equipment changes and normal drawing/sheathing remain allowed.

Use the current 0.1.4 development client together with the updated 0.1.4 server. Client-side removal alone does not replace the server-side confirmation fix. The function and event signatures are unchanged by these fixes.

Reading and saving state

The observed inventory state and request success are separate. Empty slot values may be reported even if presentation cleanup fails; inspect known, fresh and the result event rather than treating an empty string alone as completed cleanup. A failed or timed-out request is not an automatic rollback.

The result event confirms the requesting player's native operation and the server's validation. It is not an acknowledgement that every remote client has already rendered the updated models. A later manual change can also make the current state differ from the completed request. Persist the fresh observed slot values rather than assuming that the last requested key is the complete loadout.

Failure and lifecycle

Typical reasons include confirmed, superseded, native-equip-not-allowed, readback-timeout, client-confirmation-timeout and character/life changes. Native work is polled at 20 Hz while pending, with idle observations at 1 Hz. There is no blind replay after a native call. Client timeout is 6 seconds from native queueing; server timeout is 8 seconds from dispatch. Timeout does not prove an in-flight action had no effect: inspect current state before retrying.

Stopping a resource discards its pending results, preventing old completions from entering a restarted script. An already issued native action may finish; stop is not rollback. Failed, expired, superseded or cancelled requests cannot commit a successful clear. Character life revision is checked so a result from before death/respawn cannot clear a new loadout.

Unavailable native inventory/carry data or an interrupted presentation lifecycle may produce an explicit failure instead of confirmed. Do not blindly repeat a toggle or assume that queue acceptance proves successful equipment.