<s> import sys <EOL> import types <EOL> from minecraft_data . v1_8 import windows as windows_by_id <EOL> from minecraft_data . v1_8 import windows_list <EOL> from spockbot . mcdata import constants , get_item_or_block <EOL> from spockbot . mcdata . blocks import Block <EOL> from spockbot . mcdata . items import Item <EOL> from spockbot . mcdata . utils import camel_case , snake_case <EOL> def make_slot_check ( wanted ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( wanted , types . FunctionType ) : <EOL> return wanted <EOL> if isinstance ( wanted , int ) : <EOL> item , meta = wanted , None <EOL> elif isinstance ( wanted , Slot ) : <EOL> item , meta = wanted . item_id , wanted . damage <EOL> elif isinstance ( wanted , ( Item , Block ) ) : <EOL> item , meta = wanted . id , wanted . metadata <EOL> elif isinstance ( wanted , str ) : <EOL> item_or_block = get_item_or_block ( wanted , init = True ) <EOL> item , meta = item_or_block . id , item_or_block . metadata <EOL> else : <EOL> try : <EOL> item , meta = wanted <EOL> except TypeError : <EOL> raise ValueError ( '<STR_LIT>' % wanted ) <EOL> return lambda slot : item == slot . item_id and meta in ( None , slot . damage ) <EOL> class Slot ( object ) : <EOL> def __init__ ( self , window , slot_nr , id = constants . INV_ITEMID_EMPTY , <EOL> damage = <NUM_LIT:0> , amount = <NUM_LIT:0> , enchants = None ) : <EOL> self . window = window <EOL> self . slot_nr = slot_nr <EOL> self . item_id = id <EOL> self . damage = damage <EOL> self . amount = amount <EOL> self . nbt = enchants <EOL> self . item = get_item_or_block ( self . item_id , self . damage ) or Item ( ) <EOL> def move_to_window ( self , window , slot_nr ) : <EOL> self . window , self . slot_nr = window , slot_nr <EOL> @ property <EOL> def is_empty ( self ) : <EOL> return self . amount <= <NUM_LIT:0> <EOL> def matches ( self , other ) : <EOL> return make_slot_check ( other ) ( self ) <EOL> def stacks_with ( self , other ) : <EOL> if self . item_id != other . item_id : <EOL> return False <EOL> if self . damage != other . damage : <EOL> return False <EOL> return self . item . stack_size != <NUM_LIT:1> <EOL> def get_dict ( self ) : <EOL> """<STR_LIT>""" <EOL> data = { '<STR_LIT:id>' : self . item_id } <EOL> if self . item_id != constants . INV_ITEMID_EMPTY : <EOL> data [ '<STR_LIT>' ] = self . damage <EOL> data [ '<STR_LIT>' ] = self . amount <EOL> if self . nbt is not None : <EOL> data [ '<STR_LIT>' ] = self . nbt <EOL> return data <EOL> def copy ( self ) : <EOL> return Slot ( self . window , self . slot_nr , self . item_id , <EOL> self . damage , self . amount , self . nbt ) <EOL> def __bool__ ( self ) : <EOL> return not self . is_empty <EOL> def __repr__ ( self ) : <EOL> if self . is_empty : <EOL> s = '<STR_LIT>' <EOL> else : <EOL> item = self . item <EOL> s = '<STR_LIT>' % ( self . amount , item . stack_size , str ( item ) ) <EOL> if self . slot_nr != - <NUM_LIT:1> : <EOL> s += '<STR_LIT>' % self . slot_nr <EOL> if self . window : <EOL> s += '<STR_LIT>' % self . window <EOL> return '<STR_LIT>' % s <EOL> class SlotCursor ( Slot ) : <EOL> def __init__ ( self , id = constants . INV_ITEMID_EMPTY , damage = <NUM_LIT:0> , amount = <NUM_LIT:0> , <EOL> enchants = None ) : <EOL> class CursorWindow ( object ) : <EOL> window_id = constants . INV_WINID_CURSOR <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' <EOL> super ( SlotCursor , self ) . __init__ ( <EOL> CursorWindow ( ) , constants . INV_SLOT_NR_CURSOR , <EOL> id , damage , amount , enchants ) <EOL> class BaseClick ( object ) : <EOL> def get_packet ( self , inv_plugin ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( ) <EOL> def apply ( self , inv_plugin ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( ) <EOL> def on_success ( self , inv_plugin , emit_set_slot ) : <EOL> """<STR_LIT>""" <EOL> self . dirty = set ( ) <EOL> self . apply ( inv_plugin ) <EOL> for changed_slot in self . dirty : <EOL> emit_set_slot ( changed_slot ) <EOL> def copy_slot_type ( self , slot_from , slot_to ) : <EOL> slot_to . item_id , slot_to . damage = slot_from . item_id , slot_from . damage <EOL> slot_to . nbt = slot_from . nbt <EOL> self . mark_dirty ( slot_to ) <EOL> def swap_slots ( self , slot_a , slot_b ) : <EOL> slot_a . item_id , slot_b . item_id = slot_b . item_id , slot_a . item_id <EOL> slot_a . damage , slot_b . damage = slot_b . damage , slot_a . damage <EOL> slot_a . amount , slot_b . amount = slot_b . amount , slot_a . amount <EOL> slot_a . nbt , slot_b . nbt = slot_b . nbt , slot_a . nbt <EOL> self . mark_dirty ( slot_a ) <EOL> self . mark_dirty ( slot_b ) <EOL> def transfer ( self , from_slot , to_slot , max_amount ) : <EOL> transfer_amount = min ( max_amount , from_slot . amount , <EOL> to_slot . item . stack_size - to_slot . amount ) <EOL> if transfer_amount <= <NUM_LIT:0> : <EOL> return <EOL> self . copy_slot_type ( from_slot , to_slot ) <EOL> to_slot . amount += transfer_amount <EOL> from_slot . amount -= transfer_amount <EOL> self . cleanup_if_empty ( from_slot ) <EOL> def cleanup_if_empty ( self , slot ) : <EOL> if slot . is_empty : <EOL> empty_slot_at_same_position = Slot ( slot . window , slot . slot_nr ) <EOL> self . copy_slot_type ( empty_slot_at_same_position , slot ) <EOL> self . mark_dirty ( slot ) <EOL> def mark_dirty ( self , slot ) : <EOL> self . dirty . add ( slot ) <EOL> class SingleClick ( BaseClick ) : <EOL> def __init__ ( self , slot , button = constants . INV_BUTTON_LEFT ) : <EOL> self . slot = slot <EOL> self . button = button <EOL> if button not in ( constants . INV_BUTTON_LEFT , <EOL> constants . INV_BUTTON_RIGHT ) : <EOL> raise NotImplementedError ( <EOL> '<STR_LIT>' % button ) <EOL> def get_packet ( self , inv_plugin ) : <EOL> slot_nr = self . slot . slot_nr <EOL> if self . slot == inv_plugin . cursor_slot : <EOL> slot_nr = constants . INV_OUTSIDE_WINDOW <EOL> return { <EOL> '<STR_LIT>' : slot_nr , <EOL> '<STR_LIT>' : self . button , <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> '<STR_LIT>' : self . slot . get_dict ( ) , <EOL> } <EOL> def apply ( self , inv_plugin ) : <EOL> clicked = self . slot <EOL> cursor = inv_plugin . cursor_slot <EOL> if clicked == cursor : <EOL> if self . button == constants . INV_BUTTON_LEFT : <EOL> clicked . amount = <NUM_LIT:0> <EOL> elif self . button == constants . INV_BUTTON_RIGHT : <EOL> clicked . amount -= <NUM_LIT:1> <EOL> self . cleanup_if_empty ( clicked ) <EOL> elif self . button == constants . INV_BUTTON_LEFT : <EOL> if clicked . stacks_with ( cursor ) : <EOL> self . transfer ( cursor , clicked , cursor . amount ) <EOL> else : <EOL> self . swap_slots ( cursor , clicked ) <EOL> elif self . button == constants . INV_BUTTON_RIGHT : <EOL> if cursor . is_empty : <EOL> self . transfer ( clicked , cursor , ( clicked . amount + <NUM_LIT:1> ) // <NUM_LIT:2> ) <EOL> elif clicked . is_empty or clicked . stacks_with ( cursor ) : <EOL> self . transfer ( cursor , clicked , <NUM_LIT:1> ) <EOL> else : <EOL> self . swap_slots ( cursor , clicked ) <EOL> else : <EOL> raise NotImplementedError ( <EOL> '<STR_LIT>' % self . button ) <EOL> class DropClick ( BaseClick ) : <EOL> def __init__ ( self , slot , drop_stack = False ) : <EOL> self . slot = slot <EOL> self . drop_stack = drop_stack <EOL> def get_packet ( self , inv_plugin ) : <EOL> if self . slot == inv_plugin . cursor_slot : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> if not inv_plugin . cursor_slot . is_empty : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> return { <EOL> '<STR_LIT>' : self . slot . slot_nr , <EOL> '<STR_LIT>' : <NUM_LIT:1> if self . drop_stack else <NUM_LIT:0> , <EOL> '<STR_LIT>' : <NUM_LIT:4> , <EOL> '<STR_LIT>' : inv_plugin . cursor_slot . get_dict ( ) , <EOL> } <EOL> def apply ( self , inv_plugin ) : <EOL> if self . drop_stack : <EOL> self . slot . amount = <NUM_LIT:0> <EOL> else : <EOL> self . slot . amount -= <NUM_LIT:1> <EOL> self . cleanup_if_empty ( self . slot ) <EOL> class Window ( object ) : <EOL> """<STR_LIT>""" <EOL> name = None <EOL> inv_type = None <EOL> inv_data = { } <EOL> def __init__ ( self , window_id , title , slot_count , <EOL> inv_type = None , persistent_slots = None , eid = None ) : <EOL> assert not inv_type or inv_type == self . inv_type , '<STR_LIT>' % ( inv_type , self . inv_type ) <EOL> self . is_storage = slot_count > <NUM_LIT:0> <EOL> if not self . is_storage : <EOL> window_dict = windows_by_id [ inv_type ] <EOL> if '<STR_LIT>' in window_dict : <EOL> slot_count = max ( slot [ '<STR_LIT:index>' ] + slot . get ( '<STR_LIT:size>' , <NUM_LIT:1> ) <EOL> for slot in window_dict [ '<STR_LIT>' ] ) <EOL> self . window_id = window_id <EOL> self . title = title <EOL> self . eid = eid <EOL> self . slots = [ Slot ( self , slot_nr ) for slot_nr in range ( slot_count ) ] <EOL> if persistent_slots is None : <EOL> for slot_nr in range ( constants . INV_SLOTS_PERSISTENT ) : <EOL> self . slots . append ( Slot ( self , slot_nr + slot_count ) ) <EOL> else : <EOL> moved_slots = persistent_slots [ - constants . INV_SLOTS_PERSISTENT : ] <EOL> for slot_nr , moved_slot in enumerate ( moved_slots ) : <EOL> moved_slot . move_to_window ( self , slot_nr + slot_count ) <EOL> self . slots . append ( moved_slot ) <EOL> self . properties = { } <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( <EOL> self . __class__ . __name__ , <EOL> self . window_id , self . title , len ( self . slots ) ) <EOL> @ property <EOL> def persistent_slots ( self ) : <EOL> return self . slots [ - constants . INV_SLOTS_PERSISTENT : ] <EOL> @ property <EOL> def inventory_slots ( self ) : <EOL> return self . slots [ <EOL> - constants . INV_SLOTS_PERSISTENT : - constants . INV_SLOTS_HOTBAR ] <EOL> @ property <EOL> def hotbar_slots ( self ) : <EOL> return self . slots [ - constants . INV_SLOTS_HOTBAR : ] <EOL> @ property <EOL> def window_slots ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . slots [ : - constants . INV_SLOTS_PERSISTENT ] <EOL> def _make_window ( window_dict ) : <EOL> """<STR_LIT>""" <EOL> cls_name = '<STR_LIT>' % camel_case ( str ( window_dict [ '<STR_LIT:name>' ] ) ) <EOL> bases = ( Window , ) <EOL> attrs = { <EOL> '<STR_LIT>' : sys . modules [ __name__ ] , <EOL> '<STR_LIT:name>' : str ( window_dict [ '<STR_LIT:name>' ] ) , <EOL> '<STR_LIT>' : str ( window_dict [ '<STR_LIT:id>' ] ) , <EOL> '<STR_LIT>' : window_dict , <EOL> } <EOL> def make_slot_method ( index , size = <NUM_LIT:1> ) : <EOL> if size == <NUM_LIT:1> : <EOL> return lambda self : self . slots [ index ] <EOL> else : <EOL> return lambda self : self . slots [ index : ( index + size ) ] <EOL> for slots in window_dict . get ( '<STR_LIT>' , [ ] ) : <EOL> index = slots [ '<STR_LIT:index>' ] <EOL> size = slots . get ( '<STR_LIT:size>' , <NUM_LIT:1> ) <EOL> attr_name = snake_case ( str ( slots [ '<STR_LIT:name>' ] ) ) <EOL> attr_name += '<STR_LIT>' if size == <NUM_LIT:1> else '<STR_LIT>' <EOL> slots_method = make_slot_method ( index , size ) <EOL> slots_method . __name__ = attr_name <EOL> attrs [ attr_name ] = property ( slots_method ) <EOL> for i , prop_name in enumerate ( window_dict . get ( '<STR_LIT>' , [ ] ) ) : <EOL> def make_prop_method ( i ) : <EOL> return lambda self : self . properties [ i ] <EOL> prop_method = make_prop_method ( i ) <EOL> prop_name = snake_case ( str ( prop_name ) ) <EOL> prop_method . __name__ = prop_name <EOL> attrs [ prop_name ] = property ( prop_method ) <EOL> cls = type ( cls_name , bases , attrs ) <EOL> assert not hasattr ( sys . modules [ __name__ ] , cls_name ) , '<STR_LIT>' % ( cls_name , __name__ ) <EOL> setattr ( sys . modules [ __name__ ] , cls_name , cls ) <EOL> return cls <EOL> inv_types = { } <EOL> def _create_windows ( ) : <EOL> for window in windows_list : <EOL> cls = _make_window ( window ) <EOL> inv_types [ cls . inv_type ] = cls <EOL> _create_windows ( ) <EOL> _player_window = sys . modules [ __name__ ] . PlayerWindow <EOL> def _player_init ( self , * args , ** kwargs ) : <EOL> super ( _player_window , self ) . __init__ ( <EOL> constants . INV_WINID_PLAYER , self . name , constants . INV_SLOTS_PLAYER , <EOL> * args , ** kwargs ) <EOL> setattr ( _player_window , '<STR_LIT>' , _player_init ) </s>
