102 lines
3.4 KiB
Python
102 lines
3.4 KiB
Python
from django.db import models
|
|
from minecraft.models import MinecraftProfile
|
|
from django.db.models.signals import post_save, post_delete
|
|
from api.events import VaultContentsEvent, broadcast_server_event
|
|
from minecraft.models import Item
|
|
from django.conf import settings
|
|
|
|
class VaultError(Exception):
|
|
pass
|
|
|
|
class VaultSlot(models.Model):
|
|
player = models.ForeignKey(MinecraftProfile, related_name='vault_slots')
|
|
quantity = models.IntegerField(default=-1)
|
|
position = models.IntegerField()
|
|
item = models.ForeignKey(Item, null=True, blank=True)
|
|
|
|
class Meta:
|
|
ordering = ['position']
|
|
|
|
def __unicode__(self):
|
|
return "%s.%s: %s %s"%(self.player, self.position, self.quantity, self.item)
|
|
|
|
@classmethod
|
|
def getEmptySlots(cls, player):
|
|
return cls.objects.filter(player=player, item=None)
|
|
|
|
@classmethod
|
|
def addToInventory(cls, player, item, quantity):
|
|
neededQuantity = quantity
|
|
stackTotal = item.metadata['stack']
|
|
slots = cls.findAvailableSlots(player, item, quantity)
|
|
for s in slots:
|
|
assert(neededQuantity >= 0)
|
|
if neededQuantity == 0:
|
|
break
|
|
if s.item is None:
|
|
s.item = item
|
|
s.quantity = 0
|
|
availableCapacity = min(stackTotal-s.quantity, neededQuantity)
|
|
s.quantity = min(stackTotal, neededQuantity)
|
|
neededQuantity -= availableCapacity
|
|
print "Used", availableCapacity, "in", s, "need", neededQuantity
|
|
s.save()
|
|
assert(neededQuantity == 0)
|
|
|
|
@classmethod
|
|
def findAvailableSlots(cls, player, item, quantity):
|
|
stackTotal = item.metadata['stack']
|
|
neededQuantity = quantity
|
|
slots = []
|
|
for slot in cls.objects.filter(player=player, item=item,
|
|
quantity__lt=stackTotal):
|
|
neededQuantity -= stackTotal-slot.quantity
|
|
slots.append(slot)
|
|
for slot in cls.objects.filter(player=player, item=None):
|
|
neededQuantity -= stackTotal
|
|
slots.append(slot)
|
|
if neededQuantity > 0:
|
|
raise VaultError, "Insufficient available slots."
|
|
return slots
|
|
|
|
def send_vault_delete(sender, instance, *args, **kwargs):
|
|
slots = [
|
|
{
|
|
'item': None,
|
|
'quantity': -1,
|
|
'damage': None,
|
|
'data': None,
|
|
'position': instance.position
|
|
}
|
|
]
|
|
broadcast_server_event(VaultContentsEvent(instance.player.mc_username,
|
|
slots))
|
|
|
|
def send_vault_update(sender, instance, created, *args, **kwargs):
|
|
if created and instance.item:
|
|
slots = [
|
|
{
|
|
'item': instance.item.material,
|
|
'quantity': instance.quantity,
|
|
'damage': instance.item.damage,
|
|
'data': instance.item.data,
|
|
'position': instance.position
|
|
}
|
|
]
|
|
broadcast_server_event(VaultContentsEvent(instance.player.mc_username, slots))
|
|
|
|
post_save.connect(send_vault_update, sender=VaultSlot, dispatch_uid='derp')
|
|
post_delete.connect(send_vault_delete, sender=VaultSlot, dispatch_uid='derp')
|
|
|
|
def create_initial_slots(sender, instance, created, *args, **kwargs):
|
|
slots = instance.vault_slots.all()
|
|
if len(slots) < settings.CAMINUS_VAULT_SLOTS:
|
|
neededPositions = range(0, settings.CAMINUS_VAULT_SLOTS)
|
|
for s in slots:
|
|
neededPositions.remove(s.position)
|
|
for pos in neededPositions:
|
|
VaultSlot.objects.create(player=instance, position=pos)
|
|
|
|
post_save.connect(create_initial_slots, sender=MinecraftProfile)
|
|
|