introduce extra melee attack for walking monsters to prevent 'kite'

This commit is contained in:
ErikasKontenis 2020-04-27 17:15:19 +03:00
parent e6fbf4a654
commit 24a3e9b18c
5 changed files with 69 additions and 4 deletions

View File

@ -607,8 +607,13 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos
} else { } else {
if (hasExtraSwing()) { if (hasExtraSwing()) {
//our target is moving lets see if we can get in hit //our target is moving lets see if we can get in hit
if (getMonster()) {
g_dispatcher.addTask(createTask(std::bind(&Game::checkMonsterExtraAttack, &g_game, getID())));
}
else {
g_dispatcher.addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game, getID()))); g_dispatcher.addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game, getID())));
} }
}
if (newTile->getZone() != oldTile->getZone()) { if (newTile->getZone() != oldTile->getZone()) {
onAttackedCreatureChangeZone(attackedCreature->getZone()); onAttackedCreatureChangeZone(attackedCreature->getZone());

View File

@ -3205,6 +3205,16 @@ void Game::checkCreatureAttack(uint32_t creatureId)
} }
} }
void Game::checkMonsterExtraAttack(uint32_t creatureId)
{
Creature* creature = getCreatureByID(creatureId);
if (creature && creature->getHealth() > 0) {
if (Monster* monster = creature->getMonster()) {
monster->doExtraMeleeAttack();
}
}
}
void Game::addCreatureCheck(Creature* creature) void Game::addCreatureCheck(Creature* creature)
{ {
creature->creatureCheck = true; creature->creatureCheck = true;

View File

@ -435,6 +435,7 @@ class Game
void checkCreatureWalk(uint32_t creatureId); void checkCreatureWalk(uint32_t creatureId);
void updateCreatureWalk(uint32_t creatureId); void updateCreatureWalk(uint32_t creatureId);
void checkCreatureAttack(uint32_t creatureId); void checkCreatureAttack(uint32_t creatureId);
void checkMonsterExtraAttack(uint32_t creatureId);
void checkCreatures(size_t index); void checkCreatures(size_t index);
void checkLight(); void checkLight();

View File

@ -119,6 +119,11 @@ void Monster::onAttackedCreature(Creature* creature)
} }
} }
void Monster::onAttackedCreatureDisappear(bool)
{
extraMeleeAttack = true;
}
void Monster::onCreatureAppear(Creature* creature, bool isLogin) void Monster::onCreatureAppear(Creature* creature, bool isLogin)
{ {
Creature::onCreatureAppear(creature, isLogin); Creature::onCreatureAppear(creature, isLogin);
@ -855,6 +860,36 @@ void Monster::onThink(uint32_t interval)
} }
} }
void Monster::doExtraMeleeAttack()
{
if (!attackedCreature || (isSummon() && attackedCreature == this)) {
return;
}
bool updateLook = false;
bool isCloseAttack = false;
if (OTSYS_TIME() >= earliestAttackTime && !isFleeing()) {
updateLook = true;
isCloseAttack = Combat::closeAttack(this, attackedCreature, FIGHTMODE_BALANCED);
if (isCloseAttack) {
egibleToDance = true;
earliestAttackTime = OTSYS_TIME() + 2000;
removeCondition(CONDITION_AGGRESSIVE, true);
extraMeleeAttack = false;
}
if (!isCloseAttack) {
//melee swing out of reach
extraMeleeAttack = true;
}
}
if (updateLook) {
updateLookDirection();
}
}
void Monster::doAttacking(uint32_t) void Monster::doAttacking(uint32_t)
{ {
if (!attackedCreature || (isSummon() && attackedCreature == this)) { if (!attackedCreature || (isSummon() && attackedCreature == this)) {
@ -865,13 +900,21 @@ void Monster::doAttacking(uint32_t)
const Position& targetPos = attackedCreature->getPosition(); const Position& targetPos = attackedCreature->getPosition();
bool updateLook = false; bool updateLook = false;
bool isCloseAttack = false;
if (OTSYS_TIME() >= earliestAttackTime && !isFleeing()) { if (OTSYS_TIME() >= earliestAttackTime && !isFleeing()) {
updateLook = true; updateLook = true;
if (Combat::closeAttack(this, attackedCreature, FIGHTMODE_BALANCED)) { isCloseAttack = Combat::closeAttack(this, attackedCreature, FIGHTMODE_BALANCED);
if (isCloseAttack) {
egibleToDance = true; egibleToDance = true;
earliestAttackTime = OTSYS_TIME() + 2000; earliestAttackTime = OTSYS_TIME() + 2000;
removeCondition(CONDITION_AGGRESSIVE, true); removeCondition(CONDITION_AGGRESSIVE, true);
extraMeleeAttack = false;
}
if (!isCloseAttack) {
//melee swing out of reach
extraMeleeAttack = true;
} }
} }

View File

@ -126,6 +126,7 @@ class Monster final : public Creature
} }
void onAttackedCreature(Creature* creature) final; void onAttackedCreature(Creature* creature) final;
void onAttackedCreatureDisappear(bool isLogout) override;
void onCreatureAppear(Creature* creature, bool isLogin) final; void onCreatureAppear(Creature* creature, bool isLogin) final;
void onRemoveCreature(Creature* creature, bool isLogout) final; void onRemoveCreature(Creature* creature, bool isLogout) final;
@ -146,7 +147,11 @@ class Monster final : public Creature
void setNormalCreatureLight() final; void setNormalCreatureLight() final;
bool getCombatValues(int32_t& min, int32_t& max) final; bool getCombatValues(int32_t& min, int32_t& max) final;
void doExtraMeleeAttack();
void doAttacking(uint32_t interval) final; void doAttacking(uint32_t interval) final;
bool hasExtraSwing() override {
return extraMeleeAttack;
}
bool searchTarget(TargetSearchType_t searchType); bool searchTarget(TargetSearchType_t searchType);
bool selectTarget(Creature* creature); bool selectTarget(Creature* creature);
@ -197,6 +202,7 @@ class Monster final : public Creature
Position masterPos; Position masterPos;
bool isIdle = true; bool isIdle = true;
bool extraMeleeAttack = false;
bool isMasterInRange = false; bool isMasterInRange = false;
bool egibleToDance = true; bool egibleToDance = true;