forked from fogleman/Minecraft
-
Notifications
You must be signed in to change notification settings - Fork 33
/
inventory.py
135 lines (105 loc) · 4.26 KB
/
inventory.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# Imports, sorted alphabetically.
# Python packages
import sys
# Third-party packages
# Nothing for now...
# Modules from this project
from items import *
__all__ = (
'Inventory',
)
class Inventory:
sort_mode = 0
def __init__(self, slot_count = 27):
self.slot_count = slot_count
self.slots = [None] * self.slot_count
def __repr__(self):
return "Inventory(" + str(self.slot_count) + ")"
def find_empty_slot(self):
return next((index for index,value in enumerate(self.slots) if not value), -1)
def add_item(self, item_id, quantity = 1, durability = -1):
if quantity < 1 or item_id == 0:
return False
item_stack = self.get_item(item_id)
max_size = get_item(item_id).max_stack_size
retval = False
while quantity > 0:
# can't find an unfilled slot
if not item_stack:
# find an empty slot to store these items
index = self.find_empty_slot()
if index == -1 and len(self.slots) == self.slot_count:
return retval
# overflow ?
if quantity > max_size:
quantity -= max_size
item_stack = ItemStack(type=item_id, amount=max_size, durability=durability)
else:
item_stack = ItemStack(type=item_id, amount=quantity, durability=durability)
quantity = 0
self.slots[index] = item_stack
retval = True
else:
capacity = max_size - item_stack.amount
if quantity < capacity: # there is a slot with enough space
item_stack.change_amount(quantity)
return True
else: # overflow
quantity -= capacity
item_stack.change_amount(capacity)
# find next unfilled slot
item_stack = self.get_unfilled_item(item_id)
return True
def remove_item(self, item_id, quantity = 1):
if quantity < 1:
return False
index = self.get_index(item_id)
return self.remove_by_index(index, quantity)
def remove_by_index(self, index, quantity = 1):
if quantity < 1 or index < 0 or not self.slots[index]:
return False
retval = False
self.slots[index].change_amount(quantity*-1)
if self.slots[index].amount == 0:
self.slots[index] = None
retval = True
return retval
def remove_all_by_index(self, index):
self.slots[index] = None
def remove_unnecessary_stacks(self):
for i, slot in enumerate(self.slots):
if slot and slot.amount == 0:
self.slots[i] = None
def sort(self, reverse=True):
if self.sort_mode == 0:
self.sort_with_key(key=lambda x: x.id if x != None else -sys.maxsize - 1, reverse=True)
if self.sort_mode == 1:
self.sort_with_key(key=lambda x: x.amount if x != None else -sys.maxsize - 1, reverse=True)
elif self.sort_mode == 2:
self.sort_with_key(key=lambda x: x.amount if x != None else sys.maxsize - 1, reverse=False)
def sort_with_key(self, key, reverse=True):
self.slots = sorted(self.slots, key=key, reverse=reverse)
def change_sort_mode(self, change=1):
self.sort_mode += change
if self.sort_mode > 2:
self.sort_mode = 0
elif self.sort_mode < 0:
self.sort_mode = 2
self.sort()
def at(self, index):
index = int(index)
if 0 <= index < self.slot_count:
return self.slots[index]
return None
def get_index(self, item_id):
return next((index for index, x in enumerate(self.slots) if x and x.type == item_id), -1)
def get_item(self, item_id):
return next((x for x in self.slots if x and x.type == item_id), None)
def get_unfilled_item(self, item_id):
return next((x for x in self.slots if x and (x.type == item_id) and (x.amount < x.max_stack_size)), None)
def get_items(self):
return self.slots
def __str__(self):
return str(self.__dict__)
def __eq__(self, other):
return self.__dict__ == other.__dict__