Files
caminus/vault/models.py
Torrie Fischer 61c39dc9c2 wip?
2023-06-10 13:21:31 +02:00

106 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 Event, ServerQueue, WebQueue
from minecraft.models import Item
from django.conf import settings
from caminus.bulkops import insert_many
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_update(sender, instance, created, *args, **kwargs):
if instance.item:
slots = [
{
'material': instance.item.material,
'quantity': instance.quantity,
'damage': instance.item.damage,
'data': instance.item.data,
'position': instance.position,
'name': instance.item.name(),
'durability': instance.item.metadata['durability']
}
]
else:
slots = [
{
'material': None,
'quantity': None,
'damage': None,
'data': None,
'position': instance.position,
'name': None,
'durability': None
}
]
evt = Event('vault-contents', player=instance.player.mc_username, items=slots)
ServerQueue.broadcast(evt)
WebQueue.broadcast(evt)
post_save.connect(send_vault_update, sender=VaultSlot, dispatch_uid='derp')
def ensure_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)
bulk = []
for pos in neededPositions:
bulk.append(VaultSlot(player=instance, position=pos))
insert_many(bulk)
post_save.connect(ensure_initial_slots, sender=MinecraftProfile)