====== Mauspositionsbestimmung im Multiplayer ====== by Kimichura ====== Vorwort ====== Ersteinmal ein dickes Dankeschön an Napoleon (warrior) der mir immer wieder geholfen hat, egal welche sinnlosen Fragen ich im gestellt hab. ;) Und auch Danke an Anarki. :) Bei diesem Skript geht es (wie die Überschrift schon sagt) um die MausPositionsBestimmung im Multiplayer. ====== Code ====== -- MausPositionsBestimmung im MP -- Script Version 2.1 -- by Kimichura function MousePosition_Init() GameCallback_FulfillTribute =function()return 1 end --bereitstellen der leeren tables & variablen MousePosition = {} MousePosition.Payer = 8 -- spieler, bei dem die tribute erstellt werden MousePosition.Player = {} for player = 1,8 do MousePosition.Player[player] = {} MousePosition.Player[player].Tribute = {} MousePosition.Player[player].Tribute.X = {} MousePosition.Player[player].Tribute.Y = {} MousePosition.Player[player].Tribute.Function = {} for i = 1,5 do MousePosition.Player[player].Tribute.X[i] = {} MousePosition.Player[player].Tribute.Y[i] = {} end MousePosition.Player[player].CalcPosition = {} MousePosition.Player[player].CalcPosition.X = 0 MousePosition.Player[player].CalcPosition.Y = 0 MousePosition.Player[player].Position = {} MousePosition.Player[player].Position.X = 0 MousePosition.Player[player].Position.Y = 0 end -- tribut menü für den "payer" unzugänglich machen -- da durch manuelles bezahlen fehler praktisch "vorprogrammiert" sind -- evtl. könnte man das ja noch lokal abfragen.. ich glaub aber net das das so ressi-fressend ist. GUIAction_ToggleMenu_Orig = GUIAction_ToggleMenu; GUIAction_ToggleMenu = function( _what, _flag) if GUI.GetPlayerID() == MousePosition.Payer then if _what == gvGUI_WidgetID.TradeWindow then Message("@color:255,0,0: Zugang verweigert!") Message("Das Tributmen\195\188 wurde unzug\195\164nglich gemacht, da es f\195\188r die Positionsbestimmung gebraucht wird!") return false end end GUIAction_ToggleMenu_Orig(_what,_flag) end -- lokale tables bereitstellen -- diese tables werden nur gebraucht wenn mans auf meine art wie in dem beispiel macht! MousePosition.Local = {} MousePosition.Local.JobId = {} MousePosition.Local.Button = {} --------------------------------------------------------------------------------------- ---------------------------------------------------------- definieren der funktionen function MousePosition:Tribute_Create() --erstellen der tribute 8*10*10 = 800 tribute -- ein paar mehr als geplant...(geplant waren nur 160^^) for _player = 1,8 do local player = _player for i = 0,9 do local index = i MousePosition.Player[player].Tribute.X[1][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,1,0,false)end} MousePosition.Player[player].Tribute.X[2][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,2,0,false)end} MousePosition.Player[player].Tribute.X[3][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,3,0,false)end} MousePosition.Player[player].Tribute.X[4][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,4,0,false)end} MousePosition.Player[player].Tribute.X[5][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,5,0,false)end} MousePosition.Player[player].Tribute.Y[1][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,1,1,true)end} MousePosition.Player[player].Tribute.Y[2][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,2,1,false)end} MousePosition.Player[player].Tribute.Y[3][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,3,1,false)end} MousePosition.Player[player].Tribute.Y[4][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,4,1,false)end} MousePosition.Player[player].Tribute.Y[5][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,5,1,false)end} end end end function MousePosition:Tribute_Recreate(_player) local player = _player for i = 0,9 do local index = i Logic.RemoveTribute(MousePosition.Payer,MousePosition.Player[player].Tribute.X[1][index]) Logic.RemoveTribute(MousePosition.Payer,MousePosition.Player[player].Tribute.X[2][index]) Logic.RemoveTribute(MousePosition.Payer,MousePosition.Player[player].Tribute.X[3][index]) Logic.RemoveTribute(MousePosition.Payer,MousePosition.Player[player].Tribute.X[4][index]) Logic.RemoveTribute(MousePosition.Payer,MousePosition.Player[player].Tribute.X[5][index]) Logic.RemoveTribute(MousePosition.Payer,MousePosition.Player[player].Tribute.Y[1][index]) Logic.RemoveTribute(MousePosition.Payer,MousePosition.Player[player].Tribute.Y[2][index]) Logic.RemoveTribute(MousePosition.Payer,MousePosition.Player[player].Tribute.Y[3][index]) Logic.RemoveTribute(MousePosition.Payer,MousePosition.Player[player].Tribute.Y[4][index]) Logic.RemoveTribute(MousePosition.Payer,MousePosition.Player[player].Tribute.Y[5][index]) MousePosition.Player[player].Tribute.X[1][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,1,0,false)end} MousePosition.Player[player].Tribute.X[2][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,2,0,false)end} MousePosition.Player[player].Tribute.X[3][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,3,0,false)end} MousePosition.Player[player].Tribute.X[4][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,4,0,false)end} MousePosition.Player[player].Tribute.X[5][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,5,0,false)end} MousePosition.Player[player].Tribute.Y[1][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,1,1,true)end} MousePosition.Player[player].Tribute.Y[2][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,2,1,false)end} MousePosition.Player[player].Tribute.Y[3][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,3,1,false)end} MousePosition.Player[player].Tribute.Y[4][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,4,1,false)end} MousePosition.Player[player].Tribute.Y[5][index] = MousePosition:AddTribute{Callback=function()MousePosition:Tribute_Callback(player,index,5,1,false)end} end end function MousePosition:Tribute_Callback(_player,_count,_count2,_flag,_finish) if _flag == 0 then -- X MousePosition.Player[_player].CalcPosition.X = MousePosition.Player[_player].CalcPosition.X + MousePosition:Tribute_Multi(_count,_count2) elseif _flag == 1 then -- Y MousePosition.Player[_player].CalcPosition.Y = MousePosition.Player[_player].CalcPosition.Y + MousePosition:Tribute_Multi(_count,_count2) end if _finish == true then -- ich hatte in einer älteren version es so eingebaut, dass sich der tribut selbst neuerstellt -- jedoch kam es dadurch zu fehlern. es wurden im singleplayer nach ca. 3 maligem ausführen -- einfach tribute nicht bezahlt so das sich "merkwürdige" zahlen ergeben haben -- deshalb lösch ich jetz alle komplett, und setz sie neu auf :) MousePosition:Tribute_Recreate(_player) -- speichern der position MousePosition.Player[_player].Position.X = MousePosition.Player[_player].CalcPosition.X MousePosition.Player[_player].Position.Y = MousePosition.Player[_player].CalcPosition.Y ------------------------- -- zurücksetzen der zum berechnen verwendeten variablen MousePosition.Player[_player].CalcPosition.X = 0 MousePosition.Player[_player].CalcPosition.Y = 0 ------------------------------------------------------- -- und ab damit! MousePosition:Global_Start(_player,MousePosition.Player[_player].Position.X,MousePosition.Player[_player].Position.Y) if MousePosition.Player[_player].CurrFunc ~= nil then _G[MousePosition.Player[_player].CurrFunc](_player,MousePosition.Player[_player].Position.X,MousePosition.Player[_player].Position.Y) MousePosition.Player[_player].CurrFunc = nil end end end function MousePosition:Tribute_Multi(_count,_factor)-- kleine funktion zum berechnen der koordinaten if _factor == 5 then _factor = 10000 elseif _factor == 4 then _factor = 1000 elseif _factor == 3 then _factor = 100 elseif _factor == 2 then _factor = 10 end return _count*_factor end function MousePosition:Local_Start(_funcName) -- aufrufen wenn pos ermittelt werden soll -- diese function wird nur LOKAL ausgeführt -- _funcName ist dabei ein string -- _funcName erhält danach 3 parameter -- also: -- _funcName(player,posX,posY) assert(type(_funcName) == "string", "MousePosition:Local_Start(_funcName)" .. string.char(13) .. "_funcName muss ein string sein!") local player = GUI.GetPlayerID() local x,y = GUI.Debug_GetMapPositionUnderMouse() local tableX = {} local tableY = {} x = math.floor(x+0.5) y = math.floor(y+0.5) -- aufspalten der koordinaten in einzelne zahlen local x5 = math.floor(x/10000) local x4 = math.floor(x/1000) - x5*10 local x3 = math.floor(x/100) - x4*10 - x5*100 local x2 = math.floor(x/10) - x3*10 - x4*100 - x5*1000 local x1 = math.floor(x/1) - x2*10 - x3*100 - x4*1000 - x5*10000 local y5 = math.floor(y/10000) local y4 = math.floor(y/1000) - y5*10 local y3 = math.floor(y/100) - y4*10 - y5*100 local y2 = math.floor(y/10) - y3*10 - y4*100 - y5*1000 local y1 = math.floor(y/1) - y2*10 - y3*100 - y4*1000 - y5*10000 ------------------------------------------------- -- einsetzen in tables, da ich zu doof war es von anfang an richtig zu machen ;) table.insert(tableX,x1) table.insert(tableX,x2) table.insert(tableX,x3) table.insert(tableX,x4) table.insert(tableX,x5) table.insert(tableY,y1) table.insert(tableY,y2) table.insert(tableY,y3) table.insert(tableY,y4) table.insert(tableY,y5) ---------------------------- -- wenn _funcName angegeben ist starten :) if _funcName ~= nil then GUI.PayTribute(MousePosition.Payer,MousePosition.Player[player].Tribute.Function[_funcName]) end for i = 5,1,-1 do GUI.PayTribute(MousePosition.Payer,MousePosition.Player[player].Tribute.X[i][tableX[i]]) GUI.PayTribute(MousePosition.Payer,MousePosition.Player[player].Tribute.Y[i][tableY[i]]) end end function MousePosition:AddTribute(_tribute) -- kleine ergänzung um AddTribute hernehmen zu können, da ich zu faul war -- cost, text und playerId bei jedem tribut einzeln anzugeben ;) _tribute.cost = {Gold=0} _tribute.text = " " _tribute.playerId = MousePosition.Payer return AddTribute(_tribute) end function MousePosition:DefineFunction(_funcName) assert(type(_funcName) == "string","MousePosition:DefineFunction()" .. string.char(13) .. "Wrong Input!" .. string.char(13) .. "_funcName ist kein string!") for wert = 1,8 do local player = wert MousePosition.Player[player].Tribute.Function[_funcName] = MousePosition:AddTribute({Callback=function() MousePosition:Tribute_Function_Callback(player,_funcName) end}) end end function MousePosition:Tribute_Function_Callback(_player,_funcName) MousePosition.Player[_player].CurrFunc = _funcName MousePosition.Player[_player].Tribute.Function[_funcName] = MousePosition:AddTribute({Callback=function() MousePosition:Tribute_Function_Callback(_player,_funcName) end}) end -- createn der Tribute MousePosition:Tribute_Create() ------------------------------ function MousePosition:Global_Start(_player,_posX,_posY) -- "finished" function --- könnte man eig. streichen, da man ja immer eigene funktionen hernimmt^^ end end Das war der Code. Zusätzlich wird jedoch noch die Comfort-Funktion AddTribute benötigt. Die hier http://www.dedk.de/wiki/doku.php?id=comfort:tribute_comforts zu finden ist. ====== Anwendung ====== Zu aller erst muss MousePosition_Init() aufgerufen werden. So. Nun zur Anwendung. Als zweites muss dem Skript eine Callback-Funktion übergeben werden. Das geschieht so: MousePosition:DefineFunction("Callback_Func") Wobei Callback_Func eine freiwählbare Funktion sein kann, jedoch muss sie existieren und sie muss MousePosition:DefineFunction als string also in "" übergeben werden. (Man kann beliebig viele übergeben.) So das wars. Jetzt kann das Skript richtig verwendet werden. Um die Positionsbestimmung zu Starten muss MousePosition:Local_Start("Callback_Func") aufgerufen werden.(Dies geschieht am besten durch einen GUI-Fähigkeiten-Hack wie im Beispiel zu sehen ist.) Wird das getan, so wird die Callback_Func mit 3 Parametern aufgerufen (Player,X-Koordinate,Y-Koordinate). Also zum Beispiel so: Callback_Func(1,24758,28573) ====== Beispiel ====== So das wars schon wieder hier folgt noch ein Beispiel: Darin werden Helias1 bis Helias8 (wenn sie vorhanden sind) teleportiert. Wenn man auf Segnen und dann "in die Map" klickt. function Beispiel() MousePosition:DefineFunction("GUI_Action_Hero6Bless_Callback") MousePosition.Local.Button["GUIAction_Hero6Bless"] = 0 -- fähigkeit ist einsatzbereit Teleportierender_Helias() -- evtl. sollte man einen cooldown einbauen, jedoch war ich einfach zu faul -- genauso wie mit den "fähigkeiten-beschreibungen" end function Teleportierender_Helias() GUIAction_Hero6Bless_Orig = GUIAction_Hero6Bless GUIAction_Hero6Bless = function() if MousePosition.Local.Button["GUIAction_Hero6Bless"] == 0 then -- fähigkeit nicht aktiviert GUI.ActivateSendHawkCommandState() -- aktivieren MousePosition.Local.JobId["GUIAction_Hero6Bless"] = StartSimpleHiResJob("GUI_Action_Hero6Bless_Job") MousePosition.Local.Button["GUIAction_Hero6Bless"] = 1 else -- es ist bereits aktiviert -- abbrechen! EndJob(MousePosition.Local.JobId["GUIAction_Hero6Bless"]) -- job beenden MousePosition.Local.Button["GUIAction_Hero6Bless"] = 0 GUI.CancelState() end end end function GUI_Action_Hero6Bless_Job() -- job zum überprüfen ob der spieler die fähigkeit auch ausführt if GUI.GetCurrentStateName() ~= "SendHawkCommand" then MousePosition:Local_Start("GUI_Action_Hero6Bless_Callback") -- bestimmung der pos und aufrufen des callbacks return true end end function GUI_Action_Hero6Bless_Callback(_player,_posX,_posY) -- GLOBAL -- health berechnen, da helias ja sonst auch wenn er stark angeschlagen wäre immer 600 hp hätte :) local health = Logic.GetEntityHealth(Logic.GetEntityIDByName("Helias".._player)) local maxhealth = Logic.GetEntityMaxHealth(Logic.GetEntityIDByName("Helias".._player)) local healthtohurt = math.abs(maxhealth-health) ------------------- local _realPlayer = GUI.GetPlayerID() -- spieler id speichern (ist bei jedem anders :)) DestroyEntity("Helias".._player) -- helias zerstören... SetEntityName(Logic.CreateEntity(Entities.PU_Hero6,_posX,_posY,0,_player),"Helias".._player) -- wiedererstellen Logic.HurtEntity(Logic.GetEntityIDByName("Helias".._player),healthtohurt) -- helias verletzen if _player == _realPlayer then -- hier gehts nur für den spieler weiter, der helias teleportiert hat! GUI.SetSelectedEntity(Logic.GetEntityIDByName("Helias".._player)) -- helias selektieren MousePosition.Local.Button["GUIAction_Hero6Bless"] = 0 end end ====== Schlusswort ====== Ich hoffe irgendjemand kann damit was anfangen, auch wenn meine Erklärungen mehr als schlecht sind. Falls noch Fragen offen stehen nicht zögern mir (Kimichura) eine PN zu schreiben. :)