Weapon control

From Wiki G1R-MP G1 Remake Multiplayer
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

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. Clearing settles one slot at a time without the unsafe bulk UnequipWeapons call. Its native toggle behavior must still pass retail gameplay tests; failure must report failure/timeout, not simulated success.

Development test

gothic_rp includes /weapontest status, prepare, start, set <key>, restore and stop. Require a spawned/authenticated test character, enabled test tools and admin.players permission. Prepare grants missing test weapons but no stats or ammunition. Start tests a sword, bows, crossbow, repeated equips, clear and two-slot combination. Restore reinstates the original slots recorded by start; granted items remain in inventory.

Test local rendering, a second client, late join, firing with correct ammo, native requirements, clear/restore, death and resource restart. Automated tests validate policies and Lua contracts, not the full retail gameplay path.