From 4d656f8bd1ff8151daf196c944fbc945e9b91219 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 19 Nov 2013 00:50:00 +0100 Subject: [PATCH] New pvp modes to combat controls --- data/images/game/combatmodes/mount.png | Bin 0 -> 2069 bytes data/images/game/combatmodes/redfistmode.png | Bin 0 -> 2140 bytes .../images/game/combatmodes/whitedovemode.png | Bin 0 -> 1949 bytes .../images/game/combatmodes/whitehandmode.png | Bin 0 -> 2015 bytes .../game/combatmodes/yellowhandmode.png | Bin 0 -> 2093 bytes .../game_combatcontrols/combatcontrols.lua | 113 ++++++++++++++++++ .../game_combatcontrols/combatcontrols.otui | 64 ++++++++-- modules/gamelib/const.lua | 6 + src/client/const.h | 7 ++ src/client/game.cpp | 25 +++- src/client/game.h | 5 +- src/client/luafunctions.cpp | 2 + src/client/protocolgame.h | 2 +- src/client/protocolgameparse.cpp | 6 +- src/client/protocolgamesend.cpp | 5 +- 15 files changed, 210 insertions(+), 25 deletions(-) create mode 100644 data/images/game/combatmodes/mount.png create mode 100644 data/images/game/combatmodes/redfistmode.png create mode 100644 data/images/game/combatmodes/whitedovemode.png create mode 100644 data/images/game/combatmodes/whitehandmode.png create mode 100644 data/images/game/combatmodes/yellowhandmode.png diff --git a/data/images/game/combatmodes/mount.png b/data/images/game/combatmodes/mount.png new file mode 100644 index 0000000000000000000000000000000000000000..879646a12973e6a91fe267d4d2131e1a7fe40377 GIT binary patch literal 2069 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 literal 0 HcmV?d00001 diff --git a/data/images/game/combatmodes/whitehandmode.png b/data/images/game/combatmodes/whitehandmode.png new file mode 100644 index 0000000000000000000000000000000000000000..c010d828925937100b8a5f17b28fd73259aedc6b GIT binary patch literal 2015 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 X^p9W%KcKm300000NkvXXu0mjf{F&?M literal 0 HcmV?d00001 diff --git a/modules/game_combatcontrols/combatcontrols.lua b/modules/game_combatcontrols/combatcontrols.lua index 1f04b2fc..5d0f1644 100644 --- a/modules/game_combatcontrols/combatcontrols.lua +++ b/modules/game_combatcontrols/combatcontrols.lua @@ -5,7 +5,14 @@ fightBalancedBox = nil fightDefensiveBox = nil chaseModeButton = nil safeFightButton = nil +whiteDoveBox = nil +whiteHandBox = nil +yellowHandBox = nil +redFistBox = nil +mountButton = nil +pvpModesPanel = nil fightModeRadioGroup = nil +pvpModeRadioGroup = nil function init() combatControlsButton = modules.client_topmenu.addRightGameToggleButton('combatControlsButton', tr('Combat Controls'), '/images/topbuttons/combatcontrols', toggle) @@ -16,15 +23,33 @@ function init() fightOffensiveBox = combatControlsWindow:recursiveGetChildById('fightOffensiveBox') fightBalancedBox = combatControlsWindow:recursiveGetChildById('fightBalancedBox') fightDefensiveBox = combatControlsWindow:recursiveGetChildById('fightDefensiveBox') + chaseModeButton = combatControlsWindow:recursiveGetChildById('chaseModeBox') safeFightButton = combatControlsWindow:recursiveGetChildById('safeFightBox') + + mountButton = combatControlsWindow:recursiveGetChildById('mountButton') + mountButton.onClick = onMountButtonClick + + pvpModesPanel = combatControlsWindow:recursiveGetChildById('pvpModesPanel') + + whiteDoveBox = combatControlsWindow:recursiveGetChildById('whiteDoveBox') + whiteHandBox = combatControlsWindow:recursiveGetChildById('whiteHandBox') + yellowHandBox = combatControlsWindow:recursiveGetChildById('yellowHandBox') + redFistBox = combatControlsWindow:recursiveGetChildById('redFistBox') fightModeRadioGroup = UIRadioGroup.create() fightModeRadioGroup:addWidget(fightOffensiveBox) fightModeRadioGroup:addWidget(fightBalancedBox) fightModeRadioGroup:addWidget(fightDefensiveBox) + + pvpModeRadioGroup = UIRadioGroup.create() + pvpModeRadioGroup:addWidget(whiteDoveBox) + pvpModeRadioGroup:addWidget(whiteHandBox) + pvpModeRadioGroup:addWidget(yellowHandBox) + pvpModeRadioGroup:addWidget(redFistBox) connect(fightModeRadioGroup, { onSelectionChange = onSetFightMode }) + connect(pvpModeRadioGroup, { onSelectionChange = onSetPVPMode }) connect(chaseModeButton, { onCheckChange = onSetChaseMode }) connect(safeFightButton, { onCheckChange = onSetSafeFight }) connect(g_game, { @@ -33,9 +58,12 @@ function init() onFightModeChange = update, onChaseModeChange = update, onSafeFightChange = update, + onPVPModeChange = update, onWalk = check, onAutoWalk = check }) + + connect(LocalPlayer, { onOutfitChange = onOutfitChange }) if g_game.isOnline() then online() @@ -50,6 +78,7 @@ function terminate() end fightModeRadioGroup:destroy() + pvpModeRadioGroup:destroy() combatControlsWindow:destroy() combatControlsButton:destroy() @@ -59,9 +88,12 @@ function terminate() onFightModeChange = update, onChaseModeChange = update, onSafeFightChange = update, + onPVPModeChange = update, onWalk = check, onAutoWalk = check }) + + disconnect(LocalPlayer, { onOutfitChange = onOutfitChange }) end function update() @@ -79,6 +111,14 @@ function update() local safeFight = g_game.isSafeFight() safeFightButton:setChecked(not safeFight) + + if g_game.getFeature(GamePVPMode) then + local pvpMode = g_game.getPVPMode() + local pvpWidget = getPVPBoxByMode(pvpMode) + if pvpWidget then + pvpModeRadioGroup:selectWidget(pvpWidget) + end + end end function check() @@ -101,8 +141,26 @@ function online() g_game.setFightMode(lastCombatControls[char].fightMode) g_game.setChaseMode(lastCombatControls[char].chaseMode) g_game.setSafeFight(lastCombatControls[char].safeFight) + if g_game.getFeature(GamePVPMode) and lastCombatControls[char].pvpMode then + g_game.setPVPMode(lastCombatControls[char].pvpMode) + end end end + + if g_game.getFeature(GamePlayerMounts) then + mountButton:setVisible(true) + mountButton:setChecked(player:isMounted()) + else + mountButton:setVisible(false) + end + + if g_game.getFeature(GamePVPMode) then + pvpModesPanel:setVisible(true) + combatControlsWindow:setHeight(combatControlsWindow.extendedControlsHeight) + else + pvpModesPanel:setVisible(false) + combatControlsWindow:setHeight(combatControlsWindow.simpleControlsHeight) + end end update() @@ -123,6 +181,10 @@ function offline() safeFight = g_game.isSafeFight() } + if g_game.getFeature(GamePVPMode) then + lastCombatControls[char].pvpMode = g_game.getPVPMode() + end + -- save last combat control settings g_settings.setNode('LastCombatControls', lastCombatControls) end @@ -166,6 +228,57 @@ function onSetSafeFight(self, checked) g_game.setSafeFight(not checked) end +function onSetPVPMode(self, selectedPVPButton) + if selectedPVPButton == nil then + return + end + + local buttonId = selectedPVPButton:getId() + local pvpMode = PVPWhiteDove + if buttonId == 'whiteDoveBox' then + pvpMode = PVPWhiteDove + elseif buttonId == 'whiteHandBox' then + pvpMode = PVPWhiteHand + elseif buttonId == 'yellowHandBox' then + pvpMode = PVPYellowHand + elseif buttonId == 'redFistBox' then + pvpMode = PVPRedFist + end + + if g_game.getFeature(GamePVPMode) then + g_game.setPVPMode(pvpMode) + end +end + function onMiniWindowClose() combatControlsButton:setOn(false) end + +function onMountButtonClick(self, mousePos) + local player = g_game.getLocalPlayer() + if player then + player:toggleMount() + end +end + +function onOutfitChange(localPlayer, outfit, oldOutfit) + if outfit.mount == oldOutfit.mount then + return + end + + mountButton:setChecked(outfit.mount ~= nil and outfit.mount > 0) +end + +function getPVPBoxByMode(mode) + local widget = nil + if mode == PVPWhiteDove then + widget = whiteDoveBox + elseif mode == PVPWhiteHand then + widget = whiteHandBox + elseif mode == PVPYellowHand then + widget = yellowHandBox + elseif mode == PVPRedFist then + widget = redFistBox + end + return widget +end diff --git a/modules/game_combatcontrols/combatcontrols.otui b/modules/game_combatcontrols/combatcontrols.otui index df12d94e..57e92da2 100644 --- a/modules/game_combatcontrols/combatcontrols.otui +++ b/modules/game_combatcontrols/combatcontrols.otui @@ -1,12 +1,7 @@ CombatBox < UICheckBox size: 20 20 image-clip: 0 0 20 20 - anchors.top: parent.top - margin: 0 4 - $first: - margin: 0 1 - $last: - margin: 0 1 + margin: 2 4 $checked: image-clip: 0 20 20 20 @@ -21,33 +16,78 @@ ChaseModeBox < CombatBox image-source: /images/game/combatmodes/chasemode SafeFightBox < CombatBox image-source: /images/game/combatmodes/safefight + +MountButton < CombatBox + image-source: /images/game/combatmodes/mount + +WhiteDoveBox < CombatBox + image-source: /images/game/combatmodes/whitedovemode +WhiteHandBox < CombatBox + image-source: /images/game/combatmodes/whitehandmode +YellowHandBox < CombatBox + image-source: /images/game/combatmodes/yellowhandmode +RedFistBox < CombatBox + image-source: /images/game/combatmodes/redfistmode MiniWindow id: combatControlsWindow !text: tr('Combat Controls') icon: /images/topbuttons/combatcontrols - height: 48 + height: 49 &save: true + &simpleControlsHeight: 49 + &extendedControlsHeight: 72 @onClose: modules.game_combatcontrols.onMiniWindowClose() MiniWindowContents FightOffensiveBox id: fightOffensiveBox + anchors.top: parent.top anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter + margin: 2 1 FightBalancedBox id: fightBalancedBox + anchors.top: parent.top anchors.left: prev.right - anchors.verticalCenter: parent.verticalCenter FightDefensiveBox id: fightDefensiveBox + anchors.top: parent.top anchors.left: prev.right - anchors.verticalCenter: parent.verticalCenter + MountButton + id: mountButton + anchors.top: parent.top + anchors.right: next.left ChaseModeBox id: chaseModeBox + anchors.top: parent.top anchors.right: next.left - anchors.verticalCenter: parent.verticalCenter SafeFightBox id: safeFightBox + anchors.top: parent.top + anchors.right: parent.right + margin: 2 1 + + Panel + id: pvpModesPanel + anchors.left: parent.left anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter + anchors.bottom: parent.bottom + height: 20 + + WhiteDoveBox + id: whiteDoveBox + anchors.left: parent.left + anchors.bottom: parent.bottom + margin: 2 1 + WhiteHandBox + id: whiteHandBox + anchors.left: prev.right + anchors.bottom: parent.bottom + YellowHandBox + id: yellowHandBox + anchors.left: prev.right + anchors.bottom: parent.bottom + RedFistBox + id: redFistBox + anchors.left: prev.right + anchors.bottom: parent.bottom \ No newline at end of file diff --git a/modules/gamelib/const.lua b/modules/gamelib/const.lua index faf55c84..67e7afcd 100644 --- a/modules/gamelib/const.lua +++ b/modules/gamelib/const.lua @@ -47,6 +47,11 @@ FightDefensive = 3 DontChase = 0 ChaseOpponent = 1 +PVPWhiteDove = 0 +PVPWhiteHand = 1 +PVPYellowHand = 2 +PVPRedFist = 3 + GameProtocolChecksum = 1 GameAccountNames = 2 GameChallengeOnLogin = 3 @@ -94,6 +99,7 @@ GameMesssageLevel = 46 GameNewFluids = 47 GamePlayerStateU16 = 48 GameNewOutfitProtocol = 49 +GamePVPMode = 50 TextColors = { red = '#f55e5e', --'#c83200' diff --git a/src/client/const.h b/src/client/const.h index e9ad69ca..3a084a26 100644 --- a/src/client/const.h +++ b/src/client/const.h @@ -206,6 +206,13 @@ namespace Otc ChaseOpponent = 1 }; + enum PVPModes { + WhiteDove = 0, + WhiteHand = 1, + YellowHand = 2, + RedFist = 3 + }; + enum PlayerSkulls { SkullNone = 0, SkullYellow, diff --git a/src/client/game.cpp b/src/client/game.cpp index b648d099..b61dd958 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -51,6 +51,7 @@ Game::Game() m_canReportBugs = false; m_fightMode = Otc::FightBalanced; m_chaseMode = Otc::DontChase; + m_pvpMode = Otc::WhiteDove; m_safeFight = true; } @@ -76,6 +77,7 @@ void Game::resetGameStates() m_canReportBugs = false; m_fightMode = Otc::FightBalanced; m_chaseMode = Otc::DontChase; + m_pvpMode = Otc::WhiteDove; m_safeFight = true; m_followingCreature = nullptr; m_attackingCreature = nullptr; @@ -176,7 +178,7 @@ void Game::processGameStart() m_online = true; // synchronize fight modes with the server - m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight); + m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight, m_pvpMode); // NOTE: the entire map description and local player information is not known yet (bot call is allowed here) enableBotCall(); @@ -239,15 +241,17 @@ void Game::processPlayerHelpers(int helpers) g_lua.callGlobalField("g_game", "onPlayerHelpersUpdate", helpers); } -void Game::processPlayerModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeMode) +void Game::processPlayerModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeMode, Otc::PVPModes pvpMode) { m_fightMode = fightMode; m_chaseMode = chaseMode; m_safeFight = safeMode; + m_pvpMode = pvpMode; g_lua.callGlobalField("g_game", "onFightModeChange", fightMode); g_lua.callGlobalField("g_game", "onChaseModeChange", chaseMode); g_lua.callGlobalField("g_game", "onSafeFightChange", safeMode); + g_lua.callGlobalField("g_game", "onPVPModeChange", pvpMode); } void Game::processPing() @@ -1195,7 +1199,7 @@ void Game::setChaseMode(Otc::ChaseModes chaseMode) if(m_chaseMode == chaseMode) return; m_chaseMode = chaseMode; - m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight); + m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight, m_pvpMode); g_lua.callGlobalField("g_game", "onChaseModeChange", chaseMode); } @@ -1206,7 +1210,7 @@ void Game::setFightMode(Otc::FightModes fightMode) if(m_fightMode == fightMode) return; m_fightMode = fightMode; - m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight); + m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight, m_pvpMode); g_lua.callGlobalField("g_game", "onFightModeChange", fightMode); } @@ -1217,10 +1221,21 @@ void Game::setSafeFight(bool on) if(m_safeFight == on) return; m_safeFight = on; - m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight); + m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight, m_pvpMode); g_lua.callGlobalField("g_game", "onSafeFightChange", on); } +void Game::setPVPMode(Otc::PVPModes pvpMode) +{ + if(!canPerformGameAction()) + return; + if(m_pvpMode == pvpMode) + return; + m_pvpMode = pvpMode; + m_protocolGame->sendChangeFightModes(m_fightMode, m_chaseMode, m_safeFight, m_pvpMode); + g_lua.callGlobalField("g_game", "onPVPModeChange", pvpMode); +} + void Game::inspectNpcTrade(const ItemPtr& item) { if(!canPerformGameAction() || !item) diff --git a/src/client/game.h b/src/client/game.h index a63ff0f0..d2de19ed 100644 --- a/src/client/game.h +++ b/src/client/game.h @@ -74,7 +74,7 @@ protected: void processWalkCancel(Otc::Direction direction); void processPlayerHelpers(int helpers); - void processPlayerModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeMode); + void processPlayerModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeMode, Otc::PVPModes pvpMode); // message related void processTextMessage(Otc::MessageMode mode, const std::string& text); @@ -211,9 +211,11 @@ public: void setChaseMode(Otc::ChaseModes chaseMode); void setFightMode(Otc::FightModes fightMode); void setSafeFight(bool on); + void setPVPMode(Otc::PVPModes pvpMode); Otc::ChaseModes getChaseMode() { return m_chaseMode; } Otc::FightModes getFightMode() { return m_fightMode; } bool isSafeFight() { return m_safeFight; } + Otc::PVPModes getPVPMode() { return m_pvpMode; } // npc trade related void inspectNpcTrade(const ItemPtr& item); @@ -336,6 +338,7 @@ private: int m_pingDelay; Otc::FightModes m_fightMode; Otc::ChaseModes m_chaseMode; + Otc::PVPModes m_pvpMode; Otc::Direction m_lastWalkDir; bool m_safeFight; bool m_canReportBugs; diff --git a/src/client/luafunctions.cpp b/src/client/luafunctions.cpp index 22bfe4e3..f71dace8 100644 --- a/src/client/luafunctions.cpp +++ b/src/client/luafunctions.cpp @@ -218,9 +218,11 @@ void Client::registerLuaFunctions() g_lua.bindSingletonFunction("g_game", "removeVip", &Game::removeVip, &g_game); g_lua.bindSingletonFunction("g_game", "setChaseMode", &Game::setChaseMode, &g_game); g_lua.bindSingletonFunction("g_game", "setFightMode", &Game::setFightMode, &g_game); + g_lua.bindSingletonFunction("g_game", "setPVPMode", &Game::setPVPMode, &g_game); g_lua.bindSingletonFunction("g_game", "setSafeFight", &Game::setSafeFight, &g_game); g_lua.bindSingletonFunction("g_game", "getChaseMode", &Game::getChaseMode, &g_game); g_lua.bindSingletonFunction("g_game", "getFightMode", &Game::getFightMode, &g_game); + g_lua.bindSingletonFunction("g_game", "getPVPMode", &Game::getPVPMode, &g_game); g_lua.bindSingletonFunction("g_game", "isSafeFight", &Game::isSafeFight, &g_game); g_lua.bindSingletonFunction("g_game", "inspectNpcTrade", &Game::inspectNpcTrade, &g_game); g_lua.bindSingletonFunction("g_game", "buyItem", &Game::buyItem, &g_game); diff --git a/src/client/protocolgame.h b/src/client/protocolgame.h index 87e35d73..d7d2df21 100644 --- a/src/client/protocolgame.h +++ b/src/client/protocolgame.h @@ -83,7 +83,7 @@ public: void sendCloseRuleViolation(const std::string& reporter); void sendCancelRuleViolation(); void sendCloseNpcChannel(); - void sendChangeFightModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeFight); + void sendChangeFightModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeFight, Otc::PVPModes pvpMode); void sendAttack(uint creatureId, uint seq); void sendFollow(uint creatureId, uint seq); void sendInviteToParty(uint creatureId); diff --git a/src/client/protocolgameparse.cpp b/src/client/protocolgameparse.cpp index 4bb6b0d5..343558f7 100644 --- a/src/client/protocolgameparse.cpp +++ b/src/client/protocolgameparse.cpp @@ -1158,11 +1158,11 @@ void ProtocolGame::parsePlayerModes(const InputMessagePtr& msg) int chaseMode = msg->getU8(); bool safeMode = msg->getU8(); - //TODO: implement pvp modes + int pvpMode = 0; if(g_game.getFeature(Otc::GamePVPMode)) - msg->getU8(); // pvp mode + pvpMode = msg->getU8(); - g_game.processPlayerModes((Otc::FightModes)fightMode, (Otc::ChaseModes)chaseMode, safeMode); + g_game.processPlayerModes((Otc::FightModes)fightMode, (Otc::ChaseModes)chaseMode, safeMode, (Otc::PVPModes)pvpMode); } void ProtocolGame::parseSpellCooldown(const InputMessagePtr& msg) diff --git a/src/client/protocolgamesend.cpp b/src/client/protocolgamesend.cpp index 35d7075a..aaa05d4c 100644 --- a/src/client/protocolgamesend.cpp +++ b/src/client/protocolgamesend.cpp @@ -573,7 +573,7 @@ void ProtocolGame::sendCloseNpcChannel() send(msg); } -void ProtocolGame::sendChangeFightModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeFight) +void ProtocolGame::sendChangeFightModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeFight, Otc::PVPModes pvpMode) { OutputMessagePtr msg(new OutputMessage); msg->addU8(Proto::ClientChangeFightModes); @@ -581,9 +581,8 @@ void ProtocolGame::sendChangeFightModes(Otc::FightModes fightMode, Otc::ChaseMod msg->addU8(chaseMode); msg->addU8(safeFight ? 0x01: 0x00); - //TODO: implement pvp modes if(g_game.getFeature(Otc::GamePVPMode)) - msg->addU8(0); // pvp mode + msg->addU8(pvpMode); send(msg); }