Merge branch 'master' of github.com:edubart/otclient
This commit is contained in:
		
						commit
						4e03b15b27
					
				|  | @ -63,6 +63,8 @@ SET(SOURCES | |||
|     src/item.cpp | ||||
|     src/tile.cpp | ||||
|     src/thing.cpp | ||||
|     src/creature.cpp | ||||
|     src/effect.cpp | ||||
| 
 | ||||
|     # framework third party | ||||
|     src/framework/thirdparty/apngloader.cpp | ||||
|  |  | |||
|  | @ -0,0 +1,64 @@ | |||
| #include "creature.h" | ||||
| #include "tibiadat.h" | ||||
| #include "graphics/graphics.h" | ||||
| #include <graphics/framebuffer.h> | ||||
| #include "game.h" | ||||
| 
 | ||||
| #include <GL/gl.h> | ||||
| #include <GL/glu.h> | ||||
| #include <GL/glext.h> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // OW BART TEM COMO USAR 2 FRAMEBUFFER?
 | ||||
| // SERIA O IDEAL PARA DESENHAR A COR DOS BONEQUIN.
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| Creature::Creature() | ||||
| { | ||||
|     m_type = Thing::TYPE_CREATURE; | ||||
| } | ||||
| 
 | ||||
| ThingAttributes *Creature::getAttributes() | ||||
| { | ||||
|     return g_tibiaDat.getCreatureAttributes(m_outfit.type); | ||||
| } | ||||
| 
 | ||||
| void Creature::draw(int x, int y) | ||||
| { | ||||
|     //ThingAttributes *creatureAttributes = getAttributes();
 | ||||
|     int anim = 0; | ||||
| 
 | ||||
|     // draw outfit
 | ||||
|     internalDraw(x, y, 0, m_direction, 0, 0, anim); | ||||
| 
 | ||||
|     // draw addons
 | ||||
|     //for(int a = 0; a < m_outfit.addons; ++a) {
 | ||||
|         //internalDraw(x, y, 0, m_direction, m_outfit.addons & (1 << a), 0, anim);
 | ||||
|     //}
 | ||||
|     //glPushAttrib(GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT);
 | ||||
| 
 | ||||
|     //glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
 | ||||
| 
 | ||||
|     //Color colors[4] = {Color::yellow, Color::red, Color::green, Color::blue};
 | ||||
| 
 | ||||
|     //for(int i = 0; i < 4; ++i) {
 | ||||
| 
 | ||||
| 
 | ||||
|         /*g_graphics.bindColor(colors[i]);
 | ||||
|         internalDraw(creatureAttributes->width*32 - 32, creatureAttributes->height*32 - 32, 1, m_direction, 0, 0, 0); | ||||
|         framebuffer.unbind(); | ||||
| 
 | ||||
| 
 | ||||
|         g_graphics.bindColor(Color::green);*/ | ||||
|         //framebuffer.draw(x, y, creatureAttributes->width*32, creatureAttributes->height*32);
 | ||||
|     //}
 | ||||
|     //glPopAttrib();
 | ||||
| } | ||||
|  | @ -0,0 +1,51 @@ | |||
| #ifndef CREATURE_H | ||||
| #define CREATURE_H | ||||
| 
 | ||||
| #include <global.h> | ||||
| #include "thing.h" | ||||
| 
 | ||||
| struct Outfit | ||||
| { | ||||
|     uint16 type; | ||||
|     uint8 head; | ||||
|     uint8 body; | ||||
|     uint8 legs; | ||||
|     uint8 feet; | ||||
|     uint8 addons; | ||||
| }; | ||||
| 
 | ||||
| class Creature; | ||||
| typedef std::shared_ptr<Creature> CreaturePtr; | ||||
| 
 | ||||
| class Creature : public Thing | ||||
| { | ||||
| public: | ||||
|     Creature(); | ||||
| 
 | ||||
|     virtual ThingAttributes *getAttributes(); | ||||
|     void draw(int x, int y); | ||||
| 
 | ||||
|     void setName(const std::string& name) { m_name = name; } | ||||
|     std::string getName() { return m_name; } | ||||
| 
 | ||||
|     void setHealthPercent(uint8 healthPercent) { m_healthPercent = healthPercent; } | ||||
|     uint8 getHealthPercent() { return m_healthPercent; } | ||||
| 
 | ||||
|     void setDirection(Direction direction) { m_direction = direction; } | ||||
|     Direction getDirection() { return m_direction; } | ||||
| 
 | ||||
|     void setOutfit(const Outfit& outfit) { m_outfit = outfit; } | ||||
|     Outfit getOutfit() { return m_outfit; } | ||||
| 
 | ||||
|     virtual Creature *getCreature() { return this; } | ||||
|     virtual const Creature *getCreature() const { return this; } | ||||
| 
 | ||||
| private: | ||||
|     std::string m_name; | ||||
|     uint8 m_healthPercent; | ||||
|     Direction m_direction; | ||||
|     Outfit m_outfit; | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| #endif // CREATURE_H
 | ||||
|  | @ -0,0 +1,18 @@ | |||
| #include "effect.h" | ||||
| #include "tibiadat.h" | ||||
| 
 | ||||
| Effect::Effect() | ||||
| { | ||||
|     m_type = Thing::TYPE_EFFECT; | ||||
| } | ||||
| 
 | ||||
| ThingAttributes *Effect::getAttributes() | ||||
| { | ||||
|     return g_tibiaDat.getEffectAttributes(m_id); | ||||
| } | ||||
| 
 | ||||
| void Effect::draw(int x, int y) | ||||
| { | ||||
|     int anim = 0; | ||||
|     internalDraw(x, y, 0, 0, 0, 0, anim); | ||||
| } | ||||
|  | @ -0,0 +1,21 @@ | |||
| #ifndef EFFECT_H | ||||
| #define EFFECT_H | ||||
| 
 | ||||
| #include <global.h> | ||||
| #include "thing.h" | ||||
| 
 | ||||
| class Effect; | ||||
| typedef std::shared_ptr<Effect> EffectPtr; | ||||
| 
 | ||||
| class Effect : public Thing | ||||
| { | ||||
| public: | ||||
|     Effect(); | ||||
| 
 | ||||
|     virtual ThingAttributes *getAttributes(); | ||||
|     void draw(int x, int y); | ||||
| 
 | ||||
| private: | ||||
| }; | ||||
| 
 | ||||
| #endif // EFFECT_H
 | ||||
|  | @ -11,6 +11,11 @@ Connection::Connection() : | |||
| { | ||||
| } | ||||
| 
 | ||||
| Connection::~Connection() | ||||
| { | ||||
|     disconnect(); | ||||
| } | ||||
| 
 | ||||
| void Connection::poll() | ||||
| { | ||||
|     ioService.poll(); | ||||
|  | @ -28,6 +33,11 @@ void Connection::connect(const std::string& host, uint16 port, const ConnectCall | |||
|     m_timer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), std::placeholders::_1)); | ||||
| } | ||||
| 
 | ||||
| void Connection::disconnect() | ||||
| { | ||||
|     m_socket.close(); | ||||
| } | ||||
| 
 | ||||
| void Connection::send(uint8* buffer, uint16 size) | ||||
| { | ||||
|     asio::async_write(m_socket, | ||||
|  |  | |||
|  | @ -11,10 +11,12 @@ class Connection : public std::enable_shared_from_this<Connection>, boost::nonco | |||
| 
 | ||||
| public: | ||||
|     Connection(); | ||||
|     ~Connection(); | ||||
| 
 | ||||
|     static void poll(); | ||||
| 
 | ||||
|     void connect(const std::string& host, uint16 port, const ConnectCallback& connectCallback); | ||||
|     void disconnect(); | ||||
|     void send(uint8* buffer, uint16 size); | ||||
|     void recv(uint16 bytes, uint32 timeout, const RecvCallback& callback); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,9 +1,10 @@ | |||
| #include "color.h" | ||||
| 
 | ||||
| Color Color::white(0xFF, 0xFF, 0xFF, 0xFF); | ||||
| Color Color::black(0x00, 0x00, 0x00, 0xFF); | ||||
| Color Color::alpha(0x00, 0x00, 0x00, 0x00); | ||||
| Color Color::red  (0xFF, 0x00, 0x00, 0xFF); | ||||
| Color Color::green(0x00, 0xFF, 0x00, 0xFF); | ||||
| Color Color::blue (0x00, 0x00, 0xFF, 0xFF); | ||||
| Color Color::pink (0xFF, 0x00, 0xFF, 0xFF); | ||||
| Color Color::white (0xFF, 0xFF, 0xFF, 0xFF); | ||||
| Color Color::black (0x00, 0x00, 0x00, 0xFF); | ||||
| Color Color::alpha (0x00, 0x00, 0x00, 0x00); | ||||
| Color Color::red   (0xFF, 0x00, 0x00, 0xFF); | ||||
| Color Color::green (0x00, 0xFF, 0x00, 0xFF); | ||||
| Color Color::blue  (0x00, 0x00, 0xFF, 0xFF); | ||||
| Color Color::pink  (0xFF, 0x00, 0xFF, 0xFF); | ||||
| Color Color::yellow(0x00, 0xFF, 0xFF, 0xFF); | ||||
|  |  | |||
|  | @ -39,6 +39,7 @@ public: | |||
|     static Color green; | ||||
|     static Color blue; | ||||
|     static Color pink; | ||||
|     static Color yellow; | ||||
| 
 | ||||
| private: | ||||
|     RGBA color; | ||||
|  |  | |||
|  | @ -1,3 +1,8 @@ | |||
| #include "game.h" | ||||
| 
 | ||||
| Game g_game; | ||||
| 
 | ||||
| Game::Game() | ||||
| { | ||||
|     m_online = false; | ||||
| } | ||||
|  |  | |||
							
								
								
									
										11
									
								
								src/game.h
								
								
								
								
							
							
						
						
									
										11
									
								
								src/game.h
								
								
								
								
							|  | @ -9,17 +9,22 @@ | |||
| class Game | ||||
| { | ||||
| public: | ||||
|     Game(); | ||||
| 
 | ||||
|     void setProtocol(ProtocolGame *protocolGame) { m_protocolGame = protocolGame; } | ||||
|     ProtocolGame *getProtocol() { return m_protocolGame; } | ||||
|     void setProtocol(ProtocolGamePtr protocolGame) { m_protocolGame = protocolGame; } | ||||
|     ProtocolGamePtr getProtocol() { return m_protocolGame; } | ||||
| 
 | ||||
|     Map *getMap() { return &m_map; } | ||||
|     Player *getPlayer() { return &m_player; } | ||||
| 
 | ||||
|     void setOnline(bool online) { m_online = online; } | ||||
|     bool getOnline() { return m_online; } | ||||
| 
 | ||||
| private: | ||||
|     Map m_map; | ||||
|     Player m_player; | ||||
|     ProtocolGame *m_protocolGame; | ||||
|     ProtocolGamePtr m_protocolGame; | ||||
|     bool m_online; | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										92
									
								
								src/item.cpp
								
								
								
								
							
							
						
						
									
										92
									
								
								src/item.cpp
								
								
								
								
							|  | @ -2,96 +2,34 @@ | |||
| #include "tibiadat.h" | ||||
| #include "tibiaspr.h" | ||||
| #include <graphics/graphics.h> | ||||
| 
 | ||||
| ItemAttributes::ItemAttributes() | ||||
| { | ||||
|     group = ITEM_GROUP_NONE; | ||||
|     blockSolid = false; | ||||
|     hasHeight = false; | ||||
|     blockPathFind = false; | ||||
|     blockProjectile = false; | ||||
|     alwaysOnTop = false; | ||||
|     alwaysOnTopOrder = 0; | ||||
|     stackable = false; | ||||
|     useable = false; | ||||
|     moveable = true; | ||||
|     pickupable = false; | ||||
|     rotable = false; | ||||
|     readable = false; | ||||
|     lookThrough = false; | ||||
|     speed = 0; | ||||
|     lightLevel = 0; | ||||
|     lightColor = 0; | ||||
|     isVertical = false; | ||||
|     isHorizontal = false; | ||||
|     isHangable = false; | ||||
|     miniMapColor = 0; | ||||
|     hasMiniMapColor = false; | ||||
|     subParam07 = 0; | ||||
|     subParam08 = 0; | ||||
|     sprites = NULL; | ||||
|     width = 0; | ||||
|     height = 0; | ||||
|     blendframes = 0; | ||||
|     xdiv = 0; | ||||
|     ydiv = 0; | ||||
|     zdiv = 0; | ||||
|     animcount = 0; | ||||
| } | ||||
| 
 | ||||
| ItemAttributes::~ItemAttributes() | ||||
| { | ||||
|     if(sprites) | ||||
|         delete []sprites; | ||||
| } | ||||
| #include "thing.h" | ||||
| 
 | ||||
| Item::Item() | ||||
| { | ||||
|     m_type = Thing::TYPE_ITEM; | ||||
| } | ||||
| 
 | ||||
| void Item::draw(int x, int y, int z) | ||||
| ThingAttributes *Item::getAttributes() | ||||
| { | ||||
|     ItemAttributes *itemAttributes = g_tibiaDat.getItemAttributes(m_id); | ||||
|     return g_tibiaDat.getItemAttributes(m_id); | ||||
| } | ||||
| 
 | ||||
|     int cDivX = 0, cDivY = 0, cDivZ = 0, cAnim = 0; | ||||
| void Item::draw(int x, int y) | ||||
| { | ||||
|     ThingAttributes *itemAttributes = getAttributes(); | ||||
| 
 | ||||
|     if(itemAttributes->group == ITEM_GROUP_SPLASH || itemAttributes->group == ITEM_GROUP_FLUID || itemAttributes->stackable) { | ||||
|     int xdiv = 0, ydiv = 0, zdiv = 0, anim = 0; | ||||
| 
 | ||||
|     if(itemAttributes->group == THING_GROUP_SPLASH || itemAttributes->group == THING_GROUP_FLUID || itemAttributes->stackable) { | ||||
|         //cDivX = subType % itemAttributes->xdiv;
 | ||||
|         //cDivY = subType / itemAttributes->xdiv;
 | ||||
|     } | ||||
|     else if(!itemAttributes->moveable) { | ||||
|         cDivX = x % itemAttributes->xdiv; | ||||
|         cDivY = y % itemAttributes->ydiv; | ||||
|         cDivZ = z % itemAttributes->zdiv; | ||||
|         xdiv = m_position.x % itemAttributes->xdiv; | ||||
|         ydiv = m_position.y % itemAttributes->ydiv; | ||||
|         zdiv = m_position.z % itemAttributes->zdiv; | ||||
|     } | ||||
| 
 | ||||
|     x *= 32; | ||||
|     y *= 32; | ||||
|     z = (7-z)*32; | ||||
| 
 | ||||
|     for(int b = 0; b < itemAttributes->blendframes; b++) { | ||||
|         for(int yi = 0; yi < itemAttributes->height; yi++) { | ||||
|             for(int xi = 0; xi < itemAttributes->width; xi++) { | ||||
|                 uint16 sprIndex = xi + | ||||
|                                   yi * itemAttributes->width + | ||||
|                                   b * itemAttributes->width * itemAttributes->height + | ||||
|                                   cDivX * itemAttributes->width * itemAttributes->height * itemAttributes->blendframes + | ||||
|                                   cDivY * itemAttributes->width * itemAttributes->height * itemAttributes->blendframes * itemAttributes->xdiv + | ||||
|                                   cDivZ * itemAttributes->width * itemAttributes->height * itemAttributes->blendframes * itemAttributes->xdiv * itemAttributes->ydiv + | ||||
|                                   cAnim * itemAttributes->width * itemAttributes->height * itemAttributes->blendframes * itemAttributes->xdiv * itemAttributes->ydiv * itemAttributes->zdiv; | ||||
|                 uint16 itemId = itemAttributes->sprites[sprIndex]; | ||||
|                 if(itemId == 0xFFFF) | ||||
|                     continue; | ||||
|                 TexturePtr data = g_tibiaSpr.getSprite(itemId); | ||||
| 
 | ||||
|                 // todo verify this to draw in correct pos (screenX, screenY)
 | ||||
|                 g_graphics.drawTexturedRect(Rect(x - xi*32 - z, y - yi*32 - z, 32, 32), data, Rect(0, 0, 32, 32)); | ||||
| 
 | ||||
|                 //g_graphics.drawBoundingRect(Rect(x - xi*32 - z, y - yi*32 - z, 32, 32), Color::green);
 | ||||
|                 if(x/32 == 7 && y/32 == 5 && z/32+7 == 7) | ||||
|                     g_graphics.drawBoundingRect(Rect(x - xi*32 - z, y - yi*32 - z, 32, 32), Color::red); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     for(int b = 0; b < itemAttributes->blendframes; b++) | ||||
|         internalDraw(x, y, b, xdiv, ydiv, zdiv, anim); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										44
									
								
								src/item.h
								
								
								
								
							
							
						
						
									
										44
									
								
								src/item.h
								
								
								
								
							|  | @ -4,47 +4,16 @@ | |||
| #include <global.h> | ||||
| #include "thing.h" | ||||
| 
 | ||||
| enum ItemGroup { | ||||
|     ITEM_GROUP_NONE = 0, | ||||
|     ITEM_GROUP_GROUND, | ||||
|     ITEM_GROUP_CONTAINER, | ||||
|     ITEM_GROUP_WEAPON, | ||||
|     ITEM_GROUP_AMMUNITION, | ||||
|     ITEM_GROUP_ARMOR, | ||||
|     ITEM_GROUP_RUNE, | ||||
|     ITEM_GROUP_TELEPORT, | ||||
|     ITEM_GROUP_MAGICFIELD, | ||||
|     ITEM_GROUP_WRITEABLE, | ||||
|     ITEM_GROUP_KEY, | ||||
|     ITEM_GROUP_SPLASH, | ||||
|     ITEM_GROUP_FLUID, | ||||
|     ITEM_GROUP_DOOR, | ||||
|     ITEM_GROUP_LAST | ||||
| }; | ||||
| class Item; | ||||
| typedef std::shared_ptr<Item> ItemPtr; | ||||
| 
 | ||||
| class ItemAttributes | ||||
| { | ||||
| public: | ||||
|     ItemAttributes(); | ||||
|     ~ItemAttributes(); | ||||
| 
 | ||||
|     bool stackable, alwaysOnTop, useable, readable, moveable, blockSolid, blockProjectile, blockPathFind, pickupable, | ||||
|          isHangable, isHorizontal, isVertical, rotable, hasHeight, lookThrough, hasMiniMapColor; | ||||
|     uint8 alwaysOnTopOrder, width, height, blendframes, xdiv, ydiv, zdiv, animcount; | ||||
|     uint16 id, speed, subParam07, subParam08, lightLevel, lightColor, uheight, miniMapColor; | ||||
|     uint16 *sprites; | ||||
|     ItemGroup group; | ||||
| }; | ||||
| 
 | ||||
| class Item : virtual public Thing | ||||
| class Item : public Thing | ||||
| { | ||||
| public: | ||||
|     Item(); | ||||
| 
 | ||||
|     void draw(int x, int y, int z); | ||||
| 
 | ||||
|     void setId(uint16 id) { m_id = id; } | ||||
|     uint16 getId() const { return m_id; } | ||||
|     virtual ThingAttributes *getAttributes(); | ||||
|     void draw(int x, int y); | ||||
| 
 | ||||
|     void setCount(uint8 count) { m_count = count; } | ||||
| 
 | ||||
|  | @ -52,8 +21,7 @@ public: | |||
|     virtual const Item* getItem() const { return this; } | ||||
| 
 | ||||
| private: | ||||
|     uint16 m_id; | ||||
|     uint8 m_count; | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
| #endif // ITEM_H
 | ||||
|  |  | |||
							
								
								
									
										48
									
								
								src/map.cpp
								
								
								
								
							
							
						
						
									
										48
									
								
								src/map.cpp
								
								
								
								
							|  | @ -17,41 +17,59 @@ void Map::draw(int x, int y) | |||
|     if(playerPos->z <= 7) { | ||||
| 
 | ||||
|         // player pos it 8-6. check if we can draw upper floors.
 | ||||
|         /*bool draw = true;
 | ||||
|         bool draw = true; | ||||
|         for(int jz = 6; jz >= 0; --jz) { | ||||
|             if(m_tiles[Position(8+(6-jz), 6+(6-jz), jz)]->getStackSize() > 0) { | ||||
|                 draw = false; | ||||
|             Position coverPos = Position(playerPos->x-(6-jz), playerPos->y-(6-jz), jz); | ||||
|             if(m_tiles[coverPos]) { | ||||
|                 if(m_tiles[coverPos]->getStackSize() > 0 && jz < playerPos->z) { | ||||
|                     draw = false; | ||||
|                 } | ||||
|             } | ||||
|         }*/ | ||||
|         } | ||||
| 
 | ||||
|         for(int iz = 7; iz > 0; --iz) { | ||||
| 
 | ||||
|             // +1 in draws cause 64x64 items may affect view.
 | ||||
|             for(int ix = - 8; ix < + 8; ++ix) { | ||||
|                 for(int iy = - 6; iy < + 6; ++iy) { | ||||
|                     Position relativePos = Position(playerPos->x + ix, playerPos->y + iy, iz); | ||||
|             for(int ix = -7; ix < + 8+7; ++ix) { | ||||
|                 for(int iy = -5; iy < + 6+7; ++iy) { | ||||
|                     Position itemPos = Position(playerPos->x + ix, playerPos->y + iy, iz); | ||||
|                     //Position drawPos = Position(ix + 8, iy - playerPos->y + 6, iz);
 | ||||
|                     //logDebug("x: ", relativePos.x, " y: ", relativePos.y, " z: ", (int)relativePos.z);
 | ||||
|                     if(m_tiles.find(relativePos) != m_tiles.end()) | ||||
|                         m_tiles[relativePos]->draw(ix + 8, iy + 6, iz); | ||||
|                     if(m_tiles[itemPos]) | ||||
|                         m_tiles[itemPos]->draw((ix + 7 - (7-iz))*32, (iy + 5 - (7-iz))*32); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             //if(!draw)
 | ||||
|                 //break;
 | ||||
|             if(!draw) | ||||
|                 break; | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     // draw effects
 | ||||
|     for(auto it = m_effects.begin(), end = m_effects.end(); it != end; ++it) { | ||||
|         Position *effectPos = (*it)->getPosition(); | ||||
|         (*it)->draw((effectPos->x - playerPos->x + 7) * 32, (effectPos->y - playerPos->y + 5) * 32); | ||||
|     } | ||||
| 
 | ||||
|     // debug draws
 | ||||
|     g_graphics.drawBoundingRect(Rect(7*32, 5*32, 32, 32), Color::red); | ||||
| 
 | ||||
|     m_framebuffer->unbind(); | ||||
| 
 | ||||
|     m_framebuffer->draw(x, y, g_graphics.getScreenSize().width(), g_graphics.getScreenSize().height()); | ||||
| } | ||||
| 
 | ||||
| void Map::addThing(Thing *thing, const Position& pos) | ||||
| void Map::addThing(ThingPtr thing, uint8 stackpos) | ||||
| { | ||||
|     if(m_tiles.find(pos) == m_tiles.end()) { | ||||
|         m_tiles[pos] = TilePtr(new Tile()); | ||||
|     if(thing->getType() == Thing::TYPE_ITEM || thing->getType() == Thing::TYPE_CREATURE) { | ||||
|         if(!m_tiles[*thing->getPosition()]) { | ||||
|             m_tiles[*thing->getPosition()] = TilePtr(new Tile()); | ||||
|         } | ||||
| 
 | ||||
|         m_tiles[*thing->getPosition()]->addThing(thing, stackpos); | ||||
|     } | ||||
|     else if(thing->getType() == Thing::TYPE_EFFECT) { | ||||
|         m_effects.push_back(thing); | ||||
|     } | ||||
|     m_tiles[pos]->addThing(thing); | ||||
| } | ||||
|  |  | |||
|  | @ -3,18 +3,22 @@ | |||
| 
 | ||||
| #include "position.h" | ||||
| #include "tile.h" | ||||
| #include "effect.h" | ||||
| #include <graphics/graphicsdeclarations.h> | ||||
| #include <unordered_map> | ||||
| 
 | ||||
| class Map | ||||
| { | ||||
| public: | ||||
|     void addThing(Thing *thing, const Position& pos); | ||||
|     void addThing(ThingPtr thing, uint8 stackpos = 0); | ||||
| 
 | ||||
|     void draw(int x, int y); | ||||
| 
 | ||||
|     FrameBufferPtr getFramebuffer() { return m_framebuffer; } | ||||
| 
 | ||||
| private: | ||||
|     std::unordered_map<Position, TilePtr, PositionHash> m_tiles; | ||||
|     std::list<ThingPtr> m_effects; | ||||
| 
 | ||||
|     FrameBufferPtr m_framebuffer; | ||||
| }; | ||||
|  |  | |||
|  | @ -199,7 +199,8 @@ void OTClient::poll() | |||
| 
 | ||||
| void OTClient::render() | ||||
| { | ||||
|     g_game.getMap()->draw(0, 0); | ||||
|     if(g_game.getOnline()) | ||||
|         g_game.getMap()->draw(0, 0); | ||||
| 
 | ||||
|     // everything is rendered by UI components
 | ||||
|     g_ui.render(); | ||||
|  | @ -261,7 +262,7 @@ void OTClient::onInputEvent(const InputEvent& event) | |||
| { | ||||
|     g_ui.inputEvent(event); | ||||
| 
 | ||||
|     ProtocolGame *protocol = g_game.getProtocol(); | ||||
|     ProtocolGamePtr protocol = g_game.getProtocol(); | ||||
|     if(protocol) { | ||||
|         if(event.type == EventKeyDown) { | ||||
|             if(event.keycode == KC_UP) | ||||
|  |  | |||
							
								
								
									
										15
									
								
								src/player.h
								
								
								
								
							
							
						
						
									
										15
									
								
								src/player.h
								
								
								
								
							|  | @ -1,17 +1,22 @@ | |||
| #ifndef PLAYER_H | ||||
| #define PLAYER_H | ||||
| 
 | ||||
| #include "position.h" | ||||
| #include "creature.h" | ||||
| 
 | ||||
| class Player | ||||
| class Player : public Creature | ||||
| { | ||||
| public: | ||||
|     void setDrawSpeed(uint16 drawSpeed) { m_drawSpeed = drawSpeed; } | ||||
|     uint16 getDrawSpeed() { return m_drawSpeed; } | ||||
| 
 | ||||
|     void setPosition(const Position& position) { m_position = position; } | ||||
|     Position *getPosition() { return &m_position; } | ||||
|     void setCanReportBugs(uint8 canReportBugs) { m_canReportBugs = (canReportBugs != 0); } | ||||
|     bool getCanReportBugs() { return m_canReportBugs; } | ||||
| 
 | ||||
| private: | ||||
|     Position m_position; | ||||
| 
 | ||||
|     uint16 m_drawSpeed; | ||||
|     bool m_canReportBugs; | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -3,6 +3,14 @@ | |||
| 
 | ||||
| #include <global.h> | ||||
| 
 | ||||
| enum Direction | ||||
| { | ||||
|     DIRECTION_NORTH, | ||||
|     DIRECTION_EAST, | ||||
|     DIRECTION_SOUTH, | ||||
|     DIRECTION_WEST | ||||
| }; | ||||
| 
 | ||||
| class Position | ||||
| { | ||||
| public: | ||||
|  |  | |||
|  | @ -5,11 +5,12 @@ | |||
| ProtocolGame::ProtocolGame() | ||||
| { | ||||
|     m_checksumEnabled = false; | ||||
|     g_game.setProtocol(this); | ||||
|     g_game.setProtocol(ProtocolGamePtr(this)); | ||||
| } | ||||
| 
 | ||||
| ProtocolGame::~ProtocolGame() | ||||
| { | ||||
|     sendLogout(); | ||||
|     g_game.setProtocol(NULL); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
| 
 | ||||
| #include <net/protocol.h> | ||||
| #include "player.h" | ||||
| #include "thing.h" | ||||
| #include "item.h" | ||||
| 
 | ||||
| class ProtocolGame; | ||||
| typedef std::shared_ptr<ProtocolGame> ProtocolGamePtr; | ||||
|  | @ -22,6 +22,7 @@ public: | |||
|     void onRecv(InputMessage& inputMessage); | ||||
| 
 | ||||
|     // Send Messages
 | ||||
|     void sendLogout(); | ||||
|     void sendPing(); | ||||
|     void sendWalkNorth(); | ||||
|     void sendWalkEast(); | ||||
|  | @ -73,6 +74,7 @@ private: | |||
|     void parseCreatureSpeed(InputMessage& msg); | ||||
|     void parseCreatureSkulls(InputMessage& msg); | ||||
|     void parseCreatureShields(InputMessage& msg); | ||||
|     void parseCreatureTurn(InputMessage& msg); | ||||
|     void parseItemTextWindow(InputMessage& msg); | ||||
|     void parseHouseTextWindow(InputMessage& msg); | ||||
|     void parsePlayerStats(InputMessage& msg); | ||||
|  | @ -107,9 +109,9 @@ private: | |||
|     void setMapDescription(InputMessage& msg, int32 x, int32 y, int32 z, int32 width, int32 height); | ||||
|     void setFloorDescription(InputMessage& msg, int32 x, int32 y, int32 z, int32 width, int32 height, int32 offset, int32* skipTiles); | ||||
|     void setTileDescription(InputMessage& msg, Position position); | ||||
|     Thing *internalGetThing(InputMessage& msg); | ||||
|     void internalCreatureOutfit(InputMessage& msg); | ||||
|     Item *internalGetItem(InputMessage& msg, uint16 id); | ||||
|     ThingPtr internalGetThing(InputMessage& msg); | ||||
|     Outfit internalCreatureOutfit(InputMessage& msg); | ||||
|     ItemPtr internalGetItem(InputMessage& msg, uint16 id); | ||||
| 
 | ||||
|     Position parsePosition(InputMessage& msg); | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| #include "tibiadat.h" | ||||
| #include "game.h" | ||||
| #include "map.h" | ||||
| #include "effect.h" | ||||
| #include <iomanip> | ||||
| 
 | ||||
| void ProtocolGame::parseMessage(InputMessage& msg) | ||||
|  | @ -235,9 +236,12 @@ void ProtocolGame::parseMessage(InputMessage& msg) | |||
| 
 | ||||
| void ProtocolGame::parsePlayerLogin(InputMessage& msg) | ||||
| { | ||||
|     msg.getU32(); // player id
 | ||||
|     msg.getU16(); // drawing speed.
 | ||||
|     msg.getU8(); // can report bugs
 | ||||
|     Player *player = g_game.getPlayer(); | ||||
|     player->setId(msg.getU32()); | ||||
|     player->setDrawSpeed(msg.getU16()); | ||||
|     player->setCanReportBugs(msg.getU8()); | ||||
| 
 | ||||
|     g_game.setOnline(true); | ||||
| } | ||||
| 
 | ||||
| void ProtocolGame::parseGMActions(InputMessage& msg) | ||||
|  | @ -248,7 +252,8 @@ void ProtocolGame::parseGMActions(InputMessage& msg) | |||
| 
 | ||||
| void ProtocolGame::parseErrorMessage(InputMessage& msg) | ||||
| { | ||||
|     msg.getString(); // message
 | ||||
|     std::string error = msg.getString(); | ||||
|     callLuaField("onError", error); | ||||
| } | ||||
| 
 | ||||
| void ProtocolGame::parseFYIMessage(InputMessage& msg) | ||||
|  | @ -280,12 +285,7 @@ void ProtocolGame::parseCanReportBugs(InputMessage& msg) | |||
| void ProtocolGame::parseMapDescription(InputMessage& msg) | ||||
| { | ||||
|     Player *player = g_game.getPlayer(); | ||||
| 
 | ||||
|     Position playerPos = parsePosition(msg); | ||||
| 
 | ||||
|     logDebug("x: ", playerPos.x, " y: ", playerPos.y, " z: ", (int)playerPos.z); | ||||
|     player->setPosition(playerPos); | ||||
|     logDebug("x: ", player->getPosition()->x, " y: ", player->getPosition()->y, " z: ", (int)player->getPosition()->z); | ||||
|     player->setPosition(parsePosition(msg)); | ||||
|     setMapDescription(msg, player->getPosition()->x - 8, player->getPosition()->y - 6, player->getPosition()->z, 18, 14); | ||||
| } | ||||
| 
 | ||||
|  | @ -462,8 +462,11 @@ void ProtocolGame::parseWorldLight(InputMessage& msg) | |||
| 
 | ||||
| void ProtocolGame::parseMagicEffect(InputMessage& msg) | ||||
| { | ||||
|     parsePosition(msg); // effect pos
 | ||||
|     msg.getU8(); // effect
 | ||||
|     EffectPtr effect = EffectPtr(new Effect()); | ||||
|     effect->setPosition(parsePosition(msg)); | ||||
|     effect->setId(msg.getU8()); | ||||
| 
 | ||||
|     g_game.getMap()->addThing(effect); | ||||
| } | ||||
| 
 | ||||
| void ProtocolGame::parseAnimatedText(InputMessage& msg) | ||||
|  | @ -523,6 +526,12 @@ void ProtocolGame::parseCreatureShields(InputMessage& msg) | |||
|     msg.getU8(); // shield
 | ||||
| } | ||||
| 
 | ||||
| void ProtocolGame::parseCreatureTurn(InputMessage& msg) | ||||
| { | ||||
|     msg.getU32(); // creature id
 | ||||
|     msg.getU8(); // direction
 | ||||
| } | ||||
| 
 | ||||
| void ProtocolGame::parseItemTextWindow(InputMessage& msg) | ||||
| { | ||||
|     msg.getU32(); // windowId
 | ||||
|  | @ -828,43 +837,48 @@ void ProtocolGame::setFloorDescription(InputMessage& msg, int32 x, int32 y, int3 | |||
| 
 | ||||
| void ProtocolGame::setTileDescription(InputMessage& msg, Position position) | ||||
| { | ||||
|     int n = 0; | ||||
|     int stackpos = 0; | ||||
|     while(1){ | ||||
|         n++; | ||||
|         stackpos++; | ||||
|         uint16 inspectTileId = msg.getU16(true); | ||||
|         if(inspectTileId >= 0xFF00) | ||||
|             return; | ||||
|         else { | ||||
|             if(n > 10) { | ||||
|             if(stackpos > 10) { | ||||
|                 logDebug("[ProtocolGame::setTileDescription] Too many things!."); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             g_game.getMap()->addThing(internalGetThing(msg), position); | ||||
|             ThingPtr thing = internalGetThing(msg); | ||||
|             if(thing) | ||||
|                 thing->setPosition(position); | ||||
|             g_game.getMap()->addThing(thing, stackpos); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| Thing *ProtocolGame::internalGetThing(InputMessage& msg) | ||||
| ThingPtr ProtocolGame::internalGetThing(InputMessage& msg) | ||||
| { | ||||
|     Thing *thing = NULL; | ||||
|     ThingPtr thing; | ||||
| 
 | ||||
|     uint16 thingId = msg.getU16(); | ||||
|     if(thingId == 0x0061 || thingId == 0x0062) { // add new creature
 | ||||
|         CreaturePtr creature = CreaturePtr(new Creature); | ||||
| 
 | ||||
|         if(thingId == 0x0062) { //creature is known
 | ||||
|             msg.getU32(); // creature id
 | ||||
|             creature->setId(msg.getU32()); | ||||
|         } | ||||
|         else if(thingId == 0x0061) { //creature is not known
 | ||||
|             msg.getU32(); // remove id
 | ||||
|             msg.getU32(); // creature id
 | ||||
|             msg.getString(); // creature name
 | ||||
|             creature->setId(msg.getU32()); | ||||
|             creature->setName(msg.getString()); | ||||
|         } | ||||
| 
 | ||||
|         msg.getU8(); // hp
 | ||||
|         msg.getU8(); // direction
 | ||||
|         internalCreatureOutfit(msg); | ||||
|         msg.getU8(); // level
 | ||||
|         msg.getU8(); // color
 | ||||
|         creature->setHealthPercent(msg.getU8()); | ||||
|         creature->setDirection((Direction)msg.getU8()); | ||||
|         creature->setOutfit(internalCreatureOutfit(msg)); | ||||
|         msg.getU8(); // light level
 | ||||
|         msg.getU8(); // light color
 | ||||
|         msg.getU16(); // speed
 | ||||
|         msg.getU8(); // skull
 | ||||
|         msg.getU8(); // shield
 | ||||
|  | @ -873,10 +887,11 @@ Thing *ProtocolGame::internalGetThing(InputMessage& msg) | |||
|             msg.getU8(); | ||||
|         msg.getU8(); // impassable
 | ||||
| 
 | ||||
|         thing = creature; | ||||
| 
 | ||||
|     } | ||||
|     else if(thingId == 0x0063) { // creature turn
 | ||||
|         msg.getU32(); // creature id
 | ||||
|         msg.getU8(); // direction
 | ||||
|         parseCreatureTurn(msg); | ||||
|     } | ||||
|     else // item
 | ||||
|         thing = internalGetItem(msg, thingId); | ||||
|  | @ -884,31 +899,35 @@ Thing *ProtocolGame::internalGetThing(InputMessage& msg) | |||
|     return thing; | ||||
| } | ||||
| 
 | ||||
| void ProtocolGame::internalCreatureOutfit(InputMessage& msg) | ||||
| Outfit ProtocolGame::internalCreatureOutfit(InputMessage& msg) | ||||
| { | ||||
|     uint16 lookType = msg.getU16(); // looktype
 | ||||
|     if(lookType != 0) { | ||||
|         msg.getU8(); // lookhead
 | ||||
|         msg.getU8(); // lookbody
 | ||||
|         msg.getU8(); // looklegs
 | ||||
|         msg.getU8(); // lookfeet
 | ||||
|         msg.getU8(); // lookaddons
 | ||||
|     Outfit outfit; | ||||
| 
 | ||||
|     outfit.type = msg.getU16(); // looktype
 | ||||
|     if(outfit.type != 0) { | ||||
|         outfit.head = msg.getU8(); | ||||
|         outfit.body = msg.getU8(); | ||||
|         outfit.legs = msg.getU8(); | ||||
|         outfit.feet = msg.getU8(); | ||||
|         outfit.addons = msg.getU8(); | ||||
|     } | ||||
|     else { | ||||
|         msg.getU16(); // looktype
 | ||||
|         outfit.type = msg.getU16(); | ||||
|     } | ||||
| 
 | ||||
|     return outfit; | ||||
| } | ||||
| 
 | ||||
| Item *ProtocolGame::internalGetItem(InputMessage& msg, uint16 id) | ||||
| ItemPtr ProtocolGame::internalGetItem(InputMessage& msg, uint16 id) | ||||
| { | ||||
|     Item *item = new Item(); | ||||
|     ItemPtr item = ItemPtr(new Item()); | ||||
| 
 | ||||
|     if(id == 0xFFFF) | ||||
|         id = msg.getU16(); | ||||
|     item->setId(id); | ||||
| 
 | ||||
|     ItemAttributes *itemAttributes = g_tibiaDat.getItemAttributes(id); | ||||
|     if(itemAttributes->stackable || itemAttributes->group == ITEM_GROUP_FLUID || itemAttributes->group == ITEM_GROUP_SPLASH) | ||||
|     ThingAttributes *itemAttributes = g_tibiaDat.getItemAttributes(id); | ||||
|     if(itemAttributes->stackable || itemAttributes->group == THING_GROUP_FLUID || itemAttributes->group == THING_GROUP_SPLASH) | ||||
|         item->setCount(msg.getU8()); | ||||
| 
 | ||||
|     return item; | ||||
|  |  | |||
|  | @ -1,5 +1,12 @@ | |||
| #include "protocolgame.h" | ||||
| 
 | ||||
| void ProtocolGame::sendLogout() | ||||
| { | ||||
|     OutputMessage oMsg; | ||||
|     oMsg.addU8(0x14); | ||||
|     send(oMsg); | ||||
| } | ||||
| 
 | ||||
| void ProtocolGame::sendPing() | ||||
| { | ||||
|     OutputMessage oMsg; | ||||
|  |  | |||
|  | @ -1,6 +1,83 @@ | |||
| #include "thing.h" | ||||
| #include "tibiaspr.h" | ||||
| #include <graphics/graphics.h> | ||||
| 
 | ||||
| ThingAttributes::ThingAttributes() | ||||
| { | ||||
|     group = THING_GROUP_NONE; | ||||
|     blockSolid = false; | ||||
|     hasHeight = false; | ||||
|     blockPathFind = false; | ||||
|     blockProjectile = false; | ||||
|     alwaysOnTop = false; | ||||
|     alwaysOnTopOrder = 0; | ||||
|     stackable = false; | ||||
|     useable = false; | ||||
|     moveable = true; | ||||
|     pickupable = false; | ||||
|     rotable = false; | ||||
|     readable = false; | ||||
|     lookThrough = false; | ||||
|     speed = 0; | ||||
|     lightLevel = 0; | ||||
|     lightColor = 0; | ||||
|     isVertical = false; | ||||
|     isHorizontal = false; | ||||
|     isHangable = false; | ||||
|     miniMapColor = 0; | ||||
|     hasMiniMapColor = false; | ||||
|     subParam07 = 0; | ||||
|     subParam08 = 0; | ||||
|     sprites = NULL; | ||||
|     width = 0; | ||||
|     height = 0; | ||||
|     blendframes = 0; | ||||
|     xdiv = 0; | ||||
|     ydiv = 0; | ||||
|     zdiv = 0; | ||||
|     animcount = 0; | ||||
|     xOffset = 0; | ||||
|     yOffset = 0; | ||||
| } | ||||
| 
 | ||||
| ThingAttributes::~ThingAttributes() | ||||
| { | ||||
|     if(sprites) | ||||
|         delete []sprites; | ||||
| } | ||||
| 
 | ||||
| Thing::Thing() | ||||
| { | ||||
|     m_type = TYPE_NONE; | ||||
| } | ||||
| 
 | ||||
| void Thing::internalDraw(int x, int y, int blendframes, int xdiv, int ydiv, int zdiv, int anim) | ||||
| { | ||||
|     ThingAttributes *thingAttributes = getAttributes(); | ||||
|     if(!thingAttributes) | ||||
|         return; | ||||
| 
 | ||||
|     for(int yi = 0; yi < thingAttributes->height; yi++) { | ||||
|         for(int xi = 0; xi < thingAttributes->width; xi++) { | ||||
|             uint16 sprIndex = xi + | ||||
|                     yi * thingAttributes->width + | ||||
|                     blendframes * thingAttributes->width * thingAttributes->height + | ||||
|                     xdiv * thingAttributes->width * thingAttributes->height * thingAttributes->blendframes + | ||||
|                     ydiv * thingAttributes->width * thingAttributes->height * thingAttributes->blendframes * thingAttributes->xdiv + | ||||
|                     zdiv * thingAttributes->width * thingAttributes->height * thingAttributes->blendframes * thingAttributes->xdiv * thingAttributes->ydiv + | ||||
|                     anim * thingAttributes->width * thingAttributes->height * thingAttributes->blendframes * thingAttributes->xdiv * thingAttributes->ydiv * thingAttributes->zdiv; | ||||
|             uint16 itemId = thingAttributes->sprites[sprIndex]; | ||||
|             if(itemId == 0xFFFF) | ||||
|                 continue; | ||||
|             TexturePtr data = g_tibiaSpr.getSprite(itemId); | ||||
| 
 | ||||
|             int offsetX = 0, offsetY = 0; | ||||
|             if(thingAttributes->hasHeight) { | ||||
|                 offsetX = thingAttributes->xOffset; | ||||
|                 offsetY = thingAttributes->xOffset; // << look to xoffset
 | ||||
|             } | ||||
| 
 | ||||
|             g_graphics.drawTexturedRect(Rect((x - xi*32) - offsetX, (y - yi*32) - offsetY, 32, 32), data, Rect(0, 0, 32, 32)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										56
									
								
								src/thing.h
								
								
								
								
							
							
						
						
									
										56
									
								
								src/thing.h
								
								
								
								
							|  | @ -2,9 +2,45 @@ | |||
| #define THING_H | ||||
| 
 | ||||
| #include <global.h> | ||||
| #include "position.h" | ||||
| 
 | ||||
| enum ThingAttributesGroup { | ||||
|     THING_GROUP_NONE = 0, | ||||
|     THING_GROUP_GROUND, | ||||
|     THING_GROUP_CONTAINER, | ||||
|     THING_GROUP_WEAPON, | ||||
|     THING_GROUP_AMMUNITION, | ||||
|     THING_GROUP_ARMOR, | ||||
|     THING_GROUP_RUNE, | ||||
|     THING_GROUP_TELEPORT, | ||||
|     THING_GROUP_MAGICFIELD, | ||||
|     THING_GROUP_WRITEABLE, | ||||
|     THING_GROUP_KEY, | ||||
|     THING_GROUP_SPLASH, | ||||
|     THING_GROUP_FLUID, | ||||
|     THING_GROUP_DOOR, | ||||
|     THING_GROUP_LAST | ||||
| }; | ||||
| 
 | ||||
| struct ThingAttributes | ||||
| { | ||||
|     ThingAttributes(); | ||||
|     ~ThingAttributes(); | ||||
| 
 | ||||
|     bool stackable, alwaysOnTop, useable, readable, moveable, blockSolid, blockProjectile, blockPathFind, pickupable, | ||||
|          isHangable, isHorizontal, isVertical, rotable, hasHeight, lookThrough, hasMiniMapColor; | ||||
|     uint8 alwaysOnTopOrder, width, height, blendframes, xdiv, ydiv, zdiv, animcount, xOffset, yOffset; | ||||
|     uint16 id, speed, subParam07, subParam08, lightLevel, lightColor, miniMapColor; | ||||
|     uint16 *sprites; | ||||
|     ThingAttributesGroup group; | ||||
| }; | ||||
| 
 | ||||
| class Creature; | ||||
| class Item; | ||||
| 
 | ||||
| class Thing; | ||||
| typedef std::shared_ptr<Thing> ThingPtr; | ||||
| 
 | ||||
| class Thing | ||||
| { | ||||
| public: | ||||
|  | @ -13,19 +49,35 @@ public: | |||
|     enum Type { | ||||
|         TYPE_NONE, | ||||
|         TYPE_ITEM, | ||||
|         TYPE_CREATURE | ||||
|         TYPE_CREATURE, | ||||
|         TYPE_EFFECT, | ||||
|         TYPE_SHOT | ||||
|     }; | ||||
| 
 | ||||
|     void setId(uint32 id) { m_id = id; } | ||||
|     uint32 getId() { return m_id; } | ||||
| 
 | ||||
|     void setType(Type type) { m_type = type; } | ||||
|     Type getType() const { return m_type; } | ||||
| 
 | ||||
|     virtual void draw(int, int, int) {} | ||||
|     void setPosition(const Position& position) { m_position = position; } | ||||
|     Position *getPosition() { return &m_position; } | ||||
| 
 | ||||
|     virtual void draw(int, int) {} | ||||
|     virtual ThingAttributes *getAttributes() { return NULL; } | ||||
| 
 | ||||
|     virtual Item* getItem() { return NULL; } | ||||
|     virtual const Item *getItem() const { return NULL; } | ||||
|     virtual Creature *getCreature() { return NULL; } | ||||
|     virtual const Creature *getCreature() const { return NULL; } | ||||
| 
 | ||||
| protected: | ||||
|     void internalDraw(int x, int y, int blendframes, int xdiv, int ydiv, int zdiv, int anim); | ||||
| 
 | ||||
|     uint32 m_id; | ||||
|     Type m_type; | ||||
|     Position m_position; | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| #endif // THING_H
 | ||||
|  |  | |||
							
								
								
									
										135
									
								
								src/tibiadat.cpp
								
								
								
								
							
							
						
						
									
										135
									
								
								src/tibiadat.cpp
								
								
								
								
							|  | @ -20,17 +20,17 @@ bool TibiaDat::load(const std::string& filename) | |||
| 
 | ||||
|     m_totalCount = m_groupCount[0] + m_groupCount[1] + m_groupCount[2] + m_groupCount[3]; | ||||
| 
 | ||||
|     m_itemsAttributes = new ItemAttributes*[m_totalCount+1]; | ||||
|     m_thingsAttributes = new ThingAttributes*[m_totalCount+1]; | ||||
|     for(uint16 i = 0; i <= m_totalCount; i++) | ||||
|         m_itemsAttributes[i] = NULL; | ||||
|         m_thingsAttributes[i] = NULL; | ||||
| 
 | ||||
|     uint8 read_byte; | ||||
|     uint16 read_short; | ||||
|     uint32 read_long; | ||||
|     //uint32 read_long;
 | ||||
| 
 | ||||
|     for(uint16 id = 0; (id <= m_totalCount) && !fin.eof(); id++) { | ||||
|         m_itemsAttributes[id] = new ItemAttributes(); | ||||
|         m_itemsAttributes[id]->id = id; | ||||
|         m_thingsAttributes[id] = new ThingAttributes(); | ||||
|         m_thingsAttributes[id]->id = id; | ||||
| 
 | ||||
|         uint8 opt; | ||||
|         bool done = false; | ||||
|  | @ -38,109 +38,116 @@ bool TibiaDat::load(const std::string& filename) | |||
|             fin.read((char*)&opt, 1); | ||||
| 
 | ||||
|             if(opt == 0x00) { // Ground tile
 | ||||
|                 fin.read((char*)&m_itemsAttributes[id]->speed, 2); | ||||
|                 m_itemsAttributes[id]->group = ITEM_GROUP_GROUND; | ||||
|                 fin.read((char*)&m_thingsAttributes[id]->speed, 2); | ||||
|                 m_thingsAttributes[id]->group = THING_GROUP_GROUND; | ||||
|             } | ||||
|             else if(opt == 0x01) { // All OnTop
 | ||||
|                 m_itemsAttributes[id]->alwaysOnTop = true; | ||||
|                 m_itemsAttributes[id]->alwaysOnTopOrder = 1; | ||||
|                 m_thingsAttributes[id]->alwaysOnTop = true; | ||||
|                 m_thingsAttributes[id]->alwaysOnTopOrder = 1; | ||||
|             } | ||||
|             else if(opt == 0x02) { // Can walk trough (open doors, arces, bug pen fence)
 | ||||
|                 m_itemsAttributes[id]->alwaysOnTop = true; | ||||
|                 m_itemsAttributes[id]->alwaysOnTopOrder = 2; | ||||
|                 m_thingsAttributes[id]->alwaysOnTop = true; | ||||
|                 m_thingsAttributes[id]->alwaysOnTopOrder = 2; | ||||
|             } | ||||
|             else if(opt == 0x03) { // Can walk trough (arces)
 | ||||
|                 m_itemsAttributes[id]->alwaysOnTop = true; | ||||
|                 m_itemsAttributes[id]->alwaysOnTopOrder = 3; | ||||
|                 m_thingsAttributes[id]->alwaysOnTop = true; | ||||
|                 m_thingsAttributes[id]->alwaysOnTopOrder = 3; | ||||
|             } | ||||
|             else if(opt == 0x04) { // Container
 | ||||
|                 m_itemsAttributes[id]->group = ITEM_GROUP_CONTAINER; | ||||
|                 m_thingsAttributes[id]->group = THING_GROUP_CONTAINER; | ||||
|             } | ||||
|             else if(opt == 0x05) { // Stackable
 | ||||
|                 m_itemsAttributes[id]->stackable = true; | ||||
|                 m_thingsAttributes[id]->stackable = true; | ||||
|             } | ||||
|             else if(opt == 0x06) { // Unknown
 | ||||
| 
 | ||||
|             } | ||||
|             else if(opt == 0x07) { // Useable
 | ||||
|                 m_itemsAttributes[id]->useable = true; | ||||
|                 m_thingsAttributes[id]->useable = true; | ||||
|             } | ||||
|             else if(opt == 0x08) { // Writtable
 | ||||
|                 m_itemsAttributes[id]->group = ITEM_GROUP_WRITEABLE; | ||||
|                 m_itemsAttributes[id]->readable = true; | ||||
|                 fin.read((char*)&m_itemsAttributes[id]->subParam07, 2); | ||||
|                 m_thingsAttributes[id]->group = THING_GROUP_WRITEABLE; | ||||
|                 m_thingsAttributes[id]->readable = true; | ||||
|                 fin.read((char*)&m_thingsAttributes[id]->subParam07, 2); | ||||
|             } | ||||
|             else if(opt == 0x09) { // Writtable once
 | ||||
|                 // Writtable objects that can't be edited by players
 | ||||
|                 m_itemsAttributes[id]->readable = true; | ||||
|                 fin.read((char*)&m_itemsAttributes[id]->subParam08, 2); | ||||
|                 m_thingsAttributes[id]->readable = true; | ||||
|                 fin.read((char*)&m_thingsAttributes[id]->subParam08, 2); | ||||
|             } | ||||
|             else if(opt == 0x0A) { // Fluid containers
 | ||||
|                 fin.read((char*)&read_byte, 1); | ||||
|                 m_itemsAttributes[id]->group = ITEM_GROUP_FLUID; | ||||
|                 m_thingsAttributes[id]->group = THING_GROUP_FLUID; | ||||
|             } | ||||
|             else if(opt == 0x0B) { // Splashes
 | ||||
|                 m_itemsAttributes[id]->group = ITEM_GROUP_SPLASH; | ||||
|                 m_thingsAttributes[id]->group = THING_GROUP_SPLASH; | ||||
|             } | ||||
|             else if(opt == 0x0C) { // Blocks solid objects (creatures, walls etc)
 | ||||
|                 m_itemsAttributes[id]->blockSolid = true; | ||||
|                 m_thingsAttributes[id]->blockSolid = true; | ||||
|             } | ||||
|             else if(opt == 0x0D) { // Not moveable
 | ||||
|                 m_itemsAttributes[id]->moveable = false; | ||||
|                 m_thingsAttributes[id]->moveable = false; | ||||
|             } | ||||
|             else if(opt == 0x0E) { // Blocks missiles (walls, magic wall etc)
 | ||||
|                 m_itemsAttributes[id]->blockProjectile = true; | ||||
|                 m_thingsAttributes[id]->blockProjectile = true; | ||||
|             } | ||||
|             else if(opt == 0x0F) { // Blocks pathfind algorithms (monsters)
 | ||||
|                 m_itemsAttributes[id]->blockPathFind = true; | ||||
|                 m_thingsAttributes[id]->blockPathFind = true; | ||||
|             } | ||||
|             else if(opt == 0x10) { // Blocks monster movement (flowers, parcels etc)
 | ||||
|                 m_itemsAttributes[id]->pickupable = true; | ||||
|                 m_thingsAttributes[id]->pickupable = true; | ||||
|             } | ||||
|             else if(opt == 0x11) { // Hangable objects (wallpaper etc)
 | ||||
|                 m_itemsAttributes[id]->isHangable = true; | ||||
|                 m_thingsAttributes[id]->isHangable = true; | ||||
|             } | ||||
|             else if(opt == 0x12) { // Horizontal wall
 | ||||
|                 m_itemsAttributes[id]->isHorizontal = true; | ||||
|                 m_thingsAttributes[id]->isHorizontal = true; | ||||
|             } | ||||
|             else if(opt == 0x13) { // Vertical wall
 | ||||
|                 m_itemsAttributes[id]->isVertical = true; | ||||
|                 m_thingsAttributes[id]->isVertical = true; | ||||
|             } | ||||
|             else if(opt == 0x14) { // Rotable
 | ||||
|                 m_itemsAttributes[id]->rotable = true; | ||||
|                 m_thingsAttributes[id]->rotable = true; | ||||
|             } | ||||
|             else if(opt == 0x15) { // Light info
 | ||||
|                 fin.read((char*)&m_itemsAttributes[id]->lightLevel, 2); | ||||
|                 fin.read((char*)&m_itemsAttributes[id]->lightColor, 2); | ||||
|                 fin.read((char*)&m_thingsAttributes[id]->lightLevel, 2); | ||||
|                 fin.read((char*)&m_thingsAttributes[id]->lightColor, 2); | ||||
|             } | ||||
|             else if(opt == 0x16) { | ||||
|             } | ||||
|             else if(opt == 0x17) { // Changes floor
 | ||||
|             } | ||||
|             else if(opt == 0x18) { // Unknown
 | ||||
|                 fin.read((char*)&read_long, 4); | ||||
|             else if(opt == 0x18) { // Thing must be drawed with offset
 | ||||
|                 m_thingsAttributes[id]->hasHeight = true; | ||||
|                 fin.read((char*)&m_thingsAttributes[id]->xOffset, 1); | ||||
|                 fin.read((char*)&m_thingsAttributes[id]->yOffset, 1); | ||||
| 
 | ||||
|                 fin.read((char*)&read_short, 2); | ||||
|             } | ||||
|             else if(opt == 0x19) { // Has height
 | ||||
|                 m_itemsAttributes[id]->hasHeight = true; | ||||
|                 fin.read((char*)&m_itemsAttributes[id]->uheight, 2); | ||||
|             else if(opt == 0x19) { // pixels characters height
 | ||||
| 
 | ||||
|                 fin.read((char*)&m_thingsAttributes[id]->xOffset, 1); | ||||
|                 fin.read((char*)&m_thingsAttributes[id]->yOffset, 1); | ||||
|                 //logDebug((int)m_thingsAttributes[id]->xOffset, " ", (int)m_thingsAttributes[id]->yOffset);
 | ||||
|             } | ||||
|             else if(opt == 0x1A) { | ||||
|                 //m_thingsAttributes[id]->hasHeight = true;
 | ||||
|             } | ||||
|             else if(opt == 0x1B) { | ||||
|             } | ||||
|             else if(opt == 0x1C) { // Minimap color
 | ||||
|                 fin.read((char*)&m_itemsAttributes[id]->miniMapColor, 2); | ||||
|                 m_itemsAttributes[id]->hasMiniMapColor = true; | ||||
|                 fin.read((char*)&m_thingsAttributes[id]->miniMapColor, 2); | ||||
|                 m_thingsAttributes[id]->hasMiniMapColor = true; | ||||
|             } | ||||
|             else if(opt == 0x1D) { // Unknown
 | ||||
|                 fin.read((char*)&read_short, 2); | ||||
|                 if(read_short == 1112) | ||||
|                     m_itemsAttributes[id]->readable = true; | ||||
|                     m_thingsAttributes[id]->readable = true; | ||||
|             } | ||||
|             else if(opt == 0x1E) { | ||||
|             } | ||||
|             else if(opt == 0x1F) { | ||||
|                 m_itemsAttributes[id]->lookThrough = true; | ||||
|                 m_thingsAttributes[id]->lookThrough = true; | ||||
|             } | ||||
|             else if(opt == 0x20) { | ||||
|             } | ||||
|  | @ -153,32 +160,46 @@ bool TibiaDat::load(const std::string& filename) | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         fin.read((char*)&m_itemsAttributes[id]->width, 1); | ||||
|         fin.read((char*)&m_itemsAttributes[id]->height, 1); | ||||
|         if((m_itemsAttributes[id]->width > 1) || (m_itemsAttributes[id]->height > 1)) | ||||
|         fin.read((char*)&m_thingsAttributes[id]->width, 1); | ||||
|         fin.read((char*)&m_thingsAttributes[id]->height, 1); | ||||
|         if((m_thingsAttributes[id]->width > 1) || (m_thingsAttributes[id]->height > 1)) | ||||
|             fin.read((char*)&read_byte, 1); | ||||
| 
 | ||||
|         fin.read((char*)&m_itemsAttributes[id]->blendframes, 1); | ||||
|         fin.read((char*)&m_itemsAttributes[id]->xdiv, 1); | ||||
|         fin.read((char*)&m_itemsAttributes[id]->ydiv, 1); | ||||
|         fin.read((char*)&m_itemsAttributes[id]->zdiv, 1); | ||||
|         fin.read((char*)&m_itemsAttributes[id]->animcount, 1); | ||||
|         fin.read((char*)&m_thingsAttributes[id]->blendframes, 1); | ||||
|         fin.read((char*)&m_thingsAttributes[id]->xdiv, 1); | ||||
|         fin.read((char*)&m_thingsAttributes[id]->ydiv, 1); | ||||
|         fin.read((char*)&m_thingsAttributes[id]->zdiv, 1); | ||||
|         fin.read((char*)&m_thingsAttributes[id]->animcount, 1); | ||||
| 
 | ||||
|         // Read sprites id.
 | ||||
|         uint16 totalSprites = m_itemsAttributes[id]->width * m_itemsAttributes[id]->height * m_itemsAttributes[id]->blendframes * m_itemsAttributes[id]->xdiv * m_itemsAttributes[id]->ydiv * m_itemsAttributes[id]->zdiv * m_itemsAttributes[id]->animcount; | ||||
|         uint16 totalSprites = m_thingsAttributes[id]->width * m_thingsAttributes[id]->height * m_thingsAttributes[id]->blendframes * m_thingsAttributes[id]->xdiv * m_thingsAttributes[id]->ydiv * m_thingsAttributes[id]->zdiv * m_thingsAttributes[id]->animcount; | ||||
| 
 | ||||
|         m_itemsAttributes[id]->sprites = new uint16[totalSprites]; | ||||
|         m_thingsAttributes[id]->sprites = new uint16[totalSprites]; | ||||
|         for(uint16 i = 0; i < totalSprites; i++) { | ||||
|             fin.read((char*)&read_short, 2); | ||||
|             m_itemsAttributes[id]->sprites[i] = read_short-1; | ||||
|             m_thingsAttributes[id]->sprites[i] = read_short-1; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| ItemAttributes *TibiaDat::getItemAttributes(uint16 id) | ||||
| ThingAttributes *TibiaDat::getItemAttributes(uint16 id) | ||||
| { | ||||
|     // items id start at 100.
 | ||||
|     return m_itemsAttributes[id - 100]; | ||||
|     return m_thingsAttributes[id - 100]; | ||||
| } | ||||
| 
 | ||||
| ThingAttributes *TibiaDat::getCreatureAttributes(uint16 id) | ||||
| { | ||||
|     return m_thingsAttributes[id - 1 + m_groupCount[0]]; | ||||
| } | ||||
| 
 | ||||
| ThingAttributes *TibiaDat::getEffectAttributes(uint16 id) | ||||
| { | ||||
|     return m_thingsAttributes[id - 1 + m_groupCount[0] + m_groupCount[1]]; | ||||
| } | ||||
| 
 | ||||
| ThingAttributes *TibiaDat::getShotAttributes(uint16 id) | ||||
| { | ||||
|     return m_thingsAttributes[id - 100 + m_groupCount[0] + m_groupCount[1] + m_groupCount[2]]; | ||||
| } | ||||
|  |  | |||
|  | @ -2,14 +2,17 @@ | |||
| #define TIBIADAT_H | ||||
| 
 | ||||
| #include <global.h> | ||||
| #include "item.h" | ||||
| #include "thing.h" | ||||
| 
 | ||||
| class TibiaDat | ||||
| { | ||||
| public: | ||||
|     bool load(const std::string& filename); | ||||
| 
 | ||||
|     ItemAttributes *getItemAttributes(uint16 id); | ||||
|     ThingAttributes *getItemAttributes(uint16 id); | ||||
|     ThingAttributes *getCreatureAttributes(uint16 id); | ||||
|     ThingAttributes *getEffectAttributes(uint16 id); | ||||
|     ThingAttributes *getShotAttributes(uint16 id); | ||||
| 
 | ||||
|     uint16 getGroupCount(int i) { return m_groupCount[i]; } | ||||
| 
 | ||||
|  | @ -20,7 +23,7 @@ private: | |||
|     uint32 m_signature, m_totalCount; | ||||
|     uint16 m_groupCount[4]; | ||||
| 
 | ||||
|     ItemAttributes **m_itemsAttributes; | ||||
|     ThingAttributes **m_thingsAttributes; | ||||
| }; | ||||
| 
 | ||||
| extern TibiaDat g_tibiaDat; | ||||
|  |  | |||
							
								
								
									
										31
									
								
								src/tile.cpp
								
								
								
								
							
							
						
						
									
										31
									
								
								src/tile.cpp
								
								
								
								
							|  | @ -7,44 +7,43 @@ Tile::Tile() | |||
|     m_ground = NULL; | ||||
| } | ||||
| 
 | ||||
| void Tile::addThing(Thing *thing) | ||||
| void Tile::addThing(ThingPtr thing, uint8 stackpos) | ||||
| { | ||||
|     if(!thing) | ||||
|         return; | ||||
| 
 | ||||
|     if(thing->getType() == Thing::TYPE_ITEM) { | ||||
|         Item *item = thing->getItem(); | ||||
|         if(item) { | ||||
|             ItemAttributes *itemAttributes = g_tibiaDat.getItemAttributes(item->getId()); | ||||
| 
 | ||||
|             if(itemAttributes->group == ITEM_GROUP_GROUND) | ||||
|                 m_ground = item; | ||||
|     ThingAttributes *thingAttributes = thing->getAttributes(); | ||||
|     if(thingAttributes) { | ||||
|         if(thing->getType() == Thing::TYPE_ITEM) { | ||||
|             if(thingAttributes->group == THING_GROUP_GROUND) | ||||
|                 m_ground = thing; | ||||
|             else { | ||||
|                 if(itemAttributes->alwaysOnTop) | ||||
|                 if(thingAttributes->alwaysOnTop) | ||||
|                     m_itemsTop.push_back(thing); | ||||
|                 else | ||||
|                     m_itemsBot.push_back(thing); | ||||
|             } | ||||
|         } | ||||
|         else if(thing->getType() == Thing::TYPE_CREATURE) { | ||||
|             m_creatures.push_back(thing); | ||||
|         } | ||||
|     } | ||||
|     else if(thing->getType() == Thing::TYPE_CREATURE) { | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Tile::draw(int x, int y, int z) | ||||
| void Tile::draw(int x, int y) | ||||
| { | ||||
|     if(m_ground) | ||||
|         m_ground->draw(x, y, z); | ||||
|         m_ground->draw(x, y); | ||||
| 
 | ||||
|     for(auto it = m_itemsTop.begin(), end = m_itemsTop.end(); it != end; ++it) | ||||
|         (*it)->draw(x, y, z); | ||||
|         (*it)->draw(x, y); | ||||
| 
 | ||||
|     for(auto it = m_creatures.begin(), end = m_creatures.end(); it != end; ++it) | ||||
|         (*it)->draw(x, y, z); | ||||
|         (*it)->draw(x, y); | ||||
| 
 | ||||
|     for(auto it = m_itemsBot.begin(), end = m_itemsBot.end(); it != end; ++it) | ||||
|         (*it)->draw(x, y, z); | ||||
|         (*it)->draw(x, y); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										13
									
								
								src/tile.h
								
								
								
								
							
							
						
						
									
										13
									
								
								src/tile.h
								
								
								
								
							|  | @ -3,6 +3,7 @@ | |||
| 
 | ||||
| #include <global.h> | ||||
| #include "thing.h" | ||||
| #include "position.h" | ||||
| 
 | ||||
| class Tile; | ||||
| typedef std::shared_ptr<Tile> TilePtr; | ||||
|  | @ -12,17 +13,17 @@ class Tile | |||
| public: | ||||
|     Tile(); | ||||
| 
 | ||||
|     void addThing(Thing *thing); | ||||
|     void addThing(ThingPtr thing, uint8 stackpos); | ||||
| 
 | ||||
|     void draw(int x, int y, int z); | ||||
|     void draw(int x, int y); | ||||
|     bool hasGround(); | ||||
|     int getStackSize(); | ||||
| 
 | ||||
| private: | ||||
|     Item *m_ground; | ||||
|     std::list<Thing*> m_itemsBot; | ||||
|     std::list<Thing*> m_creatures; | ||||
|     std::list<Thing*> m_itemsTop; | ||||
|     ThingPtr m_ground; | ||||
|     std::list<ThingPtr> m_itemsBot; | ||||
|     std::list<ThingPtr> m_creatures; | ||||
|     std::list<ThingPtr> m_itemsTop; | ||||
| }; | ||||
| 
 | ||||
| #endif // TILE_H
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Eduardo Bart
						Eduardo Bart