89 Commits

Author SHA1 Message Date
Eduardo Bart
28786a3570 Update make_snapshop.sh 2013-11-13 14:33:29 -02:00
Eduardo Bart
b07a77f705 Changes to compile for Win64 2013-11-13 13:55:34 -02:00
Eduardo Bart
0d44942e8e Version 0.6.4 2013-11-13 13:07:37 -02:00
Eduardo Bart
dd829395e3 Merge pull request #376 from dalkon/master
Item phases & Fix party "bug" & Additions
2013-11-12 15:56:54 -08:00
dalkon
18fa54181a Format fix 2013-11-13 00:50:46 +01:00
dalkon
5b8ff29fa3 Fix party "bug" & Additions 2013-11-13 00:48:41 +01:00
dalkon
59e90e8f1e Item phases 2013-11-13 00:18:15 +01:00
Sam
5db37857bf Fix game zoom issue 2013-11-12 23:35:19 +01:00
Eduardo Bart
fc0297d6db Fix compile errors in ubuntu 2013-11-12 20:07:46 -02:00
Eduardo Bart
1060c6f78c Compilation for MSVC2013, thanks @dalkon
OTclient now compiles in "Microsoft Visual Studio 2013 Express for Windows Desktop"
All the needed libraries you can download at https://www.dropbox.com/s/2yfb1c763io8efy/otclient-msvc13-libs.zip
NOTE: You have to change VC++ Directories to the properly directories
NOTE: Latested MSVC 2013 or greated is required
2013-11-12 16:32:39 -02:00
dalkon
c9597d6682 Visual Studio 2013 Compatibility 2013-11-12 16:32:39 -02:00
dalkon
d3e97d33c7 Update .gitignore 2013-11-12 16:32:39 -02:00
Ahmed Samy
2b015d49d7 don't set bits twice 2013-11-12 20:06:59 +02:00
Ahmed Samy
f04b4a0b42 small fix 2013-11-12 20:02:24 +02:00
Ahmed Samy
ff5c22d4c0 Tiny fix
Saving newly made houses by the map editor is not even supported, so this
is not a bug
2013-11-12 17:15:09 +02:00
Sam
d6105a98d1 Fixed issue with deathwindow 2013-11-12 15:21:10 +01:00
Eduardo Bart
0938e22eb9 Fixes in stdext::format 2013-11-11 23:07:25 -02:00
Eduardo Bart
1868b235cb Implement creature marks 2013-11-11 01:45:18 -02:00
Eduardo Bart
9a30050340 Fix typo 2013-11-10 23:40:29 -02:00
Eduardo Bart
9d689f0c43 Add missing changes for protocol > 1000 2013-11-10 23:31:59 -02:00
Eduardo Bart
2b34c0ea0a Fix #337
The sound buffer was not being fully preloaded because it's size was incorrect
2013-11-10 20:35:00 -02:00
Eduardo Bart
d32f71c2b9 Partial support for protocol 1020 and minimize lag
I am able to login in global Tibia however there are game protocol errors
* there is a new opcode 167, which I dont know what it is
* there are changes in opcode 147 which handles text messages that I don't know too

Connection writing was optimized, playing "lag" should improve by 10ms,
and improve much more in systems with low fps
2013-11-10 20:10:04 -02:00
Eduardo Bart
3cff331723 Merge github.com:BrunoDCC/otclient 2013-11-10 19:36:06 -02:00
Eduardo Bart
9894f0c0b9 Merge github.com:conde2/otclient 2013-11-10 19:31:24 -02:00
conde2
e60372fdea A little fix! 2013-11-10 03:17:49 -02:00
conde2
d2473fd424 Login support for 10.21 ~ 10.22
Please someone test more it !
Not tested in real Tibia !
2013-11-10 03:13:51 -02:00
BrunoDCC
7d7bd00a63 minor fix :3 2013-11-09 22:48:29 -02:00
BrunoDCC
c81a623c43 Fixes for creatures name
fixes on save houses (Now open most generate some error)
First 10.22 commit (open dat to edit)
Add server id for new versions
2013-11-09 20:04:48 -02:00
Eduardo Bart
8b165b95fd non relevant change 2013-11-05 21:32:27 -02:00
Sam
6f9436dd60 UISprite widget added
Display single sprites
2013-10-30 21:35:29 +01:00
Henrique Santiago
ae95f51346 Merge pull request #367 from shdpl/patch-1
Polish locale update
2013-10-26 09:46:15 -07:00
shdpl
9b84570372 Polish locale update
UTF-8 or UTF-16 pls
2013-10-25 19:27:19 +02:00
Eduardo Bart
38dec168ee Fix boost::asio misuse that would cause lag
io_service::reset was not called before io_service::poll, meaning that new events would be really polled in the next Connection::poll call, this could lead to network lag in computers with low framerate (ie: a user with 10 fps would have 100ms lag just because of that)
2013-10-22 21:42:35 -02:00
Henrique Santiago
84b722f8c7 Merge pull request #365 from conde2/master
Fix - Writeable / Readable items Issues: #362 and #364
2013-10-21 17:29:13 -07:00
Joao Pasqualini Costa
b3717ceb93 Fix - Writeable / Readable items 2013-10-21 22:25:12 -02:00
Henrique Santiago
3340e06da6 Merge pull request #363 from conde2/master
Fix protocol error #362
2013-10-20 17:24:19 -07:00
Joao Pasqualini Costa
084ee45650 A little mistake 2013-10-20 20:33:44 -02:00
Joao Pasqualini Costa
7290ec3334 Some work on container pagination
Bind lua functions for containers
Update onAddItem now it have the pagination slot
Note: getSize as i see is equal to getItemsCount, but not sure thats why
I've added !
2013-10-20 20:21:20 -02:00
Joao Pasqualini Costa
971d90a596 Fix protocol error #362
TODO:
Handle the helpers in LUA, it could be added into Battle Window i think,
if someone know where should this be comment here !
2013-10-20 18:31:20 -02:00
Sam
8230bf2af4 Merge branch 'master' of https://github.com/edubart/otclient 2013-10-20 17:15:30 +02:00
Sam
241b54262a Updated lua consts 2013-10-20 17:15:24 +02:00
Ahmed Samy
63ce68b449 mapio: make sure we read the house tile flag 2013-10-12 11:38:30 +02:00
Ahmed Samy
f47ea05abc Merge https://github.com/BrunoDCC/otclient
# By BrunoDCC
# Via BrunoDCC
* https://github.com/BrunoDCC/otclient:
  Save houses and spawns fix
2013-10-11 11:38:03 +02:00
BrunoDCC
de3160c90d Save houses and spawns fix 2013-10-11 02:35:31 -03:00
Sam
67bd00556d Re-added "Don't stretch/shrink" option
Closes #345
2013-10-09 18:17:50 +02:00
Sam
778559c7b9 Protocol 10.10 fixed containers 2013-10-09 17:58:58 +02:00
Sam
3aac0ac0ec Reverting mapio.cpp change
Should not have been commited.
2013-10-07 21:38:55 +02:00
Sam
4adfafc67e Fix for Client 8.5 2013-10-07 21:32:13 +02:00
Sam
1b27a095a9 Hotkeys for Fluid Containers
Hotkeys now save subType for fluid containers instead of always trying
to use item with subType 0.
2013-10-05 18:08:49 +02:00
Sam
e6977b1b43 Improvement / Fix hotkeys
- Hotkeys now check items in inventory
- Fixed USEONETARGET hotkey bug
2013-10-05 02:31:44 +02:00
Sam
5843b78e87 Support for client version 7.6
Tell me if there are parts which I should change.

- Not everything is tested yet, feel free to report bugs in 7.6
- the data send in between login opcode and account data might not be
correct, but I could not find any documents showing the right protocol
yet
- Hotkeys working
2013-10-04 04:09:54 +02:00
Ahmed Samy
7cf645e715 Woops, fix operator less than 2013-09-02 19:12:12 +00:00
Ahmed Samy
537508021e Make g_map.findItemsById return a map instead of a vector 2013-09-02 17:53:32 +00:00
Ahmed Samy
e741a62ce9 g_map.findItemsByid 2013-08-31 01:18:17 +00:00
Ahmed Samy
56d6ef6642 Introduce 4 new functions:
- g_map.beginGhostMode(float opacity)
- g_map.endGhostMode()
- UIMap::movePixels(int x, int y)
- MapView::move(int x, int y)
2013-08-30 01:54:36 +00:00
Ahmed Samy
3db8f54aa9 Introduce 2 new functions to g_things
- g_things.findItemTypesByName
- g_things.findItemTypesByString
2013-08-29 17:53:21 +00:00
Ahmed Samy
9234030c1b Zone colors: add more tile flags to be checked for 2013-08-27 15:49:48 +00:00
Ahmed Samy
520baa28ea Move "getNPC" that was introduced in commit
00729bbc2e
from Spawn to CreatureType

I didn't have a closer look at how his code was structured, what he
basically did
is that he set all creatures in a spawn as NPC's even if it's a monster
which is
so erroneous.

Highlights:
- Add branch prediction macros
- Minor code style fixes & some others

Hopefully the branch prediction thing will speed up OTB since it's
awfully slow.
2013-08-27 03:40:18 +02:00
Ben Dol
bbdeac2e33 Merge pull request #353 from KnopersPL/master
Fix for protocol 850 errors, thanks @KnopersPL
2013-08-25 03:54:39 -07:00
KnopersPL
1f914351bb Update protocolcodes.cpp
Fix for server messages on 850
2013-08-25 12:24:18 +02:00
KnopersPL
eb68504dc1 Update protocolgameparse.cpp
Fix the slow animation move effect, some opcodes error and logging in as GM
2013-08-25 12:20:54 +02:00
Ahmed Samy
32647f11bf Introduce 2 new functions to Map
- g_map.colorizeThing
- g_map.removeThingColor
2013-08-24 00:09:56 +02:00
Ahmed Samy
644d4daeea More cleanups 2013-08-23 02:12:36 +02:00
Ahmed Samy
b27352c321 Merge branch 'master' of https://github.com/BrunoDCC/otclient
* 'master' of https://github.com/BrunoDCC/otclient:
  Add full npc read (it not cause bug)
  Fixed a npcs save Fixed a spawns and npcs load
2013-08-23 02:03:40 +02:00
BrunoDCC
a6be9ae525 Add full npc read (it not cause bug) 2013-08-22 21:00:48 -03:00
Ahmed Samy
5df3ec8cf2 More cleanups
Also, bind map descriptions auxiliar functions
2013-08-23 01:55:15 +02:00
BrunoDCC
00729bbc2e Fixed a npcs save
Fixed a spawns and npcs load
2013-08-22 20:54:09 -03:00
Ahmed Samy
3b2d8a2b5e Fix build 2013-08-22 23:20:44 +02:00
Ahmed Samy
d5298c1011 Cleanups 2013-08-22 21:15:17 +02:00
Allan Ference
aaad8ab8a0 Fix spawn loading and saving, thanks to @BrunoDCC 2013-08-20 12:14:52 +02:00
Allan Ference
efbd9ab693 Attempt to fix spawn loader 2013-08-19 18:57:25 +02:00
Allan Ference
092209c0bb Attempt to fix houses and spawns save 2013-08-19 10:38:22 +02:00
Allan Ference
05f7f6a4cf Introduce Item::getName() 2013-08-18 18:29:20 +02:00
Ben Dol
2c36ca7215 Merge pull request #350 from conde2/master
Fix Keyboard unbind, WASD walk, Mount Frames, Fix #349, #344, #304, #253 Thanks @conde2!
2013-08-17 19:23:06 -07:00
Joao Pasqualini Costa
926eb9f01e Fix #253
Message Mode 12
2013-08-17 22:57:38 -03:00
Joao Pasqualini Costa
96bb28e806 Fix Mount frame issue
This will fix mount for all protocols
2013-08-17 22:19:24 -03:00
Joao Pasqualini Costa
e15995e1eb Fix walk with WASD
This should be an alone bind, so any other control will not affect the
keys.
2013-08-17 21:56:37 -03:00
Joao Pasqualini Costa
719debfeae Fix keyboard unbind
Now this will unbind the right widget
2013-08-17 21:54:16 -03:00
Allan Ference
e7137c2535 Rework NPCs loader with g_resources (Untested) 2013-08-17 23:36:44 +02:00
Allan Ference
5eabf6f518 Optional and configurable zone colors 2013-08-17 23:06:58 +02:00
Allan Ference
5849136526 Introduce g_things.findItemTypeByName 2013-08-17 15:09:10 +02:00
Allan Ference
0451fd6b58 OTBM saver: don't escape version check for waypoints 2013-08-15 11:20:22 +02:00
Allan Ference
9cf878335a Minor changes
Mainly code style
2013-08-14 18:58:53 +02:00
BeniS
529b646316 Forgot to provide the widget for walk key bind, thanks conde2! 2013-08-13 10:22:34 +12:00
Allan Ference
1ea2b380ca Disregard progressbar 2013-08-09 17:35:56 +02:00
Allan Ference
914fe249ab Merge branch 'master' of https://github.com/BrunoDCC/otclient
* 'master' of https://github.com/BrunoDCC/otclient:
  Fix OTBM save Remove if(version > 1) { (it causes bug)
2013-08-09 14:54:09 +02:00
BrunoDCC
4d498ed0d8 Fix OTBM save
Remove if(version > 1) { (it causes bug)
2013-08-07 20:04:21 -03:00
Allan Ference
9aa667da26 MapEditor: more changes for ease of use 2013-08-04 14:21:12 +02:00
Allan Ference
e6db43ac3a MapEditor specific: Use colors for tile states 2013-08-04 14:19:10 +02:00
92 changed files with 3651 additions and 977 deletions

69
.gitignore vendored
View File

@@ -39,3 +39,72 @@ Thumbs.db
.directory
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)
project(otclient)
set(VERSION "0.6.3")
set(VERSION "0.6.4")
option(FRAMEWORK_SOUND "Use SOUND " ON)
option(FRAMEWORK_GRAPHICS "Use GRAPHICS " ON)

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

View File

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

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

View File

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

View File

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

View File

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

View File

@@ -11,7 +11,7 @@ countWindow = nil
logoutWindow = nil
exitWindow = nil
bottomSplitter = nil
limitZoom = false
limitedZoom = false
currentViewMode = 0
smartWalkDirs = {}
smartWalkDir = nil
@@ -89,15 +89,15 @@ function bindKeys()
end
function bindWalkKey(key, dir)
g_keyboard.bindKeyDown(key, function() changeWalkDir(dir) end)
g_keyboard.bindKeyUp(key, function() changeWalkDir(dir, true) end)
g_keyboard.bindKeyPress(key, function() smartWalk(dir) end)
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)
g_keyboard.unbindKeyUp(key)
g_keyboard.unbindKeyPress(key)
g_keyboard.unbindKeyDown(key, gameRootPanel)
g_keyboard.unbindKeyUp(key, gameRootPanel)
g_keyboard.unbindKeyPress(key, gameRootPanel)
end
function terminate()
@@ -127,16 +127,6 @@ function onGameStart()
else
g_game.disableFeature(GameForceFirstAutoWalkStep)
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
function onGameEnd()
@@ -153,6 +143,16 @@ function show()
setupViewMode(0)
updateStretchShrink()
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
function hide()
@@ -775,7 +775,7 @@ function setupViewMode(mode)
gameMapPanel:setZoom(11)
gameMapPanel:setVisibleDimension({ width = 15, height = 11 })
elseif mode == 2 then
local limit = limitZoom and not g_game.isGM()
local limit = limitedZoom and not g_game.isGM()
gameMapPanel:setLimitVisibleRange(limit)
gameMapPanel:setZoom(11)
gameMapPanel:setVisibleDimension({ width = 15, height = 11 })
@@ -800,5 +800,5 @@ function setupViewMode(mode)
end
function limitZoom()
limitZoom = true
limitedZoom = true
end

View File

@@ -17,6 +17,7 @@ end
function reset()
if deathWindow then
deathWindow:destroy()
deathWindow = nil
end
end

View File

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

View File

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

View File

@@ -52,23 +52,25 @@ function getShieldImagePathAndBlink(shieldId)
if shieldId == ShieldWhiteYellow then
path, blink = '/images/game/shields/shield_yellow_white', false
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
path, blink = '/images/game/shields//shield_blue', false
path, blink = '/images/game/shields/shield_blue', false
elseif shieldId == ShieldYellow then
path, blink = '/images/game/shields//shield_yellow', false
path, blink = '/images/game/shields/shield_yellow', false
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
path, blink = '/images/game/shields//shield_yellow_shared', false
path, blink = '/images/game/shields/shield_yellow_shared', false
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
path, blink = '/images/game/shields//shield_yellow_not_shared', true
path, blink = '/images/game/shields/shield_yellow_not_shared', true
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
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
return path, blink
end
@@ -81,6 +83,10 @@ function getEmblemImagePath(emblemId)
path = '/images/game/emblems/emblem_red'
elseif emblemId == EmblemBlue then
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
return path
end

View File

@@ -4,6 +4,20 @@ function g_game.getRsa()
return currentRsa
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)
if currentRsa ~= CIPSOFT_RSA and currentRsa ~= OTSERV_RSA then return end
if host:ends('.tibia.com') or host:ends('.cipsoft.com') then
@@ -34,11 +48,11 @@ end
function g_game.getSupportedClients()
return {
810, 811, 840, 842, 850, 853, 854,
860, 861, 862, 870, 910, 940, 944,
953, 954, 960, 961, 963, 970, 980,
981, 982, 983, 984, 985, 986, 1001,
1002, 1010
760, 810, 811, 840, 842, 850, 853,
854, 860, 861, 862, 870, 910, 940,
944, 953, 954, 960, 961, 963, 970,
980, 981, 982, 983, 984, 985, 986,
1001, 1002, 1010, 1020, 1021, 1022,
}
end

View File

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

View File

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

View File

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

View File

@@ -227,14 +227,17 @@ namespace Otc
ShieldBlueNoSharedExpBlink, // 7 party member sexp inactive guilty
ShieldYellowNoSharedExpBlink, // 8 // party leader sexp inactive guilty
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 {
EmblemNone = 0,
EmblemGreen,
EmblemRed,
EmblemBlue
EmblemBlue,
EmblemMember,
EmblemOther
};
enum PlayerStates {
@@ -355,6 +358,16 @@ namespace Otc
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
LastGameFeature = 101
};

View File

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

View File

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

View File

@@ -458,6 +458,11 @@ void Creature::updateWalkAnimation(int totalPixelsWalked)
int footAnimPhases = getAnimationPhases() - 1;
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)
m_walkAnimationPhase = 0;
else if(m_footStepDrawn && m_footTimer.ticksElapsed() >= footDelay && totalPixelsWalked < 32) {

View File

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

View File

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

View File

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

View File

@@ -234,6 +234,22 @@ void Game::processGMActions(const std::vector<uint8>& 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()
{
g_lua.callGlobalField("g_game", "onPing");
@@ -268,10 +284,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);
}
void Game::processOpenContainer(int containerId, const ItemPtr& containerItem, const std::string& name, int capacity, bool hasParent, const std::vector<ItemPtr>& items)
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)
{
ContainerPtr previousContainer = getContainer(containerId);
ContainerPtr container = ContainerPtr(new Container(containerId, capacity, name, containerItem, hasParent));
ContainerPtr container = ContainerPtr(new Container(containerId, capacity, name, containerItem, hasParent, isUnlocked, hasPages, containerSize, firstIndex));
m_containers[containerId] = container;
container->onAddItems(items);
@@ -296,7 +312,7 @@ void Game::processCloseContainer(int containerId)
container->onClose();
}
void Game::processContainerAddItem(int containerId, const ItemPtr& item)
void Game::processContainerAddItem(int containerId, const ItemPtr& item, int slot)
{
ContainerPtr container = getContainer(containerId);
if(!container) {
@@ -304,7 +320,7 @@ void Game::processContainerAddItem(int containerId, const ItemPtr& item)
return;
}
container->onAddItem(item);
container->onAddItem(item, slot);
}
void Game::processContainerUpdateItem(int containerId, int slot, const ItemPtr& item)
@@ -884,7 +900,7 @@ void Game::useWith(const ItemPtr& item, const ThingPtr& toThing)
if(!pos.isValid()) // virtual item
pos = Position(0xFFFF, 0, 0); // means that is a item in inventory
if(toThing->isCreature())
if(toThing->isCreature() && g_game.getProtocolVersion() >= 780)
m_protocolGame->sendUseOnCreature(pos, item->getId(), item->getStackPos(), toThing->getId());
else
m_protocolGame->sendUseItemWith(pos, item->getId(), item->getStackPos(), toThing->getPosition(), toThing->getId(), toThing->getStackPos());
@@ -903,6 +919,20 @@ void Game::useInventoryItemWith(int itemId, const ThingPtr& toThing)
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)
{
if(!canPerformGameAction() || !item)
@@ -1400,24 +1430,40 @@ void Game::setProtocolVersion(int version)
if(isOnline())
stdext::throw_exception("Unable to change protocol version while online");
if(version != 0 && (version < 810 || version > 1010))
if(version != 0 && version != 760 && (version < 810 || version > 1022))
stdext::throw_exception(stdext::format("Protocol version %d not supported", version));
m_features.reset();
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) {
enableFeature(Otc::GameProtocolChecksum);
enableFeature(Otc::GameChallengeOnLogin);
enableFeature(Otc::GameAccountNames);
}
if(version <= 854) {
if(version >= 780 && version <= 854) { // 780 might not be accurate
enableFeature(Otc::GameChargeableItems);
}
if(version >= 854) {
if(version >= 850) {
enableFeature(Otc::GameDoubleFreeCapacity);
}
if(version >= 854) {
enableFeature(Otc::GameCreatureEmblems);
}
@@ -1472,6 +1518,10 @@ void Game::setProtocolVersion(int version)
enableFeature(Otc::GameThingMarks);
}
if(version >= 1000) {
enableFeature(Otc::GamePVPMode);
}
m_protocolVersion = version;
Proto::buildMessageModesMap(version);
@@ -1487,7 +1537,7 @@ void Game::setClientVersion(int version)
if(isOnline())
stdext::throw_exception("Unable to change client version while online");
if(version != 0 && (version < 810 || version > 1010))
if(version != 0 && version != 760 && (version < 810 || version > 1022))
stdext::throw_exception(stdext::format("Client version %d not supported", version));
m_clientVersion = version;

View File

@@ -73,14 +73,17 @@ protected:
void processAttackCancel(uint seq);
void processWalkCancel(Otc::Direction direction);
void processPlayerHelpers(int helpers);
void processPlayerModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeMode);
// message related
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);
// container related
void processOpenContainer(int containerId, const ItemPtr& containerItem, const std::string& name, int capacity, bool hasParent, const std::vector<ItemPtr>& items);
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 processCloseContainer(int containerId);
void processContainerAddItem(int containerId, const ItemPtr& item);
void processContainerAddItem(int containerId, const ItemPtr& item, int slot);
void processContainerUpdateItem(int containerId, int slot, const ItemPtr& item);
void processContainerRemoveItem(int containerId, int slot);
@@ -158,6 +161,7 @@ public:
void useWith(const ItemPtr& fromThing, const ThingPtr& toThing);
void useInventoryItem(int itemId);
void useInventoryItemWith(int itemId, const ThingPtr& toThing);
ItemPtr findItemInContainers(uint itemId, int subType);
// container related
int open(const ItemPtr& item, const ContainerPtr& previousContainer);

View File

@@ -28,12 +28,10 @@ HouseManager g_houses;
House::House()
{
m_nullTile = TilePtr(new Tile(Position()));
}
House::House(uint32 hId, const std::string &name, const Position &pos)
{
m_nullTile = TilePtr(new Tile(Position()));
setId(hId);
setName(name);
if(pos.isValid())
@@ -42,16 +40,32 @@ House::House(uint32 hId, const std::string &name, const Position &pos)
void House::setTile(const TilePtr& tile)
{
tile->setFlags(TILESTATE_HOUSE);
tile->setFlag(TILESTATE_HOUSE);
tile->setHouseId(getId());
m_tiles.insert(std::make_pair(tile->getPosition(), tile));
}
const TilePtr& House::getTile(const Position& position)
TilePtr House::getTile(const Position& position)
{
TileMap::const_iterator iter = m_tiles.find(position);
if(iter != m_tiles.end())
return iter->second;
return m_nullTile;
return nullptr;
}
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)
@@ -67,16 +81,14 @@ void House::load(const TiXmlElement *elem)
m_isGuildHall = elem->readType<bool>("guildhall");
Position entryPos;
entryPos.x = elem->readType<uint16>("entryx");
entryPos.y = elem->readType<uint16>("entryy");
entryPos.z = elem->readType<uint8>("entryz");
entryPos.x = elem->readType<int>("entryx");
entryPos.y = elem->readType<int>("entryy");
entryPos.z = elem->readType<int>("entryz");
setEntry(entryPos);
}
void House::save(TiXmlElement*& elem)
void House::save(TiXmlElement* elem)
{
elem = new TiXmlElement("house");
elem->SetAttribute("name", getName());
elem->SetAttribute("houseid", getId());
@@ -93,7 +105,6 @@ void House::save(TiXmlElement*& elem)
HouseManager::HouseManager()
{
m_nullHouse = HousePtr(new House);
}
void HouseManager::addHouse(const HousePtr& house)
@@ -109,56 +120,79 @@ void HouseManager::removeHouse(uint32 houseId)
m_houses.erase(it);
}
const HousePtr& HouseManager::getHouse(uint32 houseId)
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(),
[=] (const HousePtr& house) -> bool { return house->getId() == houseId; });
return it != m_houses.end() ? *it : m_nullHouse;
[=] (const HousePtr& house) -> bool { return house->getName() == name; });
return it != m_houses.end() ? *it : nullptr;
}
void HouseManager::load(const std::string& fileName)
{
TiXmlDocument doc;
doc.Parse(g_resources.readFileContents(fileName).c_str());
if(doc.Error())
stdext::throw_exception(stdext::format("failed to load '%s': %s (House XML)", fileName, doc.ErrorDesc()));
try {
TiXmlDocument doc;
doc.Parse(g_resources.readFileContents(fileName).c_str());
if(doc.Error())
stdext::throw_exception(stdext::format("failed to load '%s': %s (House XML)", fileName, doc.ErrorDesc()));
TiXmlElement *root = doc.FirstChildElement();
if(!root || root->ValueTStr() != "houses")
stdext::throw_exception("invalid root tag name");
TiXmlElement *root = doc.FirstChildElement();
if(!root || root->ValueTStr() != "houses")
stdext::throw_exception("invalid root tag name");
for(TiXmlElement *elem = root->FirstChildElement(); elem; elem = elem->NextSiblingElement()) {
if(elem->ValueTStr() != "house")
stdext::throw_exception("invalid house tag.");
for(TiXmlElement *elem = root->FirstChildElement(); elem; elem = elem->NextSiblingElement()) {
if(elem->ValueTStr() != "house")
stdext::throw_exception("invalid house tag.");
uint32 houseId = elem->readType<uint32>("houseid");
HousePtr house = getHouse(houseId);
if(!house)
house = HousePtr(new House(houseId)), addHouse(house);
uint32 houseId = elem->readType<uint32>("houseid");
HousePtr house = getHouse(houseId);
if(!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)
{
TiXmlDocument doc;
doc.SetTabSize(2);
try {
TiXmlDocument doc;
doc.SetTabSize(2);
TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", "");
doc.LinkEndChild(decl);
TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", "");
doc.LinkEndChild(decl);
TiXmlElement* root = new TiXmlElement("houses");
doc.LinkEndChild(root);
TiXmlElement* root = new TiXmlElement("houses");
doc.LinkEndChild(root);
for(auto house : m_houses) {
TiXmlElement *elem;
house->save(elem);
root->LinkEndChild(elem);
for(auto house : m_houses) {
TiXmlElement *elem = new TiXmlElement("house");
house->save(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()));
}
}
if(!doc.SaveFile(fileName))
stdext::throw_exception(stdext::format("failed to save houses XML %s: %s", fileName, doc.ErrorDesc()));
HouseList HouseManager::filterHouses(uint32 townId)
{
HouseList ret;
for(const HousePtr& house : m_houses)
if(house->getTownId() == townId)
ret.push_back(house);
return ret;
}
HouseList::iterator HouseManager::findHouse(uint32 houseId)
@@ -166,3 +200,5 @@ HouseList::iterator HouseManager::findHouse(uint32 houseId)
return std::find_if(m_houses.begin(), m_houses.end(),
[=] (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:
House();
House(uint32 hId, const std::string& name = "", const Position& pos=Position());
~House() { m_tiles.clear(); m_nullTile = nullptr; }
~House() { m_tiles.clear(); }
void setTile(const TilePtr& tile);
const TilePtr& getTile(const Position& pos);
TilePtr getTile(const Position& pos);
void setName(const std::string& name) { m_attribs.set(HouseAttrName, name); }
std::string getName() { return m_attribs.get<std::string>(HouseAttrName); }
@@ -66,14 +66,19 @@ public:
void setEntry(const Position& p) { m_attribs.set(HouseAttrEntry, p); }
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:
void load(const TiXmlElement* elem);
void save(TiXmlElement*& elem);
void save(TiXmlElement* elem);
private:
stdext::packed_storage<uint8> m_attribs;
TileMap m_tiles;
TilePtr m_nullTile;
ItemVector m_doors;
uint32 m_lastDoorId;
stdext::boolean<false> m_isGuildHall;
friend class HouseManager;
@@ -85,16 +90,18 @@ public:
void addHouse(const HousePtr& house);
void removeHouse(uint32 houseId);
HouseList getHouseList() { return m_houses; }
const HousePtr& getHouse(uint32 houseId);
void clear() { m_houses.clear(); m_nullHouse = nullptr; }
HousePtr getHouse(uint32 houseId);
HousePtr getHouseByName(std::string name);
void load(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:
HouseList m_houses;
HousePtr m_nullHouse;
protected:
HouseList::iterator findHouse(uint32 houseId);

View File

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

View File

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

View File

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

View File

@@ -47,6 +47,7 @@
#include "uiminimap.h"
#include "uimapanchorlayout.h"
#include "uiprogressrect.h"
#include "uisprite.h"
#include "outfit.h"
#include <framework/luaengine/luainterface.h>
@@ -66,20 +67,26 @@ void Client::registerLuaFunctions()
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", "findItemTypeByClientId", &ThingTypeManager::findItemTypeByClientId, &g_things);
g_lua.bindSingletonFunction("g_things", "findThingTypeByAttr", &ThingTypeManager::findThingTypeByAttr, &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.registerSingletonClass("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", "save", &HouseManager::save, &g_houses);
g_lua.bindSingletonFunction("g_houses", "getHouse", &HouseManager::getHouse, &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", "getHouseList", &HouseManager::getHouseList, &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", "save", &HouseManager::save, &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", "removeHouse", &HouseManager::removeHouse, &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.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", "removeTown", &TownManager::removeTown, &g_towns);
g_lua.bindSingletonFunction("g_towns", "getTowns", &TownManager::getTowns, &g_towns);
@@ -99,6 +106,8 @@ void Client::registerLuaFunctions()
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", "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", "cleanTile", &Map::cleanTile, &g_map);
g_lua.bindSingletonFunction("g_map", "cleanTexts", &Map::cleanTexts, &g_map);
@@ -119,6 +128,20 @@ void Client::registerLuaFunctions()
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", "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.bindSingletonFunction("g_minimap", "clean", &Minimap::clean, &g_minimap);
@@ -162,6 +185,7 @@ void Client::registerLuaFunctions()
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", "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", "openParent", &Game::openParent, &g_game);
g_lua.bindSingletonFunction("g_game", "close", &Game::close, &g_game);
@@ -294,6 +318,10 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<Container>("getContainerItem", &Container::getContainerItem);
g_lua.bindClassMemberFunction<Container>("hasParent", &Container::hasParent);
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.bindClassMemberFunction<Thing>("setId", &Thing::setId);
@@ -336,6 +364,7 @@ void Client::registerLuaFunctions()
g_lua.registerClass<House>();
g_lua.bindClassStaticFunction<House>("create", []{ return HousePtr(new House); });
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>("getName", &House::getName);
g_lua.bindClassMemberFunction<House>("setTownId", &House::setTownId);
@@ -344,6 +373,9 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<House>("getTile", &House::getTile);
g_lua.bindClassMemberFunction<House>("setEntry", &House::setEntry);
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>("getSize", &House::getSize);
g_lua.bindClassMemberFunction<House>("setRent", &House::setRent);
@@ -423,9 +455,12 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<Item>("clone", &Item::clone);
g_lua.bindClassMemberFunction<Item>("setCount", &Item::setCount);
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>("getName", &Item::getName);
g_lua.bindClassMemberFunction<Item>("isStackable", &Item::isStackable);
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>("getClothSlot", &Item::getClothSlot);
@@ -522,6 +557,10 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<Tile>("isClickable", &Tile::isClickable);
g_lua.bindClassMemberFunction<Tile>("isPathable", &Tile::isPathable);
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.bindClassStaticFunction<UIItem>("create", []{ return UIItemPtr(new UIItem); });
@@ -539,6 +578,13 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIItem>("isVirtual", &UIItem::isVirtual);
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.bindClassStaticFunction<UICreature>("create", []{ return UICreaturePtr(new UICreature); } );
g_lua.bindClassMemberFunction<UICreature>("setCreature", &UICreature::setCreature);
@@ -550,6 +596,7 @@ void Client::registerLuaFunctions()
g_lua.registerClass<UIMap, UIWidget>();
g_lua.bindClassStaticFunction<UIMap>("create", []{ return UIMapPtr(new UIMap); });
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>("zoomIn", &UIMap::zoomIn);
g_lua.bindClassMemberFunction<UIMap>("zoomOut", &UIMap::zoomOut);
@@ -611,7 +658,7 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIMinimap>("getMinZoom", &UIMinimap::getMinZoom);
g_lua.bindClassMemberFunction<UIMinimap>("getMaxZoom", &UIMinimap::getMaxZoom);
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>("fillPosition", &UIMinimap::fillPosition);
g_lua.bindClassMemberFunction<UIMinimap>("centerInPosition", &UIMinimap::centerInPosition);

View File

@@ -216,6 +216,42 @@ bool Map::removeThingByPos(const Position& pos, int stackPos)
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)
{
for(auto staticText : m_staticTexts) {
@@ -305,6 +341,62 @@ 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)
{
m_knownCreatures[creature->getId()] = creature;
@@ -330,7 +422,7 @@ void Map::removeCreatureById(uint32 id)
void Map::removeUnawareThings()
{
// remove creatures from tiles that we are not aware anymore
// remove creatures from tiles that we are not aware of anymore
for(const auto& pair : m_knownCreatures) {
const CreaturePtr& creature = pair.second;
if(!isAwareOfPosition(creature->getPosition()))
@@ -708,3 +800,5 @@ std::tuple<std::vector<Otc::Direction>, Otc::PathFindResult> Map::findPath(const
return ret;
}
/* vim: set ts=4 sw=4 et: */

View File

@@ -144,13 +144,14 @@ public:
bool loadOtcm(const std::string& fileName);
void saveOtcm(const std::string& fileName);
void loadOtbm(const std::string& fileName, const UIWidgetPtr& pbar = 0);
void saveOtbm(const std::string& fileName, const UIWidgetPtr& pbar = 0);
void loadOtbm(const std::string& fileName);
void saveOtbm(const std::string& fileName);
// otbm attributes (description, size, etc.)
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 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 setHeight(uint16 h) { m_attribs.set(OTBM_ATTR_HEIGHT, h); }
@@ -168,6 +169,8 @@ public:
ThingPtr getThing(const Position& pos, int stackPos);
bool removeThing(const ThingPtr& thing);
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);
@@ -179,6 +182,23 @@ public:
const TilePtr& getTile(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
void addCreature(const CreaturePtr& creature);
CreaturePtr getCreatureById(uint32 id);
@@ -223,6 +243,10 @@ private:
std::vector<MapViewPtr> m_mapViews;
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;
Position m_centralPosition;
Rect m_tilesRect;
@@ -235,3 +259,5 @@ private:
extern Map g_map;
#endif
/* vim: set ts=4 sw=4 et: */

View File

@@ -32,364 +32,373 @@
#include <framework/xml/tinyxml.h>
#include <framework/ui/uiwidget.h>
void Map::loadOtbm(const std::string& fileName, const UIWidgetPtr& pbar)
void Map::loadOtbm(const std::string& fileName)
{
FileStreamPtr fin = g_resources.openFile(fileName);
if(!fin)
stdext::throw_exception(stdext::format("Unable to load map '%s'", fileName));
try {
FileStreamPtr fin = g_resources.openFile(fileName);
if(!fin)
stdext::throw_exception(stdext::format("Unable to load map '%s'", fileName));
fin->cache();
if(!g_things.isOtbLoaded())
stdext::throw_exception("OTB isn't loaded yet to load a map.");
fin->cache();
if(!g_things.isOtbLoaded())
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");
BinaryTreePtr root = fin->getBinaryTree();
if(root->getU8())
stdext::throw_exception("could not read root property!");
BinaryTreePtr root = fin->getBinaryTree();
if(root->getU8())
stdext::throw_exception("could not read root property!");
uint32 headerVersion = root->getU32();
if(headerVersion > 3)
stdext::throw_exception(stdext::format("Unknown OTBM version detected: %u.", headerVersion));
uint32 headerVersion = root->getU32();
if(headerVersion > 3)
stdext::throw_exception(stdext::format("Unknown OTBM version detected: %u.", headerVersion));
setWidth(root->getU16());
setHeight(root->getU16());
setWidth(root->getU16());
setHeight(root->getU16());
uint32 headerMajorItems = root->getU8();
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",
uint32 headerMajorItems = root->getU8();
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",
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) {
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()));
}
Position basePos;
basePos.x = nodeMapData->getU16();
basePos.y = nodeMapData->getU16();
basePos.z = nodeMapData->getU8();
BinaryTreePtr node = root->getChildren()[0];
if(node->getU8() != OTBM_MAP_DATA)
stdext::throw_exception("Could not read root data node");
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));
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));
}
}
HousePtr house = nullptr;
uint32 flags = TILESTATE_NONE;
Position pos = basePos + nodeTile->getPoint();
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();
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);
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);
}
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;
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_NOLOGOUT) == TILESTATE_NOLOGOUT)
flags |= TILESTATE_NOLOGOUT;
if((_flags & TILESTATE_REFRESH) == TILESTATE_REFRESH)
flags |= TILESTATE_REFRESH;
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",
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(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();
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);
}
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.");
if(const TilePtr& tile = getTile(pos)) {
if(house)
tile->setHouseId(house->getId());
tile->setFlags((tileflags_t)flags);
//if(!(++pbarvalue % 8192) && pbar);
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_TOWNS) {
TownPtr town = nullptr;
for(const BinaryTreePtr &nodeTown : nodeMapData->getChildren()) {
if(nodeTown->getU8() != OTBM_TOWN)
stdext::throw_exception("invalid town node.");
} else if(mapDataType == OTBM_WAYPOINTS && headerVersion > 1) {
for(const BinaryTreePtr &nodeWaypoint : nodeMapData->getChildren()) {
if(nodeWaypoint->getU8() != OTBM_WAYPOINT)
stdext::throw_exception("invalid waypoint node.");
uint32 townId = nodeTown->getU32();
std::string townName = nodeTown->getString();
std::string name = nodeWaypoint->getString();
Position townCoords;
townCoords.x = nodeTown->getU16();
townCoords.y = nodeTown->getU16();
townCoords.z = nodeTown->getU8();
Position waypointPos;
waypointPos.x = nodeWaypoint->getU16();
waypointPos.y = nodeWaypoint->getU16();
waypointPos.z = nodeWaypoint->getU8();
if(!(town = g_towns.getTown(townId))) {
town = TownPtr(new Town(townId, townName, townCoords));
g_towns.addTown(town);
if(waypointPos.isValid() && !name.empty() && m_waypoints.find(waypointPos) == m_waypoints.end())
m_waypoints.insert(std::make_pair(waypointPos, name));
}
}
} else if(mapDataType == OTBM_WAYPOINTS && headerVersion > 1) {
for(const BinaryTreePtr &nodeWaypoint : nodeMapData->getChildren()) {
if(nodeWaypoint->getU8() != OTBM_WAYPOINT)
stdext::throw_exception("invalid waypoint node.");
} else
stdext::throw_exception(stdext::format("Unknown map data node %d", (int)mapDataType));
}
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()));
}
fin->close();
}
void Map::saveOtbm(const std::string& fileName, const UIWidgetPtr&/* pbar*/)
void Map::saveOtbm(const std::string& fileName)
{
FileStreamPtr fin = g_resources.createFile(fileName);
if(!fin)
stdext::throw_exception(stdext::format("failed to open file '%s' for write", fileName));
try {
FileStreamPtr fin = g_resources.createFile(fileName);
if(!fin)
stdext::throw_exception(stdext::format("failed to open file '%s' for write", fileName));
fin->cache();
std::string dir;
if(fileName.find_last_of('/') == std::string::npos)
dir = g_resources.getWorkDir();
else
dir = fileName.substr(0, fileName.find_last_of('/'));
fin->cache();
std::string dir;
if(fileName.find_last_of('/') == std::string::npos)
dir = g_resources.getWorkDir();
else
dir = fileName.substr(0, fileName.find_last_of('/'));
uint32 version = 0;
if(g_things.getOtbMajorVersion() < ClientVersion820)
version = 1;
else
version = 2;
uint32 version = 0;
if(g_things.getOtbMajorVersion() < ClientVersion820)
version = 1;
else
version = 2;
/// 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
std::string::size_type sep_pos;
std::string houseFile = getHouseFile();
std::string spawnFile = getSpawnFile();
std::string cpyf;
/// 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
std::string::size_type sep_pos;
std::string houseFile = getHouseFile();
std::string spawnFile = getSpawnFile();
std::string cpyf;
if((sep_pos = fileName.rfind('.')) != std::string::npos && stdext::ends_with(fileName, ".otbm"))
cpyf = fileName.substr(0, sep_pos);
if((sep_pos = fileName.rfind('.')) != std::string::npos && stdext::ends_with(fileName, ".otbm"))
cpyf = fileName.substr(0, sep_pos);
if(houseFile.empty())
houseFile = cpyf + "-houses.xml";
if(houseFile.empty())
houseFile = cpyf + "-houses.xml";
if(spawnFile.empty())
spawnFile = cpyf + "-spawns.xml";
if(spawnFile.empty())
spawnFile = cpyf + "-spawns.xml";
/// 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)
spawnFile = spawnFile.substr(sep_pos + 1);
/// 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)
spawnFile = spawnFile.substr(sep_pos + 1);
if((sep_pos = houseFile.rfind('/')) != std::string::npos)
houseFile = houseFile.substr(sep_pos + 1);
if((sep_pos = houseFile.rfind('/')) != std::string::npos)
houseFile = houseFile.substr(sep_pos + 1);
fin->addU32(0); // file version
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);
fin->addU32(0); // file version
OutputBinaryTreePtr root(new OutputBinaryTree(fin));
{
// own description.
for(const auto& desc : getDescriptions()) {
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);
{
// own description.
for(const auto& desc : getDescriptions()) {
root->addU8(OTBM_ATTR_DESCRIPTION);
root->addString(desc);
}
// special one
root->addU8(OTBM_ATTR_DESCRIPTION);
root->addString(desc);
}
root->addString(stdext::format("Saved with %s v%s", g_app.getName(), g_app.getVersion()));
// special one
root->addU8(OTBM_ATTR_DESCRIPTION);
root->addString(stdext::format("Saved with %s v%s", g_app.getName(), g_app.getVersion()));
// spawn file.
root->addU8(OTBM_ATTR_SPAWN_FILE);
root->addString(spawnFile);
// spawn file.
root->addU8(OTBM_ATTR_SPAWN_FILE);
root->addString(spawnFile);
// house file.
if(version > 1) {
// house file.
root->addU8(OTBM_ATTR_HOUSE_FILE);
root->addString(houseFile);
}
int px = -1, py = -1, pz =-1;
bool firstNode = true;
int px = -1, py = -1, pz =-1;
bool firstNode = true;
for(uint8_t z = 0; z <= Otc::MAX_Z; ++z) {
for(const auto& it : m_tileBlocks[z]) {
const TileBlock& block = it.second;
for(const TilePtr& tile : block.getTiles()) {
if(!tile || tile->isEmpty())
continue;
for(uint8_t z = 0; z <= Otc::MAX_Z; ++z) {
for(const auto& it : m_tileBlocks[z]) {
const TileBlock& block = it.second;
for(const TilePtr& tile : block.getTiles()) {
if(unlikely(!tile || tile->isEmpty()))
continue;
const Position& pos = tile->getPosition();
if(!pos.isValid())
continue;
const Position& pos = tile->getPosition();
if(unlikely(!pos.isValid()))
continue;
if(pos.x < px || pos.x >= px + 256
|| pos.y < py || pos.y >= py + 256
|| pos.z != pz) {
if(!firstNode)
root->endNode(); /// OTBM_TILE_AREA
if(pos.x < px || pos.x >= px + 256
|| pos.y < py || pos.y >= py + 256
|| pos.z != pz) {
if(!firstNode)
root->endNode(); /// OTBM_TILE_AREA
firstNode = false;
root->startNode(OTBM_TILE_AREA);
firstNode = false;
root->startNode(OTBM_TILE_AREA);
px = pos.x & 0xFF00;
py = pos.y & 0xFF00;
pz = pos.z;
root->addPos(px, py, pz);
px = pos.x & 0xFF00;
py = pos.y & 0xFF00;
pz = pos.z;
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
if(!firstNode)
root->endNode(); // OTBM_TILE_AREA
root->startNode(OTBM_TOWNS);
for(const TownPtr& town : g_towns.getTowns()) {
root->addU32(town->getId());
root->addString(town->getName());
root->startNode(OTBM_TOWNS);
for(const TownPtr& town : g_towns.getTowns()) {
root->startNode(OTBM_TOWN);
Position townPos = town->getPos();
root->addPos(townPos.x, townPos.y, townPos.z);
}
root->endNode();
root->addU32(town->getId());
root->addString(town->getName());
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);
Position townPos = town->getPos();
root->addPos(townPos.x, townPos.y, townPos.z);
root->endNode();
}
root->endNode();
}
}
root->endNode(); // OTBM_MAP_DATA
}
root->endNode();
fin->flush();
fin->close();
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();
fin->close();
} catch(std::exception& e) {
g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what()));
}
}
bool Map::loadOtcm(const std::string& fileName)
@@ -537,3 +546,5 @@ void Map::saveOtcm(const std::string& fileName)
g_logger.error(stdext::format("failed to save OTCM map: %s", e.what()));
}
}
/* vim: set ts=4 sw=4 et: */

View File

@@ -564,12 +564,20 @@ Position MapView::getPosition(const Point& point, const Size& mapSize)
return position;
}
void MapView::move(int x, int y)
{
m_moveOffset.x = x;
m_moveOffset.y = y;
}
Rect MapView::calcFramebufferSource(const Size& destSize)
{
float scaleFactor = m_tileSize/(float)Otc::TILE_PIXELS;
Point drawOffset = ((m_drawDimension - m_visibleDimension - Size(1,1)).toPoint()/2) * m_tileSize;
if(isFollowingCreature())
drawOffset += m_followingCreature->getWalkOffset() * scaleFactor;
else if(!m_moveOffset.isNull())
drawOffset += m_moveOffset * scaleFactor;
Size srcSize = destSize;
Size srcVisible = m_visibleDimension * m_tileSize;
@@ -703,3 +711,5 @@ void MapView::setDrawLights(bool enable)
m_lightView = nullptr;
m_drawLights = enable;
}
/* vim: set ts=4 sw=4 et: */

View File

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

View File

@@ -189,6 +189,8 @@ public:
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);
}
// 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) {
int nz = z-n;

View File

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

View File

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

View File

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

View File

@@ -219,6 +219,9 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg)
case Proto::GameServerClearTarget:
parsePlayerCancelAttack(msg);
break;
case Proto::GameServerPlayerModes:
parsePlayerModes(msg);
break;
case Proto::GameServerTalk:
parseTalk(msg);
break;
@@ -323,6 +326,13 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg)
case Proto::GameServerEnterGame:
parseEnterGame(msg);
break;
case Proto::GameServerPlayerHelpers:
parsePlayerHelpers(msg);
break;
// PROTOCOL>=1000
case Proto::GameServerCreatureMarks:
parseCreaturesMark(msg);
break;
// otclient ONLY
case Proto::GameServerExtendedOpcode:
parseExtendedOpcode(msg);
@@ -379,13 +389,25 @@ 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)
{
std::vector<uint8> actions;
int numViolationReasons;
if(g_game.getProtocolVersion() >= 854)
if(g_game.getProtocolVersion() >= 850)
numViolationReasons = 20;
else
numViolationReasons = 32;
@@ -535,7 +557,7 @@ void ProtocolGame::parseTileAddThing(const InputMessagePtr& msg)
Position pos = getPosition(msg);
int stackPos = -1;
if(g_game.getProtocolVersion() >= 854)
if(g_game.getProtocolVersion() >= 850)
stackPos = msg->getU8();
ThingPtr thing = getThing(msg);
@@ -604,11 +626,16 @@ void ProtocolGame::parseOpenContainer(const InputMessagePtr& msg)
int capacity = msg->getU8();
bool hasParent = (msg->getU8() != 0);
bool isUnlocked = false;
bool hasPages = false;
int containerSize = 0;
int firstIndex = 0;
if(g_game.getFeature(Otc::GameContainerPagination)) {
msg->getU8(); // drag and drop
msg->getU8(); // pagination
msg->getU16(); // container size
msg->getU16(); // first index
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();
@@ -617,7 +644,7 @@ void ProtocolGame::parseOpenContainer(const InputMessagePtr& msg)
for(int i = 0; i < itemCount; i++)
items[i] = getItem(msg);
g_game.processOpenContainer(containerId, containerItem, name, capacity, hasParent, items);
g_game.processOpenContainer(containerId, containerItem, name, capacity, hasParent, items, isUnlocked, hasPages, containerSize, firstIndex);
}
void ProtocolGame::parseCloseContainer(const InputMessagePtr& msg)
@@ -629,11 +656,12 @@ void ProtocolGame::parseCloseContainer(const InputMessagePtr& msg)
void ProtocolGame::parseContainerAddItem(const InputMessagePtr& msg)
{
int containerId = msg->getU8();
ItemPtr item = getItem(msg);
int slot = 0;
if(g_game.getFeature(Otc::GameContainerPagination)) {
msg->getU16(); // slot
slot = msg->getU16(); // slot
}
g_game.processContainerAddItem(containerId, item);
ItemPtr item = getItem(msg);
g_game.processContainerAddItem(containerId, item, slot);
}
void ProtocolGame::parseContainerUpdateItem(const InputMessagePtr& msg)
@@ -655,7 +683,10 @@ void ProtocolGame::parseContainerRemoveItem(const InputMessagePtr& msg)
int slot;
if(g_game.getFeature(Otc::GameContainerPagination)) {
slot = msg->getU16();
getItem(msg);
int itemId = msg->getU16();
if(itemId != 0)
getItem(msg, itemId);
} else {
slot = msg->getU8();
}
@@ -953,7 +984,15 @@ void ProtocolGame::parseCreatureUnpass(const InputMessagePtr& msg)
void ProtocolGame::parseEditText(const InputMessagePtr& msg)
{
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();
std::string text = msg->getString();
std::string writter = msg->getString();
@@ -1038,7 +1077,9 @@ void ProtocolGame::parsePlayerStats(const InputMessagePtr& msg)
double magicLevelPercent = msg->getU8();
double soul = msg->getU8();
double stamina = msg->getU16();
double stamina = 0;
if(g_game.getFeature(Otc::GamePlayerStamina))
stamina = msg->getU16();
double baseSpeed = 0;
if(g_game.getFeature(Otc::GameSkillsBase))
@@ -1092,7 +1133,12 @@ void ProtocolGame::parsePlayerSkills(const InputMessagePtr& msg)
void ProtocolGame::parsePlayerState(const InputMessagePtr& msg)
{
int states = msg->getU16();
int states;
if(g_game.getFeature(Otc::GamePlayerStateU16))
states = msg->getU16();
else
states = msg->getU8();
m_localPlayer->setStates(states);
}
@@ -1105,6 +1151,20 @@ void ProtocolGame::parsePlayerCancelAttack(const InputMessagePtr& msg)
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)
{
int spellId = msg->getU8();
@@ -1130,10 +1190,15 @@ void ProtocolGame::parseMultiUseCooldown(const InputMessagePtr& msg)
void ProtocolGame::parseTalk(const InputMessagePtr& msg)
{
msg->getU32(); // channel statement guid
if(g_game.getFeature(Otc::GameMessageStatements))
msg->getU32(); // channel statement guid
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());
int channelId = 0;
Position pos;
@@ -1380,15 +1445,22 @@ void ProtocolGame::parseFloorChangeDown(const InputMessagePtr& msg)
void ProtocolGame::parseOpenOutfitWindow(const InputMessagePtr& msg)
{
Outfit currentOutfit = getOutfit(msg);
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();
outfitList.push_back(std::make_tuple(outfitId, outfitName, outfitAddons));
if(g_game.getFeature(Otc::GameNewOutfitProtocol)) {
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;
@@ -1601,6 +1673,28 @@ void ProtocolGame::parseChangeMapAwareRange(const InputMessagePtr& msg)
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)
{
int startz, endz, zstep;
@@ -1665,14 +1759,21 @@ Outfit ProtocolGame::getOutfit(const InputMessagePtr& msg)
{
Outfit outfit;
int lookType = msg->getU16();
int lookType;
if(g_game.getFeature(Otc::GameLooktypeU16))
lookType = msg->getU16();
else
lookType = msg->getU8();
if(lookType != 0) {
outfit.setCategory(ThingCategoryCreature);
int head = msg->getU8();
int body = msg->getU8();
int legs = msg->getU8();
int feet = msg->getU8();
int addons = msg->getU8();
int addons = 0;
if(g_game.getFeature(Otc::GamePlayerAddons))
addons = msg->getU8();
if(!g_things.isValidDatId(lookType, ThingCategoryCreature)) {
g_logger.traceError(stdext::format("invalid outfit looktype %d", lookType));
@@ -1826,14 +1927,22 @@ CreaturePtr ProtocolGame::getCreature(const InputMessagePtr& msg, int type)
// emblem is sent only when the creature is not known
int emblem = -1;
bool unpass = true;
uint8 mark;
if(g_game.getFeature(Otc::GameCreatureEmblems) && !known)
emblem = msg->getU8();
if(g_game.getFeature(Otc::GameThingMarks)) {
msg->getU8(); // creature type for summons
msg->getU8(); // mark
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)
@@ -1899,7 +2008,7 @@ ItemPtr ProtocolGame::getItem(const InputMessagePtr& msg, int id)
if(item->getAnimationPhases() > 1) {
// 0xfe => random phase
// 0xff => async?
msg->getU8(); // phase
item->setAsync(msg->getU8() == 0xff);
}
}

View File

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

View File

@@ -103,6 +103,7 @@ void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileS
m_attribs.set(attr, market);
break;
}
case ThingAttrUsable:
case ThingAttrElevation: {
m_elevation = fin->getU16();
m_attribs.set(attr, m_elevation);

View File

@@ -76,6 +76,7 @@ enum ThingAttr : uint8 {
ThingAttrLook = 31,
ThingAttrCloth = 32,
ThingAttrMarket = 33,
ThingAttrUsable = 34,
// additional
ThingAttrOpacity = 100,

View File

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

View File

@@ -43,6 +43,9 @@ public:
void addItemType(const ItemTypePtr& itemType);
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 ItemTypePtr& getNullItemType() { return m_nullItemType; }

View File

@@ -43,6 +43,15 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags, LightView *
{
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
if(drawFlags & (Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawOnBottom)) {
m_drawElevation = 0;
@@ -50,10 +59,28 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags, LightView *
if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom())
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) ||
(thing->isGroundBorder() && drawFlags & Otc::DrawGroundBorders) ||
(thing->isOnBottom() && drawFlags & Otc::DrawOnBottom)) {
thing->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView);
if(restore) {
g_painter->resetOpacity();
g_painter->resetColor();
}
}
m_drawElevation += thing->getElevation();
@@ -116,25 +143,19 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags, LightView *
CreaturePtr creature = thing->static_self_cast<Creature>();
if(creature && (!creature->isWalking() || !animate))
creature->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView);
}
}
// effects
if(drawFlags & Otc::DrawEffects) {
for(const EffectPtr& effect : m_effects){
if(drawFlags & Otc::DrawEffects)
for(const EffectPtr& effect : m_effects)
effect->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView);
}
}
// top items
if(drawFlags & Otc::DrawOnTop) {
for(const ThingPtr& thing : m_things) {
if(thing->isOnTop()){
thing->draw(dest, scaleFactor, animate, lightView);
}
}
}
if(drawFlags & Otc::DrawOnTop)
for(const ThingPtr& thing : m_things)
if(thing->isOnTop())
thing->draw(dest, scaleFactor, animate, lightView);
// draw translucent light (for tiles beneath holes)
if(hasTranslucentLight() && lightView) {
@@ -289,10 +310,9 @@ ThingPtr Tile::getTopThing()
{
if(isEmpty())
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())
return thing;
}
return m_things[m_things.size() - 1];
}
@@ -339,9 +359,8 @@ int Tile::getGroundSpeed()
uint8 Tile::getMinimapColorByte()
{
uint8 color = 255; // alpha
if(m_minimapColor != 0) {
if(m_minimapColor != 0)
return m_minimapColor;
}
for(const ThingPtr& thing : m_things) {
if(!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop())
@@ -498,11 +517,9 @@ bool Tile::isWalkable(bool ignoreCreatures)
bool Tile::isPathable()
{
for(const ThingPtr& thing : m_things) {
for(const ThingPtr& thing : m_things)
if(thing->isNotPathable())
return false;
}
return true;
}
@@ -524,19 +541,17 @@ bool Tile::isSingleDimension()
{
if(!m_walkingCreatures.empty())
return false;
for(const ThingPtr& thing : m_things) {
for(const ThingPtr& thing : m_things)
if(thing->getHeight() != 1 || thing->getWidth() != 1)
return false;
}
return true;
}
bool Tile::isLookPossible()
{
for(const ThingPtr& thing : m_things) {
for(const ThingPtr& thing : m_things)
if(thing->blockProjectile())
return false;
}
return true;
}
@@ -595,15 +610,11 @@ bool Tile::limitsFloorsView(bool isFreeView)
// ground and walls limits the view
ThingPtr firstThing = getThing(0);
if(isFreeView){
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;
}
} else if(firstThing && !firstThing->isDontHide() && (firstThing->isGround() || (firstThing->isOnBottom() && firstThing->blockProjectile())))
return true;
return false;
}
@@ -644,7 +655,9 @@ void Tile::checkTranslucentLight()
}
if(translucent)
tile->m_flags = tile->m_flags | TILESTATE_TRANSLUECENT_LIGHT;
tile->m_flags |= TILESTATE_TRANSLUECENT_LIGHT;
else
tile->m_flags = tile->m_flags & ~TILESTATE_TRANSLUECENT_LIGHT;
tile->m_flags &= ~TILESTATE_TRANSLUECENT_LIGHT;
}
/* vim: set ts=4 sw=4 et :*/

View File

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

View File

@@ -58,6 +58,15 @@ const TownPtr& TownManager::getTown(uint32 townId)
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)
{
return std::find_if(m_towns.begin(), m_towns.end(),

View File

@@ -54,6 +54,7 @@ public:
void addTown(const TownPtr& town);
void removeTown(uint32 townId);
const TownPtr& getTown(uint32 townId);
const TownPtr& getTownByName(std::string name);
TownList getTowns() { return m_towns; }
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));
m_font->drawText(count, Rect(m_rect.topLeft(), m_rect.bottomRight() - Point(3, 0)), Fw::AlignBottomRight);
}
// debug, show item id
//m_font->drawText(stdext::to_string(m_item->getId()), m_rect, Fw::AlignBottomRight);
if(m_showId)
m_font->drawText(stdext::to_string(m_item->getServerId()), m_rect, Fw::AlignBottomRight);
}
drawBorder(m_rect);
@@ -98,5 +98,7 @@ void UIItem::onStyleApply(const std::string& styleName, const OTMLNodePtr& style
setItemVisible(node->value<bool>());
else if(node->tag() == "virtual")
setVirtual(node->value<bool>());
else if(node->tag() == "show-id")
m_showId = node->value<bool>();
}
}

View File

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

View File

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

View File

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

87
src/client/uisprite.cpp Normal file
View File

@@ -0,0 +1,87 @@
/*
* 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>());
}
}

54
src/client/uisprite.h Normal file
View File

@@ -0,0 +1,54 @@
/*
* 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.
*/
#ifndef UISPRITE_H
#define UISPRITE_H
#include "declarations.h"
#include <framework/ui/uiwidget.h>
class UISprite : public UIWidget
{
public:
UISprite();
void drawSelf(Fw::DrawPane drawPane);
void setSpriteId(int id);
int getSpriteId() { return m_spriteId; }
void clearSprite() { setSpriteId(0); }
void setSpriteColor(Color color) { m_spriteColor = color; }
bool isSpriteVisible() { return m_spriteVisible; }
void setSpriteVisible(bool visible) { m_spriteVisible = visible; }
protected:
void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
TexturePtr m_sprite;
uint16 m_spriteId;
Color m_spriteColor;
stdext::boolean<true> m_spriteVisible;
};
#endif

View File

@@ -270,7 +270,7 @@ endif()
if(WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthreads")
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 "")
else()
if(APPLE)
@@ -546,6 +546,10 @@ if(FRAMEWORK_SQL)
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DFW_SQL)
endif()
if(EXTRA_LIBS)
set(framework_LIBRARIES ${framework_LIBRARIES} ${EXTRA_LIBS})
endif()
include_directories(${framework_INCLUDE_DIRS})
add_definitions(${framework_DEFINITIONS})

View File

@@ -4,7 +4,13 @@
# EGL_LIBRARY - the EGL library
FIND_PATH(EGL_INCLUDE_DIR NAMES EGL/egl.h)
FIND_LIBRARY(EGL_LIBRARY NAMES EGL.dll EGL)
SET(_EGL_STATIC_LIBS libEGL.a)
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)
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,7 +4,13 @@
# OPENGLES1_LIBRARY - the OpenGL ES 1.0 library
FIND_PATH(OPENGLES1_INCLUDE_DIR NAMES GLES/gl.h)
FIND_LIBRARY(OPENGLES1_LIBRARY NAMES GLESv1_CM.dll GLES_CM.dll GLESv1_CM GLES_CM)
SET(_OPENGLES1_STATIC_LIBS libGLESv1_CM.a libGLES_CM.a)
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)
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,7 +4,13 @@
# OPENGLES2_LIBRARY - the OpenGL ES 2.0 library
FIND_PATH(OPENGLES2_INCLUDE_DIR NAMES GLES2/gl2.h)
FIND_LIBRARY(OPENGLES2_LIBRARY NAMES GLESv2.dll GLESv2)
SET(_OPENGLES2_STATIC_LIBS libGLESv2.a)
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)
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

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

View File

@@ -147,6 +147,11 @@ void Application::poll()
#endif
g_dispatcher.poll();
// poll connection again to flush pending write
#ifdef FW_NET
Connection::poll();
#endif
}
void Application::exit()

View File

@@ -103,7 +103,9 @@ inline void glEnableVertexAttribArray (GLuint index) { }
inline void glDisableVertexAttribArray (GLuint index) { }
#else
#ifndef _MSC_VER
#define GLEW_STATIC
#endif
#include <GL/glew.h>
#endif

View File

@@ -83,7 +83,7 @@ bool Shader::compileSourceFile(const std::string& sourceFile)
std::string sourceCode = g_resources.readFileContents(sourceFile);
return compileSourceCode(sourceCode);
} catch(stdext::exception& e) {
g_logger.error(stdext::format("unable to load shader source form file: %s", sourceFile));
g_logger.error(stdext::format("unable to load shader source form file '%s': %s", sourceFile, e.what()));
}
return false;
}

View File

@@ -53,8 +53,8 @@ void LuaInterface::init()
m_globalEnv = ref();
pop();
// check if demangle_type is working as expected
assert(stdext::demangle_type<LuaObject>() == "LuaObject");
// check if demangle_class is working as expected
assert(stdext::demangle_class<LuaObject>() == "LuaObject");
// register LuaObject, the base of all other objects
registerClass<LuaObject>();

View File

@@ -64,24 +64,24 @@ public:
// register shortcuts using templates
template<class C, class B = LuaObject>
void registerClass() {
registerClass(stdext::demangle_type<C>(), stdext::demangle_type<B>());
registerClass(stdext::demangle_class<C>(), stdext::demangle_class<B>());
}
template<class C>
void registerClassStaticFunction(const std::string& functionName, const LuaCppFunction& function) {
registerClassStaticFunction(stdext::demangle_type<C>(), functionName, function);
registerClassStaticFunction(stdext::demangle_class<C>(), functionName, function);
}
template<class C>
void registerClassMemberFunction(const std::string& functionName, const LuaCppFunction& function) {
registerClassMemberFunction(stdext::demangle_type<C>(), functionName, function);
registerClassMemberFunction(stdext::demangle_class<C>(), functionName, function);
}
template<class C>
void registerClassMemberField(const std::string& field,
const LuaCppFunction& getFunction,
const LuaCppFunction& setFunction) {
registerClassMemberField(stdext::demangle_type<C>(), field, getFunction, setFunction);
registerClassMemberField(stdext::demangle_class<C>(), field, getFunction, setFunction);
}
// methods for binding functions

View File

@@ -117,5 +117,9 @@ int LuaObject::getUseCount()
std::string LuaObject::getClassName()
{
// TODO: this could be cached for more performance
#ifdef _MSC_VER
return stdext::demangle_name(typeid(*this).name()) + 6;
#else
return stdext::demangle_name(typeid(*this).name());
#endif
}

View File

@@ -50,8 +50,9 @@ Connection::~Connection()
void Connection::poll()
{
g_ioService.poll();
// reset must always be called prior to poll
g_ioService.reset();
g_ioService.poll();
}
void Connection::terminate()
@@ -125,7 +126,7 @@ void Connection::write(uint8* buffer, size_t size)
m_outputStream = std::shared_ptr<asio::streambuf>(new asio::streambuf);
m_delayedWriteTimer.cancel();
m_delayedWriteTimer.expires_from_now(boost::posix_time::milliseconds(10));
m_delayedWriteTimer.expires_from_now(boost::posix_time::milliseconds(0));
m_delayedWriteTimer.async_wait(std::bind(&Connection::onCanWrite, asConnection(), std::placeholders::_1));
}

View File

@@ -26,6 +26,7 @@
#include <framework/global.h>
#include <framework/core/application.h>
#include <winsock2.h>
#include <windows.h>
#include <process.h>
#include <imagehlp.h>
@@ -64,17 +65,28 @@ void Stacktrace(LPEXCEPTION_POINTERS e, std::stringstream& ss)
PIMAGEHLP_SYMBOL pSym;
STACKFRAME sf;
HANDLE process, thread;
DWORD dwModBase, Disp;
ULONG_PTR dwModBase, Disp;
BOOL more = FALSE;
DWORD machineType;
int count = 0;
char modname[MAX_PATH];
char symBuffer[sizeof(IMAGEHLP_SYMBOL) + 255];
pSym = (PIMAGEHLP_SYMBOL)GlobalAlloc(GMEM_FIXED, 16384);
pSym = (PIMAGEHLP_SYMBOL)symBuffer;
ZeroMemory(&sf, sizeof(sf));
#ifdef __WIN64__
sf.AddrPC.Offset = e->ContextRecord->Rip;
sf.AddrStack.Offset = e->ContextRecord->Rsp;
sf.AddrFrame.Offset = e->ContextRecord->Rbp;
machineType = IMAGE_FILE_MACHINE_AMD64;
#else
sf.AddrPC.Offset = e->ContextRecord->Eip;
sf.AddrStack.Offset = e->ContextRecord->Esp;
sf.AddrFrame.Offset = e->ContextRecord->Ebp;
machineType = IMAGE_FILE_MACHINE_I386;
#endif
sf.AddrPC.Mode = AddrModeFlat;
sf.AddrStack.Mode = AddrModeFlat;
sf.AddrFrame.Mode = AddrModeFlat;
@@ -83,7 +95,7 @@ void Stacktrace(LPEXCEPTION_POINTERS e, std::stringstream& ss)
thread = GetCurrentThread();
while(1) {
more = StackWalk(IMAGE_FILE_MACHINE_I386, process, thread, &sf, e->ContextRecord, NULL, SymFunctionTableAccess, SymGetModuleBase, NULL);
more = StackWalk(machineType, process, thread, &sf, e->ContextRecord, NULL, SymFunctionTableAccess, SymGetModuleBase, NULL);
if(!more || sf.AddrFrame.Offset == 0)
break;
@@ -93,13 +105,14 @@ void Stacktrace(LPEXCEPTION_POINTERS e, std::stringstream& ss)
else
strcpy(modname, "Unknown");
pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
pSym->MaxNameLength = MAX_PATH;
Disp = 0;
pSym->SizeOfStruct = sizeof(symBuffer);
pSym->MaxNameLength = 254;
if(SymGetSymFromAddr(process, sf.AddrPC.Offset, &Disp, pSym))
ss << stdext::format(" %d: %s(%s+%#0lx) [0x%08lX]\n", count, modname, pSym->Name, Disp, sf.AddrPC.Offset);
ss << stdext::format(" %d: %s(%s+%#0lx) [0x%016lX]\n", count, modname, pSym->Name, Disp, sf.AddrPC.Offset);
else
ss << stdext::format(" %d: %s [0x%08lX]\n", count, modname, sf.AddrPC.Offset);
ss << stdext::format(" %d: %s [0x%016lX]\n", count, modname, sf.AddrPC.Offset);
++count;
}
GlobalFree(pSym);
@@ -119,7 +132,7 @@ LONG CALLBACK ExceptionHandler(LPEXCEPTION_POINTERS e)
ss << stdext::format("build revision: %s (%s)\n", BUILD_REVISION, BUILD_COMMIT);
ss << stdext::format("crash date: %s\n", stdext::date_time_string());
ss << stdext::format("exception: %s (0x%08lx)\n", getExceptionName(e->ExceptionRecord->ExceptionCode), e->ExceptionRecord->ExceptionCode);
ss << stdext::format("exception address: 0x%08lx\n", (long unsigned int)e->ExceptionRecord->ExceptionAddress);
ss << stdext::format("exception address: 0x%08lx\n", (size_t)e->ExceptionRecord->ExceptionAddress);
ss << stdext::format(" backtrace:\n");
Stacktrace(e, ss);
ss << "\n";
@@ -148,10 +161,10 @@ LONG CALLBACK ExceptionHandler(LPEXCEPTION_POINTERS e)
MessageBox(NULL, msg.c_str(), "Application crashed", 0);
// this seems to silently close the application
return EXCEPTION_EXECUTE_HANDLER;
//return EXCEPTION_EXECUTE_HANDLER;
// this triggers the microsoft "application has crashed" error dialog
//return EXCEPTION_CONTINUE_SEARCH;
return EXCEPTION_CONTINUE_SEARCH;
}
void installCrashHandler()

View File

@@ -23,6 +23,7 @@
#ifdef WIN32
#include "platform.h"
#include <winsock2.h>
#include <windows.h>
#include <framework/stdext/stdext.h>
#include <boost/algorithm/string.hpp>
@@ -55,7 +56,7 @@ bool Platform::spawnProcess(std::string process, const std::vector<std::string>&
std::wstring wfile = stdext::utf8_to_utf16(process);
std::wstring wcommandLine = stdext::utf8_to_utf16(commandLine);
if((int)ShellExecuteW(NULL, L"open", wfile.c_str(), wcommandLine.c_str(), NULL, SW_SHOWNORMAL) > 32)
if((size_t)ShellExecuteW(NULL, L"open", wfile.c_str(), wcommandLine.c_str(), NULL, SW_SHOWNORMAL) > 32)
return true;
return false;
}
@@ -172,6 +173,7 @@ double Platform::getTotalSystemMemory()
return status.ullTotalPhys;
}
#ifndef PRODUCT_PROFESSIONAL
#define PRODUCT_PROFESSIONAL 0x00000030
#define VER_SUITE_WH_SERVER 0x00008000
#define VER_PLATFORM_WIN32s 0
@@ -228,6 +230,7 @@ double Platform::getTotalSystemMemory()
#define PRODUCT_PROFESSIONAL 0x00000030
#define PRODUCT_PROFESSIONAL_N 0x00000031
#define PRODUCT_SB_SOLUTION_SERVER 0x00000032
#endif
std::string Platform::getOSName()
{
@@ -246,7 +249,7 @@ std::string Platform::getOSName()
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*) &osvi);
bOsVersionInfoEx = VerifyVersionInfo(&osvi, 0, 0);
if(!bOsVersionInfoEx)
return std::string();

View File

@@ -691,12 +691,12 @@ LRESULT WIN32Window::windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
if(newMousePos.x >= 32767)
newMousePos.x = 0;
else
newMousePos.x = std::min(newMousePos.x, m_size.width());
newMousePos.x = std::min<int32>(newMousePos.x, m_size.width());
if(newMousePos.y >= 32767)
newMousePos.y = 0;
else
newMousePos.y = std::min(newMousePos.y, m_size.height());
newMousePos.y = std::min<int32>(newMousePos.y, m_size.height());
m_inputEvent.mouseMoved = newMousePos - m_inputEvent.mousePos;
m_inputEvent.mousePos = newMousePos;
@@ -746,8 +746,8 @@ LRESULT WIN32Window::windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
internalRestoreGLContext();
Size size = Size(LOWORD(lParam), HIWORD(lParam));
size.setWidth(std::max(std::min(size.width(), 7680), 32));
size.setHeight(std::max(std::min(size.height(), 4320), 32));
size.setWidth(std::max<int32>(std::min<int32>(size.width(), 7680), 32));
size.setHeight(std::max<int32>(std::min<int32>(size.height(), 4320), 32));
if(m_visible && (forceResize || m_size != size)) {
m_size = size;

View File

@@ -25,6 +25,7 @@
#include "platformwindow.h"
#include <winsock2.h>
#include <windows.h>
#ifdef OPENGL_ES
@@ -48,7 +49,7 @@ class WIN32Window : public PlatformWindow
bool isExtensionSupported(const char *ext);
LRESULT windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
friend class WindowProcProxy;
friend struct WindowProcProxy;
Fw::Key retranslateVirtualKey(WPARAM wParam, LPARAM lParam);

View File

@@ -46,7 +46,7 @@ bool OggSoundFile::prepareOgg()
m_channels = vi->channels;
m_rate = vi->rate;
m_bps = 16;
m_size = ov_pcm_total(&m_vorbisFile, -1) * 2;
m_size = ov_pcm_total(&m_vorbisFile, -1) * (m_bps/8) * m_channels;
return true;
}

View File

@@ -121,7 +121,7 @@ template<>
inline bool cast(const std::string& in, float& f) {
double d;
if(cast(in, d)) {
f=d;
f=(float)d;
return true;
}
return false;

View File

@@ -23,18 +23,46 @@
#ifndef STDEXT_COMPILER_H
#define STDEXT_COMPILER_H
#ifdef WIN32
#include <winsock2.h>
#endif
#ifdef __clang__
// clang is supported
#define BUILD_COMPILER "clang " __VERSION__
#elif defined(__GNUC__)
#if !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
#error "Sorry, you need gcc 4.6 or greater to compile."
#endif
#define BUILD_COMPILER "gcc " __VERSION__
#elif defined(_MSC_VER)
#if _MSC_VER < 1800
#error "You need Visual Studio 2013 or greater to compile."
#endif
#pragma warning(disable:4244) // conversion from 'A' to 'B', possible loss of data
#pragma warning(disable:4305) // 'initializing' : truncation from 'A' to 'B'
#pragma warning(disable:4146) // unary minus operator applied to unsigned type, result still unsigned
#pragma warning(disable:4800) // 'A' : forcing value to bool 'true' or 'false' (performance warning)
#define BUILD_COMPILER "msvc12"
#define __PRETTY_FUNCTION__ __FUNCDNAME__
#else
#error "Compiler not supported."
#endif
#if !defined(__GXX_EXPERIMENTAL_CXX0X__)
#error "Sorry, you must enable C++0x to compile."
/// Branch Prediction. See the GCC Manual for more information.
/// NB: These are used when speed is need most; do not use in normal
/// code, they may slow down stuff.
#if defined(__clang__) || defined(__GNUC__)
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#else
#define likely(x) (x)
#define unlikely(x) (x)
#endif
#if !defined(_MSC_VER) && !defined(__GXX_EXPERIMENTAL_CXX0X__)
#error "C++0x is required to compile this application. Try updating your compiler."
#endif
#endif

View File

@@ -22,14 +22,25 @@
#include "demangle.h"
#ifdef _MSC_VER
#include <winsock2.h>
#include <windows.h>
#include <dbghelp.h>
#else
#include <cxxabi.h>
#include <cstring>
#include <cstdlib>
#endif
namespace stdext {
const char* demangle_name(const char* name)
{
#ifdef _MSC_VER
static char buffer[1024];
UnDecorateSymbolName(name, buffer, sizeof(buffer), UNDNAME_COMPLETE);
return buffer;
#else
size_t len;
int status;
static char buffer[1024];
@@ -39,6 +50,7 @@ const char* demangle_name(const char* name)
free(demangled);
}
return buffer;
#endif
}
}

View File

@@ -31,6 +31,15 @@ namespace stdext {
/// Demangle names for GNU g++ compiler
const char* demangle_name(const char* name);
/// Returns the name of a class
template<typename T> std::string demangle_class() {
#ifdef _MSC_VER
return demangle_name(typeid(T).name()) + 6;
#else
return demangle_name(typeid(T).name());
#endif
}
/// Returns the name of a type
template<typename T> std::string demangle_type() { return demangle_name(typeid(T).name()); }

View File

@@ -40,7 +40,7 @@ template<class T, class... Args>
void print_ostream(std::ostringstream& stream, const T& first, const Args&... rest) { stream << "\t" << first; print_ostream(stream, rest...); }
template<class... T>
/// Utility for printing variables just like lua
// Utility for printing variables just like lua
void print(const T&... args) { std::ostringstream buf; print_ostream(buf, args...); std::cout << buf.str() << std::endl; }
template<typename T>
@@ -56,16 +56,35 @@ template<int N> struct expand_snprintf {
return expand_snprintf<N-1>::call(s, maxlen, format, tuple, sprintf_cast(std::get<N-1>(tuple)), args...); }};
template<> struct expand_snprintf<0> {
template<typename Tuple, typename... Args> static int call(char *s, size_t maxlen, const char *format, const Tuple& tuple, const Args&... args) {
return snprintf(s, maxlen, format, args...); }};
#ifdef _MSC_VER
return _snprintf(s, maxlen, format, args...);
#else
return snprintf(s, maxlen, format, args...);
#endif
}
};
/// Improved snprintf that accepts std::string and other types
// Improved snprintf that accepts std::string and other types
template<typename... Args>
int snprintf(char *s, size_t maxlen, const char *format, const Args&... args) {
std::tuple<typename replace_extent<Args>::type...> tuple(args...);
return expand_snprintf<std::tuple_size<decltype(tuple)>::value>::call(s, maxlen, format, tuple);
}
/// Format strings with the sprintf style, accepting std::string and string convertible types for %s
template<typename... Args>
inline int snprintf(char *s, size_t maxlen, const char *format) {
std::strncpy(s, format, maxlen);
s[maxlen-1] = 0;
return strlen(s);
}
template<typename... Args>
inline std::string format() { return std::string(); }
template<typename... Args>
inline std::string format(const std::string& format) { return format; }
// Format strings with the sprintf style, accepting std::string and string convertible types for %s
template<typename... Args>
std::string format(const std::string& format, const Args&... args) {
int n, size = 1024;

View File

@@ -178,6 +178,7 @@ std::string latin1_to_utf8(const std::string& src)
}
#ifdef WIN32
#include <winsock2.h>
#include <windows.h>
std::wstring utf8_to_utf16(const std::string& src)
{

View File

@@ -22,7 +22,11 @@
#include "time.h"
#include <boost/chrono.hpp>
#ifdef _MSC_VER
#include <thread>
#else
#include <unistd.h>
#endif
namespace stdext {
@@ -42,12 +46,20 @@ ticks_t micros() {
void millisleep(size_t ms)
{
#ifdef _MSC_VER
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
#else
usleep(ms * 1000);
#endif
};
void microsleep(size_t us)
{
#ifdef _MSC_VER
std::this_thread::sleep_for(std::chrono::microseconds(us));
#else
usleep(us);
#endif
};
}

View File

@@ -36,7 +36,7 @@ void microsleep(size_t us);
struct timer {
public:
timer() { restart(); }
float elapsed_seconds() { return (stdext::micros() - m_start)/1000000.0; }
float elapsed_seconds() { return (float)((stdext::micros() - m_start)/1000000.0); }
ticks_t elapsed_millis() { return (stdext::micros() - m_start)/1000; }
ticks_t elapsed_micros() { return stdext::micros() - m_start; }
void restart() { m_start = stdext::micros(); }

View File

@@ -172,9 +172,7 @@ enum TiXmlEncoding
TIXML_ENCODING_UTF8,
TIXML_ENCODING_LEGACY
};
constexpr TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
static const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
/** TiXmlBase is a base class for every class in TinyXml.
It does little except to establish that TinyXml classes
can be printed and provide some utility functions.

View File

@@ -43,7 +43,95 @@ revision=`git rev-list --all | wc -l`
commit=`git describe --always`
version=`cat CMakeLists.txt | grep "set(VERSION" | sed 's/.*"\([^"]*\)".*/\1/'`
# build for i686
if $rebuild; then
rm -rf build.win32
rm -rf build.win64
rm -rf build.win32dx9
rm -rf build.win64dx9
rm -rf build.linux32
rm -rf build.linux64
fi
WIN32_EXTRA_LIBS="-Wl,-Bstatic -lgcc -lstdc++ -lpthread -Wl,-Bdynamic"
# compile for win64
mkdir -p build.win64
cd build.win64
if $rebuild; then
x86_64-w64-mingw32-cmake \
-DCMAKE_BUILD_TYPE=Release \
-DBOT_PROTECTION=OFF \
-DBUILD_REVISION=$revision \
-DBUILD_COMMIT=$commit \
-DEXTRA_LIBS="$WIN32_EXTRA_LIBS" \
.. || exit
fi
make -j$makejobs || exit
cd ..
# compile for win32
mkdir -p build.win32
cd build.win32
if $rebuild; then
i686-w64-mingw32-cmake \
-DCMAKE_BUILD_TYPE=Release \
-DBOT_PROTECTION=OFF \
-DBUILD_REVISION=$revision \
-DBUILD_COMMIT=$commit \
-DEXTRA_LIBS="$WIN32_EXTRA_LIBS" \
.. || exit
fi
make -j$makejobs || exit
cd ..
# compile for win64dx9
mkdir -p build.win64dx9
cd build.win64dx9
if $rebuild; then
x86_64-w64-mingw32-cmake \
-DCMAKE_BUILD_TYPE=Release \
-DBOT_PROTECTION=OFF \
-DOPENGLES=2.0 \
-DBUILD_REVISION=$revision \
-DBUILD_COMMIT=$commit \
-DEXTRA_LIBS="$WIN32_EXTRA_LIBS" \
.. || exit
fi
make -j$makejobs || exit
cd ..
# compile for win32dx9
mkdir -p build.win32dx9
cd build.win32dx9
if $rebuild; then
i686-w64-mingw32-cmake \
-DCMAKE_BUILD_TYPE=Release \
-DBOT_PROTECTION=OFF \
-DOPENGLES=2.0 \
-DBUILD_REVISION=$revision \
-DBUILD_COMMIT=$commit \
-DEXTRA_LIBS="$WIN32_EXTRA_LIBS" \
.. || exit
fi
make -j$makejobs || exit
cd ..
# compile for linux64
mkdir -p build.linux64
cd build.linux64
if $rebuild; then
cmake -DCMAKE_BUILD_TYPE=Release \
-DBOT_PROTECTION=OFF \
-DBUILD_REVISION=$revision \
-DBUILD_COMMIT=$commit \
.. || exit
fi
make -j$makejobs || exit
cd ..
# compile for linux32
export CFLAGS="-march=i686 -m32"
export CXXFLAGS="-march=i686 -m32"
export LDFLAGS="-march=i686 -m32"
@@ -53,42 +141,6 @@ if [ -d /usr/lib32 ]; then
LIBPATH=/usr/lib32
fi
if $rebuild; then
rm -rf build.win32
rm -rf build.win32dx9
rm -rf build.linux32
fi
# compile for win32
mkdir -p build.win32
cd build.win32
if $rebuild; then
cmake -DCMAKE_TOOLCHAIN_FILE=$workdir/otclient/src/framework/cmake/${mingwplatform}_toolchain.cmake \
-DCMAKE_BUILD_TYPE=Release \
-DBOT_PROTECTION=OFF \
-DBUILD_REVISION=$revision \
-DBUILD_COMMIT=$commit \
.. || exit
fi
make -j$makejobs || exit
cd ..
# compile for win32
mkdir -p build.win32dx9
cd build.win32dx9
if $rebuild; then
cmake -DCMAKE_TOOLCHAIN_FILE=$workdir/otclient/src/framework/cmake/${mingwplatform}_toolchain.cmake \
-DCMAKE_BUILD_TYPE=Release \
-DBOT_PROTECTION=OFF \
-DOPENGLES=2.0 \
-DBUILD_REVISION=$revision \
-DBUILD_COMMIT=$commit \
.. || exit
fi
make -j$makejobs || exit
cd ..
# compile for linux32
mkdir -p build.linux32
cd build.linux32
if $rebuild; then
@@ -117,8 +169,8 @@ mkdir mods
cp $workdir/otclient/mods/README.txt mods/
cp -R $workdir/otclient/modules .
cp -R $workdir/otclient/data .
cp $workdir/otclient/build.linux32/otclient .
cp $workdir/otclient/build.linux32/otclient.map .
cp $workdir/otclient/build.linux32/otclient otclient-32
cp $workdir/otclient/build.linux64/otclient otclient-64
cp $workdir/otclient/init.lua .
cp $workdir/otclient/otclientrc.lua .
cp $workdir/otclient/BUGS .
@@ -167,10 +219,11 @@ cp $mingwbin/libEGL.dll .
cp $mingwbin/libGLESv2.dll .
cp $mingwbin/d3dcompiler_43.dll .
cp $mingwbin/d3dx9_43.dll .
cp $workdir/otclient/build.win32/otclient.exe .
cp $workdir/otclient/build.win32/otclient.map .
cp $workdir/otclient/build.win32dx9/otclient.exe otclient_dx9.exe
cp $workdir/otclient/build.win32dx9/otclient.map otclient_dx9.map
cp $mingwbin/wrap_oal.dll .
cp $workdir/otclient/build.win32/otclient.exe otclient-32.exe
cp $workdir/otclient/build.win32dx9/otclient.exe otclient_dx9-32.exe
cp $workdir/otclient/build.win64/otclient.exe otclient-64.exe
cp $workdir/otclient/build.winw64dx9/otclient.exe otclient_dx9-64.exe
cp $workdir/otclient/init.lua .
cp $workdir/otclient/otclientrc.lua .
cp $workdir/otclient/AUTHORS AUTHORS.txt

22
vc12/otclient.sln Normal file
View File

@@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2013 for Windows Desktop
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "otclient", "otclient.vcxproj", "{17A8F78F-1FFB-4128-A3B3-59CC6C19D89A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{17A8F78F-1FFB-4128-A3B3-59CC6C19D89A}.Debug|Win32.ActiveCfg = Debug|Win32
{17A8F78F-1FFB-4128-A3B3-59CC6C19D89A}.Debug|Win32.Build.0 = Debug|Win32
{17A8F78F-1FFB-4128-A3B3-59CC6C19D89A}.Release|Win32.ActiveCfg = Release|Win32
{17A8F78F-1FFB-4128-A3B3-59CC6C19D89A}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

409
vc12/otclient.vcxproj Normal file
View File

@@ -0,0 +1,409 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{17A8F78F-1FFB-4128-A3B3-59CC6C19D89A}</ProjectGuid>
<RootNamespace>otclient</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>E:\DevFolder\C++ Libraries\glew-1.10.0\include;E:\DevFolder\C++ Libraries\boost_1_54_0\include;C:\Users\crille\Documents\GitHub\dalkon\otclient\src;$(IncludePath)</IncludePath>
<LibraryPath>E:\DevFolder\C++ Libraries\glew-1.10.0\lib;E:\DevFolder\C++ Libraries\boost_1_54_0\lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>D:\otclient-msvc13-libs\libogg-1.3.1\include;D:\otclient-msvc13-libs\libvorbis-1.3.3\include;D:\otclient-msvc13-libs\physfs-2.0.3\include;D:\otclient-msvc13-libs\OpenSSL-1.0.1e\include;D:\otclient-msvc13-libs\zlib-1.2.5\include;D:\otclient-msvc13-libs\OpenAL\include\AL;D:\otclient-msvc13-libs\glew-1.10.0\include;D:\otclient-msvc13-libs\LuaJIT-2.0.2\include;D:\otclient-msvc13-libs\boost_1_55_0\include;D:\otclient\src;$(IncludePath)</IncludePath>
<LibraryPath>D:\otclient-msvc13-libs\libogg-1.3.1\lib;D:\otclient-msvc13-libs\libvorbis-1.3.3\lib;D:\otclient-msvc13-libs\physfs-2.0.3\lib;D:\otclient-msvc13-libs\OpenSSL-1.0.1e\lib\VC;D:\otclient-msvc13-libs\zlib-1.2.5\lib;D:\otclient-msvc13-libs\OpenAL\lib;D:\otclient-msvc13-libs\LuaJIT-2.0.2\lib;D:\otclient-msvc13-libs\glew-1.10.0\lib;D:\otclient-msvc13-libs\boost_1_55_0\lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_WIN32_WINNT=0x0501;BOT_PROTECTION;CLIENT;CRASH_HANDLER;FW_GRAPHICS;FW_NET;FW_SOUND;FW_XML;"BUILD_TYPE=\"RelWithDebInfo\"";"BUILD_COMMIT=\"devel\"";"BUILD_REVISION=\"0\"";"VERSION=\"0.6.3\"";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ObjectFileName>$(IntDir)/%(RelativeDir)/</ObjectFileName>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;BOT_PROTECTION;CLIENT;CRASH_HANDLER;FW_GRAPHICS;FW_NET;FW_SOUND;FW_XML;BUILD_TYPE="RelWithDebInfo";BUILD_COMMIT="devel";BUILD_REVISION="0";VERSION="0.6.3";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>false</MultiProcessorCompilation>
<ObjectFileName>$(IntDir)/%(RelativeDir)/</ObjectFileName>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>glew32.lib;zlib1.lib;libeay32MD.lib;physfs.lib;openal32.lib;luajit.lib;libogg_static.lib;libvorbisfile_static.lib;libvorbis_static.lib;opengl32.lib;dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>NotSet</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\client\animatedtext.cpp" />
<ClCompile Include="..\src\client\client.cpp" />
<ClCompile Include="..\src\client\container.cpp" />
<ClCompile Include="..\src\client\creature.cpp" />
<ClCompile Include="..\src\client\creatures.cpp" />
<ClCompile Include="..\src\client\effect.cpp" />
<ClCompile Include="..\src\client\game.cpp" />
<ClCompile Include="..\src\client\houses.cpp" />
<ClCompile Include="..\src\client\item.cpp" />
<ClCompile Include="..\src\client\itemtype.cpp" />
<ClCompile Include="..\src\client\lightview.cpp" />
<ClCompile Include="..\src\client\localplayer.cpp" />
<ClCompile Include="..\src\client\luafunctions.cpp" />
<ClCompile Include="..\src\client\luavaluecasts.cpp" />
<ClCompile Include="..\src\client\map.cpp" />
<ClCompile Include="..\src\client\mapio.cpp" />
<ClCompile Include="..\src\client\mapview.cpp" />
<ClCompile Include="..\src\client\minimap.cpp" />
<ClCompile Include="..\src\client\missile.cpp" />
<ClCompile Include="..\src\client\outfit.cpp" />
<ClCompile Include="..\src\client\player.cpp" />
<ClCompile Include="..\src\client\protocolcodes.cpp" />
<ClCompile Include="..\src\client\protocolgame.cpp" />
<ClCompile Include="..\src\client\protocolgameparse.cpp" />
<ClCompile Include="..\src\client\protocolgamesend.cpp" />
<ClCompile Include="..\src\client\shadermanager.cpp" />
<ClCompile Include="..\src\client\spritemanager.cpp" />
<ClCompile Include="..\src\client\statictext.cpp" />
<ClCompile Include="..\src\client\thing.cpp" />
<ClCompile Include="..\src\client\thingtype.cpp" />
<ClCompile Include="..\src\client\thingtypemanager.cpp" />
<ClCompile Include="..\src\client\tile.cpp" />
<ClCompile Include="..\src\client\towns.cpp" />
<ClCompile Include="..\src\client\uicreature.cpp" />
<ClCompile Include="..\src\client\uiitem.cpp" />
<ClCompile Include="..\src\client\uimap.cpp" />
<ClCompile Include="..\src\client\uimapanchorlayout.cpp" />
<ClCompile Include="..\src\client\uiminimap.cpp" />
<ClCompile Include="..\src\client\uiprogressrect.cpp" />
<ClCompile Include="..\src\client\uisprite.cpp">
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</ObjectFileName>
</ClCompile>
<ClCompile Include="..\src\framework\core\adaptativeframecounter.cpp" />
<ClCompile Include="..\src\framework\core\application.cpp" />
<ClCompile Include="..\src\framework\core\asyncdispatcher.cpp" />
<ClCompile Include="..\src\framework\core\binarytree.cpp" />
<ClCompile Include="..\src\framework\core\clock.cpp" />
<ClCompile Include="..\src\framework\core\configmanager.cpp" />
<ClCompile Include="..\src\framework\core\event.cpp">
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">FW_GRAPHICS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\src\framework\core\eventdispatcher.cpp" />
<ClCompile Include="..\src\framework\core\filestream.cpp" />
<ClCompile Include="..\src\framework\core\graphicalapplication.cpp" />
<ClCompile Include="..\src\framework\core\logger.cpp" />
<ClCompile Include="..\src\framework\core\module.cpp" />
<ClCompile Include="..\src\framework\core\modulemanager.cpp" />
<ClCompile Include="..\src\framework\core\resourcemanager.cpp" />
<ClCompile Include="..\src\framework\core\scheduledevent.cpp" />
<ClCompile Include="..\src\framework\core\timer.cpp" />
<ClCompile Include="..\src\framework\graphics\animatedtexture.cpp" />
<ClCompile Include="..\src\framework\graphics\apngloader.cpp" />
<ClCompile Include="..\src\framework\graphics\bitmapfont.cpp" />
<ClCompile Include="..\src\framework\graphics\cachedtext.cpp" />
<ClCompile Include="..\src\framework\graphics\coordsbuffer.cpp" />
<ClCompile Include="..\src\framework\graphics\fontmanager.cpp" />
<ClCompile Include="..\src\framework\graphics\framebuffer.cpp" />
<ClCompile Include="..\src\framework\graphics\framebuffermanager.cpp" />
<ClCompile Include="..\src\framework\graphics\graphics.cpp" />
<ClCompile Include="..\src\framework\graphics\hardwarebuffer.cpp" />
<ClCompile Include="..\src\framework\graphics\image.cpp" />
<ClCompile Include="..\src\framework\graphics\ogl\painterogl.cpp" />
<ClCompile Include="..\src\framework\graphics\ogl\painterogl1.cpp" />
<ClCompile Include="..\src\framework\graphics\ogl\painterogl2.cpp" />
<ClCompile Include="..\src\framework\graphics\painter.cpp" />
<ClCompile Include="..\src\framework\graphics\paintershaderprogram.cpp" />
<ClCompile Include="..\src\framework\graphics\particle.cpp" />
<ClCompile Include="..\src\framework\graphics\particleaffector.cpp" />
<ClCompile Include="..\src\framework\graphics\particleeffect.cpp" />
<ClCompile Include="..\src\framework\graphics\particleemitter.cpp" />
<ClCompile Include="..\src\framework\graphics\particlemanager.cpp" />
<ClCompile Include="..\src\framework\graphics\particlesystem.cpp" />
<ClCompile Include="..\src\framework\graphics\particletype.cpp" />
<ClCompile Include="..\src\framework\graphics\shader.cpp" />
<ClCompile Include="..\src\framework\graphics\shaderprogram.cpp" />
<ClCompile Include="..\src\framework\graphics\texture.cpp" />
<ClCompile Include="..\src\framework\graphics\texturemanager.cpp" />
<ClCompile Include="..\src\framework\input\mouse.cpp" />
<ClCompile Include="..\src\framework\luaengine\lbitlib.cpp" />
<ClCompile Include="..\src\framework\luaengine\luaexception.cpp" />
<ClCompile Include="..\src\framework\luaengine\luainterface.cpp" />
<ClCompile Include="..\src\framework\luaengine\luaobject.cpp" />
<ClCompile Include="..\src\framework\luaengine\luavaluecasts.cpp">
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(InputDir)\$(IntDir)\</ObjectFileName>
</ClCompile>
<ClCompile Include="..\src\framework\luafunctions.cpp" />
<ClCompile Include="..\src\framework\net\connection.cpp" />
<ClCompile Include="..\src\framework\net\inputmessage.cpp" />
<ClCompile Include="..\src\framework\net\outputmessage.cpp" />
<ClCompile Include="..\src\framework\net\protocol.cpp" />
<ClCompile Include="..\src\framework\net\protocolhttp.cpp" />
<ClCompile Include="..\src\framework\net\server.cpp" />
<ClCompile Include="..\src\framework\otml\otmldocument.cpp" />
<ClCompile Include="..\src\framework\otml\otmlemitter.cpp" />
<ClCompile Include="..\src\framework\otml\otmlexception.cpp" />
<ClCompile Include="..\src\framework\otml\otmlnode.cpp" />
<ClCompile Include="..\src\framework\otml\otmlparser.cpp" />
<ClCompile Include="..\src\framework\platform\platform.cpp" />
<ClCompile Include="..\src\framework\platform\platformwindow.cpp" />
<ClCompile Include="..\src\framework\platform\win32crashhandler.cpp" />
<ClCompile Include="..\src\framework\platform\win32platform.cpp" />
<ClCompile Include="..\src\framework\platform\win32window.cpp" />
<ClCompile Include="..\src\framework\sound\combinedsoundsource.cpp" />
<ClCompile Include="..\src\framework\sound\oggsoundfile.cpp" />
<ClCompile Include="..\src\framework\sound\soundbuffer.cpp" />
<ClCompile Include="..\src\framework\sound\soundchannel.cpp" />
<ClCompile Include="..\src\framework\sound\soundfile.cpp" />
<ClCompile Include="..\src\framework\sound\soundmanager.cpp" />
<ClCompile Include="..\src\framework\sound\soundsource.cpp" />
<ClCompile Include="..\src\framework\sound\streamsoundsource.cpp" />
<ClCompile Include="..\src\framework\stdext\demangle.cpp" />
<ClCompile Include="..\src\framework\stdext\math.cpp" />
<ClCompile Include="..\src\framework\stdext\net.cpp" />
<ClCompile Include="..\src\framework\stdext\string.cpp" />
<ClCompile Include="..\src\framework\stdext\time.cpp" />
<ClCompile Include="..\src\framework\ui\uianchorlayout.cpp" />
<ClCompile Include="..\src\framework\ui\uiboxlayout.cpp" />
<ClCompile Include="..\src\framework\ui\uigridlayout.cpp" />
<ClCompile Include="..\src\framework\ui\uihorizontallayout.cpp" />
<ClCompile Include="..\src\framework\ui\uilayout.cpp" />
<ClCompile Include="..\src\framework\ui\uimanager.cpp" />
<ClCompile Include="..\src\framework\ui\uiparticles.cpp" />
<ClCompile Include="..\src\framework\ui\uitextedit.cpp" />
<ClCompile Include="..\src\framework\ui\uitranslator.cpp" />
<ClCompile Include="..\src\framework\ui\uiverticallayout.cpp" />
<ClCompile Include="..\src\framework\ui\uiwidget.cpp" />
<ClCompile Include="..\src\framework\ui\uiwidgetbasestyle.cpp" />
<ClCompile Include="..\src\framework\ui\uiwidgetimage.cpp" />
<ClCompile Include="..\src\framework\ui\uiwidgettext.cpp" />
<ClCompile Include="..\src\framework\util\color.cpp" />
<ClCompile Include="..\src\framework\util\crypt.cpp" />
<ClCompile Include="..\src\framework\xml\tinystr.cpp" />
<ClCompile Include="..\src\framework\xml\tinyxml.cpp" />
<ClCompile Include="..\src\framework\xml\tinyxmlerror.cpp" />
<ClCompile Include="..\src\framework\xml\tinyxmlparser.cpp" />
<ClCompile Include="..\src\main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\client\animatedtext.h" />
<ClInclude Include="..\src\client\client.h" />
<ClInclude Include="..\src\client\const.h" />
<ClInclude Include="..\src\client\container.h" />
<ClInclude Include="..\src\client\creature.h" />
<ClInclude Include="..\src\client\creatures.h" />
<ClInclude Include="..\src\client\declarations.h" />
<ClInclude Include="..\src\client\effect.h" />
<ClInclude Include="..\src\client\game.h" />
<ClInclude Include="..\src\client\global.h" />
<ClInclude Include="..\src\client\houses.h" />
<ClInclude Include="..\src\client\item.h" />
<ClInclude Include="..\src\client\itemtype.h" />
<ClInclude Include="..\src\client\lightview.h" />
<ClInclude Include="..\src\client\localplayer.h" />
<ClInclude Include="..\src\client\luavaluecasts.h" />
<ClInclude Include="..\src\client\map.h" />
<ClInclude Include="..\src\client\mapview.h" />
<ClInclude Include="..\src\client\minimap.h" />
<ClInclude Include="..\src\client\missile.h" />
<ClInclude Include="..\src\client\outfit.h" />
<ClInclude Include="..\src\client\player.h" />
<ClInclude Include="..\src\client\position.h" />
<ClInclude Include="..\src\client\protocolcodes.h" />
<ClInclude Include="..\src\client\protocolgame.h" />
<ClInclude Include="..\src\client\shadermanager.h" />
<ClInclude Include="..\src\client\spritemanager.h" />
<ClInclude Include="..\src\client\statictext.h" />
<ClInclude Include="..\src\client\thing.h" />
<ClInclude Include="..\src\client\thingstype.h" />
<ClInclude Include="..\src\client\thingtype.h" />
<ClInclude Include="..\src\client\thingtypemanager.h" />
<ClInclude Include="..\src\client\tile.h" />
<ClInclude Include="..\src\client\towns.h" />
<ClInclude Include="..\src\client\uicreature.h" />
<ClInclude Include="..\src\client\uiitem.h" />
<ClInclude Include="..\src\client\uimap.h" />
<ClInclude Include="..\src\client\uimapanchorlayout.h" />
<ClInclude Include="..\src\client\uiminimap.h" />
<ClInclude Include="..\src\client\uiprogressrect.h" />
<ClInclude Include="..\src\client\uisprite.h" />
<ClInclude Include="..\src\framework\const.h" />
<ClInclude Include="..\src\framework\core\adaptativeframecounter.h" />
<ClInclude Include="..\src\framework\core\application.h" />
<ClInclude Include="..\src\framework\core\asyncdispatcher.h" />
<ClInclude Include="..\src\framework\core\binarytree.h" />
<ClInclude Include="..\src\framework\core\clock.h" />
<ClInclude Include="..\src\framework\core\configmanager.h" />
<ClInclude Include="..\src\framework\core\declarations.h" />
<ClInclude Include="..\src\framework\core\event.h" />
<ClInclude Include="..\src\framework\core\eventdispatcher.h" />
<ClInclude Include="..\src\framework\core\filestream.h" />
<ClInclude Include="..\src\framework\core\graphicalapplication.h" />
<ClInclude Include="..\src\framework\core\inputevent.h" />
<ClInclude Include="..\src\framework\core\logger.h" />
<ClInclude Include="..\src\framework\core\module.h" />
<ClInclude Include="..\src\framework\core\modulemanager.h" />
<ClInclude Include="..\src\framework\core\resourcemanager.h" />
<ClInclude Include="..\src\framework\core\scheduledevent.h" />
<ClInclude Include="..\src\framework\core\timer.h" />
<ClInclude Include="..\src\framework\global.h" />
<ClInclude Include="..\src\framework\graphics\animatedtexture.h" />
<ClInclude Include="..\src\framework\graphics\apngloader.h" />
<ClInclude Include="..\src\framework\graphics\bitmapfont.h" />
<ClInclude Include="..\src\framework\graphics\cachedtext.h" />
<ClInclude Include="..\src\framework\graphics\coordsbuffer.h" />
<ClInclude Include="..\src\framework\graphics\declarations.h" />
<ClInclude Include="..\src\framework\graphics\fontmanager.h" />
<ClInclude Include="..\src\framework\graphics\framebuffer.h" />
<ClInclude Include="..\src\framework\graphics\framebuffermanager.h" />
<ClInclude Include="..\src\framework\graphics\glutil.h" />
<ClInclude Include="..\src\framework\graphics\graphics.h" />
<ClInclude Include="..\src\framework\graphics\hardwarebuffer.h" />
<ClInclude Include="..\src\framework\graphics\image.h" />
<ClInclude Include="..\src\framework\graphics\ogl\painterogl.h" />
<ClInclude Include="..\src\framework\graphics\ogl\painterogl1.h" />
<ClInclude Include="..\src\framework\graphics\ogl\painterogl2.h" />
<ClInclude Include="..\src\framework\graphics\ogl\painterogl2_shadersources.h" />
<ClInclude Include="..\src\framework\graphics\painter.h" />
<ClInclude Include="..\src\framework\graphics\paintershaderprogram.h" />
<ClInclude Include="..\src\framework\graphics\particle.h" />
<ClInclude Include="..\src\framework\graphics\particleaffector.h" />
<ClInclude Include="..\src\framework\graphics\particleeffect.h" />
<ClInclude Include="..\src\framework\graphics\particleemitter.h" />
<ClInclude Include="..\src\framework\graphics\particlemanager.h" />
<ClInclude Include="..\src\framework\graphics\particlesystem.h" />
<ClInclude Include="..\src\framework\graphics\particletype.h" />
<ClInclude Include="..\src\framework\graphics\shader.h" />
<ClInclude Include="..\src\framework\graphics\shaderprogram.h" />
<ClInclude Include="..\src\framework\graphics\texture.h" />
<ClInclude Include="..\src\framework\graphics\texturemanager.h" />
<ClInclude Include="..\src\framework\graphics\vertexarray.h" />
<ClInclude Include="..\src\framework\input\mouse.h" />
<ClInclude Include="..\src\framework\luaengine\declarations.h" />
<ClInclude Include="..\src\framework\luaengine\lbitlib.h" />
<ClInclude Include="..\src\framework\luaengine\luabinder.h" />
<ClInclude Include="..\src\framework\luaengine\luaexception.h" />
<ClInclude Include="..\src\framework\luaengine\luainterface.h" />
<ClInclude Include="..\src\framework\luaengine\luaobject.h" />
<ClInclude Include="..\src\framework\luaengine\luavaluecasts.h" />
<ClInclude Include="..\src\framework\net\connection.h" />
<ClInclude Include="..\src\framework\net\declarations.h" />
<ClInclude Include="..\src\framework\net\inputmessage.h" />
<ClInclude Include="..\src\framework\net\outputmessage.h" />
<ClInclude Include="..\src\framework\net\protocol.h" />
<ClInclude Include="..\src\framework\net\protocolhttp.h" />
<ClInclude Include="..\src\framework\net\server.h" />
<ClInclude Include="..\src\framework\otml\declarations.h" />
<ClInclude Include="..\src\framework\otml\otml.h" />
<ClInclude Include="..\src\framework\otml\otmldocument.h" />
<ClInclude Include="..\src\framework\otml\otmlemitter.h" />
<ClInclude Include="..\src\framework\otml\otmlexception.h" />
<ClInclude Include="..\src\framework\otml\otmlnode.h" />
<ClInclude Include="..\src\framework\otml\otmlparser.h" />
<ClInclude Include="..\src\framework\pch.h" />
<ClInclude Include="..\src\framework\platform\crashhandler.h" />
<ClInclude Include="..\src\framework\platform\platform.h" />
<ClInclude Include="..\src\framework\platform\platformwindow.h" />
<ClInclude Include="..\src\framework\platform\win32window.h" />
<ClInclude Include="..\src\framework\sound\combinedsoundsource.h" />
<ClInclude Include="..\src\framework\sound\declarations.h" />
<ClInclude Include="..\src\framework\sound\oggsoundfile.h" />
<ClInclude Include="..\src\framework\sound\soundbuffer.h" />
<ClInclude Include="..\src\framework\sound\soundchannel.h" />
<ClInclude Include="..\src\framework\sound\soundfile.h" />
<ClInclude Include="..\src\framework\sound\soundmanager.h" />
<ClInclude Include="..\src\framework\sound\soundsource.h" />
<ClInclude Include="..\src\framework\sound\streamsoundsource.h" />
<ClInclude Include="..\src\framework\stdext\any.h" />
<ClInclude Include="..\src\framework\stdext\boolean.h" />
<ClInclude Include="..\src\framework\stdext\cast.h" />
<ClInclude Include="..\src\framework\stdext\compiler.h" />
<ClInclude Include="..\src\framework\stdext\demangle.h" />
<ClInclude Include="..\src\framework\stdext\dumper.h" />
<ClInclude Include="..\src\framework\stdext\dynamic_storage.h" />
<ClInclude Include="..\src\framework\stdext\exception.h" />
<ClInclude Include="..\src\framework\stdext\format.h" />
<ClInclude Include="..\src\framework\stdext\math.h" />
<ClInclude Include="..\src\framework\stdext\net.h" />
<ClInclude Include="..\src\framework\stdext\packed_any.h" />
<ClInclude Include="..\src\framework\stdext\packed_storage.h" />
<ClInclude Include="..\src\framework\stdext\packed_vector.h" />
<ClInclude Include="..\src\framework\stdext\shared_object.h" />
<ClInclude Include="..\src\framework\stdext\shared_ptr.h" />
<ClInclude Include="..\src\framework\stdext\stdext.h" />
<ClInclude Include="..\src\framework\stdext\string.h" />
<ClInclude Include="..\src\framework\stdext\thread.h" />
<ClInclude Include="..\src\framework\stdext\time.h" />
<ClInclude Include="..\src\framework\stdext\traits.h" />
<ClInclude Include="..\src\framework\stdext\types.h" />
<ClInclude Include="..\src\framework\ui\declarations.h" />
<ClInclude Include="..\src\framework\ui\ui.h" />
<ClInclude Include="..\src\framework\ui\uianchorlayout.h" />
<ClInclude Include="..\src\framework\ui\uiboxlayout.h" />
<ClInclude Include="..\src\framework\ui\uigridlayout.h" />
<ClInclude Include="..\src\framework\ui\uihorizontallayout.h" />
<ClInclude Include="..\src\framework\ui\uilayout.h" />
<ClInclude Include="..\src\framework\ui\uimanager.h" />
<ClInclude Include="..\src\framework\ui\uiparticles.h" />
<ClInclude Include="..\src\framework\ui\uitextedit.h" />
<ClInclude Include="..\src\framework\ui\uitranslator.h" />
<ClInclude Include="..\src\framework\ui\uiverticallayout.h" />
<ClInclude Include="..\src\framework\ui\uiwidget.h" />
<ClInclude Include="..\src\framework\util\color.h" />
<ClInclude Include="..\src\framework\util\crypt.h" />
<ClInclude Include="..\src\framework\util\databuffer.h" />
<ClInclude Include="..\src\framework\util\matrix.h" />
<ClInclude Include="..\src\framework\util\point.h" />
<ClInclude Include="..\src\framework\util\rect.h" />
<ClInclude Include="..\src\framework\util\size.h" />
<ClInclude Include="..\src\framework\xml\tinystr.h" />
<ClInclude Include="..\src\framework\xml\tinyxml.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\src\otcicon.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

File diff suppressed because it is too large Load Diff