-------------------------------------------------------------- -- (SERVER SIDE) Obstacle Course Starter NPC -- -- Starts the course for the player -------------------------------------------------------------- ---------------------------------------------------------------- -- Includes ---------------------------------------------------------------- require('ai/AG/L_AG_SCENE_2_INCLUDE') MS_IN_SEC = 1000 ---------------------------------------------------------------- -- Startup of the object ---------------------------------------------------------------- function onStartup(self) -- set max users to something high self:SetActivityParams{ modifyActivityActive=true, activityActive = true, maxUsers = 9999, modifyMaxUsers = true } self:SendLuaNotificationRequest{requestTarget=GAMEOBJ:GetZoneControlID(), messageName="PlayerExit"} end ---------------------------------------------------------------- -- Returns true/false if a player is in the activity -- takes SELF and a PLAYER object ---------------------------------------------------------------- function IsPlayerInActivity(self, player) -- check if player is in activity local existMsg = self:ActivityUserExists{ userID = player } if (existMsg) then return existMsg.bExists end return false end ---------------------------------------------------------------- -- Happens on interaction for server ---------------------------------------------------------------- function onUse(self, msg) -- get player who clicked on us local player = msg.user -- check if player is in course if ( IsPlayerInActivity(self, player) == true ) then -- offer exit self:Help{rerouteID = player, iHelpID = 0} else -- offer start activity self:Help{rerouteID = player, iHelpID = 1} end end ---------------------------------------------------------------- -- Sent from a player when responding from a messagebox ---------------------------------------------------------------- function onMessageBoxRespond(self, msg) -- Response to Exit activity dialog and user pressed OK if ( msg.identifier == "player_dialog_cancel_course" and msg.iButton == 1) then -- remove the user self:RemoveActivityUser{ userID = msg.sender } -- Response to Start activity dialog and ok is pressed and player is not in activity elseif (msg.identifier == "player_dialog_start_course" and msg.iButton == 1 and IsPlayerInActivity(self, msg.sender) == false) then -- add the new user self:AddActivityUser{ userID = msg.sender } -- start the activity for the new user StartActivity(self, msg.sender) end end ---------------------------------------------------------------- -- Stores the start time for the player in the activity and -- sends messages to start it ---------------------------------------------------------------- function StartActivity(self, player) -- get the current time in sec local startTime = (GAMEOBJ:GetSystemTime() / MS_IN_SEC) + 4 self:SetActivityUserData{ userID = player, typeIndex = 1, value = tonumber(startTime) } end ---------------------------------------------------------------- -- Handle FireEvent message ---------------------------------------------------------------- function onFireEvent(self, msg) -- user is trying to cancel if ( msg.args == "course_cancel" and IsPlayerInActivity(self, msg.senderID) == true ) then --print(msg.senderID:GetName().name .. ' canceled the race') self:NotifyClientObject{name = "stop_timer" , param1 = 1, rerouteID = msg.senderID} -- remove the user from activity self:RemoveActivityUser{ userID = msg.senderID } -- notify user of remove self:Help{rerouteID = msg.senderID, iHelpID = 2} elseif ( msg.args == "course_finish" and IsPlayerInActivity(self, msg.senderID) == true ) then -- store the finish time in sec local endTime = GAMEOBJ:GetSystemTime() / MS_IN_SEC -- store the time as activity rating [1] self:SetActivityUserData{ userID = msg.senderID, typeIndex = 2, value = tonumber(endTime) } -- distribute rewards self:DistributeActivityRewards{ userID = msg.senderID, bAutoAddCurrency = true, bAutoAddItems = true } -- do complete activity events --self:CompleteActivity{ userID = msg.senderID } self:CompleteActivity{ userID = msg.senderID} -- remove the user from activity self:RemoveActivityUser{ userID = msg.senderID } end end ---------------------------------------------------------------- -- Player has exited the map ---------------------------------------------------------------- function notifyPlayerExit(self, other, msg) if IsPlayerInActivity(self, msg.playerID) then -- remove the user from activity self:RemoveActivityUser{ userID = msg.playerID } end end -------------------------------------------------------------- -- Passes start/end time and gets the total time -------------------------------------------------------------- function GetTotalTime(startTime, endTime) -- calculate total time (subtract countdown and cap at 0) local totalTime = tonumber(endTime) - tonumber(startTime) --totalTime = totalTime -- - CONSTANTS["COUNTDOWN_DELAY_SEC"] if (totalTime < 0) then totalTime = 0 end return math.floor(totalTime) end -------------------------------------------------------------- -- Called when the activity is trying to calculate final rating -------------------------------------------------------------- function onDoCalculateActivityRating(self, msg) -- get the time for the player local totalTime = GetTotalTime(msg.fValue2, msg.fValue3) msg.outActivityRating = totalTime return msg end -------------------------------------------------------------- -- Called when the activity is trying to complete -------------------------------------------------------------- function onDoCompleteActivityEvents(self, msg) -- get the time for the player local totalTime = GetTotalTime(msg.fValue2, msg.fValue3) self:SetActivityUserData{ userID = msg.userID, typeIndex = 0, value = tonumber(totalTime) } --print(msg.userID:GetName().name .. " Total Time" .. msg.fValue2 .. " - " .. msg.fValue3 .. " = " .. totalTime) -- complete mission 286 if it's not already complete if msg.userID:GetMissionState{missionID = 286}.missionState < 8 then msg.userID:UpdateMissionTask{taskType = "complete", value = 286, value2 = 1, target = self} end -- complete activities (Note: negate time to work with perform activity task types / convert back to ms) totalTime = totalTime -- * MS_IN_SEC --total time has to be negative for perform activity task to function properly msg.userID:UpdateMissionTask{ taskType = "performact_time", value2 = self:GetActivityID().activityID, value = totalTime * -1 } -- Update Leaderboards for this user (Note: negate time to work with perform activity task types) self:UpdateActivityLeaderboard{ userID = msg.userID } -- @TODO: Uncomment once we are showing a summary screen to get DB information -- get the leaderboard data for the user and update summary screen if it exists self:RequestActivitySummaryLeaderboardData{ user = msg.userID, queryType = 7 } -- need fix to leaderboard so it can be closed --print(msg.senderID:GetName().name .. ' finished the race') self:NotifyClientObject{name = "stop_timer" , param1 = 1, param2 = totalTime, rerouteID = msg.userID} -- notify user of remove self:Help{rerouteID = msg.userID, iHelpID = 3} end