attack and follow
This commit is contained in:
parent
320b67e292
commit
7e7050929d
|
@ -37,10 +37,18 @@ 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()
|
||||||
menu:addOption('Message to ' .. creatureThing:getName(), function() print('message') end)
|
menu:addOption('Message to ' .. creatureThing:getName(), function() print('message') end)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue