Advertisement
Guest User

Untitled

a guest
Jan 21st, 2020
228
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 42.72 KB | None | 0 0
  1. if not SERVER then return end
  2. zfs = zfs or {}
  3. zfs.f = zfs.f or {}
  4.  
  5. ////////////////////////////////
  6.  
  7. zfs.Shop_Interactions = {}
  8.  
  9.  
  10. util.AddNetworkString("zfs_AnimEvent")
  11. util.AddNetworkString("zfs_ItemPriceChange_cl")
  12. util.AddNetworkString("zfs_ItemPriceChange_sv")
  13. util.AddNetworkString("zfs_ItemSellWindowClose_sv")
  14. util.AddNetworkString("zfs_shop_FX")
  15. util.AddNetworkString("zfs_UpdateStorage")
  16.  
  17. // This Handels Price Change
  18. net.Receive("zfs_ItemPriceChange_sv", function(len, ply)
  19.     if zfs.f.NW_Player_Timeout(ply) then return end
  20.  
  21.     local ChangedPriceInfo = net.ReadTable()
  22.     local newPrice = ChangedPriceInfo.ChangedPrice
  23.     local shop = ChangedPriceInfo.Shop
  24.  
  25.     if (IsValid(shop) and shop:GetClass() == "zfs_shop") then
  26.         if newPrice < zfs.config.Price.Minimum then
  27.             zfs.f.Notify(ply, zfs.language.Shop.ChangePrice_PriceMinimum .. tostring(zfs.config.Price.Minimum) .. tostring(zfs.config.Currency), 1)
  28.  
  29.             return
  30.         end
  31.  
  32.         if newPrice > zfs.config.Price.Maximum then
  33.             zfs.f.Notify(ply, zfs.language.Shop.ChangePrice_PriceMaximum .. tostring(zfs.config.Price.Maximum) .. tostring(zfs.config.Currency), 1)
  34.  
  35.             return
  36.         end
  37.  
  38.         local ahzdistance = false
  39.  
  40.         if zfs.f.InDistance(ply:GetPos(), shop:GetPos(),  200) then
  41.             ahzdistance = true
  42.         end
  43.  
  44.         if not ply:Alive() or not ahzdistance then return end
  45.         // Function do change price
  46.         zfs.f.Notify(ply, zfs.language.Shop.ChangePrice_PriceChanged .. tostring(newPrice) .. tostring(zfs.config.Currency) .. "!", 0)
  47.         shop:SetPPrice(newPrice)
  48.     end
  49. end)
  50.  
  51. ////////////////////////////////
  52. local iconSize = 50
  53. local margin = 3
  54. local ScreenW, ScreenH = 390, 260
  55. local productBoxX, productBoxY = -ScreenW * 0.61, -ScreenH * 0.36
  56. ////////////////////////////////
  57.  
  58.  
  59.  
  60. //////////////////////////////////////////////////////////////
  61. /////////////////////// Initialize ///////////////////////////
  62. //////////////////////////////////////////////////////////////
  63.  
  64. // Called when the Shop Initializes
  65. function zfs.f.Shop_Initialize(Shop)
  66.     zfs.f.EntList_Add(Shop)
  67.     Shop:SetSkin(zfs.config.Theme)
  68.  
  69.     // This function tells the Clients too use the Animation Played on Client instead of the animation data that gets send from the ServerAnim
  70.     Shop:UseClientSideAnimation()
  71.  
  72.     zfs.f.Shop_SpawnMixer(Shop)
  73.  
  74.     Shop.Sweeteners = {}
  75.     Shop.Sweeteners["Milk"] = zfs.f.Shop_SpawnSweetener(Shop,"Milk", 0, 0, 10)
  76.     Shop.Sweeteners["Coffe"] = zfs.f.Shop_SpawnSweetener(Shop,"Coffe", 1, 11, 0)
  77.     Shop.Sweeteners["Chocolate"] = zfs.f.Shop_SpawnSweetener(Shop,"Chocolate", 2, 22, -10)
  78.  
  79.     //Thats the stuff we need do call with a little delay
  80.     timer.Simple(1, function()
  81.         if IsValid(Shop) then
  82.  
  83.             // Our Sell Table and Product Count
  84.             Shop.ProductCount = 0
  85.             zfs.f.Shop_SetupSellTable(Shop)
  86.  
  87.             // Resets all of our Vars
  88.             zfs.f.Shop_action_Restart(Shop)
  89.             zfs.f.Shop_ChangeState(Shop,0)
  90.             zfs.f.CreateAnimTable(Shop,"idle_turnedoff", 1)
  91.  
  92.             zfs.f.Shop_StartStorage(Shop)
  93.         end
  94.     end)
  95.  
  96.     // The States i use, just here as a reminder
  97.     //["DISABLED"] = 0
  98.     //["MENU"] = 1
  99.     //["STORAGE"] = 2
  100.     //["ORDERING"] = 3
  101.     //["CONFIRMING_PRODUCT"] = 4
  102.     //["CUP_CHOOSETOPPING"] = 5
  103.     //["CONFIRMING_TOPPING"] = 6
  104.     //["WAIT_FOR_CUP"] = 7
  105.     //["SLICE_FRUITS"] = 8
  106.     //["WAIT_FOR_SWEETENER"] = 9
  107.     //["FILLING_SWEETENER"] = 10
  108.     //["WAIT_FOR_MIXERBUTTON"] = 11
  109.     //["MIXING"] = 12
  110. end
  111.  
  112. //////////////////////////////////////////////////////////////
  113. //////////////////////////////////////////////////////////////
  114.  
  115.  
  116. //////////////////////////////////////////////////////////////
  117. ////////////////////////// Setup /////////////////////////////
  118. //////////////////////////////////////////////////////////////
  119. // This Spawns Our Sweeteners
  120. function zfs.f.Shop_SpawnSweetener(Shop,sweettype, skin, right, AngleOffset)
  121.     local ent = ents.Create("zfs_sweetener_base")
  122.     local attach = Shop:GetAttachment(Shop:LookupAttachment("workplace"))
  123.  
  124.     if attach and IsValid(ent) then
  125.         local ang = Shop:GetAngles()
  126.         ang:RotateAroundAxis(Shop:GetUp(), -90 + AngleOffset)
  127.         ent:SetAngles(ang)
  128.         ent:SetPos(attach.Pos + Shop:GetUp() * 6 + Shop:GetForward() * -12 + Shop:GetForward() * right)
  129.  
  130.         ent:Spawn()
  131.         ent:Activate()
  132.  
  133.         ent:SetParent(Shop)
  134.         ent:SetSkin(skin)
  135.         ent:SetNoDraw(true)
  136.         ent.SweetenerType = sweettype
  137.         Shop:DeleteOnRemove(ent)
  138.         ent.PhysgunDisabled = true
  139.  
  140.         if zfs.config.SharedEquipment == false then
  141.             zfs.f.SetOwnerID(ent, zfs.f.GetOwner(Shop))
  142.         end
  143.     end
  144.     return ent
  145. end
  146.  
  147. // This Spawns Mixer
  148. function zfs.f.Shop_SpawnMixer(Shop)
  149.     local ent = ents.Create("zfs_mixer")
  150.     local attachInfo = Shop:GetAttachment(Shop:LookupAttachment("mixer_floor"))
  151.     if attachInfo and IsValid(ent) then
  152.         local ang = attachInfo.Ang
  153.         ang:RotateAroundAxis(Shop:GetUp(), -90)
  154.         ent:SetAngles(ang)
  155.         ent:SetPos(attachInfo.Pos)
  156.  
  157.         ent:Spawn()
  158.         ent:Activate()
  159.         ent:PhysicsInit(SOLID_VPHYSICS)
  160.         ent:SetSolid(SOLID_VPHYSICS)
  161.         ent:SetMoveType(MOVETYPE_NONE)
  162.         ent:SetCollisionGroup(COLLISION_GROUP_WEAPON)
  163.         local phys = ent:GetPhysicsObject()
  164.  
  165.         if (phys:IsValid()) then
  166.             phys:Wake()
  167.         end
  168.  
  169.         ent:SetParent(Shop, Shop:LookupAttachment("mixer_floor"))
  170.         Shop.Mixer = ent
  171.         Shop:DeleteOnRemove(ent)
  172.         ent.PhysgunDisabled = true
  173.         if zfs.config.SharedEquipment == false then
  174.             zfs.f.SetOwnerID(ent, zfs.f.GetOwner(Shop))
  175.         end
  176.     end
  177. end
  178.  
  179. // This is gonna setups our SellTable
  180. function zfs.f.Shop_SetupSellTable(Shop)
  181.     local tableCount = 16
  182.     local moveSize = 8
  183.     local x, y = 1, 1
  184.     local currpos = 2
  185.  
  186.     local attach = Shop:GetAttachment(Shop:LookupAttachment("sellpoint"))
  187.  
  188.     if attach then
  189.         for i = 0, tableCount - 1 do
  190.             local pos = attach.Pos + (Shop:GetForward() * x) + (Shop:GetRight() * y)
  191.  
  192.  
  193.             zfs.f.Debug_Sphere(pos,1,1,zfs.default_colors["red07"],true)
  194.  
  195.             if Shop.SellTable == nil then
  196.                 Shop.SellTable = {}
  197.             end
  198.  
  199.             Shop.SellTable[i] = {}
  200.             Shop.SellTable[i].Pos = Shop:WorldToLocal(pos)
  201.             Shop.SellTable[i].IsEmpty = true
  202.             Shop.SellTable[i].Entity = nil
  203.  
  204.             if (currpos > 8) then
  205.                 currpos = 1
  206.                 y = y + moveSize
  207.                 x = 1
  208.             else
  209.                 x = x + moveSize
  210.                 currpos = currpos + 1
  211.             end
  212.         end
  213.     end
  214. end
  215. //////////////////////////////////////////////////////////////
  216. //////////////////////////////////////////////////////////////
  217.  
  218.  
  219.  
  220.  
  221.  
  222. //////////////////////////////////////////////////////////////
  223. ////////////////////////// Touch /////////////////////////////
  224. //////////////////////////////////////////////////////////////
  225. function zfs.f.Shop_OnTouch(Shop, other)
  226.     if not IsValid(Shop) or not IsValid(other) then return end
  227.     if string.sub( other:GetClass(), 1, 13 ) ~= "zfs_fruitbox_"  then return end
  228.  
  229.     if zfs.f.CollisionCooldown(other) then return end
  230.  
  231.     zfs.f.Shop_FillStorage(Shop, other.FruitType, other.FruitAmount, true)
  232.     SafeRemoveEntity(other)
  233. end
  234.  
  235.  
  236. //////////////////////////////////////////////////////////////
  237. //////////////////////////////////////////////////////////////
  238.  
  239.  
  240.  
  241.  
  242.  
  243. //////////////////////////////////////////////////////////////
  244. //////////////////////// Storage /////////////////////////////
  245. //////////////////////////////////////////////////////////////
  246.  
  247. // Fills our storage on Init
  248. function zfs.f.Shop_StartStorage(Shop)
  249.     for k, v in pairs(zfs.config.StartStorage) do
  250.         zfs.f.Shop_FillStorage(Shop,k, v, false)
  251.     end
  252. end
  253.  
  254. // Adds a specified fruit and amount in our storage
  255. function zfs.f.Shop_FillStorage(Shop,fruittype, amount, PlaySound)
  256.     if Shop.StoredIngrediens == nil then
  257.         Shop.StoredIngrediens = {}
  258.     end
  259.  
  260.     local inStoreFruits = Shop.StoredIngrediens[fruittype]
  261.  
  262.     if inStoreFruits == nil then
  263.         inStoreFruits = 0
  264.     end
  265.  
  266.     Shop.StoredIngrediens[fruittype] = inStoreFruits + amount
  267.     zfs.f.Shop_UpdateNetStorage(Shop)
  268.  
  269.     if PlaySound then
  270.         zfs.f.CreateEffectTable(nil, "zfs_sfx_FillStorage", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  271.     end
  272. end
  273.  
  274. // Removes a specified fruit and amount from our storage
  275. function zfs.f.Shop_RemoveStorage(Shop,fruittype, amount)
  276.     if Shop.StoredIngrediens == nil then
  277.         Shop.StoredIngrediens = {}
  278.     end
  279.  
  280.     local inStoreFruits = Shop.StoredIngrediens[fruittype]
  281.  
  282.     if inStoreFruits == nil then
  283.         inStoreFruits = 0
  284.     end
  285.  
  286.     Shop.StoredIngrediens[fruittype] = inStoreFruits - amount
  287.     zfs.f.Shop_UpdateNetStorage(Shop)
  288. end
  289.  
  290. // This sends our current Storage to the Client
  291. function zfs.f.Shop_UpdateNetStorage(Shop)
  292.     if (Shop.StoredIngrediens == nil or table.Count(Shop.StoredIngrediens) <= 0) then
  293.         return
  294.     end
  295.  
  296.     local a_String = util.TableToJSON(Shop.StoredIngrediens)
  297.     local a_Compressed = util.Compress(a_String)
  298.  
  299.     net.Start("zfs_UpdateStorage")
  300.     net.WriteEntity(Shop)
  301.     net.WriteUInt(#a_Compressed, 16)
  302.     net.WriteData(a_Compressed, #a_Compressed)
  303.     net.SendPVS(Shop:GetPos())
  304. end
  305. //////////////////////////////////////////////////////////////
  306. //////////////////////////////////////////////////////////////
  307.  
  308.  
  309.  
  310. //////////////////////////////////////////////////////////////
  311. ////////////////////// Sell Table ////////////////////////////
  312. //////////////////////////////////////////////////////////////
  313. // This is gonna Search a empty positon on our table
  314. function zfs.f.Shop_FindEmptyPosOnSellTable(Shop)
  315.     local freePos
  316.  
  317.     for i = 0, table.Count(Shop.SellTable) - 1 do
  318.         if Shop.SellTable[i].IsEmpty then
  319.             freePos = i
  320.             break
  321.         end
  322.     end
  323.  
  324.     if (freePos) then
  325.         return freePos
  326.     else
  327.         zfs.f.Debug("Sell Place Full!")
  328.  
  329.         return false
  330.     end
  331. end
  332.  
  333. // This Adds a Product to our SellTable
  334. function zfs.f.Shop_AddProductToSellTable(Shop,Product)
  335.     Shop.ProductCount = Shop.ProductCount + 1
  336.  
  337.     local EMPTY_Pos = zfs.f.Shop_FindEmptyPosOnSellTable(Shop)
  338.     if EMPTY_Pos then
  339.         Product.SellTable_Index = EMPTY_Pos
  340.  
  341.         Shop.SellTable[EMPTY_Pos].Entity = Product
  342.         Shop.SellTable[EMPTY_Pos].IsEmpty = false
  343.  
  344.         Product:SetPos(Shop.SellTable[EMPTY_Pos].Pos)
  345.  
  346.         local attach = Shop:GetAttachment(Shop:LookupAttachment("sellpoint"))
  347.         if attach then
  348.             Product:SetAngles(attach.Ang)
  349.         end
  350.     end
  351. end
  352.  
  353. // This Removes a Product from our SellTable
  354. function zfs.f.Shop_RemoveProductToSellTable(Shop,Product, index)
  355.     Shop.ProductCount = Shop.ProductCount - 1
  356.  
  357.     Shop.SellTable[index].Entity:Remove()
  358.     Shop.SellTable[index].Entity = nil
  359.     Shop.SellTable[index].IsEmpty = true
  360. end
  361.  
  362. // Here we look if we have a free place on our table
  363. function zfs.f.Shop_Has_SellTable_EmptySpot(Shop)
  364.     local freePos
  365.  
  366.     for i = 0, table.Count(Shop.SellTable) - 1 do
  367.         if (Shop.SellTable[i].IsEmpty) then
  368.             freePos = i
  369.             break
  370.         end
  371.     end
  372.  
  373.     if (freePos) then
  374.         zfs.f.Debug("Free Place at position: " .. freePos)
  375.  
  376.         return true
  377.     else
  378.         zfs.f.Debug("Sell Place Full!")
  379.  
  380.         return false
  381.     end
  382. end
  383. //////////////////////////////////////////////////////////////
  384. //////////////////////////////////////////////////////////////
  385.  
  386.  
  387.  
  388. //////////////////////////////////////////////////////////////
  389. ////////////////////// Interaction ////////////////////////////
  390. //////////////////////////////////////////////////////////////
  391.  
  392.  
  393. //This creates a Trace for determining if the Screen got hit
  394. function zfs.f.Shop_Use(ply,Shop)
  395.     if not zfs.f.IsOwner(ply, Shop) then
  396.         zfs.f.Notify(ply, zfs.language.Shop.NotOwner, 1)
  397.  
  398.         return
  399.     end
  400.  
  401.     if table.Count(zfs.config.AllowedJobs) > 0 and zfs.config.AllowedJobs[zfs.f.GetPlayerJob(ply)] == nil then
  402.         zfs.f.Notify(ply, zfs.language.Shop.WrongJob, 1)
  403.  
  404.         return
  405.     end
  406.  
  407.     local occ_ply = Shop:GetOccupiedPlayer()
  408.  
  409.     if IsValid(occ_ply) and ply ~= occ_ply then
  410.  
  411.         return
  412.     end
  413.  
  414.     if Shop:GetIsBusy() then return end
  415.     local localTrace
  416.     localTrace = ply:GetEyeTrace()
  417.  
  418.     if localTrace and zfs.f.InDistance(ply:GetPos(), localTrace.HitPos, 300) and IsValid(localTrace.Entity) and localTrace.Entity == Shop then
  419.         zfs.f.Shop_UseLogic(Shop,localTrace, ply)
  420.     end
  421. end
  422.  
  423. //Here do we check what Button the trace is hitting
  424. function zfs.f.Shop_UseLogic(Shop,trace, ply)
  425.     local lTrace = Shop:WorldToLocal(trace.HitPos)
  426.  
  427.     if (Shop:GetCurrentState() == 7 and lTrace.x < -26 and lTrace.x > -42 and lTrace.y < 25 and lTrace.y > 13 and lTrace.z < 51 and lTrace.z > 35) then
  428.         zfs.f.Shop_action_PlaceCup(Shop)
  429.     end
  430.  
  431.     zfs.f.Shop_GUILogic(Shop,trace, ply)
  432. end
  433.  
  434. //Check if we are inside a 2D area relativ from the Root of the Entity
  435. function zfs.f.Shop_CalcWorldElementPos(trace, xStart, xEnd, yStart, yEnd)
  436.     if trace.x < xStart and trace.x > xEnd and trace.y < yStart and trace.y > yEnd then
  437.         return true
  438.     else
  439.         return false
  440.     end
  441. end
  442.  
  443. // This return true if the values are inside the Local Vector relative too the Screen
  444. function zfs.f.Shop_CalcLocalScreenPos(Shop, trace, xStart, xEnd, yStart, yEnd)
  445.     local attach = Shop:GetAttachment(Shop:LookupAttachment("screen"))
  446.  
  447.     if attach then
  448.         local AttaPos = attach.Pos
  449.         local AttaAng = attach.Ang
  450.         AttaAng:RotateAroundAxis(AttaAng:Up(), -90)
  451.         AttaAng:RotateAroundAxis(AttaAng:Right(), 180)
  452.         local lpos = WorldToLocal(trace.HitPos, Angle(0, 0, 0), AttaPos, AttaAng)
  453.  
  454.         if lpos.x < xStart and lpos.x > xEnd and lpos.y < yStart and lpos.y > yEnd then
  455.             return true
  456.         else
  457.             return false
  458.         end
  459.     else
  460.         return false
  461.     end
  462. end
  463.  
  464. // Our UI Logic
  465. function zfs.f.Shop_GUILogic(Shop,trace, ply)
  466.     local rootTrace = Shop:WorldToLocal(trace.HitPos)
  467.  
  468.     // Check if we hit the Screen
  469.     if zfs.f.Shop_CalcLocalScreenPos(Shop,trace, 14, -14, 8.5, -8.5) then
  470.  
  471.         if Shop:GetCurrentState() == 0 then
  472.             // Enables the Stand and goes to the menu
  473.             if zfs.f.Shop_CalcWorldElementPos(rootTrace, -18.5, -30, 19.7, 17) then
  474.                 zfs.f.Shop_action_Enable(Shop)
  475.             end
  476.         elseif Shop:GetCurrentState() == 1 then
  477.             // Disable
  478.             if zfs.f.Shop_CalcWorldElementPos(rootTrace, -12, -20, 20, 18.2) then
  479.                 zfs.f.Shop_action_Disable(Shop)
  480.             end
  481.  
  482.             //Make Product
  483.             if zfs.f.Shop_CalcWorldElementPos(rootTrace, -21, -29, 20, 18.2) then
  484.                 zfs.f.Shop_Player_StartUse(Shop,ply)
  485.                 zfs.f.Shop_action_MakeProduct(Shop)
  486.             end
  487.  
  488.             //Show Storage
  489.             if zfs.f.Shop_CalcWorldElementPos(rootTrace, -29, -37, 20, 18.2) then
  490.                 zfs.f.Shop_Player_StartUse(Shop,ply)
  491.                 zfs.f.Shop_action_GoToStorage(Shop)
  492.             end
  493.         elseif (Shop:GetCurrentState() == 2) then
  494.             // BackToTheMenu
  495.             if zfs.f.Shop_CalcWorldElementPos(rootTrace, -33, -37.5, 21, 20.5) then
  496.                 zfs.f.Shop_action_GoToMenu(Shop)
  497.             end
  498.         elseif (Shop:GetCurrentState() == 3 and Shop:GetTSelectedItem() == -1) then
  499.             // BackToTheMenu
  500.             if zfs.f.Shop_CalcWorldElementPos(rootTrace, -33, -37.5, 21, 20.5) then
  501.                 zfs.f.Shop_action_GoToMenu(Shop)
  502.             end
  503.  
  504.             if (Shop.ProductCount < 16) then
  505.                 zfs.f.Shop_UI_ProductSelection(Shop,trace)
  506.             else
  507.                 zfs.f.Notify(ply, zfs.language.Shop.SellTableFull, 1)
  508.             end
  509.         elseif (Shop:GetCurrentState() == 4 and Shop:GetTSelectedItem() ~= -1) then
  510.  
  511.             // Change Price
  512.             // Open vgui for custom price text entry
  513.             if zfs.config.Price.Custom and zfs.f.Shop_CalcWorldElementPos(rootTrace, -34, -37, 20.25, 19.7) and Shop:GetTSelectedItem() then
  514.                 local PriceChangeInfo = {}
  515.                 PriceChangeInfo.Price = Shop:GetPPrice()
  516.                 PriceChangeInfo.selectedItem = Shop:GetTSelectedItem()
  517.                 PriceChangeInfo.Shop = Shop
  518.  
  519.                 net.Start("zfs_ItemPriceChange_cl")
  520.                 net.WriteTable(PriceChangeInfo)
  521.                 net.Send(ply)
  522.             end
  523.  
  524.             // Confirm
  525.             if zfs.f.Shop_CalcWorldElementPos(rootTrace, -12, -23, 17.3, 16.6) and not zfs.f.Shop_MissingFruits(Shop,zfs.config.FruitCups[Shop:GetTSelectedItem()],ply) then
  526.                 zfs.f.Shop_action_ConfirmItem(Shop)
  527.             end
  528.  
  529.             //Cancel
  530.             if zfs.f.Shop_CalcWorldElementPos(rootTrace, -25, -36, 17.3, 16.6) then
  531.                 zfs.f.Shop_action_CancelItem(Shop)
  532.                 zfs.f.Shop_ChangeState(Shop,3)
  533.             end
  534.         elseif (Shop:GetCurrentState() == 5) then
  535.  
  536.             zfs.f.Shop_UI_ToppingSelection(Shop,trace)
  537.  
  538.             if (Shop:GetTSelectedTopping() ~= -1) then
  539.                 zfs.f.Shop_ChangeState(Shop,6)
  540.             end
  541.  
  542.             // Cancel
  543.             if zfs.f.Shop_CalcWorldElementPos(rootTrace, -33, -37.5, 21, 20.5) then
  544.                 zfs.f.Shop_action_CancelItem(Shop)
  545.             end
  546.         elseif (Shop:GetCurrentState() == 6 and Shop:GetTSelectedTopping() ~= -1) then
  547.             if (Shop:GetTSelectedTopping() ~= -1) then
  548.                 // Confirm
  549.                 if zfs.f.Shop_CalcWorldElementPos(rootTrace, -12, -23, 17.5, 16.5) then
  550.                     zfs.f.Shop_action_ConfirmTopping(Shop,ply)
  551.                 end
  552.  
  553.                 //Cancel
  554.                 if zfs.f.Shop_CalcWorldElementPos(rootTrace, -25, -36, 17.5, 16.5) then
  555.                     zfs.f.Shop_action_CancelTopping(Shop)
  556.                 end
  557.             end
  558.         end
  559.     end
  560. end
  561.  
  562. //Check if we clicked a Product
  563. function zfs.f.Shop_UI_ProductSelection(Shop,trace)
  564.     local attach = Shop:GetAttachment(Shop:LookupAttachment("screen"))
  565.  
  566.     if attach == nil then return end
  567.  
  568.     local AttaPos = attach.Pos
  569.     local AttaAng = attach.Ang
  570.     AttaAng:RotateAroundAxis(AttaAng:Up(), -90)
  571.     AttaAng:RotateAroundAxis(AttaAng:Right(), 180)
  572.  
  573.     for i, k in pairs(zfs.config.FruitCups) do
  574.         local x, y = zfs.f.Shop_CalcNextLine(i, iconSize, margin, productBoxX, productBoxY)
  575.         local newVec = Vector(x, y, 1)
  576.         local size = Vector(25, 25, -10)
  577.         newVec:Add(size)
  578.         newVec:Mul(0.07)
  579.         local wpos = LocalToWorld(newVec, Angle(0, 0, 0), AttaPos, AttaAng)
  580.  
  581.         if zfs.f.InDistance(trace.HitPos, wpos, 1.8) then
  582.             zfs.f.CreateEffectTable(nil, "zfs_sfx_item_select", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  583.             Shop:SetTSelectedItem(i)
  584.             Shop:SetPPrice(zfs.config.FruitCups[Shop:GetTSelectedItem()].Price)
  585.             zfs.f.Shop_ChangeState(Shop,4)
  586.         end
  587.     end
  588. end
  589.  
  590. //Check if we have enough Fruits do make the Product
  591. function zfs.f.Shop_MissingFruits(Shop,fruitcupdata,ply)
  592.     local missingFruits = {}
  593.     local hasMissingFruits = false
  594.  
  595.     for k, v in pairs(fruitcupdata.recipe) do
  596.         local StoredFruitCount = Shop.StoredIngrediens[k]
  597.  
  598.         if (StoredFruitCount == nil) then
  599.             StoredFruitCount = 0
  600.         end
  601.  
  602.         if (StoredFruitCount < v) then
  603.             missingFruits[k] = v - StoredFruitCount
  604.         end
  605.     end
  606.  
  607.     for k, v in pairs(missingFruits) do
  608.         if (v > 0) then
  609.             hasMissingFruits = true
  610.             break
  611.         end
  612.     end
  613.  
  614.     if hasMissingFruits and IsValid(ply) then
  615.         zfs.f.Notify(ply, zfs.language.Shop.MissingFruits, 1)
  616.     end
  617.  
  618.     return hasMissingFruits
  619. end
  620.  
  621. //Check if we clicked a Topping
  622. function zfs.f.Shop_UI_ToppingSelection(Shop,trace)
  623.     local attach = Shop:GetAttachment(Shop:LookupAttachment("screen"))
  624.  
  625.     if attach == nil then return end
  626.  
  627.     local AttaPos = attach.Pos
  628.     local AttaAng = attach.Ang
  629.     AttaAng:RotateAroundAxis(AttaAng:Up(), -90)
  630.     AttaAng:RotateAroundAxis(AttaAng:Right(), 180)
  631.  
  632.     for i, k in pairs(zfs.utility.SortedToppingsTable) do
  633.         local x, y = zfs.f.Shop_CalcNextLine(i, iconSize, margin, productBoxX, productBoxY)
  634.         local newVec = Vector(x, y, 1)
  635.         local size = Vector(25, 25, -10)
  636.         newVec:Add(size)
  637.         newVec:Mul(0.07)
  638.         local wpos = LocalToWorld(newVec, Angle(0, 0, 0), AttaPos, AttaAng)
  639.  
  640.         if zfs.f.InDistance(trace.HitPos, wpos, 1.8) then
  641.             Shop:SetTSelectedTopping(i)
  642.             zfs.f.CreateEffectTable(nil, "zfs_sfx_item_select", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  643.         end
  644.     end
  645. end
  646.  
  647. // Calculate all of the Item Positions
  648. function zfs.f.Shop_CalcNextLine(itemCount, aiconSize, amargin, aproductBoxX, aproductBoxY)
  649.     local ypos = 0
  650.     local xpos = 0
  651.     local rowCount = 7
  652.  
  653.     if (itemCount > rowCount * 3) then
  654.         ypos = aproductBoxY + (aiconSize * 3 + amargin * 4)
  655.         xpos = aproductBoxX + (aiconSize + amargin) * (itemCount - (rowCount * 3))
  656.     elseif (itemCount > rowCount * 2) then
  657.         ypos = aproductBoxY + (aiconSize * 2 + amargin * 3)
  658.         xpos = aproductBoxX + (aiconSize + amargin) * (itemCount - (rowCount * 2))
  659.     elseif (itemCount > rowCount) then
  660.         ypos = aproductBoxY + (aiconSize + amargin * 2)
  661.         xpos = aproductBoxX + (aiconSize + amargin) * (itemCount - rowCount)
  662.     else
  663.         ypos = aproductBoxY + amargin
  664.         xpos = aproductBoxX + (aiconSize + amargin) * itemCount
  665.     end
  666.  
  667.     return xpos, ypos
  668. end
  669.  
  670.  
  671.  
  672.  
  673.  
  674. local ResetState = {}
  675. ResetState[1] = true
  676. ResetState[2] = true
  677. ResetState[3] = true
  678. ResetState[4] = true
  679. ResetState[5] = true
  680. ResetState[6] = true
  681. ResetState[7] = false
  682. ResetState[8] = false
  683. ResetState[9] = false
  684. ResetState[10] = false
  685. ResetState[11] = false
  686. ResetState[12] = false
  687.  
  688. // This function is used to Reset the entity if the player aborts his action/Moves too far away or dies
  689. function zfs.f.Shop_ForceReset(Shop)
  690.     zfs.f.Debug("zfs.f.Shop_ForceReset")
  691.     local curState = Shop:GetCurrentState()
  692.  
  693.     if ResetState[curState] then
  694.  
  695.         zfs.f.Shop_Player_StopUse(Shop)
  696.  
  697.         zfs.f.CreateEffectTable(nil, "zfs_sfx_FillStorage", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  698.  
  699.         zfs.f.Shop_action_Restart(Shop)
  700.  
  701.         // Stops the distance check timer
  702.         zfs.f.Timer_Remove("zfs_player_interaction_shop_check_ent_" .. Shop:EntIndex())
  703.     end
  704. end
  705.  
  706. function zfs.f.Shop_Player_StartUse(Shop,ply)
  707.     zfs.f.Debug("zfs.f.Shop_Player_StartUse")
  708.     Shop:SetOccupiedPlayer(ply)
  709.  
  710.     zfs.Shop_Interactions[ply:SteamID()] = Shop
  711.  
  712.     local timerid = "zfs_player_interaction_shop_check_ent_" .. Shop:EntIndex()
  713.     zfs.f.Timer_Create(timerid,1,0,function()
  714.  
  715.         if IsValid(ply) and IsValid(zfs.Shop_Interactions[ply:SteamID()]) and zfs.f.InDistance(ply:GetPos(), zfs.Shop_Interactions[ply:SteamID()]:GetPos(), 200) == false then
  716.             zfs.f.Shop_ForceReset(zfs.Shop_Interactions[ply:SteamID()])
  717.         end
  718.     end)
  719. end
  720.  
  721. function zfs.f.Shop_Player_StopUse(Shop)
  722.     zfs.f.Debug("zfs.f.Shop_Player_StartUse")
  723.     local ply =  Shop:GetOccupiedPlayer()
  724.  
  725.  
  726.     if IsValid(ply) then
  727.         zfs.Shop_Interactions[ply:SteamID()] = nil
  728.     end
  729.  
  730.     // Stops the distance check timer
  731.     zfs.f.Timer_Remove("zfs_player_interaction_shop_check_ent_" .. Shop:EntIndex())
  732.  
  733.     Shop:SetOccupiedPlayer(NULL)
  734. end
  735. //////////////////////////////////////////////////////////////
  736. //////////////////////////////////////////////////////////////
  737.  
  738.  
  739.  
  740. //////////////////////////////////////////////////////////////
  741. ////////////////// Actions - Main ////////////////////////////
  742. //////////////////////////////////////////////////////////////
  743.  
  744. // Go Back to the Main Menu
  745. function zfs.f.Shop_action_Disable(Shop)
  746.     if Shop.PublicEntity then return end
  747.  
  748.     zfs.f.Shop_Player_StopUse(Shop)
  749.  
  750.     zfs.f.Shop_SetBusy(Shop,2)
  751.  
  752.     local phys = Shop:GetPhysicsObject()
  753.     if IsValid(phys) then
  754.         phys:Wake()
  755.         phys:EnableMotion(true)
  756.     end
  757.  
  758.     zfs.f.CreateEffectTable(nil, "zfs_sfx_item_select", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  759.     zfs.f.CreateEffectTable(nil, "zfs_sfx_ToogleMachine", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  760.  
  761.     zfs.f.Debug("You disabled the stand")
  762.  
  763.     Shop:SetSkin(1)
  764.  
  765.     zfs.f.Shop_AnimSequence(Shop.Mixer,"close", "idle", 1)
  766.  
  767.     zfs.f.Shop_AnimSequence(Shop,"dessamble", "idle_turnedoff", 1)
  768.  
  769.     zfs.f.Shop_ChangeState(Shop,0)
  770. end
  771.  
  772. // Enable The Machine
  773. function zfs.f.Shop_action_Enable(Shop)
  774.     zfs.f.Shop_SetBusy(Shop,2)
  775.     Shop:SetPos(Shop:GetPos() + Shop:GetUp() * 0.5)
  776.     local phys = Shop:GetPhysicsObject()
  777.  
  778.     if IsValid(phys) then
  779.         phys:Wake()
  780.         phys:EnableMotion(false)
  781.     end
  782.  
  783.     zfs.f.CreateEffectTable(nil, "zfs_sfx_item_select", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  784.     zfs.f.CreateEffectTable(nil, "zfs_sfx_ToogleMachine", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  785.  
  786.     zfs.f.Debug("You enabled the stand")
  787.     zfs.f.Debug("Its frozen now")
  788.  
  789.  
  790.     Shop:SetSkin(0)
  791.  
  792.     zfs.f.Shop_AnimSequence(Shop.Mixer,"open", "idle_open", 1)
  793.  
  794.     zfs.f.Shop_AnimSequence(Shop,"assemble", "idle_turnedon", 1)
  795.     zfs.f.Shop_action_GoToMenu(Shop)
  796. end
  797.  
  798. // Goes to the Menu
  799. function zfs.f.Shop_action_GoToMenu(Shop)
  800.     zfs.f.Shop_Player_StopUse(Shop)
  801.     zfs.f.CreateEffectTable(nil, "zfs_sfx_item_select", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  802.     zfs.f.Shop_ChangeState(Shop,1)
  803. end
  804.  
  805. // Goes to the Storage
  806. function zfs.f.Shop_action_GoToStorage(Shop)
  807.     zfs.f.CreateEffectTable(nil, "zfs_sfx_item_select", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  808.     zfs.f.Shop_ChangeState(Shop,2)
  809.     zfs.f.Shop_UpdateNetStorage(Shop)
  810. end
  811.  
  812. // Starts a Order
  813. function zfs.f.Shop_action_MakeProduct(Shop)
  814.     zfs.f.CreateEffectTable(nil, "zfs_sfx_item_select", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  815.     zfs.f.Shop_ChangeState(Shop,3)
  816. end
  817.  
  818. // Confirms the selected Product
  819. function zfs.f.Shop_action_ConfirmItem(Shop)
  820.     zfs.f.CreateEffectTable(nil, "zfs_sfx_item_select", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  821.  
  822.     local function AddNeedFruits(fruit, amount)
  823.         for i = 1, amount do
  824.             table.insert(Shop.NeededFruits, fruit)
  825.         end
  826.  
  827.         zfs.f.Debug("Added " .. amount .. " " .. fruit .. " to the NeedCutBowl.")
  828.     end
  829.  
  830.     local product = zfs.config.FruitCups[Shop:GetTSelectedItem()]
  831.     AddNeedFruits("zfs_melon", product.recipe["zfs_melon"])
  832.     AddNeedFruits("zfs_banana", product.recipe["zfs_banana"])
  833.     AddNeedFruits("zfs_coconut", product.recipe["zfs_coconut"])
  834.     AddNeedFruits("zfs_pomegranate", product.recipe["zfs_pomegranate"])
  835.     AddNeedFruits("zfs_strawberry", product.recipe["zfs_strawberry"])
  836.     AddNeedFruits("zfs_kiwi", product.recipe["zfs_kiwi"])
  837.     AddNeedFruits("zfs_lemon", product.recipe["zfs_lemon"])
  838.     AddNeedFruits("zfs_orange", product.recipe["zfs_orange"])
  839.     AddNeedFruits("zfs_apple", product.recipe["zfs_apple"])
  840.  
  841.     zfs.f.Debug("You need to cut")
  842.     zfs.f.Debug(Shop.NeededFruits)
  843.  
  844.  
  845.     zfs.f.Shop_ChangeState(Shop,5)
  846. end
  847.  
  848. // Confirms the Topping
  849. function zfs.f.Shop_action_ConfirmTopping(Shop,ply)
  850.     zfs.f.CreateEffectTable(nil, "zfs_sfx_item_select", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  851.     local selectedTopping = zfs.config.Toppings[Shop:GetTSelectedTopping()]
  852.  
  853.     // Does the Owner have the right Ulx Group to choose this topping?
  854.     if (table.Count(selectedTopping.UlxGroup_create) > 0 and not selectedTopping.UlxGroup_create[ply:GetNWString("usergroup")]) then
  855.         local allowedGroups = table.ToString(zfs.f.CreateAllowList(selectedTopping.UlxGroup_create), nil, false)
  856.         zfs.f.Notify(ply, tostring(zfs.language.Shop.SelectTopping_WrongUlx01 .. allowedGroups), 3)
  857.         zfs.f.Notify(ply, zfs.language.Shop.SelectTopping_WrongUlx02, 1)
  858.  
  859.         return
  860.     end
  861.  
  862.     local topping = zfs.config.Toppings[Shop:GetTSelectedTopping()]
  863.  
  864.     zfs.f.Debug("Selected Topping: " .. topping.Name)
  865.  
  866.     Shop.SmoothieCreator = ply
  867.  
  868.     zfs.f.Shop_ChangeState(Shop,7)
  869. end
  870.  
  871. // Called when we press the Cancel Product Button
  872. function zfs.f.Shop_action_CancelItem(Shop)
  873.     zfs.f.CreateEffectTable(nil, "zfs_sfx_item_select", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  874.     zfs.f.Shop_action_Restart(Shop)
  875. end
  876.  
  877. // Called when we press the Cancel Topping Button
  878. function zfs.f.Shop_action_CancelTopping(Shop)
  879.     zfs.f.CreateEffectTable(nil, "zfs_sfx_item_select", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  880.     zfs.f.Shop_ChangeState(Shop,5)
  881.     Shop:SetTSelectedTopping(-1)
  882. end
  883.  
  884. // Restarts the whole Progress
  885. function zfs.f.Shop_action_Restart(Shop)
  886.     // Here we reset our Fruit Bowl that has all our cutted fruit
  887.     Shop.FruitsInMixer = {}
  888.     table.Empty(Shop.FruitsInMixer)
  889.  
  890.     // Here we reset our needed Fruits
  891.     Shop.NeededFruits = {}
  892.     table.Empty(Shop.NeededFruits)
  893.  
  894.     // Product Fruits Count
  895.     Shop.FruitsToSlice = nil
  896.  
  897.     // Resets our MixerStuff
  898.     Shop.Mixer:SetBodygroup(0, 0)
  899.     Shop.Mixer:SetSkin(0)
  900.     Shop.Mixer:SetColor(zfs.default_colors["white01"])
  901.  
  902.     //Network Var Setup
  903.     Shop:SetPPrice(-1)
  904.     Shop:SetTSelectedItem(-1)
  905.     Shop:SetTSelectedTopping(-1)
  906.  
  907.     //Start State
  908.     Shop.mixerStack = 0
  909.     zfs.f.Shop_ChangeState(Shop,1)
  910.  
  911.     Shop.SmoothieCreator = nil
  912.  
  913.     zfs.f.Shop_Player_StopUse(Shop)
  914. end
  915. //////////////////////////////////////////////////////////////
  916. //////////////////////////////////////////////////////////////
  917.  
  918.  
  919.  
  920. //////////////////////////////////////////////////////////////
  921. /////////////// Actions - Cooking ////////////////////////////
  922. //////////////////////////////////////////////////////////////
  923. // This Places our Cup
  924. function zfs.f.Shop_action_PlaceCup(Shop)
  925.     if (Shop.Cup_InWork == nil) then
  926.         local ent = ents.Create("zfs_fruitcup_base")
  927.         ent:SetAngles(Shop:GetAngles())
  928.         ent:SetPos(Shop:GetAttachment(Shop:LookupAttachment("cupwait")).Pos)
  929.         ent:Spawn()
  930.         ent:SetParent(Shop, Shop:LookupAttachment("cupwait"))
  931.         ent:Activate()
  932.         ent:PhysicsInitSphere(0.1, "default")
  933.         ent:SetCollisionGroup(COLLISION_GROUP_WEAPON)
  934.         local ang = Shop:GetAngles()
  935.         ang:RotateAroundAxis(Shop:GetUp(), -115)
  936.         ent:SetAngles(ang)
  937.         Shop.Cup_InWork = ent
  938.         Shop:DeleteOnRemove(ent)
  939.     else
  940.         Shop.Cup_InWork:SetNoDraw(false)
  941.     end
  942.  
  943.     // Gives us the Count how many fruits we have for later use
  944.     Shop.FruitsToSlice = table.Count(Shop.NeededFruits)
  945.     zfs.f.CreateEffectTable(nil, "zfs_sfx_cup_placed", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  946.  
  947.     zfs.f.Debug("Cup got placed")
  948.     zfs.f.Shop_action_GetFruit(Shop)
  949. end
  950.  
  951. // Checks if there still is a Fruit for us to cut
  952. function zfs.f.Shop_action_GetFruit(Shop)
  953.     local toCut = nil
  954.  
  955.     for k, v in ipairs(Shop.NeededFruits) do
  956.         if (v ~= nil) then
  957.             toCut = v
  958.             break
  959.         end
  960.     end
  961.  
  962.     if (toCut ~= nil) then
  963.         zfs.f.Shop_action_PlaceFruit(Shop,toCut)
  964.         zfs.f.Debug("You got " .. table.Count(Shop.NeededFruits) .. " left to cut.")
  965.         zfs.f.Debug(Shop.NeededFruits)
  966.  
  967.     else
  968.  
  969.         zfs.f.Debug("Fruits are done, Now mix")
  970.  
  971.         zfs.f.Shop_ChangeState(Shop,9)
  972.         zfs.f.Shop_action_ShowSweetener(Shop)
  973.     end
  974. end
  975.  
  976. // Places a Fruit we need do cut
  977. function zfs.f.Shop_action_PlaceFruit(Shop,fruit)
  978.  
  979.     zfs.f.Debug("Place fruit " .. fruit)
  980.  
  981.     local ent = ents.Create(fruit)
  982.     local ang = Shop:GetAngles()
  983.     ang:RotateAroundAxis(Shop:GetUp(), ent.AngleOffset)
  984.     ent:SetAngles(ang)
  985.     ent:SetPos(Shop:GetAttachment(Shop:LookupAttachment("workplace")).Pos + Shop:GetUp() * 1)
  986.     ent:Spawn()
  987.     ent:SetParent(Shop, Shop:LookupAttachment("workplace"))
  988.     ent:Activate()
  989.     ent:SetCollisionGroup(COLLISION_GROUP_WEAPON)
  990.  
  991.     zfs.f.EntList_Add(ent)
  992.  
  993.     zfs.f.SetOwnerID(ent, zfs.f.GetOwner(Shop))
  994.     ent.WorkStation = Shop
  995.  
  996.     zfs.f.Debug("Fruit got placed")
  997.  
  998.  
  999.     zfs.f.Shop_ChangeState(Shop,8)
  1000. end
  1001.  
  1002. // Places the sliced fruit in to the Mixer
  1003. function zfs.f.Shop_action_FillMixer(Shop,fruit)
  1004.     // This Spawn the sliced fruit prop in too the mixer
  1005.     local FruitEnt = ents.Create("prop_dynamic")
  1006.     FruitEnt:SetModel("models/zerochain/fruitslicerjob/fs_slicedfruits.mdl")
  1007.  
  1008.     FruitEnt:Spawn()
  1009.     FruitEnt:Activate()
  1010.  
  1011.     Shop:DeleteOnRemove(FruitEnt)
  1012.  
  1013.     local fruitPos = Shop.Mixer:LocalToWorld(Shop.Mixer:GetUp() * 20 + Shop.Mixer:GetUp() * Shop.mixerStack)
  1014.     FruitEnt:SetPos(fruitPos)
  1015.  
  1016.     local ang = Shop:GetAngles()
  1017.     ang:RotateAroundAxis(Shop.Mixer:GetUp(), math.random(0, 360))
  1018.     FruitEnt:SetAngles(ang)
  1019.  
  1020.     FruitEnt:SetParent(Shop)
  1021.  
  1022.     // This Sets the bodygroup of the sliced fruits for the mixer
  1023.     local curFruit = fruit:GetClass()
  1024.  
  1025.     if (curFruit == "zfs_melon") then
  1026.         FruitEnt:SetBodygroup(0, 0)
  1027.     elseif (curFruit == "zfs_pomegranate") then
  1028.         FruitEnt:SetBodygroup(0, 1)
  1029.     elseif (curFruit == "zfs_coconut") then
  1030.         FruitEnt:SetBodygroup(0, 2)
  1031.     elseif (curFruit == "zfs_banana") then
  1032.         FruitEnt:SetBodygroup(0, 3)
  1033.     elseif (curFruit == "zfs_lemon") then
  1034.         FruitEnt:SetBodygroup(0, 4)
  1035.     elseif (curFruit == "zfs_kiwi") then
  1036.         FruitEnt:SetBodygroup(0, 5)
  1037.     elseif (curFruit == "zfs_orange") then
  1038.         FruitEnt:SetBodygroup(0, 6)
  1039.     elseif (curFruit == "zfs_strawberry") then
  1040.         FruitEnt:SetBodygroup(0, 7)
  1041.     elseif (curFruit == "zfs_apple") then
  1042.         FruitEnt:SetBodygroup(0, 8)
  1043.     end
  1044.  
  1045.     // This Offsets the next sliced fruit
  1046.     if (Shop.FruitsToSlice > 6) then
  1047.         Shop.mixerStack = Shop.mixerStack + (10 / Shop.FruitsToSlice)
  1048.     else
  1049.         Shop.mixerStack = Shop.mixerStack + 1
  1050.     end
  1051.  
  1052.     //Adds the sliced fruit in to our Mixer
  1053.     table.insert(Shop.FruitsInMixer, FruitEnt)
  1054.  
  1055.     // Removes the sliced fruit from our todo slice list
  1056.     table.RemoveByValue(Shop.NeededFruits, fruit:GetClass())
  1057.     zfs.f.Debug("Removed " .. tostring(fruit) .. " from the NeedCutBowl.")
  1058.  
  1059.     // This removes the Fruit prop
  1060.     fruit:Remove()
  1061.  
  1062.     zfs.f.Shop_action_GetFruit(Shop)
  1063. end
  1064.  
  1065. // Show Sweeteners
  1066. function zfs.f.Shop_action_ShowSweetener(Shop)
  1067.     // Show all the Sweeteners
  1068.     for i, k in pairs(Shop.Sweeteners) do
  1069.         if (IsValid(Shop.Sweeteners[i])) then
  1070.             Shop.Sweeteners[i]:SetNoDraw(false)
  1071.         end
  1072.     end
  1073.  
  1074.     Shop.Sweeteners["Coffe"]:SetPos(Shop:GetAttachment(Shop:LookupAttachment("workplace")).Pos + Shop:GetUp() * 6 + Shop:GetForward() * -12 + Shop:GetForward() * 0)
  1075.     Shop.Sweeteners["Milk"]:SetPos(Shop:GetAttachment(Shop:LookupAttachment("workplace")).Pos + Shop:GetUp() * 6 + Shop:GetForward() * -12 + Shop:GetForward() * 11)
  1076.     Shop.Sweeteners["Chocolate"]:SetPos(Shop:GetAttachment(Shop:LookupAttachment("workplace")).Pos + Shop:GetUp() * 6 + Shop:GetForward() * -12 + Shop:GetForward() * 22)
  1077. end
  1078.  
  1079. // Add Sweetener
  1080. function zfs.f.Shop_action_AddSweetener(Shop,sweettype)
  1081.     zfs.f.Shop_ChangeState(Shop,10)
  1082.     zfs.f.Shop_SetBusy(Shop,4)
  1083.  
  1084.     // This hides all the other Sweetener
  1085.     for i, k in pairs(Shop.Sweeteners) do
  1086.         if (IsValid(Shop.Sweeteners[i]) and i ~= sweettype) then
  1087.             Shop.Sweeteners[i]:SetNoDraw(true)
  1088.             Shop.Sweeteners[i]:SetPos(Shop:GetAttachment(Shop:LookupAttachment("fruitlift")).Pos + Shop:GetUp() * 30)
  1089.         end
  1090.     end
  1091.  
  1092.     Shop.Sweeteners[sweettype]:SetPos(Shop:GetAttachment(Shop:LookupAttachment("mixer_floor")).Pos + Shop:GetUp() * 30)
  1093. end
  1094.  
  1095. // Starts the Mixer
  1096. function zfs.f.Shop_action_StartMixer(Shop)
  1097.     // This clears all the props in the mixer
  1098.     for i, k in pairs(Shop.FruitsInMixer) do
  1099.         if (IsValid(Shop.FruitsInMixer[i])) then
  1100.             Shop.FruitsInMixer[i]:Remove()
  1101.         end
  1102.     end
  1103.  
  1104.     // This creats all of the SFX & VFX of the Mixer
  1105.     zfs.f.CreateAnimTable(Shop.Mixer, "mix", 2)
  1106.  
  1107.     zfs.f.CreateEffectTable(nil, "zfs_sfx_startmixer", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  1108.     zfs.f.CreateEffectTable(nil, "zfs_sfx_mix", Shop, Shop:GetAngles(), Shop:GetPos(), nil)
  1109.  
  1110.     Shop.Mixer:SetBodygroup(0, 1)
  1111.     Shop.Mixer:SetColor(zfs.config.FruitCups[Shop:GetTSelectedItem()].fruitColor)
  1112.     zfs.f.Shop_ChangeState(Shop,12)
  1113.     zfs.f.Shop_SetBusy(Shop,8)
  1114.  
  1115.     timer.Simple(8, function()
  1116.         if IsValid(Shop) then
  1117.             zfs.f.CreateAnimTable(Shop.Mixer, "open", 1)
  1118.  
  1119.             Shop.Mixer:SetBodygroup(0, 0)
  1120.  
  1121.             Shop.Mixer:SetColor(zfs.default_colors["white01"])
  1122.             zfs.f.Shop_action_FinishCup(Shop)
  1123.         end
  1124.     end)
  1125. end
  1126.  
  1127. // Creats our Finished Product
  1128. function zfs.f.Shop_action_FinishCup(Shop)
  1129.     // This removes our work in progress Cup
  1130.     Shop.Cup_InWork:SetNoDraw(true)
  1131.  
  1132.     // This Creates our product
  1133.     local productData = zfs.config.FruitCups[Shop:GetTSelectedItem()]
  1134.     local product = ents.Create("zfs_fruitcup_base")
  1135.     product:Spawn()
  1136.     product:Activate()
  1137.     product:SetParent(Shop)
  1138.     product:SetColor(productData.fruitColor)
  1139.     product:SetModelScale(1)
  1140.     product:SetBodygroup(0, 1)
  1141.  
  1142.     product:SetSmoothieCreator(Shop.SmoothieCreator:SteamID())
  1143.  
  1144.     // This Creates our Topping
  1145.     if (Shop:GetTSelectedTopping() ~= 1) then
  1146.         local toppingData = zfs.utility.SortedToppingsTable[Shop:GetTSelectedTopping()]
  1147.         local topping = ents.Create("zfs_topping")
  1148.         local ang = Shop:GetAngles()
  1149.         ang:RotateAroundAxis(Shop:GetUp(), 90)
  1150.         topping:SetAngles(ang)
  1151.         topping:SetPos(product:GetPos() + product:GetUp() * 10)
  1152.         topping:Spawn()
  1153.         topping:SetParent(product)
  1154.         topping:Activate()
  1155.         topping:SetModel(toppingData.Model)
  1156.         topping:SetModelScale(toppingData.mScale)
  1157.     end
  1158.  
  1159.     // Everyone can buy it but its stell a entity from the shop owner
  1160.     zfs.f.SetOwnerID(product, zfs.f.GetOwner(Shop))
  1161.  
  1162.     // Add our fruit cup to a free spot on our World/Lua Table
  1163.     zfs.f.Shop_AddProductToSellTable(Shop,product)
  1164.  
  1165.     // This Allows the Item do get sold
  1166.     product:SetReadydoSell(true)
  1167.  
  1168.     // Here we tell our Cup what item he is from the config
  1169.     product.ProductID = Shop:GetTSelectedItem()
  1170.  
  1171.     // Here we tell our Cup what his topping is
  1172.     product.ToppingID = Shop:GetTSelectedTopping()
  1173.  
  1174.     // This Sets the Price of our Cup
  1175.     if zfs.config.Price.Custom then
  1176.         product:SetPrice(Shop:GetPPrice() + zfs.config.Toppings[Shop:GetTSelectedTopping()].ExtraPrice)
  1177.     else
  1178.         // Here we calculate what the Fruit varation boni is
  1179.         local PriceBoni = zfs.f.CalculateFruitVarationBoni(productData) * zfs.config.Price.FruitMultiplicator
  1180.  
  1181.         local FruitVariationCharge = math.Round(productData.Price * PriceBoni)
  1182.  
  1183.         local finalprice = Shop:GetPPrice() + FruitVariationCharge + zfs.config.Toppings[Shop:GetTSelectedTopping()].ExtraPrice
  1184.  
  1185.         product:SetPrice(finalprice)
  1186.     end
  1187.  
  1188.     // Custom Hook
  1189.     hook.Run("zfs_OnSmoothieMade" ,Shop.SmoothieCreator, product, product.ProductID)
  1190.  
  1191.  
  1192.     // Here we remove the used fruits from our storage
  1193.     for k, v in pairs(productData.recipe) do
  1194.         if v > 0 then
  1195.             zfs.f.Shop_RemoveStorage(Shop,k, v)
  1196.         end
  1197.     end
  1198.  
  1199.     zfs.f.Shop_action_Restart(Shop)
  1200. end
  1201. //////////////////////////////////////////////////////////////
  1202. //////////////////////////////////////////////////////////////
  1203.  
  1204.  
  1205.  
  1206.  
  1207.  
  1208.  
  1209. //////////////////////////////////////////////////////////////
  1210. /////////////// Actions - Selling ////////////////////////////
  1211. //////////////////////////////////////////////////////////////
  1212. util.AddNetworkString("zfs_ItemBuyUpdate_cl")
  1213.  
  1214. net.Receive("zfs_ItemBuyUpdate_cl", function(len, ply)
  1215.     if zfs.f.NW_Player_Timeout(ply) then return end
  1216.     local ItemInfo = net.ReadTable()
  1217.     local price = ItemInfo.Price
  1218.     local w_item = Entity(ItemInfo.ItemEntIndex)
  1219.  
  1220.     if IsValid(w_item) and w_item:GetClass() == "zfs_fruitcup_base" and zfs.f.InDistance(ply:GetPos(), w_item:GetPos(), 200) and ply:Alive() then
  1221.  
  1222.         // Here we make the Transaction if the Product got sold
  1223.         if (ItemInfo.WantsToBuy) then
  1224.             // If we are on DarkRp then check if the Player has enough money
  1225.             if not zfs.f.HasMoney(ply, price) then
  1226.                 zfs.f.Notify(ply, zfs.language.Shop.Item_NoMoney, 1)
  1227.  
  1228.                 return
  1229.             end
  1230.  
  1231.             // Does the player have the right Ulx Group to Consume the topping of this Item?
  1232.             if (table.Count(zfs.config.Toppings[ItemInfo.ToppingID].UlxGroup_consume) > 0) then
  1233.                 local permission = zfs.config.Toppings[ItemInfo.ToppingID].UlxGroup_consume[ply:GetNWString("usergroup")]
  1234.  
  1235.                 if (permission == false or permission == nil) then
  1236.  
  1237.                     local allowedGroups = zfs.f.CreateAllowList(zfs.config.Toppings[ItemInfo.ToppingID].UlxGroup_consume)
  1238.                     allowedGroups = table.concat( allowedGroups, ",", 1, #allowedGroups )
  1239.  
  1240.                     zfs.f.Notify(ply, zfs.language.Shop.Item_WrongUlx01 .. allowedGroups, 3)
  1241.                     zfs.f.Notify(ply, zfs.language.Shop.Item_WrongUlx02, 1)
  1242.  
  1243.                     return
  1244.                 end
  1245.             end
  1246.  
  1247.             // Does the player have the right Job to Consume the topping of this Item?
  1248.             if (table.Count(zfs.config.Toppings[ItemInfo.ToppingID].Job_consume) > 0) then
  1249.                 local JobPermission = zfs.config.Toppings[ItemInfo.ToppingID].Job_consume[team.GetName(ply:Team())]
  1250.  
  1251.                 if (JobPermission == false or JobPermission == nil) then
  1252.  
  1253.                     local allowedJobs = zfs.f.CreateAllowList(zfs.config.Toppings[ItemInfo.ToppingID].Job_consume)
  1254.                     allowedJobs = table.concat( allowedJobs, ",", 1, #allowedJobs )
  1255.  
  1256.                     zfs.f.Notify(ply, zfs.language.Shop.Item_WrongJob01 .. allowedJobs, 3)
  1257.                     zfs.f.Notify(ply, zfs.language.Shop.Item_WrongJob02, 1)
  1258.  
  1259.                     return
  1260.                 end
  1261.             end
  1262.  
  1263.             zfs.f.Debug("Received Benefits by " .. ply:Nick())
  1264.             zfs.f.Debug(zfs.config.Toppings[ItemInfo.ToppingID].ToppingBenefits)
  1265.  
  1266.  
  1267.             // This Handles the sell action of the cup from the Shop
  1268.             zfs.f.Shop_action_SellCup(w_item:GetParent(),w_item, ply, price)
  1269.         end
  1270.  
  1271.         zfs.f.Smoothie_Interaction_Stop(ply:SteamID())
  1272.     end
  1273. end)
  1274.  
  1275. // This Function gets called from the cup when someone buys it
  1276. function zfs.f.Shop_action_SellCup(Shop,cup, ply, price)
  1277.  
  1278.     zfs.f.Debug("Buyer: " .. ply:Nick())
  1279.     zfs.f.Debug("Sold Cup EntIndex: " .. cup:EntIndex())
  1280.     zfs.f.Debug(cup.PrintName .. " Sold!")
  1281.  
  1282.     zfs.f.CreateEffectTable("zfs_sell_effect", "zfs_cup_sold", Shop, cup:GetAngles(), cup:GetPos(), nil)
  1283.     local cupData = zfs.config.FruitCups[cup.ProductID]
  1284.  
  1285.     // The Indicators for the Purchase
  1286.     local PurchaseInfo = string.Replace(zfs.language.Shop.ItemBought, "$itemName", tostring(cupData.Name))
  1287.     PurchaseInfo = string.Replace(PurchaseInfo, "$itemPrice", tostring(price))
  1288.     PurchaseInfo = string.Replace(PurchaseInfo, "$currency", zfs.config.Currency)
  1289.     zfs.f.Notify(ply, PurchaseInfo, 0)
  1290.  
  1291.     // The Topping Consume Info we tell the Player
  1292.     zfs.f.Notify(ply, zfs.config.Toppings[cup.ToppingID].ConsumInfo, 0)
  1293.  
  1294.     // This gives the player the Default Health of the Fruitcup
  1295.     local extraHealth = zfs.f.CalculateFruitHealth(zfs.config.FruitCups[cup.ProductID])
  1296.     //extraHealth = math.Clamp(extraHealth, 0, zfs.config.Health.MaxReward)
  1297.     extraHealth = math.Round(extraHealth)
  1298.  
  1299.     if (zfs.config.Health.UseHungermod) then
  1300.         local newEnergy = (ply:getDarkRPVar("Energy") or 100) + (extraHealth or 1)
  1301.         ply:setShopDarkRPVar("Energy", newEnergy)
  1302.     else
  1303.         local newHealth = ply:Health() + extraHealth
  1304.  
  1305.         if zfs.config.Health.HealthCap and newHealth > zfs.config.Health.MaxHealthCap then
  1306.             newHealth = zfs.config.Health.MaxHealthCap
  1307.             zfs.f.Notify(ply, zfs.language.Benefit.CantAdd_ExtraHealth, 1)
  1308.         end
  1309.  
  1310.         ply:SetHealth(newHealth)
  1311.     end
  1312.  
  1313.     // This gives the player all the Extra Benefits from the Topping
  1314.     for k, v in pairs(zfs.config.Toppings[cup.ToppingID].ToppingBenefits) do
  1315.         if (k ~= nil) then
  1316.             zfs.Benefits[k](ply, cup.ToppingID, true)
  1317.         end
  1318.     end
  1319.  
  1320.     // This makes the Money Transaction and informs the creator of the cup
  1321.     local smoothie_creator = player.GetBySteamID( cup:GetSmoothieCreator() )
  1322.     if IsValid(smoothie_creator) then
  1323.         zfs.f.GiveMoney(smoothie_creator, price)
  1324.         local SellInfo = ply:Nick() .. " [" .. tostring(cupData.Name) .. "] +" .. zfs.config.Currency .. tostring(price)
  1325.         zfs.f.Notify(smoothie_creator, SellInfo, 0)
  1326.     end
  1327.     zfs.f.TakeMoney(ply, price)
  1328.  
  1329.     // Custom Hook
  1330.     hook.Run("zfs_OnSmoothieSold" ,ply, price, cup,cup.ProductID)
  1331.  
  1332.  
  1333.     // This Removes the Cup from Table and World
  1334.     zfs.f.Shop_RemoveProductToSellTable(Shop,cup, cup.SellTable_Index)
  1335. end
  1336. //////////////////////////////////////////////////////////////
  1337. //////////////////////////////////////////////////////////////
  1338.  
  1339.  
  1340.  
  1341.  
  1342.  
  1343.  
  1344.  
  1345. //////////////////////////////////////////////////////////////
  1346. ////////////////////////// Misc ////////////////////////////
  1347. //////////////////////////////////////////////////////////////
  1348.  
  1349. // Gets called when we change the State
  1350. function zfs.f.Shop_ChangeState(Shop,state)
  1351.     if Shop:GetCurrentState() == state then
  1352.  
  1353.         zfs.f.Debug("Cant change to " .. state .. " since its allready in that state")
  1354.         return
  1355.     end
  1356.  
  1357.     zfs.f.Debug("State Changed too " .. state)
  1358.  
  1359.     Shop:SetCurrentState(state)
  1360. end
  1361.  
  1362. // Is used for locking the controlls and telling the Player to wait
  1363. function zfs.f.Shop_SetBusy(Shop,time)
  1364.     Shop:SetIsBusy(true)
  1365.  
  1366.     timer.Simple(time, function()
  1367.         if IsValid(Shop) then
  1368.             Shop:SetIsBusy(false)
  1369.         end
  1370.     end)
  1371. end
  1372.  
  1373. function zfs.f.Shop_AnimSequence(Shop,anim1, anim2, speed)
  1374.  
  1375.     zfs.f.CreateAnimTable(Shop, anim1, speed)
  1376.     timer.Simple(Shop:SequenceDuration(Shop:GetSequence()), function()
  1377.         if not IsValid(Shop) then return end
  1378.         zfs.f.CreateAnimTable(Shop, anim2, speed)
  1379.     end)
  1380. end
  1381. //////////////////////////////////////////////////////////////
  1382. //////////////////////////////////////////////////////////////
  1383.  
  1384.  
  1385. //////////////////////////////////////////////////////////////
  1386. ////////////////////////// Pickup ////////////////////////////
  1387. //////////////////////////////////////////////////////////////
  1388. // Here we make sure the players cant pick up the shop when its running
  1389. local function ShopPickup(ply, ent)
  1390.     if ent:GetClass() == "zfs_shop" then
  1391.         if ent:GetCurrentState() == 0 and ply == zfs.f.GetOwner(ent) then
  1392.             return true
  1393.         else
  1394.             return false
  1395.         end
  1396.     end
  1397. end
  1398.  
  1399. hook.Add("PhysgunPickup", "zfs_AllowShopPickUp", ShopPickup)
  1400. //////////////////////////////////////////////////////////////
  1401. //////////////////////////////////////////////////////////////
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement