improve containers

This commit is contained in:
Henrique Santiago 2012-01-12 22:31:39 -02:00
parent b812d60690
commit ea70f90e92
14 changed files with 169 additions and 36 deletions

View File

@ -14,5 +14,7 @@ Module
require 'uitabbar' require 'uitabbar'
require 'uipopupmenu' require 'uipopupmenu'
require 'uiwindow' require 'uiwindow'
require 'uiitem'
require 'tooltip/tooltip' require 'tooltip/tooltip'
require 'messagebox/messagebox' require 'messagebox/messagebox'

View File

@ -0,0 +1,6 @@
function UIItem:onMouseRelease(mousePosition, mouseButton)
local item = self:getItem()
if not item or not self:containsPoint(mousePosition) then return false end
return Game.processMouseAction(mousePosition, mouseButton, nil, item, item, nil, item)
end

View File

@ -7,11 +7,12 @@ Module
dependencies: dependencies:
- game_healthbar - game_healthbar
- game_inventory - game_inventory
- game_skills //- game_skills
- game_textmessage - game_textmessage
- game_viplist - game_viplist
- game_console - game_console
- game_outfit - game_outfit
- game_containers
onLoad: | onLoad: |
require 'game' require 'game'

View File

@ -1,4 +1,15 @@
function Thing:isInsideContainer()
local pos = self:getPos()
return (pos and pos.x == 65535 and pos.y >= 64)
end
function Thing:getContainerId()
local pos = self:getPos()
if not pos then return 0 end
return pos.y - 64
end
-- public functions -- public functions
function Game.processMouseAction(menuPosition, mouseButton, autoWalk, lookThing, useThing, creatureThing, multiUseThing) function Game.processMouseAction(menuPosition, mouseButton, autoWalk, lookThing, useThing, creatureThing, multiUseThing)
local keyboardModifiers = g_window.getKeyboardModifiers() local keyboardModifiers = g_window.getKeyboardModifiers()
@ -18,7 +29,7 @@ function Game.processMouseAction(menuPosition, mouseButton, autoWalk, lookThing,
if mouseButton == MouseLeftButton and selectedThing then if mouseButton == MouseLeftButton and selectedThing then
Game.useWith(Game.getSelectedThing(), useThing) Game.useWith(Game.getSelectedThing(), useThing)
Game.setSelectedThing(nil) Game.setSelectedThing(nil)
-- restore cursor restoreCursor()
return true return true
elseif keyboardModifiers == KeyboardNoModifier and mouseButton == MouseRightButton then elseif keyboardModifiers == KeyboardNoModifier and mouseButton == MouseRightButton then
Game.createThingMenu(menuPosition, lookThing, useThing, creatureThing) Game.createThingMenu(menuPosition, lookThing, useThing, creatureThing)
@ -28,7 +39,11 @@ function Game.processMouseAction(menuPosition, mouseButton, autoWalk, lookThing,
return true return true
elseif useThing and keyboardModifiers == KeyboardCtrlModifier and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then elseif useThing and keyboardModifiers == KeyboardCtrlModifier and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then
if useThing:isContainer() then if useThing:isContainer() then
print "open" if useThing:isInsideContainer() then
Game.open(useThing, useThing:getContainerId())
else
Game.open(useThing, Containers.getFreeContainerId())
end
elseif useThing:isMultiUse() then elseif useThing:isMultiUse() then
Game.setSelectedThing(useThing) Game.setSelectedThing(useThing)
setTargetCursor() setTargetCursor()
@ -50,12 +65,16 @@ function Game.processMouseAction(menuPosition, mouseButton, autoWalk, lookThing,
if multiUseThing:asCreature() then if multiUseThing:asCreature() then
Game.attack(multiUseThing:asCreature()) Game.attack(multiUseThing:asCreature())
elseif multiUseThing:isContainer() then elseif multiUseThing:isContainer() then
print "open" if multiUseThing:isInsideContainer() then
Game.open(multiUseThing, multiUseThing:getContainerId())
else
Game.open(multiUseThing, Containers.getFreeContainerId())
end
elseif multiUseThing:isMultiUse() then elseif multiUseThing:isMultiUse() then
Game.setSelectedThing(multiUseThing) Game.setSelectedThing(multiUseThing)
setTargetCursor() setTargetCursor()
else else
Game.use(useThing) Game.use(multiUseThing)
end end
return true return true
elseif lookThing and keyboardModifiers == KeyboardShiftModifier and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then elseif lookThing and keyboardModifiers == KeyboardShiftModifier and (mouseButton == MouseLeftButton or mouseButton == MouseRightButton) then
@ -81,15 +100,17 @@ function Game.createThingMenu(menuPosition, lookThing, useThing, creatureThing)
menu:addOption('Look', function() Game.look(lookThing) end) menu:addOption('Look', function() Game.look(lookThing) end)
end end
-- Open or Use, depending if thing is a container
if useThing then if useThing then
if useThing:isContainer() then if useThing:isContainer() then
-- check for open in new window if useThing:isInsideContainer() then
menu:addOption('Open', function() print('open') end) menu:addOption('Open', function() Game.open(useThing, useThing:getContainerId()) end)
menu:addOption('Open in new window', function() Game.open(useThing, Containers.getFreeContainerId()) end)
else
menu:addOption('Open', function() Game.open(useThing, Containers.getFreeContainerId()) end)
end
else else
if useThing:isMultiUse() then if useThing:isMultiUse() then
setTargetCursor() menu:addOption('Use with ...', function() Game.setSelectedThing(useThing) setTargetCursor() end)
menu:addOption('Use with ...', function() Game.setSelectedThing(useThing) end)
else else
menu:addOption('Use', function() Game.use(useThing) end) menu:addOption('Use', function() Game.use(useThing) end)
end end
@ -179,3 +200,4 @@ function Game.createThingMenu(menuPosition, lookThing, useThing, creatureThing)
menu:display(menuPosition) menu:display(menuPosition)
end end

View File

@ -0,0 +1,13 @@
MiniWindow
size: 200 186
padding-top: 30
padding-left: 10
layout:
type: grid
cell-size: 32 32
cell-spacing: 5
num-columns: 4
num-lines: 5

View File

@ -0,0 +1,79 @@
Containers = {}
-- private variables
local m_containers = {}
-- public functions
function Containers.clean()
m_containers = {}
end
function Containers.getFreeContainerId()
for i=0,15 do
if not m_containers[i] then
return i
end
end
return 0
end
-- hooked events
function Containers.onContainerOpen(containerId, itemId, name, capacity, hasParent)
local container = m_containers[containerId]
if container then
Game.gameRightPanel:removeChild(container)
end
container = displayUI('container.otui', { parent = Game.gameRightPanel })
container:setText(name)
-- set icon, itemid
-- closebutton
-- resize
if hasParent then
-- parent button
end
container.itemCount = 0
container.capacity = capacity
for i=1,capacity do
local item = UIItem.create()
item:setStyle('Item')
container:addChild(item)
end
m_containers[containerId] = container
print("opencid ".. containerId)
end
function Containers.onContainerClose(containerId)
print("closecid ".. containerId)
local container = m_containers[containerId]
if container then
Game.gameRightPanel:removeChild(container)
end
m_containers[containerId] = nil
end
function Containers.onContainerAddItem(containerId, item)
print("addcid ".. containerId)
local container = m_containers[containerId]
if not container or not item or container.itemCount >= container.capacity then return end
-- maybe this has to be moved to client internal's files
local pos = item:getPos()
pos.z = container.itemCount
item:setPos(pos)
local itemWidget = container:getChildByIndex(container.itemCount + 1)
itemWidget:setItem(item)
container.itemCount = container.itemCount + 1
end
connect(Game, { onLogin = Containers.clean,
onLogout = Containers.clean,
onContainerOpen = Containers.onContainerOpen,
onContainerClose = Containers.onContainerClose,
onContainerAddItem = Containers.onContainerAddItem })

View File

@ -0,0 +1,7 @@
Module
name: game_containers
description: Manage containers
author: OTClient team
website: https://github.com/edubart/otclient
onLoad: |
require 'containers'

View File

@ -29,12 +29,6 @@ function Inventory.onSoulChange(soul)
widget:setText("Soul:\n" .. soul) widget:setText("Soul:\n" .. soul)
end end
function Inventory.onInventoryItemMouseRelease(itemWidget, mousePosition, mouseButton)
local item = itemWidget:getItem()
if not item or not itemWidget:containsPoint(mousePosition) then return false end
return Game.processMouseAction(mousePosition, mouseButton, nil, item, item, nil, item)
end
connect(Game, { onLogin = Inventory.create, connect(Game, { onLogin = Inventory.create,
onLogout = Inventory.destroy, onLogout = Inventory.destroy,
onInventoryChange = Inventory.onInventoryChange, onInventoryChange = Inventory.onInventoryChange,

View File

@ -1,6 +1,3 @@
InvetoryItem < Item
&onMouseRelease: Inventory.onInventoryItemMouseRelease
UIWindow UIWindow
width: 192 width: 192
height: 148 height: 148
@ -9,34 +6,34 @@ UIWindow
margin-right: 6 margin-right: 6
move-policy: free updated move-policy: free updated
InvetoryItem Item
// head // head
id: slot1 id: slot1
anchors.top: parent.top anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
InvetoryItem Item
// armor // armor
id: slot4 id: slot4
anchors.top: prev.bottom anchors.top: prev.bottom
anchors.horizontalCenter: prev.horizontalCenter anchors.horizontalCenter: prev.horizontalCenter
margin-top: 5 margin-top: 5
InvetoryItem Item
// legs // legs
id: slot7 id: slot7
anchors.top: prev.bottom anchors.top: prev.bottom
anchors.horizontalCenter: prev.horizontalCenter anchors.horizontalCenter: prev.horizontalCenter
margin-top: 5 margin-top: 5
InvetoryItem Item
// feet // feet
id: slot8 id: slot8
anchors.top: prev.bottom anchors.top: prev.bottom
anchors.horizontalCenter: prev.horizontalCenter anchors.horizontalCenter: prev.horizontalCenter
margin-top: 5 margin-top: 5
InvetoryItem Item
// necklace // necklace
id: slot2 id: slot2
anchors.top: parent.top anchors.top: parent.top
@ -44,21 +41,21 @@ UIWindow
margin-top: 10 margin-top: 10
margin-right: 5 margin-right: 5
InvetoryItem Item
// left // left
id: slot6 id: slot6
anchors.top: prev.bottom anchors.top: prev.bottom
anchors.horizontalCenter: prev.horizontalCenter anchors.horizontalCenter: prev.horizontalCenter
margin-top: 5 margin-top: 5
InvetoryItem Item
// ring // ring
id: slot9 id: slot9
anchors.top: prev.bottom anchors.top: prev.bottom
anchors.horizontalCenter: prev.horizontalCenter anchors.horizontalCenter: prev.horizontalCenter
margin-top: 5 margin-top: 5
InvetoryItem Item
// backpack // backpack
id: slot3 id: slot3
anchors.top: parent.top anchors.top: parent.top
@ -66,14 +63,14 @@ UIWindow
margin-top: 10 margin-top: 10
margin-left: 5 margin-left: 5
InvetoryItem Item
// right // right
id: slot5 id: slot5
anchors.top: prev.bottom anchors.top: prev.bottom
anchors.horizontalCenter: prev.horizontalCenter anchors.horizontalCenter: prev.horizontalCenter
margin-top: 5 margin-top: 5
InvetoryItem Item
// ammo // ammo
id: slot10 id: slot10
anchors.top: prev.bottom anchors.top: prev.bottom

View File

@ -125,7 +125,7 @@ void Game::processTextMessage(const std::string& type, const std::string& messag
void Game::processContainerAddItem(int containerId, const ItemPtr& item) void Game::processContainerAddItem(int containerId, const ItemPtr& item)
{ {
if(item) if(item)
item->setPos(Position(65535, containerId, 0)); item->setPos(Position(65535, containerId + 0x40, 0));
g_lua.callGlobalField("Game", "onContainerAddItem", containerId, item); g_lua.callGlobalField("Game", "onContainerAddItem", containerId, item);
} }
@ -250,6 +250,16 @@ void Game::look(const ThingPtr& thing)
m_protocolGame->sendLookAt(thing->getPos(), thing->getId(), stackpos); m_protocolGame->sendLookAt(thing->getPos(), thing->getId(), stackpos);
} }
void Game::open(const ThingPtr& thing, int containerId)
{
if(!m_online || !thing || !checkBotProtection())
return;
int stackpos = getThingStackpos(thing);
if(stackpos != -1)
m_protocolGame->sendUseItem(thing->getPos(), thing->getId(), stackpos, containerId);
}
void Game::use(const ThingPtr& thing) void Game::use(const ThingPtr& thing)
{ {
if(!m_online || !thing || !checkBotProtection()) if(!m_online || !thing || !checkBotProtection())
@ -257,7 +267,7 @@ void Game::use(const ThingPtr& thing)
int stackpos = getThingStackpos(thing); int stackpos = getThingStackpos(thing);
if(stackpos != -1) if(stackpos != -1)
m_protocolGame->sendUseItem(thing->getPos(), thing->getId(), stackpos, 0);// last 0 has something to do with container m_protocolGame->sendUseItem(thing->getPos(), thing->getId(), stackpos, 0);
} }
void Game::useWith(const ThingPtr& fromThing, const ThingPtr& toThing) void Game::useWith(const ThingPtr& fromThing, const ThingPtr& toThing)

View File

@ -57,6 +57,7 @@ public:
void walk(Otc::Direction direction); void walk(Otc::Direction direction);
void turn(Otc::Direction direction); void turn(Otc::Direction direction);
void look(const ThingPtr& thing); void look(const ThingPtr& thing);
void open(const ThingPtr& thing, int containerId);
void use(const ThingPtr& thing); void use(const ThingPtr& thing);
void useWith(const ThingPtr& fromThing, const ThingPtr& toThing); void useWith(const ThingPtr& fromThing, const ThingPtr& toThing);
void attack(const CreaturePtr& creature); void attack(const CreaturePtr& creature);

View File

@ -179,6 +179,7 @@ void OTClient::registerLuaFunctions()
g_lua.bindClassStaticFunction<Game>("openOutfitWindow", std::bind(&Game::openOutfitWindow, &g_game)); g_lua.bindClassStaticFunction<Game>("openOutfitWindow", std::bind(&Game::openOutfitWindow, &g_game));
g_lua.bindClassStaticFunction<Game>("setOutfit", std::bind(&Game::setOutfit, &g_game, _1)); g_lua.bindClassStaticFunction<Game>("setOutfit", std::bind(&Game::setOutfit, &g_game, _1));
g_lua.bindClassStaticFunction<Game>("look", std::bind(&Game::look, &g_game, _1)); g_lua.bindClassStaticFunction<Game>("look", std::bind(&Game::look, &g_game, _1));
g_lua.bindClassStaticFunction<Game>("open", std::bind(&Game::open, &g_game, _1, _2));
g_lua.bindClassStaticFunction<Game>("use", std::bind(&Game::use, &g_game, _1)); g_lua.bindClassStaticFunction<Game>("use", std::bind(&Game::use, &g_game, _1));
g_lua.bindClassStaticFunction<Game>("useWith", std::bind(&Game::useWith, &g_game, _1, _2)); g_lua.bindClassStaticFunction<Game>("useWith", std::bind(&Game::useWith, &g_game, _1, _2));
g_lua.bindClassStaticFunction<Game>("attack", std::bind(&Game::attack, &g_game, _1)); g_lua.bindClassStaticFunction<Game>("attack", std::bind(&Game::attack, &g_game, _1));

View File

@ -441,7 +441,7 @@ void ProtocolGame::parseOpenContainer(InputMessage& msg)
for(int i = 0; i < itemCount; i++) { for(int i = 0; i < itemCount; i++) {
ItemPtr item = internalGetItem(msg); ItemPtr item = internalGetItem(msg);
g_lua.callGlobalField("Game", "onContainerAddItem", containerId, item); g_game.processContainerAddItem(containerId, item);
} }
} }
@ -455,7 +455,7 @@ void ProtocolGame::parseContainerAddItem(InputMessage& msg)
{ {
int containerId = msg.getU8(); int containerId = msg.getU8();
ItemPtr item = internalGetItem(msg); ItemPtr item = internalGetItem(msg);
g_lua.callGlobalField("Game", "onContainerAddItem", containerId, item); g_game.processContainerAddItem(containerId, item);
} }
void ProtocolGame::parseContainerUpdateItem(InputMessage& msg) void ProtocolGame::parseContainerUpdateItem(InputMessage& msg)
@ -470,7 +470,7 @@ void ProtocolGame::parseContainerRemoveItem(InputMessage& msg)
{ {
int containerId = msg.getU8(); int containerId = msg.getU8();
int slot = msg.getU8(); int slot = msg.getU8();
g_lua.callGlobalField("Game", "onContainerUpdateItem", containerId, slot); g_lua.callGlobalField("Game", "onContainerRemoveItem", containerId, slot);
} }
void ProtocolGame::parseAddInventoryItem(InputMessage& msg) void ProtocolGame::parseAddInventoryItem(InputMessage& msg)

View File

@ -98,7 +98,7 @@ public:
return Otc::InvalidDirection; return Otc::InvalidDirection;
} }
bool isValid() const { return x >= 0 && y >= 0 && z >= 0 && x < 65536 && y < 65536 && z < 16; } bool isValid() const { return x >= 0 && y >= 0 && z >= 0 && x <= 65535 && y <= 65535 && z <= 255; }
Position operator+(const Position& other) const { return Position(x + other.x, y + other.y, z + other.z); } Position operator+(const Position& other) const { return Position(x + other.x, y + other.y, z + other.z); }
Position& operator+=(const Position& other) { x+=other.x; y+=other.y; z +=other.z; return *this; } Position& operator+=(const Position& other) { x+=other.x; y+=other.y; z +=other.z; return *this; }