AddChatMessage("{0088cc}[Schaden-Meldung]: {FFFFFF}Du hast " zwischensumme " Schaden erhalten. Von " getPlayerNameById(attacker) )
Beiträge von Madd92
-
-
Na getPlayerNameById
-
Dann ist die Funktion, die du nutzt ne andere, als die die ich gepostet habe. Damit bekommst du die ID des letzten Spielers, der dir Schaden zugefügt hat. Du nutzt aber die Variable attacker auch nicht weiter. Du könntest einfach getPlayerNameById nutzen und bei der ChatMessage mitreinschreiben. Achso, kann sein, dass writeMem eher writeMemory sein muss bei dir.
-
Du hast doch getAttacker schon drin
PHP
Alles anzeigengetAttacker(bReset := false) { if (!checkHandles() || !updateOScoreboardData()) return -1 dwLocalPED := readDWORD(hGTA, ADDR_CPED_PTR) dwAttacker := readDWORD(hGTA, dwLocalPED + 0x764) if (!dwAttacker) return -1 for i, o in oScoreboardData { if (!o.PED || o.ISNPC || dwAttacker != o.PED) continue if (bReset) writeMem(hGTA, dwLocalPED + 0x764, 0, "UInt", 4) return o.ID } return -1 }
-
GetChatLine ist ja eine API Funktion. Du kannst aber auch einfach die Chatlog.txt auslesen, also das was die Funktion zumindest in der UDF auch macht. Allgemein würde ich aber die SAMP-UDF empfehlen und dass du dir erstmal die Grundlagen von AHK aneignest, wenn du das noch nicht getan hast
-
Was für eine API nutzt du denn? Sind IsPlayerInCar, IsPlayerInBoat etc. Variablen oder Funktionen? Ein Funktionsaufruf würde so aussehen: IsPlayerInCar().
Wenn du den Code in einem Timer ausführst, dann solltest du speichern, in was für einem Fahrzeug sich der Spieler befindet und dann abfragen, ob sich der Fahrzeugtyp geändert hat und nur dann den fpslimit Befehl absenden. -
Test Line Of Sight.
-
Das ist jetzt aus meiner persönlichen Funktionssammlung rauskopiert, aber wenn man das alles in die UDF einfügt, sollte es auch klappen:
PHP
Alles anzeigen; In den Deklarationsbereich: global SAMP_INFO_PTR := 0x21A0F8 global SAMP_MAX_TEXTLABELS := 1024 global SAMP_POOLS := 0x3CD global SAMP_POOL_TEXTLABEL := 0xC ; TextLabel-Funktionen updateTextLabel(textLabelID, text) { return textLabelID < 0 || textLabelID > 2047 || !checkHandles() ? false : __WRITESTRING(hGTA, dwSAMP, [SAMP_INFO_PTR, SAMP_POOLS, SAMP_POOL_TEXTLABEL, textLabelID * 0x1D, 0x0], text) } createTextLabel(text, color, xPos, yPos, zPos, drawDistance := 50.0, testLOS := 0, playerID := 0xFFFF, vehicleID := 0xFFFF) { if (!checkHandles()) return -1 dwAddress := __DWORD(hGTA, dwSAMP, [SAMP_INFO_PTR, SAMP_POOLS, SAMP_POOL_TEXTLABEL]) if (!dwAddress) return -1 Loop, 2048 { textLabelID := A_Index - 1 if (!__DWORD(hGTA, dwAddress, [0xE800 + textLabelID * 4])) { return __CALL(hGTA, dwSAMP + 0x11C0, [["i", dwAddress], ["i", textLabelID], ["s", text], ["i", color], ["f", xPos], ["f", yPos], ["f", zPos] , ["f", drawDistance], ["i", testLOS], ["i", playerID], ["i", vehicleID]], false, true) ? textLabelID : -1 } } return -1 } deleteTextLabel(ByRef textLabelID) { if (textLabelID < 0 || !checkHandles()) return false if (__CALL(hGTA, dwSAMP + 0x12D0, [["i", __DWORD(hGTA, dwSAMP, [SAMP_INFO_PTR, SAMP_POOLS, SAMP_POOL_TEXTLABEL])], ["i", textLabelID]], false, true)) { textLabelID := -1 return true } return false } ; Memory-Funktionen __DWORD(hProcess, dwAddress, offsets) { if (!hProcess || !dwAddress) return "" VarSetCapacity(dwRead, 4) for i, o in offsets { dwRet := DllCall("ReadProcessMemory", "UInt", hProcess, "UInt", dwAddress + o, "Str", dwRead, "UInt", 4, "UInt*", 0) if (!dwRet) return "" dwAddress := NumGet(dwRead, 0, "UInt") } return dwAddress } __READMEM(hProcess, dwAddress, oOffsets, sDatatype = "Int") { if (!hProcess || !dwAddress) return "" VarSetCapacity(dwRead, 4) for i, o in oOffsets { dwRet := DllCall("ReadProcessMemory", "UInt", hProcess, "UInt", dwAddress + o, "Str", dwRead, "UInt", 4, "UInt*", 0) if (!dwRet) return "" if (i == oOffsets.MaxIndex()) return NumGet(dwRead, 0, sDatatype) dwAddress := NumGet(dwRead, 0, "UInt") } } __WRITESTRING(hProcess, dwAddress, oOffsets, wString) { if (!hProcess || !dwAddress) return false if A_IsUnicode wString := __unicodeToAnsi(wString) requiredSize := StrPut(wString) VarSetCapacity(buffer, requiredSize) for i, o in oOffsets { if (i == oOffsets.MaxIndex()) { StrPut(wString, &buffer, StrLen(wString) + 1) return DllCall("WriteProcessMemory", "UInt", hProcess, "UInt", dwAddress + o, "Str", buffer, "UInt", requiredSize, "UInt", 0, "UInt") } dwRet := DllCall("ReadProcessMemory", "UInt", hProcess, "UInt", dwAddress + o, "Str", buffer, "UInt", 4, "UInt*", 0) if (!dwRet) return false dwAddress := NumGet(buffer, 0, "UInt") } } __WRITEMEM(hProcess, dwAddress, oOffsets, value, sDatatype = "Int") { dwLen := datatypes[sDatatype] if (dwLen < 1 || !hProcess || !dwAddress) return false VarSetCapacity(dwRead, 4) for i, o in oOffsets { if (i == oOffsets.MaxIndex()) { NumPut(value, dwRead, 0, sDatatype) return DllCall("WriteProcessMemory", "UInt", hProcess, "UInt", dwAddress + o, "UInt", &dwRead, "UInt", dwLen, "UInt", 0) } dwRet := DllCall("ReadProcessMemory", "UInt", hProcess, "UInt", dwAddress + o, "Str", dwRead, "UInt", 4, "UInt*", 0) if (!dwRet) return false dwAddress := NumGet(dwRead, 0, "UInt") } } __WRITERAW(hProcess, dwAddress, pBuffer, dwLen) { return (!hProcess || !dwAddress || !pBuffer || dwLen < 1) ? false : DllCall("WriteProcessMemory", "UInt", hProcess, "UInt", dwAddress, "UInt", pBuffer, "UInt", dwLen, "UInt", 0, "UInt") } __CALL(hProcess, dwFunc, aParams, bCleanupStack = true, bThisCall = false, bReturn = false, sDatatype = "Char") { if (!hProcess || !dwFunc) return "" dataOffset := 0 i := aParams.MaxIndex() bytesUsed := 0 bytesMax := 5120 dwLen := i * 5 + bCleanupStack * 3 + bReturn * 5 + 6 VarSetCapacity(injectData, dwLen, 0) while (i > 0) { if (aParams[i][1] == "i" || aParams[i][1] == "p" || aParams[i][1] == "f") value := aParams[i][2] else if (aParams[i][1] == "s") { if (bytesMax - bytesUsed < StrLen(aParams[i][2])) return "" value := pMemory + bytesUsed __WRITESTRING(hProcess, value, [0x0], aParams[i][2]) bytesUsed += StrLen(aParams[i][2]) + 1 if (ErrorLevel) return "" } else return "" NumPut((bThisCall && i == 1 ? 0xB9 : 0x68), injectData, dataOffset, "UChar") NumPut(value, injectData, ++dataOffset, aParams[i][1] == "f" ? "Float" : "Int") dataOffset += 4 i-- } offset := dwFunc - (pInjectFunc + dataOffset + 5) NumPut(0xE8, injectData, dataOffset, "UChar") NumPut(offset, injectData, ++dataOffset, "Int") dataOffset += 4 if (bReturn) { NumPut(sDatatype = "Char" ? 0xA2 : 0xA3, injectData, dataOffset, "UChar") NumPut(pMemory, injectData, ++dataOffset, "UInt") dataOffset += 4 } if (bCleanupStack) { NumPut(0xC483, injectData, dataOffset, "UShort") dataOffset += 2 NumPut((aParams.MaxIndex() - bThisCall) * 4, injectData, dataOffset, "UChar") dataOffset++ } NumPut(0xC3, injectData, dataOffset, "UChar") __WRITERAW(hGTA, pInjectFunc, &injectData, dwLen) if (ErrorLevel) return "" hThread := createRemoteThread(hGTA, 0, 0, pInjectFunc, 0, 0, 0) if (ErrorLevel) return "" waitForSingleObject(hThread, 0xFFFFFFFF) closeProcess(hThread) if (bReturn) return __READMEM(hGTA, pMemory, [0x0], sDatatype) return true }
Beispiel: -
Du könntest ein ActiveX Control benutzen: https://autohotkey.com/boards/viewtopic.php?t=4588
-
Doch man kann TextLabels an Spieler und Fahrzeuge attachen.
-
-
-
Am besten erstmal die Suchfunktion verwenden
AHK | Anti-Commandspam
Der letzte Beitrag ist ein Beispielscript, wie man es machen könnte. -
AddChatMessage("[Gegnerliste] " o.NAME " (" playerID ") hat sich {00FF00}eingeloggt") kommt dann, kannste natürlich alles verändern
-
Als Grundgerüst könntest du folgendes verwenden:
PHP
Alles anzeigenglobal gegnerListe := [] global gegnerOfflineMsg := true global gegnerOnlineMsg := true SetTimer, GegnerTimer, 1000 return GegnerTimer: if (!WinExist("GTA:SA:MP") || getGameState() != 14) { gegnerListe := [] return } if (gegnerListe.Length() <= 0) { if (!FileExist("gegner.txt")) return Loop, Read, gegner.txt gegnerListe.Push(Object("NAME", A_LoopReadLine, "ID", getPlayerIdByName(A_LoopReadLine))) } if (!WinActive("GTA:SA:MP")) return for i, o in gegnerListe { playerID := getPlayerIdByName(o.NAME) if (playerID != o.ID) { o.ID := playerID if (gegnerOfflineMsg && playerID == -1) AddChatMessage("[Gegnerliste] " o.NAME " hat sich {FF0000}ausgeloggt") else if (gegnerOnlineMsg && playerID != -1) AddChatMessage("[Gegnerliste] " o.NAME " (" playerID ") hat sich {00FF00}eingeloggt") } } return #If WinActive("GTA:SA:MP") && !isInChat() && !isInMenu() !1:: string := "" for i, o in gegnerListe { playerID := getPlayerIdByName(o.NAME) if (playerID == -1) { playerID := 9999 color := "{222222}" } else color := "{FFFFFF}" string .= color playerID "`t" color o.NAME "`t" color (playerid != 9999 ? "{00FF00}Online" : "{222222}Offline") "`n" } Sort string, N P9 string := StrReplace(string, "9999", "-") string := "ID`tName`tStatus`n" . string showDialog(DIALOG_STYLE_TABLIST_HEADERS, "Gengerliste", string, "Close") return getGameState() { return !checkHandles() ? false : readDWORD(hGTA, readDWORD(hGTA, dwSAMP + SAMP_INFO_OFFSET) + 0x3BD) }
Das kann man natürlich noch verbessern, ausbauen und Funktionen hinzufügen.
-
Werden auf dem Server die Gangs in Farben angezeigt bzw. gibt es serverseitig eine Gang-Member Liste, die du einsehen kannst?
Wenn nicht, dann kannst du auch einfach selber die Namen in eine TXT eintragen, vom Keybinder auslesen lassen und in einem Timer überprüfen, ob der Spieler online oder offline ist und das Ergebnis in einem Array speichern und bei einer Statusänderung einfach eine Nachricht dazu ausgeben. -
Ich würde ja mal im LyD Forum fragen, oder den Ersteller anschreiben, falls du das noch nicht gemacht hast
Ansonsten kannst du ja auch im LyD Forum fragen, ob jemand dir einen ähnlichen Keybinder erstellt -
Ich hab keine Ahnung von Spotify, aber nutzt du das in einer App oder im Browser?
Also wenn du die App nutzt, könntest du es mit der UDF so machen:PHP
Alles anzeigen#SingleInstance, Force #Persistent #Include SAMP.ahk SetTitleMatchMode, 2 DetectHiddenWindows, On SetTimer, SpotifySong, 1000 global oldSong := "" return SpotifySong: if (!WinActive("GTA:SA:MP")) return WinGetTitle, winTitle, ahk_class SpotifyMainWindow if (winTitle != oldSong && winTitle != "Spotify") { AddChatMessage("{32CD32}[SPOTIFY] {FFFFFF}Es wird nun {B0E0E6}" winTitle " {FFFFFF}gespielt.") oldSong := winTitle } return
-
if (antwort.equals("Ja")) statt if (antwort = "Ja") oder if (antwort == "Ja").
Compare Strings in Java -
antwort.equals("Ja")
bzw.
antwort.equalsIgnoreCase("Ja")