MattiasAldhagen

Scrap Mechanic: Creative-mode in survival world [p0.4.2 v1]

May 12th, 2020
6,047
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 33.55 KB | None | 0 0
  1. -- @reckty
  2. dofile( "$SURVIVAL_DATA/Scripts/game/survival_shapes.lua" )
  3. dofile( "$SURVIVAL_DATA/Scripts/game/survival_harvestable.lua" )
  4. dofile( "$SURVIVAL_DATA/Scripts/game/survival_constants.lua" )
  5. dofile( "$SURVIVAL_DATA/Scripts/game/managers/ElevatorManager.lua"  )
  6. dofile( "$SURVIVAL_DATA/Scripts/game/managers/RespawnManager.lua" )
  7. dofile( "$SURVIVAL_DATA/Scripts/game/managers/UnitManager.lua" )
  8. dofile( "$SURVIVAL_DATA/Scripts/game/util/Timer.lua" )
  9.  
  10. dofile( "$SURVIVAL_DATA/Scripts/game/survival_units.lua" )
  11.  
  12. SurvivalGame = class( nil )
  13. SurvivalGame.enableLimitedInventory = true
  14. SurvivalGame.enableRestrictions = true
  15.  
  16. local SyncInterval = 400 -- 400 ticks | 10 seconds
  17.  
  18.  
  19. function SurvivalGame.server_onCreate( self )
  20.     print( "SurvivalGame.server_onCreate" )
  21.     self.sv = {}
  22.     self.sv.saved = self.storage:load()
  23.     print( "Saved:", self.sv.saved )
  24.     if self.sv.saved == nil then
  25.         self.sv.saved = {}
  26.         self.sv.saved.data = self.data
  27.         print( "Seed:", string.format( "%.0f", self.sv.saved.data.seed ) )
  28.         self.sv.saved.overworld = sm.world.createWorld( "$SURVIVAL_DATA/Scripts/game/worlds/Overworld.lua", "Overworld", { dev = self.sv.saved.data.dev }, self.sv.saved.data.seed )
  29.         self.storage:save( self.sv.saved )
  30.     end
  31.     self.data = nil
  32.  
  33.     print( self.sv.saved.data )
  34.     if self.sv.saved.data and self.sv.saved.data.dev then
  35.         g_godMode = true
  36.         g_survivalDev = true
  37.     end
  38.  
  39.     self:loadCraftingRecipes()
  40.  
  41.     g_elevatorManager = ElevatorManager()
  42.     g_elevatorManager:sv_onCreate()
  43.  
  44.     g_respawnManager = RespawnManager()
  45.     g_respawnManager:sv_onCreate( self.sv.saved.overworld )
  46.  
  47.     g_unitManager = UnitManager()
  48.     g_unitManager:sv_onCreate( self.sv.saved.overworld )
  49.  
  50.     -- Game script managed global warehouse table
  51.     self.warehouses = sm.storage.load( STORAGE_CHANNEL_WAREHOUSES )
  52.     if self.warehouses then
  53.         print( "Loaded warehouses:" )
  54.         print( self.warehouses )
  55.     else
  56.         self.warehouses = {}
  57.         self:sv_e_saveWarehouses()
  58.     end
  59.     g_warehouses = self.warehouses
  60.  
  61.  
  62.     self.sv.time = sm.storage.load( STORAGE_CHANNEL_TIME )
  63.     if self.sv.time then
  64.         print( "Loaded timeData:" )
  65.         print( self.sv.time )
  66.     else
  67.         self.sv.time = {}
  68.         self.sv.time.timeOfDay = 6 / 24 -- 06:00
  69.         self.sv.time.timeProgress = true
  70.         sm.storage.save( STORAGE_CHANNEL_TIME, self.sv.time )
  71.     end
  72.     self:sv_updateClientData()
  73.  
  74.     self.sv.syncTimer = Timer()
  75.     self.sv.syncTimer:start( 0 )
  76.  end
  77.  
  78. function SurvivalGame.server_onRefresh( self )
  79.     g_craftingRecipes = nil
  80.     g_refineryRecipes = nil
  81.     self:loadCraftingRecipes()
  82. end
  83.  
  84. function BindDevCommands()
  85.     sm.game.bindChatCommand( "/ammo", { { "int", "quantity", true } }, "cl_onChatCommand", "Give ammo (default 40)" )
  86.     sm.game.bindChatCommand( "/spudgun", {}, "cl_onChatCommand", "Give the spudgun" )
  87.     sm.game.bindChatCommand( "/gatling", {}, "cl_onChatCommand", "Give the potato gatling gun" )
  88.     sm.game.bindChatCommand( "/shotgun", {}, "cl_onChatCommand", "Give the fries shotgun" )
  89.     sm.game.bindChatCommand( "/sunshake", {}, "cl_onChatCommand", "Give 1 sunshake" )
  90.     sm.game.bindChatCommand( "/baguette", {}, "cl_onChatCommand", "Give 1 revival baguette" )
  91.     sm.game.bindChatCommand( "/keycard", {}, "cl_onChatCommand", "Give 1 keycard" )
  92.     sm.game.bindChatCommand( "/powercore", {}, "cl_onChatCommand", "Give 1 powercore" )
  93.     sm.game.bindChatCommand( "/components", { { "int", "quantity", true } }, "cl_onChatCommand", "Give <quantity> components (default 10)" )
  94.     sm.game.bindChatCommand( "/glowsticks", { { "int", "quantity", true } }, "cl_onChatCommand", "Give <quantity> components (default 10)" )
  95.     sm.game.bindChatCommand( "/tumble", { { "bool", "enable", true } }, "cl_onChatCommand", "Set tumble state" )
  96.     sm.game.bindChatCommand( "/god", {}, "cl_onChatCommand", "Mechanic characters will take no damage" )
  97.     sm.game.bindChatCommand( "/respawn", {}, "cl_onChatCommand", "Respawn at last bed (or at the crash site)" )
  98.     sm.game.bindChatCommand( "/encrypt", {}, "cl_onChatCommand", "Restrict interactions in all warehouses" )
  99.     sm.game.bindChatCommand( "/decrypt", {}, "cl_onChatCommand", "Unrestrict interactions in all warehouses" )
  100.     sm.game.bindChatCommand( "/limited", {}, "cl_onChatCommand", "Use the limited inventory" )
  101.     sm.game.bindChatCommand( "/unlimited", {}, "cl_onChatCommand", "Use the unlimited inventory" )
  102.     sm.game.bindChatCommand( "/ambush", { { "number", "magnitude", true }, { "int", "wave", true } }, "cl_onChatCommand", "Starts a 'random' encounter" )
  103.     sm.game.bindChatCommand( "/recreate", {}, "cl_onChatCommand", "Recreate world" )
  104.     sm.game.bindChatCommand( "/timeofday", { { "number", "timeOfDay", true } }, "cl_onChatCommand", "Sets the time of the day as a fraction (0.5=mid day)" )
  105.     sm.game.bindChatCommand( "/timeprogress", { { "bool", "enabled", true } }, "cl_onChatCommand", "Enables or disables time progress" )
  106.     sm.game.bindChatCommand( "/day", {}, "cl_onChatCommand", "Disable time progression and set time to daytime" )
  107.     sm.game.bindChatCommand( "/spawn", { { "string", "unitName", true }, { "number", "unitGroup", true } }, "cl_onChatCommand", "Spawn a unit: 'woc', 'tapebot', 'totebot', 'haybot'" )
  108.     sm.game.bindChatCommand( "/harvestable", { { "string", "harvestableName", true } }, "cl_onChatCommand", "Create a harvestable: 'tree', 'stone'" )
  109.     sm.game.bindChatCommand( "/cleardebug", {}, "cl_onChatCommand", "Clear debug draw objects" )
  110.     sm.game.bindChatCommand( "/export", { { "string", "name", false } }, "cl_onChatCommand", "Exports blueprint $SURVIVAL_DATA/LocalBlueprints/<name>.blueprint" )
  111.     sm.game.bindChatCommand( "/import", { { "string", "name", false } }, "cl_onChatCommand", "Imports blueprint $SURVIVAL_DATA/LocalBlueprints/<name>.blueprint" )
  112.     sm.game.bindChatCommand( "/starterkit", {}, "cl_onChatCommand", "Spawn a starter kit" )
  113.     sm.game.bindChatCommand( "/mechanicstartkit", {}, "cl_onChatCommand", "Spawn a starter kit for starting at mechanic station" )
  114.     sm.game.bindChatCommand( "/pipekit", {}, "cl_onChatCommand", "Spawn a pipe kit" )
  115.     sm.game.bindChatCommand( "/foodkit", {}, "cl_onChatCommand", "Spawn a food kit" )
  116.     sm.game.bindChatCommand( "/seedkit", {}, "cl_onChatCommand", "Spawn a seed kit" )
  117.     sm.game.bindChatCommand( "/die", {}, "cl_onChatCommand", "Kill the player" )
  118.     sm.game.bindChatCommand( "/sethp", { { "number", "hp", false } }, "cl_onChatCommand", "Set player hp value" )
  119.     sm.game.bindChatCommand( "/setwater", { { "number", "water", false } }, "cl_onChatCommand", "Set player water value" )
  120.     sm.game.bindChatCommand( "/setfood", { { "number", "food", false } }, "cl_onChatCommand", "Set player food value" )
  121.     sm.game.bindChatCommand( "/aggroall", {}, "cl_onChatCommand", "All hostile units will be made aware of the player's position" )
  122.     sm.game.bindChatCommand( "/goto", { { "string", "name", false } }, "cl_onChatCommand", "Teleport to predefined position" )
  123.     sm.game.bindChatCommand( "/raid", { { "int", "level", false }, { "int", "wave", true }, { "number", "hours", true } }, "cl_onChatCommand", "Start a level <level> raid at player position at wave <wave> in <delay> hours." )
  124.     sm.game.bindChatCommand( "/stopraid", {}, "cl_onChatCommand", "Cancel all incoming raids" )
  125.     sm.game.bindChatCommand( "/disableraids", { { "bool", "enabled", false } }, "cl_onChatCommand", "Disable raids if true" )
  126.     sm.game.bindChatCommand( "/camera", {}, "cl_onChatCommand", "Spawn a SplineCamera tool" )
  127.    
  128.     sm.game.bindChatCommand( "/printglobals", {}, "cl_onChatCommand", "Print all global lua variables" )
  129.     sm.game.bindChatCommand( "/clearpathnodes", {}, "cl_onChatCommand", "Clear all path nodes in overworld" )
  130.     sm.game.bindChatCommand( "/enablepathpotatoes", { { "bool", "enable", true } }, "cl_onChatCommand", "Creates path nodes at potato hits in overworld and links to previous node" )
  131.    
  132.     -- Gamemode
  133.     sm.game.bindChatCommand( "/survival", {}, "cl_onChatCommand", "Change game-mode to survival")
  134.     sm.game.bindChatCommand( "/s", {}, "cl_onChatCommand", "Short-cut to '/survival'")
  135.     sm.game.bindChatCommand( "/creative", {}, "cl_onChatCommand", "Change game-mode to creative")
  136.     sm.game.bindChatCommand( "/c", {}, "cl_onChatCommand", "Short-cut to '/creative'")
  137.    
  138.     --Give
  139.     sm.game.bindChatCommand( "/gas", { { "int", "quantity", true } }, "cl_onChatCommand", "Give <quantity> gasoline (default 10)" )
  140.     sm.game.bindChatCommand( "/battery", { { "int", "quantity", true } }, "cl_onChatCommand", "Give <quantity> batteries (default 10)" )
  141.    
  142.    
  143. end
  144.  
  145. function SurvivalGame.client_onCreate( self )
  146.     if g_survivalDev then
  147.         BindDevCommands()
  148.     end
  149.     sm.game.bindChatCommand( "/cheat", {}, "cl_onChatCommand", "Enables Cheats")
  150.  
  151.     self.cl = {}
  152.     self.cl.time = {}
  153.     self.cl.time.timeOfDay = 0.0
  154.     self.cl.time.timeProgress = true
  155.  
  156.     self:loadCraftingRecipes()
  157.  
  158.     if g_respawnManager == nil then
  159.         assert( not sm.isHost )
  160.         g_respawnManager = RespawnManager()
  161.     end
  162.     g_respawnManager:cl_onCreate()
  163.  
  164.     if g_unitManager == nil then
  165.         assert( not sm.isHost )
  166.         g_unitManager = UnitManager()
  167.     end
  168.     g_unitManager:cl_onCreate()
  169.  
  170.     -- Music effect
  171.     g_survivalMusic = sm.effect.createEffect( "SurvivalMusic" )
  172.     assert(g_survivalMusic)
  173. end
  174.  
  175. function SurvivalGame.client_onClientDataUpdate( self, clientData )
  176.     self.cl.time = clientData.time
  177. end
  178.  
  179. function SurvivalGame.loadCraftingRecipes( self )
  180.     -- Preload all crafting recipes
  181.     if not g_craftingRecipes then
  182.         local recipePaths = {
  183.             workbench = "$SURVIVAL_DATA/CraftingRecipes/workbench.json",
  184.             dispenser = "$SURVIVAL_DATA/CraftingRecipes/dispenser.json",
  185.             cookbot = "$SURVIVAL_DATA/CraftingRecipes/cookbot.json",
  186.             craftbot = "$SURVIVAL_DATA/CraftingRecipes/craftbot.json",
  187.             undecided = "$SURVIVAL_DATA/CraftingRecipes/undecided.json",
  188.             dressbot = "$SURVIVAL_DATA/CraftingRecipes/dressbot.json"
  189.         }
  190.         g_craftingRecipes = {}
  191.         for name, path in pairs( recipePaths ) do
  192.             local json = sm.json.open( path )
  193.             local recipes = {}
  194.             local recipesByIndex = {}
  195.             for idx, recipe in ipairs( json ) do
  196.                
  197.                 recipe.craftTime = math.ceil( recipe.craftTime * 40 ) -- Seconds to ticks
  198.                 for _,ingredient in ipairs( recipe.ingredientList ) do
  199.                     ingredient.itemId = sm.uuid.new( ingredient.itemId ) -- Prepare uuid
  200.                 end
  201.  
  202.                 recipes[recipe.itemId] = recipe
  203.                 recipesByIndex[idx] = recipe
  204.  
  205.             end
  206.             -- NOTE(daniel): Wardrobe is using 'recipes' by uuid, crafter is using 'recipesByIndex'
  207.             g_craftingRecipes[name] = { path = path, recipes = recipes, recipesByIndex = recipesByIndex }
  208.         end
  209.     end
  210.  
  211.     -- Preload refinery recipes
  212.     if not g_refineryRecipes then
  213.         g_refineryRecipes = sm.json.open( "$SURVIVAL_DATA/CraftingRecipes/refinery.json" )
  214.         for _,recipe in pairs( g_refineryRecipes ) do
  215.             recipe.itemId = sm.uuid.new( recipe.itemId ) -- Prepare uuid
  216.         end
  217.     end
  218. end
  219.  
  220. function SurvivalGame.server_onFixedUpdate( self, timeStep )
  221.     -- Update time
  222.     local prevTime = self.sv.time.timeOfDay
  223.     if self.sv.time.timeProgress then
  224.         self.sv.time.timeOfDay = self.sv.time.timeOfDay + timeStep / DAYCYCLE_TIME
  225.     end
  226.     local newDay = self.sv.time.timeOfDay >= 1.0
  227.     if newDay then
  228.         self.sv.time.timeOfDay = math.fmod( self.sv.time.timeOfDay, 1 )
  229.     end
  230.  
  231.     if self.sv.time.timeOfDay >= DAYCYCLE_DAWN and prevTime < DAYCYCLE_DAWN then
  232.         g_unitManager:sv_initNewDay()
  233.     end
  234.  
  235.     -- Ambush
  236.     --if not g_survivalDev then
  237.     --  for _,ambush in ipairs( AMBUSHES ) do
  238.     --      if self.sv.time.timeOfDay >= ambush.time and ( prevTime < ambush.time or newDay ) then
  239.     --          self:sv_ambush( { magnitude = ambush.magnitude, wave = ambush.wave } )
  240.     --      end
  241.     --  end
  242.     --end
  243.  
  244.     -- Client and save sync
  245.     self.sv.syncTimer:tick()
  246.     if self.sv.syncTimer:done() then
  247.         self.sv.syncTimer:start( SyncInterval )
  248.         sm.storage.save( STORAGE_CHANNEL_TIME, self.sv.time )
  249.         self:sv_updateClientData()
  250.     end
  251.  
  252.     g_elevatorManager:sv_onFixedUpdate()
  253.     g_unitManager:sv_onFixedUpdate()
  254. end
  255.  
  256. function SurvivalGame.sv_updateClientData( self )
  257.     self.network:setClientData( { time = self.sv.time } )
  258. end
  259.  
  260. function SurvivalGame.client_onUpdate( self, dt )
  261.     -- Update time
  262.     if self.cl.time.timeProgress then
  263.         self.cl.time.timeOfDay = math.fmod( self.cl.time.timeOfDay + dt / DAYCYCLE_TIME, 1.0 )
  264.     end
  265.     sm.game.setTimeOfDay( self.cl.time.timeOfDay )
  266.  
  267.     -- Update lighting values
  268.     local index = 1
  269.     while index < #DAYCYCLE_LIGHTING_TIMES and self.cl.time.timeOfDay >= DAYCYCLE_LIGHTING_TIMES[index + 1] do
  270.         index = index + 1
  271.     end
  272.     assert( index <= #DAYCYCLE_LIGHTING_TIMES )
  273.  
  274.     local light = 0.0
  275.     if index < #DAYCYCLE_LIGHTING_TIMES then
  276.         local p = ( self.cl.time.timeOfDay - DAYCYCLE_LIGHTING_TIMES[index] ) / ( DAYCYCLE_LIGHTING_TIMES[index + 1] - DAYCYCLE_LIGHTING_TIMES[index] )
  277.         light = sm.util.lerp( DAYCYCLE_LIGHTING_VALUES[index], DAYCYCLE_LIGHTING_VALUES[index + 1], p )
  278.     else
  279.         light = DAYCYCLE_LIGHTING_VALUES[index]
  280.     end
  281.     sm.render.setOutdoorLighting( light )
  282. end
  283.  
  284. function SurvivalGame.client_showMessage( self, params )
  285.     sm.gui.chatMessage( params )
  286. end
  287.  
  288. function SurvivalGame.cl_onChatCommand( self, params )
  289.     if params[1] == "/ammo" then
  290.         self.network:sendToServer( "sv_giveItem", { player = sm.localPlayer.getPlayer(), item = obj_plantables_potato, quantity = ( params[2] or 50 ) } )
  291.     elseif params[1] == "/spudgun" then
  292.         self.network:sendToServer( "sv_giveItem", { player = sm.localPlayer.getPlayer(), item = tool_spudgun, quantity = 1 } )
  293.     elseif params[1] == "/gatling" then
  294.         self.network:sendToServer( "sv_giveItem", { player = sm.localPlayer.getPlayer(), item = tool_gatling, quantity = 1 } )
  295.     elseif params[1] == "/shotgun" then
  296.         self.network:sendToServer( "sv_giveItem", { player = sm.localPlayer.getPlayer(), item = tool_shotgun, quantity = 1 } )
  297.     elseif params[1] == "/sunshake" then
  298.         self.network:sendToServer( "sv_giveItem", { player = sm.localPlayer.getPlayer(), item = obj_consumable_sunshake, quantity = 1 } )
  299.     elseif params[1] == "/baguette" then
  300.         self.network:sendToServer( "sv_giveItem", { player = sm.localPlayer.getPlayer(), item = obj_consumable_longsandwich, quantity = 1 } )
  301.     elseif params[1] == "/keycard" then
  302.         self.network:sendToServer( "sv_giveItem", { player = sm.localPlayer.getPlayer(), item = obj_survivalobject_keycard, quantity = 1 } )
  303.     elseif params[1] == "/camera" then
  304.         self.network:sendToServer( "sv_giveItem", { player = sm.localPlayer.getPlayer(), item = sm.uuid.new( "5bbe87d3-d60a-48b5-9ca9-0086c80ebf7f" ), quantity = 1 } )
  305.     elseif params[1] == "/powercore" then
  306.         self.network:sendToServer( "sv_giveItem", { player = sm.localPlayer.getPlayer(), item = obj_survivalobject_powercore, quantity = 1 } )
  307.     elseif params[1] == "/components" then
  308.         self.network:sendToServer( "sv_giveItem", { player = sm.localPlayer.getPlayer(), item = obj_consumable_component, quantity = ( params[2] or 10 ) } )
  309.     elseif params[1] == "/glowsticks" then
  310.         self.network:sendToServer( "sv_giveItem", { player = sm.localPlayer.getPlayer(), item = obj_consumable_glowstick, quantity = ( params[2] or 10 ) } )
  311.     elseif params[1] == "/god" then
  312.         self.network:sendToServer( "sv_switchGodMode" )
  313.     elseif params[1] == "/encrypt" then
  314.         self.network:sendToServer( "sv_enableRestrictions", true )
  315.     elseif params[1] == "/decrypt" then
  316.         self.network:sendToServer( "sv_enableRestrictions", false )
  317.     elseif params[1] == "/unlimited" then
  318.         self.network:sendToServer( "sv_setLimitedInventory", false )
  319.     elseif params[1] == "/limited" then
  320.         self.network:sendToServer( "sv_setLimitedInventory", true )
  321.     elseif params[1] == "/ambush" then
  322.         self.network:sendToServer( "sv_ambush", { magnitude = params[2] or 1, wave = params[3] } )
  323.     elseif params[1] == "/recreate" then
  324.         self.network:sendToServer( "sv_recreateWorld", sm.localPlayer.getPlayer() )
  325.     elseif params[1] == "/timeofday" then
  326.         self.network:sendToServer( "sv_setTimeOfDay", params[2] )
  327.     elseif params[1] == "/timeprogress" then
  328.         self.network:sendToServer( "sv_setTimeProgress", params[2] )
  329.     elseif params[1] == "/day" then
  330.         self.network:sendToServer( "sv_setTimeOfDay", 0.5 )
  331.         self.network:sendToServer( "sv_setTimeProgress", false )
  332.     elseif params[1] == "/die" then
  333.         self.network:sendToServer( "sv_killPlayer", { player = sm.localPlayer.getPlayer() })
  334.     elseif params[1] == "/spawn" then
  335.         local rayCastValid, rayCastResult = sm.localPlayer.getRaycast( 100 )
  336.         if rayCastValid then
  337.             local spawnParams = {
  338.                 uuid = sm.uuid.new( "00000000-0000-0000-0000-000000000000" ),
  339.                 world = sm.localPlayer.getPlayer().character:getWorld(),
  340.                 position = rayCastResult.pointWorld,
  341.                 yaw = 0.0
  342.             }
  343.             if params[2] == "woc" then
  344.                 spawnParams.uuid = unit_woc
  345.             elseif params[2] == "tapebot" or params[2] == "tb" then
  346.                 spawnParams.uuid = unit_tapebot
  347.             elseif params[2] == "redtapebot" or params[2] == "rtb" then
  348.                 spawnParams.uuid = unit_tapebot_red
  349.             elseif params[2] == "totebot" or params[2] == "green" or params[2] == "t" then
  350.                 spawnParams.uuid = unit_totebot_green
  351.             elseif params[2] == "haybot" or params[2] == "h" then
  352.                 spawnParams.uuid = unit_haybot
  353.             elseif params[2] == "worm" then
  354.                 spawnParams.uuid = unit_worm
  355.             elseif params[2] == "farmbot" or params[2] == "f" then
  356.                 spawnParams.uuid = unit_farmbot
  357.             elseif params[2] then
  358.                 spawnParams.uuid = sm.uuid.new( params[2] )
  359.             end
  360.  
  361.             if params[3] then
  362.                 spawnParams.unitParams = {}
  363.                 spawnParams.unitParams.groupId = params[3]
  364.             end
  365.             self.network:sendToServer( "sv_spawnUnit", spawnParams )
  366.         end
  367.     elseif params[1] == "/harvestable" then
  368.         local character = sm.localPlayer.getPlayer().character
  369.         if character then
  370.             local harvestableUuid = sm.uuid.new( "00000000-0000-0000-0000-000000000000" )
  371.             if params[2] == "tree" then
  372.                 harvestableUuid = sm.uuid.new( "c4ea19d3-2469-4059-9f13-3ddb4f7e0b79" )
  373.             elseif params[2] == "stone" then
  374.                 harvestableUuid = sm.uuid.new( "0d3362ae-4cb3-42ae-8a08-d3f9ed79e274" )
  375.             elseif params[2] == "soil" then
  376.                 harvestableUuid = hvs_soil
  377.             elseif params[2] == "fencelong" then
  378.                 harvestableUuid = sm.uuid.new( "c0f19413-6d8e-4b20-819a-949553242259" )
  379.             elseif params[2] == "fenceshort" then
  380.                 harvestableUuid = sm.uuid.new( "144b5e79-483e-4da6-86ab-c575d0fdcd11" )
  381.             elseif params[2] == "fencecorner" then
  382.                 harvestableUuid = sm.uuid.new( "ead875db-59d0-45f5-861e-b3075e1f8434" )
  383.             elseif params[2] == "beehive" then
  384.                 harvestableUuid = hvs_farmables_beehive
  385.             elseif params[2] == "cotton" then
  386.                 harvestableUuid = hvs_farmables_cottonplant
  387.             elseif params[2] then
  388.                 harvestableUuid = sm.uuid.new( params[2] )
  389.             end
  390.             local spawnParams = { world = character:getWorld(), uuid = harvestableUuid, position = character.worldPosition, quat = sm.vec3.getRotation( sm.vec3.new( 0, 1, 0 ), sm.vec3.new( 0, 0, 1 ) )  }
  391.             self.network:sendToServer( "sv_spawnHarvestable", spawnParams )
  392.         end
  393.     elseif params[1] == "/cleardebug" then
  394.         sm.debugDraw.clear()
  395.     elseif params[1] == "/export" then
  396.         local rayCastValid, rayCastResult = sm.localPlayer.getRaycast( 100 )
  397.         if rayCastValid and rayCastResult.type == "body" then
  398.             local importParams = {
  399.                 name = params[2],
  400.                 body = rayCastResult:getBody()
  401.             }
  402.             self.network:sendToServer( "sv_exportCreation", importParams )
  403.         end
  404.     elseif params[1] == "/import" then
  405.         local rayCastValid, rayCastResult = sm.localPlayer.getRaycast( 100 )
  406.         if rayCastValid then
  407.             local importParams = {
  408.                 world = sm.localPlayer.getPlayer().character:getWorld(),
  409.                 name = params[2],
  410.                 position = rayCastResult.pointWorld
  411.             }
  412.             self.network:sendToServer( "sv_importCreation", importParams )
  413.         end
  414.     elseif params[1] == "/cheat" then
  415.         g_survivalDev = true
  416.         BindDevCommands()
  417.     elseif params[1] == "/creative" or params[1] == "/c" then
  418.         self.network:sendToServer( "sv_setGodMode", true )
  419.         self.network:sendToServer( "sv_setLimitedInventory", false )
  420.     elseif params[1] == "/survival" or params[1] == "/s" then
  421.         self.network:sendToServer( "sv_setGodMode", false )
  422.         self.network:sendToServer( "sv_setLimitedInventory", true )
  423.     elseif params[1] == "/gas" then
  424.         self.network:sendToServer( "sv_giveItem", { player = sm.localPlayer.getPlayer(), item = obj_consumable_gas, quantity = ( params[2] or 10 ) } )
  425.     elseif params[1] == "/battery" then
  426.         self.network:sendToServer( "sv_giveItem", { player = sm.localPlayer.getPlayer(), item = obj_consumable_battery, quantity = ( params[2] or 10 ) } )
  427.     else
  428.         self.network:sendToServer( "sv_onChatCommand", params )
  429.     end
  430. end
  431.  
  432. function SurvivalGame.sv_giveItem( self, params )
  433.     sm.container.beginTransaction()
  434.     sm.container.collect( params.player:getInventory(), params.item, params.quantity, false )
  435.     sm.container.endTransaction()
  436. end
  437.  
  438. function SurvivalGame.sv_switchGodMode( self )
  439.     g_godMode = not g_godMode
  440.     self.network:sendToClients( "client_showMessage", "GODMODE: " .. ( g_godMode and "On" or "Off" ) )
  441. end
  442.  
  443. function SurvivalGame.sv_setGodMode( self, state )
  444.     g_godMode = state
  445.     self.network:sendToClients( "client_showMessage", "GODMODE: " .. ( g_godMode and "On" or "Off" ) )
  446. end
  447.  
  448. function SurvivalGame.sv_enableRestrictions( self, state )
  449.     sm.game.enableRestrictions( state )
  450.     self.network:sendToClients( "client_showMessage", ( state and "Restricted" or "Unrestricted"  ) )
  451. end
  452.  
  453. function SurvivalGame.sv_setLimitedInventory( self, state )
  454.     sm.game.setLimitedInventory( state )
  455.     self.network:sendToClients( "client_showMessage", ( state and "Limited inventory" or "Unlimited inventory"  ) )
  456. end
  457.  
  458. function SurvivalGame.sv_ambush( self, params )
  459.     if sm.exists( self.sv.saved.overworld ) then
  460.         sm.event.sendToWorld( self.sv.saved.overworld, "sv_ambush", params )
  461.     end
  462. end
  463.  
  464. function SurvivalGame.sv_recreateWorld( self, player )
  465.     local character = player:getCharacter()
  466.     if character:getWorld() == self.sv.saved.overworld then
  467.         self.sv.saved.overworld:destroy()
  468.         self.sv.saved.overworld = sm.world.createWorld( "$SURVIVAL_DATA/Scripts/game/worlds/Overworld.lua", "Overworld", { dev = g_survivalDev }, self.sv.saved.data.seed )
  469.         self.storage:save( self.sv.saved )
  470.  
  471.         local params = { pos = character:getWorldPosition(), dir = character:getDirection() }
  472.         self.sv.saved.overworld:loadCell( math.floor( params.pos.x/64 ), math.floor( params.pos.y/64 ), player, "sv_recreatePlayerCharacter", params )
  473.  
  474.         self.network:sendToClients( "client_showMessage", "Recreating world" )
  475.     else
  476.         self.network:sendToClients( "client_showMessage", "Recreate world only allowed for overworld" )
  477.     end
  478. end
  479.  
  480. function SurvivalGame.sv_setTimeOfDay( self, timeOfDay )
  481.     if timeOfDay then
  482.         self.sv.time.timeOfDay = timeOfDay
  483.         self.sv.syncTimer.count = self.sv.syncTimer.ticks -- Force sync
  484.     end
  485.     self.network:sendToClients( "client_showMessage", ( "Time of day set to "..self.sv.time.timeOfDay ) )
  486. end
  487.  
  488. function SurvivalGame.sv_setTimeProgress( self, timeProgress )
  489.     if timeProgress ~= nil then
  490.         self.sv.time.timeProgress = timeProgress
  491.         self.sv.syncTimer.count = self.sv.syncTimer.ticks -- Force sync
  492.     end
  493.     self.network:sendToClients( "client_showMessage", ( "Time scale set to "..( self.sv.time.timeProgress and "on" or "off ") ) )
  494. end
  495.  
  496. function SurvivalGame.sv_killPlayer( self, params )
  497.     params.damage = 9999
  498.     sm.event.sendToPlayer( params.player, "sv_e_receiveDamage", params )
  499. end
  500.  
  501. function SurvivalGame.sv_spawnUnit( self, params )
  502.     sm.event.sendToWorld( params.world, "sv_e_spawnUnit", params )
  503. end
  504.  
  505. function SurvivalGame.sv_spawnHarvestable( self, params )
  506.     sm.event.sendToWorld( params.world, "sv_spawnHarvestable", params )
  507. end
  508.  
  509. function SurvivalGame.sv_exportCreation( self, params )
  510.     local obj = sm.json.parseJsonString( sm.creation.exportToString( params.body ) )
  511.     sm.json.save( obj, "$SURVIVAL_DATA/LocalBlueprints/"..params.name..".blueprint" )
  512. end
  513.  
  514. function SurvivalGame.sv_importCreation( self, params )
  515.     sm.creation.importFromFile( params.world, "$SURVIVAL_DATA/LocalBlueprints/"..params.name..".blueprint", params.position )
  516. end
  517.  
  518. function SurvivalGame.sv_onChatCommand( self, params, player )
  519.     if params[1] == "/tumble" then
  520.         if params[2] ~= nil then
  521.             player.character:setTumbling( params[2] )
  522.         end
  523.         if player.character:isTumbling() then
  524.             self.network:sendToClients( "client_showMessage", "Player is tumbling" )
  525.         else
  526.             self.network:sendToClients( "client_showMessage", "Player is not tumbling" )
  527.         end
  528.  
  529.     elseif params[1] == "/sethp" then
  530.         sm.event.sendToPlayer( player, "sv_e_debug", { hp = params[2] } )
  531.  
  532.     elseif params[1] == "/setwater" then
  533.         sm.event.sendToPlayer( player, "sv_e_debug", { water = params[2] } )
  534.  
  535.     elseif params[1] == "/setfood" then
  536.         sm.event.sendToPlayer( player, "sv_e_debug", { food = params[2] } )
  537.  
  538.     elseif params[1] == "/goto" then
  539.         local pos
  540.         if params[2] == "here" then
  541.             pos = player.character:getWorldPosition()
  542.         elseif params[2] == "start" then
  543.             pos = START_AREA_SPAWN_POINT
  544.         elseif params[2] == "hideout" then
  545.             pos = sm.vec3.new( 32, -1248, 100 )
  546.         else
  547.             self.network:sendToClient( player, "client_showMessage", "Unknown place" )
  548.         end
  549.         if pos then
  550.             local cellX, cellY = math.floor( pos.x/64 ), math.floor( pos.y/64 )
  551.             self.sv.saved.overworld:loadCell( cellX, cellY, player, "sv_recreatePlayerCharacter", { pos = pos, dir = player.character:getDirection() } )
  552.         end
  553.  
  554.     elseif params[1] == "/respawn" then
  555.         sm.event.sendToPlayer( player, "sv_e_respawn" )
  556.  
  557.     elseif params[1] == "/printglobals" then
  558.         print( "Globals:" )
  559.         for k,_ in pairs(_G) do
  560.             print( k )
  561.         end
  562.  
  563.     elseif params[1] == "/clearpathnodes"
  564.         or params[1] == "/enablepathpotatoes"
  565.         or params[1] == "/starterkit"
  566.         or params[1] == "/mechanicstartkit"
  567.         or params[1] == "/pipekit"
  568.         or params[1] == "/foodkit"
  569.         or params[1] == "/seedkit"
  570.         or params[1] == "/aggroall"
  571.         or params[1] == "/raid"
  572.         or params[1] == "/stopraid"
  573.         or params[1] == "/disableraids"
  574.     then
  575.         params.player = player
  576.         sm.event.sendToWorld( player.character:getWorld(), "sv_e_onChatCommand", params )
  577.     end
  578. end
  579.  
  580. function SurvivalGame.server_onPlayerJoined( self, player, newPlayer )
  581.     print( player.name, "joined the game" )
  582.  
  583.     if newPlayer then --Player is first time joiners
  584.         local inventory = player:getInventory()
  585.  
  586.         sm.container.beginTransaction()
  587.  
  588.         if g_survivalDev then
  589.             --Hotbar
  590.             sm.container.setItem( inventory, 0, tool_sledgehammer, 1 )
  591.             sm.container.setItem( inventory, 1, tool_spudgun, 1 )
  592.             sm.container.setItem( inventory, 6, obj_plantables_potato, 20 )
  593.             sm.container.setItem( inventory, 7, obj_plantables_potato, 20 )
  594.             sm.container.setItem( inventory, 8, tool_lift, 1 )
  595.             sm.container.setItem( inventory, 9, tool_connect, 1 )
  596.  
  597.             --Actual inventory
  598.             sm.container.setItem( inventory, 10, tool_paint, 1 )
  599.             sm.container.setItem( inventory, 11, tool_weld, 1 )
  600.         else
  601.             sm.container.setItem( inventory, 0, tool_sledgehammer, 1 )
  602.             sm.container.setItem( inventory, 1, tool_lift, 1 )
  603.         end
  604.  
  605.         sm.container.endTransaction()
  606.  
  607.         local spawnPoint = START_AREA_SPAWN_POINT
  608.         if g_survivalDev then
  609.             spawnPoint = SURVIVAL_DEV_SPAWN_POINT
  610.         end
  611.         if not sm.exists( self.sv.saved.overworld ) then
  612.             sm.world.loadWorld( self.sv.saved.overworld )
  613.         end
  614.         self.sv.saved.overworld:loadCell( math.floor( spawnPoint.x/64 ), math.floor( spawnPoint.y/64 ), player, "sv_createNewPlayer" )
  615.     end
  616.     g_respawnManager:sv_onPlayerJoined( player )
  617.     g_unitManager:sv_onPlayerJoined( player )
  618. end
  619.  
  620. function SurvivalGame.sv_e_saveWarehouses( self )
  621.     sm.storage.save( STORAGE_CHANNEL_WAREHOUSES, self.warehouses )
  622.     print( "Saved warehouses:" )
  623.     print( self.warehouses )
  624. end
  625.  
  626. function SurvivalGame.sv_e_requestWarehouseRestrictions( self, params )
  627.     -- Send the warehouse restrictions to the world that asked
  628.     print("SurvivalGame.sv_e_requestWarehouseRestrictions")
  629.  
  630.     -- Warehouse get
  631.     local warehouse = nil
  632.     if params.warehouseIndex then
  633.         warehouse = self.warehouses[params.warehouseIndex]
  634.     end
  635.     if warehouse then
  636.         sm.event.sendToWorld( params.world, "server_updateRestrictions", warehouse.restrictions )
  637.     end
  638. end
  639.  
  640. function SurvivalGame.sv_e_setWarehouseRestrictions( self, params )
  641.     -- Set the restrictions for this warehouse and propagate the restrictions to all floors
  642.  
  643.     -- Warehouse get
  644.     local warehouse = nil
  645.     if params.warehouseIndex then
  646.         warehouse = self.warehouses[params.warehouseIndex]
  647.     end
  648.  
  649.     if warehouse then
  650.         for _, newRestrictionSetting in pairs( params.restrictions ) do
  651.             if warehouse.restrictions[newRestrictionSetting.name] then
  652.                 warehouse.restrictions[newRestrictionSetting.name].state = newRestrictionSetting.state
  653.             else
  654.                 warehouse.restrictions[newRestrictionSetting.name] = newRestrictionSetting
  655.             end
  656.         end
  657.         self.warehouses[params.warehouseIndex] = warehouse
  658.         self:sv_e_saveWarehouses()
  659.  
  660.         for i, world in ipairs( warehouse.worlds ) do
  661.             if sm.exists( world ) then
  662.                 sm.event.sendToWorld( world, "server_updateRestrictions", warehouse.restrictions )
  663.             end
  664.         end
  665.     end
  666. end
  667.  
  668. function SurvivalGame.sv_e_createElevatorDestination( self, params )
  669.     print( "SurvivalGame.sv_e_createElevatorDestination" )
  670.     print( params )
  671.  
  672.     -- Warehouse get or create
  673.     local warehouse
  674.     if params.warehouseIndex then
  675.         warehouse = self.warehouses[params.warehouseIndex]
  676.     else
  677.         assert( params.name == "ELEVATOR_ENTRANCE" )
  678.         warehouse = {}
  679.         warehouse.world = params.portal:getWorldA()
  680.         warehouse.worlds = {}
  681.         warehouse.exits = params.exits
  682.         warehouse.maxLevels = params.maxLevels
  683.         warehouse.index = #self.warehouses + 1
  684.         warehouse.restrictions = { erasable = { name = "erasable", state = false }, connectable = { name = "connectable", state = false } }
  685.         self.warehouses[#self.warehouses + 1] = warehouse
  686.         self:sv_e_saveWarehouses()
  687.     end
  688.  
  689.  
  690.     -- Level up
  691.     local level
  692.     if params.level then
  693.         if params.name == "ELEVATOR_UP" then
  694.             level = params.level + 1
  695.         elseif params.name == "ELEVATOR_DOWN" then
  696.             level = params.level - 1
  697.         elseif params.name == "ELEVATOR_EXIT" then
  698.             if #warehouse.exits > 0 then
  699.                 for _,cell in ipairs( warehouse.exits ) do
  700.                     local name = params.name.." "..cell.x..","..cell.y
  701.                     sm.portal.addWorldPortalHook( warehouse.world, name, params.portal )
  702.                     print( "Added portal hook '"..name.."' in world "..warehouse.world.id )
  703.  
  704.                     for _,object in ipairs( params.portal:getContentsA() ) do
  705.                         if type( object ) == "Character" then
  706.                             local player = object:getPlayer()
  707.                             if player then
  708.                                 print( "Loading cell", cell.x..", "..cell.y, "in world", warehouse.world.id )
  709.                                 warehouse.world:loadCell( cell.x, cell.y, player, "sv_e_elevatorCellLoaded" )
  710.                             end
  711.                         end
  712.                     end
  713.                 end
  714.             else
  715.                 print( "No exit hint found, this elevator is going nowhere!" )
  716.             end
  717.             return
  718.         else
  719.             assert( false )
  720.         end
  721.     else
  722.         if params.name == "ELEVATOR_EXIT" then
  723.             level = warehouse.maxLevels
  724.         elseif params.name == "ELEVATOR_ENTRANCE" then
  725.             level = 1
  726.         else
  727.         end
  728.     end
  729.  
  730.     -- Create warehouse world
  731.     local worldData = {}
  732.     worldData.level = level
  733.     worldData.warehouseIndex = warehouse.index
  734.     worldData.maxLevels = warehouse.maxLevels
  735.     local world = sm.world.createWorld( "$SURVIVAL_DATA/Scripts/game/worlds/WarehouseWorld.lua", "WarehouseWorld", worldData )
  736.     print( "Created WarehouseWorld "..world.id )
  737.  
  738.     -- Use the same restrictions for the new floor as the other floors
  739.     warehouse.worlds[#warehouse.worlds+1] = world
  740.     if warehouse.restrictions then
  741.         sm.event.sendToWorld( world, "server_updateRestrictions", warehouse.restrictions )
  742.     end
  743.     -- Elevator portal hook
  744.     local name
  745.     if params.name == "ELEVATOR_UP" then
  746.         name = "ELEVATOR_DOWN"
  747.     elseif params.name == "ELEVATOR_DOWN" then
  748.         name = "ELEVATOR_UP"
  749.     else
  750.         name = params.name
  751.     end
  752.     sm.portal.addWorldPortalHook( world, name, params.portal )
  753.     print( "Added portal hook '"..name.."' in world "..world.id )
  754.  
  755.     print( "Contents A:" )
  756.     print( params.portal:getContentsA() )
  757.  
  758.     for _,object in ipairs( params.portal:getContentsA() ) do
  759.         if type( object ) == "Character" then
  760.             local player = object:getPlayer()
  761.             if player then
  762.                 print( "Loading cell 0, 0 in world", world.id )
  763.                 world:loadCell( 0, 0, player, "sv_e_elevatorCellLoaded" )
  764.             end
  765.         end
  766.     end
  767. end
  768.  
  769. function SurvivalGame.sv_createNewPlayer( self, world, x, y, player )
  770.     local params = { player = player, x = x, y = y }
  771.     sm.event.sendToWorld( self.sv.saved.overworld, "sv_spawnNewCharacter", params )
  772. end
  773.  
  774. function SurvivalGame.sv_recreatePlayerCharacter( self, world, x, y, player, params )
  775.     local yaw = math.atan2( params.dir.y, params.dir.x ) - math.pi/2
  776.     local pitch = math.asin( params.dir.z )
  777.     local newCharacter = sm.character.createCharacter( player, self.sv.saved.overworld, params.pos, yaw, pitch )
  778.     player:setCharacter( newCharacter )
  779.     print( "Recreate character in new world" )
  780.     print( params )
  781. end
  782.  
  783. function SurvivalGame.sv_e_prepareCell( self, params )
  784.     if sm.exists( params.world ) == false then
  785.         sm.world.loadWorld( params.world )
  786.     end
  787.     for _,player in ipairs( params.players ) do
  788.         print( "Loading cell", params.cellX..", "..params.cellY, "in world", params.world.id, "for player", player )
  789.         params.world:loadCell( params.cellX, params.cellY, player, "sv_e_elevatorCellLoaded" )
  790.     end
  791. end
  792.  
  793. function SurvivalGame.sv_e_elevatorCellLoaded( self, world, x, y, player )
  794.     print( "SurvivalGame: World "..world.id.." cell ("..x..","..y..") loaded for player "..player.id )
  795. end
  796.  
  797. function SurvivalGame.sv_e_respawn( self, params )
  798.     if params.player.character and sm.exists( params.player.character ) then
  799.         g_respawnManager:sv_requestRespawnCharacter( params.player )
  800.     else
  801.         local spawnPoint = START_AREA_SPAWN_POINT
  802.         if g_survivalDev then
  803.             spawnPoint = SURVIVAL_DEV_SPAWN_POINT
  804.         end
  805.         self.saved.overworld:loadCell( math.floor( spawnPoint.x/64 ), math.floor( spawnPoint.y/64 ), params.player, "sv_createNewPlayer" )
  806.     end
  807. end
  808.  
  809. function SurvivalGame.sv_loadedRespawnCell( self, world, x, y, player )
  810.     g_respawnManager:sv_respawnCharacter( player, world )
  811. end
  812.  
  813. function SurvivalGame.sv_e_markBag( self, params )
  814.     sm.event.sendToWorld( params.world, "sv_e_markBag", params )
  815. end
  816.  
  817. function SurvivalGame.sv_e_unmarkBag( self, params )
  818.     sm.event.sendToWorld( params.world, "sv_e_unmarkBag", params )
  819. end
Add Comment
Please, Sign In to add comment