--*********************************************************** --** THE INDIE STONE ** --*********************************************************** if isClient() then return end require "Map/SGlobalObjectSystem" SCampfireSystem = SGlobalObjectSystem:derive("SCampfireSystem") function SCampfireSystem:new() local o = SGlobalObjectSystem.new(self, "campfire") return o end function SCampfireSystem:initSystem() SGlobalObjectSystem.initSystem(self) -- Specify GlobalObjectSystem fields that should be saved. self.system:setModDataKeys(nil) -- Specify GlobalObject fields that should be saved. self.system:setObjectModDataKeys({'exterior', 'isLit', 'fuelAmt'}) self:convertOldModData() end function SCampfireSystem:newLuaObject(globalObject) return SCampfireGlobalObject:new(self, globalObject) end function SCampfireSystem:isValidModData(modData) return modData ~= nil and modData.fuelAmt ~= nil end function SCampfireSystem:isValidIsoObject(isoObject) return isoObject and isoObject:getName() == "Campfire" end function SCampfireSystem:convertOldModData() -- If the gos_xxx.bin file existed, don't touch GameTime modData in case mods are using it. if self.system:loadedWorldVersion() ~= -1 then return end local modData = GameTime:getInstance():getModData() if modData.camping and modData.camping.campfires then self:noise('converting old-style GameTime modData') for _,campfire in pairs(modData.camping.campfires) do if not self.system:getObjectAt(campfire.x, campfire.y, campfire.z) then local globalObject = self.system:newObject(campfire.x, campfire.y, campfire.z) for k,v in pairs(campfire) do globalObject:getModData()[k] = v end end end modData.camping.campfires = nil for k,v in pairs(modData.camping) do self:noise("copied "..tostring(k).."="..tostring(v)) camping.playerData[k] = v end modData.camping = nil self:noise('converted '..self:getLuaObjectCount()..' campfires') end end -- add a campfire to the ground function SCampfireSystem:addCampfire(grid) if not grid then return end if self:getIsoObjectOnSquare(grid) then return nil end local luaObject = self:newLuaObjectOnSquare(grid) luaObject:initNew() luaObject:addObject() luaObject:addContainer() luaObject:getIsoObject():transmitCompleteItemToClients() self:noise("#campfires="..self:getLuaObjectCount()) luaObject:saveData() return luaObject; end -- remove a camp fire function SCampfireSystem:removeCampfire(luaObject) if not luaObject then return end luaObject:transferItemsToGround() luaObject:removeFireObject() -- This call also removes the luaObject because of the OnObjectAboutToBeRemoved event luaObject:removeIsoObject() end local function stringStarts(_string,_start) return string.sub(_string,1,string.len(_start))==_start end -- we lower by 1 the firelvl (every 3 hours if no more wood) function SCampfireSystem:lowerFirelvl() for i=1,self:getLuaObjectCount() do local luaObject = self:getLuaObjectByIndex(i) local square = luaObject:getSquare() if square then luaObject.exterior = square:isOutside() if not luaObject.exterior and ZombRand(5) == 0 and luaObject.isLit then -- new spread: indoor fireplaces only spread to adjecent wood/carpet floors local newSquare = getCell():getGridSquare(luaObject.x + ZombRand(-1,1), luaObject.y + ZombRand(-1,1), luaObject.z); if newSquare and newSquare~=square then local addFire = false; --check for burnable floors local floor = newSquare:getFloor(); if floor and floor:getSprite() and floor:getSprite():getName() then local name = floor:getSprite():getName(); local n = floor:getSprite():getSheetGridIdFromName(); if n>=0 and name then if (stringStarts(name,"floors_interior_tilesandwood") and n>=40) or stringStarts(name,"floors_interior_carpet") or stringStarts(name,"carpet") then addFire = true; end end end if addFire then IsoFireManager.StartFire(getCell(), newSquare, true, 100, 500); end end --[[ OLD: local newSquare = getCell():getGridSquare(luaObject.x + 1, luaObject.y, luaObject.z); if newSquare then IsoFireManager.StartFire(getCell(), newSquare, true, 100, 500); end --]] end end end end function SCampfireSystem:lowerFuelAmount() for i=1,self:getLuaObjectCount() do local luaObject = self:getLuaObjectByIndex(i) if luaObject.isLit then local amt = 1 -- if RainManager.isRaining() and luaObject.exterior then amt = 2 end luaObject.fuelAmt = math.max(luaObject.fuelAmt - amt, 0) luaObject:changeFireLvl() end end end -- attract the zombie to the campfire and warm the player function SCampfireSystem:nearCamp(delay) if isClient() then return end for i=1,self:getLuaObjectCount() do local luaObject = self:getLuaObjectByIndex(i) local gridSquare = luaObject:getSquare() -- if campfire is burning (and still there, I mean not destroy because of streaming) if luaObject.isLit and gridSquare then -- zombie are attracted 10 from the 10 next tile if fireLvl is at 1, or 20 if it's at 2 local noiseRadius = luaObject:fireRadius() addSound(getPlayer(), gridSquare:getX(),gridSquare:getY(),gridSquare:getZ(), noiseRadius, noiseRadius); end end end function SCampfireSystem:OnClientCommand(command, playerObj, args) SCampfireSystemCommand(command, playerObj, args) end SGlobalObjectSystem.RegisterSystemClass(SCampfireSystem) local function EveryTenMinutes() SCampfireSystem.instance:nearCamp(0) SCampfireSystem.instance:lowerFirelvl() end local function EveryOneMinute() SCampfireSystem.instance:lowerFuelAmount() end Events.EveryOneMinute.Add(EveryOneMinute) Events.EveryTenMinutes.Add(EveryTenMinutes)