Inhaltsverzeichnis
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. :)