-- Per-compartment flags on the original world object. No Quartermaster data is changed. QMIA = QMIA or {} QMIA.MOD_ID = "QuartermasterItemArrange" QMIA.DATA_KEY = "QMIArrange" function QMIA.isMarked(obj, ci) if not obj or ci == nil or not obj:hasModData() then return false end local flags = obj:getModData()[QMIA.DATA_KEY] return type(flags) == "table" and flags[tostring(ci)] == true end function QMIA.containerTarget(container) if not container then return nil end local obj = container:getParent() if not obj or not obj.getContainerCount or not obj.getSquare then return nil end for ci = 0, obj:getContainerCount() - 1 do if obj:getContainerByIndex(ci) == container then return obj, ci end end end -- Also called by the authoritative timed action, where Quartermaster's client helpers -- aren't loaded. Respect safehouse rules on both sides of a multiplayer connection. function QMIA.canAccess(square, player) if not square or not player then return false end if SafeHouse and SafeHouse.isSafehouseAllowLoot then return SafeHouse.isSafehouseAllowLoot(square, player) ~= false end return true end function QMIA.writeMark(obj, ci, enabled) local md = obj:getModData() local flags = md[QMIA.DATA_KEY] or {} flags[tostring(ci)] = enabled and true or nil md[QMIA.DATA_KEY] = flags obj:transmitModData() end -- Validate a client request against the current world. No client-supplied ModData -- snapshot is accepted, so changing one compartment cannot overwrite another. function QMIA.applyRequest(player, args) if type(args) ~= "table" or type(args.enabled) ~= "boolean" then return false end for _, key in ipairs({ "x", "y", "z", "oi", "ci" }) do local value = args[key] if type(value) ~= "number" or value ~= value or value == math.huge or value == -math.huge or value ~= math.floor(value) then return false end end if args.ci < 0 or args.oi < 0 or not player then return false end local square = getCell():getGridSquare(args.x, args.y, args.z) if not QMIA.canAccess(square, player) then return false end if math.abs(player:getX() - args.x) > 20 or math.abs(player:getY() - args.y) > 20 or math.abs(player:getZ() - args.z) > 1 then return false end local objects = square:getObjects() if args.oi >= objects:size() then return false end local obj = objects:get(args.oi) if not obj or not obj.getContainerCount or args.ci >= obj:getContainerCount() or not obj:getContainerByIndex(args.ci) then return false end QMIA.writeMark(obj, args.ci, args.enabled) return true end