creature walk, fps fix (map duplicate items fix with clean), some protocol parses

This commit is contained in:
Henrique 2011-08-17 01:45:55 -03:00
parent d4244be464
commit 16a187b014
13 changed files with 421 additions and 115 deletions

View File

@ -24,11 +24,24 @@ public:
void setHealthPercent(uint8 healthPercent) { m_healthPercent = healthPercent; } void setHealthPercent(uint8 healthPercent) { m_healthPercent = healthPercent; }
void setDirection(Direction direction) { m_direction = direction; } void setDirection(Direction direction) { m_direction = direction; }
void setOutfit(const Outfit& outfit) { m_outfit = outfit; } void setOutfit(const Outfit& outfit) { m_outfit = outfit; }
Direction getDirection() { return m_direction; } void setLight(const Light& light) { m_light = light; }
void setSpeed(uint16 speed) { m_speed = speed; }
void setSkull(uint8 skull) { m_skull = skull; }
void setShield(uint8 shield) { m_shield = shield; }
void setEmblem(uint8 emblem) { m_emblem = emblem; }
void setImpassable(bool impassable) { m_impassable = impassable; }
Outfit getOutfit() { return m_outfit; }
std::string getName() { return m_name; } std::string getName() { return m_name; }
uint8 getHealthPercent() { return m_healthPercent; } uint8 getHealthPercent() { return m_healthPercent; }
Direction getDirection() { return m_direction; }
Outfit getOutfit() { return m_outfit; }
Light getLight() { return m_light; }
uint16 getSpeed() { return m_speed; }
uint8 getSkull() { return m_skull; }
uint8 getShield() { return m_shield; }
uint8 getEmblem() { return m_emblem; }
bool getImpassable() { return m_impassable; }
const ThingAttributes& getAttributes(); const ThingAttributes& getAttributes();
CreaturePtr asCreature() { return std::static_pointer_cast<Creature>(shared_from_this()); } CreaturePtr asCreature() { return std::static_pointer_cast<Creature>(shared_from_this()); }
@ -38,6 +51,12 @@ private:
uint8 m_healthPercent; uint8 m_healthPercent;
Direction m_direction; Direction m_direction;
Outfit m_outfit; Outfit m_outfit;
Light m_light;
uint16 m_speed;
uint8 m_skull;
uint8 m_shield;
uint8 m_emblem;
bool m_impassable;
}; };
#endif #endif

View File

@ -16,9 +16,8 @@ void Effect::draw(int x, int y)
if(!m_finished) { if(!m_finished) {
if(g_platform.getTicks() - m_lastTicks > 75) { if(g_platform.getTicks() - m_lastTicks > 75) {
const ThingAttributes& attributes = getAttributes(); const ThingAttributes& attributes = getAttributes();
if(m_animation+1 == attributes.animcount) { if(m_animation+1 == attributes.animcount) {
g_dispatcher.addEvent(std::bind(&Map::removeThing, &g_map, asThing())); //g_dispatcher.addEvent(std::bind(&Map::removeThing, &g_map, asThing()));
m_finished = true; m_finished = true;
} }
else else

View File

@ -42,3 +42,49 @@ void Game::onLogout()
m_localPlayer.reset(); m_localPlayer.reset();
m_online = false; m_online = false;
} }
void Game::walk(Direction direction)
{
if(!m_online)
return;
// TODO: check if we can walk.
m_localPlayer->setDirection(direction);
switch(direction) {
case DIRECTION_NORTH:
m_protocolGame->sendWalkNorth();
break;
case DIRECTION_EAST:
m_protocolGame->sendWalkEast();
break;
case DIRECTION_SOUTH:
m_protocolGame->sendWalkSouth();
break;
case DIRECTION_WEST:
m_protocolGame->sendWalkWest();
break;
}
}
void Game::turn(Direction direction)
{
if(!m_online)
return;
switch(direction) {
case DIRECTION_NORTH:
m_protocolGame->sendTurnNorth();
break;
case DIRECTION_EAST:
m_protocolGame->sendTurnEast();
break;
case DIRECTION_SOUTH:
m_protocolGame->sendTurnSouth();
break;
case DIRECTION_WEST:
m_protocolGame->sendTurnWest();
break;
}
}

View File

@ -19,6 +19,9 @@ public:
void onLogin(); void onLogin();
void onLogout(); void onLogout();
void walk(Direction direction);
void turn(Direction direction);
bool isOnline() { return m_online; } bool isOnline() { return m_online; }
LocalPlayerPtr getLocalPlayer() { return m_localPlayer; } LocalPlayerPtr getLocalPlayer() { return m_localPlayer; }

View File

@ -23,8 +23,8 @@ void Map::draw(int x, int y)
int drawFloorStop = 0; int drawFloorStop = 0;
for(int jz = 6; jz >= 0; --jz) { for(int jz = 6; jz >= 0; --jz) {
Position coverPos = Position(playerPos.x+(7-jz)-1, playerPos.y+(7-jz)-1, jz); Position coverPos = Position(playerPos.x+(7-jz)-1, playerPos.y+(7-jz)-1, jz);
if(m_tiles[coverPos]) { if(const TilePtr& tile = m_tiles[coverPos]) {
if(m_tiles[coverPos]->getStackSize() > 0 && jz < playerPos.z) { if(tile->getStackSize() > 0 && jz < playerPos.z) {
drawFloorStop = jz; drawFloorStop = jz;
break; break;
} }
@ -40,8 +40,8 @@ void Map::draw(int x, int y)
for(int ix = -7+(playerPos.z-iz); ix < + 8+7; ++ix) { for(int ix = -7+(playerPos.z-iz); ix < + 8+7; ++ix) {
for(int iy = -5+(playerPos.z-iz); iy < + 6+7; ++iy) { for(int iy = -5+(playerPos.z-iz); iy < + 6+7; ++iy) {
Position itemPos = Position(playerPos.x + ix, playerPos.y + iy, iz); Position itemPos = Position(playerPos.x + ix, playerPos.y + iy, iz);
if(m_tiles[itemPos]) if(const TilePtr& tile = m_tiles[itemPos])
m_tiles[itemPos]->draw((ix + 7 - (playerPos.z-iz))*32, (iy + 5 - (playerPos.z-iz))*32); tile->draw((ix + 7 - (playerPos.z-iz))*32, (iy + 5 - (playerPos.z-iz))*32);
} }
} }
} }
@ -56,22 +56,52 @@ void Map::draw(int x, int y)
void Map::addThing(ThingPtr thing, uint8 stackpos) void Map::addThing(ThingPtr thing, uint8 stackpos)
{ {
if(!m_tiles[thing->getPosition()]) { TilePtr& tile = m_tiles[thing->getPosition()];
m_tiles[thing->getPosition()] = TilePtr(new Tile()); if(!tile) {
tile = TilePtr(new Tile());
} }
m_tiles[thing->getPosition()]->addThing(thing, stackpos); tile->addThing(thing, stackpos);
// List with effects and shots to update them. if(const CreaturePtr& creature = thing->asCreature())
if(EffectPtr effect = thing->asEffect()) { m_creatures[thing->getId()] = creature;
m_effects.push_back(effect);
}
} }
void Map::removeThing(ThingPtr thing) ThingPtr Map::getThing(const Position& pos, uint8 stackpos)
{ {
if(TilePtr& tile = m_tiles[thing->getPosition()]) { if(const TilePtr& tile = m_tiles[pos]) {
tile->removeThing(thing, 0); return tile->getThing(stackpos);
}
return ThingPtr();
}
void Map::removeThing(const Position& pos, uint8 stackpos)
{
if(TilePtr& tile = m_tiles[pos]) {
tile->removeThing(stackpos);
} }
} }
void Map::clean()
{
m_tiles.clear();
m_creatures.clear();
}
void Map::cleanTile(const Position& pos)
{
if(TilePtr& tile = m_tiles[pos])
tile->clean();
}
CreaturePtr Map::getCreatureById(uint32 id)
{
if(g_game.getLocalPlayer()->getId() == id)
return g_game.getLocalPlayer();
return m_creatures[id];
}
void Map::removeCreatureById(uint32 id)
{
m_creatures.erase(id);
}

View File

@ -2,7 +2,7 @@
#define MAP_H #define MAP_H
#include "tile.h" #include "tile.h"
#include "effect.h" #include "creature.h"
#include <framework/graphics/declarations.h> #include <framework/graphics/declarations.h>
class Map class Map
@ -11,11 +11,24 @@ public:
void draw(int x, int y); void draw(int x, int y);
void addThing(ThingPtr thing, uint8 stackpos = 0); void addThing(ThingPtr thing, uint8 stackpos = 0);
void removeThing(ThingPtr thing); ThingPtr getThing(const Position& pos, uint8 stackpos);
void removeThing(const Position& pos, uint8 stackpos);
void clean();
void cleanTile(const Position& pos);
void setLight(const Light& light) { m_light = light; }
Light getLight() { return m_light; }
CreaturePtr getCreatureById(uint32 id);
void removeCreatureById(uint32 id);
private: private:
std::unordered_map<Position, TilePtr, PositionHasher> m_tiles; std::unordered_map<Position, TilePtr, PositionHasher> m_tiles;
std::list<EffectPtr> m_effects; std::map<uint32, CreaturePtr> m_creatures;
Light m_light;
FrameBufferPtr m_framebuffer; FrameBufferPtr m_framebuffer;
}; };

View File

@ -5,6 +5,12 @@
#include "thingattributes.h" #include "thingattributes.h"
#include <framework/luascript/luaobject.h> #include <framework/luascript/luaobject.h>
struct Light
{
uint8 intensity;
uint8 color;
};
class Thing : public LuaObject class Thing : public LuaObject
{ {
public: public:

View File

@ -1,17 +1,38 @@
#include "tile.h" #include "tile.h"
#include "item.h" #include "item.h"
#include "datmanager.h" #include "datmanager.h"
#include "map.h"
#include "localplayer.h"
Tile::Tile() Tile::Tile()
{ {
} }
void Tile::draw(int x, int y)
{
if(m_ground)
m_ground->draw(x, y);
for(const ThingPtr& thing : m_itemsTop)
thing->draw(x, y);
for(const ThingPtr& thing : m_itemsBottom)
thing->draw(x, y);
for(const ThingPtr& thing : m_creatures)
thing->draw(x, y);
for(const ThingPtr& thing : m_effects)
thing->draw(x, y);
}
void Tile::addThing(ThingPtr thing, uint8 stackpos) void Tile::addThing(ThingPtr thing, uint8 stackpos)
{ {
if(!thing) if(!thing)
return; return;
const ThingAttributes& thingAttributes = thing->getAttributes(); const ThingAttributes& thingAttributes = thing->getAttributes();
if(thing->asItem()) { if(thing->asItem()) {
if(thingAttributes.group == THING_GROUP_GROUND) if(thingAttributes.group == THING_GROUP_GROUND)
m_ground = thing; m_ground = thing;
@ -30,31 +51,63 @@ void Tile::addThing(ThingPtr thing, uint8 stackpos)
} }
} }
void Tile::removeThing(ThingPtr thing, uint8 stackpos) ThingPtr Tile::getThing(uint8 stackpos)
{ {
if(thing->asEffect()) { if(stackpos == 0)
auto it = std::find(m_effects.begin(), m_effects.end(), thing); return m_ground;
assert(it != m_effects.end()); --stackpos;
m_effects.erase(it);
} if(stackpos < m_itemsTop.size())
return m_itemsTop[stackpos];
stackpos -= m_itemsTop.size();
if(stackpos < m_creatures.size())
return m_creatures[stackpos];
stackpos -= m_creatures.size();
if(stackpos < m_itemsBottom.size())
return m_itemsBottom[stackpos];
return ThingPtr();
} }
void Tile::draw(int x, int y) void Tile::removeThing(uint8 stackpos)
{ {
if(m_ground) if(stackpos == 0) {
m_ground->draw(x, y); m_ground.reset();
return;
}
--stackpos;
for(const ThingPtr& thing : m_itemsTop) if(stackpos < m_itemsTop.size()) {
thing->draw(x, y); m_itemsTop.erase(m_itemsTop.begin() + stackpos);
return;
}
stackpos -= m_itemsTop.size();
if(stackpos < m_creatures.size()) {
m_creatures.erase(m_creatures.begin() + stackpos);
return;
}
stackpos -= m_creatures.size();
if(stackpos < m_itemsBottom.size()) {
m_itemsBottom.erase(m_itemsBottom.begin() + stackpos);
return;
}
logDebug("Invalid stackpos.");
}
void Tile::clean()
{
for(const ThingPtr& thing : m_creatures) for(const ThingPtr& thing : m_creatures)
thing->draw(x, y); g_map.removeCreatureById(thing->getId());
for(const ThingPtr& thing : m_itemsBottom) m_itemsTop.clear();
thing->draw(x, y); m_creatures.clear();
m_itemsBottom.clear();
for(const ThingPtr& thing : m_effects) m_effects.clear();
thing->draw(x, y);
} }
int Tile::getStackSize() int Tile::getStackSize()

View File

@ -9,11 +9,14 @@ class Tile : public LuaObject
public: public:
Tile(); Tile();
void addThing(ThingPtr thing, uint8 stackpos);
void removeThing(ThingPtr thing, uint8 stackpos);
void draw(int x, int y); void draw(int x, int y);
void addThing(ThingPtr thing, uint8 stackpos);
ThingPtr getThing(uint8 stackpos);
void removeThing(uint8 stackpos);
void clean();
bool hasGround() { return (!!m_ground); } bool hasGround() { return (!!m_ground); }
int getStackSize(); int getStackSize();

View File

@ -25,6 +25,10 @@ public:
void sendWalkEast(); void sendWalkEast();
void sendWalkSouth(); void sendWalkSouth();
void sendWalkWest(); void sendWalkWest();
void sendTurnNorth();
void sendTurnEast();
void sendTurnSouth();
void sendTurnWest();
private: private:
void sendLoginPacket(uint32 timestamp, uint8 unknown); void sendLoginPacket(uint32 timestamp, uint8 unknown);

View File

@ -10,6 +10,8 @@ void ProtocolGame::parseMessage(InputMessage& msg)
{ {
while(!msg.eof()) { while(!msg.eof()) {
uint8 opt = msg.getU8(); uint8 opt = msg.getU8();
//dump << "protocol id:" << std::hex << (int)opt;
switch(opt) { switch(opt) {
case 0x0A: case 0x0A:
parsePlayerLogin(msg); parsePlayerLogin(msg);
@ -283,88 +285,119 @@ void ProtocolGame::parseCanReportBugs(InputMessage& msg)
void ProtocolGame::parseMapDescription(InputMessage& msg) void ProtocolGame::parseMapDescription(InputMessage& msg)
{ {
Position pos = parsePosition(msg); Position pos = parsePosition(msg);
setMapDescription(msg, pos.x - 8, pos.y - 6, pos.z, 18, 14);
m_localPlayer->setPosition(pos); m_localPlayer->setPosition(pos);
// we must clean, creatures and all.
g_map.clean();
// now we get new map.
setMapDescription(msg, pos.x - 8, pos.y - 6, pos.z, 18, 14);
} }
void ProtocolGame::parseMoveNorth(InputMessage& msg) void ProtocolGame::parseMoveNorth(InputMessage& msg)
{ {
Position pos = m_localPlayer->getPosition(); Position pos = m_localPlayer->getPosition();
pos.y--;
setMapDescription(msg, pos.x - 8, pos.y - 6, pos.z, 18, 1); setMapDescription(msg, pos.x - 8, pos.y - 6, pos.z, 18, 1);
m_localPlayer->setPosition(pos);
} }
void ProtocolGame::parseMoveEast(InputMessage& msg) void ProtocolGame::parseMoveEast(InputMessage& msg)
{ {
Position pos = m_localPlayer->getPosition(); Position pos = m_localPlayer->getPosition();
pos.x++;
setMapDescription(msg, pos.x + 9, pos.y - 6, pos.z, 1, 14); setMapDescription(msg, pos.x + 9, pos.y - 6, pos.z, 1, 14);
m_localPlayer->setPosition(pos);
} }
void ProtocolGame::parseMoveSouth(InputMessage& msg) void ProtocolGame::parseMoveSouth(InputMessage& msg)
{ {
Position pos = m_localPlayer->getPosition(); Position pos = m_localPlayer->getPosition();
pos.y++;
setMapDescription(msg, pos.x - 8, pos.y + 7, pos.z, 18, 1); setMapDescription(msg, pos.x - 8, pos.y + 7, pos.z, 18, 1);
m_localPlayer->setPosition(pos);
} }
void ProtocolGame::parseMoveWest(InputMessage& msg) void ProtocolGame::parseMoveWest(InputMessage& msg)
{ {
Position pos = m_localPlayer->getPosition(); Position pos = m_localPlayer->getPosition();
pos.x--;
setMapDescription(msg, pos.x - 8, pos.y - 6, pos.z, 1, 14); setMapDescription(msg, pos.x - 8, pos.y - 6, pos.z, 1, 14);
m_localPlayer->setPosition(pos);
} }
void ProtocolGame::parseUpdateTile(InputMessage& msg) void ProtocolGame::parseUpdateTile(InputMessage& msg)
{ {
logDebug("PARSE UPDATE TILE!");
Position tilePos = parsePosition(msg); Position tilePos = parsePosition(msg);
uint16 thingId = msg.getU16(true); uint16 thingId = msg.getU16(true);
if(thingId == 0xFF01) { if(thingId == 0xFF01) {
msg.getU16(); msg.getU16();
/*msg->AddByte(0);
msg->AddByte(0xFF);*/
} }
else { else {
setTileDescription(msg, tilePos); setTileDescription(msg, tilePos);
msg.getU16(); msg.getU16();
/*msg->AddByte(0x01);
msg->AddByte(0xFF);*/
} }
} }
void ProtocolGame::parseTileAddThing(InputMessage& msg) void ProtocolGame::parseTileAddThing(InputMessage& msg)
{ {
parsePosition(msg); // tilePos Position pos = parsePosition(msg);
msg.getU8(); // stackPos uint8 stackpos = msg.getU8();
internalGetThing(msg);
ThingPtr thing = internalGetThing(msg);
thing->setPosition(pos);
g_map.addThing(thing, stackpos);
} }
void ProtocolGame::parseTileTransformThing(InputMessage& msg) void ProtocolGame::parseTileTransformThing(InputMessage& msg)
{ {
parsePosition(msg); // tilePos Position pos = parsePosition(msg);
msg.getU8(); // stackPos uint8 stackpos = msg.getU8();
uint16 thingId = msg.getU16(); uint16 thingId = msg.getU16();
if(thingId == 0x0061 || thingId == 0x0062 || thingId == 0x0063) { if(thingId == 0x0061 || thingId == 0x0062 || thingId == 0x0063) {
msg.getU32(); // creatureId parseCreatureTurn(msg);
msg.getU8(); // direction
} }
else { else {
internalGetItem(msg, thingId); ThingPtr thing = internalGetItem(msg, thingId);
thing->setPosition(pos);
g_map.removeThing(pos, stackpos);
g_map.addThing(thing, stackpos);
} }
} }
void ProtocolGame::parseTileRemoveThing(InputMessage& msg) void ProtocolGame::parseTileRemoveThing(InputMessage& msg)
{ {
parsePosition(msg); // tilePos Position pos = parsePosition(msg);
msg.getU8(); // stackPos uint8 stackpos = msg.getU8();
g_map.removeThing(pos, stackpos);
} }
void ProtocolGame::parseCreatureMove(InputMessage& msg) void ProtocolGame::parseCreatureMove(InputMessage& msg)
{ {
parsePosition(msg); // oldPos Position oldPos = parsePosition(msg);
msg.getU8(); // oldStackPos uint8 oldStackpos = msg.getU8();
parsePosition(msg); // newPos Position newPos = parsePosition(msg);
ThingPtr thing = g_map.getThing(oldPos, oldStackpos);
if(thing) {
g_map.removeThing(oldPos, oldStackpos);
thing->setPosition(newPos);
g_map.addThing(thing);
}
CreaturePtr creature = thing->asCreature();
if(creature) {
if(oldPos + Position(0, -1, 0) == newPos)
creature->setDirection(DIRECTION_NORTH);
else if(oldPos + Position(1, 0, 0) == newPos)
creature->setDirection(DIRECTION_EAST);
else if(oldPos + Position(0, 1, 0) == newPos)
creature->setDirection(DIRECTION_SOUTH);
else if(oldPos + Position(-1, 0, 0) == newPos)
creature->setDirection(DIRECTION_WEST);
}
} }
void ProtocolGame::parseOpenContainer(InputMessage& msg) void ProtocolGame::parseOpenContainer(InputMessage& msg)
@ -458,8 +491,11 @@ void ProtocolGame::parseSafeTradeClose(InputMessage&)
void ProtocolGame::parseWorldLight(InputMessage& msg) void ProtocolGame::parseWorldLight(InputMessage& msg)
{ {
msg.getU8(); // level Light light;
msg.getU8(); // color light.intensity = msg.getU8();
light.color = msg.getU8();
g_map.setLight(light);
} }
void ProtocolGame::parseMagicEffect(InputMessage& msg) void ProtocolGame::parseMagicEffect(InputMessage& msg)
@ -493,45 +529,75 @@ void ProtocolGame::parseCreatureSquare(InputMessage& msg)
void ProtocolGame::parseCreatureHealth(InputMessage& msg) void ProtocolGame::parseCreatureHealth(InputMessage& msg)
{ {
msg.getU32(); // creatureId uint32 id = msg.getU32();
msg.getU8(); // percent uint8 healthPercent = msg.getU8();
CreaturePtr creature = g_map.getCreatureById(id);
if(creature)
creature->setHealthPercent(healthPercent);
} }
void ProtocolGame::parseCreatureLight(InputMessage& msg) void ProtocolGame::parseCreatureLight(InputMessage& msg)
{ {
msg.getU32(); // creature id uint32 id = msg.getU32();
msg.getU8(); // level
msg.getU8(); // color Light light;
light.intensity = msg.getU8();
light.color = msg.getU8();
CreaturePtr creature = g_map.getCreatureById(id);
if(creature)
creature->setLight(light);
} }
void ProtocolGame::parseCreatureOutfit(InputMessage& msg) void ProtocolGame::parseCreatureOutfit(InputMessage& msg)
{ {
msg.getU32(); // creature id uint32 id = msg.getU32();
internalGetOutfit(msg); Outfit outfit = internalGetOutfit(msg);
CreaturePtr creature = g_map.getCreatureById(id);
if(creature)
creature->setOutfit(outfit);
} }
void ProtocolGame::parseCreatureSpeed(InputMessage& msg) void ProtocolGame::parseCreatureSpeed(InputMessage& msg)
{ {
msg.getU32(); // creature id uint32 id = msg.getU32();
msg.getU16(); // speed uint16 speed = msg.getU16();
CreaturePtr creature = g_map.getCreatureById(id);
if(creature)
creature->setSpeed(speed);
} }
void ProtocolGame::parseCreatureSkulls(InputMessage& msg) void ProtocolGame::parseCreatureSkulls(InputMessage& msg)
{ {
msg.getU32(); // creature id uint32 id = msg.getU32();
msg.getU8(); // skull uint8 skull = msg.getU8();
CreaturePtr creature = g_map.getCreatureById(id);
if(creature)
creature->setSkull(skull);
} }
void ProtocolGame::parseCreatureShields(InputMessage& msg) void ProtocolGame::parseCreatureShields(InputMessage& msg)
{ {
msg.getU32(); // creature id uint32 id = msg.getU32();
msg.getU8(); // shield uint8 shield = msg.getU8();
CreaturePtr creature = g_map.getCreatureById(id);
if(creature)
creature->setShield(shield);
} }
void ProtocolGame::parseCreatureTurn(InputMessage& msg) void ProtocolGame::parseCreatureTurn(InputMessage& msg)
{ {
msg.getU32(); // creature id uint32 id = msg.getU32();
msg.getU8(); // direction Direction direction = (Direction)msg.getU8();
CreaturePtr creature = g_map.getCreatureById(id);
if(creature)
creature->setDirection(direction);
} }
void ProtocolGame::parseItemTextWindow(InputMessage& msg) void ProtocolGame::parseItemTextWindow(InputMessage& msg)
@ -694,7 +760,8 @@ void ProtocolGame::parseTextMessage(InputMessage& msg)
void ProtocolGame::parseCancelWalk(InputMessage& msg) void ProtocolGame::parseCancelWalk(InputMessage& msg)
{ {
msg.getU8(); // direction Direction direction = (Direction)msg.getU8();
g_game.getLocalPlayer()->setDirection(direction);
} }
void ProtocolGame::parseFloorChangeUp(InputMessage& msg) void ProtocolGame::parseFloorChangeUp(InputMessage& msg)
@ -709,16 +776,15 @@ void ProtocolGame::parseFloorChangeUp(InputMessage& msg)
else if(m_localPlayer->getPosition().z > 7) else if(m_localPlayer->getPosition().z > 7)
setFloorDescription(msg, pos.x - 8, pos.y - 6, pos.z - 2, 18, 14, 3, &skip); setFloorDescription(msg, pos.x - 8, pos.y - 6, pos.z - 2, 18, 14, 3, &skip);
pos.x++; //pos.x++;
pos.y++; //pos.y++;
//m_localPlayer->setPosition(pos);
m_localPlayer->setPosition(pos);
} }
void ProtocolGame::parseFloorChangeDown(InputMessage& msg) void ProtocolGame::parseFloorChangeDown(InputMessage& msg)
{ {
Position pos = m_localPlayer->getPosition(); Position pos = m_localPlayer->getPosition();
pos.z++; //pos.z++;
int skip = 0; int skip = 0;
if(pos.z == 8) { if(pos.z == 8) {
@ -729,10 +795,9 @@ void ProtocolGame::parseFloorChangeDown(InputMessage& msg)
else if(pos.z > 8 && pos.z < 14) else if(pos.z > 8 && pos.z < 14)
setFloorDescription(msg, pos.x - 8, pos.y - 6, pos.z + 2, 18, 14, -3, &skip); setFloorDescription(msg, pos.x - 8, pos.y - 6, pos.z + 2, 18, 14, -3, &skip);
pos.x--; //pos.x--;
pos.y--; //pos.y--;
//m_localPlayer->setPosition(pos);
m_localPlayer->setPosition(pos);
} }
void ProtocolGame::parseOutfitWindow(InputMessage& msg) void ProtocolGame::parseOutfitWindow(InputMessage& msg)
@ -840,14 +905,15 @@ void ProtocolGame::setFloorDescription(InputMessage& msg, int32 x, int32 y, int3
void ProtocolGame::setTileDescription(InputMessage& msg, Position position) void ProtocolGame::setTileDescription(InputMessage& msg, Position position)
{ {
g_map.cleanTile(position);
int stackpos = 0; int stackpos = 0;
while(1){ while(1){
stackpos++;
uint16 inspectTileId = msg.getU16(true); uint16 inspectTileId = msg.getU16(true);
if(inspectTileId >= 0xFF00) if(inspectTileId >= 0xFF00)
return; return;
else { else {
if(stackpos > 10) { if(stackpos >= 10) {
logDebug("[ProtocolGame::setTileDescription] Too many things!."); logDebug("[ProtocolGame::setTileDescription] Too many things!.");
return; return;
} }
@ -857,6 +923,7 @@ void ProtocolGame::setTileDescription(InputMessage& msg, Position position)
thing->setPosition(position); thing->setPosition(position);
g_map.addThing(thing, stackpos); g_map.addThing(thing, stackpos);
} }
stackpos++;
} }
} }
@ -888,26 +955,52 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg)
CreaturePtr creature = CreaturePtr(new Creature); CreaturePtr creature = CreaturePtr(new Creature);
if(thingId == 0x0062) { //creature is known if(thingId == 0x0062) { //creature is known
creature->setId(msg.getU32()); uint32 id = msg.getU32();
CreaturePtr knownCreature = g_map.getCreatureById(id);
if(knownCreature)
creature = knownCreature;
} }
else if(thingId == 0x0061) { //creature is not known else if(thingId == 0x0061) { //creature is not known
msg.getU32(); // remove id /*uint32 removeId = */msg.getU32();
creature->setId(msg.getU32()); uint32 id = msg.getU32();
creature->setName(msg.getString()); std::string name = msg.getString();
LocalPlayerPtr localPlayer = g_game.getLocalPlayer();
if(localPlayer->getId() == id)
creature = localPlayer->asCreature();
creature->setId(id);
creature->setName(name);
} }
creature->setHealthPercent(msg.getU8()); uint8 healthPercent = msg.getU8();
creature->setDirection((Direction)msg.getU8()); Direction direction = (Direction)msg.getU8();
creature->setOutfit(internalGetOutfit(msg)); Outfit outfit = internalGetOutfit(msg);
msg.getU8(); // light level
msg.getU8(); // light color
msg.getU16(); // speed
msg.getU8(); // skull
msg.getU8(); // shield
Light light;
light.intensity = msg.getU8();
light.color = msg.getU8();
uint16 speed = msg.getU16();
uint8 skull = msg.getU8();
uint8 shield = msg.getU8();
uint8 emblem = 0;
if(thingId == 0x0061) // emblem is sent only in packet type 0x61 if(thingId == 0x0061) // emblem is sent only in packet type 0x61
msg.getU8(); emblem = msg.getU8();
msg.getU8(); // impassable
bool impassable = (msg.getU8() == 0); // impassable
creature->setHealthPercent(healthPercent);
creature->setDirection(direction);
creature->setOutfit(outfit);
creature->setLight(light);
creature->setSpeed(speed);
creature->setSkull(skull);
creature->setShield(shield);
creature->setEmblem(emblem);
creature->setImpassable(impassable);
thing = creature; thing = creature;
@ -930,9 +1023,8 @@ ItemPtr ProtocolGame::internalGetItem(InputMessage& msg, uint16 id)
item->setId(id); item->setId(id);
const ThingAttributes& itemAttributes = g_dat.getItemAttributes(id); const ThingAttributes& itemAttributes = g_dat.getItemAttributes(id);
if(itemAttributes.stackable || itemAttributes.group == THING_GROUP_FLUID || itemAttributes.group == THING_GROUP_SPLASH) { if(itemAttributes.stackable || itemAttributes.group == THING_GROUP_FLUID || itemAttributes.group == THING_GROUP_SPLASH)
item->setCount(msg.getU8()); item->setCount(msg.getU8());
}
return item; return item;
} }

View File

@ -80,3 +80,32 @@ void ProtocolGame::sendWalkWest()
send(oMsg); send(oMsg);
} }
void ProtocolGame::sendTurnNorth()
{
OutputMessage oMsg;
oMsg.addU8(0x6F);
send(oMsg);
}
void ProtocolGame::sendTurnEast()
{
OutputMessage oMsg;
oMsg.addU8(0x70);
send(oMsg);
}
void ProtocolGame::sendTurnSouth()
{
OutputMessage oMsg;
oMsg.addU8(0x71);
send(oMsg);
}
void ProtocolGame::sendTurnWest()
{
OutputMessage oMsg;
oMsg.addU8(0x72);
send(oMsg);
}

View File

@ -272,17 +272,26 @@ void OTClient::onPlatformEvent(const PlatformEvent& event)
{ {
g_ui.inputEvent(event); g_ui.inputEvent(event);
ProtocolGamePtr protocol = g_game.getProtocolGame();
if(protocol) {
if(event.type == EventKeyDown) { if(event.type == EventKeyDown) {
if(!event.ctrl) {
if(event.keycode == KC_UP) if(event.keycode == KC_UP)
protocol->sendWalkNorth(); g_game.walk(DIRECTION_NORTH);
if(event.keycode == KC_RIGHT) if(event.keycode == KC_RIGHT)
protocol->sendWalkEast(); g_game.walk(DIRECTION_EAST);
if(event.keycode == KC_DOWN) if(event.keycode == KC_DOWN)
protocol->sendWalkSouth(); g_game.walk(DIRECTION_SOUTH);
if(event.keycode == KC_LEFT) if(event.keycode == KC_LEFT)
protocol->sendWalkWest(); g_game.walk(DIRECTION_WEST);
}
else {
if(event.keycode == KC_UP)
g_game.turn(DIRECTION_NORTH);
if(event.keycode == KC_RIGHT)
g_game.turn(DIRECTION_EAST);
if(event.keycode == KC_DOWN)
g_game.turn(DIRECTION_SOUTH);
if(event.keycode == KC_LEFT)
g_game.turn(DIRECTION_WEST);
} }
} }
} }