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