local wpList = {}; local playerTarget; local lastCompleteQuest = 0; local lastNewQuest = 0; local lastPlayerDirect = 0; zID = 1; callLang = { [0] = " (%s)\tSave recorded nodes and quit\n", [2] = " (%s)\tSave and clear recorded nodes\n", [1] = " (%s)\tDiscard (clear) recorded nodes\n", [3] = " Recording nodes at a %d second interval\n" }; local function roundIt(_number) if _number > (math.floor(_number) + 0.5) then return math.ceil(_number); else return math.floor(_number); end end local function joinMyTables(t1, t2) for k,v in ipairs(t2) do table.insert(t1, v) end return t1 end local function mySplit(inputstr, sep) if sep == nil then sep = "%s" end t={} ; i=1 for str in string.gmatch(inputstr, "([^"..sep.."]+)") do t[i] = str i = i + 1 end return t end local function debugArgs(_anything) if(_anything == nil)then print("Type is nil \n"); end if(type(_anything) == "table")then print("We found table, in it is:\n"); for k,v in ipairs(_anything) do debugArgs(v); end end if(type(_anything) == "boolean")then if(_anything == true)then print("Type is boolean and is true \n"); else print("Type is boolean and is false \n"); end end if(type(_anything) == "number")then print("Type is number and value is: ".._anything.." \n"); end if(type(_anything) == "string")then print("Type is string and with the message: ".._anything.." \n"); end if(type(_anything) == "function")then print("Type is function \n"); end if(type(_anything) == "userdata")then print("Type is userdata \n"); end if(type(_anything) == "thread")then print("Type is thread \n"); end end function startQuestDetect() EventMonitorStart("NEW_Q", "ADDNEW_QUESTBOOK"); EventMonitorStart("COMPLETE_Q", "QUEST_COMPLETE"); EventMonitorStart("NPCWITH_Q", "SHOW_QUESTDETAIL_FROM_NPC"); --[[ Checks if you have ever completed a quest. state = CheckQuest(questID) Returns @state 0 - if you have never completed the quest have not accepted it 1 - if you have accepted the quest but have never completed it 2 - if you have completed the quest at least once ----------- CompleteQuest(); GetChoiceItem_questDetail(?); propatly some info about reward, but return always -1 ------------ index, catalogID, name, track, level, daily, bDaily_num, iQuestType, questID, completed, QuestGroup = GetQuestInfo(index) ]]-- end function recordeNodes( _recordQuest, _recordHarvest ,_inrange , _waypointpass) player:update(); zID = getZoneId(); --make sure local tempTarget = player:getTarget() local tempDirect = player.Direction; local disToLastWP = 0 local firstwp = false; local savewp = false; local tmp = {}; local overwriteOld = false; local isharvest = false; local isnewquest = false; local iscompleteq = false; local weturned = false local NewQuestTable = {} local CompleteQuestTable = {} if( tempTarget ~= nil)then playerTarget = tempTarget; end if (angleDifference(tempDirect,lastPlayerDirect) > math.rad(60))then weturned = true; end --To compensate for different channels while(zID > 1000) do zID = zID - 1000; end if not wpList[zID] then wpList[zID] = {}; wpList[zID].checked = false; end --is this the first WP? if yes ignore distance local index1 = #wpList[zID]; if(wpList[zID][#wpList[zID]] == nil)then firstwp = true; print("We are at the first WP \n") else disToLastWP = distance(wpList[zID][ #wpList[zID]].X,wpList[zID][ #wpList[zID]].Z,wpList[zID][ #wpList[zID]].Y,player.X,player.Z,player.Y); -- print("Th distance to the last Wp is "..disToLastWP.." \n") end if( _recordHarvest)then local obj = nil; local objectList = CObjectList(); objectList:update(); for i = 0,objectList:size() do obj = objectList:getObject(i); if( obj ~= nil ) then local dist = distance(player.X, player.Z, obj.X, obj.Z) --only add if( obj.Type == PT_NODE and dist <= 50)then if( database.nodes[obj.Id] ) then local harvestType = database.nodes[obj.Id].Type; if( harvestType == NTYPE_WOOD ) then hType = "WOOD"; elseif( harvestType == NTYPE_HERB ) then hType = "HERB"; elseif( harvestType == NTYPE_ORE ) then hType = "MINE"; else hType = "QUEST"; end -- Add the node to the table by ZoneID tmp.X = roundIt(obj.X); tmp.Z = roundIt(obj.Z); tmp.Y = roundIt(obj.Y); tmp.Type = hType; tmp.Name = obj.Name; savewp = true; isharvest = true; end end end end end local foundQ = false; if( _recordQuest)then repeat foundQ = false; local timer, moretocome, questID = EventMonitorCheck("NEW_Q","1") if( questID ~= nil and questID ~= lastNewQuest )then print("New Quest was found \n") isnewquest = true; lastNewQuest = questID; savewp = true; tmp.TargetID = playerTarget.Id; table.insert(NewQuestTable, questID); foundQ = true; end local timer, moretocome, cquestID = EventMonitorCheck("COMPLETE_Q") ---The if( cquestID ~= nil and cquestID ~= lastCompleteQuest)then print("Quest complete was found \n") iscompleteq = true; lastCompleteQuest = cquestID; savewp = true; tmp.TargetID = playerTarget.Id; table.insert(CompleteQuestTable, cquestID); foundQ = true; end until foundQ == false ---local timer, moretocome, arg1, arg2 ,arg3, arg4, arg5,arg6 = EventMonitorCheck("NPCWITH_Q","4,1",true) --arg1 == 1 if NPC with Q is opend end local overwritelast = false -- means add action to last WP local removelast = false -- means overwrite X/Z/Y from last WP with current one --find a WP that is worht to safe if( firstwp or (disToLastWP > _inrange) or iscompleteq or isnewquest or isharvest )then -- we add action to another WP becasue we stand in near of it. if( (iscompleteq or lastNewQuest or isharvest) and disToLastWP <= 30 and not firstwp)then overwritelast = true; end -- remove unneeded WPs if( firstwp == false and weturned == false)then if( disToLastWP > _inrange )then if(wpList[zID][ #wpList[zID]-1] ~= nil and wpList[zID][#wpList[zID]] ~= nil and wpList[zID][ #wpList[zID]-1].X ~= nil and wpList[zID][#wpList[zID]].X ~= nil)then local x2 = wpList[zID][#wpList[zID]-1].X;--P1 local z2 = wpList[zID][#wpList[zID]-1].Z; local x1 = wpList[zID][#wpList[zID]].X;--P2 inverse order local z1 = wpList[zID][#wpList[zID]].Z; local x = player.X local z = player.Z local zz = z1 - z2 local xx = x1 - x2 local m; local b; if( xx == 0)then m = xx/zz -- z = x u. x = y b = x1 - (m * z1); testvalue = (m * z) + b if( math.abs( testvalue - x) < _waypointpass )then removelast = true; end else m = zz/xx -- x = x u. z = y b = z1 - (m * x1); testvalue = (m * x) + b if( math.abs( testvalue - z) < _waypointpass )then removelast = true; end end end end end print("We want to safe the WP as usely \n") savewp = true; end --- only update angel if we move if (angleDifference(tempDirect,lastPlayerDirect) > math.rad(20) and (disToLastWP > 20) )then lastPlayerDirect = tempDirect end ---add WP when we turn the char if( weturned == true and disToLastWP >= 20 and not firstwp)then savewp = true; print("We want to safe the WP becasue we turned \n") end if( removelast and (wpList[zID][#wpList[zID]].NewQuestTable~= nil or wpList[zID][#wpList[zID]].CompleteQuestTable ~=nil or wpList[zID][#wpList[zID]].Type ~=nil))then -- we can't remove this WP it has actions in it. removelast = false; end if(isnewquest == true)then print("We want to safe the new Quest \n") tmp.NewQuestTable = NewQuestTable; end if (iscompleteq == true)then print("We want to safe the complete Quest \n") tmp.CompleteQuestTable = CompleteQuestTable; end if( savewp == true and not removelast and not overwritelast)then print("We safe everything in case 1 \n") tmp.X = player.X tmp.Z = player.Z tmp.Y = player.Y table.insert(wpList[zID], tmp); elseif ( savewp == true and savewp == true and removelast and overwritelast)then print("We safe everything in case 2 \n") wpList[zID][#wpList[zID]].Type = tmp.Type wpList[zID][#wpList[zID]].Name = tmp.Name if(isnewquest == true)then if(wpList[zID][#wpList[zID]].NewQuestTable == nil)then wpList[zID][#wpList[zID]].NewQuestTable = tmp.NewQuestTable else wpList[zID][#wpList[zID]].NewQuestTable = joinMyTables(wpList[zID][#wpList[zID]].NewQuestTable, tmp.NewQuestTable) end end if (iscompleteq == true)then if(wpList[zID][#wpList[zID]].CompleteQuestTable == nil)then wpList[zID][#wpList[zID]].CompleteQuestTable = tmp.CompleteQuestTable else wpList[zID][#wpList[zID]].CompleteQuestTable = joinMyTables(wpList[zID][#wpList[zID]].CompleteQuestTable , tmp.CompleteQuestTable ) end end wpList[zID][#wpList[zID]].TargetID = tmp.TargetID -- now position wpList[zID][#wpList[zID]].X = player.X wpList[zID][#wpList[zID]].Z = player.Z wpList[zID][#wpList[zID]].Y = player.Y elseif( savewp == true and not removelast and overwritelast)then print("We safe everything in case 3 \n") wpList[zID][#wpList[zID]].Type = tmp.Type wpList[zID][#wpList[zID]].Name = tmp.Name if(isnewquest == true)then if(wpList[zID][#wpList[zID]].NewQuestTable == nil)then wpList[zID][#wpList[zID]].NewQuestTable = tmp.NewQuestTable else wpList[zID][#wpList[zID]].NewQuestTable = joinMyTables(wpList[zID][#wpList[zID]].NewQuestTable, tmp.NewQuestTable) end end if (iscompleteq == true)then if(wpList[zID][#wpList[zID]].CompleteQuestTable == nil)then wpList[zID][#wpList[zID]].CompleteQuestTable = tmp.CompleteQuestTable else wpList[zID][#wpList[zID]].CompleteQuestTable = joinMyTables(wpList[zID][#wpList[zID]].CompleteQuestTable , tmp.CompleteQuestTable ) end end wpList[zID][#wpList[zID]].TargetID = tmp.TargetID elseif( savewp == true and removelast and not overwritelast and #wpList[zID] ~= 0)then print("We safe everything in case 4 \n") wpList[zID][#wpList[zID]].X = player.X wpList[zID][#wpList[zID]].Z = player.Z wpList[zID][#wpList[zID]].Y = player.Y wpList[zID][#wpList[zID]].Type = tmp.Type wpList[zID][#wpList[zID]].Name = tmp.Name if(isnewquest == true)then if(wpList[zID][#wpList[zID]].NewQuestTable == nil)then wpList[zID][#wpList[zID]].NewQuestTable = tmp.NewQuestTable else wpList[zID][#wpList[zID]].NewQuestTable = joinMyTables(wpList[zID][#wpList[zID]].NewQuestTable, tmp.NewQuestTable) end end if (iscompleteq == true)then if(wpList[zID][#wpList[zID]].CompleteQuestTable == nil)then wpList[zID][#wpList[zID]].CompleteQuestTable = tmp.CompleteQuestTable else wpList[zID][#wpList[zID]].CompleteQuestTable = joinMyTables(wpList[zID][#wpList[zID]].CompleteQuestTable , tmp.CompleteQuestTable ) end end wpList[zID][#wpList[zID]].TargetID = tmp.TargetID end end function saveRecpoints() local filename = "" local file; for i,v in pairs(wpList) do if not wpList[i].checked then -- Zone the nodes are in is the filename zName = "/waypoints/HPoints/" .. string.gsub(sendMacro("GetZoneEnglishName(" .. i .. ");"), " ", "") filename = getExecutionPath() .. zName .. ".xml"; --print(filename); -- Check if file exists file, err = io.open(filename, "r"); -- File exists, add to table --if file then -- print("Loading existing node records for " .. zName); -- loadHPoints(filename, i); -- file:close(); -- end -- print(""..getExecutionPath().."\n"); -- To write the new file print("Saving nodes to file..."); file, err = io.open(filename, "w"); local t = {} t = mySplit(getExecutionPath(),"/" ) local subfolder = t[#t]; while( not file ) do if not (string.find(err, "No such file or directory") == nil) then os.execute("mkdir scripts\\".. subfolder.."\\waypoints\\HPoints"); else print("Could not open file to write, close the file! Then press (Delete) to continue.\n"); stopPE(); end file, err = io.open(filename, "w"); end --print("Writing file: " .. zName); local openformat = "\t%s"; local openformat2 = "\t%s"; -- we don't harvest local closeformat = "\n"; file:write(""); local str = sprintf("\n"); -- create first tag file:write(str); -- write first tag local harvest = "\r\n\t\tplayer:harvest();\r\n" local targetformat = "\r\n\t\tplayer:target_NPC(%d)\r\n"; local acceptformat = "\t\tAcceptQuestByName(%d)\r\n"; local completeformat = "\t\tCompleteQuestByName(%d)\r\n"; local line_num = 1; local hf_line, tag_open = "", false; for j,z in pairs(wpList[i]) do if (type(z) == "table") then local buildstring = ""; if( z.Type ~=nil )then buildstring = buildstring..harvest end if( z.TargetID~=nil )then buildstring = buildstring..sprintf(targetformat,z.TargetID); end if (z.NewQuestTable~=nil or z.CompleteQuestTable ~=nil)then -- print("Quest were found in the table \n") local qfound = false local m = 1; repeat qfound = false if( z.NewQuestTable~=nil and z.NewQuestTable[m]~=nil )then -- print("New Quest was found in the table \n") buildstring = buildstring..sprintf(acceptformat,z.NewQuestTable[m]); qfound = true; end if( z.CompleteQuestTable~=nil and z.CompleteQuestTable[m]~=nil )then -- print("Quest complete was found in the table \n") buildstring = buildstring..sprintf(completeformat, z.CompleteQuestTable[m]); qfound = true end m = m + 1; until qfound == false end if( z.Type ~=nil )then hf_line = hf_line .. sprintf(openformat,line_num, z.X, z.Z, z.Y, z.Type, string.gsub(z.Name, " ", ""),buildstring ) .. closeformat; else hf_line = hf_line .. sprintf(openformat2,line_num, z.X, z.Z, z.Y, buildstring) .. closeformat; end end line_num = line_num + 1; end file:write(hf_line); file:write(""); file:close(); wpList[i].checked = true; end end print("Clearing nodes..."); wpList = {}; end function loadHPoints(filename, hZone) local root = xml.open(filename); if( not root ) then error(sprintf("Failed to load recorded nodes from \'%s\'", filename), 0); end local elements = root:getElements(); local retPoints = {}; local tmp = {}; for i,v in pairs(elements) do tmp.X,tmp.Z,tmp.Y,tmp.Type,tmp.Name = v:getAttribute("x"), v:getAttribute("z"), v:getAttribute("y"), v:getAttribute("nodetype"), v:getAttribute("node"); local hpExists = false; for j,z in pairs(wpList[hZone]) do if (type(z) == "table") then printf("Checking existing %s node at - X:%d Z:%d Y:%d\n", tmp.Type, tmp.X, tmp.Z, tmp.Y); printf("To recorded %s node at - X:%d Z:%d Y:%d\n", z.Type, z.X, z.Z, z.Y) if ((tmp.X == z.X) and (tmp.Z == z.Z) and (tmp.Y == z.Y)) then printf("Existing %s node at - X:%d Z:%d Y:%d already in list, not adding.\n", z.Type, z.X, z.Z, z.Y) hpExists = true; end end end if not hpExists then printf("Adding %s node at - X:%d Z:%d Y:%d\n", tmp.Type, tmp.X, tmp.Z, tmp.Y); table.insert(wpList[hZone], tmp); end end end