From f397e6319c07b4fe50e90ea012c65a93b51a2752 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Fri, 3 Aug 2012 02:05:09 -0300 Subject: [PATCH] Reimplement battle using new events, no more scheduleEvents --- modules/game_battle/battle.lua | 114 ++++++++++++++--------------- src/otclient/creature.cpp | 8 +- src/otclient/creature.h | 1 + src/otclient/localplayer.cpp | 5 ++ src/otclient/localplayer.h | 1 + src/otclient/luafunctions.cpp | 1 + src/otclient/map.cpp | 3 +- src/otclient/protocolgame.h | 1 + src/otclient/protocolgameparse.cpp | 11 +++ 9 files changed, 84 insertions(+), 61 deletions(-) diff --git a/modules/game_battle/battle.lua b/modules/game_battle/battle.lua index aca33c28..86c4eb85 100644 --- a/modules/game_battle/battle.lua +++ b/modules/game_battle/battle.lua @@ -6,7 +6,6 @@ battleWindow = nil battleButton = nil battlePanel = nil lastBattleButtonSwitched = nil -checkCreaturesEvent = nil battleButtonsByCreaturesList = {} mouseWidget = nil @@ -51,28 +50,32 @@ function init() mouseWidget:setFocusable(false) connect(Creature, { onSkullChange = checkCreatureSkull, - onEmblemChange = checkCreatureEmblem } ) + onEmblemChange = checkCreatureEmblem, + onPositionChange = onCreaturePositionChange + } ) connect(g_game, { onAttackingCreatureChange = onAttack, onFollowingCreatureChange = onFollow, + onMapDescription = checkCreatures, onGameEnd = removeAllCreatures } ) - addEvent(addAllCreatures) - checkCreaturesEvent = scheduleEvent(checkCreatures, 200) end function terminate() g_keyboard.unbindKeyDown('Ctrl+B') battleButtonsByCreaturesList = {} - removeEvent(checkCreaturesEvent) battleButton:destroy() battleWindow:destroy() mouseWidget:destroy() - disconnect(Creature, { onSkullChange = checkCreatureSkull, - onEmblemChange = checkCreatureEmblem } ) + disconnect(Creature, { onSkullChange = checkCreatureSkull, + onEmblemChange = checkCreatureEmblem, + onPositionChange = onCreaturePositionChange } ) - disconnect(g_game, { onAttackingCreatureChange = onAttack } ) + disconnect(g_game, { onAttackingCreatureChange = onAttack, + onFollowingCreatureChange = onFollow, + onMapDescription = checkCreatures, + onGameEnd = removeAllCreatures } ) end function toggle() @@ -89,17 +92,19 @@ function onMiniWindowClose() battleButton:setOn(false) end -function addAllCreatures() +function checkCreatures() + removeAllCreatures() + local spectators = {} - local player = g_game.getLocalPlayer() - if g_game.isOnline() then - creatures = g_map.getSpectators(player:getPosition(), false) - for i, creature in ipairs(creatures) do - if creature ~= player and doCreatureFitFilters(creature) then - table.insert(spectators, creature) - end - end + local player = g_game.getLocalPlayer() + if g_game.isOnline() then + creatures = g_map.getSpectators(player:getPosition(), false) + for i, creature in ipairs(creatures) do + if creature ~= player and doCreatureFitFilters(creature) then + table.insert(spectators, creature) + end end + end for i, v in pairs(spectators) do addCreature(v) @@ -107,6 +112,18 @@ function addAllCreatures() end function doCreatureFitFilters(creature) + local localPlayer = g_game.getLocalPlayer() + if creature == localPlayer then + return false + end + + local pos = creature:getPosition() + if not pos then return false end + + if pos.z ~= localPlayer:getPosition().z or not localPlayer:hasSight(pos) then + return false + end + local hidePlayers = hidePlayersButton:isChecked() local hideNPCs = hideNPCsButton:isChecked() local hideMonsters = hideMonstersButton:isChecked() @@ -128,53 +145,30 @@ function doCreatureFitFilters(creature) return true end -function checkCreatures(forceRecheck) - local player = g_game.getLocalPlayer() - if g_game.isOnline() then - local spectators = {} - - -- reloading list of spectators - local creaturesAppeared = {} - creatures = g_map.getSpectators(player:getPosition(), false) - for i, creature in ipairs(creatures) do - if creature ~= player and doCreatureFitFilters(creature) then - -- searching for creatures that appeared on battle list - local battleButton = battleButtonsByCreaturesList[creature:getId()] - if battleButton == nil then - table.insert(creaturesAppeared, creature) - else - setLifeBarPercent(battleButton, creature:getHealthPercent()) - end - spectators[creature:getId()] = creature - end - end - - for i, v in pairs(creaturesAppeared) do - addCreature(v) - end - - -- searching for creatures that disappeared from battle list - local creaturesDisappeared = {} - for i, creature in pairs(battleButtonsByCreaturesList) do - if spectators[creature.creatureId] == nil then - table.insert(creaturesDisappeared, creature.creature) - end - end - - for i, v in pairs(creaturesDisappeared) do - removeCreature(v) +function onCreaturePositionChange(creature, newPos, oldPos) + if creature:isLocalPlayer() then + checkCreatures() + else + local has = hasCreature(creature) + local fit = doCreatureFitFilters(creature) + if has and not fit then + removeCreature(creature) + elseif not has and fit then + addCreature(creature) end end - if not forceRecheck then - checkCreaturesEvent = scheduleEvent(checkCreatures, 500) - end +end + +function hasCreature(creature) + return battleButtonsByCreaturesList[creature:getId()] ~= nil end function addCreature(creature) local creatureId = creature:getId() - if battleButtonsByCreaturesList[creatureId] == nil then - local battleButton = g_ui.createWidget('BattleButton', battlePanel) + local battleButton = battleButtonsByCreaturesList[creature:getId()] + if not battleButton then + battleButton = g_ui.createWidget('BattleButton', battlePanel) local creatureWidget = battleButton:getChildById('creature') local labelWidget = battleButton:getChildById('label') local lifeBarWidget = battleButton:getChildById('lifeBar') @@ -185,8 +179,8 @@ function addCreature(creature) battleButton.creatureId = creatureId battleButton.creature = creature battleButton.isHovered = false - battleButton.isTarget = false - battleButton.isFollowed = false + battleButton.isTarget = (g_game.getAttackingCreature() == creature) + battleButton.isFollowed = (g_game.getFollowingCreature() == creature) labelWidget:setText(creature:getName()) creatureWidget:setCreature(creature) @@ -196,6 +190,8 @@ function addCreature(creature) checkCreatureSkull(battleButton.creature) checkCreatureEmblem(battleButton.creature) + else + setLifeBarPercent(battleButton, creature:getHealthPercent()) end end diff --git a/src/otclient/creature.cpp b/src/otclient/creature.cpp index 56cd21fb..f5147498 100644 --- a/src/otclient/creature.cpp +++ b/src/otclient/creature.cpp @@ -286,6 +286,11 @@ void Creature::stopWalk() terminateWalk(); } +void Creature::onPositionChange(const Position& newPos, const Position& oldPos) +{ + callLuaField("onPositionChange", newPos, oldPos); +} + void Creature::onAppear() { // cancel any disappear event @@ -328,7 +333,8 @@ void Creature::onDisappear() self->callLuaField("onDisappear"); // invalidate this creature position - self->m_position = Position(); + if(!self->isLocalPlayer()) + self->setPosition(Position()); self->m_oldPosition = Position(); self->m_disappearEvent = nullptr; }); diff --git a/src/otclient/creature.h b/src/otclient/creature.h index 2c7a2544..284bdbeb 100644 --- a/src/otclient/creature.h +++ b/src/otclient/creature.h @@ -100,6 +100,7 @@ public: const ThingTypePtr& getThingType(); ThingType *rawGetThingType(); + virtual void onPositionChange(const Position& newPos, const Position& oldPos); virtual void onAppear(); virtual void onDisappear(); diff --git a/src/otclient/localplayer.cpp b/src/otclient/localplayer.cpp index b233d6cb..044b205e 100644 --- a/src/otclient/localplayer.cpp +++ b/src/otclient/localplayer.cpp @@ -383,3 +383,8 @@ double LocalPlayer::getWalkPing() sum += p; return sum / (double)m_lastWalkPings.size(); } + +bool LocalPlayer::hasSight(const Position& pos) +{ + return m_position.isInRange(pos, (Otc::VISIBLE_X_TILES - 1)/2, (Otc::VISIBLE_Y_TILES - 1)/2); +} diff --git a/src/otclient/localplayer.h b/src/otclient/localplayer.h index bfba1f1c..165f229e 100644 --- a/src/otclient/localplayer.h +++ b/src/otclient/localplayer.h @@ -73,6 +73,7 @@ public: double getStamina() { return m_stamina; } ItemPtr getInventoryItem(Otc::InventorySlot inventory) { return m_inventoryItems[inventory]; } + bool hasSight(const Position& pos); bool isKnown() { return m_known; } bool isPreWalking() { return m_preWalking; } bool isAutoWalking() { return m_autoWalking; } diff --git a/src/otclient/luafunctions.cpp b/src/otclient/luafunctions.cpp index 244c2b7b..e5b7e4df 100644 --- a/src/otclient/luafunctions.cpp +++ b/src/otclient/luafunctions.cpp @@ -393,6 +393,7 @@ void OTClient::registerLuaFunctions() g_lua.bindClassMemberFunction("isPremium", &LocalPlayer::isPremium); g_lua.bindClassMemberFunction("isKnown", &LocalPlayer::isKnown); g_lua.bindClassMemberFunction("isPreWalking", &LocalPlayer::isPreWalking); + g_lua.bindClassMemberFunction("hasSight", &LocalPlayer::hasSight); g_lua.registerClass(); g_lua.bindClassMemberFunction("clean", &Tile::clean); diff --git a/src/otclient/map.cpp b/src/otclient/map.cpp index 95225815..3d36ef50 100644 --- a/src/otclient/map.cpp +++ b/src/otclient/map.cpp @@ -301,7 +301,8 @@ void Map::setCentralPosition(const Position& centralPosition) Position oldPos = localPlayer->getPosition(); Position pos = m_centralPosition; if(oldPos != pos) { - localPlayer->onDisappear(); + if(!localPlayer->isRemoved()) + localPlayer->onDisappear(); localPlayer->setPosition(pos); localPlayer->onAppear(); } diff --git a/src/otclient/protocolgame.h b/src/otclient/protocolgame.h index d96d538b..40c88322 100644 --- a/src/otclient/protocolgame.h +++ b/src/otclient/protocolgame.h @@ -216,6 +216,7 @@ public: private: stdext::boolean m_enableSendExtendedOpcode; stdext::boolean m_gameInitialized; + stdext::boolean m_mapKnown; stdext::boolean m_firstRecv; std::string m_accountName; std::string m_accountPassword; diff --git a/src/otclient/protocolgameparse.cpp b/src/otclient/protocolgameparse.cpp index 1a32a08d..f4877756 100644 --- a/src/otclient/protocolgameparse.cpp +++ b/src/otclient/protocolgameparse.cpp @@ -399,8 +399,19 @@ void ProtocolGame::parseDeath(const InputMessagePtr& msg) void ProtocolGame::parseMapDescription(const InputMessagePtr& msg) { Position pos = getPosition(msg); + + if(!m_mapKnown) + m_localPlayer->setPosition(pos); + g_map.setCentralPosition(pos); setMapDescription(msg, pos.x - Otc::AWARE_X_LEFT_TILES, pos.y - Otc::AWARE_Y_TOP_TILES, pos.z, Otc::AWARE_X_TILES, Otc::AWARE_Y_TILES); + + if(!m_mapKnown) { + g_dispatcher.addEvent([] { g_lua.callGlobalField("g_game", "onMapKnown"); }); + m_mapKnown = true; + } + + g_dispatcher.addEvent([] { g_lua.callGlobalField("g_game", "onMapDescription"); }); } void ProtocolGame::parseMapMoveNorth(const InputMessagePtr& msg)