--*********************************************************** --** THE INDIE STONE ** --*********************************************************** require "BuildingObjects/ISBuildingObject" ISPaintCursor = ISBuildingObject:derive("ISPaintCursor"); local PaintColor = { PaintBlack = {r=0.20,g=0.20,b=0.20}; PaintBlue = {r=0.35,g=0.35,b=0.80}; PaintBrown = {r=0.45,g=0.23,b=0.11}; PaintCyan = {r=0.50,g=0.80,b=0.80}; PaintGreen = {r=0.41,g=0.80,b=0.41}; PaintGrey = {r=0.50,g=0.50,b=0.50}; PaintLightBlue = {r=0.55,g=0.55,b=0.87}; PaintLightBrown = {r=0.59,g=0.44,b=0.21}; PaintOrange = {r=0.79,g=0.44,b=0.19}; PaintPink = {r=0.81,g=0.60,b=0.60}; PaintPurple = {r=0.61,g=0.40,b=0.63}; PaintRed = {r=0.63,g=0.10,b=0.10}; PaintTurquoise = {r=0.49,g=0.70,b=0.80}; PaintWhite = {r=0.92,g=0.92,b=0.92}; PaintYellow = {r=0.84,g=0.78,b=0.30}; } function ISPaintCursor:create(x, y, z, north, sprite) local sq = getWorld():getCell():getGridSquare(x, y, z) local playerObj = self.character local playerInv = playerObj:getInventory() local object = self:getObjectList()[self.objectIndex] local args = self.args if self.action == "paintSign" then local paintCan = nil if not ISBuildMenu.cheat then local paintBrush = playerInv:getFirstTypeRecurse("Paintbrush") ISWorldObjectContextMenu.transferIfNeeded(playerObj, paintBrush) paintCan = playerInv:getFirstTypeRecurse(args.paintType) ISWorldObjectContextMenu.transferIfNeeded(playerObj, paintCan) end ISTimedActionQueue.add(ISPaintSignAction:new(playerObj, object, paintCan, args.sign, args.r, args.g, args.b, 100)) end if self.action == "paintThump" then local paintCan = nil if not ISBuildMenu.cheat then local paintBrush = playerInv:getFirstTypeRecurse("Paintbrush") ISWorldObjectContextMenu.transferIfNeeded(playerObj, paintBrush) paintCan = playerInv:getFirstTypeRecurse(args.paintType) ISWorldObjectContextMenu.transferIfNeeded(playerObj, paintCan) end ISTimedActionQueue.add(ISPaintAction:new(playerObj, object, paintCan, args.paintType, 100)) end if self.action == "plaster" then local plaster = nil if not ISBuildMenu.cheat then plaster = playerInv:getFirstTypeRecurse("BucketPlasterFull") ISWorldObjectContextMenu.transferIfNeeded(playerObj, plaster) end ISTimedActionQueue.add(ISPlasterAction:new(playerObj, object, plaster, 100)) end end function ISPaintCursor:walkTo(x, y, z) local object = self:getObjectList()[self.objectIndex] self.isWallLike = self:_isWall(object) or self:_isDoorFrame(object) return ISBuildingObject.walkTo(self, x, y, z) end function ISPaintCursor:_isWall(object) if object and object:getProperties() then return object:getProperties():Is(IsoFlagType.cutW) or object:getProperties():Is(IsoFlagType.cutN) end return false end function ISPaintCursor:_isDoorFrame(object) return object and (object:getType() == IsoObjectType.doorFrW or object:getType() == IsoObjectType.doorFrN) end function ISPaintCursor:rotateKey(key) if key == getCore():getKey("Rotate building") then self.objectIndex = self.objectIndex + 1 local objects = self:getObjectList() if self.objectIndex > #objects then self.objectIndex = 1 end end end function ISPaintCursor:isValid(square) self.renderX = square:getX() self.renderY = square:getY() self.renderZ = square:getZ() return #self:getObjectList() > 0 end function ISPaintCursor:render(x, y, z, square) if not self.floorSprite then self.floorSprite = IsoSprite.new() self.floorSprite:LoadFramesNoDirPageSimple('media/ui/FloorTileCursor.png') end local hc = getCore():getGoodHighlitedColor() if not self:isValid(square) then hc = getCore():getBadHighlitedColor() end self.floorSprite:RenderGhostTileColor(x, y, z, hc:getR(), hc:getG(), hc:getB(), 0.8) if self.currentSquare ~= square then self.objectIndex = 1 self.currentSquare = square end self.renderX = x self.renderY = y self.renderZ = z local objects = self:getObjectList() if self.objectIndex >= 1 and self.objectIndex <= #objects then local object = objects[self.objectIndex] local color = {r=0.8, g=0.8, b=0.8} if self.action ~= "plaster" then color = PaintColor[self.args.paintType] if not color then color = {r=1,g=0,b=0} end end if self.action == "paintSign" then -- if not self.signSprite then local sign = self.args.sign if object:getProperties():Is("WallW") then sign = sign + 8; end self.signSprite = IsoSprite.new() self.signSprite:LoadFramesNoDirPageSimple("constructedobjects_signs_01_" .. sign) -- end self.signSprite:RenderGhostTileColor(x, y, z, color.r, color.g, color.b, 1.0) elseif self.action == "plaster" then local north = (object:getNorth() and "North") or "" local modData = object:getModData() local spriteName = Painting[modData.wallType]["plasterTile" .. north] self.plasterSprite = IsoSprite.new() self.plasterSprite:LoadFramesNoDirPageSimple(spriteName) self.plasterSprite:RenderGhostTile(x, y, z) else local xOffset = 0 local yOffset = object:getRenderYOffset() object:getSprite():RenderGhostTileColor(x, y, z, xOffset, yOffset * Core.getTileScale(), color.r, color.g, color.b, 0.8) end end end function ISPaintCursor:onJoypadPressButton(joypadIndex, joypadData, button) local playerObj = getSpecificPlayer(joypadData.player) if button == Joypad.AButton or button == Joypad.BButton then return ISBuildingObject.onJoypadPressButton(self, joypadIndex, joypadData, button) end if button == Joypad.RBumper then self.objectIndex = self.objectIndex + 1 local objects = self:getObjectList() if self.objectIndex > #objects then self.objectIndex = 1 end end if button == Joypad.LBumper then self.objectIndex = self.objectIndex - 1 if self.objectIndex < 1 then local objects = self:getObjectList() self.objectIndex = #objects end end end function ISPaintCursor:getAPrompt() if #self:getObjectList() > 0 then if self.action == "paintSign" then return getText("ContextMenu_PaintSign") end if self.action == "paintThump" then return getText("ContextMenu_Paint") end if self.action == "plaster" then return getText("ContextMenu_Plaster") end end return nil end function ISPaintCursor:getLBPrompt() if #self:getObjectList() > 1 then return "Previous Object" end return nil end function ISPaintCursor:getRBPrompt() if #self:getObjectList() > 1 then return "Next Object" end return nil end function ISPaintCursor:canPaint(object) if not object or not object:getSquare() or not object:getSprite() then return false end if not object:getSquare():isCouldSee(self.player) then return false end if not self:hasItems() then return false end local props = object:getProperties() if self.action == "paintSign" then if props:Is("WallN") or props:Is("WallW") then return true end end if self.action == "paintThump" then if instanceof(object, "IsoThumpable") and object:isPaintable() then local modData = object:getModData() return Painting[modData.wallType][self.args.paintType] ~= nil end if props and props:Is("IsPaintable") then local wallType = props:Val("PaintingType") if Painting[wallType] ~= nil and Painting[wallType][self.args.paintType] ~= nil then return true end if OtherPainting[wallType] ~= nil and OtherPainting[wallType][self.args.paintType] ~= nil then return true end end end if self.action == "plaster" then if instanceof(object, "IsoThumpable") and object:canBePlastered() then return true end end return false end function ISPaintCursor:hasItems() local playerObj = self.character local playerInv = playerObj:getInventory() if self.action == "paintSign" or self.action == "paintThump" then if not ISBuildMenu.cheat then local paintBrush = playerInv:getFirstTypeRecurse("Paintbrush") local paintCan = playerInv:getFirstTypeRecurse(self.args.paintType) return paintBrush ~= nil and paintCan ~= nil end return true end if self.action == "plaster" then if not ISBuildMenu.cheat then local plaster = playerInv:getFirstTypeRecurse("BucketPlasterFull") return plaster ~= nil end return true end error "unhandled action in ISPaintCursor:hasItems()" end function ISPaintCursor:getObjectList() local square = getCell():getGridSquare(self.renderX, self.renderY, self.renderZ) if not square then return {} end local objects = {} for i = square:getObjects():size(),1,-1 do local object = square:getObjects():get(i-1) if self:canPaint(object) then table.insert(objects, object) end end return objects end function ISPaintCursor:new(character, action, args) local o = {} setmetatable(o, self) self.__index = self o:init() o.character = character o.player = character:getPlayerNum() o.skipBuildAction = true o.noNeedHammer = false o.skipWalk = true o.renderFloorHelper = true -- o.dragNilAfterPlace = true o.action = action o.args = args o.objectIndex = 1 o.renderX = -1 o.renderY = -1 o.renderZ = -1 return o end