--*********************************************************** --** THE INDIE STONE ** --*********************************************************** require "BuildingObjects/ISBuildingObject" require "FireFighting/FireFighting" ISExtinguishCursor = ISBuildingObject:derive("ISExtinguishCursor"); function ISExtinguishCursor:create(x, y, z, north, sprite) local playerObj = self.character if not FireFighting.isExtinguisher(self.extinguisher) or not playerObj:getInventory():contains(self.extinguisher) then self.extinguisher = FireFighting.getExtinguisher(playerObj) if not self.extinguisher then return end end x,y,z = self:getTopLeftOfSquares(x, y, z) local squares = self:getSquares(x, y, z) ISWorldObjectContextMenu.equip2(playerObj, playerObj:getPrimaryHandItem(), self.extinguisher, true); local usesPerSquare = FireFighting.getExtinguisherUses(self.extinguisher) ISTimedActionQueue.add(ISPutOutFire:new(playerObj, squares, self.extinguisher, usesPerSquare, 50)); end function ISExtinguishCursor:walkTo(x, y, z) local playerObj = self.character x,y,z = self:getTopLeftOfSquares(x, y, z) local squares = self:getSquares(x, y, z) if self.character:getJoypadBind() == -1 then local closestSq = self:getClosestSquare(squares) if playerObj:getCurrentSquare() == closestSq then return true end local adjacent = AdjacentFreeTileFinder.Find(closestSq, self.character) if not adjacent then return false end ISTimedActionQueue.add(ISWalkToTimedAction:new(playerObj, adjacent)) end return true end function ISExtinguishCursor:isValid(square) local x,y,z = self:getTopLeftOfSquares(square:getX(), square:getY(), square:getZ()) return self:isValidArea(x, y, z) end function ISExtinguishCursor:isValidArea(x, y, z) -- If the current item was used up, find another if not FireFighting.isExtinguisher(self.extinguisher) or not self.character:getInventory():contains(self.extinguisher) then self.extinguisher = FireFighting.getExtinguisher(self.character) if not self.extinguisher then return false end end local squares = self:getSquares(x, y, z) for _,square2 in ipairs(squares) do if square2:isCouldSee(self.character:getPlayerNum()) then if FireFighting.isSquareToExtinguish(square2) then return true end end end return false end function ISExtinguishCursor:isRunningAction() local actionQueue = ISTimedActionQueue.getTimedActionQueue(self.character); return actionQueue and actionQueue.queue and actionQueue.queue[1] end function ISExtinguishCursor:getTopLeftOfSquares(x, y, z) if self.character:getJoypadBind() ~= -1 then local cx,cy = math.floor(self.character:getX()), math.floor(self.character:getY()) if self.character:isOnFire() then return cx,cy,z end local dir = self.character:getDir() if dir == IsoDirections.N then x,y = cx, cy-2 elseif dir == IsoDirections.NE then x,y = cx+1, cy-2 elseif dir == IsoDirections.E then x,y = cx+1, cy elseif dir == IsoDirections.SE then x,y = cx+1, cy+1 elseif dir == IsoDirections.S then x,y = cx, cy+1 elseif dir == IsoDirections.SW then x,y = cx-2, cy+1 elseif dir == IsoDirections.W then x,y = cx-2, cy elseif dir == IsoDirections.NW then x,y = cx-2, cy-2 end end return x,y,z end function ISExtinguishCursor:render(x, y, z, square) if self:isRunningAction() then return end x,y,z = self:getTopLeftOfSquares(x, y, z) local bValid = self:isValidArea(x, y, z) if bValid then renderIsoCircle(x + 1, y + 1, z, 1, getCore():getGoodHighlitedColor():getR(),getCore():getGoodHighlitedColor():getG(),getCore():getGoodHighlitedColor():getB(), 0.5, 1) else renderIsoCircle(x + 1, y + 1, z, 1, getCore():getBadHighlitedColor():getR(),getCore():getBadHighlitedColor():getG(),getCore():getBadHighlitedColor():getB(), 0.5, 1) end --[[ if not self.floorSprite then self.floorSprite = IsoSprite.new() self.floorSprite:LoadFramesNoDirPageSimple('media/ui/FloorTileCursor.png') end --]] local squares = self:getSquares(x, y, z) for _,square2 in ipairs(squares) do if not bValid or not square2:isCouldSee(self.character:getPlayerNum()) then -- self.floorSprite:RenderGhostTileRed(square2:getX(), square2:getY(), square2:getZ()) else -- self.floorSprite:RenderGhostTileColor(square2:getX(), square2:getY(), square2:getZ(), 0, 1, 0, 0.8) local objects = self:getFireObjects(square2) for _,object in ipairs(objects) do if not ISExtinguishCursor._colorInfo then ISExtinguishCursor._colorInfo = ColorInfo.new(1.0, 0.0, 0.0, 1.0) end object:setHighlighted(true) object:setHighlightColor(ISExtinguishCursor._colorInfo) --[[ for j=1,object:getAttachedAnimSprite():size() do local spriteInst = object:getAttachedAnimSprite():get(j-1) if spriteInst then spriteInst:RenderGhostTileColor(square2:getX(), square2:getY(), square2:getZ(), 1.0, 0.0, 0.0, 1.0) end end --]] end end end if self.character:getJoypadBind() ~= -1 then return end if #squares == 0 then return end local closestSq = self:getClosestSquare(squares) local playerSq = self.character:getCurrentSquare() if playerSq == closestSq then renderIsoCircle(playerSq:getX() + 0.5, playerSq:getY() + 0.5, playerSq:getZ(), 0.5, 1, 1, 1, 0.8, 1) -- self.floorSprite:RenderGhostTileColor(playerSq:getX(), playerSq:getY(), playerSq:getZ(), 1, 1, 1, 0.8) else local adjacent = AdjacentFreeTileFinder.Find(closestSq, self.character) if adjacent then renderIsoCircle(adjacent:getX() + 0.5, adjacent:getY() + 0.5, adjacent:getZ(), 0.5, 1, 1, 1, 0.8, 1) -- self.floorSprite:RenderGhostTileColor(adjacent:getX(), adjacent:getY(), adjacent:getZ(), 1, 1, 1, 0.8) end end end function ISExtinguishCursor:onJoypadPressButton(joypadIndex, joypadData, button) if button == Joypad.AButton or button == Joypad.BButton then return ISBuildingObject.onJoypadPressButton(self, joypadIndex, joypadData, button) end end function ISExtinguishCursor:getAPrompt() return self.canBeBuild and getText("ContextMenu_ExtinguishFire") or nil end function ISExtinguishCursor:getLBPrompt() return nil end function ISExtinguishCursor:getRBPrompt() return nil end -- If you want to decrease/increase the area affected, do it here. function ISExtinguishCursor:getSquares(x, y, z) local squares = {} local square = getCell():getGridSquare(x, y, z) --[[ if square then table.insert(squares, square) end for dy = -1,1 do for dx = -1,1 do if dx ~= 0 or dy ~= 0 then local square = getCell():getGridSquare(x+dx, y+dy, z) if square then table.insert(squares, square) end end end end --]] local square = getCell():getGridSquare(x, y, z) if square then table.insert(squares, square) end square = getCell():getGridSquare(x + 1, y, z) if square then table.insert(squares, square) end square = getCell():getGridSquare(x, y + 1, z) if square then table.insert(squares, square) end square = getCell():getGridSquare(x + 1, y + 1, z) if square then table.insert(squares, square) end return squares end function ISExtinguishCursor:getClosestSquare(squares) local closest = nil local closestDist = 1000000 for _,square2 in ipairs(squares) do local dist = IsoUtils.DistanceTo(self.character:getX(), self.character:getY(), square2:getX() + 0.5, square2:getY() + 0.5) if dist < closestDist then closest = square2 closestDist = dist end end return closest end function ISExtinguishCursor:getFireObjects(square) local objects = {} for i=1,square:getObjects():size() do local object = square:getObjects():get(i-1) if instanceof(object, "IsoFire") and not object:isPermanent() then table.insert(objects, object) end end --[[ -- Would like to higlight burning characters, but: -- 1) Need proper positioning of the attached fire sprite -- 2) Can't render character 'sprite' because it might be a model or -- multiple sprites for i=1,square:getMovingObjects():size() do local chr = square:getMovingObjects():get(i-1) if instanceof(chr, "IsoGameCharacter") and chr:isOnFire() then table.insert(objects, chr) end end --]] return objects end function ISExtinguishCursor:new(character, extinguisher) local o = {} setmetatable(o, self) self.__index = self o:init() o.character = character o.player = character:getPlayerNum() o.skipBuildAction = true o.noNeedHammer = true o.skipWalk = true o.renderFloorHelper = true -- o.dragNilAfterPlace = true o.extinguisher = extinguisher return o end