diff --git a/src/creature.cpp b/src/creature.cpp index ad329a0..437b285 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -607,7 +607,12 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos } else { if (hasExtraSwing()) { //our target is moving lets see if we can get in hit - g_dispatcher.addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game, getID()))); + 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()))); + } } if (newTile->getZone() != oldTile->getZone()) { diff --git a/src/game.cpp b/src/game.cpp index b733034..b75b6a1 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -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) { creature->creatureCheck = true; diff --git a/src/game.h b/src/game.h index 2182dca..d47d04d 100644 --- a/src/game.h +++ b/src/game.h @@ -435,6 +435,7 @@ class Game void checkCreatureWalk(uint32_t creatureId); void updateCreatureWalk(uint32_t creatureId); void checkCreatureAttack(uint32_t creatureId); + void checkMonsterExtraAttack(uint32_t creatureId); void checkCreatures(size_t index); void checkLight(); diff --git a/src/monster.cpp b/src/monster.cpp index 69718e4..21f3d7d 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -119,6 +119,11 @@ void Monster::onAttackedCreature(Creature* creature) } } +void Monster::onAttackedCreatureDisappear(bool) +{ + extraMeleeAttack = true; +} + void Monster::onCreatureAppear(Creature* creature, bool 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) { if (!attackedCreature || (isSummon() && attackedCreature == this)) { @@ -865,13 +900,21 @@ void Monster::doAttacking(uint32_t) const Position& targetPos = attackedCreature->getPosition(); bool updateLook = false; + bool isCloseAttack = false; if (OTSYS_TIME() >= earliestAttackTime && !isFleeing()) { updateLook = true; - if (Combat::closeAttack(this, attackedCreature, FIGHTMODE_BALANCED)) { + 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; } } @@ -879,10 +922,10 @@ void Monster::doAttacking(uint32_t) if (spellBlock.range != 0 && std::max(Position::getDistanceX(myPos, targetPos), Position::getDistanceY(myPos, targetPos)) <= spellBlock.range) { if (uniform_random(0, spellBlock.chance) == 0 && (master || health > mType->info.runAwayHealth || uniform_random(1, 3) == 1)) { updateLookDirection(); - + minCombatValue = spellBlock.minCombatValue; maxCombatValue = spellBlock.maxCombatValue; - + spellBlock.spell->castSpell(this, attackedCreature); egibleToDance = true; } diff --git a/src/monster.h b/src/monster.h index 8447df7..0c7b6a5 100644 --- a/src/monster.h +++ b/src/monster.h @@ -126,6 +126,7 @@ class Monster final : public Creature } void onAttackedCreature(Creature* creature) final; + void onAttackedCreatureDisappear(bool isLogout) override; void onCreatureAppear(Creature* creature, bool isLogin) final; void onRemoveCreature(Creature* creature, bool isLogout) final; @@ -146,7 +147,11 @@ class Monster final : public Creature void setNormalCreatureLight() final; bool getCombatValues(int32_t& min, int32_t& max) final; + void doExtraMeleeAttack(); void doAttacking(uint32_t interval) final; + bool hasExtraSwing() override { + return extraMeleeAttack; + } bool searchTarget(TargetSearchType_t searchType); bool selectTarget(Creature* creature); @@ -197,6 +202,7 @@ class Monster final : public Creature Position masterPos; bool isIdle = true; + bool extraMeleeAttack = false; bool isMasterInRange = false; bool egibleToDance = true;