--*********************************************************** --** THE INDIE STONE ** --*********************************************************** ----------------------------------------------------------------------- -- FARMING MOD -- -- CODE BY ROBERT JOHNSON -- -- TEXTURES BY THUZTOR -- ----------------------------------------------------------------------- -- OFFICIAL TOPIC -- -- http://www.theindiestone.com/community/viewtopic.php?f=33&t=8675 -- -- -- ----------------------------------------------------------------------- if isClient() then return end require "Map/SGlobalObject" SPlantGlobalObject = SGlobalObject:derive("SPlantGlobalObject") function SPlantGlobalObject:new(luaSystem, globalObject) local o = SGlobalObject.new(self, luaSystem, globalObject) return o; end function SPlantGlobalObject.initModData(modData) modData.state = "plow" modData.nbOfGrow = -1 modData.typeOfSeed = "none" modData.fertilizer = 0 modData.mildewLvl = 0 modData.aphidLvl = 0 modData.fliesLvl = 0 modData.waterLvl = 0 modData.waterNeeded = 0 modData.waterNeededMax = nil modData.lastWaterHour = 0 modData.hasSeed = false modData.hasVegetable = false modData.health = SFarmingSystem.instance:getHealth() modData.badCare = false modData.exterior = true modData.spriteName = "vegetation_farming_01_1" modData.objectName = getText("Farming_Plowed_Land"); end function SPlantGlobalObject:initNew() SPlantGlobalObject.initModData(self) end function SPlantGlobalObject:stateFromIsoObject(isoObject) self:initNew() self:fromModData(isoObject:getModData()) self.objectName = isoObject:getName() self.spriteName = isoObject:getSpriteName() -- MapObjects-related code (see MOFarming.lua) might have changed the -- isoObject when it was loaded, we must sync with clients. if isServer() then isoObject:sendObjectChange('name') isoObject:sendObjectChange('sprite') isoObject:transmitModData() end end function SPlantGlobalObject:stateToIsoObject(isoObject) self.exterior = self:getSquare():isOutside() if tonumber(self.aphidLvl) then self.aphidLvl = math.min(self.aphidLvl, 100) end if tonumber(self.fliesLvl) then self.fliesLvl = math.min(self.fliesLvl, 100) end if tonumber(self.mildewLvl) then self.mildewLvl = math.min(self.mildewLvl, 100) end if self.lastWaterHour and self.lastWaterHour > SFarmingSystem.instance.hoursElapsed then if farming_vegetableconf.props[self.typeOfSeed] then self.nextGrowing = SFarmingSystem.instance.hoursElapsed + farming_vegetableconf.props[self.typeOfSeed].timeToGrow end self.lastWaterHour = SFarmingSystem.instance.hoursElapsed self:noise('reset lastWaterHour/nextGrowing on plant '..self.x..','..self.y) end isoObject:setName(self.objectName) isoObject:setSprite(self.spriteName) self:toModData(isoObject:getModData()) if isServer() then isoObject:sendObjectChange('name') isoObject:sendObjectChange('sprite') isoObject:transmitModData() end end function SPlantGlobalObject:getObject() return self:getIsoObject() end function SPlantGlobalObject:setObjectName(objectName) if objectName == self.objectName then return end self.objectName = objectName local object = self:getObject() if object then object:setName(self.objectName) if isServer() then object:sendObjectChange('name') end -- objectName is stored in modData self:toModData(object:getModData()) -- also update GameTime modData end end function SPlantGlobalObject:setSpriteName(spriteName) if spriteName == self.spriteName then return end self.spriteName = spriteName local object = self:getObject() if object then object:setSprite(self.spriteName) if isServer() then object:sendObjectChange('sprite') end -- spriteName is stored in modData self:toModData(object:getModData()) -- also update GameTime modData end end function SPlantGlobalObject:isAlive() return self.state ~= "destroy" and self.state ~= "dry" and self.state ~= "rotten" end function SPlantGlobalObject:canHarvest() return self:isAlive() and self.hasVegetable end function SPlantGlobalObject:addObject() if self:getObject() then return end local square = self:getSquare() if not square then return end local object = IsoObject.new(square, self.spriteName, self.objectName) object:setSpecialTooltip(true); self:toModData(object:getModData()) square:AddTileObject(object) object:transmitCompleteItemToClients() end function SPlantGlobalObject:removeObject() self:removeIsoObject() end -- if the plant doesn't have mildew, maybe it will have it ! -- base risk for mildew is 2%, but every pt of water below the required water lvl add 1% risk function SPlantGlobalObject:mildew() local mildewNumber = 2 local waterBelow = self.waterNeeded - self.waterLvl -- our plant is well watered if(waterBelow <= 0) then waterBelow = 0 end mildewNumber = mildewNumber + waterBelow if SandboxVars.PlantResilience == 1 then -- very high mildewNumber = mildewNumber - 8; elseif SandboxVars.PlantResilience == 2 then -- high mildewNumber = mildewNumber - 4; elseif SandboxVars.PlantResilience == 4 then -- low mildewNumber = mildewNumber + 4; elseif SandboxVars.PlantResilience == 5 then -- very low mildewNumber = mildewNumber + 8; end if mildewNumber < 0 then mildewNumber = 0; end -- random ! local mildewRisk = ZombRand(mildewNumber, 101) -- you got mildew ! if(mildewRisk == 99) then self.mildewLvl = 1 end end -- if the plant doesn't have aphid, maybe it will have it ! -- base risk for aphid is 2%, but every pt of water below the required water lvl add 1% risk function SPlantGlobalObject:aphid() local aphidNumber = 2 local waterBelow = self.waterNeeded - self.waterLvl -- our plant is well watered if(waterBelow <= 0) then waterBelow = 0 end aphidNumber = aphidNumber + waterBelow if SandboxVars.PlantResilience == 1 then -- very high aphidNumber = aphidNumber - 8; elseif SandboxVars.PlantResilience == 2 then -- high aphidNumber = aphidNumber - 4; elseif SandboxVars.PlantResilience == 4 then -- low aphidNumber = aphidNumber + 4; elseif SandboxVars.PlantResilience == 5 then -- very low aphidNumber = aphidNumber + 8; end if aphidNumber < 0 then aphidNumber = 0; end -- random ! -- I have to set 101 to the max, don't know why but the zombRand never take the last digit (ex, between 5 and 10, you'll never have 10...) local aphidRisk = ZombRand(aphidNumber, 101) -- you got aphid ! if(aphidRisk == 99) then self.aphidLvl = 1 end end -- if the plant doesn't have flies, maybe it will have it ! -- base risk for flies is 2%, but every pt of water below the required water lvl add 1% risk function SPlantGlobalObject:flies() local fliesNumber = 2 local waterBelow = self.waterNeeded - self.waterLvl -- our plant is well watered if(waterBelow <= 0) then waterBelow = 0 end fliesNumber = fliesNumber + waterBelow if SandboxVars.PlantResilience == 1 then -- very high fliesNumber = fliesNumber - 8; elseif SandboxVars.PlantResilience == 2 then -- high fliesNumber = fliesNumber - 4; elseif SandboxVars.PlantResilience == 4 then -- low fliesNumber = fliesNumber + 4; elseif SandboxVars.PlantResilience == 5 then -- very low fliesNumber = fliesNumber + 8; end if fliesNumber < 0 then fliesNumber = 0; end -- random ! -- I have to set 101 to the max, don't know why but the zombRand never take the last digit (ex, between 5 and 10, you'll never have 10...) local fliesRisk = ZombRand(fliesNumber, 101) -- you got flies ! if(fliesRisk == 99) then self.fliesLvl = 1 end end -- up the disease by a number, it's the double if your plant is not well watered function SPlantGlobalObject:upDisease() -- mildew lvl up by 1 or 0.5 if your plant is well watered if self.mildewLvl ~= nil and self.mildewLvl > 0 then local water = farming_vegetableconf.calcWater(self.waterNeeded, self.waterLvl) if(water >= 0) then self.mildewLvl = self.mildewLvl + 0.5 else self.mildewLvl = self.mildewLvl + 1 end self.mildewLvl = math.min(self.mildewLvl, 100) end -- flies lvl up by 1 or 0.5 if your plant is well watered if self.fliesLvl ~= nil and self.fliesLvl > 0 then local water = farming_vegetableconf.calcWater(self.waterNeeded, self.waterLvl) if(water >= 0) then self.fliesLvl = self.fliesLvl + 0.5 else self.fliesLvl = self.fliesLvl + 1 end self.fliesLvl = math.min(self.fliesLvl, 100) end -- aphid is different than mildew, you'll have to deshydrate your plant to lower the aphid lvl if self.aphidLvl ~= nil and self.aphidLvl > 0 then local water = farming_vegetableconf.calcWater(self.waterNeeded, self.waterLvl) if water == -1 or water == -2 then self.aphidLvl = self.aphidLvl - 2 if self.aphidLvl < 0 then self.aphidLvl = 0 end else self.aphidLvl = self.aphidLvl + 1 self.aphidLvl = math.min(self.aphidLvl, 100) end end end -- lower by 1 the waterLvl of all our plant function SPlantGlobalObject:lowerWaterLvl(plant) if self.waterLvl ~= nil then -- flies make water dry more quickly, every 10 pts of flies, water lower by 1 more pts local waterFliesChanger = math.floor(self.fliesLvl / 10) self.waterLvl = self.waterLvl - 1 - waterFliesChanger if self.waterLvl < 0 then self.waterLvl = 0 end end end -- if we add mildew spray function SPlantGlobalObject:cureMildew(mildewCureSource, uses) for i=1,uses do if mildewCureSource then mildewCureSource:Use() end self.mildewLvl = self.mildewLvl - 5 if self.mildewLvl < 0 then self.mildewLvl = 0 end end self:saveData() end -- if we add insecticide spray function SPlantGlobalObject:cureFlies(fliesCureSource, uses) for i=1,uses do if fliesCureSource then fliesCureSource:Use() end self.fliesLvl = self.fliesLvl - 5 if self.fliesLvl < 0 then self.fliesLvl = 0 end end self:saveData() end -- if we water our plant -- we gonna add 5 water lvl for the plant for each use of the water source function SPlantGlobalObject:water(waterSource, uses) for i=1,uses do if self.waterLvl < 100 then if waterSource then if waterSource:getUsedDelta() > 0 then waterSource:Use() end end self.waterLvl = self.waterLvl + 5 if self.waterLvl > 100 then self.waterLvl = 100 end end end -- we notice the hour of our last water, because if we don't water the plant every 48 hours, she die self.lastWaterHour = SFarmingSystem.instance.hoursElapsed; self:saveData() end -- fertilize the plant, more than 4 doses and your plant die ! (no mercy !) function SPlantGlobalObject:fertilize(fertilizer) if self.state ~= "plow" and self:isAlive() then if self.fertilizer < 4 then self.fertilizer = self.fertilizer + 1 self.nextGrowing = self.nextGrowing - 20 if self.nextGrowing < 1 then self.nextGrowing = 1 end else -- too much fertilizer and our plant die ! self:rottenThis() end self:saveData() end end -- check the stat to make them ok (if water < 0 we set it to 0 for example) -- if health < 0 the plant is dead (dry) function SPlantGlobalObject:checkStat() if self.state ~= "plow" and self.nbOfGrow > 1 then if self.waterLvl <= 0 then self:dryThis() elseif self.waterLvl > 100 then self.waterLvl = 100 end if self.health <= 0 then self:dryThis() end end if self.waterLvl < 0 then self.waterLvl = 0 end if self.health < 0 then self.health = 0 elseif self.health > 100 then self.health = 100 end end -- make the plant dry (no more water !) function SPlantGlobalObject:dryThis() if self.typeOfSeed == "Tomato" then self:setSpriteName("vegetation_farming_01_6") else self:setSpriteName("vegetation_farming_01_5") end self.state = "dry" self:setObjectName(farming_vegetableconf.getObjectName(self)) self:deadPlant() end function SPlantGlobalObject:rottenThis() local texture = nil if self.typeOfSeed == "Carrots" then texture = "vegetation_farming_01_13" elseif self.typeOfSeed == "Broccoli" then texture = "vegetation_farming_01_23" elseif self.typeOfSeed == "Strawberry plant" then texture = "vegetation_farming_01_63" elseif self.typeOfSeed == "Radishes" then texture = "vegetation_farming_01_39" elseif self.typeOfSeed == "Tomato" then texture = "vegetation_farming_01_71" elseif self.typeOfSeed == "Potatoes" then texture = "vegetation_farming_01_47" elseif self.typeOfSeed == "Cabbages" then texture = "vegetation_farming_01_31" end self:setSpriteName(texture) self.state = "rotten" self:setObjectName(farming_vegetableconf.getObjectName(self)) self:deadPlant() end -- destroy the plant (someone walked on it :)) function SPlantGlobalObject:destroyThis() -- tomato has different smashed tile if self.typeOfSeed == "Tomato" then self:setSpriteName("vegetation_farming_01_14") else self:setSpriteName("vegetation_farming_01_13") end self.state = "destroy" self:setObjectName(farming_vegetableconf.getObjectName(self)) self:deadPlant() self:saveData() end function SPlantGlobalObject:seed(typeOfSeed) -- will set the first growing state for the type of seed self.nbOfGrow = 0 self.state = "seeded" self.typeOfSeed = typeOfSeed -- You have 48 hours to water your plant, if not, she will be dry self.lastWaterHour = SFarmingSystem.instance.hoursElapsed self.waterNeeded = 0 SFarmingSystem.instance:growPlant(self, nil, true) self:saveData() end function SPlantGlobalObject:deadPlant() self.nextGrowing = 0 self.waterLvl = 0 self.nbOfGrow = 0 self.mildewLvl = 0 self.aphidLvl = 0 self.fliesLvl = 0 self.health = 0 end function SPlantGlobalObject:addIcon() end function SPlantGlobalObject:saveData() local isoObject = self:getIsoObject() if isoObject then self:toModData(isoObject:getModData()) isoObject:transmitModData() end end function SPlantGlobalObject:fromModData(modData) self.state = modData.state self.nbOfGrow = modData.nbOfGrow self.typeOfSeed = modData.typeOfSeed self.fertilizer = modData.fertilizer self.mildewLvl = modData.mildewLvl self.aphidLvl = modData.aphidLvl self.fliesLvl = modData.fliesLvl self.waterLvl = modData.waterLvl self.waterNeeded = modData.waterNeeded self.waterNeededMax = modData.waterNeededMax self.lastWaterHour = modData.lastWaterHour self.nextGrowing = modData.nextGrowing self.hasSeed = modData.hasSeed == "true" or modData.hasSeed == true self.hasVegetable = modData.hasVegetable == "true" or modData.hasVegetable == true self.health = modData.health self.badCare = modData.badCare == "true" or modData.badCare == true self.exterior = modData.exterior == true or modData.exterior == nil self.spriteName = modData.spriteName self.objectName = modData.objectName if not self.spriteName then -- old-style modData self.spriteName = farming_vegetableconf.getSpriteName(self) end if not self.objectName then -- old-style modData self.objectName = farming_vegetableconf.getObjectName(self) end end function SPlantGlobalObject:toModData(modData) modData.state = self.state modData.nbOfGrow = self.nbOfGrow modData.typeOfSeed = self.typeOfSeed modData.fertilizer = self.fertilizer modData.mildewLvl = self.mildewLvl modData.aphidLvl = self.aphidLvl modData.fliesLvl = self.fliesLvl modData.waterLvl = self.waterLvl modData.waterNeeded = self.waterNeeded modData.waterNeededMax = self.waterNeededMax modData.lastWaterHour = self.lastWaterHour modData.nextGrowing = self.nextGrowing modData.hasSeed = self.hasSeed modData.hasVegetable = self.hasVegetable modData.health = self.health modData.badCare = self.badCare modData.exterior = self.exterior modData.spriteName = self.spriteName modData.objectName = self.objectName end function SPlantGlobalObject:fromObject(object) self:initFromIsoObject(object) end function SPlantGlobalObject:loadGridSquare() local isoObject = self:getObject() if not isoObject then return end self:loadIsoObject(isoObject) end