--*********************************************************** --** THE INDIE STONE ** --*********************************************************** if isClient() then return end require "Map/SGlobalObject" SCampfireGlobalObject = SGlobalObject:derive("SCampfireGlobalObject") function SCampfireGlobalObject:new(luaSystem, globalObject) local o = SGlobalObject.new(self, luaSystem, globalObject) return o; end function SCampfireGlobalObject:initNew() self.exterior = true self.isLit = false self.fuelAmt = 0 self.radius = -1 self.spriteName = "camping_01_6" end function SCampfireGlobalObject:stateFromIsoObject(isoObject) local square = isoObject:getSquare() self:fromObject(isoObject) self.exterior = square:isOutside() self.spriteName = isoObject:getSpriteName() or "" self:processContainerItems() self.radius = -1 self:changeFireLvl() end function SCampfireGlobalObject:stateToIsoObject(isoObject) local square = isoObject:getSquare() self.exterior = square:isOutside() self.spriteName = isoObject:getSpriteName() or "" self:toModData(isoObject:getModData()) self:processContainerItems() self.radius = -1 self:changeFireLvl() end function SCampfireGlobalObject:getObject() return self:getIsoObject() end function SCampfireGlobalObject:getContainer() local isoObject = self:getIsoObject() if not isoObject then return nil end return isoObject:getContainer() end function SCampfireGlobalObject:processContainerItems() local container = self:getContainer() if not container then return end container:addItemsToProcessItems() end function SCampfireGlobalObject:getFireObject() local square = self:getSquare() if square then for i = 0,square:getObjects():size()-1 do local fireObj = square:getObjects():get(i) if instanceof(fireObj, 'IsoFire') and fireObj:isPermanent() then return fireObj end end end return nil end function SCampfireGlobalObject:addObject() if self:getObject() then return end local square = self:getSquare() if not square then return end local isoObject = IsoObject.new(square, "camping_01_6", "Campfire") isoObject:setOutlineOnMouseover(true) self:toModData(isoObject:getModData()) square:AddTileObject(isoObject) self:noise('added campfire IsoObject at index='..isoObject:getObjectIndex()) end function SCampfireGlobalObject:removeObject() local square = self:getSquare() local isoObject = self:getIsoObject() if not square or not isoObject then return end square:transmitRemoveItemFromSquare(isoObject) end function SCampfireGlobalObject:setSpriteName(spriteName) if spriteName == self.spriteName then return end self:noise('changed campfire sprite from='..self.spriteName..' to '..spriteName..' '..self.x..','..self.y..','..self.z) self.spriteName = spriteName local isoObject = self:getIsoObject() if not isoObject then return end isoObject:setSprite(spriteName) end function SCampfireGlobalObject:addContainer() local square = self:getSquare() if not square then return end local isoObject = self:getIsoObject() if not isoObject then return end local container = isoObject:getContainer() if container then return end container = ItemContainer.new("campfire", square, isoObject, 1, 1) container:setExplored(true) isoObject:setContainer(container) end function SCampfireGlobalObject:addFireObject() if self:getFireObject() then return end local square = self:getSquare() if not square then return end -- Create a 'permanent' IsoFire object. It won't spread to adjacent squares but will burn. local fireObj = IsoFire.new(getCell(), square) fireObj:AttachAnim("Fire", "01", 4, IsoFireManager.FireAnimDelay, -16, -78, true, 0, false, 0.7, IsoFireManager.FireTintMod) square:AddTileObject(fireObj) self:noise('added campfire IsoFire at index='..fireObj:getObjectIndex()) end function SCampfireGlobalObject:removeFireObject() local fireObj = self:getFireObject() if not fireObj then return end local square = self:getSquare() self:noise('removed campfire IsoFire at index='..fireObj:getObjectIndex()) square:transmitRemoveItemFromSquare(fireObj) square:getProperties():UnSet(IsoFlagType.burning) end function SCampfireGlobalObject:transferItemsToGround() local square = self:getSquare() local isoObject = self:getIsoObject() if not square or not isoObject then return end local container = isoObject:getContainer() if container then while container:getItems():size() > 0 do local item = container:getItems():get(0) container:DoRemoveItem(item) square:AddWorldInventoryItem(item, 0.0, 0.0, 0.0) end end end function SCampfireGlobalObject:fromModData(modData) self.exterior = modData.exterior self.isLit = modData.isLit or false self.fuelAmt = modData.fuelAmt end function SCampfireGlobalObject:toModData(modData) modData.exterior = self.exterior modData.isLit = self.isLit modData.fuelAmt = self.fuelAmt end function SCampfireGlobalObject:fromObject(isoObject) self:fromModData(isoObject:getModData()) end function SCampfireGlobalObject:syncIsoObject() self.transmitObject = false if not self:getIsoObject() then self:addObject() self.transmitObject = true end end function SCampfireGlobalObject:syncSprite() self.transmitSprite = false local spriteName if not self.isLit then spriteName = "camping_01_6" -- elseif self.fuelAmt <= 3 * 60 then -- spriteName = "camping_01_4" else spriteName = "camping_01_5" end if spriteName ~= self.spriteName then self:setSpriteName(spriteName) self.transmitSprite = true end end function SCampfireGlobalObject:syncModData() local isoObject = self:getIsoObject() if isoObject then self:toModData(isoObject:getModData()) end end function SCampfireGlobalObject:syncContainer() self.transmitContainer = false local isoObject = self:getIsoObject() local container = self:getContainer() if not container then self:addContainer() self.transmitContainer = isServer() elseif isoObject:getContainerCount() ~= 1 or container:getType() ~= "campfire" then for i=1,isoObject:getContainerCount() do container = isoObject:getContainerByIndex(i-1) container:removeItemsFromProcessItems() container:removeAllItems() end isoObject:removeAllContainers() self:addContainer() self.transmitContainer = isServer() end container = self:getContainer() local t if not self.isLit then t = 0 elseif self.fuelAmt <= 3 * 60 then t = 1.7 else t = 1.9 end self.transmitContainerTemp = false if math.abs(t - container:getCustomTemperature()) > 0.01 then self:noise('container temp changed from '..container:getCustomTemperature()..' to '..t) container:setCustomTemperature(t) self.transmitContainerTemp = isServer() end end function SCampfireGlobalObject:syncIsoFire() self.transmitFire = false local fireObj = self:getFireObject() if self.isLit then if not fireObj then self:addFireObject() self.transmitFire = true end elseif fireObj then self:removeFireObject() end end function SCampfireGlobalObject:changeFireLvl() if self.fuelAmt <= 0 then self.isLit = false end local isoObject = self:getIsoObject() if not isoObject then self:saveData() return end local radius = self:fireRadius() if self.radius == radius then self:saveData() isoObject:transmitModData() return end self.radius = radius local gs = self:getSquare() self:noise('changeFireLvl x,y,z='..gs:getX()..','..gs:getY()..','..gs:getZ()..' fuelAmt='..self.fuelAmt..' isLit='..tostring(self.isLit)..' radius='..radius) self:syncIsoObject() self:syncSprite() self:syncModData() self:syncContainer() local isoObject = self:getIsoObject() if self.transmitObject then self:noise('transmit campfire object') isoObject:transmitCompleteItemToClients() else if self.transmitSprite then self:noise('transmit campfire sprite') isoObject:transmitUpdatedSpriteToClients() end self:noise('transmit campfire modData') isoObject:transmitModData() if self.transmitContainer then self:noise('transmit campfire container') isoObject:sendObjectChange('containers') elseif self.transmitContainerTemp then self:noise('transmit campfire container temperature') isoObject:sendObjectChange('container.customTemperature') end end self:syncIsoFire() local fireObj = self:getFireObject() if fireObj and self.transmitFire then fireObj:transmitCompleteItemToClients() end if fireObj and fireObj:getLightRadius() ~= self.radius then fireObj:setLightRadius(self.radius) if isServer() then self:noise('transmit campfire light radius') fireObj:sendObjectChange('lightRadius') end end self:saveData() end function SCampfireGlobalObject:fireRatio() if not self.isLit then return 0 end local maxFuel = 6 * 60 return math.min(self.fuelAmt, maxFuel) / maxFuel end function SCampfireGlobalObject:fireRadius() if not self.isLit then return 0 end local minRadius = 2 local maxRadius = 18 if self.exterior then maxRadius = 10; end local maxFuel = 6 * 60 return math.max(minRadius, maxRadius * math.min(self.fuelAmt, maxFuel) / maxFuel) end function SCampfireGlobalObject:saveData() self:noise('update object modData for campfire '..self.x..','..self.y..','..self.z) local isoObject = self:getIsoObject() if isoObject then self:toModData(isoObject:getModData()) end end function SCampfireGlobalObject:lightFire() if self.isLit or self.fuelAmt <= 0 then return end self.isLit = true self:changeFireLvl() end function SCampfireGlobalObject:putOut() if not self.isLit then return end self.isLit = false self.fuelAmt = self.fuelAmt * 0.90 self:changeFireLvl() end function SCampfireGlobalObject:addFuel(fuelAmt) self.fuelAmt = self.fuelAmt + fuelAmt self:changeFireLvl() end function SCampfireGlobalObject:setFuel(fuelAmt) self.fuelAmt = fuelAmt self:changeFireLvl() end