--*********************************************************** --** THE INDIE STONE ** --*********************************************************** if isClient() then return end local ClientCommands = {} local Commands = {} Commands.object = {} ClientCommands.wantNoise = getDebug() local noise = function(msg) if (ClientCommands.wantNoise) then print('ClientCommand: '..msg) end end local getThumpableLight = function(x, y, z) local gs = getCell():getGridSquare(x, y, z) if not gs then return nil end for i=0,gs:getSpecialObjects():size()-1 do local o = gs:getSpecialObjects():get(i) if o and instanceof(o, 'IsoThumpable') and o:getLightSourceFuel() then return o end end return nil end Commands.object.toggleLight = function(player, args) local o = getThumpableLight(args.x, args.y, args.z) if o then o:toggleLightSource(not o:isLightSourceOn()) o:sendObjectChange('lightSource') end end Commands.object.insertFuel = function(player, args) local o = getThumpableLight(args.x, args.y, args.z) if o then -- when player inventory is synced properly, we will simply send -- the index/id of the item to use instead of creating a new item. local fuel = InventoryItemFactory.CreateItem(args.fuel) fuel:setUsedDelta(args.usedDelta) local previous = o:insertNewFuel(fuel, nil) o:sendObjectChange('lightSource') player:sendObjectChange('removeItemID', { id = args.itemID, type = args.fuel }) if previous then player:sendObjectChange('addItem', { item = previous }) end else noise('no thumpable light found!') end end Commands.object.removeFuel = function(player, args) local o = getThumpableLight(args.x, args.y, args.z) if o and o:haveFuel() then local fuel = o:removeCurrentFuel(nil) if fuel then o:sendObjectChange('lightSource') player:sendObjectChange('addItem', { item = fuel }) end end end Commands.object.addFireOnSquare = function(player, args) local sq = getCell():getGridSquare(args.x, args.y, args.z) IsoFireManager.StartFire(getCell(), sq, true, 100, 500); end Commands.object.addSmokeOnSquare = function(player, args) local sq = getCell():getGridSquare(args.x, args.y, args.z) IsoFireManager.StartSmoke(getCell(), sq, true, 100, 500) end Commands.object.addExplosionOnSquare = function(player, args) local sq = getCell():getGridSquare(args.x, args.y, args.z) IsoFireManager.explode(getCell(), sq, 100) end -- FIXME: getting objects by index is fragile, should have a unique ID local getThumpable = function(x, y, z, index) local sq = getCell():getGridSquare(x, y, z) if sq and index >= 0 and index < sq:getObjects():size() then o = sq:getObjects():get(index) if instanceof(o, 'IsoThumpable') then return o end end return nil end Commands.object.plaster = function(player, args) local o = getThumpable(args.x, args.y, args.z, args.index) if o then o:setSprite(args.sprite) o:setPaintable(true) o:transmitUpdatedSpriteToClients() o:sendObjectChange("paintable") end end Commands.object.addSheetRope = function(player, args) local sq = getCell():getGridSquare(args.x, args.y, args.z) if sq and args.index >= 0 and args.index < sq:getObjects():size() then local o = sq:getObjects():get(args.index) if instanceof(o, 'IsoWindow') or instanceof(o, 'IsoThumpable') then o:addSheetRope(player, args.itemType or "SheetRope") elseif IsoWindowFrame.isWindowFrame(o) then IsoWindowFrame.addSheetRope(o, player, args.itemType or "SheetRope") elseif instanceof(o, 'IsoObject') then if o:getSquare():getProperties():Is(IsoFlagType.HoppableN) or o:getSquare():getProperties():Is(IsoFlagType.HoppableW) then o:addSheetRope(player, args.itemType or "SheetRope") end else noise('not a window, window-frame, or thumpable'.. tostring(o)) for i=0,sq:getObjects():size()-1 do noise(i..' '..tostring(sq:getObjects():get(i))) end end else noise('sq is null or index is invalid') end end Commands.object.removeSheetRope = function(player, args) local sq = getCell():getGridSquare(args.x, args.y, args.z) if sq and args.index >= 0 and args.index < sq:getObjects():size() then local o = sq:getObjects():get(args.index) if instanceof(o, 'IsoWindow') or instanceof(o, 'IsoThumpable') then o:removeSheetRope(player) elseif IsoWindowFrame.isWindowFrame(o) then IsoWindowFrame.removeSheetRope(o, player) elseif instanceof(o, 'IsoObject') then if o:getSquare():getProperties():Is(IsoFlagType.HoppableN) or o:getSquare():getProperties():Is(IsoFlagType.HoppableW) then o:removeSheetRope(player) end else end end end Commands.object.addSheet = function(player, args) local sq = getCell():getGridSquare(args.x, args.y, args.z) if sq and args.index >= 0 and args.index < sq:getObjects():size() then local o = sq:getObjects():get(args.index) if instanceof(o, 'IsoDoor') or instanceof(o, 'IsoWindow') or instanceof(o, 'IsoThumpable') then o:addSheet(player) elseif IsoWindowFrame.isWindowFrame(o) then IsoWindowFrame.addSheet(o, player) else noise('expected door/window/thumpable got '..tostring(o)) end else noise('sq is null or index is invalid') end end Commands.object.removeSheet = function(player, args) local sq = getCell():getGridSquare(args.x, args.y, args.z) if sq and args.index >= 0 and args.index < sq:getObjects():size() then local o = sq:getObjects():get(args.index) if instanceof(o, 'IsoCurtain') or instanceof(o, 'IsoDoor') then o:removeSheet(player) else noise('expected curtain/door got '..tostring(o)) end else noise('sq is null or index is invalid') end end Commands.object.rotate = function(player, args) local sq = getCell():getGridSquare(args.x, args.y, args.z) if sq and args.index >= 0 and args.index < sq:getObjects():size() then local o = sq:getObjects():get(args.index) if instanceof(o, 'IsoMannequin') then o:rotate(args.dir) else noise('expected rotate-able got '..tostring(o)) end else noise('sq is null or index is invalid') end end Commands.object.openCloseCurtain = function(player, args) local sq = getCell():getGridSquare(args.x, args.y, args.z) if sq and args.index >= 0 and args.index < sq:getObjects():size() then local o = sq:getObjects():get(args.index) if instanceof(o, 'IsoDoor') then noise('isCurtainOpen='..tostring(o:isCurtainOpen())) if args.open ~= o:isCurtainOpen() then o:toggleCurtain() end else noise('expected door got '..tostring(o)) end else noise('sq is null or index is invalid') end end Commands.object.plumbObject = function(player, args) local sq = getCell():getGridSquare(args.x, args.y, args.z) if sq and args.index >= 0 and args.index < sq:getObjects():size() then local object = sq:getObjects():get(args.index) object:getModData().canBeWaterPiped = false object:setUsesExternalWaterSource(true) object:transmitModData() object:sendObjectChange('usesExternalWaterSource', { value = true }) else noise('sq is null or index is invalid') end end local function _getWallVineObject(square) if not square then return end for i=0,square:getObjects():size()-1 do local object = square:getObjects():get(i); local attached = object:getAttachedAnimSprite() if attached then for n=1,attached:size() do local sprite = attached:get(n-1) -- if sprite and sprite:getParentSprite() and sprite:getParentSprite():getProperties():Is(IsoFlagType.canBeCut) then if sprite and sprite:getParentSprite() and sprite:getParentSprite():getName() and luautils.stringStarts(sprite:getParentSprite():getName(), "f_wallvines_") then return object, n-1 end end end end end Commands.object.removeBush = function(player, args) local sq = getCell():getGridSquare(args.x, args.y, args.z) if sq then if args.wallVine then local object,index = _getWallVineObject(sq) if object and index then object:RemoveAttachedAnim(index) object:transmitUpdatedSpriteToClients() sq:removeErosionObject("WallVines") end -- and the top one, if any local topSq = getCell():getGridSquare(sq:getX(), sq:getY(), sq:getZ() + 1) local object,index = _getWallVineObject(topSq) if object and index then object:RemoveAttachedAnim(index) object:transmitUpdatedSpriteToClients() topSq:removeErosionObject("WallVines") end else for i=0,sq:getObjects():size()-1 do local object = sq:getObjects():get(i); if object:getProperties():Is(IsoFlagType.canBeCut) then sq:transmitRemoveItemFromSquare(object) if ZombRand(2) == 0 then sq:AddWorldInventoryItem("Base.TreeBranch", 0, 0, 0); end if ZombRand(1) == 0 then sq:AddWorldInventoryItem("Base.Twigs", 0, 0, 0); end i = i - 1; -- FIXME: illegal in Lua end end end else noise('sq is null') end end Commands.object.removeGrass = function(player, args) local sq = getCell():getGridSquare(args.x, args.y, args.z) if sq then for i=sq:getObjects():size(),1,-1 do local object = sq:getObjects():get(i-1) if object:getProperties() and object:getProperties():Is(IsoFlagType.canBeRemoved) then sq:transmitRemoveItemFromSquare(object) end end else noise('sq is null') end end Commands.object.shovelGround = function(player, args) local sq = getCell():getGridSquare(args.x, args.y, args.z) if sq then local type,o = ISShovelGroundCursor.GetDirtGravelSand(sq) if instanceof(o, 'IsoObject') then local shovelledSprites = o:hasModData() and o:getModData().shovelledSprites if shovelledSprites then o:RemoveAttachedAnims() -- remove blend tiles -- Restore the sprites present before dirt/gravel/sand was dumped. local sprite = getSprite(shovelledSprites[1]) if sprite then o:setSprite(sprite) end for i=2,#shovelledSprites do sprite = getSprite(shovelledSprites[i]) if sprite then o:AttachExistingAnim(sprite, 0, 0, false, 0, false, 0.0) end end o:getModData().shovelledSprites = nil o:getModData().pouredFloor = nil else -- First time taking dirt/gravel/sand. o:getModData().shovelled = true o:setSprite(getSprite("blends_natural_01_64")) o:RemoveAttachedAnims() -- remove blend tiles end o:transmitUpdatedSpriteToClients() -- remove vegetation for i=sq:getObjects():size(),1,-1 do o = sq:getObjects():get(i-1) -- FIXME: blends_grassoverlays tiles should have 'vegitation' flag if o:getSprite() and ( o:getSprite():getProperties():Is(IsoFlagType.canBeRemoved) or (o:getSprite():getProperties():Is(IsoFlagType.vegitation) and o:getType() ~= IsoObjectType.tree) or (o:getSprite():getName() and luautils.stringStarts(o:getSprite():getName(), "blends_grassoverlays"))) then sq:transmitRemoveItemFromSquare(o) end end else noise('expected IsoObject got '..tostring(o)) end else noise('sq is null') end end Commands.object.OnDestroyIsoThumpable = function(player, args) local thump = getThumpable(args.x, args.y, args.z, args.index) if thump then -- RainCollectorBarrel.OnDestroyIsoThumpable(thump, nil) -- TrapSystem.OnDestroyIsoThumpable(thump, nil) else noise('expected IsoThumpable, got '..tostring(thump)) end end Commands.object.triggerRemote = function(player, args) if args.id and args.range then IsoTrap.triggerRemote(player, args.id, args.range) else noise('missing args') end end local _getBarricadeAble = function(x, y, z, index) local sq = getCell():getGridSquare(x, y, z) if sq and index >= 0 and index < sq:getObjects():size() then local o = sq:getObjects():get(index) if instanceof(o, 'BarricadeAble') then return o end end return nil end Commands.object.barricade = function(player, args) local object = _getBarricadeAble(args.x, args.y, args.z, args.index) if object then local barricade = IsoBarricade.AddBarricadeToObject(object, player) if barricade then if args.isMetal then local metal = InventoryItemFactory.CreateItem('Base.SheetMetal') metal:setCondition(args.condition) barricade:addMetal(player, metal) barricade:transmitCompleteItemToClients() player:sendObjectChange('removeItemID', { id = args.itemID, type = "Base.SheetMetal" }) player:sendObjectChange('addXp', { perk = Perks.MetalWelding:index(), xp = 6, noMultiplier = true }) elseif args.isMetalBar then local metal = InventoryItemFactory.CreateItem('Base.MetalBar') metal:setCondition(args.condition) barricade:addMetalBar(player, metal) barricade:transmitCompleteItemToClients() player:sendObjectChange('removeItemID', { id = args.itemID, type = "Base.MetalBar" }) player:sendObjectChange('removeItemType', { type = 'Base.MetalBar', count = 2 }) player:sendObjectChange('addXp', { perk = Perks.MetalWelding:index(), xp = 6, noMultiplier = true }) else local plank = InventoryItemFactory.CreateItem('Base.Plank') plank:setCondition(args.condition) barricade:addPlank(player, plank) if barricade:getNumPlanks() == 1 then barricade:transmitCompleteItemToClients() else barricade:sendObjectChange('state') end player:sendObjectChange('removeItemID', { id = args.itemID, type = "Base.Plank" }) player:sendObjectChange('removeItemType', { type = 'Base.Nails', count = 2 }) player:sendObjectChange('addXp', { perk = Perks.Woodwork:index(), xp = 3, noMultiplier = true }) end end else noise('expected BarricadeAble') end end Commands.object.unbarricade = function(player, args) local object = _getBarricadeAble(args.x, args.y, args.z, args.index) if object and object:isBarricaded() then local barricade = object:getBarricadeForCharacter(player) if barricade then if barricade:isMetal() then local metal = barricade:removeMetal(nil) if metal then player:sendObjectChange('addItem', { item = metal }) end elseif barricade:isMetalBar() then local bar = barricade:removeMetalBar(nil) if bar then player:sendObjectChange('addItem', { item = bar }) local bar2 = InventoryItemFactory.CreateItem('Base.MetalBar') bar2:setCondition(bar:getCondition()) player:sendObjectChange('addItem', { item = bar2 }) local bar3 = InventoryItemFactory.CreateItem('Base.MetalBar') bar3:setCondition(bar:getCondition()) player:sendObjectChange('addItem', { item = bar3 }) end else local plank = barricade:removePlank(nil) if barricade:getNumPlanks() > 0 then barricade:sendObjectChange('state') end if plank then player:sendObjectChange('addItem', { item = plank }) player:sendObjectChange('addXp', { perk = Perks.Woodwork:index(), xp = 2, noMultiplier = true }) player:sendObjectChange('addXp', { perk = Perks.Strength:index(), xp = 2 }) end end end end end local _getTrashCan = function(x, y, z, index) local sq = getCell():getGridSquare(x, y, z) if sq and index >= 0 and index < sq:getObjects():size() then local object = sq:getObjects():get(index) if object:getSprite() and object:getSprite():getProperties():Is("IsTrashCan") then return object end end return nil end Commands.object.emptyTrash = function(player, args) local object = _getTrashCan(args.x, args.y, args.z, args.index) if object then object:getContainer():clear() if object:getOverlaySprite() then ItemPicker.updateOverlaySprite(object) end object:sendObjectChange('emptyTrash'); else print('expected trash can') end end Commands.object.setWaterAmount = function(player, args) -- This command works for *any* object that the player takes -- water from, including sinks and rain barrels. if args.amount < 0 then print('invalid water amount') return end local gs = getCell():getGridSquare(args.x, args.y, args.z) if not gs then print('square is nil') return end if args.index < 0 or args.index >= gs:getObjects():size() then print('invalid object') end local obj = gs:getObjects():get(args.index) local amount = obj:getWaterAmount() if amount == args.amount then return end obj:setWaterAmount(args.amount) obj:transmitModData() end Commands.object.takeWater = function(player, args) -- This takeWater command works for *any* object that the player takes -- water from, including sinks and rain barrels. local gs = getCell():getGridSquare(args.x, args.y, args.z) if gs and args.index >= 0 and args.index < gs:getObjects():size() then local gsSize = gs:getObjects():size()-1 for i=0,gsSize do local obj = gs:getObjects():get(gsSize-i) --go from highest object to lowest if obj:useWater(args.units) > 0 then obj:transmitModData() end end end end Commands.object.takeWaterFromItem = function(player, args) local gs = getCell():getGridSquare(args.x, args.y, args.z) if not gs then print('square is nil') return end for i=1,gs:getWorldObjects():size() do local obj = gs:getWorldObjects():get(i-1) if obj:getItem() and obj:getItem():getID() == args.itemID then obj:useWater(args.units) break end end end Commands.object.clearContainerExplore = function(player, args) local sq = getCell():getGridSquare(args.x, args.y, args.z) if not sq then return end if sq and args.index >= 0 and args.index < sq:getObjects():size() then local o = sq:getObjects():get(args.index) if o ~= nil then if args.containerIndex == -1 then local container = o:getContainer() container:setExplored(false) container:getSourceGrid():getRoom():getRoomDef():getProceduralSpawnedContainer():clear() else local container = o:getContainerByIndex(args.containerIndex) container:setExplored(false) container:getSourceGrid():getRoom():getRoomDef():getProceduralSpawnedContainer():clear() end end end end Commands.object.updateOverlaySprite = function(player, args) local sq = getCell():getGridSquare(args.x, args.y, args.z) if not sq then return end if sq and args.index >= 0 and args.index < sq:getObjects():size() then local o = sq:getObjects():get(args.index) if o ~= nil then if args.containerIndex == -1 then local container = o:getContainer() ItemPicker.updateOverlaySprite(container:getParent()) else local container = o:getContainerByIndex(args.containerIndex) ItemPicker.updateOverlaySprite(container:getParent()) end end end end Commands.fireplace = {} local getFireplace = function(x, y, z) local gs = getCell():getGridSquare(x, y, z) if not gs then return nil end for i=0,gs:getObjects():size()-1 do local o = gs:getObjects():get(i) if o and instanceof(o, 'IsoFireplace') then return o end end return nil end Commands.fireplace.addFuel = function(player, args) local fp = getFireplace(args.x, args.y, args.z) if fp then fp:addFuel(args.fuelAmt) fp:sendObjectChange('state') end end Commands.fireplace.setFuel = function(player, args) local fp = getFireplace(args.x, args.y, args.z) if fp then fp:setFuelAmount(args.fuelAmt) fp:sendObjectChange('state') end end Commands.fireplace.light = function(player, args) local fp = getFireplace(args.x, args.y, args.z) if fp then if args.fuelAmt then fp:addFuel(args.fuelAmt) end if not fp:isLit() and fp:hasFuel() then fp:setLit(true) end fp:sendObjectChange('state') end end Commands.fireplace.extinguish = function(player, args) local fp = getFireplace(args.x, args.y, args.z) if fp and fp:isLit() then fp:extinguish() fp:sendObjectChange('state') end end Commands.bbq = {} local getBarbecue = function(x, y, z) local gs = getCell():getGridSquare(x, y, z) if not gs then return nil end for i=0,gs:getObjects():size()-1 do local o = gs:getObjects():get(i) if o and instanceof(o, 'IsoBarbecue') then return o end end return nil end Commands.bbq.insertPropaneTank = function(player, args) local bbq = getBarbecue(args.x, args.y, args.z) if bbq then local tank = bbq:removePropaneTank() if tank then player:getSquare():AddWorldInventoryItem(tank, 0.5, 0.5, 0) end tank = InventoryItemFactory.CreateItem("Base.PropaneTank") tank:setUsedDelta(args.delta) bbq:setPropaneTank(tank) bbq:sendObjectChange('state') end end Commands.bbq.removePropaneTank = function(player, args) local bbq = getBarbecue(args.x, args.y, args.z) if bbq and bbq:hasPropaneTank() then local tank = bbq:removePropaneTank() bbq:sendObjectChange('state') player:getSquare():AddWorldInventoryItem(tank, 0.5, 0.5, 0) end end Commands.bbq.toggle = function(player, args) local bbq = getBarbecue(args.x, args.y, args.z) if bbq and bbq:hasFuel() then bbq:toggle() bbq:sendObjectChange('state') end end Commands.bbq.addFuel = function(player, args) local bbq = getBarbecue(args.x, args.y, args.z) if bbq then bbq:addFuel(args.fuelAmt) bbq:sendObjectChange('state') end end Commands.bbq.setFuel = function(player, args) local bbq = getBarbecue(args.x, args.y, args.z) if bbq then bbq:setFuelAmount(args.fuelAmt) bbq:sendObjectChange('state') end end Commands.bbq.light = function(player, args) local bbq = getBarbecue(args.x, args.y, args.z) if not bbq then return end if args.fuelAmt then bbq:addFuel(args.fuelAmt) end if bbq:hasFuel() and not bbq:isLit() then bbq:setLit(true) bbq:sendObjectChange('state') end end Commands.bbq.extinguish = function(player, args) local bbq = getBarbecue(args.x, args.y, args.z) if bbq and bbq:isLit() then bbq:extinguish() bbq:sendObjectChange('state') end end -- -- -- -- -- local function findCarBatteryCharger(x, y, z) local gs = getCell():getGridSquare(x, y, z) if not gs then return nil end for i=1,gs:getObjects():size() do local o = gs:getObjects():get(i-1) if o and instanceof(o, 'IsoCarBatteryCharger') then return o end end noise('no car-battery charger at '..x..','..y..','..z) return nil end Commands.carBatteryCharger = {} Commands.carBatteryCharger.connectBattery = function(player, args) local charger = findCarBatteryCharger(args.x, args.y, args.z) if not charger then return end local battery = charger:getBattery() if battery then noise('car-battery charger already has a battery') else player:sendObjectChange('removeItemID', { id = args.battery:getID(), type = args.battery:getFullType() }) charger:setBattery(args.battery) charger:sync() end end Commands.carBatteryCharger.removeBattery = function(player, args) local charger = findCarBatteryCharger(args.x, args.y, args.z) if not charger then return end local battery = charger:getBattery() if battery then charger:setBattery(nil) charger:sync() player:sendObjectChange('addItem', { item = battery }) else noise('car-battery charger does not have a battery') end end Commands.carBatteryCharger.activate = function(player, args) local charger = findCarBatteryCharger(args.x, args.y, args.z) if not charger then return end charger:setActivated(args.activate) charger:sync() end Commands.carBatteryCharger.place = function(player, args) local square = getCell():getGridSquare(args.x, args.y, args.z) for i=1,square:getObjects():size() do local o = square:getObjects():get(i-1) if o and instanceof(o, 'IsoCarBatteryCharger') then noise("can't place more than one car-battery charger on a square") return end end player:sendObjectChange('removeItemID', { id = args.item:getID(), type = args.item:getFullType() }) local charger = IsoCarBatteryCharger.new(args.item, getCell(), square) square:AddSpecialObject(charger) charger:transmitCompleteItemToClients() end Commands.carBatteryCharger.take = function(player, args) local charger = findCarBatteryCharger(args.x, args.y, args.z) if not charger then return end if charger:getBattery() then noise('cannot remove car-battery charger connected to a battery') return end local item = charger:getItem() if item then player:sendObjectChange('addItem', { item = item }) end charger:getSquare():transmitRemoveItemFromSquare(charger) end -- -- -- -- -- local function findClothingDryer(x, y, z) local gs = getCell():getGridSquare(x, y, z) if not gs then return nil end for i=1,gs:getObjects():size() do local obj = gs:getObjects():get(i-1) if obj and instanceof(obj, 'IsoClothingDryer') then return obj end end noise('no clothing dryer at '..x..','..y..','..z) return nil end Commands.clothingDryer = {} Commands.clothingDryer.toggle = function(player, args) local object = findClothingDryer(args.x, args.y, args.z) if not object then return end object:setActivated(not object:isActivated()) object:sendObjectChange("dryer.state") end -- -- -- -- -- local function findClothingWasher(x, y, z) local gs = getCell():getGridSquare(x, y, z) if not gs then return nil end for i=1,gs:getObjects():size() do local obj = gs:getObjects():get(i-1) if obj and instanceof(obj, 'IsoClothingWasher') then return obj end end noise('no clothing washer at '..x..','..y..','..z) return nil end Commands.clothingWasher = {} Commands.clothingWasher.toggle = function(player, args) local object = findClothingWasher(args.x, args.y, args.z) if not object then return end object:setActivated(not object:isActivated()) object:sendObjectChange("washer.state") end -- -- -- -- -- local function findComboWasherDryer(x, y, z) local gs = getCell():getGridSquare(x, y, z) if not gs then return nil end for i=1,gs:getObjects():size() do local obj = gs:getObjects():get(i-1) if obj and instanceof(obj, 'IsoCombinationWasherDryer') then return obj end end noise('no clothing washer at '..x..','..y..','..z) return nil end Commands.comboWasherDryer = {} Commands.comboWasherDryer.toggle = function(player, args) local object = findComboWasherDryer(args.x, args.y, args.z) if not object then return end object:setActivated(not object:isActivated()) object:sendObjectChange(object:isModeWasher() and "washer.state" or "dryer.state") end Commands.comboWasherDryer.setMode = function(player, args) local object = findComboWasherDryer(args.x, args.y, args.z) if not object then return end if args.mode == "washer" then object:setModeWasher() else object:setModeDryer() end object:sendObjectChange("mode") end -- -- -- -- -- Commands.player = {} Commands.player.wakeOther = function(player, args) local otherPlayer = getPlayerByOnlineID(args.id) if otherPlayer then otherPlayer:sendObjectChange("wakeUp") end end Commands.player.onHealthCheat = function(player, args) local otherPlayer = getPlayerByOnlineID(args.id) if otherPlayer and player:isAccessLevel("admin") then sendServerCommand(otherPlayer, "ISHealthPanel", "onHealthCheat", args) end end Commands.player.setWeight = function(player, args) local otherPlayer = getPlayerByOnlineID(args.id) if otherPlayer then sendServerCommand(otherPlayer, "player", "setWeight", args) end end Commands.player.syncWeight = function(player, args) local otherPlayer = getPlayerByOnlineID(args.id) if otherPlayer then sendServerCommand(otherPlayer, "player", "syncWeight", args) end end Commands.erosion = {}; Commands.erosion.disableForSquare = function(player, args) local sq = getCell():getGridSquare(args.x, args.y, args.z); if sq ~= nil then sq:disableErosion(); end end Commands.event = {} Commands.event.thunder = function(player, args) if args.isAll then local thunder = getClimateManager():getThunderStorm() local onlineUsers = getOnlinePlayers() for i=0, onlineUsers:size()-1 do local sq = onlineUsers:get(i):getSquare() thunder:triggerThunderEvent(sq:getX(), sq:getY(), true, true, true) end else getClimateManager():getThunderStorm():triggerThunderEvent(args.x, args.y, true, true, true) end end ClientCommands.OnClientCommand = function(module, command, player, args) if Commands[module] and Commands[module][command] then local argStr = '' for k,v in pairs(args) do argStr = argStr..' '..k..'='..tostring(v) end noise('received '..module..' '..command..' '..tostring(player)..argStr) Commands[module][command](player, args) end end Events.OnClientCommand.Add(ClientCommands.OnClientCommand)