# 迷你快餐店(Mini Fast Food Restaurant)
return (function()
local IDs = {--Ingame items and blocks
sceneBlk1Id = 100, --Scene block
sceneBlk2Id = 667, --Scene block
storeBoxIdx = 2001, --Box block
contTableId = 1123, --Dirty tray tableID
washTableId = 219, --Wash TableID
waterTapxId = 258, --Water tapID
funnelBlkId = 1105, --Deliver blockID
arrowheadId = 3941, --Deliver arrowsID
cookinBlkId = 2018, --Cooking blockID
cutBoardxId = 218, --Cutting board blockID
checkBlkIdx = 3950, --Check blockID
musicBlkIdx = 415, --MusicblockID
emptyDishId = 3997, --Empty dish blockID
dirtyDishId = 3999, --Dirty dishblockID
}
-- Hand held food item
local FoodIDs = {
[1] = 12502, --Toest
[2] = 12519, --Roasted Chicken Leg
[3] = 12512, --Roasted Potato
[4] = 12517, --Roasted Beef
}
-- Conversion between Deliver blocks
local FinalIDs = {
[FoodIDs[1]] = { --Hand held toast
[3997] = 4000, --10->block1
[4000] = 3991, --11->block11
[3982] = 3972, --12->block12
[3980] = 3973, --13->block13
[3976] = 3971, --14->block14
[3991] = 3985, --111->111
[3972] = 3964, --112->112
[3973] = 3961, --113->113
[3971] = 3960, --114->114
[3981] = 3965, --122->122
[3970] = 3967, --123->123
[3968] = 3966, --124->124
[3979] = 3963, --133->133
[3969] = 3962, --134->134
[3975] = 3959, --144->144
},
[FoodIDs[2]] = { --Hand held Roasted Chicken Leg
[3997] = 3982, --20->block2
[4000] = 3972, --21->block12
[3982] = 3981, --22->block22
[3980] = 3970, --23->block23
[3976] = 3968, --24->block24
[3991] = 3964, --211->112
[3972] = 3965, --212->122
[3973] = 3967, --213->123
[3971] = 3966, --214->124
[3981] = 3977, --222->222
[3970] = 3958, --223->223
[3968] = 3956, --224->224
[3979] = 3955, --233->233
[3969] = 3957, --234->234
[3975] = 3954, --244->244
},
[FoodIDs[3]] = { --Hand held Roasted Potato
[3997] = 3980, --30->block3
[4000] = 3973, --31->block13
[3982] = 3970, --32->block23
[3980] = 3979, --33->block33
[3976] = 3969, --34->block34
[3991] = 3961, --311->113
[3972] = 3967, --312->123
[3973] = 3963, --313->133
[3971] = 3962, --314->134
[3981] = 3958, --322->223
[3970] = 3955, --323->233
[3968] = 3957, --324->234
[3979] = 3978, --333->333
[3969] = 3952, --334->334
[3975] = 3953, --344->344
},
[FoodIDs[4]] = { --Hand held Roasted Beef
[3997] = 3976, --40->block4
[4000] = 3971, --41->block14
[3982] = 3968, --42->block24
[3980] = 3969, --43->block34
[3976] = 3975, --44->block44
[3991] = 3960, --411->114
[3972] = 3966, --412->124
[3973] = 3962, --413->134
[3971] = 3959, --414->144
[3981] = 3956, --422->224
[3970] = 3957, --423->234
[3968] = 3954, --424->244
[3979] = 3952, --433->334
[3969] = 3953, --434->344
[3975] = 3974, --444->444
},
}
--Clock ID:Right/Left half
local ClockNumIDs = {
-- right --
[0] = 3909,
[1] = 3923,
[2] = 3925,
[3] = 3920,
[4] = 3918,
[5] = 3916,
[6] = 3915,
[7] = 3913,
[8] = 3929,
[9] = 3911,
-- lelf --
[10] = 3908,
[11] = 3922,
[12] = 3924,
[13] = 3921,
[14] = 3919,
[15] = 3917,
[16] = 3914,
[17] = 3912,
[18] = 3943,
[19] = 3910,
}
local GameSData = {--Level content
[1] = { --Level 1
score = 5, --Score
dtime = 3*60, --Time
pos = { --Spawn Point
[1] = {x=21.5, y=7, z=14.5},
[2] = {x=22.5, y=7, z=14.5},
[3] = {x=23.5, y=7, z=14.5},
},
fpos = { --funnel Level delivery point
[1] = {x=22, y=7, z=26},
[2] = {x=23, y=7, z=26},
},
dpos = { --Dirty position
[1] = {x=18, y=7, z=26},
[2] = {x=19, y=7, z=26},
},
mpos = { --Welcome music POS
[1] = {x=23, y=14, z=20},
[2] = {x=18, y=14, z=21},
},
tools = { --Item conversion type
[IDs.cutBoardxId] = {--cut board
[1] = {[241] = 12512},
},
[IDs.washTableId] = {--wash table
[1] = {[3999] = 3997},
},
[IDs.waterTapxId] = {--water tap
[1] = {[3999] = 3997},
},
},
goals = {3973, 3979}, --Score block
target = {{3907, 3884}, {3884, 3884}},
clocks = { --Clock information
{x=21, y=9, z=27, time=45, stop=false, fdir=1},
{x=24, y=9, z=19, time=45, stop=false, fdir=2},
{x=20, y=9, z=13, time=45, stop=false, fdir=3},
{x=17, y=9, z=21, time=45, stop=false, fdir=4},
},
},
[2] = { --Level 2
score = 9, --Level Score
dtime = 4*60, --Level Time
pos = {
[1] = {x=20.5-27, y=7, z=26.5},
[2] = {x=21.5-27, y=7, z=26.5},
[3] = {x=22.5-27, y=7, z=26.5},
},
fpos = { --funnel Level delivery point
[1] = {x=-9, y=7, z=14},
[2] = {x=-10, y=7, z=14},
},
dpos = { --Dirty position
[1] = {x=-4, y=7, z=18},
[2] = {x=-4, y=7, z=17},
},
mpos = { --Welcome music POS
[1] = {x=-4, y=14, z=25},
[2] = {x=-4, y=14, z=20},
},
tools = { --Food/Item conversion type
[IDs.cookinBlkId] = {--cooking block
[1] = {[12516] = 12517},
[2] = {[12518] = 12519},
},
[IDs.washTableId] = {--wash the dishes
[1] = {[3999] = 3997},
},
[IDs.waterTapxId] = {--wash the dishes
[1] = {[3999] = 3997},
},
},
goals = {3972, 3971, 3968, 3981, 3975}, --Scoreblock
target = {{3907, 3926}, {3907, 3880}, {3926, 3880}, {3926, 3926}, {3880, 3880}},
clocks = { --Clock information
{x=-7, y=9, z=27, time=60, stop=false, fdir=1},
{x=-3, y=9, z=19, time=60, stop=false, fdir=2},
{x=-7, y=9, z=13, time=60, stop=false, fdir=3},
{x=-11, y=9, z=21, time=60, stop=false, fdir=4},
},
},
[3] = { --Level 3
score = 12, --Level Score
dtime = 5*60,--Level Time
pos = {
[1] = {x=20.5-15, y=7, z=16.5},
[2] = {x=21.5-15, y=7, z=16.5},
[3] = {x=22.5-15, y=7, z=16.5},
},
fpos = { --funnel Level delivery point
[1] = {x=6, y=7, z=25},
[2] = {x=7, y=7, z=25},
[3] = {x=8, y=7, z=25},
},
dpos = { --Dirty position
[1] = {x=1, y=7, z=24},
[2] = {x=2, y=7, z=24},
},
mpos = { --Welcome music POS
[1] = {x=2, y=14, z=24},
[2] = {x=6, y=14, z=16},
},
tools = { --Food/Item conversion type
[IDs.cutBoardxId] = {--cut board
[1] = {[241] = 12512},
},
[IDs.cookinBlkId] = {--cooking block
[1] = {[12516] = 12517},
[2] = {[12518] = 12519},
},
[IDs.washTableId] = {--wash the dishes
[1] = {[3999] = 3997},
},
[IDs.waterTapxId] = {--wash the dishes
[1] = {[3999] = 3997},
},
},
goals = {3967, 3966, 3962, 3957, 3955, 3952, 3958, 3956, 3953, 3954}, --Scoreblock
target = {{3907, 3926, 3884}, {3907, 3926, 3880}, {3907, 3880, 3884}, {3880, 3926, 3884},
{3926, 3884, 3884}, {3880, 3884, 3884}, {3884, 3926, 3926}, {3880, 3926, 3926},
{3884, 3880, 3880}, {3926, 3880, 3880}},
clocks = { --Clock information
{x=12, y=9, z=25, time=80, stop=false, fdir=1},
{x=2, y=9, z=25, time=80, stop=false, fdir=1},
{x=10, y=9, z=15, time=80, stop=false, fdir=3},
{x=2, y=9, z=15, time=80, stop=false, fdir=3},
},
},
}
-- Game Tips
local GameTips = {
NewTips = 'Customers are on the way..',
NewStage = '#GSuccessfully, you will enter the new level!#n',
CountTip = 'Level %d#Y', -- Timer Tips
windStage = '#YMini Restaurant-Level %d#n',
chatStage = 'Successfully entered level %d:#R Get %d points in %d minutes to enter the next level!#nGo!',
chatNewIn = 'Tips: Get score by puting the food into the plate or the dish according to the guest.',
windScore1 = 'OK.#YGot 1 point#n',
windScore2 = 'Well done!#YGot 2 points#n',
windScore0 = 'Sorry, this does not match the guest request.',
windComes = 'Welcome <%d> to Mini Fast Food Restaurant',
windLeave = 'Guest <%d> left…',
chatLast30 = '#RLast 30 seconds! #n to end the level.',
chatLast10 = '#RLast 10 seconds! #n to end the level.',
}
local chatType = 1
local tickCount = 0
local newTicker = 20
local IsGameEnded = false --Game over
local IsGRuleInit = false --Set rules
local BattleResult = 0 --Game result Tag
local runTime = 0
local teamIdx = 1--Set team ID
local customers = 0 --Number of Guest
local DishBlks = {IDs.dirtyDishId}
local miniTimer1 = -1 --Level timer
local miniTimer2 = -1 --Reset timing
--Store level data
local CurrStage = {
stage = 1, --Default 1st level
score = 0, --score
clocks = {},--Demand module
seqids = {},--delayFuncID
}
function EasyCopy(dtab)
local newtab = {}
for k, v in pairs(dtab) do newtab[k]=v end
return newtab
end
-- Clock = {x, y, z, time=30, fdir=1, stop=false, target={t1,t2,t3}}
function GetRandomClock(stage)
stage = stage or CurrStage.stage
sdata = GameSData[stage]
if sdata ~= nil then
local randIdx = 0 --random ID
local randClock = nil -- New clock
local clocks = GameSData[stage].clocks
randIdx = math.random(1, #clocks)
randClock = EasyCopy(clocks[randIdx])
local target = GameSData[stage].target
randIdx = math.random(1, #target)
randClock['target'] = target[randIdx]
local goals = GameSData[stage].goals
randClock['goal'] = goals[randIdx]
-- Save data
CurrStage.tgIdx = randIdx
return randClock
end
end
-- Clock = {x, y, z, time=30, fdir=1, stop=false, target={t1,t2,t3}}
-- Add or cut customer demand timer
function ClockCrtOrDel(clock, dodel)
local xPos, yPos, zPos = 0, 0, 0
local faceDir = -1 --Block orientation
local xdiv,zdiv = 0, 0 --X,Z Coordinate offset
local txdiv,tzdiv = 0, 0 --Position offset
if clock.fdir==1 then faceDir=2;xdiv=1;tzdiv=1; end --Z axis reverse direction
if clock.fdir==2 then faceDir=4;zdiv=-1;txdiv=1; end --Y axis reverse direction
if clock.fdir==3 then faceDir=3;xdiv=-1;tzdiv=-1; end --Z-axis square
if clock.fdir==4 then faceDir=5;zdiv=1;txdiv=-1; end --Y-axis square
local headId = 3946 -- Set the head of guest
xPos, yPos, zPos = clock.x, clock.y+1, clock.z
if dodel then Block:destroyBlock(xPos, yPos, zPos)
else Block:setBlockAll(xPos, yPos, zPos, headId, faceDir) end
local flagId = 3932 --Tips
local clockId = 3947 -- Left half clock ID
local drinkId = 3945 -- drink in the right side ID
local tsize = #clock.target --Required quantity
local lPanId,mPanId,rPanId = 3883,3882,3881 --L/R Whiteboard
-- add Tips
xPos, yPos, zPos = clock.x-xdiv, clock.y+1, clock.z-zdiv
if dodel then Block:destroyBlock(xPos, yPos, zPos)
else Block:setBlockAll(xPos, yPos, zPos, flagId, faceDir) end
-- add L/R Whiteboard or Required
xPos, yPos, zPos = clock.x-xdiv, clock.y+2, clock.z-zdiv
if dodel then Block:destroyBlock(xPos, yPos, zPos) --WhiteboardL
else Block:setBlockAll(xPos, yPos, zPos, lPanId, faceDir) end
if dodel then Block:destroyBlock(xPos-txdiv, yPos, zPos-tzdiv) --Required L
else Block:setBlockAll(xPos-txdiv, yPos, zPos-tzdiv, clock.target[1], faceDir) end
if tsize <= 2 then
xPos, yPos, zPos = clock.x, clock.y+2, clock.z
if dodel then Block:destroyBlock(xPos, yPos, zPos) --WhiteboardR
else Block:setBlockAll(xPos, yPos, zPos, rPanId, faceDir) end
if dodel then Block:destroyBlock(xPos-txdiv, yPos, zPos-tzdiv) --Required M
else Block:setBlockAll(xPos-txdiv, yPos, zPos-tzdiv, clock.target[2], faceDir) end
else -- Required parts more than 2
xPos, yPos, zPos = clock.x, clock.y+2, clock.z
if dodel then Block:destroyBlock(xPos, yPos, zPos) --WhiteboardM
else Block:setBlockAll(xPos, yPos, zPos, mPanId, faceDir) end
if dodel then Block:destroyBlock(xPos-txdiv, yPos, zPos-tzdiv) --RequiredM
else Block:setBlockAll(xPos-txdiv, yPos, zPos-tzdiv, clock.target[2], faceDir) end
xPos, yPos, zPos = clock.x+xdiv, clock.y+2, clock.z+zdiv
if dodel then Block:destroyBlock(xPos, yPos, zPos) --WhiteboardR
else Block:setBlockAll(xPos, yPos, zPos, rPanId, faceDir) end
if dodel then Block:destroyBlock(xPos-txdiv, yPos, zPos-tzdiv) --RequiredR
else Block:setBlockAll(xPos-txdiv, yPos, zPos-tzdiv, clock.target[3], faceDir) end
end
-- addLeft half clock
xPos, yPos, zPos = clock.x-xdiv*2, clock.y, clock.z-zdiv*2
if dodel then Block:destroyBlock(xPos, yPos, zPos)
else Block:setBlockAll(xPos, yPos, zPos, clockId, faceDir) end
-- add drink in the right side
xPos, yPos, zPos = clock.x+xdiv, clock.y, clock.z+zdiv
if dodel then Block:destroyBlock(xPos, yPos, zPos)
else Block:setBlockAll(xPos, yPos, zPos, drinkId, faceDir) end
local status = dodel and 'destroy' or 'count'
ClockCounted(clock, status)
end
-- Guest required starts to count down
function ClockCounted(clock, status)
status = status and status or 'count'
-- Return if it is timed and stopped
if status=='count' and clock.stop then return end
local faceDir = -1 -- Block orientation
local xdiv,zdiv = 0, 0 -- X,Z Coordinate offset
if clock.fdir==1 then faceDir=2;xdiv=1 end --Z axis reverse direction
if clock.fdir==2 then faceDir=4;zdiv=-1 end --Y axis reverse direction
if clock.fdir==3 then faceDir=3;xdiv=-1 end --Z-axis square
if clock.fdir==4 then faceDir=5;zdiv=1 end --Y-axis square
if status == 'destroy' then
Block:destroyBlock(clock.x, clock.y, clock.z)
Block:destroyBlock(clock.x-xdiv, clock.y, clock.z-zdiv)
return
end
-- Timing or initialization status
local strTime = tostring(clock.time)
local left = #strTime>1 and strTime:sub(1,1) or 0--Ten digits
local right = #strTime>1 and strTime:sub(2) or strTime:sub(1)
local leftId = ClockNumIDs[tonumber(left)+10]
local rightId = ClockNumIDs[tonumber(right)]
if not leftId or not rightId then return end
-- Set left and right timer
Block:setBlockAll(clock.x-xdiv, clock.y, clock.z-zdiv, leftId, faceDir)
Block:setBlockAll(clock.x, clock.y, clock.z, rightId, faceDir)
if clock.time == 10 then --10 seconds left
local tsize = #clock.target
local lPanId,mPanId,rPanId = 3906,3905,3934
Block:setBlockAll(clock.x-xdiv, clock.y+2, clock.z-zdiv, lPanId, faceDir)
if tsize <= 2 then
Block:setBlockAll(clock.x, clock.y+2, clock.z, rPanId, faceDir)
else -- more than 2 Target
Block:setBlockAll(clock.x, clock.y+2, clock.z, mPanId, faceDir)
Block:setBlockAll(clock.x+xdiv, clock.y+2, clock.z+zdiv, rPanId, faceDir)
end
local headId = 3940 --Head change
Block:setBlockAll(clock.x, clock.y+1, clock.z, headId, faceDir)
end
end
local TargetHited = function(clock)
local xPos, yPos, zPos = 0, 0, 0
local faceDir = -1 --Block orientation
local xdiv,zdiv = 0, 0 --X,Z Coordinate offset
local txdiv,tzdiv = 0, 0 --Required part Position offset
if clock.fdir==1 then faceDir=2;xdiv=1;tzdiv=1; end --Z axis reverse direction
if clock.fdir==2 then faceDir=4;zdiv=-1;txdiv=1; end --Y axis reverse direction
if clock.fdir==3 then faceDir=3;xdiv=-1;tzdiv=-1; end --Z-axis square
if clock.fdir==4 then faceDir=5;zdiv=1;txdiv=-1; end --Y-axis square
local checkId = IDs.checkBlkIdx
local tsize = #clock.target --Required Quantity
-- set Required part complete the mark
xPos, yPos, zPos = clock.x-xdiv, clock.y+2, clock.z-zdiv --RequiredL
Block:setBlockAll(xPos-txdiv, yPos, zPos-tzdiv, checkId, faceDir)
if tsize <= 2 then
xPos, yPos, zPos = clock.x, clock.y+2, clock.z --RequiredR
Block:setBlockAll(xPos-txdiv, yPos, zPos-tzdiv, checkId, faceDir)
else -- More than 2 Required parts
xPos, yPos, zPos = clock.x, clock.y+2, clock.z --RequiredM
Block:setBlockAll(xPos-txdiv, yPos, zPos-tzdiv, checkId, faceDir)
xPos, yPos, zPos = clock.x+xdiv, clock.y+2, clock.z+zdiv --RequiredR
Block:setBlockAll(xPos-txdiv, yPos, zPos-tzdiv, checkId, faceDir)
end
end
-- Refresh guest Required part
local TargetRefresh = function(cInfo)
local csize = #CurrStage.seqids
if cInfo~=nil and csize>0 then
for idx = 1, csize do --Delete from line
local seqId = CurrStage.seqids[idx]
if cInfo.seq == seqId then
table.remove(CurrStage.seqids, idx)
break
end
end
end
-- create a Required part
customers = customers + 1
local stage = CurrStage.stage
local clock = GetRandomClock(stage)
local csize = #CurrStage.clocks
CurrStage.clocks[csize+1] = clock
print('Frt===>>', csize, CurrStage.clocks)
ClockCrtOrDel(clock, false)
local chatTips = string.format(GameTips.windComes, customers)
Chat:sendSystemMsg(chatTips)
-- Reflesh the guest requiredX,Z Coordinate offset
local mPos = GameSData[stage].mpos[1]
Block:destroyBlock(mPos.x, mPos.y, mPos.z)
local createBlock = function()
Block:setBlockAll(mPos.x, mPos.y, mPos.z, IDs.musicBlkIdx)
end
threadpool:delay(1, createBlock)
end
-----Generate tray after delivery-----
local GensDirtyDish = function(cInfo)
local csize = #CurrStage.seqids
for idx = 1, csize do --Delete from line
local seqId = CurrStage.seqids[idx]
if cInfo.seq == seqId then
table.remove(CurrStage.seqids, idx)
break
end
end
local cur_stage = CurrStage.stage
local dpos = GameSData[cur_stage].dpos
local yOffset = 2
local isSucc = false
for jdx = 1, yOffset do --Up to two layers
for idx = 1, #dpos do --if the layer has no blocks
local x, y, z = dpos[idx].x,dpos[idx].y,dpos[idx].z
local ret, blockId = Block:getBlockID(x, y+jdx, z)
if ret==ErrorCode.OK and blockId==0 then
if cur_stage == 1 then --The first level is generated by a clean plate.
Block:setBlockAll(x, y+jdx, z, IDs.emptyDishId)
else --Other levels generate dirty dishes
Block:setBlockAll(x, y+jdx, z, IDs.dirtyDishId)
end
return
end
end
end
end
--if table have key
local function KeyInTable(key, ctab)
for idx, val in ipairs(ctab) do
if val==key then return true end
end
return false
end
--Replace tick times
local function IsCanTick()
tickCount = tickCount+1
if tickCount>=newTicker then
tickCount = 0
return true
end
return false
end
-- Initialize game data
local function InitGameData()
--Initialize the dish class block DishBlks
for key, dict in pairs(FinalIDs) do
for ckey, cval in pairs(dict) do
if not KeyInTable(ckey, DishBlks) then DishBlks[#DishBlks+1] = ckey end
if not KeyInTable(cval, DishBlks) then DishBlks[#DishBlks+1] = cval end
end
end
end
--Game rulemaking
local function InitGameRule()
IsGRuleInit = true -- Initialization target
GameRule.CameraDir = 1 --Default positive angle
GameRule.StartMode = 0 --Open mode
GameRule.StartPlayers = 1 --Minimum player amount:1
GameRule.DisplayScore = 1 --Display score:1
GameRule.BlockDestroy = 0 --Blocks cannot be destroyed
GameRule.WinLoseEndTime = 2
end
--Score Settlement
local function ShowGBattleUI()
-- Set the total score
local stage = CurrStage.stage
local score = CurrStage.score
for idx=1, stage-1 do
score = score + GameSData[idx].score
end
local ret, txt = Game:getDefString(3176)
local txtInfo = string.format('%s:%d', txt,score)
UI:setGBattleUI('right_little_desc', txtInfo)
UI:setGBattleUI('battle_btn', false)
UI:setGBattleUI('result', false)
UI:setGBattleUI('result_bkg', false)
UI:setGBattleUI('reopen', true)
end
--Reset new round
local function StartNewRound()
-- Stop the clock and destroy it
print('Fz==>>>', CurrStage.clocks)
for idx = #CurrStage.clocks, 1, -1 do
local clock = CurrStage.clocks[idx]
clock.stop = true
ClockCrtOrDel(clock, true)
table.remove(CurrStage.clocks, idx)
end
-- Clear Required part /Delayed call
print('Fw==>>>', CurrStage.seqids)
for idx = #CurrStage.seqids, 1, -1 do
local seqId = CurrStage.seqids[idx]
threadpool:kick(seqId)--delete Delayed call
table.remove(CurrStage.seqids, idx)
end
Game_Start() --Restart the game
end
--Get the point and check if the level is completed
local function TeamAddScore(teamId, addScore)
local teamId = teamId and teamId or teamIdx
local ret = Team:addTeamScore(teamId, addScore)
local ret, score = Team:getTeamScore(teamId)
if ret == ErrorCode.OK then CurrStage.score = score end
local ret,num,players = World:getAllPlayers()
if ret==ErrorCode.OK then
for idx = 1, #players do --add tips to all players
local scoreTips = addScore==1 and GameTips.windScore1 or GameTips.windScore2
--print('Fz==>>>', scoreTips, score==1)
Player:notifyGameInfo2Self(players[idx], scoreTips)
end
end
local cur_stage = CurrStage.stage
local stage_score = GameSData[cur_stage].score
if CurrStage.score >= stage_score then
local new_stage = cur_stage+1
if new_stage > #GameSData then
IsGameEnded = true --finished all levels
BattleResult = TEAM_RESULTS.TEAM_RESULTS_WIN
Game:doGameEnd()
else --turn to next level
CurrStage.stage = new_stage
--Chat:sendSystemMsg(GameTips.NewStage)
for idx = 1, #players do --Changed to player tips
Player:notifyGameInfo2Self(players[idx], GameTips.NewStage)
end
--Reset the new round after 3 seconds
miniTimer2 = 3
MiniTimer:pauseTimer(miniTimer1)
--threadpool:delay(3, StartNewRound)
if IsLastCount then --Reset timer music
IsLastCount = false
for stage = 1, 3 do --All levels
local musicId = IDs.musicBlkIdx
local mPos = GameSData[stage].mpos[2]
Block:setBlockAll(mPos.x, mPos.y, mPos.z, musicId)
end
end
end
end
end
local IsLastCount = false
--------Game start--------
Game_Start = function()
-- ShowItemName()
print('Fz==>Game_Start')
customers = 0
miniTimer2 = -1
CurrStage.score = 0 --Reset score
Team:setTeamScore(teamIdx, CurrStage.score)
-- Set game rules
if not IsGRuleInit then InitGameRule() end
local stage = CurrStage.stage
local ret,num,players = World:getAllPlayers()
if ret~=ErrorCode.OK or not players then return end
local items = {241, 12502, 12512, 12516, 12517, 12518, 12519}
local windTips = string.format(GameTips.windStage, stage)
for idx = 1, #players do--Traversing the player
local playerId = players[idx]
-- Set player team
Player:setTeam(playerId, teamIdx)
-- Clear the specified item on the player
for idx, itemId in ipairs(items) do
Backpack:removeGridItemByItemID(playerId, itemId)
end
-- Set player Spawn Point
local allPos = GameSData[stage].pos
local index = (idx-1)%3 + 1
local curPos = allPos[index] --Three position cycle
--if not curPos then curPos = allPos[1] end
Player:setPosition(playerId, curPos.x, curPos.y, curPos.z)
-- Tip for fist time in the level
Player:notifyGameInfo2Self(players[idx], windTips)
end
-- Create a game timer
if miniTimer1 <= 0 then
local ret, timerId = MiniTimer:createTimer('Timer1')
if ret==ErrorCode.OK then miniTimer1 = timerId end
end
if miniTimer1 > 0 then --Start level timer
local stTime = GameSData[stage].dtime
MiniTimer:startBackwardTimer(miniTimer1, stTime)
local sTip = string.format(GameTips.CountTip, stage)
MiniTimer:showTimerTips(players, miniTimer1, sTip, true)
end
local score = GameSData[stage].score
local dtime = math.modf(GameSData[stage].dtime/60)
local chatTips = string.format(GameTips.chatStage, stage,dtime,score)
Chat:sendSystemMsg(chatTips)
if stage == 1 then Chat:sendSystemMsg(GameTips.chatNewIn) end
--Chat:sendSystemMsg(GameTips.NewTips)
--add new required after 1 second
threadpool:delay(1, TargetRefresh)
IsLastCount = false
local mcPos = GameSData[stage].mpos[2]
Block:setBlockAll(mcPos.x, mcPos.y, mcPos.z, IDs.musicBlkIdx)
end
--------Update--------
Game_RunTime = function()
--10 seconds left 10 tick Generate block
if IsLastCount and tickCount==10 then
local stage = CurrStage.stage
local mPos = GameSData[stage].mpos[2]
Block:setBlockAll(mPos.x, mPos.y, mPos.z, IDs.musicBlkIdx)
end
if not IsCanTick() then return end
if IsGameEnded then return end
--10 seconds left 20 tick delete block
local stage = CurrStage.stage
if IsLastCount then --10 seconds left
local mPos = GameSData[stage].mpos[2]
Block:destroyBlock(mPos.x, mPos.y, mPos.z)
end
if miniTimer2 >= 0 then
if miniTimer2 > 0 then
local timeTip = string.format('#R%d#n',miniTimer2)
--Chat:sendSystemMsg(timeTip)
-- Changed to player Tip
local ret,num,players = World:getAllPlayers()
if ret==ErrorCode.OK then
for idx = 1, #players do
Player:notifyGameInfo2Self(players[idx], timeTip)
end
end
else
StartNewRound()
end
miniTimer2 = miniTimer2-1
end
local csize = #CurrStage.clocks
if csize <= 0 then return end
for idx = #CurrStage.clocks, 1, -1 do
local clock = CurrStage.clocks[idx]
if clock.time < 0 then --destroy
ClockCrtOrDel(clock, true)
table.remove(CurrStage.clocks, idx)
-- Tips of guest left
local chatTips = string.format(GameTips.windLeave, customers)
Chat:sendSystemMsg(chatTips)
local randsec = math.random(1, 2)
threadpool:delay(randsec, TargetRefresh)
elseif not clock.stop then --Timing
ClockCounted(clock, 'count')
clock.time = clock.time-1
end
end
if miniTimer1 ~= 0 then
local ret, curTime = MiniTimer:getTimerTime(miniTimer1)
if ret==ErrorCode.OK then
if curTime == 30 then -- Last 30 seconds
Chat:sendSystemMsg(GameTips.chatLast30)
IsLastCount = true
local mPos = GameSData[stage].mpos[2]
Block:destroyBlock(mPos.x, mPos.y, mPos.z)
elseif curTime == 10 then --Last 10 seconds
Chat:sendSystemMsg(GameTips.chatLast10)
elseif curTime <= 0 then --Game over
IsGameEnded = true --Sorry, game over
BattleResult = TEAM_RESULTS.TEAM_RESULTS_LOSE
Game:doGameEnd()
return
end
end
end
end
--------Game over--------
Game_Over = function()
local txtIdx = 270 --win
if BattleResult==TEAM_RESULTS.TEAM_RESULTS_LOSE then
txtIdx = 271 --lost
end
local ret, txtInfox = Game:getDefString(txtIdx)
print('Fz==>>>', BattleResult, txtIdx, ret, txtInfox)
Chat:sendSystemMsg(txtInfox)
Team:setTeamResults(teamIdx, BattleResult)
Team:setTeamPlayersResults(teamIdx, BattleResult)
ShowGBattleUI()
end
--------game timeout--------
Game_Tout = function()
BattleResult = TEAM_RESULTS.TEAM_RESULTS_LOSE
end
-------Player initialization-------
Player_Init = function(trigger_obj)
if not IsGRuleInit then InitGameRule() end
local playerId = trigger_obj['eventobjid']
if not playerId then return end
Player:setTeam(playerId, teamIdx)
if miniTimer1 > 0 then --Game start
local stage = CurrStage.stage
local allPos = GameSData[stage].pos
local index = 1
local ret, num = World:getPlayerTotal()
if ret==ErrorCode.OK then index = (num-1)%3+1 end
local curPos = allPos[index] --Three position cycle
Player:setPosition(playerId, curPos.x, curPos.y, curPos.z)
end
end
local curr_playerid = nil
--------start to dig the event--------
Block_DigBegin = function(trigger_obj)
print('Begin===>>', trigger_obj)
local x, y, z = trigger_obj['x'], trigger_obj['y'], trigger_obj['z']
local blockId, playerId = trigger_obj['blockid'], trigger_obj['eventobjid']
if blockId==IDs.cutBoardxId or blockId==IDs.washTableId or blockId==IDs.waterTapxId then
--Set up like Dig.End evnet can not get ID
curr_playerid = trigger_obj['eventobjid']
Block_DigEnded(trigger_obj)
return
end
-- Get the current manual item ID
local ret, toolIdx = Player:getCurToolID(playerId)
if ret ~= ErrorCode.OK then return end
-- 0、store block
if blockId == IDs.storeBoxIdx then
end
-- 1、The current square is a funnel->Click to get points
local isSpecialDish = toolIdx==IDs.emptyDishId or blockId==IDs.dirtyDishId
if (blockId==IDs.funnelBlkId or blockId==IDs.arrowheadId) and
not isSpecialDish and KeyInTable(toolIdx, DishBlks) then
local cur_stage = CurrStage.stage
local fpos = GameSData[cur_stage].fpos
local isStagePos = false
for idx = 1, #fpos do --Check the place
print('Click2===>>>', x,y,z, fpos)
if x==fpos[idx].x and z==fpos[idx].z and (y==fpos[idx].y or y==fpos[idx].y-1 or y==fpos[idx].y+1) then
isStagePos = true;
break
end
end
if not isStagePos then return end
Player:onCurToolUsed(playerId, 1)
local seqId = threadpool:delay(5, GensDirtyDish)
local seqSize = #CurrStage.seqids
CurrStage.seqids[seqSize+1] = seqId
-- Bonus points for delivery
local csize = #CurrStage.clocks
if csize <= 0 then return end
for idx = 1, csize do --return after deleted
local clock = CurrStage.clocks[idx]
local goalIdx = clock.goal --target ID
if goalIdx == toolIdx then
TargetHited(clock)
clock.stop = true--stop timing
local delayRemove = function()
return (function(cclock,cidx)
ClockCrtOrDel(cclock, true)
table.remove(CurrStage.clocks,cidx)
end)(clock,idx)
end
local seqId1 = threadpool:delay(2, delayRemove)
local seqSize = #CurrStage.seqids
CurrStage.seqids[seqSize+1] = seqId1
local randsec = math.random(3, 4)
local seqId2 = threadpool:delay(randsec, TargetRefresh)
local seqSize = #CurrStage.seqids
CurrStage.seqids[seqSize+1] = seqId2
-- more than 10sec get 2 points, within 10sec get 1 point
local score = clock.time>10 and 2 or 1
-- put it back to see if pass
TeamAddScore(teamIdx, score)
return
end
end
--Error delivery returns with a tip
local ret,num,players = World:getAllPlayers()
if ret==ErrorCode.OK then
for idx = 1, #players do
local scoreTips = GameTips.windScore0
Player:notifyGameInfo2Self(players[idx], scoreTips)
end
end
return
end
-- 2、scene block->Put the dishes
local isGameBlock = blockId==IDs.sceneBlk1Id or blockId==IDs.sceneBlk2Id
if isGameBlock and KeyInTable(toolIdx, DishBlks) then
Block:placeBlock(toolIdx, x, y+1, z)
return
end
-- 3、dish block->Plate convert/fetch
if KeyInTable(blockId, DishBlks) then
-- 3.1、Click the plate empty-handed->get plate
if toolIdx == 0 then
local bType = BACKPACK_TYPE.SHORTCUT
local ret = Player:gainItems(playerId, blockId, 1, bType)
if ret==ErrorCode.OK then Block:setBlockAll(x, y, z, 0) end
return
end
-- 3.2、Hold the food+click the plate->Corresponding delivery block
if KeyInTable(toolIdx, FoodIDs) then
local newBlockId = FinalIDs[toolIdx][blockId]
if newBlockId ~= nil then --There are output items that can be converted
local ret = Block:setBlockAll(x, y, z, newBlockId)
if ret == ErrorCode.OK then--consume hand-held items
Player:onCurToolUsed(playerId, 1)
end
end
return
end
end
end
--------Dig the end of the event--------
Block_DigEnded = function(trigger_obj)
print('End1=======>>>', trigger_obj)
local x, y, z = trigger_obj['x'], trigger_obj['y'], trigger_obj['z']
local blockId, playerId = trigger_obj['blockid'], trigger_obj['eventobjid']
-- Return directly if neither is obtained
if not playerId and not curr_playerid then return end
--DigEnd event did not reture objid
if playerId == nil then playerId = curr_playerid end
curr_playerid = nil --replace after used
local cur_stage = CurrStage.stage
local tools = GameSData[cur_stage].tools
print('End2=======>>>', tools, cur_stage, playerId)
-- Step to make items:machining=>New item
if tools[blockId] ~= nil then --Cut potatoes/rack of lamb..
local ret, toolId = Player:getCurToolID(playerId)
if ret == ErrorCode.OK then
for idx=1, #tools[blockId] do--Traversal search
local retFood = tools[blockId][idx]
local outputId = retFood[toolId]
if outputId ~= nil then --matching outputs and replacing items
local ret = Player:onCurToolUsed(playerId, 1)
if ret == ErrorCode.OK then
local bType = BACKPACK_TYPE.SHORTCUT
Player:gainItems(playerId, outputId, 1, bType)
end
end
end
end
end
end
-- Mobile can not distinguish keys of left and right
Block_PlaceBy = function(trigger_obj)
print('Place=======>>>', trigger_obj)
local x, y, z = trigger_obj['x'], trigger_obj['y'], trigger_obj['z']
local blockId, playerId = trigger_obj['blockid'], trigger_obj['eventobjid']
-- 1、The block is a funnel->Click deliver and get the score
local isSpecialDish = blockId==IDs.emptyDishId or blockId==IDs.dirtyDishId
if not isSpecialDish and KeyInTable(blockId, DishBlks) then
local cur_stage = CurrStage.stage
local fpos = GameSData[cur_stage].fpos
local isStagePos = false
for idx = 1, #fpos do --check the place
if x==fpos[idx].x and z==fpos[idx].z and (y==fpos[idx].y or y==fpos[idx].y-1 or y==fpos[idx].y+1) then
isStagePos = true;
break
end
end
print('Place==>>>', isStagePos)
-- Return if it is a wrong place
if not isStagePos then return end
Block:destroyBlock(x, y, z, false)
--Generates dirty disks with a delay of 5 seconds and cancels if it goes to the next level
local seqId = threadpool:delay(5, GensDirtyDish)
local seqSize = #CurrStage.seqids
CurrStage.seqids[seqSize+1] = seqId
-- Bonus points for delivery
local csize = #CurrStage.clocks
if csize <= 0 then return end
for idx = 1, csize do --return after deleted
local clock = CurrStage.clocks[idx]
local goalIdx = clock.goal --target ID
if goalIdx == blockId then
TargetHited(clock)
clock.stop = true--Timing stop
local delayRemove = function()
return (function(cclock,cidx)
ClockCrtOrDel(cclock, true)
table.remove(CurrStage.clocks,cidx)
end)(clock,idx)
end
local seqId1 = threadpool:delay(2, delayRemove)
local seqSize = #CurrStage.seqids
CurrStage.seqids[seqSize+1] = seqId1
local randsec = math.random(3, 4)--Random refresh within 3 seconds
--Delay refresh request within 3 seconds and cancels if it goes to the next level
local seqId2 = threadpool:delay(randsec, TargetRefresh)
local seqSize = #CurrStage.seqids
CurrStage.seqids[seqSize+1] = seqId2
-- 10sec more get 2 points, in 10sec get 1 point
local score = clock.time>10 and 2 or 1
-- put it back to see if can pass
TeamAddScore(teamIdx, score)
return
end
end
--return if error delivery
local ret,num,players = World:getAllPlayers()
if ret==ErrorCode.OK then --Get all players correctly
for idx = 1, #players do --Give tips to all players
local scoreTips = GameTips.windScore0
Player:notifyGameInfo2Self(players[idx], scoreTips)
end
end
return
end
end
--Registered Listening event
function ListenEvents_MiniCook()
InitGameData()
--Listening for game events
ScriptSupportEvent:registerEvent([=[Game.Start]=], Game_Start)
ScriptSupportEvent:registerEvent([=[Game.Run]=], Game_RunTime)
ScriptSupportEvent:registerEvent([=[Game.End]=], Game_Over)
ScriptSupportEvent:registerEvent([=[Game.TimeOver]=], Game_Tout)
ScriptSupportEvent:registerEvent([=[Player.Init]=], Player_Init)
--Event trigger condition-Begin to mining block
local bgConsIds = {IDs.sceneBlk1Id, IDs.sceneBlk2Id, IDs.storeBoxIdx, IDs.funnelBlkId, IDs.arrowheadId}
for idx=1, #DishBlks do bgConsIds[#bgConsIds+1] = DishBlks[idx] end
--Event trigger condition-End mining block
local egConsIds = {IDs.cutBoardxId, IDs.washTableId, IDs.waterTapxId}
for idx=1, #egConsIds do bgConsIds[#bgConsIds+1] = egConsIds[idx] end
--Listening for block events
ScriptSupportEvent:registerEvent_Block([=[Player.ClickBlock]=], Block_DigBegin, bgConsIds)
ScriptSupportEvent:registerEvent_Block([=[Block.PlaceBy]=], Block_PlaceBy, bgConsIds)
--ScriptSupportEvent:registerEvent_Block([=[Block.Dig.Begin]=], Block_DigBegin, bgConsIds)
--ScriptSupportEvent:registerEvent_Block([=[Block.Dig.End]=], Block_DigEnded, egConsIds)
end
-- Listening for events
ListenEvents_MiniCook()
end)()