--SỬ DỤNG:
-- 1. quest id: 1, 2

require "vl_quest_utils"
require "npc/vl_quest_npc_client"
require "questui/vl_quest_introwindow_ui"
require "questui/vl_quest_markers"
require "questui/vl_quest_popup_ui"

VLF = VLF or {}

local Func = {}
Func.GetPlayerID = VLF.GetPlayerID
Func.ActiveQuestIntro_Centre = VLF.ActiveQuestIntro_Centre
Func.ActiveQuestIntro_Free = VLF.ActiveQuestIntro_Free
Func.MarkerList_Add = VLF.MarkerList_Add
Func.MarkerList_Remove = VLF.MarkerList_Remove
Func.NPCInQueueSpawnList = VLF.NPCInQueueSpawnList
Func.DoSpawnItemQuestOnSquare = VLF.DoSpawnItemQuestOnSquare
Func.IsPlayerInArea = VLF.IsPlayerInArea
Func.GetItemQuestInINVPlayer = VLF.GetItemQuestInINVPlayer
Func.AddCorpseInArea = VLF.AddCorpseInArea
Func.DelayFunction = VLF.DelayFunction
Func.GetPlayerGlobalModDataQ1 = VLF.GetPlayerGlobalModDataQ1
Func.QuestUpdatedPopIn = VLF.QuestUpdatedPopIn
Func.DoSpawnItemQuestInContainer = VLF.DoSpawnItemQuestInContainer
Func.GetQuestGlobalModData = VLF.GetQuestGlobalModData
Func.GetNPCsByVarAndQStep = VLF.GetNPCsByVarAndQStep
Func.GetZombieID = VLF.GetZombieID
Func.SetNewZombieStats = VLF.SetNewZombieStats
Func.AddObjectToSquare = VLF.AddObjectToSquare
Func.AddCorpseCustomize = VLF.AddCorpseCustomize
Func.RemoveObjectOnSquare = VLF.RemoveObjectOnSquare
Func.GetSquare = VLF.GetSquare
Func.GetZombieOnlineIDorUID = VLF.GetZombieOnlineIDorUID
Func.NPCTurnToZombie = VLF.NPCTurnToZombie
Func.GetPlayerModData = VLF.GetPlayerModData
Func.AddItemToSquares = VLF.AddItemToSquares
Func.GetObjectOnSquare = VLF.GetObjectOnSquare
Func.GetOrCreateSquare = VLF.GetOrCreateSquare
Func.AddGenerator = VLF.AddGenerator
					
--Kiểm tra thức ăn trên người
local function HasFoodInINV(player)
    if not player then return false end
    local items = player:getInventory():getItems()
    for i = 0, items:size() - 1 do
        local item = items:get(i)
        if item then
            if item:IsFood() then
                return true
            end
        end
    end
    return false
end

--Kiểm tra nước uống trên người
local function HasDrinkInINV(player)
    if not player then return false end
    local items = player:getInventory():getItems()
    for i = 0, items:size() - 1 do
        local item = items:get(i)
        if item then
            if item:isWaterSource() then
                return true
            end
        end
    end
    return false
end

--Lấy thời gian đã sống sót của nhân vật
local function GetSurvivedTime(player)
	if player then
		local hours = player:getHoursSurvived()
		local days = math.floor(hours / 24)
		local remainHours = math.floor(hours % 24)
		local minutes = math.floor((hours * 60) % 60)
		--print(string.format("Survived time: %d days, %d hours, %d minutes", days, remainHours, minutes))
		return hours, days, remainHours
	end
end

--Cập nhật quest step : true, false hoặc "done" 
local function SetQuestStepStateC(player, args) --SetQuestStepStateC(player, {qStep = "q1s001", active = true})
	local qStep = args.qStep
	local active = args.active
	if qStep then
		local playerGMD_Quest_Q1 = Func.GetPlayerGlobalModDataQ1(player, {qStep = qStep})
		if not playerGMD_Quest_Q1[qStep] then playerGMD_Quest_Q1[qStep] = {} end
		playerGMD_Quest_Q1[qStep].active = active
		sendClientCommand(player, 'MainQuest1', 'UpdateQuestStep', {qStep = qStep, active = active})
	end
end

local function SetIsNPCqStep(player, args) --SetIsNPCqStep(player, {qStep = "q1s003"})
	local qStep = args.qStep
	if qStep then
		local playerGMD_Quest_Q1 = Func.GetPlayerGlobalModDataQ1(player, {qStep = qStep})
		if not playerGMD_Quest_Q1[qStep].isNPC then
			playerGMD_Quest_Q1[qStep].isNPC = true
			sendClientCommand(player, 'MainQuest1', 'UpdateQuestStep', {qStep_isNPC = qStep, active_isNPC = playerGMD_Quest_Q1[qStep].isNPC})
		end
	end
end
	
--Cập nhật quest step + cập nhật quest ở trong bảng nhiệm vụ chính + Hiển thị thông báo Quest Updated
function VLF.DoQuestStepActive(player, args) --VLF.DoQuestStepActive(player, {npcTalk = true, introWindow = true, isPopIn = true, qStep = "q1s001", active = "done", qStep_Next = "q1s002", active_Next = true, isNPC_Next = false, qID = 1})
	local qStep, active = args.qStep, args.active
	local qStep_Next, active_Next = args.qStep_Next, args.active_Next
	local isPopIn = args.isPopIn or false
	local isNPC_Next = args.isNPC_Next or false
	local introWindow = args.introWindow or false
	local npcTalk = args.npcTalk or false
	local playerGMD_Quest_Q1 = Func.GetPlayerGlobalModDataQ1(player, {qStep = qStep})
	
	--print("Client-----------DoQuestStepActive= ", playerGMD_Quest_Q1[qStep].isNPC)
	--cập nhật qStep trước đó hoàn thành == "done"
	if qStep then
		SetQuestStepStateC(player, {qStep = qStep, active = active})
	end
	--nếu qStep trước đó có NPC thì
	if playerGMD_Quest_Q1[qStep].isNPC == true then
		--xóa NPC khỏi danh sách chờ spawn
		Func.NPCInQueueSpawnList({qStep = qStep, active = nil})
		--xóa ModData isNPC
		playerGMD_Quest_Q1[qStep].isNPC = nil
		sendClientCommand(player, 'MainQuest1', 'UpdateQuestStep', {qStep_isNPC = qStep, active_isNPC = nil})
	end	
	--kích hoạt qStep tiếp theo = true
	if qStep_Next then
		SetQuestStepStateC(player, {qStep = qStep_Next, active = active_Next})
	end
	--nếu qStep tiếp theo có NPC thì
	if isNPC_Next and isNPC_Next == true then
		--cập nhật ModData isNPC = true
		SetIsNPCqStep(player, {qStep = qStep_Next})
		--yêu cầu server thêm NPC vào danh sách chờ spawn
		Func.NPCInQueueSpawnList({qStep = qStep_Next, active = true})
	end
	--hiện bảng thông báo cập nhật quest
	if isPopIn and isPopIn == true then
		Func.QuestUpdatedPopIn()
	end
	--hiện bảng nội dung nhiệm vụ qStep tiếp theo
	if introWindow and introWindow == true then
		local qID = args.qID or 1
		Func.ActiveQuestIntro_Centre(getText("IGUI_VLQ_"..tostring(qID).."_Desc_"..tostring(qStep_Next)), 800, 500, false, "")
	end
	--hiện bảng nội dung nhiệm vụ qStep tiếp theo
	if npcTalk and npcTalk == true then
		local qID = args.qID or 1
		Func.ActiveQuestIntro_Centre(getText("IGUI_VLQ_"..tostring(qID).."_NPCTalk_"..tostring(qStep)), 800, 500, false, "")
	end
	--xóa marker nếu có
	Func.MarkerList_Remove(qStep)
end
local DoQuestStepActive = VLF.DoQuestStepActive

--THÊM HOẶC CẬP NHẬT NHIỆM VỤ TRONG BẢNG QUEST - không cần xóa bảng đã thêm trước đó vì đã được ghi đè
local function QuestList_AddItem(text, itemData) --QuestList_AddItem("Q"..tostring(id), {id = id, qStep = qStep, isDone = isDone, qtype = qtype, isCollection = isCollection, currentCollection = currentCollection, requestCollection = requestCollection, name = getText("IGUI_VLQ_"..tostring(id).."_Name"), task = getText("IGUI_VLQ_"..tostring(id).."_Task_"..tostring(qStep)), desc = getText("IGUI_VLQ_"..tostring(id).."_Desc_"..tostring(qStep))})
    if not text or not itemData then return end
	local id,qStep  = itemData.id, itemData.qStep
	local isDone = itemData.isDone or false
	local isCollection, currentCollection, requestCollection = itemData.isCollection or false, itemData.currentCollection, itemData.requestCollection
	local collectQItemName = itemData.collectQItemName or nil
	local qtype = itemData.qtype or getText("IGUI_VLQ_MainQuest")
	if not id or not qStep then return end
	
    VLF.QuestListShowOnUI[text] = {id = id, qStep = qStep, isDone = isDone, qtype = qtype, isCollection = isCollection, currentCollection = currentCollection, requestCollection = requestCollection, collectQItemName = collectQItemName, name = itemData.name, task = itemData.task, desc = itemData.desc}
end

local function DoQuestList_AddItem(args) --DoQuestList_AddItem({id = 1, qStep = "q1s003", isDone = false, qtype = getText("IGUI_VLQ_MainQuest"), isCollection = false, currentCollection = nil, requestCollection = nil})
	local id, qStep = args.id, args.qStep
	if not id or not qStep then return end
	QuestList_AddItem("Q"..tostring(id), {id = id, qStep = qStep, isDone = args.isDone, qtype = args.qtype, isCollection = args.isCollection, currentCollection = args.currentCollection, requestCollection = args.requestCollection, collectQItemName = args.collectQItemName, name = getText("IGUI_VLQ_"..tostring(id).."_Name"), task = getText("IGUI_VLQ_"..tostring(id).."_Task_"..tostring(qStep)), desc = getText("IGUI_VLQ_"..tostring(id).."_Desc_"..tostring(qStep))})
end

--Xóa nhiệm vụ trong bảng quest
local function QuestList_RemoveItem(text) --QuestList_RemoveItem("Q1")
    if not text then return end
    if VLF.QuestListShowOnUI[text] then
        VLF.QuestListShowOnUI[text] = nil
    end
end

local function DoAddCorpses(player, square, args) --DoAddCorpses(player, square, {qStep = qStep, x = -1, y = -1, z = 0, isSplatBlood = true, isBloodFloor = true, range = 1, number = 5})
	local sq = square or getCell():getGridSquare(args.x, args.y, args.z)
	local x, y, z = sq:getX(), sq:getY(), sq:getZ()
	local corpse
	if sq then --check square để chắc chắn vị trí spawn item đã được load. Dù có teleport đến vẫn spawn.Vì khi tp, code chạy trước khi square các tầng cao chưa load
		local qStep = args.qStep
		local playerGMD_Quest_Q1 = Func.GetPlayerGlobalModDataQ1(player, {qStep = qStep})
		if not playerGMD_Quest_Q1[qStep].isAddedCorpses then
			local isSplatBlood, isBloodFloor, range, number = args.isSplatBlood or false, args.isBloodFloor or false, args.range or 1, args.number or 1
			for i = 1, number do
				corpse = Func.AddCorpseInArea({x = x, y = y, z = z, isSplatBlood = isSplatBlood, isBloodFloor = isBloodFloor, range = range})
			end
			--print("Client-----------AddedCorpses= ", number)
			playerGMD_Quest_Q1[qStep].isAddedCorpses = true
			sendClientCommand(player, 'MainQuest1', 'UpdateQuestStep', {qStep_isAddedCorpses = qStep, isAddedCorpses = playerGMD_Quest_Q1[qStep].isAddedCorpses})
		end
	end
	if corpse then return corpse
	else return nil
	end
end

local function AddCorpseEventq1s009()
	--print("Client-----------AddCorpseEventq1s009= ")
	Func.AddCorpseCustomize({x = 13521, y = 4856, z = 0, outfitName = "Police", femaleChance = 0, number = 1})
	Func.AddCorpseCustomize({x = 13515, y = 4854, z = 0, outfitName = "Police", femaleChance = 0, number = 1})	
	Func.AddCorpseCustomize({x = 13514, y = 4860, z = 0, outfitName = "Police", femaleChance = 0, number = 2})
	Func.AddCorpseCustomize({x = 13520, y = 4861, z = 0, outfitName = "Police", femaleChance = 0, number = 1})	
	Func.AddCorpseCustomize({x = 13518, y = 4859, z = 0, outfitName = "Police", femaleChance = 0, number = 1})	
	Func.AddCorpseCustomize({x = 13521, y = 4868, z = 0, outfitName = "Police", femaleChance = 0, number = 2})	
	Func.AddCorpseCustomize({x = 13524, y = 4862, z = 0, outfitName = "Police", femaleChance = 0, number = 1})
	Func.AddCorpseCustomize({x = 13520, y = 4863, z = 0, outfitName = "Police", femaleChance = 0, number = 2})
	
	Func.AddCorpseCustomize({x = 13519, y = 4852, z = 0, outfitName = "PoliceRiot", femaleChance = 0, number = 1})
	Func.AddCorpseCustomize({x = 13510, y = 4846, z = 0, outfitName = "PoliceRiot", femaleChance = 0, number = 1})
	Func.AddCorpseCustomize({x = 13529, y = 4856, z = 0, outfitName = "PoliceRiot", femaleChance = 0, number = 1})
end

--Event Zombie update kích hoạt khi player đến gần khu vực này - 5537,12403 - 5589,12510 - z: 14 - 17
local function OnZombieUpdateq1s006(zombie)
	local zData = zombie:getModData()
	if not zData.UID then zData.UID = zombie:getUID() return end
	--Kiểm tra zombie có nằm trong khu vực cần update không
	if not zData.inArea_q1s006 then
		local x, y, z = zombie:getX(), zombie:getY(), zombie:getZ()
		--print("Client-----------OnZombieUpdateq1s006= ", x, y, z)
		if ((z >= -17) and (z <= -14)) and ((x > 5537) and (x < 5589)) and ((y > 12403) and (y < 12510)) then
			zData.inArea_q1s006 = true
		else zData.inArea_q1s006 = "skip"
		end
	end
	--Nếu nằm trong khu vực update
	if zData.inArea_q1s006 == true then
		local zID = Func.GetZombieID(zombie)
		--Kiểm tra zombie ID nào cần update
		if not zData.needUpdate_q1s006 then 	
			if zID % 10 == 0 then
				zData.needUpdate_q1s006 = true
				--print("Client-----------OnZombieUpdateq1s006: 2222222222")
			else zData.needUpdate_q1s006 = "skip"
			end
		end
		
		if zData.needUpdate_q1s006 == true then
			--print("Client-----------OnZombieUpdateq1s006: 333333333")
			Func.SetNewZombieStats(zombie, {speed = 1, strength = 1, toughness = 1})
			zData.inArea_q1s006 = "updated"
		end
	end			
	
end
--Events.OnZombieUpdate.Remove(OnZombieUpdateq1s006)
--Events.OnZombieUpdate.Add(OnZombieUpdateq1s006)		

local function WaitTimePass()
	local playerGMD_Quest_Q1 = Func.GetPlayerGlobalModDataQ1(getPlayer(), {qStep = nil})
	local nowHour = getGameTime():getWorldAgeHours()
	local qStep, hourToWait
	if playerGMD_Quest_Q1.q1s037 and playerGMD_Quest_Q1.q1s037.active == true then--chờ 48h	
		qStep, hourToWait = "q1s037", 48
	elseif playerGMD_Quest_Q1.q1s033 and playerGMD_Quest_Q1.q1s033.active == true then--chờ 168h	
		qStep, hourToWait = "q1s033", 168
	elseif playerGMD_Quest_Q1.q1s029 and playerGMD_Quest_Q1.q1s029.active == true then--chờ 72h	
		qStep, hourToWait = "q1s029", 72
	elseif playerGMD_Quest_Q1.q1s024 and playerGMD_Quest_Q1.q1s024.active == true then--chờ 72h	
		qStep, hourToWait = "q1s024", 72
	elseif playerGMD_Quest_Q1.q1s022 and playerGMD_Quest_Q1.q1s022.active == true then--chờ 24h	
		qStep, hourToWait = "q1s022", 24
	elseif playerGMD_Quest_Q1.q1s019 and playerGMD_Quest_Q1.q1s019.active == true then--chờ 24h
		qStep, hourToWait = "q1s019", 24
	end
	if qStep and hourToWait then
		--print("Client-----------WaitTimePass= "..tostring(nowHour).." - "..tostring(playerGMD_Quest_Q1[qStep].startHourWait))
		if not playerGMD_Quest_Q1[qStep].startHourWait then playerGMD_Quest_Q1[qStep].startHourWait = nowHour end
		if (nowHour - playerGMD_Quest_Q1[qStep].startHourWait) >= hourToWait then
			playerGMD_Quest_Q1[qStep].waitHourPassed = true
			playerGMD_Quest_Q1[qStep].startHourWait = nil
			sendClientCommand(player, 'MainQuest1', 'UpdatePlayerGMD', {qStep = qStep, waitHourPassed = true})
			Events.EveryHours.Remove(WaitTimePass)
		end
	end
end
--Events.EveryHours.Remove(WaitTimePass)
--Events.EveryHours.Add(WaitTimePass)

--Cập nhật NPC thành NPC qStep tiếp theo
function VLF.UpdateNPCToNextQStep(zNPC, qStep_Next)
	local questMD = Func.GetQuestGlobalModData({qStep = qStep_Next})
	local zID = Func.GetZombieOnlineIDorUID(zNPC)
	questMD.NPC[qStep_Next]["spawned"] = true
	questMD.NPC[qStep_Next]["zID"] = zID
	questMD.NPCqStep[zID] = qStep_Next
	sendClientCommand(getPlayer(), 'NPCQuestCM', 'UpdateNPCToNextQStep', {qStep_Next = qStep_Next, zID = zID})
end
local UpdateNPCToNextQStep = VLF.UpdateNPCToNextQStep


--q1s000
--THÔNG BÁO BẮT ĐẦU TẬN THẾ XÁC SỐNG
local function OnStartQuestQ1()
	local player = getPlayer()
	local playerGMD_Quest_Q1 = Func.GetPlayerGlobalModDataQ1(player, {qStep = nil})
	if not playerGMD_Quest_Q1.q1s000 then playerGMD_Quest_Q1.q1s000 = {} end
	--print("OnStartQuestQ1-------------= ", playerGMD_Quest_Q1.q1s000.CreQStepMD, playerGMD_Quest_Q1.q1s000.active)
	
	--KHỞI TẠO PLAYER GLOBAL MODDATA CHO TẤT CẢ QUEST STEP
	if not playerGMD_Quest_Q1.q1s000.CreQStepMD then
		--local pID = Func.GetPlayerID(player)
		local maxStep = VLF.Quest.Q1MaxStep
		local step = "q1s"
		for i = 0, maxStep do
			local qStep = ""
			if i < 10 then qStep = step.."00"..tostring(i)
			elseif i >= 10 and i <= 99 then qStep = step.."0"..tostring(i)
			else qStep = step..tostring(i) end
			
			if not playerGMD_Quest_Q1[qStep] then playerGMD_Quest_Q1[qStep] = {} end
		end
		sendClientCommand(player, 'MainQuest1', 'CreAllQuestStepMD', nil)
		playerGMD_Quest_Q1.q1s000.CreQStepMD = true
	end
	
	--HIỂN THỊ POP UP INTRO VÀ BẮT ĐẦU NHIỆM VỤ	
	if not playerGMD_Quest_Q1.q1s000.active then
		 --nếu thời gian sống sót lớn hơn 12 thì không cần hiện pop up start intro
		if GetSurvivedTime(player) < 12 then
			Func.ActiveQuestIntro_Centre(getText("IGUI_VLQ_1_Desc_q1s001"), 800, 500, false, "")
		end	
		local active = true
		sendClientCommand(player, 'MainQuest1', 'UpdateQuestStep', {qStep = "q1s000", active = active})
		playerGMD_Quest_Q1.q1s000.active = active
	end
	
end
Events.OnGameStart.Remove(OnStartQuestQ1)
Events.OnGameStart.Add(OnStartQuestQ1)

--q1s001
local pTick = 0
local delay = 20
local localVar = {}
local function OnPlayerUpdateQ1(player)
    if not player or player:isDead() then return end
	if pTick % delay == 0 then
		local questMarker = getTexture("media/textures/questmarker_48.png")
		local qtype = getText("IGUI_VLQ_MainQuest")
		local playerGMD_Quest_Q1 = Func.GetPlayerGlobalModDataQ1(player, {qStep = nil})
		local qStep
		if playerGMD_Quest_Q1.q1s000.active == true then
			DoQuestStepActive(player, {isPopIn = false, qStep = "q1s000", active = "done", qStep_Next = "q1s001", active_Next = true})
			--print("Client-----------PlayerModData.active: q1s000 - ", playerGMD_Quest_Q1["q1s000"].active)
		
		--q1s001 - tìm nước uống
		elseif playerGMD_Quest_Q1.q1s001.active == true then
			local qStep, qStep_Next = "q1s001", "q1s002"
			DoQuestList_AddItem({id = 1, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			if HasDrinkInINV(player) then
				DoQuestStepActive(player, {introWindow = false, isPopIn = true, qStep = qStep, active = "done", qStep_Next = qStep_Next, active_Next = true})
				Func.ActiveQuestIntro_Free(getText("IGUI_VLQ_1_Desc_q1s002"), (getCore():getScreenWidth() - 800) / 2, (getCore():getScreenHeight() - 200) / 6, 800, 200, false, "")
				--print("Client-----------PlayerModData.active= "..tostring(qStep).." - ", playerGMD_Quest_Q1[qStep].active)
			end
		
		--q1s002 - tìm thức ăn
		elseif playerGMD_Quest_Q1.q1s002.active == true then
			local qStep, qStep_Next = "q1s002", "q1s003"
			DoQuestList_AddItem({id = 1, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			if HasFoodInINV(player) then
				DoQuestStepActive(player, {introWindow = true, isPopIn = true, qStep = qStep, active = "done", qStep_Next = qStep_Next, active_Next = true, isNPC_Next = true})
			end
		
		--q1s003 - NPC - Tìm em trai tại trường trung học Riverside - nói chuyện với phó Hiệu Trưởng
		elseif playerGMD_Quest_Q1.q1s003.active == true then
			local qStep, qStep_Next = "q1s003", "q1s004"
			DoQuestList_AddItem({id = 1, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 6444, y = 5447, texture = questMarker})
		
		--q1s004 - NPC - Đến trụ sở cảnh sát Riverside để hỏi về em trai - nói chuyện với cảnh sát viên
		elseif playerGMD_Quest_Q1.q1s004.active == true then
			local qStep, qStep_Next = "q1s004", "q1s005"
			DoQuestList_AddItem({id = 1, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 6082, y = 5260, texture = questMarker})
		
		--q1s005 - Đi đến nhà cảnh sát trưởng để hỏi rõ tình hình 
		elseif playerGMD_Quest_Q1.q1s005.active == true then
			local qStep, qStep_Next = "q1s005", "q1s006"
			local playerGMD_Quest_Q1 = Func.GetPlayerGlobalModDataQ1(player, {qStep = qStep})
			DoQuestList_AddItem({id = 1, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 6762, y = 5393, texture = questMarker})

			local itemFullType = "Base.GenericMail"
			--spawn nhật ký của cảnh sát trưởng
			if Func.IsPlayerInArea(player, {x1 = 6757, y1 = 5385, x2 = 6769, y2 = 5398}) then
				if not localVar[501] then
					local x, y, z = 6760, 5391, 1
					local square = Func.GetSquare({x = x, y = y, z = z, hasFloor = true})
					if square then
						local item = Func.DoSpawnItemQuestOnSquare({qStep = qStep, x = x, y = y, z = z, itemFullType = itemFullType, range = 1, isNote = true, noteStep = 1, qID = 1, iModData = "isKeyQuest1"})					 
						if item then localVar[501] = true end
					end
				end
				if not localVar[502] then
					local x, y, z = 6764, 5391, 1
					local square = Func.GetSquare({x = x, y = y, z = z, hasFloor = true})
					if square then
						local corpse = DoAddCorpses(player, square, {qStep = qStep, x = x, y = y, z = z, isSplatBlood = true, isBloodFloor = true, range = 1, number = 5})
						if corpse then localVar[502] = true end
					end
				end
			else 
				if localVar[501] ~= false then localVar[501] = false end
				if localVar[502] ~= false then localVar[502] = false end					
			end
						
			--lấy được nhật ký
			local itemQuest = Func.GetItemQuestInINVPlayer(player, itemFullType, {qStep = qStep, iModData = "isKeyQuest1"})
			if itemQuest then
				--lấy nhật ký thì npc thành zombie
				local zNPCList = Func.GetNPCsByVarAndQStep("npcQuestIdle", qStep, {_ = nil})
				if zNPCList and zNPCList[1] then
					Func.NPCTurnToZombie(player, zNPCList[1], qStep, {isPopUp = false})
				end
				
				DoQuestStepActive(player, {introWindow = true, isPopIn = true, qStep = qStep, active = "done", qStep_Next = qStep_Next, active_Next = true, isNPC_Next = false})
				--print("Client-----------PlayerModData.active= "..tostring(qStep).." - ", playerGMD_Quest_Q1[qStep].active)
			end
		
		--q1s006 - Tìm em trai tại doanh trại quân đội Military Research Facility
		elseif playerGMD_Quest_Q1.q1s006.active == true then
			local qStep, qStep_Next = "q1s006", "q1s007"
			local pData = Func.GetPlayerModData({qStep = qStep})
			DoQuestList_AddItem({id = 1, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 5561, y = 12480, texture = questMarker})

			local itemFullType = "Base.GenericMail"
			if Func.IsPlayerInArea(player, {x1 = 5537, y1 = 12456, x2 = 5583, y2 = 12504, z = 0}) then
				--Add các item quest 1 lần duy nhất
				if not pData.itemQuest[qStep].isAddItem1 then
					local x, y, z = 5579, 12486, 0
					local square = Func.GetSquare({x = x, y = y, z = z, hasIContainer = true})
					if square then
						--print("Client-----------TRY - add item quest 1= ") 
						Func.DoSpawnItemQuestInContainer({qStep = qStep, x = x, y = y, z = z, itemFullType = "Base.GenericMail", range = 0, isNote = true, noteStep = 1, qID = 1, addOnSquare = true})
						pData.itemQuest[qStep].isAddItem1 = true
					end
				end
				if not pData.itemQuest[qStep].isAddItem2 then
					local x, y, z = 5554, 12486, 0
					local square = Func.GetSquare({x = x, y = y, z = z, hasIContainer = true})
					if square then
						--print("Client-----------TRY - add item quest 2= ") 
						Func.DoSpawnItemQuestInContainer({qStep = qStep, x = x, y = y, z = z, itemFullType = "Base.GenericMail", range = 0, isNote = true, noteStep = 2, qID = 1, addOnSquare = true})
						pData.itemQuest[qStep].isAddItem2 = true
					end
				end		
			end
			--Add các item quest chính
			if Func.IsPlayerInArea(player, {x1 = 5559, y1 = 12429, x2 = 5578, y2 = 12452, z = -17}) then
				if not localVar[601] then --đảm bảo chỉ chạy 1 lần khi player ở trong khu vực này
					local x, y, z = 5566, 12430, -17
					local square = Func.GetSquare({x = x, y = y, z = z, hasIContainer = true})
					if square then
						--print("Client-----------TRY - add item quest 2= ")
						Func.DoSpawnItemQuestInContainer({qStep = qStep, x = x, y = y, z = z, itemFullType = "Base.GenericMail", range = 0, isNote = true, noteStep = 3, qID = 1, addOnSquare = true})
						localVar[601] = true
					end
				end
				if not localVar[602] then
					local x, y, z = 5564, 12432, -17
					local square = Func.GetSquare({x = x, y = y, z = z, hasIContainer = true})
					if square then
						Func.DoSpawnItemQuestInContainer({qStep = qStep, x = x, y = y, z = z, itemFullType = itemFullType, range = 0, isNote = true, noteStep = 4, qID = 1, addOnSquare = true, iModData = "isKeyQuest1"})
						localVar[602] = true
					end
				end
				if not localVar[603] then
					local x, y, z = 5564, 12434, -17
					local square = Func.GetSquare({x = x, y = y, z = z, hasIContainer = true})
					if square then
						Func.DoSpawnItemQuestInContainer({qStep = qStep, x = x, y = y, z = z, itemFullType = itemFullType, range = 0, isNote = true, noteStep = 5, qID = 1, addOnSquare = true, iModData = "isKeyQuest2"})
						localVar[603] = true
					end
				end
			else
				if localVar[601] ~= false then localVar[601] = false end
				if localVar[602] ~= false then localVar[602] = false end
				if localVar[603] ~= false then localVar[603] = false end
			end
			
			--Kiểm tra đã lấy được 2 item quest isKeyQuest chưa
			if not pData.itemQuest[qStep].hasItemQuest1 then
				local itemQuest = Func.GetItemQuestInINVPlayer(player, itemFullType, {qStep = qStep, iModData = "isKeyQuest1"})
				if itemQuest then pData.itemQuest[qStep].hasItemQuest1 = true end
			end
			if not pData.itemQuest[qStep].hasItemQuest2 then
				local itemQuest = Func.GetItemQuestInINVPlayer(player, itemFullType, {qStep = qStep, iModData = "isKeyQuest2"})
				if itemQuest then pData.itemQuest[qStep].hasItemQuest2 = true end
			end
			if pData.itemQuest[qStep].hasItemQuest1 == true and pData.itemQuest[qStep].hasItemQuest2 == true then
				DoQuestStepActive(player, {introWindow = true, isPopIn = true, qStep = qStep, active = "done", qStep_Next = qStep_Next, active_Next = true, isNPC_Next = true})
				--pData.itemQuest = {} --clear playerModData
				--print("Client-----------PlayerModData.active= "..tostring(qStep).." - ", playerGMD_Quest_Q1[qStep].active)
			end
			
		--q1s007 - Tìm em trai tại Finnegan Research Group
		elseif playerGMD_Quest_Q1.q1s007.active == true then
			local qStep, qStep_Next = "q1s007", "q1s008"
			DoQuestList_AddItem({id = 1, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 13591, y = 1703, texture = questMarker})
		
		--q1s008 - Tìm manh mối tại Louisville Metro Police Department
		elseif playerGMD_Quest_Q1.q1s008.active == true then
			local qStep, qStep_Next = "q1s008", "q1s009"
			local questMD = Func.GetQuestGlobalModData({qStep = qStep})
			DoQuestList_AddItem({id = 1, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 12539, y = 1633, texture = questMarker})	
			if Func.IsPlayerInArea(player, {x1 = 12510, y1 = 1600, x2 = 12570, y2 = 1656, z = 6}) then
				--if not pData.itemQuest[qStep].spawnedEventObj then
				local modData, val = "AddedEventObjects", true
				--print("Client----questMD.Object 111 = ", questMD.Object[qStep])
				if not questMD.Object[qStep] then questMD.Object[qStep] = {} end
				if not questMD.Object[qStep][modData] then
					local x, y, z = 12555, 1634, 6
					local square = Func.GetSquare({x = x, y = y, z = z, hasFloor = true})
					--print("Client----questMD.Object 333 = ", square)
					if square then
						sendClientCommand(player, 'NPCQuestCM', 'RemoveZombiesInAreaExceptNPC', {x1 = 12553, y1 = 1628, x2 = 12561, y2 = 1635, z = 6})
						local object = Func.AddObjectToSquare(nil, "location_business_office_generic_01_32", {isTransmit = true, needSqIsFree = true, needFloor = true, x = x, y = y, z = z, objType = "IsoObject", isNorth = true, isLocked = false})
						if object then questMD.Object[qStep][modData] = val end
						sendClientCommand(player, 'NPCQuestCM', 'UpdateQuestModData', {qStep = qStep, modData = modData, val = val})
					end
				end
			end
		
		--q1s009 - Tìm địa điểm bị tập kích
		elseif playerGMD_Quest_Q1.q1s009.active == true then
			local qStep, qStep_Next = "q1s009", "q1s010"
			local questMD = Func.GetQuestGlobalModData({qStep = qStep})
			DoQuestList_AddItem({id = 1, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			
			if Func.IsPlayerInArea(player, {x1 = 13460, y1 = 4801, x2 = 13580, y2 = 4921}) then
				--Check 4 square để đảm bảo khu vực event đã được load hết
				local square1 = Func.GetSquare({x = 13511, y = 4849, z = 0, hasFloor = true})
				local square2 = Func.GetSquare({x = 13526, y = 4849, z = 0, hasFloor = true})
				local square3 = Func.GetSquare({x = 13511, y = 4871, z = 0, hasFloor = true})
				local square4 = Func.GetSquare({x = 13526, y = 4871, z = 0, hasFloor = true})
				if square1 and square2 and square3 and square4 then	
					local modData, val = "AddedEventObjects", true
					if not questMD.Object[qStep] then questMD.Object[qStep] = {} end
					if not questMD.Object[qStep][modData] then
						sendClientCommand(player, 'MainQuest1', 'AddVehicleEvents', {qStep = qStep}) --thêm vehicles event
						AddCorpseEventq1s009() --thêm xác event
						sendClientCommand(player, 'NPCQuestCM', 'UpdateQuestModData', {qStep = qStep, modData = modData, val = val})
						questMD.Object[qStep][modData] = val
					end
					if Func.IsPlayerInArea(player, {x1 = 13511, y1 = 4849, x2 = 13526, y2 = 4871}) then
						DoQuestStepActive(player, {introWindow = false, isPopIn = true, qStep = qStep, active = "done", qStep_Next = qStep_Next, active_Next = true, isNPC_Next = false})
						--print("Client-----------PlayerModData.active= "..tostring(qStep).." - ", playerGMD_Quest_Q1[qStep].active)
					end
				end
			end
		
		--q1s010 - Tìm manh mối tại địa điểm bị tập kích 
		elseif playerGMD_Quest_Q1.q1s010.active == true then
			local qStep, qStep_Next = "q1s010", "q1s011"
			DoQuestList_AddItem({id = 1, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			
			local itemFullType = "Base.Notepad"
			if Func.IsPlayerInArea(player, {x1 = 13460, y1 = 4801, x2 = 13580, y2 = 4921}) then
				if not localVar[10] then --đảm bảo chỉ chạy 1 lần khi player ở trong khu vực này, tránh spawn lại item khi bị nhặt lên
					local x, y, z = 13519, 4862, 0
					local square = Func.GetSquare({x = x, y = y, z = z, hasFloor = true})
					if square then
						Func.DoSpawnItemQuestOnSquare({qStep = qStep, x = x, y = y, z = z, itemFullType = itemFullType, range = 1, isNote = true, noteStep = 1, qID = 1, iModData = "isKeyQuest1"})					 
						localVar[10] = true
					end
				end				
			else if localVar[10] ~= false then localVar[10] = false end
			end
			
			--lấy được note
			local itemQuest = Func.GetItemQuestInINVPlayer(player, itemFullType, {qStep = qStep, iModData = "isKeyQuest1"})
			if itemQuest then
				DoQuestStepActive(player, {introWindow = false, isPopIn = true, qStep = qStep, active = "done", qStep_Next = qStep_Next, active_Next = true, isNPC_Next = false})
				--print("Client-----------PlayerModData.active= "..tostring(qStep).." - ", playerGMD_Quest_Q1[qStep].active)
			end
		
		--q1s011 - Tìm manh mối về từ khóa MUL 
		elseif playerGMD_Quest_Q1.q1s011.active == true then
			local qStep, qStep_Next = "q1s011", "q1s012"
			DoQuestList_AddItem({id = 1, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
		end		
		
		
		--q1s012 --Phòng thí nghiệm bí ẩn
		if playerGMD_Quest_Q1.q1s012.active == true then
			local qStep, qStep_Next = "q1s012", "q1s013"
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})	
		
		--q1s013 --Tìm Dr. Bassler
		elseif playerGMD_Quest_Q1.q1s013.active == true then
			local qStep, qStep_Next = "q1s013", "q1s014"
			local questMD = Func.GetQuestGlobalModData({qStep = qStep})
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})	
			if Func.IsPlayerInArea(player, {x1 = 10569, y1 = 9444, x2 = 10689, y2 = 9564, z = 0}) then
				local modData, val = "AddedEventObjects", true
				if not questMD.Object[qStep] then questMD.Object[qStep] = {} end
				if not questMD.Object[qStep][modData] then
					local x, y, z = 10628, 9503, 0
					local square = Func.GetSquare({x = x, y = y, z = z, hasFloor = true})
					if square then
						local object = Func.AddObjectToSquare(nil, "location_business_office_generic_01_32", {isTransmit = true, needSqIsFree = true, needFloor = true, x = x, y = y, z = z, objType = "IsoObject", isNorth = true, isLocked = false})
						if object then questMD.Object[qStep][modData] = val end
						sendClientCommand(player, 'NPCQuestCM', 'UpdateQuestModData', {qStep = qStep, modData = modData, val = val})
					end
				end
			end
		
		--q1s014 --Trở về phòng thí nghiệm Dr. Venter
		elseif playerGMD_Quest_Q1.q1s014.active == true then
			local qStep, qStep_Next = "q1s014", "q1s015"
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
		
		--q1s015 --Đồng ý hỗ trợ Dr. Venter
		elseif playerGMD_Quest_Q1.q1s015.active == true then	
			local qStep, qStep_Next = "q1s015", "q1s016"
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
		
		--q1s016 --Hỗ trợ Dr. Venter tìm kiếm thức ăn -- 1 người/ngày/100 hunger --1400
		elseif playerGMD_Quest_Q1.q1s016.active == true then		
			local qStep, qStep_Next = "q1s016", "q1s017"
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			--if not playerGMD_Quest_Q1[qStep].collectQItemName then playerGMD_Quest_Q1[qStep].collectQItemName = getText("IGUI_VLQ_2_CollectQItemName_q1s016") end
			if not playerGMD_Quest_Q1[qStep].collectedRHunger then playerGMD_Quest_Q1[qStep].collectedRHunger = 0 end
			if not playerGMD_Quest_Q1[qStep].requestRHunger then playerGMD_Quest_Q1[qStep].requestRHunger = 1400 end
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = true, currentCollection = playerGMD_Quest_Q1[qStep].collectedRHunger, requestCollection = playerGMD_Quest_Q1[qStep].requestRHunger, collectQItemName = getText("IGUI_VLQ_2_CollectQItemName_q1s016")})
		
		--q1s017 --Hỗ trợ Dr. Venter tìm nước tinh khiết -- 1 người/ngày/2l --30
		elseif playerGMD_Quest_Q1.q1s017.active == true then		
			local qStep, qStep_Next = "q1s017", "q1s018"
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			--if not playerGMD_Quest_Q1[qStep].collectQItemName then playerGMD_Quest_Q1[qStep].collectQItemName = getText("IGUI_VLQ_2_CollectQItemName_q1s017") end
			if not playerGMD_Quest_Q1[qStep].collectedRThirst then playerGMD_Quest_Q1[qStep].collectedRThirst = 0 end
			if not playerGMD_Quest_Q1[qStep].requestRThirst then playerGMD_Quest_Q1[qStep].requestRThirst = 30 end
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = true, currentCollection = playerGMD_Quest_Q1[qStep].collectedRThirst, requestCollection = playerGMD_Quest_Q1[qStep].requestRThirst, collectQItemName = getText("IGUI_VLQ_2_CollectQItemName_q1s017")})
		
		--q1s018 --Hỗ trợ Dr. Venter lấy mẫu máu xác sống
		elseif playerGMD_Quest_Q1.q1s018.active == true then		
			local qStep, qStep_Next = "q1s018", "q1s019"
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			--if not playerGMD_Quest_Q1[qStep].collectQItemName then playerGMD_Quest_Q1[qStep].collectQItemName = getText("ItemName_Base.VLZBloodSyringe") end
			local qItem = instanceItem("Base.VLZBloodSyringe")
			if not playerGMD_Quest_Q1[qStep].collectedBlood then playerGMD_Quest_Q1[qStep].collectedBlood = 0 end
			if not playerGMD_Quest_Q1[qStep].requestBlood then playerGMD_Quest_Q1[qStep].requestBlood = 15 end
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = true, currentCollection = playerGMD_Quest_Q1[qStep].collectedBlood, requestCollection = playerGMD_Quest_Q1[qStep].requestBlood, collectQItemName = qItem and qItem:getName() or nil})
			if not localVar[18] then
				Events.OnPreFillWorldObjectContextMenu.Remove(VLF.AddContextMenu_BloodSample)
				Events.OnPreFillWorldObjectContextMenu.Add(VLF.AddContextMenu_BloodSample)
				localVar[18] = true
			end
		
		--q1s019 --Chờ đợi Dr. Venter nghiên cứu mẫu máu --1 ngày
		elseif playerGMD_Quest_Q1.q1s019.active == true then		
			local qStep, qStep_Next = "q1s019", "q1s020"
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			if not playerGMD_Quest_Q1[qStep].startHourWait then playerGMD_Quest_Q1[qStep].startHourWait = getGameTime():getWorldAgeHours() end
			if not localVar[19] then
				if not playerGMD_Quest_Q1[qStep].waitHourPassed then
					Events.EveryHours.Remove(WaitTimePass)
					Events.EveryHours.Add(WaitTimePass)
				end
				localVar[19] = true
			end
			if playerGMD_Quest_Q1[qStep].waitHourPassed == true then
				DoQuestStepActive(player, {isPopIn = true, qStep = qStep, active = "done", qStep_Next = qStep_Next, active_Next = true, isNPC_Next = true, qID = 2}) --cập nhật qStep --kiểm tra bắt buộc isNPC_Next
			end				
		
		--q1s020 --Trở lại phòng thí nghiệm của Dr. Venter
		elseif playerGMD_Quest_Q1.q1s020.active == true then
			local qStep, qStep_Next = "q1s020", "q1s021"	
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
		
		--q1s021 --Hỗ trợ Dr. Venter lấy 15 mẫu vật từ xác sống
		elseif playerGMD_Quest_Q1.q1s021.active == true then
			local qStep, qStep_Next = "q1s021", "q1s022"
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			--if not playerGMD_Quest_Q1[qStep].collectQItemName then playerGMD_Quest_Q1[qStep].collectQItemName = getText("ItemName_Base.VLZSpecimenContainer") end
			local qItem = instanceItem("Base.VLZSpecimenContainer")
			if not playerGMD_Quest_Q1[qStep].collectedZSpecimen then playerGMD_Quest_Q1[qStep].collectedZSpecimen = 0 end
			if not playerGMD_Quest_Q1[qStep].requestZSpecimen then playerGMD_Quest_Q1[qStep].requestZSpecimen = 15 end
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = true, currentCollection = playerGMD_Quest_Q1[qStep].collectedZSpecimen, requestCollection = playerGMD_Quest_Q1[qStep].requestZSpecimen, collectQItemName = qItem and qItem:getName() or nil})
			if not localVar[21] then
				Events.OnPreFillWorldObjectContextMenu.Remove(VLF.AddContextMenu_ZombieSpecimen)
				Events.OnPreFillWorldObjectContextMenu.Add(VLF.AddContextMenu_ZombieSpecimen)
				localVar[21] = true
			end				
		
		--q1s022 --Chờ đợi Dr. Venter nghiên cứu mẫu vật --1 ngày
		elseif playerGMD_Quest_Q1.q1s022.active == true then
			local qStep, qStep_Next = "q1s022", "q1s023"
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			if not playerGMD_Quest_Q1[qStep].startHourWait then playerGMD_Quest_Q1[qStep].startHourWait = getGameTime():getWorldAgeHours() end
			if not localVar[22] then
				if not playerGMD_Quest_Q1[qStep].waitHourPassed then
					Events.EveryHours.Remove(WaitTimePass)
					Events.EveryHours.Add(WaitTimePass)
				end
				localVar[22] = true
			end
			if playerGMD_Quest_Q1[qStep].waitHourPassed == true then
				DoQuestStepActive(player, {isPopIn = true, qStep = qStep, active = "done", qStep_Next = qStep_Next, active_Next = true, isNPC_Next = true, qID = 2}) --cập nhật qStep --kiểm tra bắt buộc isNPC_Next
			end
		
		--q1s023 --Uống rượu cùng người bạn vong niên
		elseif playerGMD_Quest_Q1.q1s023.active == true then
			local qStep, qStep_Next = "q1s023", "q1s024"
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
		
		--q1s024 --Chờ đợi Dr. Venter nghiên cứu mẫu vật --3 ngày
		elseif playerGMD_Quest_Q1.q1s024.active == true then
			local qStep, qStep_Next = "q1s024", "q1s025"
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			if not playerGMD_Quest_Q1[qStep].startHourWait then playerGMD_Quest_Q1[qStep].startHourWait = getGameTime():getWorldAgeHours() end
			if not localVar[24] then
				if not playerGMD_Quest_Q1[qStep].waitHourPassed then
					Events.EveryHours.Remove(WaitTimePass)
					Events.EveryHours.Add(WaitTimePass)
				end
				localVar[24] = true
			end
			if playerGMD_Quest_Q1[qStep].waitHourPassed == true then
				DoQuestStepActive(player, {isPopIn = true, qStep = qStep, active = "done", qStep_Next = qStep_Next, active_Next = true, isNPC_Next = true, qID = 2}) --cập nhật qStep --kiểm tra bắt buộc isNPC_Next
			end
		
		--q1s025 --Trở lại phòng thí nghiệm của Dr. Venter
		elseif playerGMD_Quest_Q1.q1s025.active == true then
			local qStep, qStep_Next = "q1s025", "q1s026"	
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
		
		--q1s026 --Hỗ trợ Dr. Venter bắt 5 con chuột sống
		elseif playerGMD_Quest_Q1.q1s026.active == true then
			local qStep, qStep_Next = "q1s026", "q1s027"
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			--if not playerGMD_Quest_Q1[qStep].collectQItemName then playerGMD_Quest_Q1[qStep].collectQItemName = "Mouse" end
			if not playerGMD_Quest_Q1[qStep].collectedMouse then playerGMD_Quest_Q1[qStep].collectedMouse = 0 end
			if not playerGMD_Quest_Q1[qStep].requestMouse then playerGMD_Quest_Q1[qStep].requestMouse = 5 end
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = true, currentCollection = playerGMD_Quest_Q1[qStep].collectedMouse, requestCollection = playerGMD_Quest_Q1[qStep].requestMouse, collectQItemName = getText("IGUI_VLQ_2_CollectQItemName_q1s026")})
		
		--q1s027 --Hỗ trợ Dr. Venter bắt 3 con ếch còn sống
		elseif playerGMD_Quest_Q1.q1s027.active == true then
			local qStep, qStep_Next = "q1s027", "q1s028"
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			--if not playerGMD_Quest_Q1[qStep].collectQItemName then playerGMD_Quest_Q1[qStep].collectQItemName = getText("ItemName_Base.Frog") end
			local qItem = instanceItem("Base.Frog")
			if not playerGMD_Quest_Q1[qStep].collectedFrog then playerGMD_Quest_Q1[qStep].collectedFrog = 0 end
			if not playerGMD_Quest_Q1[qStep].requestFrog then playerGMD_Quest_Q1[qStep].requestFrog = 3 end
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = true, currentCollection = playerGMD_Quest_Q1[qStep].collectedFrog, requestCollection = playerGMD_Quest_Q1[qStep].requestFrog, collectQItemName = qItem and qItem:getName() or nil})
		
		--q1s028 --Hỗ trợ Dr. Venter bắt 10 con đỉa còn sống- Leech
		elseif playerGMD_Quest_Q1.q1s028.active == true then
			local qStep, qStep_Next = "q1s028", "q1s029"
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			--if not playerGMD_Quest_Q1[qStep].collectQItemName then playerGMD_Quest_Q1[qStep].collectQItemName = getText("ItemName_Base.Leech") end
			local qItem = instanceItem("Base.Leech")
			if not playerGMD_Quest_Q1[qStep].collectedLeech then playerGMD_Quest_Q1[qStep].collectedLeech = 0 end
			if not playerGMD_Quest_Q1[qStep].requestLeech then playerGMD_Quest_Q1[qStep].requestLeech = 10 end
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = true, currentCollection = playerGMD_Quest_Q1[qStep].collectedLeech, requestCollection = playerGMD_Quest_Q1[qStep].requestLeech, collectQItemName = qItem and qItem:getName() or nil})
		
		--q1s029 --Chờ đợi Dr. Venter nghiên cứu mẫu vật --3 ngày
		elseif playerGMD_Quest_Q1.q1s029.active == true then
			local qStep, qStep_Next = "q1s029", "q1s030"
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			if not playerGMD_Quest_Q1[qStep].startHourWait then playerGMD_Quest_Q1[qStep].startHourWait = getGameTime():getWorldAgeHours() end
			if not localVar[29] then
				if not playerGMD_Quest_Q1[qStep].waitHourPassed then
					Events.EveryHours.Remove(WaitTimePass)
					Events.EveryHours.Add(WaitTimePass)
				end
				localVar[29] = true
			end
			if playerGMD_Quest_Q1[qStep].waitHourPassed == true then
				DoQuestStepActive(player, {isPopIn = true, qStep = qStep, active = "done", qStep_Next = qStep_Next, active_Next = true, isNPC_Next = true, qID = 2}) --cập nhật qStep --kiểm tra bắt buộc isNPC_Next
			end
		
		--q1s030 --Trở lại phòng thí nghiệm của Dr. Venter
		elseif playerGMD_Quest_Q1.q1s030.active == true then
			local qStep, qStep_Next = "q1s030", "q1s031"	
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
		
		--q1s031 --Hỗ trợ Dr. Venter tìm kiếm thức ăn -- 1 người/ngày/100 hunger --1500
		elseif playerGMD_Quest_Q1.q1s031.active == true then		
			local qStep, qStep_Next = "q1s031", "q1s032"
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			--if not playerGMD_Quest_Q1[qStep].collectQItemName then playerGMD_Quest_Q1[qStep].collectQItemName = getText("IGUI_VLQ_2_CollectQItemName_q1s016") end
			if not playerGMD_Quest_Q1[qStep].collectedRHunger then playerGMD_Quest_Q1[qStep].collectedRHunger = 0 end
			if not playerGMD_Quest_Q1[qStep].requestRHunger then playerGMD_Quest_Q1[qStep].requestRHunger = 1500 end
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = true, currentCollection = playerGMD_Quest_Q1[qStep].collectedRHunger, requestCollection = playerGMD_Quest_Q1[qStep].requestRHunger, collectQItemName = getText("IGUI_VLQ_2_CollectQItemName_q1s016")})

		--q1s032 --Hỗ trợ Dr. Venter lấy 1 mẫu vật từ người đang bị biến đổi
		elseif playerGMD_Quest_Q1.q1s032.active == true then
			local qStep, qStep_Next = "q1s032", "q1s033"
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			local qItem = instanceItem("Base.VLInfectedSpecimenContainer")
			if not playerGMD_Quest_Q1[qStep].collectedQItem then playerGMD_Quest_Q1[qStep].collectedQItem = 0 end
			if not playerGMD_Quest_Q1[qStep].requestQItem then playerGMD_Quest_Q1[qStep].requestQItem = 2 end
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = true, currentCollection = playerGMD_Quest_Q1[qStep].collectedQItem, requestCollection = playerGMD_Quest_Q1[qStep].requestQItem, collectQItemName = qItem and qItem:getName() or nil})
		
			if not localVar[32] then
				Events.EveryHours.Remove(VLF.Event_Survivalist_InHouse)
				Events.EveryHours.Add(VLF.Event_Survivalist_InHouse)
				Events.OnPreFillWorldObjectContextMenu.Remove(VLF.AddContextMenu_InfectedSpecimen)
				Events.OnPreFillWorldObjectContextMenu.Add(VLF.AddContextMenu_InfectedSpecimen)
				localVar[32] = true
			end
		
		--q1s033 --Chờ đợi Dr. Venter nghiên cứu mẫu vật --7 ngày
		elseif playerGMD_Quest_Q1.q1s033.active == true then
			local qStep, qStep_Next = "q1s033", "q1s034"
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			if not playerGMD_Quest_Q1[qStep].startHourWait then playerGMD_Quest_Q1[qStep].startHourWait = getGameTime():getWorldAgeHours() end
			if not localVar[33] then
				if not playerGMD_Quest_Q1[qStep].waitHourPassed then
					Events.EveryHours.Remove(WaitTimePass)
					Events.EveryHours.Add(WaitTimePass)
				end
				localVar[33] = true
			end
			if playerGMD_Quest_Q1[qStep].waitHourPassed == true then
				DoQuestStepActive(player, {isPopIn = true, qStep = qStep, active = "done", qStep_Next = qStep_Next, active_Next = true, isNPC_Next = true, qID = 2}) --cập nhật qStep --kiểm tra bắt buộc isNPC_Next
			end
		--q1s034 --Trở lại phòng thí nghiệm của Dr. Venter
		elseif playerGMD_Quest_Q1.q1s034.active == true then
			local qStep, qStep_Next = "q1s034", "q1s035"
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
		--q1s035 --Hối thúc Dr. Venter tiêu hủy mẫu vật sống
		elseif playerGMD_Quest_Q1.q1s035.active == true then
			local qStep, qStep_Next = "q1s035", "q1s036"
			
			--Khi q1s035_2 active thì đổi hiển thị trong bảng Quest
			if playerGMD_Quest_Q1.q1s035_2 and playerGMD_Quest_Q1.q1s035_2.active == true then
				DoQuestList_AddItem({id = 2, qStep = "q1s035_2", isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			else
				DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			end
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			
			--add sound thu hút zombie
			if pTick % (delay * 30) == 0 then
				local sq = getCell():getGridSquare(10642, 10413, 0)
				if sq then addSound(sq:getFloor(), sq:getX(), sq:getY(), sq:getZ(), 250, 1000) end
			end
				
			--Không còn zombie xung quanh thì update NPC và qStep
			local pData = Func.GetPlayerModData({qStep = nil})
			if pData.events.q1s035 == true then
				local zNPCList = Func.GetNPCsByVarAndQStep("npcQuestIdle", qStep, {_ = nil})
				--print("Client-------zNPCList= ", zNPCList)
				if zNPCList and zNPCList[1] then
					--print("Client-------zNPCList[1]= ", zNPCList[1])
					UpdateNPCToNextQStep(zNPCList[1], qStep_Next) --cập nhật NPC thành NPC qStep tiếp theo
				end
				playerGMD_Quest_Q1.q1s035_2.active = nil
				DoQuestStepActive(player, {npcTalk = false, isPopIn = true, qStep = qStep, active = "done", qStep_Next = qStep_Next, active_Next = true, isNPC_Next = true, qID = 2}) --cập nhật qStep --kiểm tra bắt buộc isNPC_Next
			end
			
		--q1s036 --Trở lại phòng thí nghiệm của Dr. Venter
		elseif playerGMD_Quest_Q1.q1s036.active == true then
			local qStep, qStep_Next = "q1s036", "q1s037"
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
		
		--q1s037 --Chờ đợi Dr. Venter nghiên cứu mẫu vật --2 ngày
		elseif playerGMD_Quest_Q1.q1s037.active == true then
			local qStep, qStep_Next = "q1s037", "q1s038"
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			if not playerGMD_Quest_Q1[qStep].startHourWait then playerGMD_Quest_Q1[qStep].startHourWait = getGameTime():getWorldAgeHours() end
			if not localVar[37] then
				if not playerGMD_Quest_Q1[qStep].waitHourPassed then
					Events.EveryHours.Remove(WaitTimePass)
					Events.EveryHours.Add(WaitTimePass)
				end
				localVar[37] = true
			end
			if playerGMD_Quest_Q1[qStep].waitHourPassed == true then
				--Nếu không ở phòng thí nghiệm +-80 ô thì mới update quest. --Để xóa NPC
				if not Func.IsPlayerInArea(player, {x1 = 10630 - 80, y1 = 10394 - 80, x2 = 10651 + 80, y2 = 10415 + 80}) then
					DoQuestStepActive(player, {isPopIn = true, qStep = qStep, active = "done", qStep_Next = qStep_Next, active_Next = true, isNPC_Next = false, qID = 2}) --cập nhật qStep --kiểm tra bắt buộc isNPC_Next
					Func.NPCInQueueSpawnList({qStep = "q1s014_2", active = nil}) --Deactive Dr. Bassler
				end
			end
		
		--q1s038 --Trở lại phòng thí nghiệm của Dr. Venter
		elseif playerGMD_Quest_Q1.q1s038.active == true then
			local qStep, qStep_Next = "q1s038", "q1s039"
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			if Func.IsPlayerInArea(player, {x1 = 10630, y1 = 10394, x2 = 10651, y2 = 10415, z = -1}) then
				DoQuestStepActive(player, {isPopIn = true, qStep = qStep, active = "done", qStep_Next = qStep_Next, active_Next = true, isNPC_Next = false, qID = 2}) --cập nhật qStep --kiểm tra bắt buộc isNPC_Next
			end
		
		--q1s039 --Lời nhắn của Dr. Venter
		elseif playerGMD_Quest_Q1.q1s039.active == true then
			local qStep, qStep_Next = "q1s039", "q1s040"
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})
			--Add thư nhắn của Tiến Sĩ
			local itemFullType = "Base.GenericMail"
			if Func.IsPlayerInArea(player, {x1 = 10630, y1 = 10394, x2 = 10651, y2 = 10415, z = -1}) then
				if not localVar[38] then
					local x, y, z = 10638, 10405, -1
					local square = Func.GetSquare({x = x, y = y, z = z, hasIContainer = true})
					if square then
						local item = Func.DoSpawnItemQuestOnSquare({qStep = qStep, x = x, y = y, z = z, itemFullType = itemFullType, range = 0, isNote = true, noteStep = 1, qID = 2, iModData = "isKeyQuest1", totalPage = 2})
						if not playerGMD_Quest_Q1[qStep].rewardsAdded then --chỉ add 1 lần duy nhất
							local item2 = Func.AddItemToSquares(square, "Base.VLUpgradeFitnessSerum1", {qStep = qStep, range = 0})
							if item2 then playerGMD_Quest_Q1[qStep].rewardsAdded = true end
						end
						if item then localVar[38] = true end						
					end
				end
			else if localVar[38] ~= false then localVar[38] = false end
			end
			--Lấy được thư nhắn của tiến sĩ
			local itemQuest = Func.GetItemQuestInINVPlayer(player, itemFullType, {qStep = qStep, iModData = "isKeyQuest1"})
			if itemQuest then
				DoQuestStepActive(player, {introWindow = false, isPopIn = true, qStep = qStep, active = "done", qStep_Next = qStep_Next, active_Next = true, isNPC_Next = false, qID = 2})
				--Không update máy phát điện ở phòng thí nghiệm nữa
				local pData = Func.GetPlayerModData({qStep = nil})
				pData.events.generatorAtLab = "stop"
			end
		
		--q1s040 --NHIỆM VỤ CHỜ CẬP NHẬT
		elseif playerGMD_Quest_Q1.q1s040.active == true then
			local qStep, qStep_Next = "q1s040", "q1s041"
			DoQuestList_AddItem({id = 2, qStep = qStep, isDone = false, qtype = qtype, isCollection = false, currentCollection = nil, requestCollection = nil})
			Func.MarkerList_Add({qStep = qStep, x = 10637, y = 10407, texture = questMarker})	

		end
			

	--CÓ THỂ CHẠY PHẦN DƯỚI BẰNG EVENT RIÊNG
	elseif pTick % 59 == 0 then
		--Zombie update khi ở Military Research Facility
		if Func.IsPlayerInArea(player, {x1 = 5537, y1 = 12456, x2 = 5589, y2 = 12510}) then
			if not localVar[1001] then
				--print("Client-----------Try-Active Event OnZombieUpdateq1s006: 222222222")
				Events.OnZombieUpdate.Remove(OnZombieUpdateq1s006)
				Events.OnZombieUpdate.Add(OnZombieUpdateq1s006)
				localVar[1001] = true
			end
		end
		
		--Cửa xuống phòng thí nghiệm của tiến sĩ luôn bị bịt lại, chỉ mở khi qStep q1s011 == true | update Generator
		if Func.IsPlayerInArea(player, {x1 = 10585, y1 = 10354, x2 = 10705, y2 = 10474}) then
			if not localVar[1002] then
				--local x, y, z = 13528, 4870, 0
				local square1 = Func.GetSquare({x = 10645, y = 10414, z = 0})
				local square2 = Func.GetSquare({x = 10646, y = 10414, z = 0})
				local square3 = Func.GetSquare({x = 10647, y = 10414, z = 0})
				if square1 and square2 and square3 then
					local playerGMD_Quest_Q1 = Func.GetPlayerGlobalModDataQ1(player, {qStep = "q1s011"})
					local spriteName = "floors_interior_tilesandwood_01_14"
					if not playerGMD_Quest_Q1.q1s011.active then
						--add obj mà không transmit để chỉ client này mới có tác dụng
						Func.AddObjectToSquare(nil, spriteName, {isTransmit = false, needSqIsFree = false, needFloor = false, x = 10645, y = 10414, z = 0, objType = "IsoObject"})
						Func.AddObjectToSquare(nil, spriteName, {isTransmit = false, needSqIsFree = false, needFloor = false, x = 10646, y = 10414, z = 0, objType = "IsoObject"})
						Func.AddObjectToSquare(nil, spriteName, {isTransmit = false, needSqIsFree = false, needFloor = false, x = 10647, y = 10414, z = 0, objType = "IsoObject"})
					else
						--Mở cửa xuống khi q1s011 == true
						Func.RemoveObjectOnSquare(nil, spriteName, {isTransmit = false, x = 10645, y = 10414, z = 0, removeAll = false})
						Func.RemoveObjectOnSquare(nil, spriteName, {isTransmit = false, x = 10646, y = 10414, z = 0, removeAll = false})
						Func.RemoveObjectOnSquare(nil, spriteName, {isTransmit = false, x = 10647, y = 10414, z = 0, removeAll = false})
						--print("Client-----------RemoveObjectOnSquare")
					end
					--Xóa zombie trong phòng thí nghiệm
					sendClientCommand(player, 'NPCQuestCM', 'RemoveZombiesInAreaExceptNPC', {x1 = 10630, y1 = 10394, x2 = 10651, y2 = 10415, z = -1})
					
					--Nếu đã mất điện thì Add Generator hoặc update Generator
					local pData = Func.GetPlayerModData({qStep = nil})
					if not pData.events.generatorAtLab then
						if not getWorld():isHydroPowerOn() then
							local x, y, z = 10647, 10398, -2
							local sq = Func.GetOrCreateSquare({x = x, y = y, z = z})
							if sq then 
								local obj = Func.GetObjectOnSquare(sq, {objName = "IsoGenerator"})
								if not obj then
									Func.AddGenerator({genType = "Base.Generator", x = x, y = y, z = z})
								else
									obj:setFuel(100)
									obj:setCondition(99)
									obj:setActivated(true)
									obj:transmitCompleteItemToServer()
									obj:sync()
								end
							end
						end	
					end
					localVar[1002] = true
				end
			end
		else if localVar[1002] ~= false then localVar[1002] = false end 
		end
		
		--Khi đến được phòng thí nghiệm của tiến sĩ thì update qStep q1s012 == true
		if Func.IsPlayerInArea(player, {x1 = 10630, y1 = 10394, x2 = 10651, y2 = 10415, z = -1}) then
			if not localVar[1003] then
				--update qStep
				local qStep = "q1s011"
				local playerGMD_Quest_Q1 = Func.GetPlayerGlobalModDataQ1(player, {qStep = qStep})
				if not playerGMD_Quest_Q1[qStep].activeQStepEvent then
					DoQuestStepActive(player, {introWindow = false, isPopIn = true, qStep = "q1s011", active = true, qStep_Next = "q1s012", active_Next = true, isNPC_Next = true})
					Func.ActiveQuestIntro_Free(getText("IGUI_VLQ_2_Desc_q1s012"), (getCore():getScreenWidth() - 800) / 2, (getCore():getScreenHeight() - 200) / 6, 800, 250, false, "")
					playerGMD_Quest_Q1[qStep].activeQStepEvent = true
					sendClientCommand(player, 'MainQuest1', 'UpdateAllPlayerGMD', playerGMD_Quest_Q1)
					--print("Client-----------playerGMD_Quest_Q1[q1s011].activeQStepEvent", playerGMD_Quest_Q1[qStep].activeQStepEvent)
				end
				localVar[1003] = true
			end
		else if localVar[1003] ~= false then localVar[1003] = false end 	
		end
	end

	if pTick == 1000 then pTick = 0 end
	pTick = pTick + 1
end
Events.OnPlayerUpdate.Remove(OnPlayerUpdateQ1)
Events.OnPlayerUpdate.Add(OnPlayerUpdateQ1)









