1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11 
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16 
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "illusions/duckman/illusions_duckman.h"
24 #include "illusions/duckman/duckman_inventory.h"
25 #include "illusions/actor.h"
26 #include "illusions/cursor.h"
27 #include "illusions/input.h"
28 #include "illusions/resources/scriptresource.h"
29 #include "engines/util.h"
30 
31 namespace Illusions {
32 
33 // DuckmanInventory
34 
DuckmanInventory(IllusionsEngine_Duckman * vm)35 DuckmanInventory::DuckmanInventory(IllusionsEngine_Duckman *vm)
36 	: _vm(vm) {
37 	initInventory();
38 }
39 
~DuckmanInventory()40 DuckmanInventory::~DuckmanInventory() {
41 }
42 
43 static const struct DMInventoryItem kInventoryItems[21] = {
44 	{0x40011, 0xE005B},
45 	{0x40099, 0xE001B},
46 	{0x4000F, 0xE000C},
47 	{0x40042, 0xE0012},
48 	{0x40044, 0xE000F},
49 	{0x40029, 0xE000D},
50 	{0x400A7, 0xE005D},
51 	{0x40096, 0xE001C},
52 	{0x40077, 0xE0010},
53 	{0x4008A, 0xE0033},
54 	{0x4004B, 0xE0045},
55 	{0x40054, 0xE0021},
56 	{0x400C6, 0xE005A},
57 	{0x4000B, 0xE005E},
58 	{0x4005F, 0xE0016},
59 	{0x40072, 0xE0017},
60 	{0x400AA, 0xE005F},
61 	{0x400B8, 0xE0050},
62 	{0x4001F, 0xE001A},
63 	{0x40095, 0xE0060},
64 	{0x40041, 0xE0053}
65 };
66 
initInventory()67 void DuckmanInventory::initInventory() {
68 	for (int y = 0; y < 4; y++) {
69 		for (int x = 0; x < 5; x++) {
70 			_inventorySlots.push_back(DMInventorySlot( 64 + x * 48,  52 + y * 32));
71 		}
72 	}
73 
74 	for (int i = 0; i < 21; i++) {
75 		_inventoryItems.push_back(kInventoryItems[i]);
76 	}
77 }
78 
openInventory()79 void DuckmanInventory::openInventory() {
80 
81 	for (uint i = 0; i < _inventorySlots.size(); ++i) {
82 		DMInventorySlot *inventorySlot = &_inventorySlots[i];
83 		if (inventorySlot->_objectId) {
84 			DMInventoryItem *inventoryItem = findInventoryItem(inventorySlot->_objectId);
85 			if (!_vm->_scriptResource->_properties.get(inventoryItem->_propertyId))
86 				inventorySlot->_objectId = 0;
87 		}
88 	}
89 
90 	for (uint i = 0; i < _inventoryItems.size(); ++i) {
91 		DMInventoryItem *inventoryItem = &_inventoryItems[i];
92 		if (_vm->_scriptResource->_properties.get(inventoryItem->_propertyId)) {
93 			DMInventorySlot *inventorySlot = findInventorySlot(inventoryItem->_objectId);
94 			if (inventorySlot) {
95 				Control *control = _vm->getObjectControl(inventoryItem->_objectId);
96 				control->setActorPosition(inventorySlot->_position);
97 				control->appearActor();
98 			} else {
99 				addInventoryItem(inventoryItem->_objectId);
100 			}
101 		}
102 	}
103 
104 }
105 
addInventoryItem(uint32 objectId)106 void DuckmanInventory::addInventoryItem(uint32 objectId) {
107 	DMInventorySlot *DMInventorySlot = findInventorySlot(0);
108 	DMInventorySlot->_objectId = objectId;
109 	Control *control = _vm->getObjectControl(objectId);
110 	control->setActorPosition(DMInventorySlot->_position);
111 	control->appearActor();
112 }
113 
clearInventorySlot(uint32 objectId)114 void DuckmanInventory::clearInventorySlot(uint32 objectId) {
115 	for (uint i = 0; i < _inventorySlots.size(); ++i) {
116 		if (_inventorySlots[i]._objectId == objectId)
117 			_inventorySlots[i]._objectId = 0;
118 	}
119 }
120 
putBackInventoryItem()121 void DuckmanInventory::putBackInventoryItem() {
122 	Common::Point mousePos = _vm->_input->getCursorPosition();
123 	if (_vm->_cursor._objectId) {
124 		DMInventorySlot *inventorySlot = findInventorySlot(_vm->_cursor._objectId);
125 		if (inventorySlot)
126 			inventorySlot->_objectId = 0;
127 		inventorySlot = findClosestInventorySlot(mousePos);
128 		inventorySlot->_objectId = _vm->_cursor._objectId;
129 		Control *control = _vm->getObjectControl(_vm->_cursor._objectId);
130 		control->setActorPosition(inventorySlot->_position);
131 		control->appearActor();
132 		_vm->_cursor._actorIndex = 7;
133 		_vm->stopCursorHoldingObject();
134 		_vm->_cursor._actorIndex = 2;
135 		_vm->_cursor._control->startSequenceActor(_vm->_cursor._sequenceId1, 2, 0);
136 		if (_vm->_cursor._currOverlappedControl)
137 			_vm->setCursorActorIndex(_vm->_cursor._actorIndex, 2, 0);
138 		else
139 			_vm->setCursorActorIndex(_vm->_cursor._actorIndex, 1, 0);
140 	}
141 }
142 
findInventorySlot(uint32 objectId)143 DMInventorySlot *DuckmanInventory::findInventorySlot(uint32 objectId) {
144 	for (uint i = 0; i < _inventorySlots.size(); ++i) {
145 		if (_inventorySlots[i]._objectId == objectId)
146 			return &_inventorySlots[i];
147 	}
148 	return 0;
149 }
150 
findInventoryItem(uint32 objectId)151 DMInventoryItem *DuckmanInventory::findInventoryItem(uint32 objectId) {
152 	for (uint i = 0; i < _inventoryItems.size(); ++i) {
153 		if (_inventoryItems[i]._objectId == objectId)
154 			return &_inventoryItems[i];
155 	}
156 	return 0;
157 }
158 
findClosestInventorySlot(Common::Point pos)159 DMInventorySlot *DuckmanInventory::findClosestInventorySlot(Common::Point pos) {
160 	int minDistance = 0xFFFFFF;
161 	DMInventorySlot *minInventorySlot = 0;
162 	for (uint i = 0; i < _inventorySlots.size(); ++i) {
163 		DMInventorySlot *inventorySlot = &_inventorySlots[i];
164 		if (inventorySlot->_objectId == 0) {
165 			int16 deltaX = ABS(inventorySlot->_position.x - pos.x);
166 			int16 deltaY = ABS(inventorySlot->_position.y - pos.y);
167 			int distance = deltaX * deltaX + deltaY * deltaY;
168 			if (inventorySlot->_objectId == 0 && distance < minDistance) {
169 				minDistance = distance;
170 				minInventorySlot = inventorySlot;
171 			}
172 		}
173 	}
174 	return minInventorySlot;
175 }
176 
177 } // End of namespace Illusions
178