13 Commits

Author SHA1 Message Date
Eduardo Bart
8f0ad27735 Minor SDL improvements 2013-03-11 14:43:42 -03:00
Eduardo Bart
d60413f7d6 Progress in SDL platform 2013-03-08 15:36:32 -03:00
Eduardo Bart
e6ee88af43 Changes to compile on android 2013-03-08 15:35:40 -03:00
Henrique Santiago
b3b849000d Add texture abstract class 2013-03-08 15:35:40 -03:00
Henrique
ab9351196c EGL and WGL working 2013-03-08 15:32:21 -03:00
Henrique Santiago
96bbe20588 EGL and GLX working 2013-03-08 15:32:21 -03:00
Henrique Santiago
77995a2e88 Compiling on linux again 2013-03-08 15:32:20 -03:00
Eduardo Bart
adf51f1852 Use SDL 2.0 2013-03-08 15:32:20 -03:00
Henrique
45eda6c573 Now drawing on windows again 2013-03-08 15:32:20 -03:00
Henrique Santiago
c3c951ebbb More changes to context 2013-03-08 15:32:20 -03:00
Henrique
a989ceb10c Add graphics context 2013-03-08 15:32:20 -03:00
Eduardo Bart
fb8552d142 Very basic rendering with SDL1.2 + OGL 2013-03-08 15:32:20 -03:00
Eduardo Bart
65b32d283b Add first SDL files 2013-03-08 15:32:20 -03:00
171 changed files with 3184 additions and 5726 deletions

71
.gitignore vendored
View File

@@ -1,3 +1,4 @@
/modules/.project
build* build*
CMakeCache.txt CMakeCache.txt
CMakeFiles CMakeFiles
@@ -38,73 +39,3 @@ tags
Thumbs.db Thumbs.db
.directory .directory
src/framework/graphics/dx/ src/framework/graphics/dx/
modules/.project/modules.sublime-workspace
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper

View File

@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.6)
project(otclient) project(otclient)
set(VERSION "0.6.4") set(VERSION "0.6.2")
option(FRAMEWORK_SOUND "Use SOUND " ON) option(FRAMEWORK_SOUND "Use SOUND " ON)
option(FRAMEWORK_GRAPHICS "Use GRAPHICS " ON) option(FRAMEWORK_GRAPHICS "Use GRAPHICS " ON)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 283 B

View File

@@ -1,31 +1,36 @@
-- by Don Daniello
-- 09 June 2012
-- http://DonDaniello.com
-- http://otland.net/members/Don+Daniello
locale = { locale = {
name = "pl", name = "pl",
languageName = "Polski", languageName = "Polski",
translation = { translation = {
["1a) Offensive Name"] = "1a) Obrazliwe Imie", ["1a) Offensive Name"] = false,
["1b) Invalid Name Format"] = "1b) Niepoprawny Format Imienia", ["1b) Invalid Name Format"] = false,
["1c) Unsuitable Name"] = "1c) Nieodpowiednie Imie", ["1c) Unsuitable Name"] = false,
["1d) Name Inciting Rule Violation"] = "1d) Imie Nawolujace Do Lamania Regulaminu", ["1d) Name Inciting Rule Violation"] = false,
["2a) Offensive Statement"] = "2a) Obrazliwa wypowiedz", ["2a) Offensive Statement"] = false,
["2b) Spamming"] = "2b) Spamowanie", ["2b) Spamming"] = false,
["2c) Illegal Advertising"] = "2c) Nielegalne Reklamy", ["2c) Illegal Advertising"] = false,
["2d) Off-Topic Public Statement"] = "2d) Publiczne Wypowiadanie Sie Nie Na Temat", ["2d) Off-Topic Public Statement"] = false,
["2e) Non-English Public Statement"] = "2e) Publiczne wypowiadanie Sie W Jezyku Innym Niz Angielski", ["2e) Non-English Public Statement"] = false,
["2f) Inciting Rule Violation"] = "2f) Nawolywanie Do Lamania Regulaminu ", ["2f) Inciting Rule Violation"] = false,
["3a) Bug Abuse"] = "3a) Wykorzystywanie Bledow", ["3a) Bug Abuse"] = false,
["3b) Game Weakness Abuse"] = "3b) Wykorzystanie Slabosci Gry", ["3b) Game Weakness Abuse"] = false,
["3c) Using Unofficial Software to Play"] = "3c) Gra Przy Uzyciu Nieoficjalnego Oprogramowania", ["3c) Using Unofficial Software to Play"] = false,
["3d) Hacking"] = "3d) Wlamywanie Sie", ["3d) Hacking"] = false,
["3e) Multi-Clienting"] = "3e) Uzycie Multi-Klienta", ["3e) Multi-Clienting"] = false,
["3f) Account Trading or Sharing"] = "3f) Handel Lub Udostepnianie Kont", ["3f) Account Trading or Sharing"] = false,
["4a) Threatening Gamemaster"] = "4a) Grozby Pod Adresem Mistrza Gry", ["4a) Threatening Gamemaster"] = false,
["4b) Pretending to Have Influence on Rule Enforcement"] = "4b) Udawanie Wplywu na Ustanawianie Regul Gry", ["4b) Pretending to Have Influence on Rule Enforcement"] = false,
["4c) False Report to Gamemaster"] = "4c) Wyslanie Falszywego Raportu Mistrzowi Gry", ["4c) False Report to Gamemaster"] = false,
["Accept"] = "Akceptuj", ["Accept"] = false,
["Account name"] = "Numer konta", ["Account name"] = "Numer konta",
["Account Status:"] = "Status Konta:", ["Account Status:"] = false,
["Action:"] = "Akcja:", ["Action:"] = false,
["Add"] = "Dodaj", ["Add"] = "Dodaj",
["Add new VIP"] = "Nowy VIP", ["Add new VIP"] = "Nowy VIP",
["Addon 1"] = "Addon 1", ["Addon 1"] = "Addon 1",
@@ -34,15 +39,15 @@ locale = {
["Add to VIP list"] = "Dodaj do VIPow", ["Add to VIP list"] = "Dodaj do VIPow",
["Adjust volume"] = "Zmien glosnosc", ["Adjust volume"] = "Zmien glosnosc",
["Alas! Brave adventurer, you have met a sad fate.\nBut do not despair, for the gods will bring you back\ninto this world in exchange for a small sacrifice\n\nSimply click on Ok to resume your journeys!"] = false, ["Alas! Brave adventurer, you have met a sad fate.\nBut do not despair, for the gods will bring you back\ninto this world in exchange for a small sacrifice\n\nSimply click on Ok to resume your journeys!"] = false,
["All"] = "Wszystkie", ["All"] = false,
["All modules and scripts were reloaded."] = "Wszystkie moduly ", ["All modules and scripts were reloaded."] = "Wszystkie moduly ",
["Allow auto chase override"] = false, ["Allow auto chase override"] = false,
["Also known as dash in tibia community, recommended\nfor playing characters with high speed"] = false, ["Also known as dash in tibia community, recommended\nfor playing characters with high speed"] = false,
["Ambient light: %s%%"] = "Swiatlo tla: %s%%", ["Ambient light: %s%%"] = false,
["Amount:"] = "Ilosc:", ["Amount:"] = "Ilosc:",
["Amount"] = "Ilosc", ["Amount"] = false,
["Anonymous"] = "Anonimowy", ["Anonymous"] = false,
["Are you sure you want to logout?"] = "Czy jestes pewien, ze sie chcesz wylogowac?", ["Are you sure you want to logout?"] = false,
["Attack"] = "Atak", ["Attack"] = "Atak",
["Author"] = "Autor", ["Author"] = "Autor",
["Autoload"] = "Autoladowanie", ["Autoload"] = "Autoladowanie",
@@ -54,17 +59,17 @@ locale = {
["Banishment"] = false, ["Banishment"] = false,
["Banishment + Final Warning"] = false, ["Banishment + Final Warning"] = false,
["Battle"] = "Bitwa", ["Battle"] = "Bitwa",
["Browse"] = "Przegladaj", ["Browse"] = false,
["Bug report sent."] = "Raport o bledzie zostal wyslany.", ["Bug report sent."] = false,
["Button Assign"] = "Przypisanie Klawisza", ["Button Assign"] = "Przypisanie Klawisza",
["Buy"] = "Kup", ["Buy"] = "Kup",
["Buy Now"] = "Kup Teraz", ["Buy Now"] = false,
["Buy Offers"] = "Oferty Kupna", ["Buy Offers"] = false,
["Buy with backpack"] = "Kupuj z plecakami", ["Buy with backpack"] = "Kupuj z plecakami",
["Cancel"] = "Anuluj", ["Cancel"] = "Anuluj",
["Cannot login while already in game."] = "Nie mozna zalogowac gdy juz w grze", ["Cannot login while already in game."] = false,
["Cap"] = false, ["Cap"] = false,
["Capacity"] = "Ladownosc", ["Capacity"] = "Capacidad",
["Center"] = false, ["Center"] = false,
["Channels"] = "Kanaly", ["Channels"] = "Kanaly",
["Character List"] = "Lista postaci", ["Character List"] = "Lista postaci",
@@ -77,64 +82,65 @@ locale = {
["Close this channel"] = "Zamknij kanal", ["Close this channel"] = "Zamknij kanal",
["Club Fighting"] = "Walka obuchem", ["Club Fighting"] = "Walka obuchem",
["Combat Controls"] = "Kontrola walki", ["Combat Controls"] = "Kontrola walki",
["Comment:"] = "Komentarz:", ["Comment:"] = false,
["Connecting to game server..."] = "Laczenie z serwerem gry...", ["Connecting to game server..."] = "Laczenie z serwerem gry...",
["Connecting to login server..."] = "Laczenie z serwerem logowania...", ["Connecting to login server..."] = "Laczenie z serwerem logowania...",
["Console"] = "Konsola", ["Console"] = false,
["Cooldowns"] = false, ["Cooldowns"] = false,
["Copy message"] = "Kopiuj wiadomosc", ["Copy message"] = false,
["Copy name"] = "Kopiuj imie", ["Copy name"] = false,
["Copy Name"] = "Kopiuj Imie", ["Copy Name"] = "Kopiuj Nick",
["Create Map Mark"] = "Utworz Znacznik na Mapie", ["Create Map Mark"] = false,
["Create mark"] = "Utworz znacznik", ["Create mark"] = false,
["Create New Offer"] = "Utworz Nowa Oferte", ["Create New Offer"] = false,
["Create Offer"] = "Utworz Oferte", ["Create Offer"] = false,
["Current hotkeys:"] = "Aktualny hotkey:", ["Current hotkeys:"] = "Aktualny hotkey:",
["Current hotkey to add: %s"] = "Aktualny hotkey do dodania: %s", ["Current hotkey to add: %s"] = "Aktualny hotkey do dodania: %s",
["Current Offers"] = "Obecne Oferty", ["Current Offers"] = false,
["Default"] = "Domyslny", ["Default"] = "Domyslny",
["Delete mark"] = "Usun znacznik", ["Delete mark"] = false,
["Description:"] = "Opis:", ["Description:"] = false,
["Description"] = "Opis", ["Description"] = "Opis",
["Destructive Behaviour"] = "Destrukcyjne Zachowanie", ["Destructive Behaviour"] = false,
["Detail"] = "Szczegoly", ["Detail"] = "Szczegoly",
["Details"] = "Szczegoly", ["Details"] = false,
["Disable Shared Experience"] = "Wylacz Dzielenie Doswiadczenia", ["Disable Shared Experience"] = "Wylacz Dzielenie Doswiadczenia",
["Dismount"] = false, ["Dismount"] = false,
["Display connection speed to the server (milliseconds)"] = "Wyswietl ping do serwera (ms)", ["Display connection speed to the server (milliseconds)"] = false,
["Distance Fighting"] = "Walka na odleglosc", ["Distance Fighting"] = "Walka na odleglosc",
["Don't stretch/shrink Game Window"] = "Nie rozszerzaj/zwezaj Okna Gry", ["Don't stretch/shrink Game Window"] = false,
["Edit hotkey text:"] = "Edytuj tresc hotkeya:", ["Edit hotkey text:"] = "Edytuj tresc hotkeya:",
["Edit List"] = "Lista Edycji", ["Edit List"] = false,
["Edit Text"] = "Edytuj tekst", ["Edit Text"] = "Edytuj tekst",
["Enable music"] = "Odtwarzaj muzyke", ["Enable music"] = false,
["Enable Shared Experience"] = "Wlacz dzielenie doswiadczenia", ["Enable Shared Experience"] = "Wlacz dzielenie doswiadczenia",
["Enable smart walking"] = false, ["Enable smart walking"] = false,
["Enable vertical synchronization"] = "Wlacz synchronizacje pionowa", ["Enable vertical synchronization"] = "Wlacz synchronizacje pionowa",
["Enable walk booster"] = false, ["Enable walk booster"] = false,
["Enter Game"] = "Wejdz do gry", ["Enter Game"] = "Wejdz do gry",
["Enter one name per line."] = "Wprowadz jedno imie na linie", ["Enter one name per line."] = false,
["Enter with your account again to update your client."] = "Zaloguj sie ponownie by zaktualizowac klienta", ["Enter with your account again to update your client."] = false,
["Error"] = "Blad", ["Error"] = "Blad",
["Excessive Unjustified Player Killing"] = "Nadmierne Nieusprawiedliwione Zabijanie Graczy", ["Error"] = "Blad",
["Excessive Unjustified Player Killing"] = false,
["Exclude from private chat"] = "Wyrzuc w prywatnej konwersacji", ["Exclude from private chat"] = "Wyrzuc w prywatnej konwersacji",
["Exit"] = false, ["Exit"] = false,
["Experience"] = "Doswiadczenie", ["Experience"] = "Doswiadczenie",
["Filter list to match your level"] = "Wyswietl tylko odpowiednie dla mojego poziomu", ["Filter list to match your level"] = false,
["Filter list to match your vocation"] = "Wyswietl tylko odpowiednie dla mojej klasy", ["Filter list to match your vocation"] = false,
["Find:"] = "Szukaj:", ["Find:"] = false,
["Fishing"] = "Wedkarstwo", ["Fishing"] = "Wedkarstwo",
["Fist Fighting"] = "Walka wrecz", ["Fist Fighting"] = "Walka wrecz",
["Follow"] = "Podazaj", ["Follow"] = "Podazaj",
["Force Exit"] = "Wymus Zamkniecie", ["Force Exit"] = false,
["For Your Information"] = false, ["For Your Information"] = false,
["Free Account"] = "Darmowe Konto", ["Free Account"] = false,
["Fullscreen"] = "Pelen ekran", ["Fullscreen"] = "Pelen ekran",
["Game"] = "Gra", ["Game"] = false,
["Game framerate limit: %s"] = "Limit FPS: %s", ["Game framerate limit: %s"] = false,
["Graphics"] = "Grafika", ["Graphics"] = "Grafika",
["Graphics card driver not detected"] = "Nie wykryto karty graficznej", ["Graphics card driver not detected"] = false,
["Graphics Engine:"] = "Silnik graficzny:", ["Graphics Engine:"] = false,
["Head"] = "Glowa", ["Head"] = "Glowa",
["Healing"] = false, ["Healing"] = false,
["Health Info"] = false, ["Health Info"] = false,
@@ -142,43 +148,43 @@ locale = {
["Hide monsters"] = "Ukryj potwory", ["Hide monsters"] = "Ukryj potwory",
["Hide non-skull players"] = "Ukryj graczy bez skulla", ["Hide non-skull players"] = "Ukryj graczy bez skulla",
["Hide Npcs"] = "Ukryj NPCe", ["Hide Npcs"] = "Ukryj NPCe",
["Hide Offline"] = "Ukryj Niedostepnych", ["Hide Offline"] = false,
["Hide party members"] = "Ukryj czlonkow druzyny", ["Hide party members"] = "Ukryj czlonkow zabawy",
["Hide players"] = "Ukryj graczy", ["Hide players"] = "Ukryj graczy",
["Hide spells for higher exp. levels"] = "Ukryj zaklecia wyzszych poziomow postaci", ["Hide spells for higher exp. levels"] = false,
["Hide spells for other vocations"] = "Ukryj zaklecia innych klas", ["Hide spells for other vocations"] = false,
["Hit Points"] = "Punkty uderzen", ["Hit Points"] = "Punkty uderzen",
["Hold left mouse button to navigate\nScroll mouse middle button to zoom\nRight mouse button to create map marks"] = false, ["Hold left mouse button to navigate\nScroll mouse middle button to zoom\nRight mouse button to create map marks"] = false,
["Hotkeys"] = "Hotkeye", ["Hotkeys"] = "Hotkeye",
["If you shut down the program, your character might stay in the game.\nClick on 'Logout' to ensure that you character leaves the game properly.\nClick on 'Exit' if you want to exit the program without logging out your character."] = false, ["If you shut down the program, your character might stay in the game.\nClick on 'Logout' to ensure that you character leaves the game properly.\nClick on 'Exit' if you want to exit the program without logging out your character."] = false,
["Ignore"] = "Ignoruj", ["Ignore"] = false,
["Ignore capacity"] = "Ignoruj pojemnosc", ["Ignore capacity"] = "Ignoruj pojemnosc",
["Ignored players:"] = "Ignorowani gracze:", ["Ignored players:"] = false,
["Ignore equipped"] = "Ignoruj ekwipunek", ["Ignore equipped"] = "Ignoruj ekwipunek",
["Ignore List"] = "Lista Ignorowanych", ["Ignore List"] = false,
["Ignore players"] = "Ignoruj graczy", ["Ignore players"] = false,
["Ignore Private Messages"] = "Ignoruj Prywatne Wiadomosci", ["Ignore Private Messages"] = false,
["Ignore Yelling"] = "Ignoruj Krzyki", ["Ignore Yelling"] = false,
["Interface framerate limit: %s"] = "Limit FPS interfejsu: %s", ["Interface framerate limit: %s"] = false,
["Inventory"] = "Ekwipunek", ["Inventory"] = "Inwentarz",
["Invite to Party"] = "Zapros do druzyny", ["Invite to Party"] = "Zapros do zabawy",
["Invite to private chat"] = "Zapros do prywatnej konwersacji", ["Invite to private chat"] = "Zapros do prywatnej konwersacji",
["IP Address Banishment"] = "Blokada adresu IP", ["IP Address Banishment"] = false,
["Item Offers"] = "Oferty Przedmiotow", ["Item Offers"] = false,
["It is empty."] = "To jest puste.", ["It is empty."] = false,
["Join %s's Party"] = "Dolacz do druzyny gracza %s", ["Join %s's Party"] = false,
["Leave Party"] = "Opusc druzyne", ["Leave Party"] = "Opusc zabawe",
["Level"] = "Poziom", ["Level"] = "Poziom",
["Lifetime Premium Account"] = "Konto Premium na Stale", ["Lifetime Premium Account"] = false,
["Limits FPS to 60"] = "Ogranicz FPS do 60", ["Limits FPS to 60"] = "Ogranicz FPS do 60",
["List of items that you're able to buy"] = "Lista przedmiotow, ktore mozesz kupic", ["List of items that you're able to buy"] = "Lista przedmiotow, ktore mozesz kupic",
["List of items that you're able to sell"] = "Lista przedmiotow, ktore mozesz sprzedac", ["List of items that you're able to sell"] = "Lista przedmiotow, ktore mozesz sprzedac",
["Load"] = "Wczytaj", ["Load"] = "Wczytaj",
["Logging out..."] = "Wylogowuje...", ["Logging out..."] = false,
["Login"] = "Zaloguj", ["Login"] = "Zaloguj",
["Login Error"] = "Blad Logowania", ["Login Error"] = "Blad Logowania",
["Login Error"] = "Blad Logowania", ["Login Error"] = "Blad Logowania",
["Logout"] = "Wyloguj", ["Logout"] = false,
["Look"] = "Spojrz", ["Look"] = "Spojrz",
["Magic Level"] = "Poziom Magiczny", ["Magic Level"] = "Poziom Magiczny",
["Make sure that your client uses\nthe correct game protocol version"] = "Upewnij sie, ze twoj klient\nuzywa wlasciwego protokolu gry.", ["Make sure that your client uses\nthe correct game protocol version"] = "Upewnij sie, ze twoj klient\nuzywa wlasciwego protokolu gry.",
@@ -187,7 +193,7 @@ locale = {
["Market"] = false, ["Market"] = false,
["Market Offers"] = false, ["Market Offers"] = false,
["Message of the day"] = "Wiadomosc dnia", ["Message of the day"] = "Wiadomosc dnia",
["Message to "] = "Wiadomosc do ", ["Message to "] = false,
["Message to %s"] = "Wiadomosc do %s", ["Message to %s"] = "Wiadomosc do %s",
["Minimap"] = "Minimapa", ["Minimap"] = "Minimapa",
["Module Manager"] = "Menedzer modulow", ["Module Manager"] = "Menedzer modulow",
@@ -195,32 +201,32 @@ locale = {
["Mount"] = false, ["Mount"] = false,
["Move Stackable Item"] = "Przenies przedmiot", ["Move Stackable Item"] = "Przenies przedmiot",
["Move up"] = "Przenies wyzej", ["Move up"] = "Przenies wyzej",
["My Offers"] = "Moje Oferty", ["My Offers"] = false,
["Name:"] = "Nazwa:", ["Name:"] = "Nazwa:",
["Name Report"] = false, ["Name Report"] = false,
["Name Report + Banishment"] = false, ["Name Report + Banishment"] = false,
["Name Report + Banishment + Final Warning"] = false, ["Name Report + Banishment + Final Warning"] = false,
["No"] = "Nie", ["No"] = false,
["No graphics card detected, everything will be drawn using the CPU,\nthus the performance will be really bad.\nPlease update your graphics driver to have a better performance."] = false, ["No graphics card detected, everything will be drawn using the CPU,\nthus the performance will be really bad.\nPlease update your graphics driver to have a better performance."] = false,
["No item selected."] = "Nie wybrano przedmiotu.", ["No item selected."] = false,
["No Mount"] = "Brak wierzchowca", ["No Mount"] = false,
["No Outfit"] = "Brak stroju", ["No Outfit"] = false,
["No statement has been selected."] = false, ["No statement has been selected."] = false,
["Notation"] = false, ["Notation"] = false,
["NPC Trade"] = "Handel NPC", ["NPC Trade"] = "Handel NPC",
["Offer History"] = "Historia Ofert", ["Offer History"] = false,
["Offers"] = "Oferty", ["Offers"] = false,
["Offer Type:"] = "Typ Oferty:", ["Offer Type:"] = false,
["Offline Training"] = "Trening Offline", ["Offline Training"] = false,
["Ok"] = "Ok", ["Ok"] = "Ok",
["on %s.\n"] = false, ["on %s.\n"] = false,
["Open"] = "Otworz", ["Open"] = "Otworz",
["Open a private message channel:"] = "Otworz prywatny kanal:", ["Open a private message channel:"] = "Otworz prywatny kanal:",
["Open charlist automatically when starting client"] = "Automatycznie otworz liste postaci przy starcie gry", ["Open charlist automatically when starting client"] = false,
["Open in new window"] = "Otworz w nowym oknie", ["Open in new window"] = "Otworz w nowym oknie",
["Open new channel"] = "Otworz nowy kanal", ["Open new channel"] = "Otworz nowy kanal",
["Options"] = "Opcje", ["Options"] = "Opcje",
["Overview"] = "Podsumowanie", ["Overview"] = false,
["Pass Leadership to %s"] = "Przekaz przywodztwo %s", ["Pass Leadership to %s"] = "Przekaz przywodztwo %s",
["Password"] = "Haslo", ["Password"] = "Haslo",
["Piece Price:"] = false, ["Piece Price:"] = false,
@@ -230,79 +236,79 @@ locale = {
["Please use this dialog to only report bugs. Do not report rule violations here!"] = false, ["Please use this dialog to only report bugs. Do not report rule violations here!"] = false,
["Please wait"] = "Prosze czekac", ["Please wait"] = "Prosze czekac",
["Port"] = "Port", ["Port"] = "Port",
["Position:"] = "Pozycja:", ["Position:"] = false,
["Position: %i %i %i"] = "Pozycja: %i %i %i", ["Position: %i %i %i"] = false,
["Premium Account (%s) days left"] = "Konto Premium (%s) dni", ["Premium Account (%s) days left"] = false,
["Price:"] = "Cena:", ["Price:"] = "Cena:",
["Primary"] = "Podstawowy", ["Primary"] = "Podstawowy",
["Protocol"] = "Protokol", ["Protocol"] = false,
["Quest Log"] = "Dziennik Misji", ["Quest Log"] = false,
["Randomize"] = false, ["Randomize"] = false,
["Randomize characters outfit"] = false, ["Randomize characters outfit"] = false,
["Reason:"] = "Powod:", ["Reason:"] = false,
["Refresh"] = "Odswiez", ["Refresh"] = "Odswiez",
["Refresh Offers"] = "Odswiez Oferty", ["Refresh Offers"] = false,
["Regeneration Time"] = "Czas Regeneracji", ["Regeneration Time"] = false,
["Reject"] = "Odrzuc", ["Reject"] = false,
["Reload All"] = "Przeladuj Wszystko", ["Reload All"] = "Przeladuj Wszystko",
["Remember account and password when starts client"] = "Zapamietaj identyfikator konta oraz haslo", ["Remember account and password when starts client"] = false,
["Remember password"] = "Zapamietaj haslo", ["Remember password"] = "Zapamietaj haslo",
["Remove"] = "Usun", ["Remove"] = "Usun",
["Remove %s"] = "Usun %s", ["Remove %s"] = "Usun %s",
["Report Bug"] = "Zglos Blad", ["Report Bug"] = false,
["Reserved for more functionality later."] = "Zarezerowane dla przyszlych funkcjonalnosci.", ["Reserved for more functionality later."] = false,
["Reset Market"] = false, ["Reset Market"] = false,
["Revoke %s's Invitation"] = "Odmow na zaproszenie gracza %s", ["Revoke %s's Invitation"] = false,
["Rotate"] = "Obroc", ["Rotate"] = "Obroc",
["Rule Violation"] = "Zlamanie Regul", ["Rule Violation"] = false,
["Save"] = "Zapisz", ["Save"] = false,
["Save Messages"] = "Zapisz Wiadomosci", ["Save Messages"] = false,
["Search:"] = "Szukaj:", ["Search:"] = "Szukaj:",
["Search all items"] = "Znajdz wszystkie przedmioty", ["Search all items"] = false,
["Secondary"] = "Drugorzedny", ["Secondary"] = "Drugorzedny",
["Select object"] = "Wybierz obiekt", ["Select object"] = "Wybierz obiekt",
["Select Outfit"] = "Wybierz outfit", ["Select Outfit"] = "Wybierz outfit",
["Select your language"] = "Wybierz jezyk", ["Select your language"] = false,
["Sell"] = "Sprzedaj", ["Sell"] = "Sprzedaj",
["Sell Now"] = "Sprzedaj Teraz", ["Sell Now"] = false,
["Sell Offers"] = "Oferty Sprzedazy", ["Sell Offers"] = false,
["Send"] = "Wyslij", ["Send"] = false,
["Send automatically"] = "Wyslij automatycznie", ["Send automatically"] = "Wyslij automatycznie",
["Send Message"] = "Wyslij Wiadomosc", ["Send Message"] = false,
["Server"] = "Serwer", ["Server"] = "Serwer",
["Server Log"] = "Log Serwera", ["Server Log"] = "Log Serwera",
["Set Outfit"] = "Ustaw outfit", ["Set Outfit"] = "Ustaw outfit",
["Shielding"] = "Obrona tarcza", ["Shielding"] = "Obrona tarcza",
["Show all items"] = "Pokaz wszystkie przedmioty", ["Show all items"] = "Pokaz wszystkie przedmioty",
["Show connection ping"] = "Wyswietl ping", ["Show connection ping"] = false,
["Show Depot Only"] = false, ["Show Depot Only"] = false,
["Show event messages in console"] = "Pokaz wydarzenia w konsoli", ["Show event messages in console"] = "Pokaz wydarzenia w konsoli",
["Show frame rate"] = "Pokaz FPS", ["Show frame rate"] = "Pokaz ilosc FPS",
["Show info messages in console"] = "Pokaz informacje w konsoli", ["Show info messages in console"] = "Pokaz informacje w konsoli",
["Show left panel"] = "Pokaz lewy panel", ["Show left panel"] = false,
["Show levels in console"] = "Pokaz poziomy w konsoli", ["Show levels in console"] = "Pokaz poziomy w konsoli",
["Show Offline"] = "Pokaz Niedostepnych", ["Show Offline"] = false,
["Show private messages in console"] = "Pokaz prywatne wiadomosci w konsoli", ["Show private messages in console"] = "Pokaz prywatne wiadomosci w konsoli",
["Show private messages on screen"] = "Pokaz prywatne wiadomosci na ekranie", ["Show private messages on screen"] = false,
["Show Server Messages"] = "Pokaz Wiadomosci Serwera", ["Show Server Messages"] = false,
["Show status messages in console"] = "Pokaz status w konsoli", ["Show status messages in console"] = "Pokaz status w konsoli",
["Show Text"] = "Pokaz Tekst", ["Show Text"] = false,
["Show timestamps in console"] = "Pokaz znaczniki czasu w konsoli", ["Show timestamps in console"] = "Pokaz znaczniki czasu w konsoli",
["Show your depot items only"] = false, ["Show your depot items only"] = false,
["Skills"] = "Umiejetnosci", ["Skills"] = "Umiejetnosci",
["Soul"] = "Dusze", ["Soul"] = false,
["Soul Points"] = "Punkty Duszy", ["Soul Points"] = "Punkty Duszy",
["Special"] = false, ["Special"] = false,
["Speed"] = "Predkosc", ["Speed"] = false,
["Spell Cooldowns"] = false, ["Spell Cooldowns"] = false,
["Spell List"] = "Lista Zaklec", ["Spell List"] = false,
["Stamina"] = "Wytrzymalosc", ["Stamina"] = "Wytrzymalosc",
["Statement:"] = false, ["Statement:"] = false,
["Statement Report"] = false, ["Statement Report"] = false,
["Statistics"] = "Statystki", ["Statistics"] = false,
["Stop Attack"] = "Anuluj atak", ["Stop Attack"] = "Zatrzymaj atak",
["Stop Follow"] = "Przestan podazac", ["Stop Follow"] = "Zatrzymaj podazanie",
["Support"] = "Wsparcie", ["Support"] = false,
["%s: (use object)"] = "%s: (uzyj obiekt)", ["%s: (use object)"] = "%s: (uzyj obiekt)",
["%s: (use object on target)"] = "%s: (uzyj obiektu na celu)", ["%s: (use object on target)"] = "%s: (uzyj obiektu na celu)",
["%s: (use object on yourself)"] = "%s: (uzyj obiektu na sobie)", ["%s: (use object on yourself)"] = "%s: (uzyj obiektu na sobie)",
@@ -310,15 +316,15 @@ locale = {
["Sword Fighting"] = "Atak mieczem", ["Sword Fighting"] = "Atak mieczem",
["Terminal"] = "Terminal", ["Terminal"] = "Terminal",
["There is no way."] = "Nie ma drogi.", ["There is no way."] = "Nie ma drogi.",
["Title"] = "Tytul", ["Title"] = false,
["Total Price"] = "Cena sumaryczna", ["Total Price:"] = false,
["Trade"] = "Handel", ["Trade"] = "Handel",
["Trade with ..."] = "Handluj z ...", ["Trade with ..."] = "Handluj z ...",
["Trying to reconnect in %s seconds."] = "Ponowna proba laczenia za %s sekund.", ["Trying to reconnect in %s seconds."] = false,
["Unable to load dat file, please place a valid dat in '%s'"] = "Nie mozna zaladowac pliku .dat z '%s'", ["Unable to load dat file, please place a valid dat in '%s'"] = false,
["Unable to load spr file, please place a valid spr in '%s'"] = "Nie mozna zaladowac pliku .spr z '%s'", ["Unable to load spr file, please place a valid spr in '%s'"] = false,
["Unable to logout."] = "Nie mozna sie wylogowac.", ["Unable to logout."] = "Nie mozna sie wylogowac.",
["Unignore"] = "Anuluj Ignorowanie", ["Unignore"] = false,
["Unload"] = "Wylacz", ["Unload"] = "Wylacz",
["Update needed"] = false, ["Update needed"] = false,
["Use"] = "Uzyj", ["Use"] = "Uzyj",
@@ -328,87 +334,42 @@ locale = {
["Version"] = "Wersja", ["Version"] = "Wersja",
["VIP List"] = "Lista VIP", ["VIP List"] = "Lista VIP",
["Voc."] = false, ["Voc."] = false,
["Vocation"] = "Klasa", ["Vocation"] = false,
["Waiting List"] = "Lista Oczekujacych", ["Waiting List"] = false,
["Website"] = "Strona:", ["Website"] = "Strona:",
["Weight:"] = "Waga:", ["Weight:"] = "Waga:",
["Will detect when to use diagonal step based on the\nkeys you are pressing"] = false, ["Will detect when to use diagonal step based on the\nkeys you are pressing"] = false,
["With crosshair"] = "Z celownikiem", ["With crosshair"] = "Z celownikiem",
["Yes"] = "Tak", ["Yes"] = false,
["You are bleeding"] = "Krwawisz", ["You are bleeding"] = false,
["You are burning"] = "Palisz sie", ["You are burning"] = "Palisz sie",
["You are cursed"] = "Jestes przeklety", ["You are cursed"] = "Jestes przeklety",
["You are dazzled"] = "Jestes oslepiony", ["You are dazzled"] = "Jestes oslepiony",
["You are dead."] = "Zginales marnie.", ["You are dead."] = "Zginales marnie.",
["You are dead"] = "Jestes martwy", ["You are dead"] = false,
["You are drowning"] = "Topisz sie", ["You are drowning"] = "Topisz sie",
["You are drunk"] = "Caly swiat wiruje", ["You are drunk"] = false,
["You are electrified"] = "Jestes porazony pradem", ["You are electrified"] = "Jestes porazony pradem",
["You are freezing"] = "Marzniesz", ["You are freezing"] = "Marzniesz",
["You are hasted"] = "Zapieprzasz", ["You are hasted"] = "Zapieprzasz",
["You are hungry"] = "Burczy ci w brzuchu", ["You are hungry"] = false,
["You are paralysed"] = "Jestes sparalizowany", ["You are paralysed"] = "Jestes sparalizowany",
["You are poisoned"] = "Jestes zatruty", ["You are poisoned"] = "Jestes zatruty",
["You are protected by a magic shield"] = "Jestes chroniony magiczna tarcza", ["You are protected by a magic shield"] = "Jestes chroniony magiczna tarcza",
["You are strengthened"] = "Jestes wzmocniony", ["You are strengthened"] = "Jestes wzmocniony",
["You are within a protection zone"] = "Jestes w strefie ochronnej", ["You are within a protection zone"] = "Jestes w strefie ochronnej",
["You can enter new text."] = "Mozesz wprowadzic nowy tekst.", ["You can enter new text."] = false,
["You have %s percent"] = "Masz %s procent", ["You have %s percent"] = "Masz %s procent",
["You have %s percent to go"] = "Brakuje Ci %s procent", ["You have %s percent to go"] = "Brakuje Ci %s procent",
["You may not logout during a fight"] = "Nie mozesz sie wylogowac w trakcie walki", ["You may not logout during a fight"] = "Nie mozesz sie wylogowac w trakcie walki",
["You may not logout or enter a protection zone"] = "Nie mozesz sie wylogowac ani wejsc do strefy ochronnej", ["You may not logout or enter a protection zone"] = "Nie mozesz sie wylogowac ani wejsc do strefy ochronnej",
["You must enter a comment."] = "Prosze wprowadzic komentarz", ["You must enter a comment."] = false,
["You must enter a valid server address and port."] = "Prosze wprowadzic poprawny adres i port.", ["You must enter a valid server address and port."] = false,
["You must select a character to login!"] = "Musisz wybrac postac aby sie zalogowac!", ["You must select a character to login!"] = "Musisz wybrac postac aby sie zalogowac!",
["Your Capacity:"] = "Twoja Ladownosc:", ["Your Capacity:"] = false,
["You read the following, written by \n%s\n"] = false, ["You read the following, written by \n%s\n"] = false,
["You read the following, written on \n%s.\n"] = false, ["You read the following, written on \n%s.\n"] = false,
["Your Money:"] = false, ["Your Money:"] = false,
["Enable dash walking"] = false,
["Will boost your walk on high speed characters"] = "Przyspieszy poruszanie sie postaci o wysokiej predkosci",
["Display creature names"] = "Wyswietlaj nazwy potworow",
["Display creature health bars"] = "Wyswietlaj paski zycia potworow",
["Display text messages"] = "Wyswietlaj wiadomosci tekstowe",
["Change language"] = "Zmien jezyk",
["Enable lights"] = "Odblokuj oswietlenie",
["Enable audio"] = "Odblokuj dzwiek",
["Enable music sound"] = "Odblokuj muzyke",
["Music volume: %d"] = "Glosnosc muzyki: %d",
["Audio"] = "Dzwiek",
["Server List"] = "Lista serwerow",
["Server list"] = "Lista serwerow",
["Client Version"] = "Wersja klienta",
["Add new server"] = "Dodaj nowy serwer",
["Select"] = "Wybierz",
["New Server"] = "Nowy serwer",
["Host"] = false,
["Reset All"] = "Ustaw domyslne",
["Disable chat mode, allow to walk using ASDW"] = "Zablokuj tryb rozmow, zezwol na poruszanie sie za pomoca klawiszy ADSW",
["Name"] = "Imie",
["Price"] = "Cena",
["Your Money"] = "Twoje fundusze",
["Weight"] = "Waga",
["Your Capacity"] = "Twoj udzwig",
["Search"] = "Szukaj",
["Sell All"] = "Sprzedaj wszystko",
["Statement"] = false,
["Reason"] = "Powod",
["Action"] = "Akcja",
["Comment"] = "Komentarz",
["Balance"] = false,
["Offer Type"] = "Typ oferty",
["Piece Price"] = false,
["Find"] = "Szukaj",
["Formula"] = "Formula",
["Group"] = "Groupa",
["Type"] = "Typ",
["Cooldown"] = false,
["Premium"] = false,
["Any"] = "Dowolny",
["Sorcerer"] = "Czarodziej",
["Druid"] = false,
["Paladin"] = "Paladyn",
["Knight"] = "Rycerz"
} }
} }

View File

@@ -11,9 +11,3 @@ HorizontalList < UIScrollArea
border-width: 1 border-width: 1
border-color: #1d222b border-color: #1d222b
background-color: #222833 background-color: #222833
VerticalList < UIScrollArea
layout: verticalBox
border-width: 1
border-color: #1d222b
background-color: #222833

View File

@@ -48,7 +48,7 @@ g_modules.ensureModuleLoaded("game_interface")
-- mods 1000-9999 -- mods 1000-9999
g_modules.autoLoadModules(9999) g_modules.autoLoadModules(9999)
local script = '/' .. g_app.getCompactName() .. 'rc' local script = '/' .. g_app.getCompactName() .. 'rc.lua'
if g_resources.fileExists(script) then if g_resources.fileExists(script) then
dofile(script) dofile(script)

View File

@@ -1,10 +0,0 @@
{
"folders":
[
{
"path": "..",
"folder_exclude_patterns": [".*", "*.*~"],
"file_exclude_patterns": [".*", "*.*~"]
}
]
}

View File

@@ -1,5 +1,5 @@
local musicFilename = "/sounds/startup" local musicFilename = "/sounds/startup"
local musicChannel = g_sounds.getChannel(1) local musicChannel = nil
function setMusic(filename) function setMusic(filename)
musicFilename = filename musicFilename = filename
@@ -57,11 +57,14 @@ function init()
onExit = exit }) onExit = exit })
g_window.setMinimumSize({ width = 600, height = 480 }) g_window.setMinimumSize({ width = 600, height = 480 })
musicChannel = g_sounds.getChannel(1)
g_sounds.preload(musicFilename) g_sounds.preload(musicFilename)
-- initialize in fullscreen mode on mobile devices -- initialize in fullscreen mode on mobile devices
if g_window.getPlatformType() == "X11-EGL" then if g_app.getOs() == "android" then
g_window.setFullscreen(true) g_window.maximize()
--g_window.setFullscreen(true)
else else
-- window size -- window size
local size = { width = 800, height = 600 } local size = { width = 800, height = 600 }
@@ -104,6 +107,11 @@ function terminate()
g_settings.set('window-size', g_window.getUnmaximizedSize()) g_settings.set('window-size', g_window.getUnmaximizedSize())
g_settings.set('window-pos', g_window.getUnmaximizedPos()) g_settings.set('window-pos', g_window.getUnmaximizedPos())
g_settings.set('window-maximized', g_window.isMaximized()) g_settings.set('window-maximized', g_window.isMaximized())
local protocolVersion = g_game.getProtocolVersion()
if protocolVersion ~= 0 then
g_settings.set('protocol-version', protocolVersion)
end
end end
function exit() function exit()

View File

@@ -19,4 +19,4 @@ Module
- client_terminal - client_terminal
- client_modulemanager - client_modulemanager
- client_serverlist - client_serverlist
- client_stats //- client_stats

View File

@@ -6,7 +6,7 @@ local enterGame
local motdWindow local motdWindow
local motdButton local motdButton
local enterGameButton local enterGameButton
local clientBox local protocolBox
local protocolLogin local protocolLogin
local motdEnabled = true local motdEnabled = true
@@ -73,6 +73,11 @@ local function onCharacterList(protocol, characters, account, otui)
end end
end end
local function onChangeProtocol(combobox, option)
local clients = g_game.getSupportedClients(option)
protocolBox:setTooltip("Supports Client" .. (#clients > 1 and "s" or "") .. ": " .. table.tostring(clients))
end
local function onUpdateNeeded(protocol, signature) local function onUpdateNeeded(protocol, signature)
loadBox:destroy() loadBox:destroy()
loadBox = nil loadBox = nil
@@ -104,8 +109,7 @@ function EnterGame.init()
local host = g_settings.get('host') local host = g_settings.get('host')
local port = g_settings.get('port') local port = g_settings.get('port')
local autologin = g_settings.getBoolean('autologin') local autologin = g_settings.getBoolean('autologin')
local clientVersion = g_settings.getInteger('client-version') local protocolVersion = g_settings.getInteger('protocol-version')
if clientVersion == 0 then clientVersion = 860 end
if port == nil or port == 0 then port = 7171 end if port == nil or port == 0 then port = 7171 end
@@ -116,11 +120,11 @@ function EnterGame.init()
enterGame:getChildById('serverPortTextEdit'):setText(port) enterGame:getChildById('serverPortTextEdit'):setText(port)
enterGame:getChildById('autoLoginBox'):setChecked(autologin) enterGame:getChildById('autoLoginBox'):setChecked(autologin)
clientBox = enterGame:getChildById('clientComboBox') protocolBox = enterGame:getChildById('protocolComboBox')
for _, proto in pairs(g_game.getSupportedClients()) do protocolBox.onOptionChange = onChangeProtocol
clientBox:addOption(proto) if protocolVersion then
protocolBox:setCurrentOption(protocolVersion)
end end
clientBox:setCurrentOption(clientVersion)
enterGame:hide() enterGame:hide()
@@ -150,7 +154,7 @@ function EnterGame.terminate()
enterGame = nil enterGame = nil
enterGameButton:destroy() enterGameButton:destroy()
enterGameButton = nil enterGameButton = nil
clientBox = nil protocolBox = nil
if motdWindow then if motdWindow then
motdWindow:destroy() motdWindow:destroy()
motdWindow = nil motdWindow = nil
@@ -214,7 +218,8 @@ function EnterGame.doLogin()
G.password = enterGame:getChildById('accountPasswordTextEdit'):getText() G.password = enterGame:getChildById('accountPasswordTextEdit'):getText()
G.host = enterGame:getChildById('serverHostTextEdit'):getText() G.host = enterGame:getChildById('serverHostTextEdit'):getText()
G.port = tonumber(enterGame:getChildById('serverPortTextEdit'):getText()) G.port = tonumber(enterGame:getChildById('serverPortTextEdit'):getText())
local clientVersion = tonumber(clientBox:getText()) local protocolVersion = tonumber(protocolBox:getText())
local clientVersions = g_game.getSupportedClients(protocolVersion)
EnterGame.hide() EnterGame.hide()
if g_game.isOnline() then if g_game.isOnline() then
@@ -225,7 +230,6 @@ function EnterGame.doLogin()
g_settings.set('host', G.host) g_settings.set('host', G.host)
g_settings.set('port', G.port) g_settings.set('port', G.port)
g_settings.set('client-version', clientVersion)
protocolLogin = ProtocolLogin.create() protocolLogin = ProtocolLogin.create()
protocolLogin.onLoginError = onError protocolLogin.onLoginError = onError
@@ -241,8 +245,10 @@ function EnterGame.doLogin()
end }) end })
g_game.chooseRsa(G.host) g_game.chooseRsa(G.host)
g_game.setClientVersion(clientVersion) g_game.setProtocolVersion(protocolVersion)
g_game.setProtocolVersion(g_game.getProtocolVersionForClient(clientVersion)) if #clientVersions > 0 then
g_game.setClientVersion(clientVersions[#clientVersions])
end
if modules.game_things.isLoaded() then if modules.game_things.isLoaded() then
protocolLogin:login(G.host, G.port, G.account, G.password) protocolLogin:login(G.host, G.port, G.account, G.password)
@@ -263,14 +269,14 @@ end
function EnterGame.setDefaultServer(host, port, protocol) function EnterGame.setDefaultServer(host, port, protocol)
local hostTextEdit = enterGame:getChildById('serverHostTextEdit') local hostTextEdit = enterGame:getChildById('serverHostTextEdit')
local portTextEdit = enterGame:getChildById('serverPortTextEdit') local portTextEdit = enterGame:getChildById('serverPortTextEdit')
local clientLabel = enterGame:getChildById('clientLabel') local protocolLabel = enterGame:getChildById('protocolLabel')
local accountTextEdit = enterGame:getChildById('accountNameTextEdit') local accountTextEdit = enterGame:getChildById('accountNameTextEdit')
local passwordTextEdit = enterGame:getChildById('accountPasswordTextEdit') local passwordTextEdit = enterGame:getChildById('accountPasswordTextEdit')
if hostTextEdit:getText() ~= host then if hostTextEdit:getText() ~= host then
hostTextEdit:setText(host) hostTextEdit:setText(host)
portTextEdit:setText(port) portTextEdit:setText(port)
clientBox:setCurrentOption(protocol) protocolBox:setCurrentOption(protocol)
accountTextEdit:setText('') accountTextEdit:setText('')
passwordTextEdit:setText('') passwordTextEdit:setText('')
end end
@@ -286,9 +292,9 @@ function EnterGame.setUniqueServer(host, port, protocol, windowWidth, windowHeig
portTextEdit:setVisible(false) portTextEdit:setVisible(false)
portTextEdit:setHeight(0) portTextEdit:setHeight(0)
clientBox:setCurrentOption(protocol) protocolBox:setCurrentOption(protocol)
clientBox:setVisible(false) protocolBox:setVisible(false)
clientBox:setHeight(0) protocolBox:setHeight(0)
local serverLabel = enterGame:getChildById('serverLabel') local serverLabel = enterGame:getChildById('serverLabel')
serverLabel:setVisible(false) serverLabel:setVisible(false)
@@ -296,9 +302,9 @@ function EnterGame.setUniqueServer(host, port, protocol, windowWidth, windowHeig
local portLabel = enterGame:getChildById('portLabel') local portLabel = enterGame:getChildById('portLabel')
portLabel:setVisible(false) portLabel:setVisible(false)
portLabel:setHeight(0) portLabel:setHeight(0)
local clientLabel = enterGame:getChildById('clientLabel') local protocolLabel = enterGame:getChildById('protocolLabel')
clientLabel:setVisible(false) protocolLabel:setVisible(false)
clientLabel:setHeight(0) protocolLabel:setHeight(0)
local serverListButton = enterGame:getChildById('serverListButton') local serverListButton = enterGame:getChildById('serverListButton')
serverListButton:setVisible(false) serverListButton:setVisible(false)

View File

@@ -68,7 +68,7 @@ EnterGameWindow
TextEdit TextEdit
id: serverHostTextEdit id: serverHostTextEdit
!tooltip: tr('Make sure that your client uses\nthe correct game client version') !tooltip: tr('Make sure that your client uses\nthe correct game protocol version')
anchors.left: parent.left anchors.left: parent.left
anchors.right: serverListButton.left anchors.right: serverListButton.left
anchors.top: serverLabel.bottom anchors.top: serverLabel.bottom
@@ -76,8 +76,8 @@ EnterGameWindow
margin-right: 4 margin-right: 4
MenuLabel MenuLabel
id: clientLabel id: protocolLabel
!text: tr('Client Version') !text: tr('Protocol')
anchors.left: parent.left anchors.left: parent.left
anchors.top: serverHostTextEdit.bottom anchors.top: serverHostTextEdit.bottom
text-auto-resize: true text-auto-resize: true
@@ -85,13 +85,17 @@ EnterGameWindow
margin-top: 8 margin-top: 8
ComboBox ComboBox
id: clientComboBox id: protocolComboBox
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.horizontalCenter anchors.right: parent.horizontalCenter
anchors.top: clientLabel.bottom anchors.top: protocolLabel.bottom
margin-top: 2 margin-top: 2
margin-right: 3 margin-right: 3
width: 90 width: 90
@onSetup: |
for _, proto in pairs(g_game.getSupportedProtocols()) do
self:addOption(proto)
end
MenuLabel MenuLabel
id: portLabel id: portLabel
@@ -106,7 +110,7 @@ EnterGameWindow
text: 7171 text: 7171
anchors.right: parent.right anchors.right: parent.right
anchors.left: parent.horizontalCenter anchors.left: parent.horizontalCenter
anchors.top: clientComboBox.top anchors.top: protocolComboBox.top
margin-left: 3 margin-left: 3
CheckBox CheckBox

View File

@@ -137,7 +137,7 @@ function unloadCurrentModule()
local module = g_modules.getModule(focusedChild:getText()) local module = g_modules.getModule(focusedChild:getText())
if module then if module then
module:unload() module:unload()
if modules.client_modulemanager == nil then return end if ModuleManager == nil then return end
updateModuleInfo(module:getName()) updateModuleInfo(module:getName())
refreshLoadedModules() refreshLoadedModules()
end end

View File

@@ -39,10 +39,6 @@ Panel
id: fullscreen id: fullscreen
!text: tr('Fullscreen') !text: tr('Fullscreen')
tooltip: Ctrl+Shift+F tooltip: Ctrl+Shift+F
OptionCheckBox
id: dontStretchShrink
!text: tr('Don\'t stretch/shrink Game Window')
Label Label
id: backgroundFrameRateLabel id: backgroundFrameRateLabel
@@ -50,7 +46,7 @@ Panel
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.top: prev.bottom anchors.top: prev.bottom
margin-top: 12 margin-top: 6
@onSetup: | @onSetup: |
local value = modules.client_options.getOption('backgroundFrameRate') local value = modules.client_options.getOption('backgroundFrameRate')
local text = value local text = value

View File

@@ -25,8 +25,7 @@ local defaultOptions = {
ambientLight = 25, ambientLight = 25,
displayNames = true, displayNames = true,
displayHealth = true, displayHealth = true,
displayText = true, displayText = true
dontStretchShrink = false
} }
local optionsWindow local optionsWindow
@@ -224,10 +223,6 @@ function setOption(key, value, force)
gameMapPanel:setDrawHealthBars(value) gameMapPanel:setDrawHealthBars(value)
elseif key == 'displayText' then elseif key == 'displayText' then
gameMapPanel:setDrawTexts(value) gameMapPanel:setDrawTexts(value)
elseif key == 'dontStretchShrink' then
addEvent(function()
modules.game_interface.updateStretchShrink()
end)
end end
-- change value for keybind updates -- change value for keybind updates

View File

@@ -49,7 +49,7 @@ MainWindow
anchors.left: protocolLabel.left anchors.left: protocolLabel.left
anchors.right: port.right anchors.right: port.right
@onSetup: | @onSetup: |
for _, proto in pairs(g_game.getSupportedClients()) do for _, proto in pairs(g_game.getSupportedProtocols()) do
self:addOption(proto) self:addOption(proto)
end end

View File

@@ -257,13 +257,10 @@ function flushLines()
for _,line in pairs(cachedLines) do for _,line in pairs(cachedLines) do
-- delete old lines if needed -- delete old lines if needed
if numLines > MaxLogLines then if numLines > MaxLogLines then
local firstChild = terminalBuffer:getChildByIndex(1) local len = #terminalBuffer:getChildByIndex(1):getText()
if firstChild then terminalBuffer:getChildByIndex(1):destroy()
local len = #firstChild:getText() table.remove(allLines, 1)
firstChild:destroy() fulltext = string.sub(fulltext, len)
table.remove(allLines, 1)
fulltext = string.sub(fulltext, len)
end
end end
local label = g_ui.createWidget('TerminalLabel', terminalBuffer) local label = g_ui.createWidget('TerminalLabel', terminalBuffer)
@@ -288,7 +285,6 @@ function addLine(text, color)
flushEvent = scheduleEvent(flushLines, 10) flushEvent = scheduleEvent(flushLines, 10)
end end
text = string.gsub(text, '\t', ' ')
table.insert(cachedLines, {text=text, color=color}) table.insert(cachedLines, {text=text, color=color})
end end

View File

@@ -157,14 +157,14 @@ function g_keyboard.unbindKeyDown(keyComboDesc, arg1, arg2)
disconnect(widget.boundKeyDownCombos, keyComboDesc, callback) disconnect(widget.boundKeyDownCombos, keyComboDesc, callback)
end end
function g_keyboard.unbindKeyUp(keyComboDesc, arg1, arg2) function g_keyboard.unbindKeyUp(keyComboDesc, widget)
local callback, widget = getUnbindArgs(arg1, arg2) local callback, widget = getUnbindArgs(arg1, arg2)
if widget.boundKeyUpCombos == nil then return end if widget.boundKeyUpCombos == nil then return end
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc) local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)
disconnect(widget.boundKeyUpCombos, keyComboDesc, callback) disconnect(widget.boundKeyUpCombos, keyComboDesc, callback)
end end
function g_keyboard.unbindKeyPress(keyComboDesc, arg1, arg2) function g_keyboard.unbindKeyPress(keyComboDesc, widget, callback)
local callback, widget = getUnbindArgs(arg1, arg2) local callback, widget = getUnbindArgs(arg1, arg2)
if widget.boundKeyPressCombos == nil then return end if widget.boundKeyPressCombos == nil then return end
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc) local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)

View File

@@ -20,8 +20,8 @@ function string:starts(start)
return string.sub(self, 1, #start) == start return string.sub(self, 1, #start) == start
end end
function string:ends(test) function string.ends(s, test)
return test =='' or string.sub(self,-string.len(test)) == test return test =='' or string.sub(s,-string.len(test)) == test
end end
function string:trim() function string:trim()

View File

@@ -110,9 +110,7 @@ function UITabBar:selectTab(tab)
tab:setOn(false) tab:setOn(false)
local parent = tab:getParent() local parent = tab:getParent()
if parent then parent:focusChild(tab, MouseFocusReason)
parent:focusChild(tab, MouseFocusReason)
end
end end
function UITabBar:selectNextTab() function UITabBar:selectNextTab()

View File

@@ -1,16 +1,11 @@
battleWindow = nil battleWindow = nil
battleButton = nil battleButton = nil
battlePanel = nil battlePanel = nil
filterPanel = nil
toggleFilterButton = nil
lastBattleButtonSwitched = nil lastBattleButtonSwitched = nil
battleButtonsByCreaturesList = {} battleButtonsByCreaturesList = {}
creatureAgeList = {}
mouseWidget = nil mouseWidget = nil
sortTypeBox = nil
sortOrderBox = nil
hidePlayersButton = nil hidePlayersButton = nil
hideNPCsButton = nil hideNPCsButton = nil
hideMonstersButton = nil hideMonstersButton = nil
@@ -30,15 +25,6 @@ function init()
battlePanel = battleWindow:recursiveGetChildById('battlePanel') battlePanel = battleWindow:recursiveGetChildById('battlePanel')
filterPanel = battleWindow:recursiveGetChildById('filterPanel')
toggleFilterButton = battleWindow:recursiveGetChildById('toggleFilterButton')
if isHidingFilters() then
hideFilterPanel()
end
sortTypeBox = battleWindow:recursiveGetChildById('sortTypeBox')
sortOrderBox = battleWindow:recursiveGetChildById('sortOrderBox')
hidePlayersButton = battleWindow:recursiveGetChildById('hidePlayers') hidePlayersButton = battleWindow:recursiveGetChildById('hidePlayers')
hideNPCsButton = battleWindow:recursiveGetChildById('hideNPCs') hideNPCsButton = battleWindow:recursiveGetChildById('hideNPCs')
hideMonstersButton = battleWindow:recursiveGetChildById('hideMonsters') hideMonstersButton = battleWindow:recursiveGetChildById('hideMonsters')
@@ -52,18 +38,6 @@ function init()
battleWindow:setContentMinimumHeight(80) battleWindow:setContentMinimumHeight(80)
sortTypeBox:addOption('Name', 'name')
sortTypeBox:addOption('Distance', 'distance')
sortTypeBox:addOption('Age', 'age')
sortTypeBox:addOption('Health', 'health')
sortTypeBox:setCurrentOptionByData(getSortType())
sortTypeBox.onOptionChange = onChangeSortType
sortOrderBox:addOption('Asc.', 'asc')
sortOrderBox:addOption('Desc.', 'desc')
sortOrderBox:setCurrentOptionByData(getSortOrder())
sortOrderBox.onOptionChange = onChangeSortOrder
connect(Creature, { connect(Creature, {
onSkullChange = updateCreatureSkull, onSkullChange = updateCreatureSkull,
onEmblemChange = updateCreatureEmblem, onEmblemChange = updateCreatureEmblem,
@@ -73,10 +47,6 @@ function init()
onAppear = onCreatureAppear, onAppear = onCreatureAppear,
onDisappear = onCreatureDisappear onDisappear = onCreatureDisappear
}) })
connect(LocalPlayer, {
onPositionChange = onCreaturePositionChange
})
connect(g_game, { connect(g_game, {
onAttackingCreatureChange = onAttack, onAttackingCreatureChange = onAttack,
@@ -105,10 +75,6 @@ function terminate()
onDisappear = onCreatureDisappear onDisappear = onCreatureDisappear
}) })
disconnect(LocalPlayer, {
onPositionChange = onCreaturePositionChange
})
disconnect(g_game, { disconnect(g_game, {
onAttackingCreatureChange = onAttack, onAttackingCreatureChange = onAttack,
onFollowingCreatureChange = onFollow, onFollowingCreatureChange = onFollow,
@@ -130,93 +96,6 @@ function onMiniWindowClose()
battleButton:setOn(false) battleButton:setOn(false)
end end
function getSortType()
local settings = g_settings.getNode('BattleList')
if not settings then
return 'name'
end
return settings['sortType']
end
function setSortType(state)
settings = {}
settings['sortType'] = state
g_settings.mergeNode('BattleList', settings)
checkCreatures()
end
function getSortOrder()
local settings = g_settings.getNode('BattleList')
if not settings then
return 'asc'
end
return settings['sortOrder']
end
function setSortOrder(state)
settings = {}
settings['sortOrder'] = state
g_settings.mergeNode('BattleList', settings)
checkCreatures()
end
function isSortAsc()
return getSortOrder() == 'asc'
end
function isSortDesc()
return getSortOrder() == 'desc'
end
function isHidingFilters()
local settings = g_settings.getNode('BattleList')
if not settings then
return false
end
return settings['hidingFilters']
end
function setHidingFilters(state)
settings = {}
settings['hidingFilters'] = state
g_settings.mergeNode('BattleList', settings)
end
function hideFilterPanel()
filterPanel.originalHeight = filterPanel:getHeight()
filterPanel:setHeight(0)
toggleFilterButton:getParent():setMarginTop(0)
toggleFilterButton:setImageClip(torect("0 0 21 12"))
setHidingFilters(true)
filterPanel:setVisible(false)
end
function showFilterPanel()
toggleFilterButton:getParent():setMarginTop(5)
filterPanel:setHeight(filterPanel.originalHeight)
toggleFilterButton:setImageClip(torect("21 0 21 12"))
setHidingFilters(false)
filterPanel:setVisible(true)
end
function toggleFilterPanel()
if filterPanel:isVisible() then
hideFilterPanel()
else
showFilterPanel()
end
end
function onChangeSortType(comboBox, option)
setSortType(option:lower())
end
function onChangeSortOrder(comboBox, option)
setSortOrder(option:lower():gsub('[.]', '')) -- Replace dot in option name
end
function checkCreatures() function checkCreatures()
removeAllCreatures() removeAllCreatures()
@@ -272,42 +151,15 @@ end
function onCreatureHealthPercentChange(creature, health) function onCreatureHealthPercentChange(creature, health)
local battleButton = battleButtonsByCreaturesList[creature:getId()] local battleButton = battleButtonsByCreaturesList[creature:getId()]
if battleButton then if battleButton then
if getSortType() == 'health' then
removeCreature(creature)
addCreature(creature)
return
end
battleButton:setLifeBarPercent(creature:getHealthPercent()) battleButton:setLifeBarPercent(creature:getHealthPercent())
end end
end end
local function getDistanceBetween(p1, p2)
return math.max(math.abs(p1.x - p2.x), math.abs(p1.y - p2.y))
end
function onCreaturePositionChange(creature, newPos, oldPos) function onCreaturePositionChange(creature, newPos, oldPos)
if creature:isLocalPlayer() then if creature:isLocalPlayer() then
if oldPos and newPos and newPos.z ~= oldPos.z then if oldPos and newPos and newPos.z ~= oldPos.z then
checkCreatures() checkCreatures()
else else
-- Distance will change when moving, recalculate and move to correct index
if getSortType() == 'distance' then
local distanceList = {}
for id, creatureButton in pairs(battleButtonsByCreaturesList) do
table.insert(distanceList, {distance = getDistanceBetween(newPos, creatureButton.creature:getPosition()), widget = creatureButton})
end
if isSortAsc() then
table.sort(distanceList, function(a, b) return a.distance < b.distance end)
else
table.sort(distanceList, function(a, b) return a.distance > b.distance end)
end
for i = 1, #distanceList do
battlePanel:moveChildToIndex(distanceList[i].widget, i)
end
end
for id, creatureButton in pairs(battleButtonsByCreaturesList) do for id, creatureButton in pairs(battleButtonsByCreaturesList) do
addCreature(creatureButton.creature) addCreature(creatureButton.creature)
end end
@@ -318,9 +170,6 @@ function onCreaturePositionChange(creature, newPos, oldPos)
if has and not fit then if has and not fit then
removeCreature(creature) removeCreature(creature)
elseif fit then elseif fit then
if has and getSortType() == 'distance' then
removeCreature(creature)
end
addCreature(creature) addCreature(creature)
end end
end end
@@ -352,13 +201,8 @@ function addCreature(creature)
local creatureId = creature:getId() local creatureId = creature:getId()
local battleButton = battleButtonsByCreaturesList[creatureId] local battleButton = battleButtonsByCreaturesList[creatureId]
-- Register when creature is added to battlelist for the first time
if not creatureAgeList[creatureId] then
creatureAgeList[creatureId] = os.time()
end
if not battleButton then if not battleButton then
battleButton = g_ui.createWidget('BattleButton') battleButton = g_ui.createWidget('BattleButton', battlePanel)
battleButton:setup(creature) battleButton:setup(creature)
battleButton.onHoverChange = onBattleButtonHoverChange battleButton.onHoverChange = onBattleButtonHoverChange
@@ -373,77 +217,6 @@ function addCreature(creature)
if creature == g_game.getFollowingCreature() then if creature == g_game.getFollowingCreature() then
onFollow(creature) onFollow(creature)
end end
local inserted = false
local nameLower = creature:getName():lower()
local healthPercent = creature:getHealthPercent()
local playerPosition = g_game.getLocalPlayer():getPosition()
local distance = getDistanceBetween(playerPosition, creature:getPosition())
local age = creatureAgeList[creatureId]
local childCount = battlePanel:getChildCount()
for i = 1, childCount do
local child = battlePanel:getChildByIndex(i)
local childName = child:getCreature():getName():lower()
local equal = false
if getSortType() == 'age' then
local childAge = creatureAgeList[child:getCreature():getId()]
if (age < childAge and isSortAsc()) or (age > childAge and isSortDesc()) then
battlePanel:insertChild(i, battleButton)
inserted = true
break
elseif age == childAge then
equal = true
end
elseif getSortType() == 'distance' then
local childDistance = getDistanceBetween(child:getCreature():getPosition(), playerPosition)
if (distance < childDistance and isSortAsc()) or (distance > childDistance and isSortDesc()) then
battlePanel:insertChild(i, battleButton)
inserted = true
break
elseif childDistance == distance then
equal = true
end
elseif getSortType() == 'health' then
local childHealth = child:getCreature():getHealthPercent()
if (healthPercent < childHealth and isSortAsc()) or (healthPercent > childHealth and isSortDesc()) then
battlePanel:insertChild(i, battleButton)
inserted = true
break
elseif healthPercent == childHealth then
equal = true
end
end
-- If any other sort type is selected and values are equal, sort it by name also
if getSortType() == 'name' or equal then
local length = math.min(childName:len(), nameLower:len())
for j=1,length do
if (nameLower:byte(j) < childName:byte(j) and isSortAsc()) or (nameLower:byte(j) > childName:byte(j) and isSortDesc()) then
battlePanel:insertChild(i, battleButton)
inserted = true
break
elseif (nameLower:byte(j) > childName:byte(j) and isSortAsc()) or (nameLower:byte(j) < childName:byte(j) and isSortDesc()) then
break
elseif j == nameLower:len() and isSortAsc() then
battlePanel:insertChild(i, battleButton)
inserted = true
elseif j == childName:len() and isSortDesc() then
battlePanel:insertChild(i, battleButton)
inserted = true
end
end
end
if inserted then
break
end
end
-- Insert at the end if no other place is found
if not inserted then
battlePanel:insertChild(childCount + 1, battleButton)
end
else else
battleButton:setLifeBarPercent(creature:getHealthPercent()) battleButton:setLifeBarPercent(creature:getHealthPercent())
end end
@@ -453,7 +226,6 @@ function addCreature(creature)
end end
function removeAllCreatures() function removeAllCreatures()
creatureAgeList = {}
for i, v in pairs(battleButtonsByCreaturesList) do for i, v in pairs(battleButtonsByCreaturesList) do
removeCreature(v.creature) removeCreature(v.creature)
end end

View File

@@ -45,12 +45,11 @@ MiniWindow
&save: true &save: true
Panel Panel
id: filterPanel
margin-top: 26 margin-top: 26
anchors.top: parent.top anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left
anchors.right: miniwindowScrollBar.left anchors.right: miniwindowScrollBar.left
height: 45 height: 20
Panel Panel
anchors.top: parent.top anchors.top: parent.top
@@ -86,56 +85,16 @@ MiniWindow
!tooltip: tr('Hide party members') !tooltip: tr('Hide party members')
@onCheckChange: modules.game_battle.checkCreatures() @onCheckChange: modules.game_battle.checkCreatures()
Panel
anchors.top: prev.bottom
anchors.horizontalCenter: parent.horizontalCenter
height: 20
width: 128
margin-top: 6
ComboBox
id: sortTypeBox
width: 74
anchors.top: parent.top
anchors.left: prev.right
anchors.horizontalCenter: parent.horizontalCenter
margin-left: -28
ComboBox
id: sortOrderBox
width: 54
anchors.top: parent.top
anchors.left: prev.right
margin-left: 4
Panel
height: 18
anchors.top: prev.bottom
anchors.left: parent.left
anchors.right: miniwindowScrollBar.left
margin-top: 5
UIWidget
id: toggleFilterButton
anchors.top: prev.top
width: 21
anchors.horizontalCenter: parent.horizontalCenter
image-source: /images/ui/arrow_vertical
image-rect: 0 0 21 12
image-clip: 21 0 21 12
@onClick: modules.game_battle.toggleFilterPanel()
phantom: false
HorizontalSeparator HorizontalSeparator
anchors.top: prev.top anchors.top: prev.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.right: miniwindowScrollBar.left anchors.right: miniwindowScrollBar.left
margin-right: 1 margin-right: 1
margin-top: 11 margin-top: 4
MiniWindowContents MiniWindowContents
anchors.top: prev.bottom anchors.top: prev.bottom
margin-top: 6 margin-top: 0
Panel Panel
id: battlePanel id: battlePanel

View File

@@ -1,206 +0,0 @@
IgnoreListLabel < Label
font: verdana-11px-monochrome
background-color: alpha
text-offset: 2 0
focusable: true
phantom: false
$focus:
background-color: #ffffff22
color: #ffffff
WhiteListLabel < Label
font: verdana-11px-monochrome
background-color: alpha
text-offset: 2 0
focusable: true
phantom: false
$focus:
background-color: #ffffff22
color: #ffffff
MainWindow
id: communicationWindow
!text: tr('Ignore List')
size: 515 410
@onEscape: self:destroy()
CheckBox
id: checkboxUseIgnoreList
!text: tr('Activate ignorelist')
anchors.left: parent.left
anchors.top: parent.top
width: 180
Label
!text: tr('Ignored Players:')
anchors.left: parent.left
anchors.top: prev.bottom
margin-top: 10
TextList
id: ignoreList
vertical-scrollbar: ignoreListScrollBar
anchors.left: parent.left
anchors.top: prev.bottom
height: 150
width: 230
margin-bottom: 10
margin-top: 3
padding: 1
focusable: false
TextEdit
id: ignoreNameEdit
anchors.top: prev.bottom
anchors.left: parent.left
width: 110
margin-top: 5
Button
id: buttonIgnoreAdd
!text: tr('Add')
width: 48
height: 20
margin-left: 5
anchors.top: prev.top
anchors.left: prev.right
Button
id: buttonIgnoreRemove
!text: tr('Remove')
width: 64
height: 20
margin-left: 5
anchors.top: prev.top
anchors.left: prev.right
Label
!text: tr('Global ignore settings')
anchors.left: parent.left
anchors.top: prev.bottom
margin-top: 20
CheckBox
id: checkboxIgnorePrivateMessages
!text: tr('Ignore Private Messages')
anchors.left: parent.left
anchors.top: prev.bottom
width: 180
margin-top: 5
CheckBox
id: checkboxIgnoreYelling
!text: tr('Ignore Yelling')
anchors.left: parent.left
anchors.top: prev.bottom
width: 180
margin-top: 5
CheckBox
id: checkboxUseWhiteList
!text: tr('Activate whitelist')
anchors.top: parent.top
anchors.left: ignoreList.right
margin-left: 20
width: 180
Label
!text: tr('Allowed Players:')
anchors.top: prev.bottom
anchors.left: prev.left
margin-top: 10
TextList
id: whiteList
vertical-scrollbar: whiteListScrollBar
anchors.left: prev.left
anchors.top: prev.bottom
height: 150
width: 230
margin-bottom: 10
margin-top: 3
padding: 1
focusable: false
TextEdit
id: whitelistNameEdit
anchors.top: prev.bottom
anchors.left: prev.left
width: 110
margin-top: 5
Button
id: buttonWhitelistAdd
!text: tr('Add')
width: 48
height: 20
margin-left: 5
anchors.top: prev.top
anchors.left: prev.right
Button
id: buttonWhitelistRemove
!text: tr('Remove')
width: 64
height: 20
margin-left: 5
anchors.top: prev.top
anchors.left: prev.right
Label
!text: tr('Global whitelist settings')
anchors.left: whiteList.left
anchors.top: prev.bottom
margin-top: 20
CheckBox
id: checkboxAllowVIPs
!text: tr('Allow VIPs to message you')
anchors.left: prev.left
anchors.top: prev.bottom
width: 180
margin-top: 5
Panel
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
height: 30
Panel
size: 160 30
anchors.horizontalCenter: parent.horizontalCenter
Button
id: buttonSave
!text: tr('Save')
width: 75
anchors.top: parent.top
anchors.left: parent.left
Button
id: buttonCancel
!text: tr('Cancel')
width: 75
anchors.top: parent.top
anchors.left: prev.right
margin-left: 10
VerticalScrollBar
id: ignoreListScrollBar
anchors.top: ignoreList.top
anchors.bottom: ignoreList.bottom
anchors.right: ignoreList.right
step: 14
pixels-scroll: true
VerticalScrollBar
id: whiteListScrollBar
anchors.top: whiteList.top
anchors.bottom: whiteList.bottom
anchors.right: whiteList.right
step: 14
pixels-scroll: true

View File

@@ -61,7 +61,7 @@ consoleTabBar = nil
consoleTextEdit = nil consoleTextEdit = nil
channels = nil channels = nil
channelsWindow = nil channelsWindow = nil
communicationWindow = nil ignoreWindow = nil
ownPrivateName = nil ownPrivateName = nil
messageHistory = {} messageHistory = {}
currentMessageIndex = 0 currentMessageIndex = 0
@@ -74,14 +74,10 @@ violationReportTab = nil
ignoredChannels = {} ignoredChannels = {}
filters = {} filters = {}
local communicationSettings = { local ignoreSettings = {
useIgnoreList = true,
useWhiteList = true,
privateMessages = false, privateMessages = false,
yelling = false, yelling = false,
allowVIPs = false, players = {}
ignoredPlayers = {},
whitelistedPlayers = {}
} }
function init() function init()
@@ -143,57 +139,8 @@ function init()
g_keyboard.bindKeyDown('Ctrl+O', g_game.requestChannels) g_keyboard.bindKeyDown('Ctrl+O', g_game.requestChannels)
g_keyboard.bindKeyDown('Ctrl+E', removeCurrentTab) g_keyboard.bindKeyDown('Ctrl+E', removeCurrentTab)
g_keyboard.bindKeyDown('Ctrl+H', openHelp) g_keyboard.bindKeyDown('Ctrl+H', openHelp)
consoleToggleChat = consolePanel:getChildById('toggleChat')
load()
end
function toggleChat()
if consoleToggleChat:isChecked() then
disableChat()
else
enableChat()
end
end
function enableChat()
local gameInterface = modules.game_interface
consoleTextEdit:setVisible(true)
consoleTextEdit:setText("")
g_keyboard.unbindKeyUp("Space")
g_keyboard.unbindKeyUp("Enter")
gameInterface.unbindWalkKey("W")
gameInterface.unbindWalkKey("D")
gameInterface.unbindWalkKey("S")
gameInterface.unbindWalkKey("A")
consoleToggleChat:setTooltip(tr("Disable chat mode, allow to walk using ASDW"))
end
function disableChat()
local gameInterface = modules.game_interface
consoleTextEdit:setVisible(false) load()
consoleTextEdit:setText("")
local quickFunc = function()
if consoleToggleChat:isChecked() then
consoleToggleChat:setChecked(false)
end
enableChat()
end
g_keyboard.bindKeyUp("Space", quickFunc)
g_keyboard.bindKeyUp("Enter", quickFunc)
gameInterface.bindWalkKey("W", North)
gameInterface.bindWalkKey("D", East)
gameInterface.bindWalkKey("S", South)
gameInterface.bindWalkKey("A", West)
consoleToggleChat:setTooltip(tr("Enable chat mode"))
end end
function terminate() function terminate()
@@ -219,14 +166,14 @@ function terminate()
g_keyboard.unbindKeyDown('Ctrl+E') g_keyboard.unbindKeyDown('Ctrl+E')
g_keyboard.unbindKeyDown('Ctrl+H') g_keyboard.unbindKeyDown('Ctrl+H')
saveCommunicationSettings() saveIgnoreSettings()
if channelsWindow then if channelsWindow then
channelsWindow:destroy() channelsWindow:destroy()
end end
if communicationWindow then if ignoreWindow then
communicationWindow:destroy() ignoreWindow:destroy()
end end
if violationWindow then if violationWindow then
@@ -250,7 +197,7 @@ function load()
if settings then if settings then
messageHistory = settings.messageHistory or {} messageHistory = settings.messageHistory or {}
end end
loadCommunicationSettings() loadIgnoreSettings()
end end
function onTabChange(tabBar, tab) function onTabChange(tabBar, tab)
@@ -519,7 +466,7 @@ function addTabText(text, speaktype, tab, creatureName)
-- Remove the curly braces -- Remove the curly braces
for i = 1, #highlightData / 3 do for i = 1, #highlightData / 3 do
local dataBlock = { _start = highlightData[(i-1)*3+1], _end = highlightData[(i-1)*3+2], words = highlightData[(i-1)*3+3] } local dataBlock = { _start = highlightData[(i-1)*3+1], _end = highlightData[(i-1)*3+2], words = highlightData[(i-1)*3+3] }
text = text:gsub("%{(.-)%}", dataBlock.words, 1) text = text:gsub("{"..dataBlock.words.."}", dataBlock.words)
-- Recalculate positions as braces are removed -- Recalculate positions as braces are removed
highlightData[(i-1)*3+1] = dataBlock._start - ((i-1) * 2) highlightData[(i-1)*3+1] = dataBlock._start - ((i-1) * 2)
@@ -832,11 +779,7 @@ function onTalk(name, level, mode, message, channelId, creaturePos)
return return
end end
local localPlayer = g_game.getLocalPlayer() if name ~= g_game.getCharacterName() then
if name ~= g_game.getCharacterName()
and isUsingIgnoreList()
and not(isUsingWhiteList()) or (isUsingWhiteList() and not(isWhitelisted(name)) and not(isAllowingVIPs() and localPlayer:hasVip(name))) then
if mode == MessageModes.Yell and isIgnoringYelling() then if mode == MessageModes.Yell and isIgnoringYelling() then
return return
elseif speaktype.private and isIgnoringPrivate() and mode ~= MessageModes.NpcFrom then elseif speaktype.private and isIgnoringPrivate() and mode ~= MessageModes.NpcFrom then
@@ -1014,221 +957,107 @@ function onChannelList(channelList)
end end
end end
function loadCommunicationSettings() function loadIgnoreSettings()
communicationSettings.whitelistedPlayers = {}
communicationSettings.ignoredPlayers = {}
local ignoreNode = g_settings.getNode('IgnorePlayers') local ignoreNode = g_settings.getNode('IgnorePlayers')
if ignoreNode then if ignoreNode then
for i = 1, #ignoreNode do for i = 1, #ignoreNode do
table.insert(communicationSettings.ignoredPlayers, ignoreNode[i]) table.insert(ignoreSettings.players, ignoreNode[i])
end end
end end
ignoreSettings.privateMessages = g_settings.getBoolean('IgnorePrivateMessages')
ignoreSettings.yelling = g_settings.getBoolean('IgnoreYelling')
end
local whitelistNode = g_settings.getNode('WhitelistedPlayers') function saveIgnoreSettings()
if whitelistNode then local tmpSettings = {}
for i = 1, #whitelistNode do for i = 1, #ignoreSettings.players do
table.insert(communicationSettings.whitelistedPlayers, whitelistNode[i]) table.insert(tmpSettings, ignoreSettings.players[i])
end
end end
g_settings.set('IgnorePrivateMessages', ignoreSettings.privateMessages)
communicationSettings.useIgnoreList = g_settings.getBoolean('UseIgnoreList') g_settings.set('IgnoreYelling', ignoreSettings.yelling)
communicationSettings.useWhiteList = g_settings.getBoolean('UseWhiteList') g_settings.setNode('IgnorePlayers', tmpSettings)
communicationSettings.privateMessages = g_settings.getBoolean('IgnorePrivateMessages')
communicationSettings.yelling = g_settings.getBoolean('IgnoreYelling')
communicationSettings.allowVIPs = g_settings.getBoolean('AllowVIPs')
end end
function saveCommunicationSettings()
local tmpIgnoreList = {}
local ignoredPlayers = getIgnoredPlayers()
for i = 1, #ignoredPlayers do
table.insert(tmpIgnoreList, ignoredPlayers[i])
end
local tmpWhiteList = {}
local whitelistedPlayers = getWhitelistedPlayers()
for i = 1, #whitelistedPlayers do
table.insert(tmpWhiteList, whitelistedPlayers[i])
end
g_settings.set('UseIgnoreList', communicationSettings.useIgnoreList)
g_settings.set('UseWhiteList', communicationSettings.useWhiteList)
g_settings.set('IgnorePrivateMessages', communicationSettings.privateMessages)
g_settings.set('IgnoreYelling', communicationSettings.yelling)
g_settings.setNode('IgnorePlayers', tmpIgnoreList)
g_settings.setNode('WhitelistedPlayers', tmpWhiteList)
end
function getIgnoredPlayers()
return communicationSettings.ignoredPlayers
end
function getWhitelistedPlayers()
return communicationSettings.whitelistedPlayers
end
function isUsingIgnoreList()
return communicationSettings.useIgnoreList
end
function isUsingWhiteList()
return communicationSettings.useWhiteList
end
function isIgnored(name) function isIgnored(name)
return table.find(communicationSettings.ignoredPlayers, name, true) return table.find(ignoreSettings.players, name, true)
end end
function addIgnoredPlayer(name) function addIgnoredPlayer(name)
if isIgnored(name) then return end if not isIgnored(name) then
table.insert(communicationSettings.ignoredPlayers, name) table.insert(ignoreSettings.players, name)
end
end end
function removeIgnoredPlayer(name) function removeIgnoredPlayer(name)
table.removevalue(communicationSettings.ignoredPlayers, name) table.removevalue(ignoreSettings.players, name)
end
function isWhitelisted(name)
return table.find(communicationSettings.whitelistedPlayers, name, true)
end
function addWhitelistedPlayer(name)
if isWhitelisted(name) then return end
table.insert(communicationSettings.whitelistedPlayers, name)
end
function removeWhitelistedPlayer(name)
table.removevalue(communicationSettings.whitelistedPlayers, name)
end end
function isIgnoringPrivate() function isIgnoringPrivate()
return communicationSettings.privateMessages return ignoreSettings.privateMessages
end end
function isIgnoringYelling() function isIgnoringYelling()
return communicationSettings.yelling return ignoreSettings.yelling
end
function isAllowingVIPs()
return communicationSettings.allowVIPs
end end
function onClickIgnoreButton() function onClickIgnoreButton()
if communicationWindow then return end if ignoreWindow then return end
communicationWindow = g_ui.displayUI('communicationwindow') ignoreWindow = g_ui.displayUI('ignorewindow')
local ignoreListPanel = communicationWindow:getChildById('ignoreList') local ignoreListPanel = ignoreWindow:getChildById('ignoreList')
local whiteListPanel = communicationWindow:getChildById('whiteList') ignoreWindow.onDestroy = function() ignoreWindow = nil end
communicationWindow.onDestroy = function() communicationWindow = nil end
local useIgnoreListBox = communicationWindow:getChildById('checkboxUseIgnoreList') local removeButton = ignoreWindow:getChildById('buttonRemove')
useIgnoreListBox:setChecked(communicationSettings.useIgnoreList) removeButton:disable()
local useWhiteListBox = communicationWindow:getChildById('checkboxUseWhiteList') ignoreListPanel.onChildFocusChange = function() removeButton:enable() end
useWhiteListBox:setChecked(communicationSettings.useWhiteList) removeButton.onClick = function()
local removeIgnoreButton = communicationWindow:getChildById('buttonIgnoreRemove')
removeIgnoreButton:disable()
ignoreListPanel.onChildFocusChange = function() removeIgnoreButton:enable() end
removeIgnoreButton.onClick = function()
local selection = ignoreListPanel:getFocusedChild() local selection = ignoreListPanel:getFocusedChild()
if selection then if selection then
ignoreListPanel:removeChild(selection) ignoreListPanel:removeChild(selection)
selection:destroy() selection:destroy()
end end
removeIgnoreButton:disable() if ignoreListPanel:getChildCount() == 0 then
end removeButton:disable()
local removeWhitelistButton = communicationWindow:getChildById('buttonWhitelistRemove')
removeWhitelistButton:disable()
whiteListPanel.onChildFocusChange = function() removeWhitelistButton:enable() end
removeWhitelistButton.onClick = function()
local selection = whiteListPanel:getFocusedChild()
if selection then
whiteListPanel:removeChild(selection)
selection:destroy()
end end
removeWhitelistButton:disable()
end end
local newlyIgnoredPlayers = {} local newlyIgnoredPlayers = {}
local addIgnoreName = communicationWindow:getChildById('ignoreNameEdit') local addName = ignoreWindow:getChildById('ignoreNameEdit')
local addIgnoreButton = communicationWindow:getChildById('buttonIgnoreAdd') local addButton = ignoreWindow:getChildById('buttonAdd')
local addIgnoreFunction = function() local addFunction = function()
local newEntry = addIgnoreName:getText() if addName:getText() == '' then return end
if newEntry == '' then return end if table.find(ignoreSettings.players, addName:getText()) then return end
if table.find(getIgnoredPlayers(), newEntry) then return end if table.find(newlyIgnoredPlayers, addName:getText()) then return end
if table.find(newlyIgnoredPlayers, newEntry) then return end local label = g_ui.createWidget('IgnoreListLabel', ignoreListPanel)
local label = g_ui.createWidget('IgnoreListLabel', ignoreListPanel) label:setText(addName:getText())
label:setText(newEntry) table.insert(newlyIgnoredPlayers, addName:getText())
table.insert(newlyIgnoredPlayers, newEntry) label:setPhantom(false)
addIgnoreName:setText('') addName:setText('')
end end
addIgnoreButton.onClick = addIgnoreFunction addButton.onClick = addFunction
ignoreWindow.onEnter = addFunction
local newlyWhitelistedPlayers = {}
local addWhitelistName = communicationWindow:getChildById('whitelistNameEdit')
local addWhitelistButton = communicationWindow:getChildById('buttonWhitelistAdd')
local addWhitelistFunction = function()
local newEntry = addWhitelistName:getText()
if newEntry == '' then return end
if table.find(getWhitelistedPlayers(), newEntry) then return end
if table.find(newlyWhitelistedPlayers, newEntry) then return end
local label = g_ui.createWidget('WhiteListLabel', whiteListPanel)
label:setText(newEntry)
table.insert(newlyWhitelistedPlayers, newEntry)
addWhitelistName:setText('')
end
addWhitelistButton.onClick = addWhitelistFunction
communicationWindow.onEnter = function()
if addWhitelistName:isFocused() then
addWhitelistFunction()
elseif addIgnoreName:isFocused() then
addIgnoreFunction()
end
end
local ignorePrivateMessageBox = communicationWindow:getChildById('checkboxIgnorePrivateMessages') local ignorePrivateMessageBox = ignoreWindow:getChildById('checkboxIgnorePrivateMessages')
ignorePrivateMessageBox:setChecked(communicationSettings.privateMessages) ignorePrivateMessageBox:setChecked(ignoreSettings.privateMessages)
local ignoreYellingBox = communicationWindow:getChildById('checkboxIgnoreYelling') local ignoreYellingBox = ignoreWindow:getChildById('checkboxIgnoreYelling')
ignoreYellingBox:setChecked(communicationSettings.yelling) ignoreYellingBox:setChecked(ignoreSettings.yelling)
local allowVIPsBox = communicationWindow:getChildById('checkboxAllowVIPs')
allowVIPsBox:setChecked(communicationSettings.allowVIPs)
local saveButton = communicationWindow:recursiveGetChildById('buttonSave') local saveButton = ignoreWindow:getChildById('buttonSave')
saveButton.onClick = function() saveButton.onClick = function()
communicationSettings.ignoredPlayers = {} ignoreSettings.players = {}
for i = 1, ignoreListPanel:getChildCount() do for i = 1, ignoreListPanel:getChildCount() do
addIgnoredPlayer(ignoreListPanel:getChildByIndex(i):getText()) addIgnoredPlayer(ignoreListPanel:getChildByIndex(i):getText())
end --table.insert(ignoreSettings.players, ignoreListPanel:getChildByIndex(i):getText())
end
communicationSettings.whitelistedPlayers = {}
for i = 1, whiteListPanel:getChildCount() do ignoreSettings.yelling = ignoreYellingBox:isChecked()
addWhitelistedPlayer(whiteListPanel:getChildByIndex(i):getText()) ignoreSettings.privateMessages = ignorePrivateMessageBox:isChecked()
end ignoreWindow:destroy()
end
communicationSettings.useIgnoreList = useIgnoreListBox:isChecked()
communicationSettings.useWhiteList = useWhiteListBox:isChecked()
communicationSettings.yelling = ignoreYellingBox:isChecked()
communicationSettings.privateMessages = ignorePrivateMessageBox:isChecked()
communicationSettings.allowVIPs = allowVIPsBox:isChecked()
communicationWindow:destroy()
end
local cancelButton = communicationWindow:recursiveGetChildById('buttonCancel')
cancelButton.onClick = function()
communicationWindow:destroy()
end
local ignoredPlayers = getIgnoredPlayers() for _, name in pairs(ignoreSettings.players) do
for i = 1, #ignoredPlayers do local label = g_ui.createWidget('IgnoreListLabel', ignoreListPanel)
local label = g_ui.createWidget('IgnoreListLabel', ignoreListPanel) label:setText(name)
label:setText(ignoredPlayers[i]) label:setPhantom(false)
end
local whitelistedPlayers = getWhitelistedPlayers()
for i = 1, #whitelistedPlayers do
local label = g_ui.createWidget('WhiteListLabel', whiteListPanel)
label:setText(whitelistedPlayers[i])
end end
end end
@@ -1260,4 +1089,4 @@ function offline()
g_keyboard.unbindKeyDown('Ctrl+R') g_keyboard.unbindKeyDown('Ctrl+R')
end end
clear() clear()
end end

View File

@@ -56,21 +56,12 @@ Panel
id: consolePanel id: consolePanel
anchors.fill: parent anchors.fill: parent
CheckBox
id: toggleChat
!tooltip: tr('Disable chat mode, allow to walk using ASDW')
anchors.left: parent.left
anchors.top: parent.top
margin-left: 13
margin-top: 8
@onCheckChange: toggleChat()
TabButton TabButton
id: prevChannelButton id: prevChannelButton
icon: /images/game/console/leftarrow icon: /images/game/console/leftarrow
anchors.left: toggleChat.right anchors.left: parent.left
anchors.top: parent.top anchors.top: parent.top
margin-left: 3 margin-left: 6
margin-top: 6 margin-top: 6
ConsoleTabBar ConsoleTabBar

View File

@@ -0,0 +1,98 @@
IgnoreListLabel < Label
font: verdana-11px-monochrome
background-color: alpha
text-offset: 2 0
focusable: true
$focus:
background-color: #ffffff22
color: #ffffff
MainWindow
id: ignoreWindow
!text: tr('Ignore List')
size: 500 240
@onEscape: self:destroy()
Label
!text: tr('Ignored players:')
anchors.left: parent.left
anchors.top: parent.top
TextList
id: ignoreList
vertical-scrollbar: ignoreListScrollBar
anchors.left: parent.left
anchors.top: prev.bottom
height: 150
width: 230
margin-bottom: 10
margin-top: 3
padding: 1
focusable: false
Button
id: buttonRemove
!text: tr('Remove')
width: 64
anchors.right: prev.right
anchors.bottom: parent.bottom
TextEdit
id: ignoreNameEdit
anchors.left: ignoreList.right
anchors.top: ignoreList.top
width: 180
margin-left: 8
margin-right: 3
Button
id: buttonAdd
!text: tr('Add')
width: 48
height: 20
anchors.right: parent.right
anchors.top: prev.top
CheckBox
id: checkboxIgnorePrivateMessages
!text: tr('Ignore Private Messages')
anchors.left: ignoreList.right
anchors.top: ignoreList.top
width: 180
margin-top: 25
margin-left: 8
CheckBox
id: checkboxIgnoreYelling
!text: tr('Ignore Yelling')
anchors.left: ignoreList.right
anchors.top: prev.top
width: 180
margin-top: 25
margin-left: 8
Button
id: buttonSave
!text: tr('Save')
width: 64
anchors.right: next.left
anchors.bottom: parent.bottom
margin-right: 10
@onClick: self:getParent():onEnter()
Button
id: buttonCancel
!text: tr('Cancel')
width: 64
anchors.right: parent.right
anchors.bottom: parent.bottom
@onClick: self:getParent():destroy()
VerticalScrollBar
id: ignoreListScrollBar
anchors.top: ignoreList.top
anchors.bottom: ignoreList.bottom
anchors.right: ignoreList.right
step: 14
pixels-scroll: true

View File

@@ -216,7 +216,6 @@ function save()
hotkeys[child.keyCombo] = { hotkeys[child.keyCombo] = {
autoSend = child.autoSend, autoSend = child.autoSend,
itemId = child.itemId, itemId = child.itemId,
subType = child.subType,
useType = child.useType, useType = child.useType,
value = child.value value = child.value
} }
@@ -267,9 +266,6 @@ function onChooseItemMouseRelease(self, mousePosition, mouseButton)
if item and currentHotkeyLabel then if item and currentHotkeyLabel then
currentHotkeyLabel.itemId = item:getId() currentHotkeyLabel.itemId = item:getId()
if item:isFluidContainer() then
currentHotkeyLabel.subType = item:getSubType()
end
if item:isMultiUse() then if item:isMultiUse() then
currentHotkeyLabel.useType = HOTKEY_MANAGER_USEWITH currentHotkeyLabel.useType = HOTKEY_MANAGER_USEWITH
else else
@@ -297,7 +293,6 @@ end
function clearObject() function clearObject()
currentHotkeyLabel.itemId = nil currentHotkeyLabel.itemId = nil
currentHotkeyLabel.subType = nil
currentHotkeyLabel.useType = nil currentHotkeyLabel.useType = nil
currentHotkeyLabel.autoSend = nil currentHotkeyLabel.autoSend = nil
currentHotkeyLabel.value = nil currentHotkeyLabel.value = nil
@@ -345,14 +340,12 @@ function addKeyCombo(keyCombo, keySettings, focus)
hotkeyLabel.keyCombo = keyCombo hotkeyLabel.keyCombo = keyCombo
hotkeyLabel.autoSend = toboolean(keySettings.autoSend) hotkeyLabel.autoSend = toboolean(keySettings.autoSend)
hotkeyLabel.itemId = tonumber(keySettings.itemId) hotkeyLabel.itemId = tonumber(keySettings.itemId)
hotkeyLabel.subType = tonumber(keySettings.subType)
hotkeyLabel.useType = tonumber(keySettings.useType) hotkeyLabel.useType = tonumber(keySettings.useType)
if keySettings.value then hotkeyLabel.value = tostring(keySettings.value) end if keySettings.value then hotkeyLabel.value = tostring(keySettings.value) end
else else
hotkeyLabel.keyCombo = keyCombo hotkeyLabel.keyCombo = keyCombo
hotkeyLabel.autoSend = false hotkeyLabel.autoSend = false
hotkeyLabel.itemId = nil hotkeyLabel.itemId = nil
hotkeyLabel.subType = nil
hotkeyLabel.useType = nil hotkeyLabel.useType = nil
hotkeyLabel.value = '' hotkeyLabel.value = ''
end end
@@ -382,42 +375,15 @@ function doKeyCombo(keyCombo)
modules.game_console.setTextEditText(hotKey.value) modules.game_console.setTextEditText(hotKey.value)
end end
elseif hotKey.useType == HOTKEY_MANAGER_USE then elseif hotKey.useType == HOTKEY_MANAGER_USE then
if g_game.getProtocolVersion() < 780 or hotKey.subType then g_game.useInventoryItem(hotKey.itemId)
local item = g_game.findPlayerItem(hotKey.itemId, hotKey.subType or -1)
if item then
g_game.use(item)
end
else
g_game.useInventoryItem(hotKey.itemId)
end
elseif hotKey.useType == HOTKEY_MANAGER_USEONSELF then elseif hotKey.useType == HOTKEY_MANAGER_USEONSELF then
if g_game.getProtocolVersion() < 780 or hotKey.subType then g_game.useInventoryItemWith(hotKey.itemId, g_game.getLocalPlayer())
local item = g_game.findPlayerItem(hotKey.itemId, hotKey.subType or -1)
if item then
g_game.useWith(item, g_game.getLocalPlayer())
end
else
g_game.useInventoryItemWith(hotKey.itemId, g_game.getLocalPlayer())
end
elseif hotKey.useType == HOTKEY_MANAGER_USEONTARGET then elseif hotKey.useType == HOTKEY_MANAGER_USEONTARGET then
local attackingCreature = g_game.getAttackingCreature() local attackingCreature = g_game.getAttackingCreature()
if not attackingCreature then return end if not attackingCreature then return end
if not attackingCreature:getTile() then return end g_game.useInventoryItemWith(hotKey.itemId, attackingCreature)
if g_game.getProtocolVersion() < 780 or hotKey.subType then
local item = g_game.findPlayerItem(hotKey.itemId, hotKey.subType or -1)
if item then
g_game.useWith(item, attackingCreature)
end
else
g_game.useInventoryItemWith(hotKey.itemId, attackingCreature)
end
elseif hotKey.useType == HOTKEY_MANAGER_USEWITH then elseif hotKey.useType == HOTKEY_MANAGER_USEWITH then
local item = Item.create(hotKey.itemId) local item = Item.create(hotKey.itemId)
if g_game.getProtocolVersion() < 780 or hotKey.subType then
local tmpItem = g_game.findPlayerItem(hotKey.itemId, hotKey.subType or -1)
if not tmpItem then return true end
item = tmpItem
end
modules.game_interface.startUseWith(item) modules.game_interface.startUseWith(item)
end end
end end
@@ -462,9 +428,6 @@ function updateHotkeyForm(reset)
selectObjectButton:disable() selectObjectButton:disable()
clearObjectButton:enable() clearObjectButton:enable()
currentItemPreview:setItemId(currentHotkeyLabel.itemId) currentItemPreview:setItemId(currentHotkeyLabel.itemId)
if currentHotkeyLabel.subType then
currentItemPreview:setItemSubType(currentHotkeyLabel.subType)
end
if currentItemPreview:getItem():isMultiUse() then if currentItemPreview:getItem():isMultiUse() then
useOnSelf:enable() useOnSelf:enable()
useOnTarget:enable() useOnTarget:enable()

View File

@@ -11,7 +11,7 @@ countWindow = nil
logoutWindow = nil logoutWindow = nil
exitWindow = nil exitWindow = nil
bottomSplitter = nil bottomSplitter = nil
limitedZoom = false limitZoom = false
currentViewMode = 0 currentViewMode = 0
smartWalkDirs = {} smartWalkDirs = {}
smartWalkDir = nil smartWalkDir = nil
@@ -42,8 +42,7 @@ function init()
gameBottomPanel = gameRootPanel:getChildById('gameBottomPanel') gameBottomPanel = gameRootPanel:getChildById('gameBottomPanel')
connect(gameLeftPanel, { onVisibilityChange = onLeftPanelVisibilityChange }) connect(gameLeftPanel, { onVisibilityChange = onLeftPanelVisibilityChange })
logoutButton = modules.client_topmenu.addLeftButton('logoutButton', tr('Exit'), logoutButton = modules.client_topmenu.addLeftButton('logoutButton', tr('Exit'), '/images/topbuttons/logout', tryLogout, true)
'/images/topbuttons/logout', tryLogout, true)
setupViewMode(0) setupViewMode(0)
@@ -57,19 +56,42 @@ end
function bindKeys() function bindKeys()
gameRootPanel:setAutoRepeatDelay(250) gameRootPanel:setAutoRepeatDelay(250)
g_keyboard.bindKeyDown('Up', function() changeWalkDir(North) end, gameRootPanel, true)
bindWalkKey('Up', North) g_keyboard.bindKeyDown('Right', function() changeWalkDir(East) end, gameRootPanel, true)
bindWalkKey('Right', East) g_keyboard.bindKeyDown('Down', function() changeWalkDir(South) end, gameRootPanel, true)
bindWalkKey('Down', South) g_keyboard.bindKeyDown('Left', function() changeWalkDir(West) end, gameRootPanel, true)
bindWalkKey('Left', West) g_keyboard.bindKeyDown('Numpad8', function() changeWalkDir(North) end, gameRootPanel, true)
bindWalkKey('Numpad8', North) g_keyboard.bindKeyDown('Numpad9', function() changeWalkDir(NorthEast) end, gameRootPanel, true)
bindWalkKey('Numpad9', NorthEast) g_keyboard.bindKeyDown('Numpad6', function() changeWalkDir(East) end, gameRootPanel, true)
bindWalkKey('Numpad6', East) g_keyboard.bindKeyDown('Numpad3', function() changeWalkDir(SouthEast) end, gameRootPanel, true)
bindWalkKey('Numpad3', SouthEast) g_keyboard.bindKeyDown('Numpad2', function() changeWalkDir(South) end, gameRootPanel, true)
bindWalkKey('Numpad2', South) g_keyboard.bindKeyDown('Numpad1', function() changeWalkDir(SouthWest) end, gameRootPanel, true)
bindWalkKey('Numpad1', SouthWest) g_keyboard.bindKeyDown('Numpad4', function() changeWalkDir(West) end, gameRootPanel, true)
bindWalkKey('Numpad4', West) g_keyboard.bindKeyDown('Numpad7', function() changeWalkDir(NorthWest) end, gameRootPanel, true)
bindWalkKey('Numpad7', NorthWest) g_keyboard.bindKeyUp('Up', function() changeWalkDir(North, true) end, gameRootPanel, true)
g_keyboard.bindKeyUp('Right', function() changeWalkDir(East, true) end, gameRootPanel, true)
g_keyboard.bindKeyUp('Down', function() changeWalkDir(South, true) end, gameRootPanel, true)
g_keyboard.bindKeyUp('Left', function() changeWalkDir(West, true) end, gameRootPanel, true)
g_keyboard.bindKeyUp('Numpad8', function() changeWalkDir(North, true) end, gameRootPanel, true)
g_keyboard.bindKeyUp('Numpad9', function() changeWalkDir(NorthEast, true) end, gameRootPanel, true)
g_keyboard.bindKeyUp('Numpad6', function() changeWalkDir(East, true) end, gameRootPanel, true)
g_keyboard.bindKeyUp('Numpad3', function() changeWalkDir(SouthEast, true) end, gameRootPanel, true)
g_keyboard.bindKeyUp('Numpad2', function() changeWalkDir(South, true) end, gameRootPanel, true)
g_keyboard.bindKeyUp('Numpad1', function() changeWalkDir(SouthWest, true) end, gameRootPanel, true)
g_keyboard.bindKeyUp('Numpad4', function() changeWalkDir(West, true) end, gameRootPanel, true)
g_keyboard.bindKeyUp('Numpad7', function() changeWalkDir(NorthWest, true) end, gameRootPanel, true)
g_keyboard.bindKeyPress('Up', function() smartWalk(North) end, gameRootPanel)
g_keyboard.bindKeyPress('Right', function() smartWalk(East) end, gameRootPanel)
g_keyboard.bindKeyPress('Down', function() smartWalk(South) end, gameRootPanel)
g_keyboard.bindKeyPress('Left', function() smartWalk(West) end, gameRootPanel)
g_keyboard.bindKeyPress('Numpad8', function() smartWalk(North) end, gameRootPanel)
g_keyboard.bindKeyPress('Numpad9', function() smartWalk(NorthEast) end, gameRootPanel)
g_keyboard.bindKeyPress('Numpad6', function() smartWalk(East) end, gameRootPanel)
g_keyboard.bindKeyPress('Numpad3', function() smartWalk(SouthEast) end, gameRootPanel)
g_keyboard.bindKeyPress('Numpad2', function() smartWalk(South) end, gameRootPanel)
g_keyboard.bindKeyPress('Numpad1', function() smartWalk(SouthWest) end, gameRootPanel)
g_keyboard.bindKeyPress('Numpad4', function() smartWalk(West) end, gameRootPanel)
g_keyboard.bindKeyPress('Numpad7', function() smartWalk(NorthWest) end, gameRootPanel)
g_keyboard.bindKeyPress('Ctrl+Up', function() g_game.turn(North) changeWalkDir(North) end, gameRootPanel) g_keyboard.bindKeyPress('Ctrl+Up', function() g_game.turn(North) changeWalkDir(North) end, gameRootPanel)
g_keyboard.bindKeyPress('Ctrl+Right', function() g_game.turn(East) changeWalkDir(East) end, gameRootPanel) g_keyboard.bindKeyPress('Ctrl+Right', function() g_game.turn(East) changeWalkDir(East) end, gameRootPanel)
@@ -82,24 +104,12 @@ function bindKeys()
g_keyboard.bindKeyPress('Escape', function() g_game.cancelAttackAndFollow() end, gameRootPanel) g_keyboard.bindKeyPress('Escape', function() g_game.cancelAttackAndFollow() end, gameRootPanel)
g_keyboard.bindKeyPress('Ctrl+=', function() gameMapPanel:zoomIn() end, gameRootPanel) g_keyboard.bindKeyPress('Ctrl+=', function() gameMapPanel:zoomIn() end, gameRootPanel)
g_keyboard.bindKeyPress('Ctrl+-', function() gameMapPanel:zoomOut() end, gameRootPanel) g_keyboard.bindKeyPress('Ctrl+-', function() gameMapPanel:zoomOut() end, gameRootPanel)
g_keyboard.bindKeyDown('Ctrl+Q', function() tryLogout(false) end, gameRootPanel) g_keyboard.bindKeyDown('Ctrl+Q', logout, gameRootPanel)
g_keyboard.bindKeyDown('Ctrl+L', function() tryLogout(false) end, gameRootPanel) g_keyboard.bindKeyDown('Ctrl+L', logout, gameRootPanel)
g_keyboard.bindKeyDown('Ctrl+W', function() g_map.cleanTexts() modules.game_textmessage.clearMessages() end, gameRootPanel) g_keyboard.bindKeyDown('Ctrl+W', function() g_map.cleanTexts() modules.game_textmessage.clearMessages() end, gameRootPanel)
g_keyboard.bindKeyDown('Ctrl+.', nextViewMode, gameRootPanel) g_keyboard.bindKeyDown('Ctrl+.', nextViewMode, gameRootPanel)
end end
function bindWalkKey(key, dir)
g_keyboard.bindKeyDown(key, function() changeWalkDir(dir) end, gameRootPanel, true)
g_keyboard.bindKeyUp(key, function() changeWalkDir(dir, true) end, gameRootPanel, true)
g_keyboard.bindKeyPress(key, function() smartWalk(dir) end, gameRootPanel)
end
function unbindWalkKey(key)
g_keyboard.unbindKeyDown(key, gameRootPanel)
g_keyboard.unbindKeyUp(key, gameRootPanel)
g_keyboard.unbindKeyPress(key, gameRootPanel)
end
function terminate() function terminate()
save() save()
hide() hide()
@@ -127,6 +137,16 @@ function onGameStart()
else else
g_game.disableFeature(GameForceFirstAutoWalkStep) g_game.disableFeature(GameForceFirstAutoWalkStep)
end end
addEvent(function()
if not limitZoom or g_game.isGM() then
gameMapPanel:setMaxZoomOut(513)
gameMapPanel:setLimitVisibleRange(false)
else
gameMapPanel:setMaxZoomOut(11)
gameMapPanel:setLimitVisibleRange(true)
end
end)
end end
function onGameEnd() function onGameEnd()
@@ -143,16 +163,6 @@ function show()
setupViewMode(0) setupViewMode(0)
updateStretchShrink() updateStretchShrink()
logoutButton:setTooltip(tr('Logout')) logoutButton:setTooltip(tr('Logout'))
addEvent(function()
if not limitedZoom or g_game.isGM() then
gameMapPanel:setMaxZoomOut(513)
gameMapPanel:setLimitVisibleRange(false)
else
gameMapPanel:setMaxZoomOut(11)
gameMapPanel:setLimitVisibleRange(true)
end
end)
end end
function hide() function hide()
@@ -205,8 +215,8 @@ function tryExit()
return true return true
end end
local exitFunc = function() g_game.safeLogout() forceExit() end local exitFunc = function() logout() forceExit() end
local logoutFunc = function() g_game.safeLogout() exitWindow:destroy() exitWindow = nil end local logoutFunc = function() logout() exitWindow:destroy() exitWindow = nil end
local cancelFunc = function() exitWindow:destroy() exitWindow = nil end local cancelFunc = function() exitWindow:destroy() exitWindow = nil end
exitWindow = displayGeneralBox(tr('Exit'), tr("If you shut down the program, your character might stay in the game.\nClick on 'Logout' to ensure that you character leaves the game properly.\nClick on 'Exit' if you want to exit the program without logging out your character."), exitWindow = displayGeneralBox(tr('Exit'), tr("If you shut down the program, your character might stay in the game.\nClick on 'Logout' to ensure that you character leaves the game properly.\nClick on 'Exit' if you want to exit the program without logging out your character."),
@@ -218,10 +228,14 @@ function tryExit()
return true return true
end end
function tryLogout(prompt) function logout()
if type(prompt) ~= "boolean" then if g_game.isOnline() then
prompt = true g_game.safeLogout()
return true
end end
end
function tryLogout()
if not g_game.isOnline() then if not g_game.isOnline() then
exit() exit()
return return
@@ -231,42 +245,13 @@ function tryLogout(prompt)
return return
end end
local msg, yesCallback local yesCallback = function() logout() logoutWindow:destroy() logoutWindow=nil end
if not g_game.isConnectionOk() then local noCallback = function() logoutWindow:destroy() logoutWindow=nil end
msg = 'Your connection is failing, if you logout now your character will be still online, do you want to force logout?'
yesCallback = function() logoutWindow = displayGeneralBox(tr('Logout'), tr('Are you sure you want to logout?'), {
g_game.forceLogout() { text=tr('Yes'), callback=yesCallback },
if logoutWindow then { text=tr('No'), callback=noCallback },
logoutWindow:destroy() anchor=AnchorHorizontalCenter}, yesCallback, noCallback)
logoutWindow=nil
end
end
else
msg = 'Are you sure you want to logout?'
yesCallback = function()
g_game.safeLogout()
if logoutWindow then
logoutWindow:destroy()
logoutWindow=nil
end
end
end
local noCallback = function()
logoutWindow:destroy()
logoutWindow=nil
end
if prompt then
logoutWindow = displayGeneralBox(tr('Logout'), tr(msg), {
{ text=tr('Yes'), callback=yesCallback },
{ text=tr('No'), callback=noCallback },
anchor=AnchorHorizontalCenter}, yesCallback, noCallback)
else
yesCallback()
end
end end
function stopSmartWalk() function stopSmartWalk()
@@ -478,20 +463,17 @@ function createThingMenu(menuPosition, lookThing, useThing, creatureThing)
end end
else else
local localPosition = localPlayer:getPosition()
if not classic then shortcut = '(Alt)' else shortcut = nil end if not classic then shortcut = '(Alt)' else shortcut = nil end
if creatureThing:getPosition().z == localPosition.z then if g_game.getAttackingCreature() ~= creatureThing then
if g_game.getAttackingCreature() ~= creatureThing then menu:addOption(tr('Attack'), function() g_game.attack(creatureThing) end, shortcut)
menu:addOption(tr('Attack'), function() g_game.attack(creatureThing) end, shortcut) else
else menu:addOption(tr('Stop Attack'), function() g_game.cancelAttack() end, shortcut)
menu:addOption(tr('Stop Attack'), function() g_game.cancelAttack() end, shortcut) end
end
if g_game.getFollowingCreature() ~= creatureThing then
if g_game.getFollowingCreature() ~= creatureThing then menu:addOption(tr('Follow'), function() g_game.follow(creatureThing) end)
menu:addOption(tr('Follow'), function() g_game.follow(creatureThing) end) else
else menu:addOption(tr('Stop Follow'), function() g_game.cancelFollow() end)
menu:addOption(tr('Stop Follow'), function() g_game.cancelFollow() end)
end
end end
if creatureThing:isPlayer() then if creatureThing:isPlayer() then
@@ -537,7 +519,7 @@ function createThingMenu(menuPosition, lookThing, useThing, creatureThing)
end end
end end
if modules.game_ruleviolation.hasWindowAccess() and creatureThing:isPlayer() then if modules.game_ruleviolation.hasWindowAccess() then
menu:addSeparator() menu:addSeparator()
menu:addOption(tr('Rule Violation'), function() modules.game_ruleviolation.show(creatureThing:getName()) end) menu:addOption(tr('Rule Violation'), function() modules.game_ruleviolation.show(creatureThing:getName()) end)
end end
@@ -549,7 +531,7 @@ function createThingMenu(menuPosition, lookThing, useThing, creatureThing)
menu:display(menuPosition) menu:display(menuPosition)
end end
function processMouseAction(menuPosition, mouseButton, autoWalkPos, lookThing, useThing, creatureThing, attackCreature) function processMouseAction(menuPosition, mouseButton, autoWalkPos, lookThing, useThing, creatureThing)
local keyboardModifiers = g_keyboard.getModifiers() local keyboardModifiers = g_keyboard.getModifiers()
if not modules.client_options.getOption('classicControl') then if not modules.client_options.getOption('classicControl') then
@@ -575,10 +557,7 @@ function processMouseAction(menuPosition, mouseButton, autoWalkPos, lookThing, u
return true return true
end end
return true return true
elseif attackCreature and g_keyboard.isAltPressed() and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then elseif creatureThing and g_keyboard.isAltPressed() and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then
g_game.attack(attackCreature)
return true
elseif creatureThing and creatureThing:getPosition().z == autoWalkPos.z and g_keyboard.isAltPressed() and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then
g_game.attack(creatureThing) g_game.attack(creatureThing)
return true return true
end end
@@ -587,10 +566,7 @@ function processMouseAction(menuPosition, mouseButton, autoWalkPos, lookThing, u
else else
if useThing and keyboardModifiers == KeyboardNoModifier and mouseButton == MouseRightButton and not g_mouse.isPressed(MouseLeftButton) then if useThing and keyboardModifiers == KeyboardNoModifier and mouseButton == MouseRightButton and not g_mouse.isPressed(MouseLeftButton) then
local player = g_game.getLocalPlayer() local player = g_game.getLocalPlayer()
if attackCreature and attackCreature ~= player then if creatureThing and creatureThing ~= player then
g_game.attack(attackCreature)
return true
elseif creatureThing and creatureThing ~= player and creatureThing:getPosition().z == autoWalkPos.z then
g_game.attack(creatureThing) g_game.attack(creatureThing)
return true return true
elseif useThing:isContainer() then elseif useThing:isContainer() then
@@ -618,10 +594,7 @@ function processMouseAction(menuPosition, mouseButton, autoWalkPos, lookThing, u
elseif useThing and keyboardModifiers == KeyboardCtrlModifier and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then elseif useThing and keyboardModifiers == KeyboardCtrlModifier and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then
createThingMenu(menuPosition, lookThing, useThing, creatureThing) createThingMenu(menuPosition, lookThing, useThing, creatureThing)
return true return true
elseif attackCreature and g_keyboard.isAltPressed() and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then elseif creatureThing and g_keyboard.isAltPressed() and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then
g_game.attack(attackCreature)
return true
elseif creatureThing and creatureThing:getPosition().z == autoWalkPos.z and g_keyboard.isAltPressed() and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then
g_game.attack(creatureThing) g_game.attack(creatureThing)
return true return true
end end
@@ -682,8 +655,6 @@ function moveStackableItem(item, toPos)
end end
g_keyboard.bindKeyPress("Up", function() check() spinbox:up() end, spinbox) g_keyboard.bindKeyPress("Up", function() check() spinbox:up() end, spinbox)
g_keyboard.bindKeyPress("Down", function() check() spinbox:down() end, spinbox) g_keyboard.bindKeyPress("Down", function() check() spinbox:down() end, spinbox)
g_keyboard.bindKeyPress("Right", function() check() spinbox:up() end, spinbox)
g_keyboard.bindKeyPress("Left", function() check() spinbox:down() end, spinbox)
g_keyboard.bindKeyPress("PageUp", function() check() spinbox:setValue(spinbox:getValue()+10) end, spinbox) g_keyboard.bindKeyPress("PageUp", function() check() spinbox:setValue(spinbox:getValue()+10) end, spinbox)
g_keyboard.bindKeyPress("PageDown", function() check() spinbox:setValue(spinbox:getValue()-10) end, spinbox) g_keyboard.bindKeyPress("PageDown", function() check() spinbox:setValue(spinbox:getValue()-10) end, spinbox)
@@ -775,7 +746,8 @@ function setupViewMode(mode)
gameMapPanel:setZoom(11) gameMapPanel:setZoom(11)
gameMapPanel:setVisibleDimension({ width = 15, height = 11 }) gameMapPanel:setVisibleDimension({ width = 15, height = 11 })
elseif mode == 2 then elseif mode == 2 then
local limit = limitedZoom and not g_game.isGM() local limit = limitZoom and not g_game.isGM()
gameMapPanel:setKeepAspectRatio(false)
gameMapPanel:setLimitVisibleRange(limit) gameMapPanel:setLimitVisibleRange(limit)
gameMapPanel:setZoom(11) gameMapPanel:setZoom(11)
gameMapPanel:setVisibleDimension({ width = 15, height = 11 }) gameMapPanel:setVisibleDimension({ width = 15, height = 11 })
@@ -800,5 +772,5 @@ function setupViewMode(mode)
end end
function limitZoom() function limitZoom()
limitedZoom = true limitZoom = true
end end

View File

@@ -6,11 +6,11 @@ CountWindow < MainWindow
SpinBox SpinBox
id: spinBox id: spinBox
anchors.left: parent.left anchors.left: parent.left
anchors.top: parent.top anchors.top: parent.bottom
width: 1 width: 0
height: 1 height: 0
phantom: true phantom: true
margin-top: 2 padding-bottom: -40
focusable: true focusable: true
Item Item

View File

@@ -78,21 +78,15 @@ function UIGameMap:onMouseRelease(mousePosition, mouseButton)
local useThing local useThing
local creatureThing local creatureThing
local multiUseThing local multiUseThing
local attackCreature
local tile = self:getTile(mousePosition) local tile = self:getTile(mousePosition)
if tile then if tile then
lookThing = tile:getTopLookThing() lookThing = tile:getTopLookThing()
useThing = tile:getTopUseThing() useThing = tile:getTopUseThing()
creatureThing = tile:getTopCreature() creatureThing = tile:getTopCreature()
end
local autoWalkTile = g_map.getTile(autoWalkPos)
if autoWalkTile then
attackCreature = autoWalkTile:getTopCreature()
end end
local ret = modules.game_interface.processMouseAction(mousePosition, mouseButton, autoWalkPos, lookThing, useThing, creatureThing, attackCreature) local ret = modules.game_interface.processMouseAction(mousePosition, mouseButton, autoWalkPos, lookThing, useThing, creatureThing)
if ret then if ret then
self.allowNextRelease = false self.allowNextRelease = false
end end

View File

@@ -86,7 +86,7 @@ function UIItem:onMouseRelease(mousePosition, mouseButton)
g_game.look(item) g_game.look(item)
self.cancelNextRelease = true self.cancelNextRelease = true
return true return true
elseif modules.game_interface.processMouseAction(mousePosition, mouseButton, nil, item, item, nil, nil) then elseif modules.game_interface.processMouseAction(mousePosition, mouseButton, nil, item, item, nil, item) then
return true return true
end end
return false return false

View File

@@ -151,7 +151,8 @@ function onTradeTypeChange(radioTabs, selected, deselected)
ignoreCapacity:setVisible(currentTradeType == BUY) ignoreCapacity:setVisible(currentTradeType == BUY)
ignoreEquipped:setVisible(currentTradeType == SELL) ignoreEquipped:setVisible(currentTradeType == SELL)
showAllItems:setVisible(currentTradeType == SELL) showAllItems:setVisible(currentTradeType == SELL)
sellAllButton:setVisible(currentTradeType == SELL) sellAllButton:setVisible(false)
--sellAllButton:setVisible(currentTradeType == SELL)
refreshTradeItems() refreshTradeItems()
refreshPlayerGoods() refreshPlayerGoods()

View File

@@ -252,6 +252,7 @@ MainWindow
margin-right: 10 margin-right: 10
visible: false visible: false
@onClick: modules.game_npctrade.sellAll() @onClick: modules.game_npctrade.sellAll()
visible: false
Button Button
id: tradeButton id: tradeButton

View File

@@ -17,7 +17,6 @@ end
function reset() function reset()
if deathWindow then if deathWindow then
deathWindow:destroy() deathWindow:destroy()
deathWindow = nil
end end
end end
@@ -48,7 +47,7 @@ function openWindow()
deathWindow = nil deathWindow = nil
end end
local cancelFunc = function() local cancelFunc = function()
g_game.safeLogout() modules.game_interface.logout()
cancelButton:getParent():destroy() cancelButton:getParent():destroy()
deathWindow = nil deathWindow = nil
end end

View File

@@ -28,8 +28,6 @@ MessageTypes = {
[MessageModes.Blue] = MessageSettings.consoleBlue, [MessageModes.Blue] = MessageSettings.consoleBlue,
[MessageModes.PrivateFrom] = MessageSettings.consoleBlue, [MessageModes.PrivateFrom] = MessageSettings.consoleBlue,
[MessageModes.GamemasterBroadcast] = MessageSettings.consoleRed,
[MessageModes.DamageDealed] = MessageSettings.status, [MessageModes.DamageDealed] = MessageSettings.status,
[MessageModes.DamageReceived] = MessageSettings.status, [MessageModes.DamageReceived] = MessageSettings.status,
[MessageModes.Heal] = MessageSettings.status, [MessageModes.Heal] = MessageSettings.status,

View File

@@ -18,7 +18,7 @@ function isLoaded()
end end
function load() function load()
local version = g_game.getClientVersion() local version = g_game.getProtocolVersion()
local datPath, sprPath local datPath, sprPath
if filename then if filename then

View File

@@ -88,23 +88,6 @@ function isHiddingOffline()
return settings['hideOffline'] return settings['hideOffline']
end end
function getSortedBy()
local settings = g_settings.getNode('VipList')
if not settings then
return 'status'
end
return settings['sortedBy']
end
function sortBy(state)
settings = {}
settings['sortedBy'] = state
g_settings.mergeNode('VipList', settings)
refresh()
end
function onAddVip(id, name, state) function onAddVip(id, name, state)
local vipList = vipWindow:getChildById('contentsPanel') local vipList = vipWindow:getChildById('contentsPanel')
@@ -135,13 +118,13 @@ function onAddVip(id, name, state)
for i=1,childrenCount do for i=1,childrenCount do
local child = vipList:getChildByIndex(i) local child = vipList:getChildByIndex(i)
if state == VipState.Online and child.vipState ~= VipState.Online and getSortedBy() == 'status' then if state == VipState.Online and child.vipState ~= VipState.Online then
vipList:insertChild(i, label) vipList:insertChild(i, label)
return return
end end
if ((state ~= VipState.Online and child.vipState ~= VipState.Online) if (state ~= VipState.Online and child.vipState ~= VipState.Online)
or (state == VipState.Online and child.vipState == VipState.Online)) or getSortedBy() == 'name' then or (state == VipState.Online and child.vipState == VipState.Online) then
local childText = child:getText():lower() local childText = child:getText():lower()
local length = math.min(childText:len(), nameLower:len()) local length = math.min(childText:len(), nameLower:len())
@@ -184,14 +167,6 @@ function onVipListMousePress(widget, mousePos, mouseButton)
else else
menu:addOption(tr('Show Offline'), function() hideOffline(false) end) menu:addOption(tr('Show Offline'), function() hideOffline(false) end)
end end
if not(getSortedBy() == 'name') then
menu:addOption(tr('Sort by name'), function() sortBy('name') end)
end
if not(getSortedBy() == 'status') then
menu:addOption(tr('Sort by status'), function() sortBy('status') end)
end
menu:display(mousePos) menu:display(mousePos)
@@ -221,15 +196,6 @@ function onVipListLabelMousePress(widget, mousePos, mouseButton)
else else
menu:addOption(tr('Show Offline'), function() hideOffline(false) end) menu:addOption(tr('Show Offline'), function() hideOffline(false) end)
end end
if not(getSortedBy() == 'name') then
menu:addOption(tr('Sort by name'), function() sortBy('name') end)
end
if not(getSortedBy() == 'status') then
menu:addOption(tr('Sort by status'), function() sortBy('status') end)
end
menu:display(mousePos) menu:display(mousePos)
return true return true

View File

@@ -22,14 +22,11 @@ ShieldBlueNoSharedExpBlink = 7
ShieldYellowNoSharedExpBlink = 8 ShieldYellowNoSharedExpBlink = 8
ShieldBlueNoSharedExp = 9 ShieldBlueNoSharedExp = 9
ShieldYellowNoSharedExp = 10 ShieldYellowNoSharedExp = 10
ShieldGray = 11
EmblemNone = 0 EmblemNone = 0
EmblemGreen = 1 EmblemGreen = 1
EmblemRed = 2 EmblemRed = 2
EmblemBlue = 3 EmblemBlue = 3
EmblemMember = 4
EmblemOther = 5
North = 0 North = 0
East = 1 East = 1
@@ -84,16 +81,6 @@ GameNewSpeedLaw = 36
GameForceFirstAutoWalkStep = 37 GameForceFirstAutoWalkStep = 37
GameMinimapRemove = 38 GameMinimapRemove = 38
GameDoubleShopSellAmount = 39 GameDoubleShopSellAmount = 39
GameContainerPagination = 40
GameThingMarks = 41
GameLooktypeU16 = 42
GamePlayerStamina = 43
GamePlayerAddons = 44
GameMessageStatements = 45
GameMesssageLevel = 46
GameNewFluids = 47
GamePlayerStateU16 = 48
GameNewOutfitProtocol = 49
TextColors = { TextColors = {
red = '#f55e5e', --'#c83200' red = '#f55e5e', --'#c83200'
@@ -175,7 +162,7 @@ CIPSOFT_RSA = "1321277432058722840622950990822933849527763264961655079678763618"
"88792221429527047321331896351555606801473202394175817" "88792221429527047321331896351555606801473202394175817"
-- set to the latest Tibia.pic signature to make otclient compatible with official tibia -- set to the latest Tibia.pic signature to make otclient compatible with official tibia
PIC_SIGNATURE = 0x52131b61 PIC_SIGNATURE = 0x50a6469d
OsTypes = { OsTypes = {
Linux = 1, Linux = 1,

View File

@@ -52,25 +52,23 @@ function getShieldImagePathAndBlink(shieldId)
if shieldId == ShieldWhiteYellow then if shieldId == ShieldWhiteYellow then
path, blink = '/images/game/shields/shield_yellow_white', false path, blink = '/images/game/shields/shield_yellow_white', false
elseif shieldId == ShieldWhiteBlue then elseif shieldId == ShieldWhiteBlue then
path, blink = '/images/game/shields/shield_blue_white', false path, blink = '/images/game/shields//shield_blue_white', false
elseif shieldId == ShieldBlue then elseif shieldId == ShieldBlue then
path, blink = '/images/game/shields/shield_blue', false path, blink = '/images/game/shields//shield_blue', false
elseif shieldId == ShieldYellow then elseif shieldId == ShieldYellow then
path, blink = '/images/game/shields/shield_yellow', false path, blink = '/images/game/shields//shield_yellow', false
elseif shieldId == ShieldBlueSharedExp then elseif shieldId == ShieldBlueSharedExp then
path, blink = '/images/game/shields/shield_blue_shared', false path, blink = '/images/game/shields//shield_blue_shared', false
elseif shieldId == ShieldYellowSharedExp then elseif shieldId == ShieldYellowSharedExp then
path, blink = '/images/game/shields/shield_yellow_shared', false path, blink = '/images/game/shields//shield_yellow_shared', false
elseif shieldId == ShieldBlueNoSharedExpBlink then elseif shieldId == ShieldBlueNoSharedExpBlink then
path, blink = '/images/game/shields/shield_blue_not_shared', true path, blink = '/images/game/shields//shield_blue_not_shared', true
elseif shieldId == ShieldYellowNoSharedExpBlink then elseif shieldId == ShieldYellowNoSharedExpBlink then
path, blink = '/images/game/shields/shield_yellow_not_shared', true path, blink = '/images/game/shields//shield_yellow_not_shared', true
elseif shieldId == ShieldBlueNoSharedExp then elseif shieldId == ShieldBlueNoSharedExp then
path, blink = '/images/game/shields/shield_blue_not_shared', false path, blink = '/images/game/shields//shield_blue_not_shared', false
elseif shieldId == ShieldYellowNoSharedExp then elseif shieldId == ShieldYellowNoSharedExp then
path, blink = '/images/game/shields/shield_yellow_not_shared', false path, blink = '/images/game/shields//shield_yellow_not_shared', false
elseif shieldId == ShieldGray then
path, blink = '/images/game/shields/shield_gray', false
end end
return path, blink return path, blink
end end
@@ -83,10 +81,6 @@ function getEmblemImagePath(emblemId)
path = '/images/game/emblems/emblem_red' path = '/images/game/emblems/emblem_red'
elseif emblemId == EmblemBlue then elseif emblemId == EmblemBlue then
path = '/images/game/emblems/emblem_blue' path = '/images/game/emblems/emblem_blue'
elseif emblemId == EmblemMember then
path = '/images/game/emblems/emblem_member'
elseif emblemId == EmblemOther then
path = '/images/game/emblems/emblem_other'
end end
return path return path
end end

View File

@@ -4,23 +4,9 @@ function g_game.getRsa()
return currentRsa return currentRsa
end end
function g_game.findPlayerItem(itemId, subType)
local localPlayer = g_game.getLocalPlayer()
if localPlayer then
for slot = InventorySlotFirst, InventorySlotLast do
local item = localPlayer:getInventoryItem(slot)
if item and item:getId() == itemId and (subType == -1 or item:getSubType() == subType) then
return item
end
end
end
return g_game.findItemInContainers(itemId, subType)
end
function g_game.chooseRsa(host) function g_game.chooseRsa(host)
if currentRsa ~= CIPSOFT_RSA and currentRsa ~= OTSERV_RSA then return end if currentRsa ~= CIPSOFT_RSA and currentRsa ~= OTSERV_RSA then return end
if host:ends('.tibia.com') or host:ends('.cipsoft.com') then if string.ends(host, '.tibia.com') or string.ends(host, '.cipsoft.com') then
g_game.setRsa(CIPSOFT_RSA) g_game.setRsa(CIPSOFT_RSA)
if g_app.getOs() == 'windows' then if g_app.getOs() == 'windows' then
@@ -46,29 +32,22 @@ function g_game.isOfficialTibia()
return currentRsa == CIPSOFT_RSA return currentRsa == CIPSOFT_RSA
end end
function g_game.getSupportedClients() function g_game.getSupportedProtocols()
return { return {
760, 810, 811, 840, 842, 850, 853, 810, 811, 840, 842, 850, 853, 854,
854, 860, 861, 862, 870, 910, 940, 860, 861, 862, 870, 910, 940, 944,
944, 953, 954, 960, 961, 963, 970, 953, 954, 960, 961, 963, 970, 971,
980, 981, 982, 983, 984, 985, 986, 973, 974
1001, 1002, 1010, 1020, 1021, 1022,
} }
end end
function g_game.getProtocolVersionForClient(client) function g_game.getSupportedClients(protocol)
clients = { clients = {
[980] = 971, [971] = {980},
[981] = 973, [973] = {981},
[982] = 974, [974] = {982}
[983] = 975,
[984] = 976,
[985] = 977,
[986] = 978,
[1001] = 979,
[1002] = 980,
} }
return clients[client] or client return clients[protocol] or {protocol}
end end
g_game.setRsa(OTSERV_RSA) g_game.setRsa(OTSERV_RSA)

View File

@@ -188,9 +188,5 @@ ClientOpcodes = {
ClientMarketCreate = 246, -- 944 ClientMarketCreate = 246, -- 944
ClientMarketCancel = 247, -- 944 ClientMarketCancel = 247, -- 944
ClientMarketAccept = 248, -- 944 ClientMarketAccept = 248, -- 944
ClientAnswerModalDialog = 249, -- 960 ClientAnswerModalDialog = 249 -- 960
-- 760
ClientEnterAccount760 = 513,
ClientEnterGame760 = 522
} }

View File

@@ -27,13 +27,9 @@ end
function ProtocolLogin:sendLoginPacket() function ProtocolLogin:sendLoginPacket()
local msg = OutputMessage.create() local msg = OutputMessage.create()
if g_game.getProtocolVersion() == 760 then
msg:addU16(ClientOpcodes.ClientEnterAccount760) msg:addU8(ClientOpcodes.ClientEnterAccount)
else msg:addU16(g_game.getOs())
msg:addU8(ClientOpcodes.ClientEnterAccount)
msg:addU16(g_game.getOs())
end
msg:addU16(g_game.getProtocolVersion()) msg:addU16(g_game.getProtocolVersion())
if g_game.getProtocolVersion() >= 971 then if g_game.getProtocolVersion() >= 971 then
@@ -53,16 +49,14 @@ function ProtocolLogin:sendLoginPacket()
-- first RSA byte must be 0 -- first RSA byte must be 0
msg:addU8(0) msg:addU8(0)
if g_game.getProtocolVersion() >= 800 then -- xtea key
-- xtea key self:generateXteaKey()
self:generateXteaKey() local xteaKey = self:getXteaKey()
local xteaKey = self:getXteaKey() msg:addU32(xteaKey[1])
msg:addU32(xteaKey[1]) msg:addU32(xteaKey[2])
msg:addU32(xteaKey[2]) msg:addU32(xteaKey[3])
msg:addU32(xteaKey[3]) msg:addU32(xteaKey[4])
msg:addU32(xteaKey[4])
end
if g_game.getFeature(GameAccountNames) then if g_game.getFeature(GameAccountNames) then
msg:addString(self.accountName) msg:addString(self.accountName)
else else
@@ -79,18 +73,14 @@ function ProtocolLogin:sendLoginPacket()
local paddingBytes = g_crypt.rsaGetSize() - (msg:getMessageSize() - offset) local paddingBytes = g_crypt.rsaGetSize() - (msg:getMessageSize() - offset)
assert(paddingBytes >= 0) assert(paddingBytes >= 0)
msg:addPaddingBytes(paddingBytes, 0) msg:addPaddingBytes(paddingBytes, 0)
if g_game.getProtocolVersion() >= 800 then msg:encryptRsa()
msg:encryptRsa()
end
if g_game.getFeature(GameProtocolChecksum) then if g_game.getFeature(GameProtocolChecksum) then
self:enableChecksum() self:enableChecksum()
end end
self:send(msg) self:send(msg)
if g_game.getProtocolVersion() >= 800 then self:enableXteaEncryption()
self:enableXteaEncryption()
end
self:recv() self:recv()
end end
@@ -135,47 +125,19 @@ end
function ProtocolLogin:parseCharacterList(msg) function ProtocolLogin:parseCharacterList(msg)
local characters = {} local characters = {}
local charactersCount = msg:getU8()
for i=1,charactersCount do
local character = {}
character.name = msg:getString()
character.worldName = msg:getString()
character.worldIp = iptostring(msg:getU32())
character.worldPort = msg:getU16()
if g_game.getProtocolVersion() > 1010 then if g_game.getProtocolVersion() >= 971 then
local worlds = {} character.unknown = msg:getU8()
local worldsCount = msg:getU8()
for i=1, worldsCount do
local world = {}
local worldId = msg:getU8()
world.worldName = msg:getString()
world.worldIp = msg:getString()
world.worldPort = msg:getU16()
msg:getU8() -- unknow byte?
worlds[worldId] = world
end end
local charactersCount = msg:getU8() characters[i] = character
for i=1, charactersCount do
local character = {}
local worldId = msg:getU8()
character.name = msg:getString()
character.worldName = worlds[worldId].worldName
character.worldIp = worlds[worldId].worldIp
character.worldPort = worlds[worldId].worldPort
characters[i] = character
end
else
local charactersCount = msg:getU8()
for i=1,charactersCount do
local character = {}
character.name = msg:getString()
character.worldName = msg:getString()
character.worldIp = iptostring(msg:getU32())
character.worldPort = msg:getU16()
if g_game.getProtocolVersion() >= 971 then
character.unknown = msg:getU8()
end
characters[i] = character
end
end end
local account = {} local account = {}

View File

@@ -2,4 +2,3 @@
-- you can place any custom user code here -- you can place any custom user code here
print 'Startup done :]' print 'Startup done :]'

View File

@@ -100,8 +100,6 @@ set(client_SOURCES ${client_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/uiprogressrect.h ${CMAKE_CURRENT_LIST_DIR}/uiprogressrect.h
${CMAKE_CURRENT_LIST_DIR}/uimapanchorlayout.cpp ${CMAKE_CURRENT_LIST_DIR}/uimapanchorlayout.cpp
${CMAKE_CURRENT_LIST_DIR}/uimapanchorlayout.h ${CMAKE_CURRENT_LIST_DIR}/uimapanchorlayout.h
${CMAKE_CURRENT_LIST_DIR}/uisprite.cpp
${CMAKE_CURRENT_LIST_DIR}/uisprite.h
# util # util
${CMAKE_CURRENT_LIST_DIR}/position.h ${CMAKE_CURRENT_LIST_DIR}/position.h

View File

@@ -227,17 +227,14 @@ namespace Otc
ShieldBlueNoSharedExpBlink, // 7 party member sexp inactive guilty ShieldBlueNoSharedExpBlink, // 7 party member sexp inactive guilty
ShieldYellowNoSharedExpBlink, // 8 // party leader sexp inactive guilty ShieldYellowNoSharedExpBlink, // 8 // party leader sexp inactive guilty
ShieldBlueNoSharedExp, // 9 party member sexp inactive innocent ShieldBlueNoSharedExp, // 9 party member sexp inactive innocent
ShieldYellowNoSharedExp, // 10 party leader sexp inactive innocent ShieldYellowNoSharedExp // 10 party leader sexp inactive innocent
ShieldGray // 11 member of another party
}; };
enum PlayerEmblems { enum PlayerEmblems {
EmblemNone = 0, EmblemNone = 0,
EmblemGreen, EmblemGreen,
EmblemRed, EmblemRed,
EmblemBlue, EmblemBlue
EmblemMember,
EmblemOther
}; };
enum PlayerStates { enum PlayerStates {
@@ -356,18 +353,6 @@ namespace Otc
GameForceFirstAutoWalkStep = 37, GameForceFirstAutoWalkStep = 37,
GameMinimapRemove = 38, GameMinimapRemove = 38,
GameDoubleShopSellAmount = 39, GameDoubleShopSellAmount = 39,
GameContainerPagination = 40,
GameThingMarks = 41,
GameLooktypeU16 = 42,
GamePlayerStamina = 43,
GamePlayerAddons = 44,
GameMessageStatements = 45,
GameMessageLevel = 46,
GameNewFluids = 47,
GamePlayerStateU16 = 48,
GameNewOutfitProtocol = 49,
GamePVPMode = 50,
// 51-100 reserved to be defined in lua // 51-100 reserved to be defined in lua
LastGameFeature = 101 LastGameFeature = 101
}; };

View File

@@ -23,7 +23,7 @@
#include "container.h" #include "container.h"
#include "item.h" #include "item.h"
Container::Container(int id, int capacity, const std::string& name, const ItemPtr& containerItem, bool hasParent, bool isUnlocked, bool hasPages, int containerSize, int firstIndex) Container::Container(int id, int capacity, const std::string& name, const ItemPtr& containerItem, bool hasParent)
{ {
m_id = id; m_id = id;
m_capacity = capacity; m_capacity = capacity;
@@ -31,10 +31,6 @@ Container::Container(int id, int capacity, const std::string& name, const ItemPt
m_containerItem = containerItem; m_containerItem = containerItem;
m_hasParent = hasParent; m_hasParent = hasParent;
m_closed = false; m_closed = false;
m_unlocked = isUnlocked;
m_hasPages = hasPages;
m_size = containerSize;
m_firstIndex = firstIndex;
} }
ItemPtr Container::getItem(int slot) ItemPtr Container::getItem(int slot)
@@ -55,20 +51,12 @@ void Container::onClose()
callLuaField("onClose"); callLuaField("onClose");
} }
void Container::onAddItem(const ItemPtr& item, int slot) void Container::onAddItem(const ItemPtr& item)
{ {
m_items.push_front(item); m_items.push_front(item);
updateItemsPositions(); updateItemsPositions();
callLuaField("onAddItem", slot, item); callLuaField("onAddItem", 0, item);
}
ItemPtr Container::findItemById(uint itemId, int subType)
{
for(const ItemPtr item : m_items)
if(item->getId() == itemId && (subType == -1 || item->getSubType() == subType))
return item;
return nullptr;
} }
void Container::onAddItems(const std::vector<ItemPtr>& items) void Container::onAddItems(const std::vector<ItemPtr>& items)

View File

@@ -32,7 +32,7 @@
class Container : public LuaObject class Container : public LuaObject
{ {
protected: protected:
Container(int id, int capacity, const std::string& name, const ItemPtr& containerItem, bool hasParent, bool isUnlocked, bool hasPages, int containerSize, int firstIndex); Container(int id, int capacity, const std::string& name, const ItemPtr& containerItem, bool hasParent);
public: public:
ItemPtr getItem(int slot); ItemPtr getItem(int slot);
@@ -45,16 +45,11 @@ public:
std::string getName() { return m_name; } std::string getName() { return m_name; }
bool hasParent() { return m_hasParent; } bool hasParent() { return m_hasParent; }
bool isClosed() { return m_closed; } bool isClosed() { return m_closed; }
bool isUnlocked() { return m_unlocked; }
bool hasPages() { return m_hasPages; }
int getSize() { return m_size; }
int getFirstIndex() { return m_firstIndex; }
ItemPtr findItemById(uint itemId, int subType);
protected: protected:
void onOpen(const ContainerPtr& previousContainer); void onOpen(const ContainerPtr& previousContainer);
void onClose(); void onClose();
void onAddItem(const ItemPtr& item, int slot); void onAddItem(const ItemPtr& item);
void onAddItems(const std::vector<ItemPtr>& items); void onAddItems(const std::vector<ItemPtr>& items);
void onUpdateItem(int slot, const ItemPtr& item); void onUpdateItem(int slot, const ItemPtr& item);
void onRemoveItem(int slot); void onRemoveItem(int slot);
@@ -70,10 +65,6 @@ private:
std::string m_name; std::string m_name;
bool m_hasParent; bool m_hasParent;
bool m_closed; bool m_closed;
bool m_unlocked;
bool m_hasPages;
int m_size;
int m_firstIndex;
std::deque<ItemPtr> m_items; std::deque<ItemPtr> m_items;
}; };

View File

@@ -128,7 +128,7 @@ void Creature::internalDrawOutfit(Point dest, float scaleFactor, bool animateWal
dest -= datType->getDisplacement() * scaleFactor; dest -= datType->getDisplacement() * scaleFactor;
datType->draw(dest, scaleFactor, 0, xPattern, 0, 0, animationPhase, lightView); datType->draw(dest, scaleFactor, 0, xPattern, 0, 0, animationPhase, lightView);
dest += getDisplacement() * scaleFactor; dest += getDisplacement() * scaleFactor;
zPattern = std::min(1, getNumPatternZ() - 1); zPattern = 1;
} }
PointF jumpOffset = m_jumpOffset * scaleFactor; PointF jumpOffset = m_jumpOffset * scaleFactor;
@@ -458,11 +458,6 @@ void Creature::updateWalkAnimation(int totalPixelsWalked)
int footAnimPhases = getAnimationPhases() - 1; int footAnimPhases = getAnimationPhases() - 1;
int footDelay = getStepDuration(true) / 3; int footDelay = getStepDuration(true) / 3;
// Since mount is a different outfit we need to get the mount animation phases
if(m_outfit.getMount() != 0) {
ThingType *type = g_things.rawGetThingType(m_outfit.getMount(), m_outfit.getCategory());
footAnimPhases = type->getAnimationPhases() - 1;
}
if(footAnimPhases == 0) if(footAnimPhases == 0)
m_walkAnimationPhase = 0; m_walkAnimationPhase = 0;
else if(m_footStepDrawn && m_footTimer.ticksElapsed() >= footDelay && totalPixelsWalked < 32) { else if(m_footStepDrawn && m_footTimer.ticksElapsed() >= footDelay && totalPixelsWalked < 32) {

View File

@@ -50,9 +50,9 @@ void CreatureManager::terminate()
void Spawn::load(TiXmlElement* node) void Spawn::load(TiXmlElement* node)
{ {
Position centerPos; Position centerPos;
centerPos.x = node->readType<int>("centerx"); centerPos.x = node->readType<uint16>("centerx");
centerPos.y = node->readType<int>("centery"); centerPos.y = node->readType<uint16>("centery");
centerPos.z = node->readType<int>("centerz"); centerPos.z = node->readType<uint8>("centerz");
setCenterPos(centerPos); setCenterPos(centerPos);
setRadius(node->readType<int32>("radius")); setRadius(node->readType<int32>("radius"));
@@ -65,7 +65,6 @@ void Spawn::load(TiXmlElement* node)
std::string cName = cNode->Attribute("name"); std::string cName = cNode->Attribute("name");
stdext::tolower(cName); stdext::tolower(cName);
stdext::trim(cName); stdext::trim(cName);
stdext::ucwords(cName);
if (!(cType = g_creatures.getCreatureByName(cName))) if (!(cType = g_creatures.getCreatureByName(cName)))
continue; continue;
@@ -77,18 +76,17 @@ void Spawn::load(TiXmlElement* node)
dir = (Otc::Direction)dir_; dir = (Otc::Direction)dir_;
cType->setDirection(dir); cType->setDirection(dir);
Position placePos; centerPos.x += cNode->readType<int>("x");
placePos.x = centerPos.x + cNode->readType<int>("x"); centerPos.y += cNode->readType<int>("y");
placePos.y = centerPos.y + cNode->readType<int>("y"); centerPos.z = cNode->readType<int>("z");
placePos.z = cNode->readType<int>("z"); addCreature(centerPos, cType);
cType->setRace(cNode->ValueStr() == "npc" ? CreatureRaceNpc : CreatureRaceMonster);
addCreature(placePos, cType);
} }
} }
void Spawn::save(TiXmlElement* node) void Spawn::save(TiXmlElement*& node)
{ {
node = new TiXmlElement("spawn");
const Position& c = getCenterPos(); const Position& c = getCenterPos();
node->SetAttribute("centerx", c.x); node->SetAttribute("centerx", c.x);
node->SetAttribute("centery", c.y); node->SetAttribute("centery", c.y);
@@ -99,10 +97,10 @@ void Spawn::save(TiXmlElement* node)
TiXmlElement* creatureNode = nullptr; TiXmlElement* creatureNode = nullptr;
for(const auto& pair : m_creatures) { for(const auto& pair : m_creatures) {
const CreatureTypePtr& creature = pair.second; if(!(creatureNode = new TiXmlElement("monster")))
if(!(creatureNode = new TiXmlElement(creature->getRace() == CreatureRaceNpc ? "npc" : "monster")))
stdext::throw_exception("oom?"); stdext::throw_exception("oom?");
const CreatureTypePtr& creature = pair.second;
creatureNode->SetAttribute("name", creature->getName()); creatureNode->SetAttribute("name", creature->getName());
creatureNode->SetAttribute("spawntime", creature->getSpawnTime()); creatureNode->SetAttribute("spawntime", creature->getSpawnTime());
@@ -111,8 +109,8 @@ void Spawn::save(TiXmlElement* node)
const Position& placePos = pair.first; const Position& placePos = pair.first;
assert(placePos.isValid()); assert(placePos.isValid());
creatureNode->SetAttribute("x", c.x - placePos.x); creatureNode->SetAttribute("x", placePos.x);
creatureNode->SetAttribute("y", c.y - placePos.y); creatureNode->SetAttribute("y", placePos.y);
creatureNode->SetAttribute("z", placePos.z); creatureNode->SetAttribute("z", placePos.z);
node->LinkEndChild(creatureNode); node->LinkEndChild(creatureNode);
@@ -123,14 +121,11 @@ void Spawn::addCreature(const Position& placePos, const CreatureTypePtr& cType)
{ {
const Position& centerPos = getCenterPos(); const Position& centerPos = getCenterPos();
int m_radius = getRadius(); int m_radius = getRadius();
if(!isInZone(placePos, centerPos, m_radius)) { if(!isInZone(placePos, centerPos, m_radius))
g_logger.warning(stdext::format("cannot place creature at %s (spawn's center position: %s, spawn radius: %d) (increment radius)", stdext::throw_exception(stdext::format("cannot place creature at %s %s %d (increment radius)",
stdext::to_string(placePos), stdext::to_string(centerPos), stdext::to_string(placePos), stdext::to_string(centerPos),
m_radius m_radius
)); ));
return;
}
g_map.addThing(cType->cast(), placePos, 4); g_map.addThing(cType->cast(), placePos, 4);
m_creatures.insert(std::make_pair(placePos, cType)); m_creatures.insert(std::make_pair(placePos, cType));
} }
@@ -150,8 +145,6 @@ CreaturePtr CreatureType::cast()
CreaturePtr ret(new Creature); CreaturePtr ret(new Creature);
std::string cName = getName(); std::string cName = getName();
stdext::tolower(cName);
stdext::trim(cName);
stdext::ucwords(cName); stdext::ucwords(cName);
ret->setName(cName); ret->setName(cName);
@@ -206,12 +199,20 @@ void CreatureManager::loadNpcs(const std::string& folder)
if(!stdext::ends_with(tmp, "/")) if(!stdext::ends_with(tmp, "/"))
tmp += "/"; tmp += "/";
if(!g_resources.directoryExists(tmp)) // FIXME: filesystem is not supported anymore, rework the following code with g_resources
/*
boost::filesystem::path npcPath(boost::filesystem::current_path().generic_string() + tmp);
if(!boost::filesystem::exists(npcPath))
stdext::throw_exception(stdext::format("NPCs folder '%s' was not found.", folder)); stdext::throw_exception(stdext::format("NPCs folder '%s' was not found.", folder));
const auto& fileList = g_resources.listDirectoryFiles(tmp); for(boost::filesystem::directory_iterator it(npcPath), end; it != end; ++it) {
for(const std::string& file : fileList) std::string f = it->path().filename().string();
loadCreatureBuffer(g_resources.readFileContents(tmp + file)); if(boost::filesystem::is_directory(it->status()))
continue;
loadCreatureBuffer(g_resources.readFileContents(tmp + f));
}
*/
} }
void CreatureManager::loadSpawns(const std::string& fileName) void CreatureManager::loadSpawns(const std::string& fileName)
@@ -226,54 +227,46 @@ void CreatureManager::loadSpawns(const std::string& fileName)
return; return;
} }
try { TiXmlDocument doc;
TiXmlDocument doc; doc.Parse(g_resources.readFileContents(fileName).c_str());
doc.Parse(g_resources.readFileContents(fileName).c_str()); if(doc.Error())
if(doc.Error()) stdext::throw_exception(stdext::format("cannot load spawns xml file '%s: '%s'", fileName, doc.ErrorDesc()));
stdext::throw_exception(stdext::format("cannot load spawns xml file '%s: '%s'", fileName, doc.ErrorDesc()));
TiXmlElement* root = doc.FirstChildElement(); TiXmlElement* root = doc.FirstChildElement();
if(!root || root->ValueStr() != "spawns") if(!root || root->ValueStr() != "spawns")
stdext::throw_exception("malformed spawns file"); stdext::throw_exception("malformed spawns file");
for(TiXmlElement* node = root->FirstChildElement(); node; node = node->NextSiblingElement()) { for(TiXmlElement* node = root->FirstChildElement(); node; node = node->NextSiblingElement()) {
if(node->ValueTStr() != "spawn") if(node->ValueTStr() != "spawn")
stdext::throw_exception("invalid spawn node"); stdext::throw_exception("invalid spawn node");
SpawnPtr spawn(new Spawn); SpawnPtr spawn(new Spawn);
spawn->load(node); spawn->load(node);
m_spawns.insert(std::make_pair(spawn->getCenterPos(), spawn)); m_spawns.insert(std::make_pair(spawn->getCenterPos(), spawn));
}
doc.Clear();
m_spawnLoaded = true;
} catch(std::exception& e) {
g_logger.error(stdext::format("Failed to load '%s': %s", fileName, e.what()));
} }
doc.Clear();
m_spawnLoaded = true;
} }
void CreatureManager::saveSpawns(const std::string& fileName) void CreatureManager::saveSpawns(const std::string& fileName)
{ {
try { TiXmlDocument doc;
TiXmlDocument doc; doc.SetTabSize(2);
doc.SetTabSize(2);
TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", ""); TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", "");
doc.LinkEndChild(decl); doc.LinkEndChild(decl);
TiXmlElement* root = new TiXmlElement("spawns"); TiXmlElement* root = new TiXmlElement("spawns");
doc.LinkEndChild(root); doc.LinkEndChild(root);
for(auto pair : m_spawns) { for(auto pair : m_spawns) {
TiXmlElement* elem = new TiXmlElement("spawn"); TiXmlElement* elem;
pair.second->save(elem); pair.second->save(elem);
root->LinkEndChild(elem); root->LinkEndChild(elem);
}
if(!doc.SaveFile("data"+fileName))
stdext::throw_exception(stdext::format("failed to save spawns XML %s: %s", fileName, doc.ErrorDesc()));
} catch(std::exception& e) {
g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what()));
} }
if(!doc.SaveFile(fileName))
stdext::throw_exception(stdext::format("failed to save spawns XML %s: %s", fileName, doc.ErrorDesc()));
} }
void CreatureManager::loadCreatureBuffer(const std::string& buffer) void CreatureManager::loadCreatureBuffer(const std::string& buffer)
@@ -290,7 +283,6 @@ void CreatureManager::loadCreatureBuffer(const std::string& buffer)
std::string cName = root->Attribute("name"); std::string cName = root->Attribute("name");
stdext::tolower(cName); stdext::tolower(cName);
stdext::trim(cName); stdext::trim(cName);
stdext::ucwords(cName);
CreatureTypePtr newType(new CreatureType(cName)); CreatureTypePtr newType(new CreatureType(cName));
for(TiXmlElement* attrib = root->FirstChildElement(); attrib; attrib = attrib->NextSiblingElement()) { for(TiXmlElement* attrib = root->FirstChildElement(); attrib; attrib = attrib->NextSiblingElement()) {
@@ -337,7 +329,6 @@ const CreatureTypePtr& CreatureManager::getCreatureByName(std::string name)
{ {
stdext::tolower(name); stdext::tolower(name);
stdext::trim(name); stdext::trim(name);
stdext::ucwords(name);
auto it = std::find_if(m_creatures.begin(), m_creatures.end(), auto it = std::find_if(m_creatures.begin(), m_creatures.end(),
[=] (const CreatureTypePtr& m) -> bool { return m->getName() == name; }); [=] (const CreatureTypePtr& m) -> bool { return m->getName() == name; });
if(it != m_creatures.end()) if(it != m_creatures.end())
@@ -372,11 +363,8 @@ SpawnPtr CreatureManager::getSpawn(const Position& centerPos)
SpawnPtr CreatureManager::addSpawn(const Position& centerPos, int radius) SpawnPtr CreatureManager::addSpawn(const Position& centerPos, int radius)
{ {
auto iter = m_spawns.find(centerPos); auto iter = m_spawns.find(centerPos);
if(iter != m_spawns.end()) { if(iter != m_spawns.end())
if(iter->second->getRadius() != radius)
iter->second->setRadius(radius);
return iter->second; return iter->second;
}
SpawnPtr ret(new Spawn); SpawnPtr ret(new Spawn);
@@ -387,5 +375,3 @@ SpawnPtr CreatureManager::addSpawn(const Position& centerPos, int radius)
return ret; return ret;
} }
/* vim: set ts=4 sw=4 et: */

View File

@@ -33,20 +33,14 @@ enum CreatureAttr : uint8
CreatureAttrName = 1, CreatureAttrName = 1,
CreatureAttrOutfit = 2, CreatureAttrOutfit = 2,
CreatureAttrSpawnTime = 3, CreatureAttrSpawnTime = 3,
CreatureAttrDir = 4, CreatureAttrDir = 4
CreatureAttrRace = 5
};
enum CreatureRace : uint8
{
CreatureRaceNpc = 0,
CreatureRaceMonster = 1
}; };
enum SpawnAttr : uint8 enum SpawnAttr : uint8
{ {
SpawnAttrRadius = 0, SpawnAttrRadius = 0,
SpawnAttrCenter = 1, SpawnAttrCenter = 1,
SpawnAttrPos = 2
}; };
class Spawn : public LuaObject class Spawn : public LuaObject
@@ -59,7 +53,7 @@ public:
int32 getRadius() { return m_attribs.get<int32>(SpawnAttrRadius); } int32 getRadius() { return m_attribs.get<int32>(SpawnAttrRadius); }
void setCenterPos(const Position& pos) { m_attribs.set(SpawnAttrCenter, pos); } void setCenterPos(const Position& pos) { m_attribs.set(SpawnAttrCenter, pos); }
Position getCenterPos() { return m_attribs.get<Position>(SpawnAttrCenter); } Position getCenterPos() { return m_attribs.get<Position>(SpawnAttrPos); }
void addCreature(const Position& placePos, const CreatureTypePtr& cType); void addCreature(const Position& placePos, const CreatureTypePtr& cType);
void removeCreature(const Position& pos); void removeCreature(const Position& pos);
@@ -67,7 +61,7 @@ public:
protected: protected:
void load(TiXmlElement* node); void load(TiXmlElement* node);
void save(TiXmlElement* node); void save(TiXmlElement*& node);
private: private:
stdext::dynamic_storage<uint8> m_attribs; stdext::dynamic_storage<uint8> m_attribs;
@@ -93,9 +87,6 @@ public:
void setDirection(Otc::Direction dir) { m_attribs.set(CreatureAttrDir, dir); } void setDirection(Otc::Direction dir) { m_attribs.set(CreatureAttrDir, dir); }
Otc::Direction getDirection() { return m_attribs.get<Otc::Direction>(CreatureAttrDir); } Otc::Direction getDirection() { return m_attribs.get<Otc::Direction>(CreatureAttrDir); }
void setRace(CreatureRace race) { m_attribs.set(CreatureAttrRace, race); }
CreatureRace getRace() { return m_attribs.get<CreatureRace>(CreatureAttrRace); }
CreaturePtr cast(); CreaturePtr cast();
private: private:

View File

@@ -77,10 +77,8 @@ typedef stdext::shared_object_ptr<Spawn> SpawnPtr;
typedef std::vector<ThingPtr> ThingList; typedef std::vector<ThingPtr> ThingList;
typedef std::vector<ThingTypePtr> ThingTypeList; typedef std::vector<ThingTypePtr> ThingTypeList;
typedef std::vector<ItemTypePtr> ItemTypeList; typedef std::vector<ItemTypePtr> ItemTypeList;
typedef std::list<HousePtr> HouseList; typedef std::vector<HousePtr> HouseList;
typedef std::list<TownPtr> TownList; typedef std::vector<TownPtr> TownList;
typedef std::list<ItemPtr> ItemList;
typedef std::vector<ItemPtr> ItemVector;
typedef std::unordered_map<Position, TilePtr, PositionHasher> TileMap; typedef std::unordered_map<Position, TilePtr, PositionHasher> TileMap;
// net // net
@@ -98,11 +96,9 @@ class UIMinimap;
class UIProgressRect; class UIProgressRect;
class UIMapAnchorLayout; class UIMapAnchorLayout;
class UIPositionAnchor; class UIPositionAnchor;
class UISprite;
typedef stdext::shared_object_ptr<UIItem> UIItemPtr; typedef stdext::shared_object_ptr<UIItem> UIItemPtr;
typedef stdext::shared_object_ptr<UICreature> UICreaturePtr; typedef stdext::shared_object_ptr<UICreature> UICreaturePtr;
typedef stdext::shared_object_ptr<UISprite> UISpritePtr;
typedef stdext::shared_object_ptr<UIMap> UIMapPtr; typedef stdext::shared_object_ptr<UIMap> UIMapPtr;
typedef stdext::shared_object_ptr<UIMinimap> UIMinimapPtr; typedef stdext::shared_object_ptr<UIMinimap> UIMinimapPtr;
typedef stdext::shared_object_ptr<UIProgressRect> UIProgressRectPtr; typedef stdext::shared_object_ptr<UIProgressRect> UIProgressRectPtr;

View File

@@ -99,11 +99,6 @@ void Game::resetGameStates()
m_walkEvent = nullptr; m_walkEvent = nullptr;
} }
if(m_checkConnectionEvent) {
m_checkConnectionEvent->cancel();
m_checkConnectionEvent = nullptr;
}
m_containers.clear(); m_containers.clear();
m_vips.clear(); m_vips.clear();
m_gmActions.clear(); m_gmActions.clear();
@@ -188,16 +183,6 @@ void Game::processGameStart()
g_game.ping(); g_game.ping();
}, m_pingDelay); }, m_pingDelay);
} }
m_checkConnectionEvent = g_dispatcher.cycleEvent([this] {
if(!g_game.isConnectionOk() && !m_connectionFailWarned) {
g_lua.callGlobalField("g_game", "onConnectionFailing", true);
m_connectionFailWarned = true;
} else if(g_game.isConnectionOk() && m_connectionFailWarned) {
g_lua.callGlobalField("g_game", "onConnectionFailing", false);
m_connectionFailWarned = false;
}
}, 1000);
} }
void Game::processGameEnd() void Game::processGameEnd()
@@ -205,11 +190,6 @@ void Game::processGameEnd()
m_online = false; m_online = false;
g_lua.callGlobalField("g_game", "onGameEnd"); g_lua.callGlobalField("g_game", "onGameEnd");
if(m_connectionFailWarned) {
g_lua.callGlobalField("g_game", "onConnectionFailing", false);
m_connectionFailWarned = false;
}
// reset game state // reset game state
resetGameStates(); resetGameStates();
@@ -234,22 +214,6 @@ void Game::processGMActions(const std::vector<uint8>& actions)
g_lua.callGlobalField("g_game", "onGMActions", actions); g_lua.callGlobalField("g_game", "onGMActions", actions);
} }
void Game::processPlayerHelpers(int helpers)
{
g_lua.callGlobalField("g_game", "onPlayerHelpersUpdate", helpers);
}
void Game::processPlayerModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeMode)
{
m_fightMode = fightMode;
m_chaseMode = chaseMode;
m_safeFight = safeMode;
g_lua.callGlobalField("g_game", "onFightModeChange", fightMode);
g_lua.callGlobalField("g_game", "onChaseModeChange", chaseMode);
g_lua.callGlobalField("g_game", "onSafeFightChange", safeMode);
}
void Game::processPing() void Game::processPing()
{ {
g_lua.callGlobalField("g_game", "onPing"); g_lua.callGlobalField("g_game", "onPing");
@@ -284,10 +248,10 @@ void Game::processTalk(const std::string& name, int level, Otc::MessageMode mode
g_lua.callGlobalField("g_game", "onTalk", name, level, mode, text, channelId, pos); g_lua.callGlobalField("g_game", "onTalk", name, level, mode, text, channelId, pos);
} }
void Game::processOpenContainer(int containerId, const ItemPtr& containerItem, const std::string& name, int capacity, bool hasParent, const std::vector<ItemPtr>& items, bool isUnlocked, bool hasPages, int containerSize, int firstIndex) void Game::processOpenContainer(int containerId, const ItemPtr& containerItem, const std::string& name, int capacity, bool hasParent, const std::vector<ItemPtr>& items)
{ {
ContainerPtr previousContainer = getContainer(containerId); ContainerPtr previousContainer = getContainer(containerId);
ContainerPtr container = ContainerPtr(new Container(containerId, capacity, name, containerItem, hasParent, isUnlocked, hasPages, containerSize, firstIndex)); ContainerPtr container = ContainerPtr(new Container(containerId, capacity, name, containerItem, hasParent));
m_containers[containerId] = container; m_containers[containerId] = container;
container->onAddItems(items); container->onAddItems(items);
@@ -312,7 +276,7 @@ void Game::processCloseContainer(int containerId)
container->onClose(); container->onClose();
} }
void Game::processContainerAddItem(int containerId, const ItemPtr& item, int slot) void Game::processContainerAddItem(int containerId, const ItemPtr& item)
{ {
ContainerPtr container = getContainer(containerId); ContainerPtr container = getContainer(containerId);
if(!container) { if(!container) {
@@ -320,7 +284,7 @@ void Game::processContainerAddItem(int containerId, const ItemPtr& item, int slo
return; return;
} }
container->onAddItem(item, slot); container->onAddItem(item);
} }
void Game::processContainerUpdateItem(int containerId, int slot, const ItemPtr& item) void Game::processContainerUpdateItem(int containerId, int slot, const ItemPtr& item)
@@ -590,7 +554,7 @@ bool Game::walk(Otc::Direction direction)
if(m_lastWalkDir != direction) { if(m_lastWalkDir != direction) {
// must add a new walk event // must add a new walk event
float ticks = m_localPlayer->getStepTicksLeft(); float ticks = m_localPlayer->getStepTicksLeft();
if(ticks <= 0) { ticks = 1; } if(ticks < 0) { ticks = 0; }
if(m_walkEvent) { if(m_walkEvent) {
m_walkEvent->cancel(); m_walkEvent->cancel();
@@ -733,16 +697,15 @@ void Game::autoWalk(std::vector<Otc::Direction> dirs)
auto it = dirs.begin(); auto it = dirs.begin();
Otc::Direction direction = *it; Otc::Direction direction = *it;
if(!m_localPlayer->canWalk(direction)) if(m_localPlayer->canWalk(direction)) {
return; TilePtr toTile = g_map.getTile(m_localPlayer->getPosition().translatedToDirection(direction));
if(toTile && toTile->isWalkable() && !m_localPlayer->isServerWalking()) {
m_localPlayer->preWalk(direction);
TilePtr toTile = g_map.getTile(m_localPlayer->getPosition().translatedToDirection(direction)); if(getFeature(Otc::GameForceFirstAutoWalkStep)) {
if(toTile && toTile->isWalkable() && !m_localPlayer->isServerWalking()) { forceWalk(direction);
m_localPlayer->preWalk(direction); dirs.erase(it);
}
if(getFeature(Otc::GameForceFirstAutoWalkStep)) {
forceWalk(direction);
dirs.erase(it);
} }
} }
@@ -900,7 +863,7 @@ void Game::useWith(const ItemPtr& item, const ThingPtr& toThing)
if(!pos.isValid()) // virtual item if(!pos.isValid()) // virtual item
pos = Position(0xFFFF, 0, 0); // means that is a item in inventory pos = Position(0xFFFF, 0, 0); // means that is a item in inventory
if(toThing->isCreature() && g_game.getProtocolVersion() >= 780) if(toThing->isCreature())
m_protocolGame->sendUseOnCreature(pos, item->getId(), item->getStackPos(), toThing->getId()); m_protocolGame->sendUseOnCreature(pos, item->getId(), item->getStackPos(), toThing->getId());
else else
m_protocolGame->sendUseItemWith(pos, item->getId(), item->getStackPos(), toThing->getPosition(), toThing->getId(), toThing->getStackPos()); m_protocolGame->sendUseItemWith(pos, item->getId(), item->getStackPos(), toThing->getPosition(), toThing->getId(), toThing->getStackPos());
@@ -919,20 +882,6 @@ void Game::useInventoryItemWith(int itemId, const ThingPtr& toThing)
m_protocolGame->sendUseItemWith(pos, itemId, 0, toThing->getPosition(), toThing->getId(), toThing->getStackPos()); m_protocolGame->sendUseItemWith(pos, itemId, 0, toThing->getPosition(), toThing->getId(), toThing->getStackPos());
} }
ItemPtr Game::findItemInContainers(uint itemId, int subType)
{
for(auto& it : m_containers) {
const ContainerPtr& container = it.second;
if(container) {
ItemPtr item = container->findItemById(itemId, subType);
if(item != nullptr)
return item;
}
}
return nullptr;
}
int Game::open(const ItemPtr& item, const ContainerPtr& previousContainer) int Game::open(const ItemPtr& item, const ContainerPtr& previousContainer)
{ {
if(!canPerformGameAction() || !item) if(!canPerformGameAction() || !item)
@@ -1180,7 +1129,7 @@ void Game::removeVip(int playerId)
{ {
if(!canPerformGameAction()) if(!canPerformGameAction())
return; return;
auto it = m_vips.find(playerId); auto it = m_vips.find(playerId);
if(it == m_vips.end()) if(it == m_vips.end())
return; return;
@@ -1430,40 +1379,24 @@ void Game::setProtocolVersion(int version)
if(isOnline()) if(isOnline())
stdext::throw_exception("Unable to change protocol version while online"); stdext::throw_exception("Unable to change protocol version while online");
if(version != 0 && version != 760 && (version < 810 || version > 1022)) if(version != 0 && (version < 810 || version > 974))
stdext::throw_exception(stdext::format("Protocol version %d not supported", version)); stdext::throw_exception(stdext::format("Protocol version %d not supported", version));
m_features.reset(); m_features.reset();
enableFeature(Otc::GameFormatCreatureName); enableFeature(Otc::GameFormatCreatureName);
if(version >= 780)
{
enableFeature(Otc::GamePlayerAddons);
enableFeature(Otc::GamePlayerStamina);
enableFeature(Otc::GameNewFluids);
enableFeature(Otc::GameMessageLevel);
enableFeature(Otc::GameMessageStatements);
enableFeature(Otc::GamePlayerStateU16);
enableFeature(Otc::GameLooktypeU16);
enableFeature(Otc::GameNewOutfitProtocol);
}
if(version >= 840) { if(version >= 840) {
enableFeature(Otc::GameProtocolChecksum); enableFeature(Otc::GameProtocolChecksum);
enableFeature(Otc::GameChallengeOnLogin); enableFeature(Otc::GameChallengeOnLogin);
enableFeature(Otc::GameAccountNames); enableFeature(Otc::GameAccountNames);
} }
if(version >= 780 && version <= 854) { // 780 might not be accurate if(version <= 854) {
enableFeature(Otc::GameChargeableItems); enableFeature(Otc::GameChargeableItems);
} }
if(version >= 850) {
enableFeature(Otc::GameDoubleFreeCapacity);
}
if(version >= 854) { if(version >= 854) {
enableFeature(Otc::GameDoubleFreeCapacity);
enableFeature(Otc::GameCreatureEmblems); enableFeature(Otc::GameCreatureEmblems);
} }
@@ -1510,18 +1443,6 @@ void Game::setProtocolVersion(int version)
enableFeature(Otc::GameNewSpeedLaw); enableFeature(Otc::GameNewSpeedLaw);
} }
if(version >= 976) {
enableFeature(Otc::GameContainerPagination);
}
if(version >= 979) {
enableFeature(Otc::GameThingMarks);
}
if(version >= 1000) {
enableFeature(Otc::GamePVPMode);
}
m_protocolVersion = version; m_protocolVersion = version;
Proto::buildMessageModesMap(version); Proto::buildMessageModesMap(version);
@@ -1537,7 +1458,7 @@ void Game::setClientVersion(int version)
if(isOnline()) if(isOnline())
stdext::throw_exception("Unable to change client version while online"); stdext::throw_exception("Unable to change client version while online");
if(version != 0 && version != 760 && (version < 810 || version > 1022)) if(version != 0 && (version < 810 || version > 982))
stdext::throw_exception(stdext::format("Client version %d not supported", version)); stdext::throw_exception(stdext::format("Client version %d not supported", version));
m_clientVersion = version; m_clientVersion = version;

View File

@@ -73,17 +73,14 @@ protected:
void processAttackCancel(uint seq); void processAttackCancel(uint seq);
void processWalkCancel(Otc::Direction direction); void processWalkCancel(Otc::Direction direction);
void processPlayerHelpers(int helpers);
void processPlayerModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeMode);
// message related // message related
void processTextMessage(Otc::MessageMode mode, const std::string& text); void processTextMessage(Otc::MessageMode mode, const std::string& text);
void processTalk(const std::string& name, int level, Otc::MessageMode mode, const std::string& text, int channelId, const Position& pos); void processTalk(const std::string& name, int level, Otc::MessageMode mode, const std::string& text, int channelId, const Position& pos);
// container related // container related
void processOpenContainer(int containerId, const ItemPtr& containerItem, const std::string& name, int capacity, bool hasParent, const std::vector<ItemPtr>& items, bool isUnlocked, bool hasPages, int containerSize, int firstIndex); void processOpenContainer(int containerId, const ItemPtr& containerItem, const std::string& name, int capacity, bool hasParent, const std::vector<ItemPtr>& items);
void processCloseContainer(int containerId); void processCloseContainer(int containerId);
void processContainerAddItem(int containerId, const ItemPtr& item, int slot); void processContainerAddItem(int containerId, const ItemPtr& item);
void processContainerUpdateItem(int containerId, int slot, const ItemPtr& item); void processContainerUpdateItem(int containerId, int slot, const ItemPtr& item);
void processContainerRemoveItem(int containerId, int slot); void processContainerRemoveItem(int containerId, int slot);
@@ -161,7 +158,6 @@ public:
void useWith(const ItemPtr& fromThing, const ThingPtr& toThing); void useWith(const ItemPtr& fromThing, const ThingPtr& toThing);
void useInventoryItem(int itemId); void useInventoryItem(int itemId);
void useInventoryItemWith(int itemId, const ThingPtr& toThing); void useInventoryItemWith(int itemId, const ThingPtr& toThing);
ItemPtr findItemInContainers(uint itemId, int subType);
// container related // container related
int open(const ItemPtr& item, const ContainerPtr& previousContainer); int open(const ItemPtr& item, const ContainerPtr& previousContainer);
@@ -235,7 +231,7 @@ public:
void openRuleViolation(const std::string& reporter); void openRuleViolation(const std::string& reporter);
void closeRuleViolation(const std::string& reporter); void closeRuleViolation(const std::string& reporter);
void cancelRuleViolation(); void cancelRuleViolation();
// reports // reports
void reportBug(const std::string& comment); void reportBug(const std::string& comment);
void reportRuleViolation(const std::string& target, int reason, int action, const std::string& comment, const std::string& statement, int statementId, bool ipBanishment); void reportRuleViolation(const std::string& target, int reason, int action, const std::string& comment, const std::string& statement, int statementId, bool ipBanishment);
@@ -285,7 +281,6 @@ public:
bool isDead() { return m_dead; } bool isDead() { return m_dead; }
bool isAttacking() { return !!m_attackingCreature; } bool isAttacking() { return !!m_attackingCreature; }
bool isFollowing() { return !!m_followingCreature; } bool isFollowing() { return !!m_followingCreature; }
bool isConnectionOk() { return m_protocolGame && m_protocolGame->getElapsedTicksSinceLastRead() < 5000; }
int getPing() { return m_ping >= 0 ? std::max(m_ping, m_pingTimer.elapsed_millis()) : -1; } int getPing() { return m_ping >= 0 ? std::max(m_ping, m_pingTimer.elapsed_millis()) : -1; }
ContainerPtr getContainer(int index) { return m_containers[index]; } ContainerPtr getContainer(int index) { return m_containers[index]; }
@@ -345,8 +340,6 @@ private:
std::bitset<Otc::LastGameFeature> m_features; std::bitset<Otc::LastGameFeature> m_features;
ScheduledEventPtr m_pingEvent; ScheduledEventPtr m_pingEvent;
ScheduledEventPtr m_walkEvent; ScheduledEventPtr m_walkEvent;
ScheduledEventPtr m_checkConnectionEvent;
bool m_connectionFailWarned;
int m_protocolVersion; int m_protocolVersion;
int m_clientVersion; int m_clientVersion;
std::string m_clientSignature; std::string m_clientSignature;

View File

@@ -28,10 +28,12 @@ HouseManager g_houses;
House::House() House::House()
{ {
m_nullTile = TilePtr(new Tile(Position()));
} }
House::House(uint32 hId, const std::string &name, const Position &pos) House::House(uint32 hId, const std::string &name, const Position &pos)
{ {
m_nullTile = TilePtr(new Tile(Position()));
setId(hId); setId(hId);
setName(name); setName(name);
if(pos.isValid()) if(pos.isValid())
@@ -40,32 +42,16 @@ House::House(uint32 hId, const std::string &name, const Position &pos)
void House::setTile(const TilePtr& tile) void House::setTile(const TilePtr& tile)
{ {
tile->setFlag(TILESTATE_HOUSE); tile->setFlags(TILESTATE_HOUSE);
tile->setHouseId(getId());
m_tiles.insert(std::make_pair(tile->getPosition(), tile)); m_tiles.insert(std::make_pair(tile->getPosition(), tile));
} }
TilePtr House::getTile(const Position& position) const TilePtr& House::getTile(const Position& position)
{ {
TileMap::const_iterator iter = m_tiles.find(position); TileMap::const_iterator iter = m_tiles.find(position);
if(iter != m_tiles.end()) if(iter != m_tiles.end())
return iter->second; return iter->second;
return nullptr; return m_nullTile;
}
void House::addDoor(const ItemPtr& door)
{
if (!door) return;
door->setDoorId(m_lastDoorId);
m_doors[m_lastDoorId++] = door;
}
void House::removeDoorById(uint32 doorId)
{
if(doorId >= m_lastDoorId)
stdext::throw_exception(stdext::format("Failed to remove door of id %d (would overflow), max id: %d",
doorId, m_lastDoorId));
m_doors[doorId] = nullptr;
} }
void House::load(const TiXmlElement *elem) void House::load(const TiXmlElement *elem)
@@ -81,14 +67,16 @@ void House::load(const TiXmlElement *elem)
m_isGuildHall = elem->readType<bool>("guildhall"); m_isGuildHall = elem->readType<bool>("guildhall");
Position entryPos; Position entryPos;
entryPos.x = elem->readType<int>("entryx"); entryPos.x = elem->readType<uint16>("entryx");
entryPos.y = elem->readType<int>("entryy"); entryPos.y = elem->readType<uint16>("entryy");
entryPos.z = elem->readType<int>("entryz"); entryPos.z = elem->readType<uint8>("entryz");
setEntry(entryPos); setEntry(entryPos);
} }
void House::save(TiXmlElement* elem) void House::save(TiXmlElement*& elem)
{ {
elem = new TiXmlElement("house");
elem->SetAttribute("name", getName()); elem->SetAttribute("name", getName());
elem->SetAttribute("houseid", getId()); elem->SetAttribute("houseid", getId());
@@ -105,6 +93,7 @@ void House::save(TiXmlElement* elem)
HouseManager::HouseManager() HouseManager::HouseManager()
{ {
m_nullHouse = HousePtr(new House);
} }
void HouseManager::addHouse(const HousePtr& house) void HouseManager::addHouse(const HousePtr& house)
@@ -120,79 +109,56 @@ void HouseManager::removeHouse(uint32 houseId)
m_houses.erase(it); m_houses.erase(it);
} }
HousePtr HouseManager::getHouse(uint32 houseId) const HousePtr& HouseManager::getHouse(uint32 houseId)
{
auto it = findHouse(houseId);
return it != m_houses.end() ? *it : nullptr;
}
HousePtr HouseManager::getHouseByName(std::string name)
{ {
auto it = std::find_if(m_houses.begin(), m_houses.end(), auto it = std::find_if(m_houses.begin(), m_houses.end(),
[=] (const HousePtr& house) -> bool { return house->getName() == name; }); [=] (const HousePtr& house) -> bool { return house->getId() == houseId; });
return it != m_houses.end() ? *it : nullptr; return it != m_houses.end() ? *it : m_nullHouse;
} }
void HouseManager::load(const std::string& fileName) void HouseManager::load(const std::string& fileName)
{ {
try { TiXmlDocument doc;
TiXmlDocument doc; doc.Parse(g_resources.readFileContents(fileName).c_str());
doc.Parse(g_resources.readFileContents(fileName).c_str()); if(doc.Error())
if(doc.Error()) stdext::throw_exception(stdext::format("failed to load '%s': %s (House XML)", fileName, doc.ErrorDesc()));
stdext::throw_exception(stdext::format("failed to load '%s': %s (House XML)", fileName, doc.ErrorDesc()));
TiXmlElement *root = doc.FirstChildElement(); TiXmlElement *root = doc.FirstChildElement();
if(!root || root->ValueTStr() != "houses") if(!root || root->ValueTStr() != "houses")
stdext::throw_exception("invalid root tag name"); stdext::throw_exception("invalid root tag name");
for(TiXmlElement *elem = root->FirstChildElement(); elem; elem = elem->NextSiblingElement()) { for(TiXmlElement *elem = root->FirstChildElement(); elem; elem = elem->NextSiblingElement()) {
if(elem->ValueTStr() != "house") if(elem->ValueTStr() != "house")
stdext::throw_exception("invalid house tag."); stdext::throw_exception("invalid house tag.");
uint32 houseId = elem->readType<uint32>("houseid"); uint32 houseId = elem->readType<uint32>("houseid");
HousePtr house = getHouse(houseId); HousePtr house = getHouse(houseId);
if(!house) if(!house)
house = HousePtr(new House(houseId)), addHouse(house); house = HousePtr(new House(houseId)), addHouse(house);
house->load(elem); house->load(elem);
}
} catch(std::exception& e) {
g_logger.error(stdext::format("Failed to load '%s': %s", fileName, e.what()));
} }
} }
void HouseManager::save(const std::string& fileName) void HouseManager::save(const std::string& fileName)
{ {
try { TiXmlDocument doc;
TiXmlDocument doc; doc.SetTabSize(2);
doc.SetTabSize(2);
TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", ""); TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", "");
doc.LinkEndChild(decl); doc.LinkEndChild(decl);
TiXmlElement* root = new TiXmlElement("houses"); TiXmlElement* root = new TiXmlElement("houses");
doc.LinkEndChild(root); doc.LinkEndChild(root);
for(auto house : m_houses) { for(auto house : m_houses) {
TiXmlElement *elem = new TiXmlElement("house"); TiXmlElement *elem;
house->save(elem); house->save(elem);
root->LinkEndChild(elem); root->LinkEndChild(elem);
}
if(!doc.SaveFile("data"+fileName))
stdext::throw_exception(stdext::format("failed to save houses XML %s: %s", fileName, doc.ErrorDesc()));
} catch(std::exception& e) {
g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what()));
} }
}
HouseList HouseManager::filterHouses(uint32 townId) if(!doc.SaveFile(fileName))
{ stdext::throw_exception(stdext::format("failed to save houses XML %s: %s", fileName, doc.ErrorDesc()));
HouseList ret;
for(const HousePtr& house : m_houses)
if(house->getTownId() == townId)
ret.push_back(house);
return ret;
} }
HouseList::iterator HouseManager::findHouse(uint32 houseId) HouseList::iterator HouseManager::findHouse(uint32 houseId)
@@ -200,5 +166,3 @@ HouseList::iterator HouseManager::findHouse(uint32 houseId)
return std::find_if(m_houses.begin(), m_houses.end(), return std::find_if(m_houses.begin(), m_houses.end(),
[=] (const HousePtr& house) -> bool { return house->getId() == houseId; }); [=] (const HousePtr& house) -> bool { return house->getId() == houseId; });
} }
/* vim: set ts=4 sw=4 et: */

View File

@@ -43,10 +43,10 @@ class House : public LuaObject
public: public:
House(); House();
House(uint32 hId, const std::string& name = "", const Position& pos=Position()); House(uint32 hId, const std::string& name = "", const Position& pos=Position());
~House() { m_tiles.clear(); } ~House() { m_tiles.clear(); m_nullTile = nullptr; }
void setTile(const TilePtr& tile); void setTile(const TilePtr& tile);
TilePtr getTile(const Position& pos); const TilePtr& getTile(const Position& pos);
void setName(const std::string& name) { m_attribs.set(HouseAttrName, name); } void setName(const std::string& name) { m_attribs.set(HouseAttrName, name); }
std::string getName() { return m_attribs.get<std::string>(HouseAttrName); } std::string getName() { return m_attribs.get<std::string>(HouseAttrName); }
@@ -66,19 +66,14 @@ public:
void setEntry(const Position& p) { m_attribs.set(HouseAttrEntry, p); } void setEntry(const Position& p) { m_attribs.set(HouseAttrEntry, p); }
Position getEntry() { return m_attribs.get<Position>(HouseAttrEntry); } Position getEntry() { return m_attribs.get<Position>(HouseAttrEntry); }
void addDoor(const ItemPtr& door);
void removeDoor(const ItemPtr& door) { removeDoorById(door->getDoorId()); }
void removeDoorById(uint32 doorId);
protected: protected:
void load(const TiXmlElement* elem); void load(const TiXmlElement* elem);
void save(TiXmlElement* elem); void save(TiXmlElement*& elem);
private: private:
stdext::packed_storage<uint8> m_attribs; stdext::packed_storage<uint8> m_attribs;
TileMap m_tiles; TileMap m_tiles;
ItemVector m_doors; TilePtr m_nullTile;
uint32 m_lastDoorId;
stdext::boolean<false> m_isGuildHall; stdext::boolean<false> m_isGuildHall;
friend class HouseManager; friend class HouseManager;
@@ -90,18 +85,16 @@ public:
void addHouse(const HousePtr& house); void addHouse(const HousePtr& house);
void removeHouse(uint32 houseId); void removeHouse(uint32 houseId);
HousePtr getHouse(uint32 houseId); HouseList getHouseList() { return m_houses; }
HousePtr getHouseByName(std::string name); const HousePtr& getHouse(uint32 houseId);
void clear() { m_houses.clear(); m_nullHouse = nullptr; }
void load(const std::string& fileName); void load(const std::string& fileName);
void save(const std::string& fileName); void save(const std::string& fileName);
void clear() { m_houses.clear(); }
HouseList getHouseList() { return m_houses; }
HouseList filterHouses(uint32 townId);
private: private:
HouseList m_houses; HouseList m_houses;
HousePtr m_nullHouse;
protected: protected:
HouseList::iterator findHouse(uint32 houseId); HouseList::iterator findHouse(uint32 houseId);

View File

@@ -40,11 +40,7 @@
Item::Item() : Item::Item() :
m_clientId(0), m_clientId(0),
m_serverId(0), m_serverId(0),
m_countOrSubType(1), m_countOrSubType(1)
m_color(Color::alpha),
m_async(true),
m_phase(0),
m_lastPhase(0)
{ {
} }
@@ -62,11 +58,6 @@ ItemPtr Item::createFromOtb(int id)
return item; return item;
} }
std::string Item::getName()
{
return g_things.findItemTypeByClientId(m_clientId)->getName();
}
void Item::draw(const Point& dest, float scaleFactor, bool animate, LightView *lightView) void Item::draw(const Point& dest, float scaleFactor, bool animate, LightView *lightView)
{ {
if(m_clientId == 0) if(m_clientId == 0)
@@ -79,15 +70,7 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate, LightView *l
int xPattern = 0, yPattern = 0, zPattern = 0; int xPattern = 0, yPattern = 0, zPattern = 0;
calculatePatterns(xPattern, yPattern, zPattern); calculatePatterns(xPattern, yPattern, zPattern);
if(m_color != Color::alpha)
g_painter->setColor(m_color);
rawGetThingType()->draw(dest, scaleFactor, 0, xPattern, yPattern, zPattern, animationPhase, lightView); rawGetThingType()->draw(dest, scaleFactor, 0, xPattern, yPattern, zPattern, animationPhase, lightView);
/// Sanity check
/// This is just to ensure that we don't overwrite some color and
/// screw up the whole rendering.
if(m_color != Color::alpha)
g_painter->resetColor();
} }
void Item::setId(uint32 id) void Item::setId(uint32 id)
@@ -204,11 +187,6 @@ void Item::serializeItem(const OutputBinaryTreePtr& out)
out->addU16(getDepotId()); out->addU16(getDepotId());
} }
if(isHouseDoor()) {
out->addU8(ATTR_HOUSEDOORID);
out->addU8(getDoorId());
}
uint16 aid = m_attribs.get<uint16>(ATTR_ACTION_ID); uint16 aid = m_attribs.get<uint16>(ATTR_ACTION_ID);
uint16 uid = m_attribs.get<uint16>(ATTR_UNIQUE_ID); uint16 uid = m_attribs.get<uint16>(ATTR_UNIQUE_ID);
if(aid) { if(aid) {
@@ -222,8 +200,10 @@ void Item::serializeItem(const OutputBinaryTreePtr& out)
} }
out->endNode(); out->endNode();
for(auto i : m_containerItems) if(!m_containerItems.empty()) {
i->serializeItem(out); for(auto c : m_containerItems)
c->serializeItem(out);
}
} }
int Item::getSubType() int Item::getSubType()
@@ -291,68 +271,65 @@ void Item::calculatePatterns(int& xPattern, int& yPattern, int& zPattern)
} }
} else if(isSplash() || isFluidContainer()) { } else if(isSplash() || isFluidContainer()) {
int color = Otc::FluidTransparent; int color = Otc::FluidTransparent;
if(g_game.getFeature(Otc::GameNewFluids)) { switch(m_countOrSubType) {
switch(m_countOrSubType) { case Otc::FluidNone:
case Otc::FluidNone: color = Otc::FluidTransparent;
color = Otc::FluidTransparent; break;
break; case Otc::FluidWater:
case Otc::FluidWater: color = Otc::FluidBlue;
color = Otc::FluidBlue; break;
break; case Otc::FluidMana:
case Otc::FluidMana: color = Otc::FluidPurple;
color = Otc::FluidPurple; break;
break; case Otc::FluidBeer:
case Otc::FluidBeer: color = Otc::FluidBrown;
color = Otc::FluidBrown; break;
break; case Otc::FluidOil:
case Otc::FluidOil: color = Otc::FluidBrown;
color = Otc::FluidBrown; break;
break; case Otc::FluidBlood:
case Otc::FluidBlood: color = Otc::FluidRed;
color = Otc::FluidRed; break;
break; case Otc::FluidSlime:
case Otc::FluidSlime: color = Otc::FluidGreen;
color = Otc::FluidGreen; break;
break; case Otc::FluidMud:
case Otc::FluidMud: color = Otc::FluidBrown;
color = Otc::FluidBrown; break;
break; case Otc::FluidLemonade:
case Otc::FluidLemonade: color = Otc::FluidYellow;
color = Otc::FluidYellow; break;
break; case Otc::FluidMilk:
case Otc::FluidMilk: color = Otc::FluidWhite;
color = Otc::FluidWhite; break;
break; case Otc::FluidWine:
case Otc::FluidWine: color = Otc::FluidPurple;
color = Otc::FluidPurple; break;
break; case Otc::FluidHealth:
case Otc::FluidHealth: color = Otc::FluidRed;
color = Otc::FluidRed; break;
break; case Otc::FluidUrine:
case Otc::FluidUrine: color = Otc::FluidYellow;
color = Otc::FluidYellow; break;
break; case Otc::FluidRum:
case Otc::FluidRum: color = Otc::FluidBrown;
color = Otc::FluidBrown; break;
break; case Otc::FluidFruidJuice:
case Otc::FluidFruidJuice: color = Otc::FluidYellow;
color = Otc::FluidYellow; break;
break; case Otc::FluidCoconutMilk:
case Otc::FluidCoconutMilk: color = Otc::FluidWhite;
color = Otc::FluidWhite; break;
break; case Otc::FluidTea:
case Otc::FluidTea: color = Otc::FluidBrown;
color = Otc::FluidBrown; break;
break; case Otc::FluidMead:
case Otc::FluidMead: color = Otc::FluidBrown;
color = Otc::FluidBrown; break;
break; default:
default: color = Otc::FluidTransparent;
color = Otc::FluidTransparent; break;
break; }
}
} else
color = m_countOrSubType;
xPattern = (color % 4) % getNumPatternX(); xPattern = (color % 4) % getNumPatternX();
yPattern = (color / 4) % getNumPatternY(); yPattern = (color / 4) % getNumPatternY();
@@ -366,17 +343,9 @@ void Item::calculatePatterns(int& xPattern, int& yPattern, int& zPattern)
int Item::calculateAnimationPhase(bool animate) int Item::calculateAnimationPhase(bool animate)
{ {
if(getAnimationPhases() > 1) { if(getAnimationPhases() > 1) {
if(animate) { if(animate)
if(m_async) return (g_clock.millis() % (Otc::ITEM_TICKS_PER_FRAME * getAnimationPhases())) / Otc::ITEM_TICKS_PER_FRAME;
return (g_clock.millis() % (Otc::ITEM_TICKS_PER_FRAME * getAnimationPhases())) / Otc::ITEM_TICKS_PER_FRAME; else
else {
if(g_clock.millis() - m_lastPhase >= Otc::ITEM_TICKS_PER_FRAME) {
m_phase = (m_phase + 1) % getAnimationPhases();
m_lastPhase = g_clock.millis();
}
return m_phase;
}
} else
return getAnimationPhases()-1; return getAnimationPhases()-1;
} }
return 0; return 0;
@@ -398,4 +367,3 @@ ThingType* Item::rawGetThingType()
{ {
return g_things.rawGetThingType(m_clientId, ThingCategoryItem); return g_things.rawGetThingType(m_clientId, ThingCategoryItem);
} }
/* vim: set ts=4 sw=4 et :*/

View File

@@ -24,7 +24,6 @@
#define ITEM_H #define ITEM_H
#include <framework/global.h> #include <framework/global.h>
#include "thing.h" #include "thing.h"
#include "effect.h" #include "effect.h"
#include "itemtype.h" #include "itemtype.h"
@@ -89,7 +88,6 @@ public:
void setCountOrSubType(int value) { m_countOrSubType = value; } void setCountOrSubType(int value) { m_countOrSubType = value; }
void setCount(int count) { m_countOrSubType = count; } void setCount(int count) { m_countOrSubType = count; }
void setSubType(int subType) { m_countOrSubType = subType; } void setSubType(int subType) { m_countOrSubType = subType; }
void setColor(const Color& c) { m_color = c; }
int getCountOrSubType() { return m_countOrSubType; } int getCountOrSubType() { return m_countOrSubType; }
int getSubType(); int getSubType();
@@ -97,9 +95,10 @@ public:
uint32 getId() { return m_clientId; } uint32 getId() { return m_clientId; }
uint16 getClientId() { return m_clientId; } uint16 getClientId() { return m_clientId; }
uint16 getServerId() { return m_serverId; } uint16 getServerId() { return m_serverId; }
std::string getName();
bool isValid(); bool isValid();
ItemPtr clone();
void unserializeItem(const BinaryTreePtr& in); void unserializeItem(const BinaryTreePtr& in);
void serializeItem(const OutputBinaryTreePtr& out); void serializeItem(const OutputBinaryTreePtr& out);
@@ -112,9 +111,6 @@ public:
void setActionId(uint16 actionId) { m_attribs.set(ATTR_ACTION_ID, actionId); } void setActionId(uint16 actionId) { m_attribs.set(ATTR_ACTION_ID, actionId); }
void setUniqueId(uint16 uniqueId) { m_attribs.set(ATTR_UNIQUE_ID, uniqueId); } void setUniqueId(uint16 uniqueId) { m_attribs.set(ATTR_UNIQUE_ID, uniqueId); }
void setAsync(bool enable) { m_async = enable; }
bool isHouseDoor() { return m_attribs.has(ATTR_HOUSEDOORID); }
bool isDepot() { return m_attribs.has(ATTR_DEPOT_ID); } bool isDepot() { return m_attribs.has(ATTR_DEPOT_ID); }
bool isContainer() { return m_attribs.has(ATTR_CONTAINER_ITEMS); } bool isContainer() { return m_attribs.has(ATTR_CONTAINER_ITEMS); }
bool isDoor() { return m_attribs.has(ATTR_HOUSEDOORID); } bool isDoor() { return m_attribs.has(ATTR_HOUSEDOORID); }
@@ -122,7 +118,6 @@ public:
bool isMoveable(); bool isMoveable();
bool isGround(); bool isGround();
ItemPtr clone();
ItemPtr asItem() { return static_self_cast<Item>(); } ItemPtr asItem() { return static_self_cast<Item>(); }
bool isItem() { return true; } bool isItem() { return true; }
@@ -141,12 +136,7 @@ private:
uint16 m_serverId; uint16 m_serverId;
uint8 m_countOrSubType; uint8 m_countOrSubType;
stdext::packed_storage<uint8> m_attribs; stdext::packed_storage<uint8> m_attribs;
ItemList m_containerItems; std::vector<ItemPtr> m_containerItems;
Color m_color;
bool m_async;
uint8 m_phase;
ticks_t m_lastPhase;
}; };
#pragma pack(pop) #pragma pack(pop)

View File

@@ -23,7 +23,6 @@
#include "thingtypemanager.h" #include "thingtypemanager.h"
#include "thingtype.h" #include "thingtype.h"
#include "game.h"
#include <framework/core/filestream.h> #include <framework/core/filestream.h>
#include <framework/core/binarytree.h> #include <framework/core/binarytree.h>
@@ -51,37 +50,28 @@ void ItemType::unserialize(const BinaryTreePtr& node)
switch(attr) { switch(attr) {
case ItemTypeAttrServerId: { case ItemTypeAttrServerId: {
uint16 serverId = node->getU16(); uint16 serverId = node->getU16();
if(g_game.getProtocolVersion() < 960) { if(serverId > 20000 && serverId < 20100) {
if(serverId > 20000 && serverId < 20100) { serverId -= 20000;
serverId -= 20000; } else if(lastId > 99 && lastId != serverId - 1) {
} else if(lastId > 99 && lastId != serverId - 1) {
while(lastId != serverId - 1) { while(lastId != serverId - 1) {
ItemTypePtr tmp(new ItemType); ItemTypePtr tmp(new ItemType);
tmp->setServerId(lastId++); tmp->setServerId(lastId++);
g_things.addItemType(tmp); g_things.addItemType(tmp);
}
}
} else {
if(serverId > 30000 && serverId < 30100) {
serverId -= 30000;
} else if(lastId > 99 && lastId != serverId - 1) {
while(lastId != serverId - 1) {
ItemTypePtr tmp(new ItemType);
tmp->setServerId(lastId++);
g_things.addItemType(tmp);
}
} }
} }
setServerId(serverId); setServerId(serverId);
lastId = serverId; lastId = serverId;
break; break;
} }
case ItemTypeAttrClientId: case ItemTypeAttrClientId: {
setClientId(node->getU16()); setClientId(node->getU16());
break; break;
case ItemTypeAttrName: }
case ItemTypeAttrName: {
setName(node->getString(len)); setName(node->getString(len));
break; break;
}
default: default:
node->skip(len); // skip attribute node->skip(len); // skip attribute
break; break;

View File

@@ -26,6 +26,7 @@
#include <framework/graphics/framebuffermanager.h> #include <framework/graphics/framebuffermanager.h>
#include <framework/graphics/painter.h> #include <framework/graphics/painter.h>
#include <framework/graphics/image.h> #include <framework/graphics/image.h>
#include <framework/graphics/ogl/textureogl.h>
enum { enum {
MAX_LIGHT_INTENSITY = 8, MAX_LIGHT_INTENSITY = 8,
@@ -61,7 +62,7 @@ TexturePtr LightView::generateLightBubble(float centerFactor)
} }
} }
TexturePtr tex = TexturePtr(new Texture(lightImage, true)); TexturePtr tex = TexturePtr(new TextureOGL(lightImage, true));
tex->setSmooth(true); tex->setSmooth(true);
return tex; return tex;
} }

View File

@@ -72,7 +72,7 @@ bool LocalPlayer::canWalk(Otc::Direction direction)
return false; return false;
// last walk is not done yet // last walk is not done yet
if((m_walkTimer.ticksElapsed() < getStepDuration()) && !isAutoWalking()) if(m_walkTimer.ticksElapsed() < getStepDuration())
return false; return false;
// prewalk has a timeout, because for some reason that I don't know yet the server sometimes doesn't answer the prewalk // prewalk has a timeout, because for some reason that I don't know yet the server sometimes doesn't answer the prewalk
@@ -83,7 +83,7 @@ bool LocalPlayer::canWalk(Otc::Direction direction)
return false; return false;
// cannot walk while already walking // cannot walk while already walking
if((m_walking && !isAutoWalking()) && (!prewalkTimeouted || m_secondPreWalk)) if(m_walking && !prewalkTimeouted)
return false; return false;
return true; return true;
@@ -95,7 +95,6 @@ void LocalPlayer::walk(const Position& oldPos, const Position& newPos)
if(m_preWalking) { if(m_preWalking) {
// switch to normal walking // switch to normal walking
m_preWalking = false; m_preWalking = false;
m_secondPreWalk = false;
m_lastPrewalkDone = true; m_lastPrewalkDone = true;
// if is to the last prewalk destination, updates the walk preserving the animation // if is to the last prewalk destination, updates the walk preserving the animation
if(newPos == m_lastPrewalkDestination) { if(newPos == m_lastPrewalkDestination) {
@@ -119,8 +118,7 @@ void LocalPlayer::preWalk(Otc::Direction direction)
Position newPos = m_position.translatedToDirection(direction); Position newPos = m_position.translatedToDirection(direction);
// avoid reanimating prewalks // avoid reanimating prewalks
if(m_preWalking) { if(m_preWalking && m_lastPrewalkDestination == newPos) {
m_secondPreWalk = true;
return; return;
} }
@@ -279,7 +277,6 @@ void LocalPlayer::terminateWalk()
{ {
Creature::terminateWalk(); Creature::terminateWalk();
m_preWalking = false; m_preWalking = false;
m_secondPreWalk = false;
m_idleTimer.restart(); m_idleTimer.restart();
auto self = asLocalPlayer(); auto self = asLocalPlayer();

View File

@@ -126,7 +126,6 @@ private:
ticks_t m_walkLockExpiration; ticks_t m_walkLockExpiration;
stdext::boolean<false> m_preWalking; stdext::boolean<false> m_preWalking;
stdext::boolean<true> m_lastPrewalkDone; stdext::boolean<true> m_lastPrewalkDone;
stdext::boolean<false> m_secondPreWalk;
stdext::boolean<false> m_serverWalking; stdext::boolean<false> m_serverWalking;
stdext::boolean<false> m_knownCompletePath; stdext::boolean<false> m_knownCompletePath;

View File

@@ -47,7 +47,6 @@
#include "uiminimap.h" #include "uiminimap.h"
#include "uimapanchorlayout.h" #include "uimapanchorlayout.h"
#include "uiprogressrect.h" #include "uiprogressrect.h"
#include "uisprite.h"
#include "outfit.h" #include "outfit.h"
#include <framework/luaengine/luainterface.h> #include <framework/luaengine/luainterface.h>
@@ -67,26 +66,20 @@ void Client::registerLuaFunctions()
g_lua.bindSingletonFunction("g_things", "getItemType", &ThingTypeManager::getItemType, &g_things); g_lua.bindSingletonFunction("g_things", "getItemType", &ThingTypeManager::getItemType, &g_things);
g_lua.bindSingletonFunction("g_things", "getThingTypes", &ThingTypeManager::getThingTypes, &g_things); g_lua.bindSingletonFunction("g_things", "getThingTypes", &ThingTypeManager::getThingTypes, &g_things);
g_lua.bindSingletonFunction("g_things", "findItemTypeByClientId", &ThingTypeManager::findItemTypeByClientId, &g_things); g_lua.bindSingletonFunction("g_things", "findItemTypeByClientId", &ThingTypeManager::findItemTypeByClientId, &g_things);
g_lua.bindSingletonFunction("g_things", "findItemTypeByName", &ThingTypeManager::findItemTypeByName, &g_things);
g_lua.bindSingletonFunction("g_things", "findItemTypesByName", &ThingTypeManager::findItemTypesByName, &g_things);
g_lua.bindSingletonFunction("g_things", "findItemTypesByString", &ThingTypeManager::findItemTypesByString, &g_things);
g_lua.bindSingletonFunction("g_things", "findItemTypeByCategory", &ThingTypeManager::findItemTypeByCategory, &g_things);
g_lua.bindSingletonFunction("g_things", "findThingTypeByAttr", &ThingTypeManager::findThingTypeByAttr, &g_things); g_lua.bindSingletonFunction("g_things", "findThingTypeByAttr", &ThingTypeManager::findThingTypeByAttr, &g_things);
g_lua.bindSingletonFunction("g_things", "findItemTypeByCategory", &ThingTypeManager::findItemTypeByCategory, &g_things);
g_lua.registerSingletonClass("g_houses"); g_lua.registerSingletonClass("g_houses");
g_lua.bindSingletonFunction("g_houses", "clear", &HouseManager::clear, &g_houses); g_lua.bindSingletonFunction("g_houses", "clear", &HouseManager::clear, &g_houses);
g_lua.bindSingletonFunction("g_houses", "load", &HouseManager::load, &g_houses); g_lua.bindSingletonFunction("g_houses", "load", &HouseManager::load, &g_houses);
g_lua.bindSingletonFunction("g_houses", "save", &HouseManager::save, &g_houses); g_lua.bindSingletonFunction("g_houses", "save", &HouseManager::save, &g_houses);
g_lua.bindSingletonFunction("g_houses", "getHouse", &HouseManager::getHouse, &g_houses); g_lua.bindSingletonFunction("g_houses", "getHouse", &HouseManager::getHouse, &g_houses);
g_lua.bindSingletonFunction("g_houses", "getHouseByName", &HouseManager::getHouseByName, &g_houses); g_lua.bindSingletonFunction("g_houses", "addHouse", &HouseManager::addHouse, &g_houses);
g_lua.bindSingletonFunction("g_houses", "addHouse", &HouseManager::addHouse, &g_houses); g_lua.bindSingletonFunction("g_houses", "removeHouse", &HouseManager::removeHouse, &g_houses);
g_lua.bindSingletonFunction("g_houses", "removeHouse", &HouseManager::removeHouse, &g_houses); g_lua.bindSingletonFunction("g_houses", "getHouseList", &HouseManager::getHouseList, &g_houses);
g_lua.bindSingletonFunction("g_houses", "getHouseList", &HouseManager::getHouseList, &g_houses);
g_lua.bindSingletonFunction("g_houses", "filterHouses", &HouseManager::filterHouses, &g_houses);
g_lua.registerSingletonClass("g_towns"); g_lua.registerSingletonClass("g_towns");
g_lua.bindSingletonFunction("g_towns", "getTown", &TownManager::getTown, &g_towns); g_lua.bindSingletonFunction("g_towns", "getTown", &TownManager::getTown, &g_towns);
g_lua.bindSingletonFunction("g_towns", "getTownByName",&TownManager::getTownByName,&g_towns);
g_lua.bindSingletonFunction("g_towns", "addTown", &TownManager::addTown, &g_towns); g_lua.bindSingletonFunction("g_towns", "addTown", &TownManager::addTown, &g_towns);
g_lua.bindSingletonFunction("g_towns", "removeTown", &TownManager::removeTown, &g_towns); g_lua.bindSingletonFunction("g_towns", "removeTown", &TownManager::removeTown, &g_towns);
g_lua.bindSingletonFunction("g_towns", "getTowns", &TownManager::getTowns, &g_towns); g_lua.bindSingletonFunction("g_towns", "getTowns", &TownManager::getTowns, &g_towns);
@@ -106,8 +99,6 @@ void Client::registerLuaFunctions()
g_lua.bindSingletonFunction("g_map", "getThing", &Map::getThing, &g_map); g_lua.bindSingletonFunction("g_map", "getThing", &Map::getThing, &g_map);
g_lua.bindSingletonFunction("g_map", "removeThingByPos", &Map::removeThingByPos, &g_map); g_lua.bindSingletonFunction("g_map", "removeThingByPos", &Map::removeThingByPos, &g_map);
g_lua.bindSingletonFunction("g_map", "removeThing", &Map::removeThing, &g_map); g_lua.bindSingletonFunction("g_map", "removeThing", &Map::removeThing, &g_map);
g_lua.bindSingletonFunction("g_map", "colorizeThing", &Map::colorizeThing, &g_map);
g_lua.bindSingletonFunction("g_map", "removeThingColor", &Map::removeThingColor, &g_map);
g_lua.bindSingletonFunction("g_map", "clean", &Map::clean, &g_map); g_lua.bindSingletonFunction("g_map", "clean", &Map::clean, &g_map);
g_lua.bindSingletonFunction("g_map", "cleanTile", &Map::cleanTile, &g_map); g_lua.bindSingletonFunction("g_map", "cleanTile", &Map::cleanTile, &g_map);
g_lua.bindSingletonFunction("g_map", "cleanTexts", &Map::cleanTexts, &g_map); g_lua.bindSingletonFunction("g_map", "cleanTexts", &Map::cleanTexts, &g_map);
@@ -128,20 +119,6 @@ void Client::registerLuaFunctions()
g_lua.bindSingletonFunction("g_map", "setSpawnFile", &Map::setSpawnFile, &g_map); g_lua.bindSingletonFunction("g_map", "setSpawnFile", &Map::setSpawnFile, &g_map);
g_lua.bindSingletonFunction("g_map", "createTile", &Map::createTile, &g_map); g_lua.bindSingletonFunction("g_map", "createTile", &Map::createTile, &g_map);
g_lua.bindSingletonFunction("g_map", "getSize", &Map::getSize, &g_map); g_lua.bindSingletonFunction("g_map", "getSize", &Map::getSize, &g_map);
g_lua.bindSingletonFunction("g_map", "setDescription", &Map::setDescription, &g_map);
g_lua.bindSingletonFunction("g_map", "getDescriptions", &Map::getDescriptions, &g_map);
g_lua.bindSingletonFunction("g_map", "clearDescriptions", &Map::clearDescriptions, &g_map);
g_lua.bindSingletonFunction("g_map", "setShowZone", &Map::setShowZone, &g_map);
g_lua.bindSingletonFunction("g_map", "setShowZones", &Map::setShowZones, &g_map);
g_lua.bindSingletonFunction("g_map", "setZoneColor", &Map::setZoneColor, &g_map);
g_lua.bindSingletonFunction("g_map", "setZoneOpacity", &Map::setZoneOpacity, &g_map);
g_lua.bindSingletonFunction("g_map", "getZoneOpacity", &Map::getZoneOpacity, &g_map);
g_lua.bindSingletonFunction("g_map", "getZoneColor", &Map::getZoneColor, &g_map);
g_lua.bindSingletonFunction("g_map", "showZones", &Map::showZones, &g_map);
g_lua.bindSingletonFunction("g_map", "showZone", &Map::showZone, &g_map);
g_lua.bindSingletonFunction("g_map", "beginGhostMode", &Map::beginGhostMode, &g_map);
g_lua.bindSingletonFunction("g_map", "endGhostMode", &Map::endGhostMode, &g_map);
g_lua.bindSingletonFunction("g_map", "findItemsById", &Map::findItemsById, &g_map);
g_lua.registerSingletonClass("g_minimap"); g_lua.registerSingletonClass("g_minimap");
g_lua.bindSingletonFunction("g_minimap", "clean", &Minimap::clean, &g_minimap); g_lua.bindSingletonFunction("g_minimap", "clean", &Minimap::clean, &g_minimap);
@@ -185,7 +162,6 @@ void Client::registerLuaFunctions()
g_lua.bindSingletonFunction("g_game", "useWith", &Game::useWith, &g_game); g_lua.bindSingletonFunction("g_game", "useWith", &Game::useWith, &g_game);
g_lua.bindSingletonFunction("g_game", "useInventoryItem", &Game::useInventoryItem, &g_game); g_lua.bindSingletonFunction("g_game", "useInventoryItem", &Game::useInventoryItem, &g_game);
g_lua.bindSingletonFunction("g_game", "useInventoryItemWith", &Game::useInventoryItemWith, &g_game); g_lua.bindSingletonFunction("g_game", "useInventoryItemWith", &Game::useInventoryItemWith, &g_game);
g_lua.bindSingletonFunction("g_game", "findItemInContainers", &Game::findItemInContainers, &g_game);
g_lua.bindSingletonFunction("g_game", "open", &Game::open, &g_game); g_lua.bindSingletonFunction("g_game", "open", &Game::open, &g_game);
g_lua.bindSingletonFunction("g_game", "openParent", &Game::openParent, &g_game); g_lua.bindSingletonFunction("g_game", "openParent", &Game::openParent, &g_game);
g_lua.bindSingletonFunction("g_game", "close", &Game::close, &g_game); g_lua.bindSingletonFunction("g_game", "close", &Game::close, &g_game);
@@ -254,7 +230,6 @@ void Client::registerLuaFunctions()
g_lua.bindSingletonFunction("g_game", "isDead", &Game::isDead, &g_game); g_lua.bindSingletonFunction("g_game", "isDead", &Game::isDead, &g_game);
g_lua.bindSingletonFunction("g_game", "isAttacking", &Game::isAttacking, &g_game); g_lua.bindSingletonFunction("g_game", "isAttacking", &Game::isAttacking, &g_game);
g_lua.bindSingletonFunction("g_game", "isFollowing", &Game::isFollowing, &g_game); g_lua.bindSingletonFunction("g_game", "isFollowing", &Game::isFollowing, &g_game);
g_lua.bindSingletonFunction("g_game", "isConnectionOk", &Game::isConnectionOk, &g_game);
g_lua.bindSingletonFunction("g_game", "getPing", &Game::getPing, &g_game); g_lua.bindSingletonFunction("g_game", "getPing", &Game::getPing, &g_game);
g_lua.bindSingletonFunction("g_game", "getContainer", &Game::getContainer, &g_game); g_lua.bindSingletonFunction("g_game", "getContainer", &Game::getContainer, &g_game);
g_lua.bindSingletonFunction("g_game", "getContainers", &Game::getContainers, &g_game); g_lua.bindSingletonFunction("g_game", "getContainers", &Game::getContainers, &g_game);
@@ -318,10 +293,6 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<Container>("getContainerItem", &Container::getContainerItem); g_lua.bindClassMemberFunction<Container>("getContainerItem", &Container::getContainerItem);
g_lua.bindClassMemberFunction<Container>("hasParent", &Container::hasParent); g_lua.bindClassMemberFunction<Container>("hasParent", &Container::hasParent);
g_lua.bindClassMemberFunction<Container>("isClosed", &Container::isClosed); g_lua.bindClassMemberFunction<Container>("isClosed", &Container::isClosed);
g_lua.bindClassMemberFunction<Container>("isUnlocked", &Container::isUnlocked);
g_lua.bindClassMemberFunction<Container>("hasPages", &Container::hasPages);
g_lua.bindClassMemberFunction<Container>("getSize", &Container::getSize);
g_lua.bindClassMemberFunction<Container>("getFirstIndex", &Container::getFirstIndex);
g_lua.registerClass<Thing>(); g_lua.registerClass<Thing>();
g_lua.bindClassMemberFunction<Thing>("setId", &Thing::setId); g_lua.bindClassMemberFunction<Thing>("setId", &Thing::setId);
@@ -364,7 +335,6 @@ void Client::registerLuaFunctions()
g_lua.registerClass<House>(); g_lua.registerClass<House>();
g_lua.bindClassStaticFunction<House>("create", []{ return HousePtr(new House); }); g_lua.bindClassStaticFunction<House>("create", []{ return HousePtr(new House); });
g_lua.bindClassMemberFunction<House>("setId", &House::setId); g_lua.bindClassMemberFunction<House>("setId", &House::setId);
g_lua.bindClassMemberFunction<House>("getId", &House::getId);
g_lua.bindClassMemberFunction<House>("setName", &House::setName); g_lua.bindClassMemberFunction<House>("setName", &House::setName);
g_lua.bindClassMemberFunction<House>("getName", &House::getName); g_lua.bindClassMemberFunction<House>("getName", &House::getName);
g_lua.bindClassMemberFunction<House>("setTownId", &House::setTownId); g_lua.bindClassMemberFunction<House>("setTownId", &House::setTownId);
@@ -373,9 +343,6 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<House>("getTile", &House::getTile); g_lua.bindClassMemberFunction<House>("getTile", &House::getTile);
g_lua.bindClassMemberFunction<House>("setEntry", &House::setEntry); g_lua.bindClassMemberFunction<House>("setEntry", &House::setEntry);
g_lua.bindClassMemberFunction<House>("getEntry", &House::getEntry); g_lua.bindClassMemberFunction<House>("getEntry", &House::getEntry);
g_lua.bindClassMemberFunction<House>("addDoor", &House::addDoor);
g_lua.bindClassMemberFunction<House>("removeDoor", &House::removeDoor);
g_lua.bindClassMemberFunction<House>("removeDoorById", &House::removeDoorById);
g_lua.bindClassMemberFunction<House>("setSize", &House::setSize); g_lua.bindClassMemberFunction<House>("setSize", &House::setSize);
g_lua.bindClassMemberFunction<House>("getSize", &House::getSize); g_lua.bindClassMemberFunction<House>("getSize", &House::getSize);
g_lua.bindClassMemberFunction<House>("setRent", &House::setRent); g_lua.bindClassMemberFunction<House>("setRent", &House::setRent);
@@ -455,12 +422,9 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<Item>("clone", &Item::clone); g_lua.bindClassMemberFunction<Item>("clone", &Item::clone);
g_lua.bindClassMemberFunction<Item>("setCount", &Item::setCount); g_lua.bindClassMemberFunction<Item>("setCount", &Item::setCount);
g_lua.bindClassMemberFunction<Item>("getCount", &Item::getCount); g_lua.bindClassMemberFunction<Item>("getCount", &Item::getCount);
g_lua.bindClassMemberFunction<Item>("getSubType", &Item::getSubType);
g_lua.bindClassMemberFunction<Item>("getId", &Item::getId); g_lua.bindClassMemberFunction<Item>("getId", &Item::getId);
g_lua.bindClassMemberFunction<Item>("getName", &Item::getName);
g_lua.bindClassMemberFunction<Item>("isStackable", &Item::isStackable); g_lua.bindClassMemberFunction<Item>("isStackable", &Item::isStackable);
g_lua.bindClassMemberFunction<Item>("isMarketable", &Item::isMarketable); g_lua.bindClassMemberFunction<Item>("isMarketable", &Item::isMarketable);
g_lua.bindClassMemberFunction<Item>("isFluidContainer", &Item::isFluidContainer);
g_lua.bindClassMemberFunction<Item>("getMarketData", &Item::getMarketData); g_lua.bindClassMemberFunction<Item>("getMarketData", &Item::getMarketData);
g_lua.bindClassMemberFunction<Item>("getClothSlot", &Item::getClothSlot); g_lua.bindClassMemberFunction<Item>("getClothSlot", &Item::getClothSlot);
@@ -557,10 +521,6 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<Tile>("isClickable", &Tile::isClickable); g_lua.bindClassMemberFunction<Tile>("isClickable", &Tile::isClickable);
g_lua.bindClassMemberFunction<Tile>("isPathable", &Tile::isPathable); g_lua.bindClassMemberFunction<Tile>("isPathable", &Tile::isPathable);
g_lua.bindClassMemberFunction<Tile>("overwriteMinimapColor", &Tile::overwriteMinimapColor); g_lua.bindClassMemberFunction<Tile>("overwriteMinimapColor", &Tile::overwriteMinimapColor);
g_lua.bindClassMemberFunction<Tile>("setFlag", &Tile::setFlag);
g_lua.bindClassMemberFunction<Tile>("setFlags", &Tile::setFlags);
g_lua.bindClassMemberFunction<Tile>("getFlags", &Tile::getFlags);
g_lua.bindClassMemberFunction<Tile>("hasFlag", &Tile::hasFlag);
g_lua.registerClass<UIItem, UIWidget>(); g_lua.registerClass<UIItem, UIWidget>();
g_lua.bindClassStaticFunction<UIItem>("create", []{ return UIItemPtr(new UIItem); }); g_lua.bindClassStaticFunction<UIItem>("create", []{ return UIItemPtr(new UIItem); });
@@ -578,13 +538,6 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIItem>("isVirtual", &UIItem::isVirtual); g_lua.bindClassMemberFunction<UIItem>("isVirtual", &UIItem::isVirtual);
g_lua.bindClassMemberFunction<UIItem>("isItemVisible", &UIItem::isItemVisible); g_lua.bindClassMemberFunction<UIItem>("isItemVisible", &UIItem::isItemVisible);
g_lua.registerClass<UISprite, UIWidget>();
g_lua.bindClassStaticFunction<UISprite>("create", []{ return UISpritePtr(new UISprite); });
g_lua.bindClassMemberFunction<UISprite>("setSpriteId", &UISprite::setSpriteId);
g_lua.bindClassMemberFunction<UISprite>("clearSprite", &UISprite::clearSprite);
g_lua.bindClassMemberFunction<UISprite>("getSpriteId", &UISprite::getSpriteId);
g_lua.bindClassMemberFunction<UISprite>("setSpriteColor", &UISprite::setSpriteColor);
g_lua.registerClass<UICreature, UIWidget>(); g_lua.registerClass<UICreature, UIWidget>();
g_lua.bindClassStaticFunction<UICreature>("create", []{ return UICreaturePtr(new UICreature); } ); g_lua.bindClassStaticFunction<UICreature>("create", []{ return UICreaturePtr(new UICreature); } );
g_lua.bindClassMemberFunction<UICreature>("setCreature", &UICreature::setCreature); g_lua.bindClassMemberFunction<UICreature>("setCreature", &UICreature::setCreature);
@@ -596,7 +549,6 @@ void Client::registerLuaFunctions()
g_lua.registerClass<UIMap, UIWidget>(); g_lua.registerClass<UIMap, UIWidget>();
g_lua.bindClassStaticFunction<UIMap>("create", []{ return UIMapPtr(new UIMap); }); g_lua.bindClassStaticFunction<UIMap>("create", []{ return UIMapPtr(new UIMap); });
g_lua.bindClassMemberFunction<UIMap>("drawSelf", &UIMap::drawSelf); g_lua.bindClassMemberFunction<UIMap>("drawSelf", &UIMap::drawSelf);
g_lua.bindClassMemberFunction<UIMap>("movePixels", &UIMap::movePixels);
g_lua.bindClassMemberFunction<UIMap>("setZoom", &UIMap::setZoom); g_lua.bindClassMemberFunction<UIMap>("setZoom", &UIMap::setZoom);
g_lua.bindClassMemberFunction<UIMap>("zoomIn", &UIMap::zoomIn); g_lua.bindClassMemberFunction<UIMap>("zoomIn", &UIMap::zoomIn);
g_lua.bindClassMemberFunction<UIMap>("zoomOut", &UIMap::zoomOut); g_lua.bindClassMemberFunction<UIMap>("zoomOut", &UIMap::zoomOut);
@@ -658,7 +610,7 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIMinimap>("getMinZoom", &UIMinimap::getMinZoom); g_lua.bindClassMemberFunction<UIMinimap>("getMinZoom", &UIMinimap::getMinZoom);
g_lua.bindClassMemberFunction<UIMinimap>("getMaxZoom", &UIMinimap::getMaxZoom); g_lua.bindClassMemberFunction<UIMinimap>("getMaxZoom", &UIMinimap::getMaxZoom);
g_lua.bindClassMemberFunction<UIMinimap>("getZoom", &UIMinimap::getZoom); g_lua.bindClassMemberFunction<UIMinimap>("getZoom", &UIMinimap::getZoom);
g_lua.bindClassMemberFunction<UIMinimap>("getScale", &UIMinimap::getScale); g_lua.bindClassMemberFunction<UIMinimap>("getScale", &UIMinimap::getScale);
g_lua.bindClassMemberFunction<UIMinimap>("anchorPosition", &UIMinimap::anchorPosition); g_lua.bindClassMemberFunction<UIMinimap>("anchorPosition", &UIMinimap::anchorPosition);
g_lua.bindClassMemberFunction<UIMinimap>("fillPosition", &UIMinimap::fillPosition); g_lua.bindClassMemberFunction<UIMinimap>("fillPosition", &UIMinimap::fillPosition);
g_lua.bindClassMemberFunction<UIMinimap>("centerInPosition", &UIMinimap::centerInPosition); g_lua.bindClassMemberFunction<UIMinimap>("centerInPosition", &UIMinimap::centerInPosition);

View File

@@ -216,42 +216,6 @@ bool Map::removeThingByPos(const Position& pos, int stackPos)
return false; return false;
} }
void Map::colorizeThing(const ThingPtr& thing, const Color& color)
{
if(!thing)
return;
if(thing->isItem())
thing->static_self_cast<Item>()->setColor(color);
else if(thing->isCreature()) {
const TilePtr& tile = thing->getTile();
assert(tile);
const ThingPtr& topThing = tile->getTopThing();
assert(topThing);
topThing->static_self_cast<Item>()->setColor(color);
}
}
void Map::removeThingColor(const ThingPtr& thing)
{
if(!thing)
return;
if(thing->isItem())
thing->static_self_cast<Item>()->setColor(Color::alpha);
else if(thing->isCreature()) {
const TilePtr& tile = thing->getTile();
assert(tile);
const ThingPtr& topThing = tile->getTopThing();
assert(topThing);
topThing->static_self_cast<Item>()->setColor(Color::alpha);
}
}
StaticTextPtr Map::getStaticText(const Position& pos) StaticTextPtr Map::getStaticText(const Position& pos)
{ {
for(auto staticText : m_staticTexts) { for(auto staticText : m_staticTexts) {
@@ -341,62 +305,6 @@ void Map::cleanTile(const Position& pos)
} }
} }
void Map::setShowZone(tileflags_t zone, bool show)
{
if(show)
m_zoneFlags |= (uint32)zone;
else
m_zoneFlags &= ~(uint32)zone;
}
void Map::setShowZones(bool show)
{
if(!show)
m_zoneFlags = 0;
else if(m_zoneFlags == 0)
m_zoneFlags = TILESTATE_HOUSE | TILESTATE_PROTECTIONZONE;
}
void Map::setZoneColor(tileflags_t zone, const Color& color)
{
if((m_zoneFlags & zone) == zone)
m_zoneColors[zone] = color;
}
void Map::beginGhostMode(float opacity)
{
g_painter->setOpacity(opacity);
}
void Map::endGhostMode()
{
g_painter->resetOpacity();
}
std::map<Position, ItemPtr> Map::findItemsById(uint16 clientId, uint32 max)
{
std::map<Position, ItemPtr> ret;
uint32 count = 0;
for(uint8_t z = 0; z <= Otc::MAX_Z; ++z) {
for(const auto& pair : m_tileBlocks[z]) {
const TileBlock& block = pair.second;
for(const TilePtr& tile : block.getTiles()) {
if(unlikely(!tile || tile->isEmpty()))
continue;
for(const ItemPtr& item : tile->getItems()) {
if(item->getId() == clientId) {
ret.insert(std::make_pair(tile->getPosition(), item));
if(++count >= max)
break;
}
}
}
}
}
return ret;
}
void Map::addCreature(const CreaturePtr& creature) void Map::addCreature(const CreaturePtr& creature)
{ {
m_knownCreatures[creature->getId()] = creature; m_knownCreatures[creature->getId()] = creature;
@@ -422,7 +330,7 @@ void Map::removeCreatureById(uint32 id)
void Map::removeUnawareThings() void Map::removeUnawareThings()
{ {
// remove creatures from tiles that we are not aware of anymore // remove creatures from tiles that we are not aware anymore
for(const auto& pair : m_knownCreatures) { for(const auto& pair : m_knownCreatures) {
const CreaturePtr& creature = pair.second; const CreaturePtr& creature = pair.second;
if(!isAwareOfPosition(creature->getPosition())) if(!isAwareOfPosition(creature->getPosition()))
@@ -800,5 +708,3 @@ std::tuple<std::vector<Otc::Direction>, Otc::PathFindResult> Map::findPath(const
return ret; return ret;
} }
/* vim: set ts=4 sw=4 et: */

View File

@@ -144,14 +144,13 @@ public:
bool loadOtcm(const std::string& fileName); bool loadOtcm(const std::string& fileName);
void saveOtcm(const std::string& fileName); void saveOtcm(const std::string& fileName);
void loadOtbm(const std::string& fileName); void loadOtbm(const std::string& fileName, const UIWidgetPtr& pbar = 0);
void saveOtbm(const std::string& fileName); void saveOtbm(const std::string& fileName, const UIWidgetPtr& pbar = 0);
// otbm attributes (description, size, etc.) // otbm attributes (description, size, etc.)
void setHouseFile(const std::string& file) { m_attribs.set(OTBM_ATTR_HOUSE_FILE, file); } void setHouseFile(const std::string& file) { m_attribs.set(OTBM_ATTR_HOUSE_FILE, file); }
void setSpawnFile(const std::string& file) { m_attribs.set(OTBM_ATTR_SPAWN_FILE, file); } void setSpawnFile(const std::string& file) { m_attribs.set(OTBM_ATTR_SPAWN_FILE, file); }
void setDescription(const std::string& desc) { m_attribs.set(OTBM_ATTR_DESCRIPTION, desc); } void setDescription(const std::string& desc) { m_attribs.set(OTBM_ATTR_DESCRIPTION, desc); }
void clearDescriptions() { m_attribs.remove(OTBM_ATTR_DESCRIPTION); }
void setWidth(uint16 w) { m_attribs.set(OTBM_ATTR_WIDTH, w); } void setWidth(uint16 w) { m_attribs.set(OTBM_ATTR_WIDTH, w); }
void setHeight(uint16 h) { m_attribs.set(OTBM_ATTR_HEIGHT, h); } void setHeight(uint16 h) { m_attribs.set(OTBM_ATTR_HEIGHT, h); }
@@ -169,8 +168,6 @@ public:
ThingPtr getThing(const Position& pos, int stackPos); ThingPtr getThing(const Position& pos, int stackPos);
bool removeThing(const ThingPtr& thing); bool removeThing(const ThingPtr& thing);
bool removeThingByPos(const Position& pos, int stackPos); bool removeThingByPos(const Position& pos, int stackPos);
void colorizeThing(const ThingPtr& thing, const Color& color);
void removeThingColor(const ThingPtr& thing);
StaticTextPtr getStaticText(const Position& pos); StaticTextPtr getStaticText(const Position& pos);
@@ -182,23 +179,6 @@ public:
const TilePtr& getTile(const Position& pos); const TilePtr& getTile(const Position& pos);
void cleanTile(const Position& pos); void cleanTile(const Position& pos);
// tile zone related
void setShowZone(tileflags_t zone, bool show);
void setShowZones(bool show);
void setZoneColor(tileflags_t flag, const Color& color);
void setZoneOpacity(float opacity) { m_zoneOpacity = opacity; }
float getZoneOpacity() { return m_zoneOpacity; }
Color getZoneColor(tileflags_t flag) { return m_zoneColors[flag]; }
tileflags_t getZoneFlags() { return (tileflags_t)m_zoneFlags; }
bool showZones() { return m_zoneFlags != 0; }
bool showZone(tileflags_t zone) { return (m_zoneFlags & zone) == zone; }
void beginGhostMode(float opacity);
void endGhostMode();
std::map<Position, ItemPtr> findItemsById(uint16 clientId, uint32 max);
// known creature related // known creature related
void addCreature(const CreaturePtr& creature); void addCreature(const CreaturePtr& creature);
CreaturePtr getCreatureById(uint32 id); CreaturePtr getCreatureById(uint32 id);
@@ -243,10 +223,6 @@ private:
std::vector<MapViewPtr> m_mapViews; std::vector<MapViewPtr> m_mapViews;
std::unordered_map<Position, std::string, PositionHasher> m_waypoints; std::unordered_map<Position, std::string, PositionHasher> m_waypoints;
uint32 m_zoneFlags;
std::array<Color, TILESTATE_LAST> m_zoneColors;
float m_zoneOpacity;
Light m_light; Light m_light;
Position m_centralPosition; Position m_centralPosition;
Rect m_tilesRect; Rect m_tilesRect;
@@ -259,5 +235,3 @@ private:
extern Map g_map; extern Map g_map;
#endif #endif
/* vim: set ts=4 sw=4 et: */

View File

@@ -32,373 +32,364 @@
#include <framework/xml/tinyxml.h> #include <framework/xml/tinyxml.h>
#include <framework/ui/uiwidget.h> #include <framework/ui/uiwidget.h>
void Map::loadOtbm(const std::string& fileName) void Map::loadOtbm(const std::string& fileName, const UIWidgetPtr& pbar)
{ {
try { FileStreamPtr fin = g_resources.openFile(fileName);
FileStreamPtr fin = g_resources.openFile(fileName); if(!fin)
if(!fin) stdext::throw_exception(stdext::format("Unable to load map '%s'", fileName));
stdext::throw_exception(stdext::format("Unable to load map '%s'", fileName));
fin->cache(); fin->cache();
if(!g_things.isOtbLoaded()) if(!g_things.isOtbLoaded())
stdext::throw_exception("OTB isn't loaded yet to load a map."); stdext::throw_exception("OTB isn't loaded yet to load a map.");
if(fin->getU32()) if(fin->getU32())
stdext::throw_exception("Unknown file version detected"); stdext::throw_exception("Unknown file version detected");
BinaryTreePtr root = fin->getBinaryTree(); BinaryTreePtr root = fin->getBinaryTree();
if(root->getU8()) if(root->getU8())
stdext::throw_exception("could not read root property!"); stdext::throw_exception("could not read root property!");
uint32 headerVersion = root->getU32(); uint32 headerVersion = root->getU32();
if(headerVersion > 3) if(headerVersion > 3)
stdext::throw_exception(stdext::format("Unknown OTBM version detected: %u.", headerVersion)); stdext::throw_exception(stdext::format("Unknown OTBM version detected: %u.", headerVersion));
setWidth(root->getU16()); setWidth(root->getU16());
setHeight(root->getU16()); setHeight(root->getU16());
uint32 headerMajorItems = root->getU8(); uint32 headerMajorItems = root->getU8();
if(headerMajorItems > g_things.getOtbMajorVersion()) { if(headerMajorItems > g_things.getOtbMajorVersion()) {
stdext::throw_exception(stdext::format("This map was saved with different OTB version. read %d what it's supposed to be: %d", stdext::throw_exception(stdext::format("This map was saved with different OTB version. read %d what it's supposed to be: %d",
headerMajorItems, g_things.getOtbMajorVersion())); headerMajorItems, g_things.getOtbMajorVersion()));
}
root->skip(3);
uint32 headerMinorItems = root->getU32();
if(headerMinorItems > g_things.getOtbMinorVersion()) {
g_logger.warning(stdext::format("This map needs an updated OTB. read %d what it's supposed to be: %d or less",
headerMinorItems, g_things.getOtbMinorVersion()));
}
BinaryTreePtr node = root->getChildren()[0];
if(node->getU8() != OTBM_MAP_DATA)
stdext::throw_exception("Could not read root data node");
while(node->canRead()) {
uint8 attribute = node->getU8();
std::string tmp = node->getString();
switch (attribute) {
case OTBM_ATTR_DESCRIPTION:
setDescription(tmp);
break;
case OTBM_ATTR_SPAWN_FILE:
setSpawnFile(fileName.substr(0, fileName.rfind('/') + 1) + tmp);
break;
case OTBM_ATTR_HOUSE_FILE:
setHouseFile(fileName.substr(0, fileName.rfind('/') + 1) + tmp);
break;
default:
stdext::throw_exception(stdext::format("Invalid attribute '%d'", (int)attribute));
}
}
for(const BinaryTreePtr& nodeMapData : node->getChildren()) {
uint8 mapDataType = nodeMapData->getU8();
if(mapDataType == OTBM_TILE_AREA) {
Position basePos;
basePos.x = nodeMapData->getU16();
basePos.y = nodeMapData->getU16();
basePos.z = nodeMapData->getU8();
for(const BinaryTreePtr &nodeTile : nodeMapData->getChildren()) {
uint8 type = nodeTile->getU8();
if(unlikely(type != OTBM_TILE && type != OTBM_HOUSETILE))
stdext::throw_exception(stdext::format("invalid node tile type %d", (int)type));
HousePtr house = nullptr;
uint32 flags = TILESTATE_NONE;
Position pos = basePos + nodeTile->getPoint();
if(type == OTBM_HOUSETILE) {
uint32 hId = nodeTile->getU32();
TilePtr tile = getOrCreateTile(pos);
if(!(house = g_houses.getHouse(hId))) {
house = HousePtr(new House(hId));
g_houses.addHouse(house);
}
house->setTile(tile);
}
while(nodeTile->canRead()) {
uint8 tileAttr = nodeTile->getU8();
switch(tileAttr) {
case OTBM_ATTR_TILE_FLAGS: {
uint32 _flags = nodeTile->getU32();
if((_flags & TILESTATE_PROTECTIONZONE) == TILESTATE_PROTECTIONZONE)
flags |= TILESTATE_PROTECTIONZONE;
else if((_flags & TILESTATE_OPTIONALZONE) == TILESTATE_OPTIONALZONE)
flags |= TILESTATE_OPTIONALZONE;
else if((_flags & TILESTATE_HARDCOREZONE) == TILESTATE_HARDCOREZONE)
flags |= TILESTATE_HARDCOREZONE;
if((_flags & TILESTATE_NOLOGOUT) == TILESTATE_NOLOGOUT)
flags |= TILESTATE_NOLOGOUT;
if((_flags & TILESTATE_REFRESH) == TILESTATE_REFRESH)
flags |= TILESTATE_REFRESH;
if((_flags & TILESTATE_HOUSE) == TILESTATE_HOUSE)
flags |= TILESTATE_HOUSE;
break;
}
case OTBM_ATTR_ITEM: {
addThing(Item::createFromOtb(nodeTile->getU16()), pos);
break;
}
default: {
stdext::throw_exception(stdext::format("invalid tile attribute %d at pos %s",
(int)tileAttr, stdext::to_string(pos)));
}
}
}
for(const BinaryTreePtr& nodeItem : nodeTile->getChildren()) {
if(unlikely(nodeItem->getU8() != OTBM_ITEM))
stdext::throw_exception("invalid item node");
ItemPtr item = Item::createFromOtb(nodeItem->getU16());
item->unserializeItem(nodeItem);
if(item->isContainer()) {
for(const BinaryTreePtr& containerItem : nodeItem->getChildren()) {
if(containerItem->getU8() != OTBM_ITEM)
stdext::throw_exception("invalid container item node");
ItemPtr cItem = Item::createFromOtb(containerItem->getU16());
cItem->unserializeItem(containerItem);
item->addContainerItem(cItem);
}
}
if(house && item->isMoveable()) {
g_logger.warning(stdext::format("Moveable item found in house: %d at pos %s - escaping...", item->getId(), stdext::to_string(pos)));
item.reset();
}
addThing(item, pos);
}
if(const TilePtr& tile = getTile(pos)) {
if(tile->hasFlag(TILESTATE_HOUSE))
tile->setFlags(tile->getFlags() & ~TILESTATE_HOUSE);
tile->setFlags((tileflags_t)flags);
}
}
} else if(mapDataType == OTBM_TOWNS) {
TownPtr town = nullptr;
for(const BinaryTreePtr &nodeTown : nodeMapData->getChildren()) {
if(nodeTown->getU8() != OTBM_TOWN)
stdext::throw_exception("invalid town node.");
uint32 townId = nodeTown->getU32();
std::string townName = nodeTown->getString();
Position townCoords;
townCoords.x = nodeTown->getU16();
townCoords.y = nodeTown->getU16();
townCoords.z = nodeTown->getU8();
if(!(town = g_towns.getTown(townId)))
g_towns.addTown(TownPtr(new Town(townId, townName, townCoords)));
}
} else if(mapDataType == OTBM_WAYPOINTS && headerVersion > 1) {
for(const BinaryTreePtr &nodeWaypoint : nodeMapData->getChildren()) {
if(nodeWaypoint->getU8() != OTBM_WAYPOINT)
stdext::throw_exception("invalid waypoint node.");
std::string name = nodeWaypoint->getString();
Position waypointPos;
waypointPos.x = nodeWaypoint->getU16();
waypointPos.y = nodeWaypoint->getU16();
waypointPos.z = nodeWaypoint->getU8();
if(waypointPos.isValid() && !name.empty() && m_waypoints.find(waypointPos) == m_waypoints.end())
m_waypoints.insert(std::make_pair(waypointPos, name));
}
} else
stdext::throw_exception(stdext::format("Unknown map data node %d", (int)mapDataType));
}
fin->close();
} catch(std::exception& e) {
g_logger.error(stdext::format("Failed to load '%s': %s", fileName, e.what()));
} }
root->skip(3);
uint32 headerMinorItems = root->getU32();
if(headerMinorItems > g_things.getOtbMinorVersion()) {
g_logger.warning(stdext::format("This map needs an updated OTB. read %d what it's supposed to be: %d or less",
headerMinorItems, g_things.getOtbMinorVersion()));
}
BinaryTreePtr node = root->getChildren()[0];
if(node->getU8() != OTBM_MAP_DATA)
stdext::throw_exception("Could not read root data node");
while (node->canRead()) {
uint8 attribute = node->getU8();
std::string tmp = node->getString();
switch (attribute) {
case OTBM_ATTR_DESCRIPTION:
setDescription(tmp);
break;
case OTBM_ATTR_SPAWN_FILE:
setSpawnFile(fileName.substr(0, fileName.rfind('/') + 1) + tmp);
break;
case OTBM_ATTR_HOUSE_FILE:
setHouseFile(fileName.substr(0, fileName.rfind('/') + 1) + tmp);
break;
default:
stdext::throw_exception(stdext::format("Invalid attribute '%d'", (int)attribute));
}
}
for(const BinaryTreePtr& nodeMapData : node->getChildren()) {
uint8 mapDataType = nodeMapData->getU8();
if(mapDataType == OTBM_TILE_AREA) {
Position basePos;
basePos.x = nodeMapData->getU16();
basePos.y = nodeMapData->getU16();
basePos.z = nodeMapData->getU8();
for(const BinaryTreePtr &nodeTile : nodeMapData->getChildren()) {
uint8 type = nodeTile->getU8();
if(type != OTBM_TILE && type != OTBM_HOUSETILE)
stdext::throw_exception(stdext::format("invalid node tile type %d", (int)type));
HousePtr house = nullptr;
uint32 flags = TILESTATE_NONE;
Position pos = basePos + nodeTile->getPoint();
if(type == OTBM_HOUSETILE) {
uint32 hId = nodeTile->getU32();
TilePtr tile = getOrCreateTile(pos);
if(!(house = g_houses.getHouse(hId))) {
house = HousePtr(new House(hId));
g_houses.addHouse(house);
}
house->setTile(tile);
}
while(nodeTile->canRead()) {
uint8 tileAttr = nodeTile->getU8();
switch (tileAttr) {
case OTBM_ATTR_TILE_FLAGS: {
uint32 _flags = nodeTile->getU32();
if((_flags & TILESTATE_PROTECTIONZONE) == TILESTATE_PROTECTIONZONE)
flags |= TILESTATE_PROTECTIONZONE;
else if((_flags & TILESTATE_OPTIONALZONE) == TILESTATE_OPTIONALZONE)
flags |= TILESTATE_OPTIONALZONE;
else if((_flags & TILESTATE_HARDCOREZONE) == TILESTATE_HARDCOREZONE)
flags |= TILESTATE_HARDCOREZONE;
if((_flags & TILESTATE_NOLOGOUT) == TILESTATE_NOLOGOUT)
flags |= TILESTATE_NOLOGOUT;
if((_flags & TILESTATE_REFRESH) == TILESTATE_REFRESH)
flags |= TILESTATE_REFRESH;
break;
}
case OTBM_ATTR_ITEM: {
addThing(Item::createFromOtb(nodeTile->getU16()), pos);
break;
}
default: {
stdext::throw_exception(stdext::format("invalid tile attribute %d at pos %s",
(int)tileAttr, stdext::to_string(pos)));
}
}
}
for(const BinaryTreePtr& nodeItem : nodeTile->getChildren()) {
if(nodeItem->getU8() != OTBM_ITEM)
stdext::throw_exception("invalid item node");
ItemPtr item = Item::createFromOtb(nodeItem->getU16());
item->unserializeItem(nodeItem);
if(item->isContainer()) {
for(const BinaryTreePtr& containerItem : nodeItem->getChildren()) {
if(containerItem->getU8() != OTBM_ITEM)
stdext::throw_exception("invalid container item node");
ItemPtr cItem = Item::createFromOtb(containerItem->getU16());
cItem->unserializeItem(containerItem);
item->addContainerItem(cItem);
}
}
if(house && item->isMoveable()) {
g_logger.warning(stdext::format("Moveable item found in house: %d at pos %s - escaping...", item->getId(), stdext::to_string(pos)));
item.reset();
}
addThing(item, pos);
}
if(const TilePtr& tile = getTile(pos)) {
if(house)
tile->setHouseId(house->getId());
tile->setFlags((tileflags_t)flags);
//if(!(++pbarvalue % 8192) && pbar);
}
}
} else if(mapDataType == OTBM_TOWNS) {
TownPtr town = nullptr;
for(const BinaryTreePtr &nodeTown : nodeMapData->getChildren()) {
if(nodeTown->getU8() != OTBM_TOWN)
stdext::throw_exception("invalid town node.");
uint32 townId = nodeTown->getU32();
std::string townName = nodeTown->getString();
Position townCoords;
townCoords.x = nodeTown->getU16();
townCoords.y = nodeTown->getU16();
townCoords.z = nodeTown->getU8();
if(!(town = g_towns.getTown(townId))) {
town = TownPtr(new Town(townId, townName, townCoords));
g_towns.addTown(town);
}
}
} else if(mapDataType == OTBM_WAYPOINTS && headerVersion > 1) {
for(const BinaryTreePtr &nodeWaypoint : nodeMapData->getChildren()) {
if(nodeWaypoint->getU8() != OTBM_WAYPOINT)
stdext::throw_exception("invalid waypoint node.");
std::string name = nodeWaypoint->getString();
Position waypointPos;
waypointPos.x = nodeWaypoint->getU16();
waypointPos.y = nodeWaypoint->getU16();
waypointPos.z = nodeWaypoint->getU8();
if(waypointPos.isValid() && !name.empty() && m_waypoints.find(waypointPos) == m_waypoints.end())
m_waypoints.insert(std::make_pair(waypointPos, name));
}
} else
stdext::throw_exception(stdext::format("Unknown map data node %d", (int)mapDataType));
}
fin->close();
} }
void Map::saveOtbm(const std::string& fileName) void Map::saveOtbm(const std::string& fileName, const UIWidgetPtr&/* pbar*/)
{ {
try { FileStreamPtr fin = g_resources.createFile(fileName);
FileStreamPtr fin = g_resources.createFile(fileName); if(!fin)
if(!fin) stdext::throw_exception(stdext::format("failed to open file '%s' for write", fileName));
stdext::throw_exception(stdext::format("failed to open file '%s' for write", fileName));
fin->cache(); fin->cache();
std::string dir; std::string dir;
if(fileName.find_last_of('/') == std::string::npos) if(fileName.find_last_of('/') == std::string::npos)
dir = g_resources.getWorkDir(); dir = g_resources.getWorkDir();
else else
dir = fileName.substr(0, fileName.find_last_of('/')); dir = fileName.substr(0, fileName.find_last_of('/'));
uint32 version = 0; uint32 version = 0;
if(g_things.getOtbMajorVersion() < ClientVersion820) if(g_things.getOtbMajorVersion() < ClientVersion820)
version = 1; version = 1;
else else
version = 2; version = 2;
/// Usually when a map has empty house/spawn file it means the map is new. /// Usually when a map has empty house/spawn file it means the map is new.
/// TODO: Ask the user for a map name instead of those ugly uses of substr /// TODO: Ask the user for a map name instead of those ugly uses of substr
std::string::size_type sep_pos; std::string::size_type sep_pos;
std::string houseFile = getHouseFile(); std::string houseFile = getHouseFile();
std::string spawnFile = getSpawnFile(); std::string spawnFile = getSpawnFile();
std::string cpyf; std::string cpyf;
if((sep_pos = fileName.rfind('.')) != std::string::npos && stdext::ends_with(fileName, ".otbm")) if((sep_pos = fileName.rfind('.')) != std::string::npos && stdext::ends_with(fileName, ".otbm"))
cpyf = fileName.substr(0, sep_pos); cpyf = fileName.substr(0, sep_pos);
if(houseFile.empty()) if(houseFile.empty())
houseFile = cpyf + "-houses.xml"; houseFile = cpyf + "-houses.xml";
if(spawnFile.empty()) if(spawnFile.empty())
spawnFile = cpyf + "-spawns.xml"; spawnFile = cpyf + "-spawns.xml";
/// we only need the filename to save to, the directory should be resolved by the OTBM loader not here /// we only need the filename to save to, the directory should be resolved by the OTBM loader not here
if((sep_pos = spawnFile.rfind('/')) != std::string::npos) if((sep_pos = spawnFile.rfind('/')) != std::string::npos)
spawnFile = spawnFile.substr(sep_pos + 1); spawnFile = spawnFile.substr(sep_pos + 1);
if((sep_pos = houseFile.rfind('/')) != std::string::npos) if((sep_pos = houseFile.rfind('/')) != std::string::npos)
houseFile = houseFile.substr(sep_pos + 1); houseFile = houseFile.substr(sep_pos + 1);
fin->addU32(0); // file version fin->addU32(0); // file version
OutputBinaryTreePtr root(new OutputBinaryTree(fin)); OutputBinaryTreePtr root(new OutputBinaryTree(fin));
{
root->addU32(version);
Size mapSize = getSize();
root->addU16(mapSize.width());
root->addU16(mapSize.height());
root->addU32(g_things.getOtbMajorVersion());
root->addU32(g_things.getOtbMinorVersion());
root->startNode(OTBM_MAP_DATA);
{ {
root->addU32(version); // own description.
for(const auto& desc : getDescriptions()) {
Size mapSize = getSize();
root->addU16(mapSize.width());
root->addU16(mapSize.height());
root->addU32(g_things.getOtbMajorVersion());
root->addU32(g_things.getOtbMinorVersion());
root->startNode(OTBM_MAP_DATA);
{
// own description.
for(const auto& desc : getDescriptions()) {
root->addU8(OTBM_ATTR_DESCRIPTION);
root->addString(desc);
}
// special one
root->addU8(OTBM_ATTR_DESCRIPTION); root->addU8(OTBM_ATTR_DESCRIPTION);
root->addString(stdext::format("Saved with %s v%s", g_app.getName(), g_app.getVersion())); root->addString(desc);
}
// spawn file. // special one
root->addU8(OTBM_ATTR_SPAWN_FILE); root->addU8(OTBM_ATTR_DESCRIPTION);
root->addString(spawnFile); root->addString(stdext::format("Saved with %s v%s", g_app.getName(), g_app.getVersion()));
// house file. // spawn file.
root->addU8(OTBM_ATTR_SPAWN_FILE);
root->addString(spawnFile);
// house file.
if(version > 1) {
root->addU8(OTBM_ATTR_HOUSE_FILE); root->addU8(OTBM_ATTR_HOUSE_FILE);
root->addString(houseFile); root->addString(houseFile);
}
int px = -1, py = -1, pz =-1; int px = -1, py = -1, pz =-1;
bool firstNode = true; bool firstNode = true;
for(uint8_t z = 0; z <= Otc::MAX_Z; ++z) { for(uint8_t z = 0; z <= Otc::MAX_Z; ++z) {
for(const auto& it : m_tileBlocks[z]) { for(const auto& it : m_tileBlocks[z]) {
const TileBlock& block = it.second; const TileBlock& block = it.second;
for(const TilePtr& tile : block.getTiles()) { for(const TilePtr& tile : block.getTiles()) {
if(unlikely(!tile || tile->isEmpty())) if(!tile || tile->isEmpty())
continue; continue;
const Position& pos = tile->getPosition(); const Position& pos = tile->getPosition();
if(unlikely(!pos.isValid())) if(!pos.isValid())
continue; continue;
if(pos.x < px || pos.x >= px + 256 if(pos.x < px || pos.x >= px + 256
|| pos.y < py || pos.y >= py + 256 || pos.y < py || pos.y >= py + 256
|| pos.z != pz) { || pos.z != pz) {
if(!firstNode) if(!firstNode)
root->endNode(); /// OTBM_TILE_AREA root->endNode(); /// OTBM_TILE_AREA
firstNode = false; firstNode = false;
root->startNode(OTBM_TILE_AREA); root->startNode(OTBM_TILE_AREA);
px = pos.x & 0xFF00; px = pos.x & 0xFF00;
py = pos.y & 0xFF00; py = pos.y & 0xFF00;
pz = pos.z; pz = pos.z;
root->addPos(px, py, pz); root->addPos(px, py, pz);
}
root->startNode(tile->isHouseTile() ? OTBM_HOUSETILE : OTBM_TILE);
root->addPoint(Point(pos.x, pos.y) & 0xFF);
if(tile->isHouseTile())
root->addU32(tile->getHouseId());
if(tile->getFlags()) {
root->addU8(OTBM_ATTR_TILE_FLAGS);
root->addU32(tile->getFlags());
}
const auto& itemList = tile->getItems();
const ItemPtr& ground = tile->getGround();
if(ground) {
// Those types are called "complex" needs other stuff to be written.
// For containers, there is container items, for depot, depot it and so on.
if(!ground->isContainer() && !ground->isDepot()
&& !ground->isDoor() && !ground->isTeleport()) {
root->addU8(OTBM_ATTR_ITEM);
root->addU16(ground->getServerId());
} else
ground->serializeItem(root);
}
for(const ItemPtr& item : itemList)
if(!item->isGround())
item->serializeItem(root);
root->endNode(); // OTBM_TILE
} }
root->startNode(tile->isHouseTile() ? OTBM_HOUSETILE : OTBM_TILE);
root->addPoint(Point(pos.x, pos.y) & 0xFF);
if(tile->isHouseTile())
root->addU32(tile->getHouseId());
if(tile->getFlags()) {
root->addU8(OTBM_ATTR_TILE_FLAGS);
root->addU32(tile->getFlags());
}
const auto& itemList = tile->getItems();
const ItemPtr& ground = tile->getGround();
if(ground) {
// Those types are called "complex" needs other stuff to be written.
// For containers, there is container items, for depot, depot it and so on.
if(!ground->isContainer() && !ground->isDepot()
&& !ground->isDoor() && !ground->isTeleport()) {
root->addU8(OTBM_ATTR_ITEM);
root->addU16(ground->getServerId());
} else
ground->serializeItem(root);
}
for(const ItemPtr& item : itemList)
if(!item->isGround())
item->serializeItem(root);
root->endNode(); // OTBM_TILE
} }
} }
if(!firstNode)
root->endNode(); // OTBM_TILE_AREA
root->startNode(OTBM_TOWNS);
for(const TownPtr& town : g_towns.getTowns()) {
root->startNode(OTBM_TOWN);
root->addU32(town->getId());
root->addString(town->getName());
Position townPos = town->getPos();
root->addPos(townPos.x, townPos.y, townPos.z);
root->endNode();
}
root->endNode();
if(version > 1) {
root->startNode(OTBM_WAYPOINTS);
for(const auto& it : m_waypoints) {
root->startNode(OTBM_WAYPOINT);
root->addString(it.second);
Position pos = it.first;
root->addPos(pos.x, pos.y, pos.z);
root->endNode();
}
root->endNode();
}
} }
root->endNode(); // OTBM_MAP_DATA
}
root->endNode();
fin->flush(); if(!firstNode)
fin->close(); root->endNode(); // OTBM_TILE_AREA
} catch(std::exception& e) {
g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what())); root->startNode(OTBM_TOWNS);
for(const TownPtr& town : g_towns.getTowns()) {
root->addU32(town->getId());
root->addString(town->getName());
Position townPos = town->getPos();
root->addPos(townPos.x, townPos.y, townPos.z);
}
root->endNode();
if(version > 1) {
root->startNode(OTBM_WAYPOINTS);
for(const auto& it : m_waypoints) {
root->addString(it.second);
Position pos = it.first;
root->addPos(pos.x, pos.y, pos.z);
}
root->endNode();
}
}
root->endNode(); // OTBM_MAP_DATA
} }
root->endNode();
fin->flush();
fin->close();
} }
bool Map::loadOtcm(const std::string& fileName) bool Map::loadOtcm(const std::string& fileName)
@@ -546,5 +537,3 @@ void Map::saveOtcm(const std::string& fileName)
g_logger.error(stdext::format("failed to save OTCM map: %s", e.what())); g_logger.error(stdext::format("failed to save OTCM map: %s", e.what()));
} }
} }
/* vim: set ts=4 sw=4 et: */

View File

@@ -564,20 +564,12 @@ Position MapView::getPosition(const Point& point, const Size& mapSize)
return position; return position;
} }
void MapView::move(int x, int y)
{
m_moveOffset.x = x;
m_moveOffset.y = y;
}
Rect MapView::calcFramebufferSource(const Size& destSize) Rect MapView::calcFramebufferSource(const Size& destSize)
{ {
float scaleFactor = m_tileSize/(float)Otc::TILE_PIXELS; float scaleFactor = m_tileSize/(float)Otc::TILE_PIXELS;
Point drawOffset = ((m_drawDimension - m_visibleDimension - Size(1,1)).toPoint()/2) * m_tileSize; Point drawOffset = ((m_drawDimension - m_visibleDimension - Size(1,1)).toPoint()/2) * m_tileSize;
if(isFollowingCreature()) if(isFollowingCreature())
drawOffset += m_followingCreature->getWalkOffset() * scaleFactor; drawOffset += m_followingCreature->getWalkOffset() * scaleFactor;
else if(!m_moveOffset.isNull())
drawOffset += m_moveOffset * scaleFactor;
Size srcSize = destSize; Size srcSize = destSize;
Size srcVisible = m_visibleDimension * m_tileSize; Size srcVisible = m_visibleDimension * m_tileSize;
@@ -616,21 +608,21 @@ int MapView::calcFirstVisibleFloor()
Position pos = cameraPosition.translated(ix, iy); Position pos = cameraPosition.translated(ix, iy);
// process tiles that we can look through, e.g. windows, doors // process tiles that we can look through, e.g. windows, doors
if((ix == 0 && iy == 0) || ((std::abs(ix) != std::abs(iy)) && g_map.isLookPossible(pos))) { if((ix == 0 && iy == 0) || (/*(std::abs(ix) != std::abs(iy)) && */g_map.isLookPossible(pos))) {
Position upperPos = pos; Position upperPos = pos;
Position coveredPos = pos; Position coveredPos = pos;
while(coveredPos.coveredUp() && upperPos.up() && upperPos.z >= firstFloor) { while(coveredPos.coveredUp() && upperPos.up() && upperPos.z >= firstFloor) {
// check tiles physically above // check tiles physically above
TilePtr tile = g_map.getTile(upperPos); TilePtr tile = g_map.getTile(upperPos);
if(tile && tile->limitsFloorsView(!g_map.isLookPossible(pos))) { if(tile && tile->limitsFloorsView()) {
firstFloor = upperPos.z + 1; firstFloor = upperPos.z + 1;
break; break;
} }
// check tiles geometrically above // check tiles geometrically above
tile = g_map.getTile(coveredPos); tile = g_map.getTile(coveredPos);
if(tile && tile->limitsFloorsView(g_map.isLookPossible(pos))) { if(tile && tile->limitsFloorsView()) {
firstFloor = coveredPos.z + 1; firstFloor = coveredPos.z + 1;
break; break;
} }
@@ -711,5 +703,3 @@ void MapView::setDrawLights(bool enable)
m_lightView = nullptr; m_lightView = nullptr;
m_drawLights = enable; m_drawLights = enable;
} }
/* vim: set ts=4 sw=4 et: */

View File

@@ -108,8 +108,6 @@ public:
void setDrawLights(bool enable); void setDrawLights(bool enable);
bool isDrawingLights() { return m_drawLights; } bool isDrawingLights() { return m_drawLights; }
void move(int x, int y);
void setAnimated(bool animated) { m_animated = animated; requestVisibleTilesCacheUpdate(); } void setAnimated(bool animated) { m_animated = animated; requestVisibleTilesCacheUpdate(); }
bool isAnimating() { return m_animated; } bool isAnimating() { return m_animated; }
@@ -141,7 +139,6 @@ private:
Size m_optimizedSize; Size m_optimizedSize;
Point m_virtualCenterOffset; Point m_virtualCenterOffset;
Point m_visibleCenterOffset; Point m_visibleCenterOffset;
Point m_moveOffset;
Position m_customCameraPosition; Position m_customCameraPosition;
stdext::boolean<true> m_mustUpdateVisibleTilesCache; stdext::boolean<true> m_mustUpdateVisibleTilesCache;
stdext::boolean<true> m_mustDrawVisibleTilesCache; stdext::boolean<true> m_mustDrawVisibleTilesCache;

View File

@@ -29,6 +29,7 @@
#include <framework/graphics/painter.h> #include <framework/graphics/painter.h>
#include <framework/graphics/image.h> #include <framework/graphics/image.h>
#include <framework/graphics/framebuffermanager.h> #include <framework/graphics/framebuffermanager.h>
#include <framework/graphics/ogl/textureogl.h>
#include <framework/core/resourcemanager.h> #include <framework/core/resourcemanager.h>
#include <framework/core/filestream.h> #include <framework/core/filestream.h>
#include <zlib.h> #include <zlib.h>
@@ -65,7 +66,7 @@ void MinimapBlock::update()
if(shouldDraw) { if(shouldDraw) {
if(!m_texture) { if(!m_texture) {
m_texture = TexturePtr(new Texture(image, true)); m_texture = TexturePtr(new TextureOGL(image, true));
} else { } else {
m_texture->uploadPixels(image, true); m_texture->uploadPixels(image, true);
} }

View File

@@ -189,8 +189,6 @@ public:
bool isInRange(const Position& pos, int minXRange, int maxXRange, int minYRange, int maxYRange) const { bool isInRange(const Position& pos, int minXRange, int maxXRange, int minYRange, int maxYRange) const {
return (pos.x >= x-minXRange && pos.x <= x+maxXRange && pos.y >= y-minYRange && pos.y <= y+maxYRange && pos.z == z); return (pos.x >= x-minXRange && pos.x <= x+maxXRange && pos.y >= y-minYRange && pos.y <= y+maxYRange && pos.z == z);
} }
// operator less than for std::map
bool operator<(const Position& other) const { return x < other.x || y < other.y || z < other.z; }
bool up(int n = 1) { bool up(int n = 1) {
int nz = z-n; int nz = z-n;

View File

@@ -57,7 +57,7 @@ void buildMessageModesMap(int version) {
messageModesMap[Otc::MessageFailure] = 20; messageModesMap[Otc::MessageFailure] = 20;
messageModesMap[Otc::MessageBlue] = 21; messageModesMap[Otc::MessageBlue] = 21;
messageModesMap[Otc::MessageRed] = 22; messageModesMap[Otc::MessageRed] = 22;
} else if(version >= 850) { } else if(version >= 854) {
messageModesMap[Otc::MessageNone] = 0; messageModesMap[Otc::MessageNone] = 0;
messageModesMap[Otc::MessageSay] = 1; messageModesMap[Otc::MessageSay] = 1;
messageModesMap[Otc::MessageWhisper] = 2; messageModesMap[Otc::MessageWhisper] = 2;
@@ -87,7 +87,7 @@ void buildMessageModesMap(int version) {
messageModesMap[Otc::MessageLook] = 25; messageModesMap[Otc::MessageLook] = 25;
messageModesMap[Otc::MessageFailure] = 26; messageModesMap[Otc::MessageFailure] = 26;
messageModesMap[Otc::MessageBlue] = 27; messageModesMap[Otc::MessageBlue] = 27;
} else if(version >= 760) { } else if(version >= 810) {
messageModesMap[Otc::MessageNone] = 0; messageModesMap[Otc::MessageNone] = 0;
messageModesMap[Otc::MessageSay] = 1; messageModesMap[Otc::MessageSay] = 1;
messageModesMap[Otc::MessageWhisper] = 2; messageModesMap[Otc::MessageWhisper] = 2;

View File

@@ -102,8 +102,6 @@ namespace Proto {
GameServerCreatureSkull = 144, GameServerCreatureSkull = 144,
GameServerCreatureParty = 145, GameServerCreatureParty = 145,
GameServerCreatureUnpass = 146, GameServerCreatureUnpass = 146,
GameServerCreatureMarks = 147,
GameServerPlayerHelpers = 148,
GameServerEditText = 150, GameServerEditText = 150,
GameServerEditList = 151, GameServerEditList = 151,
GameServerPlayerDataBasic = 159, // 950 GameServerPlayerDataBasic = 159, // 950
@@ -111,7 +109,6 @@ namespace Proto {
GameServerPlayerSkills = 161, GameServerPlayerSkills = 161,
GameServerPlayerState = 162, GameServerPlayerState = 162,
GameServerClearTarget = 163, GameServerClearTarget = 163,
GameServerPlayerModes = 167,
GameServerSpellDelay = 164, // 870 GameServerSpellDelay = 164, // 870
GameServerSpellGroupDelay = 165, // 870 GameServerSpellGroupDelay = 165, // 870
GameServerMultiUseDelay = 166, // 870 GameServerMultiUseDelay = 166, // 870
@@ -250,9 +247,7 @@ namespace Proto {
enum CreatureType { enum CreatureType {
CreatureTypePlayer = 0, CreatureTypePlayer = 0,
CreatureTypeMonster, CreatureTypeMonster,
CreatureTypeNpc, CreatureTypeNpc
CreatureTypeSummonOwn,
CreatureTypeSummonOther
}; };
enum CreaturesIdRange { enum CreaturesIdRange {

View File

@@ -125,7 +125,6 @@ public:
void addPosition(const OutputMessagePtr& msg, const Position& position); void addPosition(const OutputMessagePtr& msg, const Position& position);
private: private:
void parsePlayerHelpers(const InputMessagePtr& msg);
void parseMessage(const InputMessagePtr& msg); void parseMessage(const InputMessagePtr& msg);
void parsePendingGame(const InputMessagePtr& msg); void parsePendingGame(const InputMessagePtr& msg);
void parseEnterGame(const InputMessagePtr& msg); void parseEnterGame(const InputMessagePtr& msg);
@@ -179,7 +178,6 @@ private:
void parsePlayerSkills(const InputMessagePtr& msg); void parsePlayerSkills(const InputMessagePtr& msg);
void parsePlayerState(const InputMessagePtr& msg); void parsePlayerState(const InputMessagePtr& msg);
void parsePlayerCancelAttack(const InputMessagePtr& msg); void parsePlayerCancelAttack(const InputMessagePtr& msg);
void parsePlayerModes(const InputMessagePtr& msg);
void parseSpellCooldown(const InputMessagePtr& msg); void parseSpellCooldown(const InputMessagePtr& msg);
void parseSpellGroupCooldown(const InputMessagePtr& msg); void parseSpellGroupCooldown(const InputMessagePtr& msg);
void parseMultiUseCooldown(const InputMessagePtr& msg); void parseMultiUseCooldown(const InputMessagePtr& msg);
@@ -215,7 +213,6 @@ private:
void parseShowModalDialog(const InputMessagePtr& msg); void parseShowModalDialog(const InputMessagePtr& msg);
void parseExtendedOpcode(const InputMessagePtr& msg); void parseExtendedOpcode(const InputMessagePtr& msg);
void parseChangeMapAwareRange(const InputMessagePtr& msg); void parseChangeMapAwareRange(const InputMessagePtr& msg);
void parseCreaturesMark(const InputMessagePtr& msg);
public: public:
void setMapDescription(const InputMessagePtr& msg, int x, int y, int z, int width, int height); void setMapDescription(const InputMessagePtr& msg, int x, int y, int z, int width, int height);

View File

@@ -219,9 +219,6 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg)
case Proto::GameServerClearTarget: case Proto::GameServerClearTarget:
parsePlayerCancelAttack(msg); parsePlayerCancelAttack(msg);
break; break;
case Proto::GameServerPlayerModes:
parsePlayerModes(msg);
break;
case Proto::GameServerTalk: case Proto::GameServerTalk:
parseTalk(msg); parseTalk(msg);
break; break;
@@ -326,13 +323,6 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg)
case Proto::GameServerEnterGame: case Proto::GameServerEnterGame:
parseEnterGame(msg); parseEnterGame(msg);
break; break;
case Proto::GameServerPlayerHelpers:
parsePlayerHelpers(msg);
break;
// PROTOCOL>=1000
case Proto::GameServerCreatureMarks:
parseCreaturesMark(msg);
break;
// otclient ONLY // otclient ONLY
case Proto::GameServerExtendedOpcode: case Proto::GameServerExtendedOpcode:
parseExtendedOpcode(msg); parseExtendedOpcode(msg);
@@ -389,25 +379,13 @@ void ProtocolGame::parseEnterGame(const InputMessagePtr& msg)
} }
} }
void ProtocolGame::parsePlayerHelpers(const InputMessagePtr& msg)
{
uint id = msg->getU32();
int helpers = msg->getU16();
CreaturePtr creature = g_map.getCreatureById(id);
if(creature)
g_game.processPlayerHelpers(helpers);
else
g_logger.traceError("could not get creature");
}
void ProtocolGame::parseGMActions(const InputMessagePtr& msg) void ProtocolGame::parseGMActions(const InputMessagePtr& msg)
{ {
std::vector<uint8> actions; std::vector<uint8> actions;
int numViolationReasons; int numViolationReasons;
if(g_game.getProtocolVersion() >= 850) if(g_game.getProtocolVersion() >= 854)
numViolationReasons = 20; numViolationReasons = 20;
else else
numViolationReasons = 32; numViolationReasons = 32;
@@ -557,7 +535,7 @@ void ProtocolGame::parseTileAddThing(const InputMessagePtr& msg)
Position pos = getPosition(msg); Position pos = getPosition(msg);
int stackPos = -1; int stackPos = -1;
if(g_game.getProtocolVersion() >= 850) if(g_game.getProtocolVersion() >= 854)
stackPos = msg->getU8(); stackPos = msg->getU8();
ThingPtr thing = getThing(msg); ThingPtr thing = getThing(msg);
@@ -625,26 +603,13 @@ void ProtocolGame::parseOpenContainer(const InputMessagePtr& msg)
std::string name = msg->getString(); std::string name = msg->getString();
int capacity = msg->getU8(); int capacity = msg->getU8();
bool hasParent = (msg->getU8() != 0); bool hasParent = (msg->getU8() != 0);
bool isUnlocked = false;
bool hasPages = false;
int containerSize = 0;
int firstIndex = 0;
if(g_game.getFeature(Otc::GameContainerPagination)) {
isUnlocked = (msg->getU8() != 0); // drag and drop
hasPages = (msg->getU8() != 0); // pagination
containerSize = msg->getU16(); // container size
firstIndex = msg->getU16(); // first index
}
int itemCount = msg->getU8(); int itemCount = msg->getU8();
std::vector<ItemPtr> items(itemCount); std::vector<ItemPtr> items(itemCount);
for(int i = 0; i < itemCount; i++) for(int i = 0; i < itemCount; i++)
items[i] = getItem(msg); items[i] = getItem(msg);
g_game.processOpenContainer(containerId, containerItem, name, capacity, hasParent, items, isUnlocked, hasPages, containerSize, firstIndex); g_game.processOpenContainer(containerId, containerItem, name, capacity, hasParent, items);
} }
void ProtocolGame::parseCloseContainer(const InputMessagePtr& msg) void ProtocolGame::parseCloseContainer(const InputMessagePtr& msg)
@@ -656,23 +621,14 @@ void ProtocolGame::parseCloseContainer(const InputMessagePtr& msg)
void ProtocolGame::parseContainerAddItem(const InputMessagePtr& msg) void ProtocolGame::parseContainerAddItem(const InputMessagePtr& msg)
{ {
int containerId = msg->getU8(); int containerId = msg->getU8();
int slot = 0;
if(g_game.getFeature(Otc::GameContainerPagination)) {
slot = msg->getU16(); // slot
}
ItemPtr item = getItem(msg); ItemPtr item = getItem(msg);
g_game.processContainerAddItem(containerId, item, slot); g_game.processContainerAddItem(containerId, item);
} }
void ProtocolGame::parseContainerUpdateItem(const InputMessagePtr& msg) void ProtocolGame::parseContainerUpdateItem(const InputMessagePtr& msg)
{ {
int containerId = msg->getU8(); int containerId = msg->getU8();
int slot; int slot = msg->getU8();
if(g_game.getFeature(Otc::GameContainerPagination)) {
slot = msg->getU16();
} else {
slot = msg->getU8();
}
ItemPtr item = getItem(msg); ItemPtr item = getItem(msg);
g_game.processContainerUpdateItem(containerId, slot, item); g_game.processContainerUpdateItem(containerId, slot, item);
} }
@@ -680,16 +636,7 @@ void ProtocolGame::parseContainerUpdateItem(const InputMessagePtr& msg)
void ProtocolGame::parseContainerRemoveItem(const InputMessagePtr& msg) void ProtocolGame::parseContainerRemoveItem(const InputMessagePtr& msg)
{ {
int containerId = msg->getU8(); int containerId = msg->getU8();
int slot; int slot = msg->getU8();
if(g_game.getFeature(Otc::GameContainerPagination)) {
slot = msg->getU16();
int itemId = msg->getU16();
if(itemId != 0)
getItem(msg, itemId);
} else {
slot = msg->getU8();
}
g_game.processContainerRemoveItem(containerId, slot); g_game.processContainerRemoveItem(containerId, slot);
} }
@@ -984,15 +931,7 @@ void ProtocolGame::parseCreatureUnpass(const InputMessagePtr& msg)
void ProtocolGame::parseEditText(const InputMessagePtr& msg) void ProtocolGame::parseEditText(const InputMessagePtr& msg)
{ {
uint id = msg->getU32(); uint id = msg->getU32();
int itemId = msg->getU16();
int itemId;
if(g_game.getProtocolVersion() >= 1010) {
// TODO: processEditText with ItemPtr as parameter
ItemPtr item = getItem(msg);
itemId = item->getId();
} else
itemId = msg->getU16();
int maxLength = msg->getU16(); int maxLength = msg->getU16();
std::string text = msg->getString(); std::string text = msg->getString();
std::string writter = msg->getString(); std::string writter = msg->getString();
@@ -1077,9 +1016,7 @@ void ProtocolGame::parsePlayerStats(const InputMessagePtr& msg)
double magicLevelPercent = msg->getU8(); double magicLevelPercent = msg->getU8();
double soul = msg->getU8(); double soul = msg->getU8();
double stamina = 0; double stamina = msg->getU16();
if(g_game.getFeature(Otc::GamePlayerStamina))
stamina = msg->getU16();
double baseSpeed = 0; double baseSpeed = 0;
if(g_game.getFeature(Otc::GameSkillsBase)) if(g_game.getFeature(Otc::GameSkillsBase))
@@ -1133,12 +1070,7 @@ void ProtocolGame::parsePlayerSkills(const InputMessagePtr& msg)
void ProtocolGame::parsePlayerState(const InputMessagePtr& msg) void ProtocolGame::parsePlayerState(const InputMessagePtr& msg)
{ {
int states; int states = msg->getU16();
if(g_game.getFeature(Otc::GamePlayerStateU16))
states = msg->getU16();
else
states = msg->getU8();
m_localPlayer->setStates(states); m_localPlayer->setStates(states);
} }
@@ -1151,20 +1083,6 @@ void ProtocolGame::parsePlayerCancelAttack(const InputMessagePtr& msg)
g_game.processAttackCancel(seq); g_game.processAttackCancel(seq);
} }
void ProtocolGame::parsePlayerModes(const InputMessagePtr& msg)
{
int fightMode = msg->getU8();
int chaseMode = msg->getU8();
bool safeMode = msg->getU8();
//TODO: implement pvp modes
if(g_game.getFeature(Otc::GamePVPMode))
msg->getU8(); // pvp mode
g_game.processPlayerModes((Otc::FightModes)fightMode, (Otc::ChaseModes)chaseMode, safeMode);
}
void ProtocolGame::parseSpellCooldown(const InputMessagePtr& msg) void ProtocolGame::parseSpellCooldown(const InputMessagePtr& msg)
{ {
int spellId = msg->getU8(); int spellId = msg->getU8();
@@ -1190,15 +1108,10 @@ void ProtocolGame::parseMultiUseCooldown(const InputMessagePtr& msg)
void ProtocolGame::parseTalk(const InputMessagePtr& msg) void ProtocolGame::parseTalk(const InputMessagePtr& msg)
{ {
if(g_game.getFeature(Otc::GameMessageStatements)) msg->getU32(); // channel statement guid
msg->getU32(); // channel statement guid
std::string name = g_game.formatCreatureName(msg->getString()); std::string name = g_game.formatCreatureName(msg->getString());
int level = msg->getU16();
int level = 0;
if(g_game.getFeature(Otc::GameMessageLevel))
level = msg->getU16();
Otc::MessageMode mode = Proto::translateMessageModeFromServer(msg->getU8()); Otc::MessageMode mode = Proto::translateMessageModeFromServer(msg->getU8());
int channelId = 0; int channelId = 0;
Position pos; Position pos;
@@ -1445,22 +1358,15 @@ void ProtocolGame::parseFloorChangeDown(const InputMessagePtr& msg)
void ProtocolGame::parseOpenOutfitWindow(const InputMessagePtr& msg) void ProtocolGame::parseOpenOutfitWindow(const InputMessagePtr& msg)
{ {
Outfit currentOutfit = getOutfit(msg); Outfit currentOutfit = getOutfit(msg);
std::vector<std::tuple<int, std::string, int> > outfitList; std::vector<std::tuple<int, std::string, int> > outfitList;
int outfitCount = msg->getU8();
for(int i = 0; i < outfitCount; i++) {
int outfitId = msg->getU16();
std::string outfitName = msg->getString();
int outfitAddons = msg->getU8();
if(g_game.getFeature(Otc::GameNewOutfitProtocol)) { outfitList.push_back(std::make_tuple(outfitId, outfitName, outfitAddons));
int outfitCount = msg->getU8();
for(int i = 0; i < outfitCount; i++) {
int outfitId = msg->getU16();
std::string outfitName = msg->getString();
int outfitAddons = msg->getU8();
outfitList.push_back(std::make_tuple(outfitId, outfitName, outfitAddons));
}
} else {
int outfitStart = msg->getU8();
int outfitEnd = msg->getU8();
for(int i = outfitStart; i <= outfitEnd; i++)
outfitList.push_back(std::make_tuple(i, "", 0));
} }
std::vector<std::tuple<int, std::string> > mountList; std::vector<std::tuple<int, std::string> > mountList;
@@ -1673,28 +1579,6 @@ void ProtocolGame::parseChangeMapAwareRange(const InputMessagePtr& msg)
g_lua.callGlobalField("g_game", "onMapChangeAwareRange", xrange, yrange); g_lua.callGlobalField("g_game", "onMapChangeAwareRange", xrange, yrange);
} }
void ProtocolGame::parseCreaturesMark(const InputMessagePtr& msg)
{
int len = msg->getU8();
for(int i=0; i<len; ++i) {
uint32 id = msg->getU32();
bool isPermanent = msg->getU8() != 1;
uint8 markType = msg->getU8();
CreaturePtr creature = g_map.getCreatureById(id);
if(creature) {
if(isPermanent) {
if(markType == 0xff)
creature->hideStaticSquare();
else
creature->showStaticSquare(Color::from8bit(markType));
} else
creature->addTimedSquare(markType);
} else
g_logger.traceError("could not get creature");
}
}
void ProtocolGame::setMapDescription(const InputMessagePtr& msg, int x, int y, int z, int width, int height) void ProtocolGame::setMapDescription(const InputMessagePtr& msg, int x, int y, int z, int width, int height)
{ {
int startz, endz, zstep; int startz, endz, zstep;
@@ -1759,21 +1643,14 @@ Outfit ProtocolGame::getOutfit(const InputMessagePtr& msg)
{ {
Outfit outfit; Outfit outfit;
int lookType; int lookType = msg->getU16();
if(g_game.getFeature(Otc::GameLooktypeU16))
lookType = msg->getU16();
else
lookType = msg->getU8();
if(lookType != 0) { if(lookType != 0) {
outfit.setCategory(ThingCategoryCreature); outfit.setCategory(ThingCategoryCreature);
int head = msg->getU8(); int head = msg->getU8();
int body = msg->getU8(); int body = msg->getU8();
int legs = msg->getU8(); int legs = msg->getU8();
int feet = msg->getU8(); int feet = msg->getU8();
int addons = 0; int addons = msg->getU8();
if(g_game.getFeature(Otc::GamePlayerAddons))
addons = msg->getU8();
if(!g_things.isValidDatId(lookType, ThingCategoryCreature)) { if(!g_things.isValidDatId(lookType, ThingCategoryCreature)) {
g_logger.traceError(stdext::format("invalid outfit looktype %d", lookType)); g_logger.traceError(stdext::format("invalid outfit looktype %d", lookType));
@@ -1927,24 +1804,10 @@ CreaturePtr ProtocolGame::getCreature(const InputMessagePtr& msg, int type)
// emblem is sent only when the creature is not known // emblem is sent only when the creature is not known
int emblem = -1; int emblem = -1;
bool unpass = true; bool unpass = true;
uint8 mark;
if(g_game.getFeature(Otc::GameCreatureEmblems) && !known) if(g_game.getFeature(Otc::GameCreatureEmblems) && !known)
emblem = msg->getU8(); emblem = msg->getU8();
if(g_game.getFeature(Otc::GameThingMarks)) {
msg->getU8(); // creature type for summons
mark = msg->getU8(); // mark
msg->getU16(); // helpers
if(creature) {
if(mark == 0xff)
creature->hideStaticSquare();
else
creature->showStaticSquare(Color::from8bit(mark));
}
}
if(g_game.getProtocolVersion() >= 854) if(g_game.getProtocolVersion() >= 854)
unpass = msg->getU8(); unpass = msg->getU8();
@@ -1997,10 +1860,6 @@ ItemPtr ProtocolGame::getItem(const InputMessagePtr& msg, int id)
if(item->getId() == 0) if(item->getId() == 0)
stdext::throw_exception(stdext::format("unable to create item with invalid id %d", id)); stdext::throw_exception(stdext::format("unable to create item with invalid id %d", id));
if(g_game.getFeature(Otc::GameThingMarks)) {
msg->getU8(); // mark
}
if(item->isStackable() || item->isFluidContainer() || item->isSplash() || item->isChargeable()) if(item->isStackable() || item->isFluidContainer() || item->isSplash() || item->isChargeable())
item->setCountOrSubType(msg->getU8()); item->setCountOrSubType(msg->getU8());
@@ -2008,7 +1867,7 @@ ItemPtr ProtocolGame::getItem(const InputMessagePtr& msg, int id)
if(item->getAnimationPhases() > 1) { if(item->getAnimationPhases() > 1) {
// 0xfe => random phase // 0xfe => random phase
// 0xff => async? // 0xff => async?
item->setAsync(msg->getU8() == 0xff); msg->getU8(); // phase
} }
} }

View File

@@ -52,16 +52,8 @@ void ProtocolGame::sendLoginPacket(uint challengeTimestamp, uint8 challengeRando
{ {
OutputMessagePtr msg(new OutputMessage); OutputMessagePtr msg(new OutputMessage);
if(g_game.getProtocolVersion() == 760) msg->addU8(Proto::ClientPendingGame);
{ msg->addU16(g_game.getOs());
msg->addU16(0x20A);
msg->addU8(g_game.getOs());
}
else
{
msg->addU8(Proto::ClientPendingGame);
msg->addU16(g_game.getOs());
}
msg->addU16(g_game.getProtocolVersion()); msg->addU16(g_game.getProtocolVersion());
if(g_game.getProtocolVersion() >= 971) { if(g_game.getProtocolVersion() >= 971) {
@@ -73,16 +65,13 @@ void ProtocolGame::sendLoginPacket(uint challengeTimestamp, uint8 challengeRando
msg->addU8(0); // first RSA byte must be 0 msg->addU8(0); // first RSA byte must be 0
if(g_game.getProtocolVersion() >= 800) // xtea key
{ generateXteaKey();
// xtea key msg->addU32(m_xteaKey[0]);
generateXteaKey(); msg->addU32(m_xteaKey[1]);
msg->addU32(m_xteaKey[0]); msg->addU32(m_xteaKey[2]);
msg->addU32(m_xteaKey[1]); msg->addU32(m_xteaKey[3]);
msg->addU32(m_xteaKey[2]); msg->addU8(0); // is gm set?
msg->addU32(m_xteaKey[3]);
msg->addU8(0); // is gm set?
}
if(g_game.getFeature(Otc::GameAccountNames)) if(g_game.getFeature(Otc::GameAccountNames))
msg->addString(m_accountName); msg->addString(m_accountName);
@@ -107,16 +96,14 @@ void ProtocolGame::sendLoginPacket(uint challengeTimestamp, uint8 challengeRando
msg->addPaddingBytes(paddingBytes); msg->addPaddingBytes(paddingBytes);
// encrypt with RSA // encrypt with RSA
if(g_game.getProtocolVersion() >= 800) msg->encryptRsa();
msg->encryptRsa();
if(g_game.getFeature(Otc::GameProtocolChecksum)) if(g_game.getFeature(Otc::GameProtocolChecksum))
enableChecksum(); enableChecksum();
send(msg); send(msg);
if(g_game.getProtocolVersion() >= 800) enableXteaEncryption();
enableXteaEncryption();
} }
void ProtocolGame::sendEnterGame() void ProtocolGame::sendEnterGame()
@@ -580,11 +567,6 @@ void ProtocolGame::sendChangeFightModes(Otc::FightModes fightMode, Otc::ChaseMod
msg->addU8(fightMode); msg->addU8(fightMode);
msg->addU8(chaseMode); msg->addU8(chaseMode);
msg->addU8(safeFight ? 0x01: 0x00); msg->addU8(safeFight ? 0x01: 0x00);
//TODO: implement pvp modes
if(g_game.getFeature(Otc::GamePVPMode))
msg->addU8(0); // pvp mode
send(msg); send(msg);
} }

View File

@@ -48,9 +48,11 @@ bool SpriteManager::loadSpr(std::string file)
file = g_resources.guessFilePath(file, "spr"); file = g_resources.guessFilePath(file, "spr");
m_spritesFile = g_resources.openFile(file); m_spritesFile = g_resources.openFile(file);
// cache file buffer to avoid lags from hard drive
m_spritesFile->cache();
// cache file buffer to avoid lags from hard drive
#ifndef MOBILE
m_spritesFile->cache();
#endif
m_signature = m_spritesFile->getU32(); m_signature = m_spritesFile->getU32();
m_spritesCount = g_game.getFeature(Otc::GameSpritesU32) ? m_spritesFile->getU32() : m_spritesFile->getU16(); m_spritesCount = g_game.getFeature(Otc::GameSpritesU32) ? m_spritesFile->getU32() : m_spritesFile->getU16();
m_spritesOffset = m_spritesFile->tell(); m_spritesOffset = m_spritesFile->tell();

View File

@@ -28,6 +28,7 @@
#include <framework/graphics/graphics.h> #include <framework/graphics/graphics.h>
#include <framework/graphics/texture.h> #include <framework/graphics/texture.h>
#include <framework/graphics/image.h> #include <framework/graphics/image.h>
#include <framework/graphics/ogl/textureogl.h>
#include <framework/graphics/texturemanager.h> #include <framework/graphics/texturemanager.h>
#include <framework/core/filestream.h> #include <framework/core/filestream.h>
#include <framework/otml/otml.h> #include <framework/otml/otml.h>
@@ -67,17 +68,6 @@ void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileS
attr -= 1; attr -= 1;
} }
if(g_game.getProtocolVersion() >= 1010) {
/* In 10.10 all attributes from 16 and up were
* incremented by 1 to make space for 16 as
* "No Movement Animation" flag.
*/
if(attr == 16)
attr = ThingAttrNoMoveAnimation;
else if(attr > 16)
attr -= 1;
}
switch(attr) { switch(attr) {
case ThingAttrDisplacement: { case ThingAttrDisplacement: {
m_displacement.x = fin->getU16(); m_displacement.x = fin->getU16();
@@ -103,7 +93,6 @@ void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileS
m_attribs.set(attr, market); m_attribs.set(attr, market);
break; break;
} }
case ThingAttrUsable:
case ThingAttrElevation: { case ThingAttrElevation: {
m_elevation = fin->getU16(); m_elevation = fin->getU16();
m_attribs.set(attr, m_elevation); m_attribs.set(attr, m_elevation);
@@ -138,8 +127,8 @@ void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileS
int totalSprites = m_size.area() * m_layers * m_numPatternX * m_numPatternY * m_numPatternZ * m_animationPhases; int totalSprites = m_size.area() * m_layers * m_numPatternX * m_numPatternY * m_numPatternZ * m_animationPhases;
// if(totalSprites == 0) if(totalSprites == 0)
// stdext::throw_exception("a thing type has no sprites"); stdext::throw_exception("a thing type has no sprites");
if(totalSprites > 4096) if(totalSprites > 4096)
stdext::throw_exception("a thing type has more than 4096 sprites"); stdext::throw_exception("a thing type has more than 4096 sprites");
@@ -295,7 +284,7 @@ const TexturePtr& ThingType::getTexture(int animationPhase)
} }
} }
} }
animationPhaseTexture = TexturePtr(new Texture(fullImage, true)); animationPhaseTexture = TexturePtr(new TextureOGL(fullImage));
animationPhaseTexture->setSmooth(true); animationPhaseTexture->setSmooth(true);
} }
return animationPhaseTexture; return animationPhaseTexture;

View File

@@ -76,13 +76,11 @@ enum ThingAttr : uint8 {
ThingAttrLook = 31, ThingAttrLook = 31,
ThingAttrCloth = 32, ThingAttrCloth = 32,
ThingAttrMarket = 33, ThingAttrMarket = 33,
ThingAttrUsable = 34,
// additional // additional
ThingAttrOpacity = 100, ThingAttrOpacity = 100,
ThingAttrNotPreWalkable = 101, ThingAttrNotPreWalkable = 101,
ThingAttrNoMoveAnimation = 253, // real value is 16, but we need to do this for backwards compatibility
ThingAttrChargeable = 254, // deprecated ThingAttrChargeable = 254, // deprecated
ThingLastAttr = 255 ThingLastAttr = 255
}; };

View File

@@ -27,7 +27,6 @@
#include "itemtype.h" #include "itemtype.h"
#include "creature.h" #include "creature.h"
#include "creatures.h" #include "creatures.h"
#include "game.h"
#include <framework/core/resourcemanager.h> #include <framework/core/resourcemanager.h>
#include <framework/core/filestream.h> #include <framework/core/filestream.h>
@@ -135,121 +134,102 @@ bool ThingTypeManager::loadOtml(std::string file)
void ThingTypeManager::loadOtb(const std::string& file) void ThingTypeManager::loadOtb(const std::string& file)
{ {
try { FileStreamPtr fin = g_resources.openFile(file);
FileStreamPtr fin = g_resources.openFile(file);
uint signature = fin->getU32(); uint signature = fin->getU32();
if(signature != 0) if(signature != 0)
stdext::throw_exception("invalid otb file"); stdext::throw_exception("invalid otb file");
BinaryTreePtr root = fin->getBinaryTree(); BinaryTreePtr root = fin->getBinaryTree();
signature = root->getU32(); signature = root->getU32();
if(signature != 0) if(signature != 0)
stdext::throw_exception("invalid otb file"); stdext::throw_exception("invalid otb file");
root->skip(4); root->skip(4);
m_otbMajorVersion = root->getU32(); m_otbMajorVersion = root->getU32();
m_otbMinorVersion = root->getU32(); m_otbMinorVersion = root->getU32();
root->skip(4); root->skip(4);
root->skip(128); // description root->skip(128); // description
m_reverseItemTypes.clear(); m_reverseItemTypes.clear();
m_itemTypes.resize(root->getChildren().size() + 1, m_nullItemType); m_itemTypes.resize(root->getChildren().size() + 1, m_nullItemType);
m_reverseItemTypes.resize(root->getChildren().size() + 1, m_nullItemType);
for(const BinaryTreePtr& node : root->getChildren()) { for(const BinaryTreePtr& node : root->getChildren()) {
ItemTypePtr itemType(new ItemType); ItemTypePtr itemType(new ItemType);
itemType->unserialize(node); itemType->unserialize(node);
addItemType(itemType); addItemType(itemType);
uint16 clientId = itemType->getClientId(); uint16 clientId = itemType->getClientId();
if(unlikely(clientId >= m_reverseItemTypes.size())) if(clientId >= m_reverseItemTypes.size())
m_reverseItemTypes.resize(clientId + 1); m_reverseItemTypes.resize(clientId+1);
m_reverseItemTypes[clientId] = itemType; m_reverseItemTypes[clientId] = itemType;
}
m_otbLoaded = true;
} catch(std::exception& e) {
g_logger.error(stdext::format("Failed to load '%s' (OTB file): %s", file, e.what()));
} }
m_otbLoaded = true;
} }
void ThingTypeManager::loadXml(const std::string& file) void ThingTypeManager::loadXml(const std::string& file)
{ {
try { if(!isOtbLoaded())
if(!isOtbLoaded()) stdext::throw_exception("OTB must be loaded before XML");
stdext::throw_exception("OTB must be loaded before XML");
TiXmlDocument doc; TiXmlDocument doc;
doc.Parse(g_resources.readFileContents(file).c_str()); doc.Parse(g_resources.readFileContents(file).c_str());
if(doc.Error()) if(doc.Error())
stdext::throw_exception(stdext::format("failed to parse '%s': '%s'", file, doc.ErrorDesc())); stdext::throw_exception(stdext::format("failed to parse '%s': '%s'", file, doc.ErrorDesc()));
TiXmlElement* root = doc.FirstChildElement(); TiXmlElement* root = doc.FirstChildElement();
if(!root || root->ValueTStr() != "items") if(!root || root->ValueTStr() != "items")
stdext::throw_exception("invalid root tag name"); stdext::throw_exception("invalid root tag name");
for(TiXmlElement *element = root->FirstChildElement(); element; element = element->NextSiblingElement()) { for (TiXmlElement *element = root->FirstChildElement(); element; element = element->NextSiblingElement()) {
if(unlikely(element->ValueTStr() != "item")) if(element->ValueTStr() != "item")
continue; continue;
uint16 id = element->readType<uint16>("id"); uint16 id = element->readType<uint16>("id");
if(id != 0) { if(id != 0) {
std::vector<std::string> s_ids = stdext::split(element->Attribute("id"), ";"); std::vector<std::string> s_ids = stdext::split(element->Attribute("id"), ";");
for(const std::string& s : s_ids) { for(const std::string& s : s_ids) {
std::vector<int32> ids = stdext::split<int32>(s, "-"); std::vector<int32> ids = stdext::split<int32>(s, "-");
if(ids.size() > 1) { if(ids.size() > 1) {
int32 i = ids[0]; int32 i = ids[0];
while(i <= ids[1]) while(i <= ids[1])
parseItemType(i++, element); parseItemType(i++, element);
} else } else
parseItemType(atoi(s.c_str()), element); parseItemType(atoi(s.c_str()), element);
} }
} else { } else {
std::vector<int32> begin = stdext::split<int32>(element->Attribute("fromid"), ";"); std::vector<int32> begin = stdext::split<int32>(element->Attribute("fromid"), ";");
std::vector<int32> end = stdext::split<int32>(element->Attribute("toid"), ";"); std::vector<int32> end = stdext::split<int32>(element->Attribute("toid"), ";");
if(begin[0] && begin.size() == end.size()) { if(begin[0] && begin.size() == end.size()) {
size_t size = begin.size(); size_t size = begin.size();
for(size_t i = 0; i < size; ++i) for(size_t i = 0; i < size; ++i) {
while(begin[i] <= end[i]) while(begin[i] <= end[i])
parseItemType(begin[i]++, element); parseItemType(begin[i]++, element);
} }
} }
} }
doc.Clear();
m_xmlLoaded = true;
g_logger.debug("items.xml read successfully.");
} catch(std::exception& e) {
g_logger.error(stdext::format("Failed to load '%s' (XML file): %s", file, e.what()));
} }
doc.Clear();
m_xmlLoaded = true;
g_logger.debug("items.xml read successfully.");
} }
void ThingTypeManager::parseItemType(uint16 id, TiXmlElement* elem) void ThingTypeManager::parseItemType(uint16 id, TiXmlElement* elem)
{ {
uint16 serverId = id; uint16 serverId = id;
ItemTypePtr itemType = nullptr; ItemTypePtr itemType = nullptr;
if(g_game.getProtocolVersion() < 960) { if(serverId > 20000 && serverId < 20100) {
if(serverId > 20000 && serverId < 20100) { serverId -= 20000;
serverId -= 20000;
itemType = ItemTypePtr(new ItemType); itemType = ItemTypePtr(new ItemType);
itemType->setServerId(serverId); itemType->setServerId(serverId);
addItemType(itemType); addItemType(itemType);
} else } else
itemType = getItemType(serverId); itemType = getItemType(serverId);
} else {
if(serverId > 30000 && serverId < 30100) {
serverId -= 30000;
itemType = ItemTypePtr(new ItemType);
itemType->setServerId(serverId);
addItemType(itemType);
} else
itemType = getItemType(serverId);
}
itemType->setName(elem->Attribute("name")); itemType->setName(elem->Attribute("name"));
for(TiXmlElement* attrib = elem->FirstChildElement(); attrib; attrib = attrib->NextSiblingElement()) { for(TiXmlElement* attrib = elem->FirstChildElement(); attrib; attrib = attrib->NextSiblingElement()) {
@@ -287,7 +267,7 @@ void ThingTypeManager::parseItemType(uint16 id, TiXmlElement* elem)
void ThingTypeManager::addItemType(const ItemTypePtr& itemType) void ThingTypeManager::addItemType(const ItemTypePtr& itemType)
{ {
uint16 id = itemType->getServerId(); uint16 id = itemType->getServerId();
if(unlikely(id >= m_itemTypes.size())) if(id >= m_itemTypes.size())
m_itemTypes.resize(id + 1, m_nullItemType); m_itemTypes.resize(id + 1, m_nullItemType);
m_itemTypes[id] = itemType; m_itemTypes[id] = itemType;
} }
@@ -303,32 +283,6 @@ const ItemTypePtr& ThingTypeManager::findItemTypeByClientId(uint16 id)
return m_nullItemType; return m_nullItemType;
} }
const ItemTypePtr& ThingTypeManager::findItemTypeByName(std::string name)
{
for(const ItemTypePtr& it : m_itemTypes)
if(it->getName() == name)
return it;
return m_nullItemType;
}
ItemTypeList ThingTypeManager::findItemTypesByName(std::string name)
{
ItemTypeList ret;
for(const ItemTypePtr& it : m_itemTypes)
if(it->getName() == name)
ret.push_back(it);
return ret;
}
ItemTypeList ThingTypeManager::findItemTypesByString(std::string name)
{
ItemTypeList ret;
for(const ItemTypePtr& it : m_itemTypes)
if(it->getName().find(name) != std::string::npos)
ret.push_back(it);
return ret;
}
const ThingTypePtr& ThingTypeManager::getThingType(uint16 id, ThingCategory category) const ThingTypePtr& ThingTypeManager::getThingType(uint16 id, ThingCategory category)
{ {
if(category >= ThingLastCategory || id >= m_thingTypes[category].size()) { if(category >= ThingLastCategory || id >= m_thingTypes[category].size()) {
@@ -341,7 +295,7 @@ const ThingTypePtr& ThingTypeManager::getThingType(uint16 id, ThingCategory cate
const ItemTypePtr& ThingTypeManager::getItemType(uint16 id) const ItemTypePtr& ThingTypeManager::getItemType(uint16 id)
{ {
if(id >= m_itemTypes.size() || m_itemTypes[id] == m_nullItemType) { if(id >= m_itemTypes.size() || m_itemTypes[id] == m_nullItemType) {
g_logger.error(stdext::format("invalid thing type, server id: %d", id)); g_logger.error(stdext::format("invalid thing type server id %d", id));
return m_nullItemType; return m_nullItemType;
} }
return m_itemTypes[id]; return m_itemTypes[id];
@@ -372,5 +326,3 @@ const ThingTypeList& ThingTypeManager::getThingTypes(ThingCategory category)
stdext::throw_exception(stdext::format("invalid thing type category %d", category)); stdext::throw_exception(stdext::format("invalid thing type category %d", category));
return m_thingTypes[category]; return m_thingTypes[category];
} }
/* vim: set ts=4 sw=4 et: */

View File

@@ -43,9 +43,6 @@ public:
void addItemType(const ItemTypePtr& itemType); void addItemType(const ItemTypePtr& itemType);
const ItemTypePtr& findItemTypeByClientId(uint16 id); const ItemTypePtr& findItemTypeByClientId(uint16 id);
const ItemTypePtr& findItemTypeByName(std::string name);
ItemTypeList findItemTypesByName(std::string name);
ItemTypeList findItemTypesByString(std::string str);
const ThingTypePtr& getNullThingType() { return m_nullThingType; } const ThingTypePtr& getNullThingType() { return m_nullThingType; }
const ItemTypePtr& getNullItemType() { return m_nullItemType; } const ItemTypePtr& getNullItemType() { return m_nullItemType; }

View File

@@ -43,15 +43,6 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags, LightView *
{ {
bool animate = drawFlags & Otc::DrawAnimations; bool animate = drawFlags & Otc::DrawAnimations;
/* Flags to be checked for. */
static const tileflags_t flags[] = {
TILESTATE_HOUSE,
TILESTATE_PROTECTIONZONE,
TILESTATE_OPTIONALZONE,
TILESTATE_HARDCOREZONE,
TILESTATE_NOLOGOUT
};
// first bottom items // first bottom items
if(drawFlags & (Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawOnBottom)) { if(drawFlags & (Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawOnBottom)) {
m_drawElevation = 0; m_drawElevation = 0;
@@ -59,28 +50,10 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags, LightView *
if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom()) if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom())
break; break;
bool restore = false;
if(g_map.showZones() && thing->isGround()) {
for(unsigned int i = 0; i < sizeof(flags) / sizeof(tileflags_t); ++i) {
tileflags_t flag = flags[i];
if(hasFlag(flag) && g_map.showZone(flag)) {
g_painter->setOpacity(g_map.getZoneOpacity());
g_painter->setColor(g_map.getZoneColor(flag));
restore = true;
break;
}
}
}
if((thing->isGround() && drawFlags & Otc::DrawGround) || if((thing->isGround() && drawFlags & Otc::DrawGround) ||
(thing->isGroundBorder() && drawFlags & Otc::DrawGroundBorders) || (thing->isGroundBorder() && drawFlags & Otc::DrawGroundBorders) ||
(thing->isOnBottom() && drawFlags & Otc::DrawOnBottom)) { (thing->isOnBottom() && drawFlags & Otc::DrawOnBottom)) {
thing->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView); thing->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView);
if(restore) {
g_painter->resetOpacity();
g_painter->resetColor();
}
} }
m_drawElevation += thing->getElevation(); m_drawElevation += thing->getElevation();
@@ -143,19 +116,25 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags, LightView *
CreaturePtr creature = thing->static_self_cast<Creature>(); CreaturePtr creature = thing->static_self_cast<Creature>();
if(creature && (!creature->isWalking() || !animate)) if(creature && (!creature->isWalking() || !animate))
creature->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView); creature->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView);
} }
} }
// effects // effects
if(drawFlags & Otc::DrawEffects) if(drawFlags & Otc::DrawEffects) {
for(const EffectPtr& effect : m_effects) for(const EffectPtr& effect : m_effects){
effect->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView); effect->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView);
}
}
// top items // top items
if(drawFlags & Otc::DrawOnTop) if(drawFlags & Otc::DrawOnTop) {
for(const ThingPtr& thing : m_things) for(const ThingPtr& thing : m_things) {
if(thing->isOnTop()) if(thing->isOnTop()){
thing->draw(dest, scaleFactor, animate, lightView); thing->draw(dest, scaleFactor, animate, lightView);
}
}
}
// draw translucent light (for tiles beneath holes) // draw translucent light (for tiles beneath holes)
if(hasTranslucentLight() && lightView) { if(hasTranslucentLight() && lightView) {
@@ -310,9 +289,10 @@ ThingPtr Tile::getTopThing()
{ {
if(isEmpty()) if(isEmpty())
return nullptr; return nullptr;
for(const ThingPtr& thing : m_things) for(const ThingPtr& thing : m_things) {
if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop() && !thing->isCreature()) if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop() && !thing->isCreature())
return thing; return thing;
}
return m_things[m_things.size() - 1]; return m_things[m_things.size() - 1];
} }
@@ -359,8 +339,9 @@ int Tile::getGroundSpeed()
uint8 Tile::getMinimapColorByte() uint8 Tile::getMinimapColorByte()
{ {
uint8 color = 255; // alpha uint8 color = 255; // alpha
if(m_minimapColor != 0) if(m_minimapColor != 0) {
return m_minimapColor; return m_minimapColor;
}
for(const ThingPtr& thing : m_things) { for(const ThingPtr& thing : m_things) {
if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop()) if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop())
@@ -476,7 +457,7 @@ ThingPtr Tile::getTopMultiUseThing()
if(thing->isForceUse()) if(thing->isForceUse())
return thing; return thing;
} }
for(uint i = 0; i < m_things.size(); ++i) { for(uint i = 0; i < m_things.size(); ++i) {
ThingPtr thing = m_things[i]; ThingPtr thing = m_things[i];
if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop()) { if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop()) {
@@ -517,9 +498,11 @@ bool Tile::isWalkable(bool ignoreCreatures)
bool Tile::isPathable() bool Tile::isPathable()
{ {
for(const ThingPtr& thing : m_things) for(const ThingPtr& thing : m_things) {
if(thing->isNotPathable()) if(thing->isNotPathable())
return false; return false;
}
return true; return true;
} }
@@ -541,17 +524,19 @@ bool Tile::isSingleDimension()
{ {
if(!m_walkingCreatures.empty()) if(!m_walkingCreatures.empty())
return false; return false;
for(const ThingPtr& thing : m_things) for(const ThingPtr& thing : m_things) {
if(thing->getHeight() != 1 || thing->getWidth() != 1) if(thing->getHeight() != 1 || thing->getWidth() != 1)
return false; return false;
}
return true; return true;
} }
bool Tile::isLookPossible() bool Tile::isLookPossible()
{ {
for(const ThingPtr& thing : m_things) for(const ThingPtr& thing : m_things) {
if(thing->blockProjectile()) if(thing->blockProjectile())
return false; return false;
}
return true; return true;
} }
@@ -605,20 +590,15 @@ bool Tile::hasCreature()
return false; return false;
} }
bool Tile::limitsFloorsView(bool isFreeView) bool Tile::limitsFloorsView()
{ {
// ground and walls limits the view // ground and walls limits the view
ThingPtr firstThing = getThing(0); ThingPtr firstThing = getThing(0);
if(firstThing && !firstThing->isDontHide() && (firstThing->isGround() || firstThing->isOnBottom()))
if(isFreeView) {
if(firstThing && !firstThing->isDontHide() && (firstThing->isGround() || firstThing->isOnBottom()))
return true;
} else if(firstThing && !firstThing->isDontHide() && (firstThing->isGround() || (firstThing->isOnBottom() && firstThing->blockProjectile())))
return true; return true;
return false; return false;
} }
bool Tile::canErase() bool Tile::canErase()
{ {
return m_walkingCreatures.empty() && m_effects.empty() && m_things.empty() && m_flags == 0 && m_minimapColor == 0; return m_walkingCreatures.empty() && m_effects.empty() && m_things.empty() && m_flags == 0 && m_minimapColor == 0;
@@ -655,9 +635,7 @@ void Tile::checkTranslucentLight()
} }
if(translucent) if(translucent)
tile->m_flags |= TILESTATE_TRANSLUECENT_LIGHT; tile->m_flags = tile->m_flags | TILESTATE_TRANSLUECENT_LIGHT;
else else
tile->m_flags &= ~TILESTATE_TRANSLUECENT_LIGHT; tile->m_flags = tile->m_flags & ~TILESTATE_TRANSLUECENT_LIGHT;
} }
/* vim: set ts=4 sw=4 et :*/

View File

@@ -48,9 +48,7 @@ enum tileflags_t
TILESTATE_TRASHHOLDER = 1 << 20, TILESTATE_TRASHHOLDER = 1 << 20,
TILESTATE_BED = 1 << 21, TILESTATE_BED = 1 << 21,
TILESTATE_DEPOT = 1 << 22, TILESTATE_DEPOT = 1 << 22,
TILESTATE_TRANSLUECENT_LIGHT = 1 << 23, TILESTATE_TRANSLUECENT_LIGHT = 1 << 23
TILESTATE_LAST = 1 << 24
}; };
class Tile : public LuaObject class Tile : public LuaObject
@@ -107,19 +105,17 @@ public:
bool mustHookSouth(); bool mustHookSouth();
bool mustHookEast(); bool mustHookEast();
bool hasCreature(); bool hasCreature();
bool limitsFloorsView(bool isFreeView = false); bool limitsFloorsView();
bool canErase(); bool canErase();
bool hasElevation(int elevation = 1); bool hasElevation(int elevation = 1);
void overwriteMinimapColor(uint8 color) { m_minimapColor = color; } void overwriteMinimapColor(uint8 color) { m_minimapColor = color; }
void setFlag(uint32 flag) { m_flags |= flag; } void setFlags(tileflags_t flags) { m_flags |= (uint32)flags; }
void setFlags(uint32 flags) { m_flags = flags; }
bool hasFlag(uint32 flag) { return (m_flags & flag) == flag; }
uint32 getFlags() { return m_flags; } uint32 getFlags() { return m_flags; }
void setHouseId(uint32 hid) { m_houseId = hid; } void setHouseId(uint32 hid) { m_houseId = hid; }
uint32 getHouseId() { return m_houseId; } uint32 getHouseId() { return m_houseId; }
bool isHouseTile() const { return m_houseId != 0 && (m_flags & TILESTATE_HOUSE) == TILESTATE_HOUSE; } bool isHouseTile() const { return (m_flags & TILESTATE_HOUSE) == TILESTATE_HOUSE; }
TilePtr asTile() { return static_self_cast<Tile>(); } TilePtr asTile() { return static_self_cast<Tile>(); }

View File

@@ -58,15 +58,6 @@ const TownPtr& TownManager::getTown(uint32 townId)
return m_nullTown; return m_nullTown;
} }
const TownPtr& TownManager::getTownByName(std::string name)
{
auto it = std::find_if(m_towns.begin(), m_towns.end(),
[=] (const TownPtr& town) -> bool { return town->getName() == name; } );
if(it != m_towns.end())
return *it;
return m_nullTown;
}
TownList::iterator TownManager::findTown(uint32 townId) TownList::iterator TownManager::findTown(uint32 townId)
{ {
return std::find_if(m_towns.begin(), m_towns.end(), return std::find_if(m_towns.begin(), m_towns.end(),

View File

@@ -54,7 +54,6 @@ public:
void addTown(const TownPtr& town); void addTown(const TownPtr& town);
void removeTown(uint32 townId); void removeTown(uint32 townId);
const TownPtr& getTown(uint32 townId); const TownPtr& getTown(uint32 townId);
const TownPtr& getTownByName(std::string name);
TownList getTowns() { return m_towns; } TownList getTowns() { return m_towns; }
void clear() { m_towns.clear(); m_nullTown = nullptr; } void clear() { m_towns.clear(); m_nullTown = nullptr; }

View File

@@ -63,8 +63,8 @@ void UIItem::drawSelf(Fw::DrawPane drawPane)
g_painter->setColor(Color(231, 231, 231)); g_painter->setColor(Color(231, 231, 231));
m_font->drawText(count, Rect(m_rect.topLeft(), m_rect.bottomRight() - Point(3, 0)), Fw::AlignBottomRight); m_font->drawText(count, Rect(m_rect.topLeft(), m_rect.bottomRight() - Point(3, 0)), Fw::AlignBottomRight);
} }
if(m_showId) // debug, show item id
m_font->drawText(stdext::to_string(m_item->getServerId()), m_rect, Fw::AlignBottomRight); //m_font->drawText(stdext::to_string(m_item->getId()), m_rect, Fw::AlignBottomRight);
} }
drawBorder(m_rect); drawBorder(m_rect);
@@ -98,7 +98,5 @@ void UIItem::onStyleApply(const std::string& styleName, const OTMLNodePtr& style
setItemVisible(node->value<bool>()); setItemVisible(node->value<bool>());
else if(node->tag() == "virtual") else if(node->tag() == "virtual")
setVirtual(node->value<bool>()); setVirtual(node->value<bool>());
else if(node->tag() == "show-id")
m_showId = node->value<bool>();
} }
} }

View File

@@ -54,7 +54,6 @@ protected:
ItemPtr m_item; ItemPtr m_item;
stdext::boolean<false> m_virtual; stdext::boolean<false> m_virtual;
stdext::boolean<true> m_itemVisible; stdext::boolean<true> m_itemVisible;
stdext::boolean<false> m_showId;
}; };
#endif #endif

View File

@@ -70,11 +70,6 @@ void UIMap::drawSelf(Fw::DrawPane drawPane)
} }
} }
void UIMap::movePixels(int x, int y)
{
m_mapView->move(x, y);
}
bool UIMap::setZoom(int zoom) bool UIMap::setZoom(int zoom)
{ {
m_zoom = std::min(std::max(zoom, m_maxZoomIn), m_maxZoomOut); m_zoom = std::min(std::max(zoom, m_maxZoomIn), m_maxZoomOut);
@@ -220,5 +215,3 @@ void UIMap::updateMapSize()
if(!m_keepAspectRatio) if(!m_keepAspectRatio)
updateVisibleDimension(); updateVisibleDimension();
} }
/* vim: set ts=4 sw=4 et: */

View File

@@ -37,7 +37,6 @@ public:
void drawSelf(Fw::DrawPane drawPane); void drawSelf(Fw::DrawPane drawPane);
void movePixels(int x, int y);
bool setZoom(int zoom); bool setZoom(int zoom);
bool zoomIn(); bool zoomIn();
bool zoomOut(); bool zoomOut();

View File

@@ -1,87 +0,0 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "uisprite.h"
#include <framework/otml/otml.h>
#include <framework/graphics/graphics.h>
#include <framework/graphics/texturemanager.h>
#include <client/spritemanager.h>
UISprite::UISprite() :
m_spriteId(0),
m_spriteColor(Color::white)
{ }
void UISprite::drawSelf(Fw::DrawPane drawPane)
{
if((drawPane & Fw::ForegroundPane) == 0)
return;
// draw style components in order
if(m_backgroundColor.aF() > Fw::MIN_ALPHA) {
Rect backgroundDestRect = m_rect;
backgroundDestRect.expand(-m_borderWidth.top, -m_borderWidth.right, -m_borderWidth.bottom, -m_borderWidth.left);
drawBackground(m_rect);
}
drawImage(m_rect);
if(m_spriteVisible && m_sprite) {
g_painter->setColor(m_spriteColor);
g_painter->drawTexturedRect(getPaddingRect(), m_sprite);
}
drawBorder(m_rect);
drawIcon(m_rect);
drawText(m_rect);
}
void UISprite::setSpriteId(int id)
{
if(!g_sprites.isLoaded())
return;
m_spriteId = id;
if(id == 0)
m_sprite = nullptr;
else {
ImagePtr image = g_sprites.getSpriteImage(id);
if(image)
m_sprite = new Texture(image);
else
m_sprite = nullptr;
}
}
void UISprite::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
{
UIWidget::onStyleApply(styleName, styleNode);
for(const OTMLNodePtr& node : styleNode->children()) {
if(node->tag() == "sprite-id")
setSpriteId(node->value<int>());
else if(node->tag() == "sprite-visible")
setSpriteVisible(node->value<bool>());
else if(node->tag() == "sprite-color")
setSpriteColor(node->value<Color>());
}
}

View File

@@ -123,15 +123,20 @@ set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/otml/otmlparser.h ${CMAKE_CURRENT_LIST_DIR}/otml/otmlparser.h
# crash handler # crash handler
${CMAKE_CURRENT_LIST_DIR}/platform/crashhandler.h
${CMAKE_CURRENT_LIST_DIR}/platform/unixcrashhandler.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/win32crashhandler.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/win32platform.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/unixplatform.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/platform.cpp ${CMAKE_CURRENT_LIST_DIR}/platform/platform.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/platform.h ${CMAKE_CURRENT_LIST_DIR}/platform/platform.h
) )
if(WIN32)
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/platform/win32platform.cpp
)
else()
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/platform/unixplatform.cpp
)
endif()
set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/luafunctions.cpp set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/luafunctions.cpp
PROPERTIES LANGUAGE CXX COMPILE_FLAGS "-g0 -Os") PROPERTIES LANGUAGE CXX COMPILE_FLAGS "-g0 -Os")
@@ -258,6 +263,15 @@ if(CRASH_HANDLER)
message(STATUS "Crash handler: ON") message(STATUS "Crash handler: ON")
if(WIN32) if(WIN32)
set(framework_LIBRARIES ${framework_LIBRARIES} imagehlp) set(framework_LIBRARIES ${framework_LIBRARIES} imagehlp)
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/platform/crashhandler.h
${CMAKE_CURRENT_LIST_DIR}/platform/win32crashhandler.cpp
)
else()
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/platform/crashhandler.h
${CMAKE_CURRENT_LIST_DIR}/platform/unixcrashhandler.cpp
)
endif() endif()
else() else()
message(STATUS "Crash handler: OFF") message(STATUS "Crash handler: OFF")
@@ -270,7 +284,7 @@ endif()
if(WIN32) if(WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthreads") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthreads")
set(framework_DEFINITIONS ${framework_DEFINITIONS} -D_WIN32_WINNT=0x0501) set(framework_DEFINITIONS ${framework_DEFINITIONS} -D_WIN32_WINNT=0x0501)
#set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,--large-address-aware") # strip all debug information set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,--large-address-aware") # strip all debug information
set(SYSTEM_LIBRARIES "") set(SYSTEM_LIBRARIES "")
else() else()
if(APPLE) if(APPLE)
@@ -290,18 +304,24 @@ endif()
if(FRAMEWORK_GRAPHICS) if(FRAMEWORK_GRAPHICS)
set(OPENGLES "OFF" CACHE "Use OpenGL ES 1.0 or 2.0 (for mobiles devices)" STRING) set(OPENGLES "OFF" CACHE "Use OpenGL ES 1.0 or 2.0 (for mobiles devices)" STRING)
if(OPENGLES STREQUAL "2.0") if(OPENGLES)
find_package(OpenGLES2 REQUIRED) set(framework_SOURCES ${framework_SOURCES}
find_package(EGL REQUIRED) ${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/graphicscontextegl.cpp
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DOPENGL_ES=2) ${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/graphicscontextegl.h
set(framework_INCLUDE_DIRS ${framework_INCLUDE_DIRS} ${EGL_INCLUDE_DIR} ${OPENGLES2_INCLUDE_DIR}) )
set(framework_LIBRARIES ${framework_LIBRARIES} ${EGL_LIBRARY} ${OPENGLES2_LIBRARY}) if(OPENGLES STREQUAL "2.0")
ELSEif(OPENGLES STREQUAL "1.0") find_package(OpenGLES2 REQUIRED)
find_package(OpenGLES1 REQUIRED) find_package(EGL REQUIRED)
find_package(EGL REQUIRED) set(framework_DEFINITIONS ${framework_DEFINITIONS} -DOPENGL_ES=2)
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DOPENGL_ES=1) set(framework_INCLUDE_DIRS ${framework_INCLUDE_DIRS} ${EGL_INCLUDE_DIR} ${OPENGLES2_INCLUDE_DIR})
set(framework_INCLUDE_DIRS ${framework_INCLUDE_DIRS} ${EGL_INCLUDE_DIR} ${OPENGLES1_INCLUDE_DIR}) set(framework_LIBRARIES ${framework_LIBRARIES} ${EGL_LIBRARY} ${OPENGLES2_LIBRARY})
set(framework_LIBRARIES ${framework_LIBRARIES} ${EGL_LIBRARY} ${OPENGLES1_LIBRARY}) elseif(OPENGLES STREQUAL "1.0")
find_package(OpenGLES1 REQUIRED)
find_package(EGL REQUIRED)
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DOPENGL_ES=1)
set(framework_INCLUDE_DIRS ${framework_INCLUDE_DIRS} ${EGL_INCLUDE_DIR} ${OPENGLES1_INCLUDE_DIR})
set(framework_LIBRARIES ${framework_LIBRARIES} ${EGL_LIBRARY} ${OPENGLES1_LIBRARY})
endif()
else() else()
## TODO: CMake Documentation says that this is not the right ## TODO: CMake Documentation says that this is not the right
# Thing for Mac OS X, but it works for now. # Thing for Mac OS X, but it works for now.
@@ -336,6 +356,8 @@ if(FRAMEWORK_GRAPHICS)
set(framework_SOURCES ${framework_SOURCES} set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/graphics/dx/painterdx9.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/dx/painterdx9.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/dx/painterdx9.h ${CMAKE_CURRENT_LIST_DIR}/graphics/dx/painterdx9.h
${CMAKE_CURRENT_LIST_DIR}/graphics/dx/graphicscontextdx9.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/dx/graphicscontextdx9.h
) )
endif() endif()
@@ -343,6 +365,44 @@ if(FRAMEWORK_GRAPHICS)
set(framework_LIBRARIES ${framework_LIBRARIES} X11) set(framework_LIBRARIES ${framework_LIBRARIES} X11)
endif() endif()
option(SDL "Use SDL 2.0 support" OFF)
if(SDL)
find_package(SDL2 REQUIRED)
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DSDL)
set(framework_INCLUDE_DIRS ${framework_INCLUDE_DIRS} ${SDL2_INCLUDE_DIR})
set(framework_LIBRARIES ${framework_LIBRARIES} ${SDL2_LIBRARY})
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/graphics/sdl/paintersdl.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/sdl/paintersdl.h
${CMAKE_CURRENT_LIST_DIR}/platform/sdlwindow.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/sdlwindow.h
)
else()
if(WIN32)
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/platform/win32window.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/win32window.h
)
if(NOT OPENGLES)
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/graphicscontextwgl.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/graphicscontextwgl.h
)
endif()
else()
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/platform/x11window.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/x11window.h
)
if(NOT OPENGLES)
set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/graphicscontextglx.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/graphicscontextglx.h
)
endif()
endif()
endif()
set(framework_SOURCES ${framework_SOURCES} set(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/graphics/animatedtexture.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/animatedtexture.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/animatedtexture.h ${CMAKE_CURRENT_LIST_DIR}/graphics/animatedtexture.h
@@ -362,6 +422,8 @@ if(FRAMEWORK_GRAPHICS)
${CMAKE_CURRENT_LIST_DIR}/graphics/glutil.h ${CMAKE_CURRENT_LIST_DIR}/graphics/glutil.h
${CMAKE_CURRENT_LIST_DIR}/graphics/graphics.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/graphics.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/graphics.h ${CMAKE_CURRENT_LIST_DIR}/graphics/graphics.h
${CMAKE_CURRENT_LIST_DIR}/graphics/graphicscontext.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/graphicscontext.h
${CMAKE_CURRENT_LIST_DIR}/graphics/hardwarebuffer.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/hardwarebuffer.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/hardwarebuffer.h ${CMAKE_CURRENT_LIST_DIR}/graphics/hardwarebuffer.h
${CMAKE_CURRENT_LIST_DIR}/graphics/image.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/image.cpp
@@ -397,6 +459,8 @@ if(FRAMEWORK_GRAPHICS)
${CMAKE_CURRENT_LIST_DIR}/graphics/shaderprogram.h ${CMAKE_CURRENT_LIST_DIR}/graphics/shaderprogram.h
${CMAKE_CURRENT_LIST_DIR}/graphics/texture.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/texture.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/texture.h ${CMAKE_CURRENT_LIST_DIR}/graphics/texture.h
${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/textureogl.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/ogl/textureogl.h
${CMAKE_CURRENT_LIST_DIR}/graphics/texturemanager.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/texturemanager.cpp
${CMAKE_CURRENT_LIST_DIR}/graphics/texturemanager.h ${CMAKE_CURRENT_LIST_DIR}/graphics/texturemanager.h
${CMAKE_CURRENT_LIST_DIR}/graphics/vertexarray.h ${CMAKE_CURRENT_LIST_DIR}/graphics/vertexarray.h
@@ -435,10 +499,6 @@ if(FRAMEWORK_GRAPHICS)
# platform window # platform window
${CMAKE_CURRENT_LIST_DIR}/platform/platformwindow.cpp ${CMAKE_CURRENT_LIST_DIR}/platform/platformwindow.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/platformwindow.h ${CMAKE_CURRENT_LIST_DIR}/platform/platformwindow.h
${CMAKE_CURRENT_LIST_DIR}/platform/win32window.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/win32window.h
${CMAKE_CURRENT_LIST_DIR}/platform/x11window.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/x11window.h
# window input # window input
${CMAKE_CURRENT_LIST_DIR}/input/mouse.cpp ${CMAKE_CURRENT_LIST_DIR}/input/mouse.cpp
@@ -546,10 +606,6 @@ if(FRAMEWORK_SQL)
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DFW_SQL) set(framework_DEFINITIONS ${framework_DEFINITIONS} -DFW_SQL)
endif() endif()
if(EXTRA_LIBS)
set(framework_LIBRARIES ${framework_LIBRARIES} ${EXTRA_LIBS})
endif()
include_directories(${framework_INCLUDE_DIRS}) include_directories(${framework_INCLUDE_DIRS})
add_definitions(${framework_DEFINITIONS}) add_definitions(${framework_DEFINITIONS})

View File

@@ -4,13 +4,7 @@
# EGL_LIBRARY - the EGL library # EGL_LIBRARY - the EGL library
FIND_PATH(EGL_INCLUDE_DIR NAMES EGL/egl.h) FIND_PATH(EGL_INCLUDE_DIR NAMES EGL/egl.h)
SET(_EGL_STATIC_LIBS libEGL.a) FIND_LIBRARY(EGL_LIBRARY NAMES EGL.dll EGL)
SET(_EGL_SHARED_LIBS libEGL.dll.a EGL)
#IF(USE_STATIC_LIBS)
# FIND_LIBRARY(EGL_LIBRARY NAMES ${_EGL_STATIC_LIBS} ${_EGL_SHARED_LIBS})
#ELSE()
FIND_LIBRARY(EGL_LIBRARY NAMES ${_EGL_SHARED_LIBS} ${_EGL_STATIC_LIBS})
#ENDIF()
INCLUDE(FindPackageHandleStandardArgs) INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(EGL DEFAULT_MSG EGL_LIBRARY EGL_INCLUDE_DIR) FIND_PACKAGE_HANDLE_STANDARD_ARGS(EGL DEFAULT_MSG EGL_LIBRARY EGL_INCLUDE_DIR)
MARK_AS_ADVANCED(EGL_LIBRARY EGL_INCLUDE_DIR) MARK_AS_ADVANCED(EGL_LIBRARY EGL_INCLUDE_DIR)

View File

@@ -4,13 +4,7 @@
# OPENGLES1_LIBRARY - the OpenGL ES 1.0 library # OPENGLES1_LIBRARY - the OpenGL ES 1.0 library
FIND_PATH(OPENGLES1_INCLUDE_DIR NAMES GLES/gl.h) FIND_PATH(OPENGLES1_INCLUDE_DIR NAMES GLES/gl.h)
SET(_OPENGLES1_STATIC_LIBS libGLESv1_CM.a libGLES_CM.a) FIND_LIBRARY(OPENGLES1_LIBRARY NAMES GLESv1_CM.dll GLES_CM.dll GLESv1_CM GLES_CM)
SET(_OPENGLES1_SHARED_LIBS libGLESv1_CM.dll.a libGLES_CM.dll.a GLESv1_CM GLES_CM)
#IF(USE_STATIC_LIBS)
# FIND_LIBRARY(OPENGLES1_LIBRARY NAMES ${_OPENGLES1_STATIC_LIBS} ${_OPENGLES1_SHARED_LIBS})
#ELSE()
FIND_LIBRARY(OPENGLES1_LIBRARY NAMES ${_OPENGLES1_SHARED_LIBS} ${_OPENGLES1_STATIC_LIBS})
#ENDIF()
INCLUDE(FindPackageHandleStandardArgs) INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenGLES2 DEFAULT_MSG OPENGLES1_LIBRARY OPENGLES1_INCLUDE_DIR) FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenGLES2 DEFAULT_MSG OPENGLES1_LIBRARY OPENGLES1_INCLUDE_DIR)
MARK_AS_ADVANCED(OPENGLES1_LIBRARY OPENGLES1_INCLUDE_DIR) MARK_AS_ADVANCED(OPENGLES1_LIBRARY OPENGLES1_INCLUDE_DIR)

View File

@@ -4,13 +4,7 @@
# OPENGLES2_LIBRARY - the OpenGL ES 2.0 library # OPENGLES2_LIBRARY - the OpenGL ES 2.0 library
FIND_PATH(OPENGLES2_INCLUDE_DIR NAMES GLES2/gl2.h) FIND_PATH(OPENGLES2_INCLUDE_DIR NAMES GLES2/gl2.h)
SET(_OPENGLES2_STATIC_LIBS libGLESv2.a) FIND_LIBRARY(OPENGLES2_LIBRARY NAMES GLESv2.dll GLESv2)
SET(_OPENGLES2_SHARED_LIBS libGLESv2.dll.a GLESv2)
#IF(USE_STATIC_LIBS)
# FIND_LIBRARY(OPENGLES2_LIBRARY NAMES ${_OPENGLES2_STATIC_LIBS} ${_OPENGLES2_SHARED_LIBS})
#ELSE()
FIND_LIBRARY(OPENGLES2_LIBRARY NAMES ${_OPENGLES2_SHARED_LIBS} ${_OPENGLES2_STATIC_LIBS})
#ENDIF()
INCLUDE(FindPackageHandleStandardArgs) INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenGLES2 DEFAULT_MSG OPENGLES2_LIBRARY OPENGLES2_INCLUDE_DIR) FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenGLES2 DEFAULT_MSG OPENGLES2_LIBRARY OPENGLES2_INCLUDE_DIR)
MARK_AS_ADVANCED(OPENGLES2_LIBRARY OPENGLES2_INCLUDE_DIR) MARK_AS_ADVANCED(OPENGLES2_LIBRARY OPENGLES2_INCLUDE_DIR)

View File

@@ -0,0 +1,16 @@
# Try to find the SDL2 library
# SDL2_FOUND - system has SDL2
# SDL2_INCLUDE_DIR - the SDL2 include directory
# SDL2_LIBRARY - the SDL2 library
FIND_PATH(SDL2_INCLUDE_DIR PATH_SUFFIXES SDL2 SDL NAMES SDL.h)
SET(_SDL2_STATIC_LIBS libSDL2.a libSDL.a)
SET(_SDL2_SHARED_LIBS libSDL2.dll.a SDL2 SDL libSDL.dll.a SDL)
IF(USE_STATIC_LIBS)
FIND_LIBRARY(SDL2_LIBRARY NAMES ${_SDL2_STATIC_LIBS} ${_SDL2_SHARED_LIBS})
ELSE()
FIND_LIBRARY(SDL2_LIBRARY NAMES ${_SDL2_SHARED_LIBS} ${_SDL2_STATIC_LIBS})
ENDIF()
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 DEFAULT_MSG SDL2_LIBRARY SDL2_INCLUDE_DIR)
MARK_AS_ADVANCED(SDL2_LIBRARY SDL2_INCLUDE_DIR)

View File

@@ -23,11 +23,11 @@
#ifndef FRAMEWORK_CONST_H #ifndef FRAMEWORK_CONST_H
#define FRAMEWORK_CONST_H #define FRAMEWORK_CONST_H
#include "stdext/compiler.h"
#define DEG_TO_RAD (acos(-1)/180.0) #define DEG_TO_RAD (acos(-1)/180.0)
#define RAD_TO_DEC (180.0/acos(-1)) #define RAD_TO_DEC (180.0/acos(-1))
#define BUILD_COMPILER "gcc " __VERSION__
#ifndef BUILD_COMMIT #ifndef BUILD_COMMIT
#define BUILD_COMMIT "devel" #define BUILD_COMMIT "devel"
#endif #endif
@@ -52,8 +52,9 @@
namespace Fw namespace Fw
{ {
static const float pi = 3.14159265; constexpr float pi = 3.14159265;
static const float MIN_ALPHA = 0.003f; constexpr float MIN_ALPHA = 0.003f;
enum Key : unsigned char { enum Key : unsigned char {
KeyUnknown = 0, KeyUnknown = 0,
KeyEscape = 1, KeyEscape = 1,

View File

@@ -33,6 +33,7 @@
#include <framework/platform/platform.h> #include <framework/platform/platform.h>
#include <locale> #include <locale>
#include <boost/concept_check.hpp>
#ifdef FW_NET #ifdef FW_NET
#include <framework/net/connection.h> #include <framework/net/connection.h>
@@ -147,11 +148,6 @@ void Application::poll()
#endif #endif
g_dispatcher.poll(); g_dispatcher.poll();
// poll connection again to flush pending write
#ifdef FW_NET
Connection::poll();
#endif
} }
void Application::exit() void Application::exit()
@@ -168,10 +164,14 @@ void Application::close()
std::string Application::getOs() std::string Application::getOs()
{ {
#if defined(WIN32) #if defined(ANDROID)
return "android";
#elif defined(IOS)
return "ios";
#elif defined(WIN32)
return "windows"; return "windows";
#elif defined(__APPLE__) #elif defined(__APPLE__)
return "mac"; return "macos";
#elif __linux #elif __linux
return "linux"; return "linux";
#else #else

View File

@@ -24,12 +24,14 @@
#include "graphicalapplication.h" #include "graphicalapplication.h"
#include <framework/core/clock.h> #include <framework/core/clock.h>
#include <framework/core/eventdispatcher.h> #include <framework/core/eventdispatcher.h>
#include <framework/input/mouse.h>
#include <framework/platform/platformwindow.h> #include <framework/platform/platformwindow.h>
#include <framework/ui/uimanager.h> #include <framework/ui/uimanager.h>
#include <framework/graphics/graphics.h> #include <framework/graphics/graphics.h>
#include <framework/graphics/particlemanager.h> #include <framework/graphics/particlemanager.h>
#include <framework/graphics/texturemanager.h> #include <framework/graphics/texturemanager.h>
#include <framework/graphics/painter.h> #include <framework/graphics/painter.h>
#include <framework/graphics/ogl/textureogl.h>
#ifdef FW_SOUND #ifdef FW_SOUND
#include <framework/sound/soundmanager.h> #include <framework/sound/soundmanager.h>
@@ -232,7 +234,7 @@ void GraphicalApplication::resize(const Size& size)
m_onInputEvent = false; m_onInputEvent = false;
if(g_graphics.canCacheBackbuffer()) { if(g_graphics.canCacheBackbuffer()) {
m_foreground = TexturePtr(new Texture(size)); m_foreground = TexturePtr(new TextureOGL(size));
m_foreground->setUpsideDown(true); m_foreground->setUpsideDown(true);
} }
m_mustRepaint = true; m_mustRepaint = true;

Some files were not shown because too many files have changed in this diff Show More