Reimplement battle using new events, no more scheduleEvents

This commit is contained in:
Eduardo Bart 2012-08-03 02:05:09 -03:00
parent 06388c5673
commit f397e6319c
9 changed files with 84 additions and 61 deletions

View File

@ -6,7 +6,6 @@ battleWindow = nil
battleButton = nil battleButton = nil
battlePanel = nil battlePanel = nil
lastBattleButtonSwitched = nil lastBattleButtonSwitched = nil
checkCreaturesEvent = nil
battleButtonsByCreaturesList = {} battleButtonsByCreaturesList = {}
mouseWidget = nil mouseWidget = nil
@ -51,28 +50,32 @@ function init()
mouseWidget:setFocusable(false) mouseWidget:setFocusable(false)
connect(Creature, { onSkullChange = checkCreatureSkull, connect(Creature, { onSkullChange = checkCreatureSkull,
onEmblemChange = checkCreatureEmblem } ) onEmblemChange = checkCreatureEmblem,
onPositionChange = onCreaturePositionChange
} )
connect(g_game, { onAttackingCreatureChange = onAttack, connect(g_game, { onAttackingCreatureChange = onAttack,
onFollowingCreatureChange = onFollow, onFollowingCreatureChange = onFollow,
onMapDescription = checkCreatures,
onGameEnd = removeAllCreatures } ) onGameEnd = removeAllCreatures } )
addEvent(addAllCreatures)
checkCreaturesEvent = scheduleEvent(checkCreatures, 200)
end end
function terminate() function terminate()
g_keyboard.unbindKeyDown('Ctrl+B') g_keyboard.unbindKeyDown('Ctrl+B')
battleButtonsByCreaturesList = {} battleButtonsByCreaturesList = {}
removeEvent(checkCreaturesEvent)
battleButton:destroy() battleButton:destroy()
battleWindow:destroy() battleWindow:destroy()
mouseWidget:destroy() mouseWidget:destroy()
disconnect(Creature, { onSkullChange = checkCreatureSkull, disconnect(Creature, { onSkullChange = checkCreatureSkull,
onEmblemChange = checkCreatureEmblem } ) onEmblemChange = checkCreatureEmblem,
onPositionChange = onCreaturePositionChange } )
disconnect(g_game, { onAttackingCreatureChange = onAttack } ) disconnect(g_game, { onAttackingCreatureChange = onAttack,
onFollowingCreatureChange = onFollow,
onMapDescription = checkCreatures,
onGameEnd = removeAllCreatures } )
end end
function toggle() function toggle()
@ -89,17 +92,19 @@ function onMiniWindowClose()
battleButton:setOn(false) battleButton:setOn(false)
end end
function addAllCreatures() function checkCreatures()
removeAllCreatures()
local spectators = {} local spectators = {}
local player = g_game.getLocalPlayer() local player = g_game.getLocalPlayer()
if g_game.isOnline() then if g_game.isOnline() then
creatures = g_map.getSpectators(player:getPosition(), false) creatures = g_map.getSpectators(player:getPosition(), false)
for i, creature in ipairs(creatures) do for i, creature in ipairs(creatures) do
if creature ~= player and doCreatureFitFilters(creature) then if creature ~= player and doCreatureFitFilters(creature) then
table.insert(spectators, creature) table.insert(spectators, creature)
end end
end
end end
end
for i, v in pairs(spectators) do for i, v in pairs(spectators) do
addCreature(v) addCreature(v)
@ -107,6 +112,18 @@ function addAllCreatures()
end end
function doCreatureFitFilters(creature) 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 hidePlayers = hidePlayersButton:isChecked()
local hideNPCs = hideNPCsButton:isChecked() local hideNPCs = hideNPCsButton:isChecked()
local hideMonsters = hideMonstersButton:isChecked() local hideMonsters = hideMonstersButton:isChecked()
@ -128,53 +145,30 @@ function doCreatureFitFilters(creature)
return true return true
end end
function checkCreatures(forceRecheck) function onCreaturePositionChange(creature, newPos, oldPos)
local player = g_game.getLocalPlayer() if creature:isLocalPlayer() then
if g_game.isOnline() then checkCreatures()
local spectators = {} else
local has = hasCreature(creature)
-- reloading list of spectators local fit = doCreatureFitFilters(creature)
local creaturesAppeared = {} if has and not fit then
creatures = g_map.getSpectators(player:getPosition(), false) removeCreature(creature)
for i, creature in ipairs(creatures) do elseif not has and fit then
if creature ~= player and doCreatureFitFilters(creature) then addCreature(creature)
-- 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)
end end
end end
if not forceRecheck then end
checkCreaturesEvent = scheduleEvent(checkCreatures, 500)
end function hasCreature(creature)
return battleButtonsByCreaturesList[creature:getId()] ~= nil
end end
function addCreature(creature) function addCreature(creature)
local creatureId = creature:getId() local creatureId = creature:getId()
if battleButtonsByCreaturesList[creatureId] == nil then local battleButton = battleButtonsByCreaturesList[creature:getId()]
local battleButton = g_ui.createWidget('BattleButton', battlePanel) if not battleButton then
battleButton = g_ui.createWidget('BattleButton', battlePanel)
local creatureWidget = battleButton:getChildById('creature') local creatureWidget = battleButton:getChildById('creature')
local labelWidget = battleButton:getChildById('label') local labelWidget = battleButton:getChildById('label')
local lifeBarWidget = battleButton:getChildById('lifeBar') local lifeBarWidget = battleButton:getChildById('lifeBar')
@ -185,8 +179,8 @@ function addCreature(creature)
battleButton.creatureId = creatureId battleButton.creatureId = creatureId
battleButton.creature = creature battleButton.creature = creature
battleButton.isHovered = false battleButton.isHovered = false
battleButton.isTarget = false battleButton.isTarget = (g_game.getAttackingCreature() == creature)
battleButton.isFollowed = false battleButton.isFollowed = (g_game.getFollowingCreature() == creature)
labelWidget:setText(creature:getName()) labelWidget:setText(creature:getName())
creatureWidget:setCreature(creature) creatureWidget:setCreature(creature)
@ -196,6 +190,8 @@ function addCreature(creature)
checkCreatureSkull(battleButton.creature) checkCreatureSkull(battleButton.creature)
checkCreatureEmblem(battleButton.creature) checkCreatureEmblem(battleButton.creature)
else
setLifeBarPercent(battleButton, creature:getHealthPercent())
end end
end end

View File

@ -286,6 +286,11 @@ void Creature::stopWalk()
terminateWalk(); terminateWalk();
} }
void Creature::onPositionChange(const Position& newPos, const Position& oldPos)
{
callLuaField("onPositionChange", newPos, oldPos);
}
void Creature::onAppear() void Creature::onAppear()
{ {
// cancel any disappear event // cancel any disappear event
@ -328,7 +333,8 @@ void Creature::onDisappear()
self->callLuaField("onDisappear"); self->callLuaField("onDisappear");
// invalidate this creature position // invalidate this creature position
self->m_position = Position(); if(!self->isLocalPlayer())
self->setPosition(Position());
self->m_oldPosition = Position(); self->m_oldPosition = Position();
self->m_disappearEvent = nullptr; self->m_disappearEvent = nullptr;
}); });

View File

@ -100,6 +100,7 @@ public:
const ThingTypePtr& getThingType(); const ThingTypePtr& getThingType();
ThingType *rawGetThingType(); ThingType *rawGetThingType();
virtual void onPositionChange(const Position& newPos, const Position& oldPos);
virtual void onAppear(); virtual void onAppear();
virtual void onDisappear(); virtual void onDisappear();

View File

@ -383,3 +383,8 @@ double LocalPlayer::getWalkPing()
sum += p; sum += p;
return sum / (double)m_lastWalkPings.size(); 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);
}

View File

@ -73,6 +73,7 @@ public:
double getStamina() { return m_stamina; } double getStamina() { return m_stamina; }
ItemPtr getInventoryItem(Otc::InventorySlot inventory) { return m_inventoryItems[inventory]; } ItemPtr getInventoryItem(Otc::InventorySlot inventory) { return m_inventoryItems[inventory]; }
bool hasSight(const Position& pos);
bool isKnown() { return m_known; } bool isKnown() { return m_known; }
bool isPreWalking() { return m_preWalking; } bool isPreWalking() { return m_preWalking; }
bool isAutoWalking() { return m_autoWalking; } bool isAutoWalking() { return m_autoWalking; }

View File

@ -393,6 +393,7 @@ void OTClient::registerLuaFunctions()
g_lua.bindClassMemberFunction<LocalPlayer>("isPremium", &LocalPlayer::isPremium); g_lua.bindClassMemberFunction<LocalPlayer>("isPremium", &LocalPlayer::isPremium);
g_lua.bindClassMemberFunction<LocalPlayer>("isKnown", &LocalPlayer::isKnown); g_lua.bindClassMemberFunction<LocalPlayer>("isKnown", &LocalPlayer::isKnown);
g_lua.bindClassMemberFunction<LocalPlayer>("isPreWalking", &LocalPlayer::isPreWalking); g_lua.bindClassMemberFunction<LocalPlayer>("isPreWalking", &LocalPlayer::isPreWalking);
g_lua.bindClassMemberFunction<LocalPlayer>("hasSight", &LocalPlayer::hasSight);
g_lua.registerClass<Tile>(); g_lua.registerClass<Tile>();
g_lua.bindClassMemberFunction<Tile>("clean", &Tile::clean); g_lua.bindClassMemberFunction<Tile>("clean", &Tile::clean);

View File

@ -301,7 +301,8 @@ void Map::setCentralPosition(const Position& centralPosition)
Position oldPos = localPlayer->getPosition(); Position oldPos = localPlayer->getPosition();
Position pos = m_centralPosition; Position pos = m_centralPosition;
if(oldPos != pos) { if(oldPos != pos) {
localPlayer->onDisappear(); if(!localPlayer->isRemoved())
localPlayer->onDisappear();
localPlayer->setPosition(pos); localPlayer->setPosition(pos);
localPlayer->onAppear(); localPlayer->onAppear();
} }

View File

@ -216,6 +216,7 @@ public:
private: private:
stdext::boolean<false> m_enableSendExtendedOpcode; stdext::boolean<false> m_enableSendExtendedOpcode;
stdext::boolean<false> m_gameInitialized; stdext::boolean<false> m_gameInitialized;
stdext::boolean<false> m_mapKnown;
stdext::boolean<true> m_firstRecv; stdext::boolean<true> m_firstRecv;
std::string m_accountName; std::string m_accountName;
std::string m_accountPassword; std::string m_accountPassword;

View File

@ -399,8 +399,19 @@ void ProtocolGame::parseDeath(const InputMessagePtr& msg)
void ProtocolGame::parseMapDescription(const InputMessagePtr& msg) void ProtocolGame::parseMapDescription(const InputMessagePtr& msg)
{ {
Position pos = getPosition(msg); Position pos = getPosition(msg);
if(!m_mapKnown)
m_localPlayer->setPosition(pos);
g_map.setCentralPosition(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); 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) void ProtocolGame::parseMapMoveNorth(const InputMessagePtr& msg)