Files
caminus/vault/models.py
2012-11-17 16:06:13 -05:00

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)