--*********************************************************** --** ROBERT JOHNSON ** --*********************************************************** ISDoubleDoor = ISBuildingObject:derive("ISDoubleDoor"); --************************************************************************-- --** ISDoubleDoor:new --** --************************************************************************-- function ISDoubleDoor:create(x, y, z, north, sprite) local cell = getWorld():getCell(); local square = cell:getGridSquare(x, y, z); local xa, ya = self:getSquare2Pos(square, north) local xb, yb = self:getSquare3Pos(square, north) local xc, yc = self:getSquare4Pos(square, north) local spriteAName = self.sprite2; local spriteBName = self.sprite3; local spriteCName = self.sprite4; -- if we're not north we also change our sprite if self.north then spriteAName = self.northSprite2; spriteBName = self.northSprite3; spriteCName = self.northSprite4; end self:addDoorPart(x,y,z,north,sprite,1); self:addDoorPart(xa,ya,z,north,spriteAName,2); self:addDoorPart(xb,yb,z,north,spriteBName,3); self:addDoorPart(xc,yc,z,north,spriteCName,4); end function ISDoubleDoor:addDoorPart(x,y,z,north,sprite,index) local cell = getWorld():getCell(); self.sq = cell:getGridSquare(x, y, z); if self:partExists(self.sq, index) then return end self.javaObject = IsoThumpable.new(cell, self.sq, sprite, north, self); local consumedItems = {}; if index == 1 then consumedItems = buildUtil.consumeMaterial(self); end buildUtil.setInfo(self.javaObject, self); self:overrideModData(index); self.javaObject:setMaxHealth(self:getHealth()); self.javaObject:setHealth(self.javaObject:getMaxHealth()); local isGate = self.name and self.name:contains("Gate") local breakSound = isGate and "WoodGateBreak" or "WoodDoorBreak" if self.modData and self.modData["use:Base.BlowTorch"] then breakSound = isGate and "MetalGateBreak" or "MetalDoorBreak"; end self.javaObject:setBreakSound(breakSound); self.sq:AddSpecialObject(self.javaObject); -- set the key id if we had one for _,item in ipairs(consumedItems) do if item:getType() == "Doorknob" and item:getKeyId() ~= -1 then self.javaObject:setKeyId(item:getKeyId(), false) end end self.javaObject:transmitCompleteItemToServer(); end function ISDoubleDoor:overrideModData(spriteIndex) local modData = self.javaObject:getModData(); local modData2 = copyTable(modData); for k,v in pairs(modData2) do if luautils.stringStarts(k, "need:") then local itemFullType = luautils.split(k, ":")[2]; local count = tonumber(v); if itemFullType == "Base.Doorknob" then if spriteIndex == 2 or spriteIndex == 3 then modData[k] = "1"; else modData[k] = nil; end elseif itemFullType == "Base.Hinge" then if spriteIndex == 1 or spriteIndex == 4 then modData[k] = tostring(math.floor(count / 2 + 0.01)); else modData[k] = nil; end else local count2 = math.floor(count / 4 + 0.01); if (count % 4 ~= 0) and (spriteIndex <= count % 4) then count2 = count2 + 1; end if count2 == 0 then modData[k] = nil; else modData[k] = tostring(count2); end end end end end function ISDoubleDoor:new(sprite, spriteIndex) local o = {}; setmetatable(o, self); self.__index = self; o:init(); o:setSprite(sprite .. spriteIndex); o.sprite2 = sprite .. spriteIndex+1; o.sprite3 = sprite .. spriteIndex-8; o.sprite4 = sprite .. spriteIndex-7; o.northSprite = sprite .. spriteIndex-6; o.northSprite2 = sprite .. spriteIndex-5; o.northSprite3 = sprite .. spriteIndex+2; o.northSprite4 = sprite .. spriteIndex+3; o.isDoor = true; o.thumpDmg = 5; o.name = "Double Door"; o.isWallLike = true return o; end -- return the health of the new wall, it's 300 + 100 per carpentry lvl function ISDoubleDoor:getHealth() return 300 + buildUtil.getWoodHealth(self); end function ISDoubleDoor:isValid(square) if not self:haveMaterial(square) then return false end if not square:hasFloor(self.north) then return false; end if not self:partExists(square, 1) and not square:isFreeOrMidair(false) then return false end if square:isVehicleIntersecting() then return false end local xa, ya = self:getSquare2Pos(square, self.north) local xb, yb = self:getSquare3Pos(square, self.north) local xc, yc = self:getSquare4Pos(square, self.north) local squareA = getCell():getGridSquare(xa, ya, square:getZ()) local squareB = getCell():getGridSquare(xb, yb, square:getZ()) local squareC = getCell():getGridSquare(xc, yc, square:getZ()) if (not squareA) or (not squareB) or (not squareC) then return false end local existsA = self:partExists(squareA, 2) local existsB = self:partExists(squareB, 3) local existsC = self:partExists(squareC, 4) if not existsA and not buildUtil.canBePlace(self, squareA) then return false end if not existsB and not buildUtil.canBePlace(self, squareB) then return false end if not existsC and not buildUtil.canBePlace(self, squareC) then return false end -- don't allow double doors inside buildings to avoid weird conflicts -- Allowing this as it prevented building double doors on the outer walls of buildings (to replace a destroyed garage door, for example). -- I don't remember what the 'weird conflicts' inside buildings were. -- I added a check for walls between each part in IsoDoor.isDoubleDoorObstructed(). -- if square:getBuilding() or squareA:getBuilding() or squareB:getBuilding() or squareC:getBuilding() then return false; end if squareA:isSomethingTo(square) then return false end if squareB:isSomethingTo(squareA) then return false end if squareC:isSomethingTo(squareB) then return false end if buildUtil.stairIsBlockingPlacement(square, true, self.north) then return false end if buildUtil.stairIsBlockingPlacement(squareA, true, self.north) then return false end if buildUtil.stairIsBlockingPlacement(squareB, true, self.north) then return false end if buildUtil.stairIsBlockingPlacement(squareC, true, self.north) then return false end return true; end -- used to render more tile for example function ISDoubleDoor:render(x, y, z, square) if not self:partExists(square, 1) then -- render the first part local spriteName = self:getSprite() local sprite = IsoSprite.new() sprite:LoadFramesNoDirPageSimple(spriteName) -- if the square is free and our item can be build local spriteFree = ISBuildingObject.isValid(self, square) if buildUtil.stairIsBlockingPlacement(square, true, self.north) then spriteFree = false end if spriteFree then sprite:RenderGhostTile(x, y, z); else sprite:RenderGhostTileRed(x, y, z); end end -- name of our 3 sprites needed for the rest of the door local spriteAName = self.sprite2; local spriteBName = self.sprite3; local spriteCName = self.sprite4; local spriteAFree = true; local spriteBFree = true; local spriteCFree = true; -- we get the x and y of our next tile (depend if we're placing the door north or not) local xa, ya = self:getSquare2Pos(square, self.north) local xb, yb = self:getSquare3Pos(square, self.north) local xc, yc = self:getSquare4Pos(square, self.north) -- if we're not north we also change our sprite if self.north then spriteName = self.northSprite; spriteAName = self.northSprite2; spriteBName = self.northSprite3; spriteCName = self.northSprite4; end local squareA = getCell():getGridSquare(xa, ya, z); if squareA == nil and getWorld():isValidSquare(xa, ya, z) then squareA = IsoGridSquare.new(getCell(), nil, xa, ya, z); getCell():ConnectNewSquare(squareA, false); end local squareB = getCell():getGridSquare(xb, yb, z); if squareB == nil and getWorld():isValidSquare(xb, yb, z) then squareB = IsoGridSquare.new(getCell(), nil, xb, yb, z); getCell():ConnectNewSquare(squareB, false); end local squareC = getCell():getGridSquare(xc, yc, z); if squareC == nil and getWorld():isValidSquare(xc, yc, z) then squareC = IsoGridSquare.new(getCell(), nil, xc, yc, z); getCell():ConnectNewSquare(squareC, false); end local existsA = self:partExists(squareA, 2) local existsB = self:partExists(squareB, 3) local existsC = self:partExists(squareC, 4) -- test if the square are free to add our door if not existsA and not buildUtil.canBePlace(self, squareA) then spriteAFree = false; end if not existsB and not buildUtil.canBePlace(self, squareB) then spriteBFree = false; end if not existsC and not buildUtil.canBePlace(self, squareC) then spriteCFree = false; end if squareA and (squareA:isSomethingTo(square) or buildUtil.stairIsBlockingPlacement(squareA, true, self.north)) then spriteAFree = false end if squareB and (squareB:isSomethingTo(squareA) or buildUtil.stairIsBlockingPlacement(squareB, true, self.north)) then spriteBFree = false end if squareC and (squareC:isSomethingTo(squareB) or buildUtil.stairIsBlockingPlacement(squareC, true, self.north)) then spriteCFree = false end -- render each parts if not existsA then local spriteA = IsoSprite.new(); spriteA:LoadFramesNoDirPageSimple(spriteAName); if spriteAFree then spriteA:RenderGhostTile(xa, ya, z); else spriteA:RenderGhostTileRed(xa, ya, z); end end if not existsB then local spriteB = IsoSprite.new(); spriteB:LoadFramesNoDirPageSimple(spriteBName); if spriteBFree then spriteB:RenderGhostTile(xb, yb, z); else spriteB:RenderGhostTileRed(xb, yb, z); end end if not existsC then local spriteC = IsoSprite.new(); spriteC:LoadFramesNoDirPageSimple(spriteCName); if spriteCFree then spriteC:RenderGhostTile(xc, yc, z); else spriteC:RenderGhostTileRed(xc, yc, z); end end end function ISDoubleDoor:getSquare2Pos(square, north) local x = square:getX() local y = square:getY() local z = square:getZ() if north then x = x + 1 else y = y - 1 end return x, y, z end function ISDoubleDoor:getSquare3Pos(square, north) local x = square:getX() local y = square:getY() local z = square:getZ() if north then x = x + 2 else y = y - 2 end return x, y, z end function ISDoubleDoor:getSquare4Pos(square, north) local x = square:getX() local y = square:getY() local z = square:getZ() if north then x = x + 3 else y = y - 3 end return x, y, z end function ISDoubleDoor:partExists(square, index) local spriteName if self.north then if index == 1 then spriteName = self.northSprite elseif index == 2 then spriteName = self.northSprite2 elseif index == 3 then spriteName = self.northSprite3 else spriteName = self.northSprite4 end else if index == 1 then spriteName = self.sprite elseif index == 2 then spriteName = self.sprite2 elseif index == 3 then spriteName = self.sprite3 else spriteName = self.sprite4 end end local objects = square:getSpecialObjects() for i=1,objects:size() do local object = objects:get(i-1) if IsoDoor.getDoubleDoorIndex(object) == index and object:getNorth() == self.north and not object:IsOpen() and object:getSprite():getName() == spriteName then return true end end return false end