attack and follow

This commit is contained in:
Henrique Santiago 2012-01-05 12:24:38 -02:00
parent 320b67e292
commit 7e7050929d
7 changed files with 101 additions and 13 deletions

View File

@ -37,9 +37,17 @@ function Game.createThingMenu(menuPosition, lookThing, useThing, creatureThing)
if creatureThing:asLocalPlayer() then if creatureThing:asLocalPlayer() then
menu:addOption('Set Outfit', function() Game.openOutfitWindow() end) menu:addOption('Set Outfit', function() Game.openOutfitWindow() end)
else else
-- todo: check for stop attack/follow if Game.getAttackingCreature() ~= creatureThing then
menu:addOption('Attack', function() Game.attack(creatureThing) end) menu:addOption('Attack', function() Game.attack(creatureThing) end)
menu:addOption('Follow', function() Game.follow(creatureThing)end) else
menu:addOption('Stop Attack', function() Game.cancelAttack() end)
end
if Game.getFollowingCreature() ~= creatureThing then
menu:addOption('Follow', function() Game.follow(creatureThing) end)
else
menu:addOption('Stop Follow', function() Game.cancelFollow() end)
end
if creatureThing:asPlayer() then if creatureThing:asPlayer() then
menu:addSeparator() menu:addSeparator()

View File

@ -39,7 +39,8 @@
Creature::Creature() : Thing() Creature::Creature() : Thing()
{ {
m_healthPercent = 0; m_healthPercent = 0;
m_showSquareColor = false; m_showVolatileSquare = false;
m_showStaticSquare = false;
m_direction = Otc::South; m_direction = Otc::South;
m_walkTimePerPixel = 1000.0/32.0; m_walkTimePerPixel = 1000.0/32.0;
@ -58,12 +59,17 @@ int MASK_TEXTURE_UNIFORM = 14;
void Creature::draw(const Point& p) void Creature::draw(const Point& p)
{ {
// TODO: activate on attack, follow, discover how 'attacked' works if(m_showVolatileSquare) {
if(m_showSquareColor) { g_painter.setColor(m_volatileSquareColor);
g_painter.setColor(Outfit::getColor(m_squareColor)); g_painter.drawBoundingRect(Rect(p + m_walkOffset - Point(m_type->parameters[ThingType::DisplacementX], m_type->parameters[ThingType::DisplacementY]) + 3, Size(28, 28)), 2);
g_painter.drawBoundingRect(Rect(p + m_walkOffset - 8, Size(32, 32)), 2);
} }
if(m_showStaticSquare) {
g_painter.setColor(m_staticSquareColor);
g_painter.drawBoundingRect(Rect(p + m_walkOffset - Point(m_type->parameters[ThingType::DisplacementX], m_type->parameters[ThingType::DisplacementY]) + 1, Size(32, 32)), 2);
}
g_painter.setColor(Fw::white);
if(!outfitProgram) { if(!outfitProgram) {
outfitProgram = PainterShaderProgramPtr(new PainterShaderProgram); outfitProgram = PainterShaderProgramPtr(new PainterShaderProgram);
outfitProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader); outfitProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
@ -319,6 +325,18 @@ void Creature::setOutfit(const Outfit& outfit)
m_outfit.resetClothes(); m_outfit.resetClothes();
} }
void Creature::addVolatileSquare(uint8 color)
{
m_showVolatileSquare = true;
m_volatileSquareColor = Color::from8bit(color);
// schedule removal
auto self = asCreature();
g_dispatcher.scheduleEvent([self]() {
self->removeVolatileSquare();
}, VOLATILE_SQUARE_DURATION);
}
ThingType *Creature::getType() ThingType *Creature::getType()
{ {
return g_thingsType.getThingType(m_outfit.getType(), ThingsType::Creature); return g_thingsType.getThingType(m_outfit.getType(), ThingsType::Creature);

View File

@ -30,6 +30,10 @@
class Creature : public Thing class Creature : public Thing
{ {
public: public:
enum {
VOLATILE_SQUARE_DURATION = 1000
};
Creature(); Creature();
virtual ~Creature() { } virtual ~Creature() { }
@ -46,7 +50,12 @@ public:
void setShield(uint8 shield) { m_shield = shield; } void setShield(uint8 shield) { m_shield = shield; }
void setEmblem(uint8 emblem) { m_emblem = emblem; } void setEmblem(uint8 emblem) { m_emblem = emblem; }
void setPassable(bool passable) { m_passable = passable; } void setPassable(bool passable) { m_passable = passable; }
void setSquareColor(uint8 squareColor) { m_squareColor = squareColor; }
void addVolatileSquare(uint8 color);
void removeVolatileSquare() { m_showVolatileSquare = false; }
void activateStaticSquare(const Color& color) { m_showStaticSquare = true; m_staticSquareColor = color; }
void deactivateStaticSquare() { m_showStaticSquare = false; }
std::string getName() { return m_name; } std::string getName() { return m_name; }
uint8 getHealthPercent() { return m_healthPercent; } uint8 getHealthPercent() { return m_healthPercent; }
@ -83,8 +92,8 @@ protected:
uint8 m_shield; uint8 m_shield;
uint8 m_emblem; uint8 m_emblem;
bool m_passable; bool m_passable;
uint8 m_squareColor; Color m_volatileSquareColor, m_staticSquareColor;
bool m_showSquareColor; bool m_showVolatileSquare, m_showStaticSquare;
FontPtr m_informationFont; FontPtr m_informationFont;
Color m_informationColor; Color m_informationColor;

View File

@ -109,6 +109,8 @@ void Game::walk(Otc::Direction direction)
if(!m_online || !m_localPlayer->canWalk(direction) || !g_ui.isOnInputEvent()) if(!m_online || !m_localPlayer->canWalk(direction) || !g_ui.isOnInputEvent())
return; return;
cancelFollow();
m_localPlayer->clientWalk(direction); m_localPlayer->clientWalk(direction);
switch(direction) { switch(direction) {
@ -185,17 +187,55 @@ void Game::attack(const CreaturePtr& creature)
if(!m_online || !creature || !g_ui.isOnInputEvent()) if(!m_online || !creature || !g_ui.isOnInputEvent())
return; return;
if(m_attackingCreature)
m_attackingCreature->deactivateStaticSquare();
creature->activateStaticSquare(Fw::red);
m_attackingCreature = creature;
m_protocolGame->sendAttack(creature->getId()); m_protocolGame->sendAttack(creature->getId());
} }
void Game::cancelAttack()
{
if(m_attackingCreature) {
m_protocolGame->sendAttack(0);
m_attackingCreature->deactivateStaticSquare();
m_attackingCreature = nullptr;
}
}
void Game::onAttackCancelled()
{
if(m_attackingCreature) {
m_attackingCreature->deactivateStaticSquare();
m_attackingCreature = nullptr;
}
}
void Game::follow(const CreaturePtr& creature) void Game::follow(const CreaturePtr& creature)
{ {
if(!m_online || !creature || !g_ui.isOnInputEvent()) if(!m_online || !creature || !g_ui.isOnInputEvent())
return; return;
if(m_followingCreature)
m_followingCreature->deactivateStaticSquare();
creature->activateStaticSquare(Fw::green);
m_followingCreature = creature;
m_protocolGame->sendFollow(creature->getId()); m_protocolGame->sendFollow(creature->getId());
} }
void Game::cancelFollow()
{
if(m_followingCreature) {
m_protocolGame->sendFollow(0);
m_followingCreature->deactivateStaticSquare();
m_followingCreature = nullptr;
}
}
void Game::rotate(const ThingPtr& thing) void Game::rotate(const ThingPtr& thing)
{ {
if(!m_online || !thing || !g_ui.isOnInputEvent()) if(!m_online || !thing || !g_ui.isOnInputEvent())

View File

@ -51,7 +51,9 @@ public:
void look(const ThingPtr& thing); void look(const ThingPtr& thing);
void use(const ThingPtr& thing); void use(const ThingPtr& thing);
void attack(const CreaturePtr& creature); void attack(const CreaturePtr& creature);
void cancelAttack();
void follow(const CreaturePtr& creature); void follow(const CreaturePtr& creature);
void cancelFollow();
void rotate(const ThingPtr& thing); void rotate(const ThingPtr& thing);
void talkChannel(int channelType, int channelId, const std::string& message); void talkChannel(int channelType, int channelId, const std::string& message);
void talkPrivate(int channelType, const std::string& receiver, const std::string& message); void talkPrivate(int channelType, const std::string& receiver, const std::string& message);
@ -61,6 +63,10 @@ public:
void addVip(const std::string& name); void addVip(const std::string& name);
void removeVip(int playerId); void removeVip(int playerId);
int getThingStackpos(const ThingPtr& thing); int getThingStackpos(const ThingPtr& thing);
void onAttackCancelled();
CreaturePtr getAttackingCreature() { return m_attackingCreature; }
CreaturePtr getFollowingCreature() { return m_followingCreature; }
bool isOnline() { return m_online; } bool isOnline() { return m_online; }
@ -75,6 +81,8 @@ private:
ProtocolGamePtr m_protocolGame; ProtocolGamePtr m_protocolGame;
bool m_online; bool m_online;
int m_serverBeat; int m_serverBeat;
CreaturePtr m_attackingCreature, m_followingCreature;
}; };
extern Game g_game; extern Game g_game;

View File

@ -73,11 +73,15 @@ void OTClient::registerLuaFunctions()
g_lua.bindClassStaticFunction<Game>("look", std::bind(&Game::look, &g_game, _1)); g_lua.bindClassStaticFunction<Game>("look", std::bind(&Game::look, &g_game, _1));
g_lua.bindClassStaticFunction<Game>("use", std::bind(&Game::use, &g_game, _1)); g_lua.bindClassStaticFunction<Game>("use", std::bind(&Game::use, &g_game, _1));
g_lua.bindClassStaticFunction<Game>("attack", std::bind(&Game::attack, &g_game, _1)); g_lua.bindClassStaticFunction<Game>("attack", std::bind(&Game::attack, &g_game, _1));
g_lua.bindClassStaticFunction<Game>("cancelAttack", std::bind(&Game::cancelAttack, &g_game));
g_lua.bindClassStaticFunction<Game>("follow", std::bind(&Game::follow, &g_game, _1)); g_lua.bindClassStaticFunction<Game>("follow", std::bind(&Game::follow, &g_game, _1));
g_lua.bindClassStaticFunction<Game>("cancelFollow", std::bind(&Game::cancelFollow, &g_game));
g_lua.bindClassStaticFunction<Game>("rotate", std::bind(&Game::rotate, &g_game, _1)); g_lua.bindClassStaticFunction<Game>("rotate", std::bind(&Game::rotate, &g_game, _1));
g_lua.bindClassStaticFunction<Game>("inviteToParty", std::bind(&Game::inviteToParty, &g_game, _1)); g_lua.bindClassStaticFunction<Game>("inviteToParty", std::bind(&Game::inviteToParty, &g_game, _1));
g_lua.bindClassStaticFunction<Game>("addVip", std::bind(&Game::addVip, &g_game, _1)); g_lua.bindClassStaticFunction<Game>("addVip", std::bind(&Game::addVip, &g_game, _1));
g_lua.bindClassStaticFunction<Game>("removeVip", std::bind(&Game::removeVip, &g_game, _1)); g_lua.bindClassStaticFunction<Game>("removeVip", std::bind(&Game::removeVip, &g_game, _1));
g_lua.bindClassStaticFunction<Game>("getAttackingCreature", std::bind(&Game::getAttackingCreature, &g_game));
g_lua.bindClassStaticFunction<Game>("getFollowingCreature", std::bind(&Game::getFollowingCreature, &g_game));
g_lua.registerClass<UIItem, UIWidget>(); g_lua.registerClass<UIItem, UIWidget>();
g_lua.bindClassStaticFunction<UIItem>("create", &UIItem::create<UIItem>); g_lua.bindClassStaticFunction<UIItem>("create", &UIItem::create<UIItem>);

View File

@ -573,7 +573,7 @@ void ProtocolGame::parseCreatureSquare(InputMessage& msg)
CreaturePtr creature = g_map.getCreatureById(id); CreaturePtr creature = g_map.getCreatureById(id);
if(creature) if(creature)
creature->setSquareColor(color); creature->addVolatileSquare(color);
} }
void ProtocolGame::parseCreatureHealth(InputMessage& msg) void ProtocolGame::parseCreatureHealth(InputMessage& msg)
@ -735,7 +735,8 @@ void ProtocolGame::parsePlayerIcons(InputMessage& msg)
void ProtocolGame::parsePlayerCancelAttack(InputMessage& msg) void ProtocolGame::parsePlayerCancelAttack(InputMessage& msg)
{ {
msg.getU32(); msg.getU32(); // unknown
g_game.onAttackCancelled();
} }
void ProtocolGame::parseCreatureSpeak(InputMessage& msg) void ProtocolGame::parseCreatureSpeak(InputMessage& msg)