add combat controls

This commit is contained in:
Eduardo Bart 2012-02-07 21:06:52 -02:00
parent e51789378a
commit ee1357a848
21 changed files with 293 additions and 8 deletions

1
TODO
View File

@ -61,6 +61,7 @@ change Align/Anchors lua API from enum to text
== Client == Client
make possible to reload modules make possible to reload modules
fix modules recursivity, it makes client crash
implement left panel with dragging windows implement left panel with dragging windows
clean sprites cache periodically clean sprites cache periodically
create a shader manager create a shader manager

View File

@ -61,6 +61,7 @@ TopPanel
type: horizontalBox type: horizontalBox
spacing: 4 spacing: 4
padding: 6 4 padding: 6 4
visible: false
Panel Panel
id: rightButtonsPanel id: rightButtonsPanel

View File

@ -309,3 +309,11 @@ SpeakChannelRed = 11
SpeakChannelOrange = 12 SpeakChannelOrange = 12
SpeakMonsterSay = 13 SpeakMonsterSay = 13
SpeakMonsterYell = 14 SpeakMonsterYell = 14
FightOffensive = 1
FightBalanced = 2
FightDefensive = 3
DontChase = 0
ChaseOpponent = 1

View File

@ -51,6 +51,11 @@ function displayUI(arg1, options)
return widget return widget
end end
function loadUI(otui, parent)
local otuiFilePath = resolvepath(otui, 2)
return g_ui.loadUI(otuiFilePath, parent)
end
function createWidget(style, parent) function createWidget(style, parent)
local className = g_ui.getStyleClass(style) local className = g_ui.getStyleClass(style)
if className == "" then if className == "" then

View File

@ -57,6 +57,19 @@ function disconnect(object, signalsAndSlots)
end end
end end
function newclass()
local class = {}
function class.internalCreate()
local instance = {}
for k,v in pairs(class) do
instance[k] = v
end
return instance
end
class.create = class.internalCreate
return class
end
function extends(base) function extends(base)
local derived = {} local derived = {}
function derived.internalCreate() function derived.internalCreate()

View File

@ -25,6 +25,8 @@ Module
dofile 'uimessagebox' dofile 'uimessagebox'
dofile 'tooltip' dofile 'tooltip'
dofile 'radiogroup'
ToolTip.init() ToolTip.init()
onUnload: | onUnload: |

View File

@ -0,0 +1,43 @@
RadioGroup = newclass()
function RadioGroup.create()
local radiogroup = RadioGroup.internalCreate()
radiogroup.widgets = {}
return radiogroup
end
function RadioGroup:destroy()
while #self.widgets ~= 0 do
self:removeWidget(self.widgets[1])
end
end
function RadioGroup:addWidget(widget)
table.insert(self.widgets, widget)
widget.onMousePress = function(widget) self:selectWidget(widget) end
end
function RadioGroup:removeWidget(widget)
if self.selectedWidget == widget then
self:selectWidget(nil)
end
widget.onMousePress = nil
table.removevalue(self.widgets, widget)
end
function RadioGroup:selectWidget(selectedWidget)
if selectedWidget == self.selectedWidget then return end
local previousSelectedWidget = self.selectedWidget
self.selectedWidget = selectedWidget
if previousSelectedWidget then
previousSelectedWidget:setChecked(false)
end
if selectedWidget then
selectedWidget:setChecked(true)
end
signalcall(self.onSelectionChange, self, selectedWidget, previousSelectedWidget)
end

View File

@ -57,6 +57,8 @@ function ToolTip.terminate()
currentHoveredWidget = nil currentHoveredWidget = nil
toolTipLabel:destroy() toolTipLabel:destroy()
toolTipLabel = nil toolTipLabel = nil
ToolTip = nil
end end
function ToolTip.display(text) function ToolTip.display(text)

View File

@ -7,9 +7,7 @@ function UICheckBox.create()
return checkbox return checkbox
end end
function UICheckBox:onMouseRelease(mousePos, mouseButton) function UICheckBox:onMousePress(mousePos, mouseButton)
if self:isPressed() and self:containsPoint(mousePos) then
self:setChecked(not self:isChecked()) self:setChecked(not self:isChecked())
return true return true
end
end end

View File

@ -1,13 +1,132 @@
CombatControls = {} CombatControls = {}
-- private variables
local combatControlsButton local combatControlsButton
local combatControlsWindow
local fightOffensiveBox
local fightBalancedBox
local fightDefensiveBox
local chaseModeButton
local safeFightButton
local fightModeRadioGroup
-- private functions
local function onFightModeChange(self, selectedFightButton)
if selectedFightButton == nil then return end
local buttonId = selectedFightButton:getId()
local fightMode
if buttonId == 'fightOffensiveBox' then
fightMode = FightOffensive
elseif buttonId == 'fightBalancedBox' then
fightMode = FightBalanced
else
fightMode = FightDefensive
end
if Game.getFightMode ~= fightMode then
Game.setFightMode(fightMode)
end
end
local function onChaseModeChange(self, checked)
local chaseMode
if checked then
chaseMode = ChaseOpponent
else
chaseMode = DontChase
end
if Game.getChaseMode() ~= chaseMode then
Game.setChaseMode(chaseMode)
end
end
local function onSafeFightChange(self, checked)
local safeFight = not checked
if Game.isSafeFight() ~= safeFight then
Game.setSafeFight(not checked)
end
end
-- public functions
function CombatControls.init() function CombatControls.init()
combatControlsButton = TopMenu.addGameButton('combatControlsButton', 'Combat Controls', 'combatcontrols.png', CombatControls.toggle) combatControlsButton = TopMenu.addGameButton('combatControlsButton', 'Combat Controls', 'combatcontrols.png', CombatControls.toggle)
end combatControlsButton:setOn(true)
combatControlsWindow = loadUI('combatcontrols.otui')
fightOffensiveBox = combatControlsWindow:getChildById('fightOffensiveBox')
fightBalancedBox = combatControlsWindow:getChildById('fightBalancedBox')
fightDefensiveBox = combatControlsWindow:getChildById('fightDefensiveBox')
chaseModeButton = combatControlsWindow:getChildById('chaseModeBox')
safeFightButton = combatControlsWindow:getChildById('safeFightBox')
fightModeRadioGroup = RadioGroup.create()
fightModeRadioGroup:addWidget(fightOffensiveBox)
fightModeRadioGroup:addWidget(fightBalancedBox)
fightModeRadioGroup:addWidget(fightDefensiveBox)
connect(fightModeRadioGroup, { onSelectionChange = onFightModeChange })
connect(chaseModeButton, { onCheckChange = onChaseModeChange })
connect(safeFightButton, { onCheckChange = onSafeFightChange })
connect(Game, { onLogin = CombatControls.online })
connect(Game, { onLogout = CombatControls.offline })
if Game.isOnline() then
CombatControls.online()
end
end
function CombatControls.terminate() function CombatControls.terminate()
if Game.isOnline() then
CombatControls.offline()
end
fightModeRadioGroup:destroy()
fightModeRadioGroup = nil
fightOffensiveBox = nil
fightBalancedBox = nil
fightDefensiveBox = nil
chaseModeButton = nil
safeFightButton = nil
combatControlsButton:destroy() combatControlsButton:destroy()
combatControlsButton = nil combatControlsButton = nil
combatControlsWindow:destroy()
combatControlsWindow = nil
disconnect(Game, { onLogin = CombatControls.online })
disconnect(Game, { onLogout = CombatControls.offline })
CombatControls = nil
end end
function CombatControls.online()
Game.gameRightPanel:addChild(combatControlsWindow)
combatControlsWindow:setVisible(combatControlsButton:isOn())
local fightMode = Game.getFightMode()
if fightMode == FightOffensive then
fightModeRadioGroup:selectWidget(fightOffensiveBox)
elseif fightMode == FightBalanced then
fightModeRadioGroup:selectWidget(fightBalancedBox)
else
fightModeRadioGroup:selectWidget(fightDefensiveBox)
end
local chaseMode = Game.getChaseMode()
chaseModeButton:setChecked(chaseMode == ChaseOpponent)
local safeFight = Game.isSafeFight()
safeFightButton:setChecked(not safeFight)
end
function CombatControls.offline()
Game.gameRightPanel:removeChild(combatControlsWindow)
end
function CombatControls.toggle()
local visible = not combatControlsWindow:isExplicitlyVisible()
combatControlsWindow:setVisible(visible)
combatControlsButton:setOn(visible)
end

View File

@ -0,0 +1,43 @@
CombatBox < UICheckBox
size: 20 20
image-clip: 0 0 20 20
anchors.top: parent.top
margin-left: 5
margin-right: 5
$checked:
image-clip: 0 20 20 20
FightOffensiveBox < CombatBox
image-source: /game_combatcontrols/icons/fightoffensive.png
FightBalancedBox < CombatBox
image-source: /game_combatcontrols/icons/fightbalanced.png
FightDefensiveBox < CombatBox
image-source: /game_combatcontrols/icons/fightdefensive.png
ChaseModeBox < CombatBox
image-source: /game_combatcontrols/icons/chasemode.png
SafeFightBox < CombatBox
image-source: /game_combatcontrols/icons/safefight.png
UIWindow
width: 130
height: 30
margin-top: 10
margin-left: 6
margin-right: 6
FightOffensiveBox
id: fightOffensiveBox
anchors.right: next.left
FightBalancedBox
id: fightBalancedBox
anchors.right: next.left
FightDefensiveBox
id: fightDefensiveBox
anchors.horizontalCenter: parent.horizontalCenter
ChaseModeBox
id: chaseModeBox
anchors.left: prev.right
SafeFightBox
id: safeFightBox
anchors.left: prev.right

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -4,7 +4,6 @@ UIWindow
margin-top: 10 margin-top: 10
margin-left: 6 margin-left: 6
margin-right: 6 margin-right: 6
move-policy: free updated
Item Item
// head // head

View File

@ -211,7 +211,7 @@ namespace Otc
}; };
enum ChaseModes { enum ChaseModes {
StandWhileFighting = 0, DontChase = 0,
ChaseOpponent = 1 ChaseOpponent = 1
}; };

View File

@ -77,6 +77,12 @@ void Game::processLogin(const LocalPlayerPtr& localPlayer, int serverBeat)
m_localPlayer = localPlayer; m_localPlayer = localPlayer;
m_serverBeat = serverBeat; m_serverBeat = serverBeat;
// synchronize fight modes with the server
m_fightMode = Otc::FightBalanced;
m_chaseMode = Otc::DontChase;
m_safeFight = true;
m_protocolGame->sendFightTatics(m_fightMode, m_chaseMode, m_safeFight);
// NOTE: the entire map description is not known yet // NOTE: the entire map description is not known yet
g_lua.callGlobalField("Game", "onLogin", localPlayer); g_lua.callGlobalField("Game", "onLogin", localPlayer);
} }
@ -384,6 +390,33 @@ void Game::move(const ThingPtr& thing, const Position& toPos, int count)
m_protocolGame->sendThrow(thing->getPosition(), thing->getId(), thing->getStackpos(), toPos, count); m_protocolGame->sendThrow(thing->getPosition(), thing->getId(), thing->getStackpos(), toPos, count);
} }
void Game::setChaseMode(Otc::ChaseModes chaseMode)
{
if(!isOnline() || !checkBotProtection())
return;
m_chaseMode = chaseMode;
m_protocolGame->sendFightTatics(m_fightMode, m_chaseMode, m_safeFight);
}
void Game::setFightMode(Otc::FightModes fightMode)
{
if(!isOnline() || !checkBotProtection())
return;
m_fightMode = fightMode;
m_protocolGame->sendFightTatics(m_fightMode, m_chaseMode, m_safeFight);
}
void Game::setSafeFight(bool on)
{
if(!isOnline() || !checkBotProtection())
return;
m_safeFight = on;
m_protocolGame->sendFightTatics(m_fightMode, m_chaseMode, m_safeFight);
}
void Game::attack(const CreaturePtr& creature) void Game::attack(const CreaturePtr& creature)
{ {
if(!isOnline() || !creature || !checkBotProtection()) if(!isOnline() || !creature || !checkBotProtection())

View File

@ -74,6 +74,14 @@ public:
void useInventoryItemWith(int itemId, const ThingPtr& toThing); void useInventoryItemWith(int itemId, const ThingPtr& toThing);
void move(const ThingPtr &thing, const Position& toPos, int count); void move(const ThingPtr &thing, const Position& toPos, int count);
// fight tatics related
void setChaseMode(Otc::ChaseModes chaseMode);
void setFightMode(Otc::FightModes fightMode);
void setSafeFight(bool on);
Otc::ChaseModes getChaseMode() { return m_chaseMode; }
Otc::FightModes getFightMode() { return m_fightMode; }
bool isSafeFight() { return m_safeFight; }
// attack/follow related // attack/follow related
void attack(const CreaturePtr& creature); void attack(const CreaturePtr& creature);
void cancelAttack(); void cancelAttack();
@ -124,6 +132,10 @@ private:
ProtocolGamePtr m_protocolGame; ProtocolGamePtr m_protocolGame;
bool m_dead; bool m_dead;
int m_serverBeat; int m_serverBeat;
Otc::FightModes m_fightMode;
Otc::ChaseModes m_chaseMode;
bool m_safeFight;
}; };
extern Game g_game; extern Game g_game;

View File

@ -204,6 +204,12 @@ void OTClient::registerLuaFunctions()
g_lua.bindClassStaticFunction<Game>("turn", std::bind(&Game::turn, &g_game, _1)); g_lua.bindClassStaticFunction<Game>("turn", std::bind(&Game::turn, &g_game, _1));
g_lua.bindClassStaticFunction<Game>("walk", std::bind(&Game::walk, &g_game, _1)); g_lua.bindClassStaticFunction<Game>("walk", std::bind(&Game::walk, &g_game, _1));
g_lua.bindClassStaticFunction<Game>("forceWalk", std::bind(&Game::forceWalk, &g_game, _1)); g_lua.bindClassStaticFunction<Game>("forceWalk", std::bind(&Game::forceWalk, &g_game, _1));
g_lua.bindClassStaticFunction<Game>("setChaseMode", std::bind(&Game::setChaseMode, &g_game, _1));
g_lua.bindClassStaticFunction<Game>("setFightMode", std::bind(&Game::setFightMode, &g_game, _1));
g_lua.bindClassStaticFunction<Game>("setSafeFight", std::bind(&Game::setSafeFight, &g_game, _1));
g_lua.bindClassStaticFunction<Game>("getChaseMode", std::bind(&Game::getChaseMode, &g_game));
g_lua.bindClassStaticFunction<Game>("getFightMode", std::bind(&Game::getFightMode, &g_game));
g_lua.bindClassStaticFunction<Game>("isSafeFight", std::bind(&Game::isSafeFight, &g_game));
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>("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));