def __init__(self, gobject_template, gobject_instance=None, **kwargs):
        super().__init__(**kwargs)

        self.update_packet_factory = UpdatePacketFactory(
            [ObjectTypes.TYPE_OBJECT, ObjectTypes.TYPE_GAMEOBJECT])

        self.gobject_template = gobject_template
        self.gobject_instance = gobject_instance

        self.guid = (gobject_instance.spawn_id
                     if gobject_instance else 0) | HighGuid.HIGHGUID_GAMEOBJECT

        if self.gobject_template:
            self.display_id = self.gobject_template.display_id

        if gobject_instance:
            self.state = self.gobject_instance.spawn_state
            self.location.x = self.gobject_instance.spawn_positionX
            self.location.y = self.gobject_instance.spawn_positionY
            self.location.z = self.gobject_instance.spawn_positionZ
            self.location.o = self.gobject_instance.spawn_orientation
            self.map_ = self.gobject_instance.spawn_map
            self.scale = self.gobject_template.scale

        self.object_type.append(ObjectTypes.TYPE_GAMEOBJECT)
Beispiel #2
0
    def update_surrounding(self):
        self.send_update_surrounding()
        GridManager.send_surrounding(NameQueryHandler.get_query_details(
            self.player),
                                     self,
                                     include_self=True)

        players, creatures, gobjects = GridManager.get_surrounding_objects(
            self, [
                ObjectTypes.TYPE_PLAYER, ObjectTypes.TYPE_UNIT,
                ObjectTypes.TYPE_GAMEOBJECT
            ])

        for guid, player in players.items():
            if self.guid != guid:
                if guid not in self.objects_in_range:
                    update_packet = UpdatePacketFactory.compress_if_needed(
                        PacketWriter.get_packet(
                            OpCode.SMSG_UPDATE_OBJECT,
                            player.get_update_packet(
                                update_type=UpdateTypes.UPDATE_FULL,
                                is_self=False)))
                    self.session.request.sendall(update_packet)
                    self.session.request.sendall(
                        NameQueryHandler.get_query_details(player.player))
                self.objects_in_range[guid] = {'object': player, 'near': True}

        for guid, creature in creatures.items():
            if guid not in self.objects_in_range:
                update_packet = UpdatePacketFactory.compress_if_needed(
                    PacketWriter.get_packet(
                        OpCode.SMSG_UPDATE_OBJECT,
                        creature.get_update_packet(
                            update_type=UpdateTypes.UPDATE_FULL,
                            is_self=False)))
                self.session.request.sendall(update_packet)
                self.session.request.sendall(creature.query_details())
            self.objects_in_range[guid] = {'object': creature, 'near': True}

        for guid, gobject in gobjects.items():
            if guid not in self.objects_in_range:
                update_packet = UpdatePacketFactory.compress_if_needed(
                    PacketWriter.get_packet(
                        OpCode.SMSG_UPDATE_OBJECT,
                        gobject.get_update_packet(
                            update_type=UpdateTypes.UPDATE_FULL,
                            is_self=False)))
                self.session.request.sendall(update_packet)
                self.session.request.sendall(gobject.query_details())
            self.objects_in_range[guid] = {'object': gobject, 'near': True}

        for guid, object_info in list(self.objects_in_range.items()):
            if not object_info['near']:
                self.session.request.sendall(
                    self.objects_in_range[guid]['object'].get_destroy_packet())
                del self.objects_in_range[guid]
            else:
                self.objects_in_range[guid]['near'] = False
    def __init__(self, creature_template, creature_instance=None, **kwargs):
        super().__init__(**kwargs)

        self.update_packet_factory = UpdatePacketFactory(
            [ObjectTypes.TYPE_OBJECT, ObjectTypes.TYPE_UNIT])

        self.creature_template = creature_template
        self.creature_instance = creature_instance

        self.guid = (creature_instance.spawn_id
                     if creature_instance else 0) | HighGuid.HIGHGUID_UNIT

        if self.creature_template:
            self.entry = self.creature_template.entry
            self.scale = self.creature_template.scale if self.creature_template.scale > 0 else 1
            self.max_health = self.creature_template.health_max
            self.level = randrange(self.creature_template.level_min,
                                   self.creature_template.level_max + 1)
            self.resistance_0 = self.creature_template.armor
            self.resistance_1 = self.creature_template.holy_res
            self.resistance_2 = self.creature_template.fire_res
            self.resistance_3 = self.creature_template.nature_res
            self.resistance_4 = self.creature_template.frost_res
            self.resistance_5 = self.creature_template.shadow_res
            display_id_list = list(
                filter((0).__ne__, [
                    self.creature_template.display_id1,
                    self.creature_template.display_id2,
                    self.creature_template.display_id3,
                    self.creature_template.display_id4
                ]))
            self.display_id = choice(
                display_id_list) if len(display_id_list) > 0 else 4  # 4 = cube
            self.npc_flags = self.creature_template.npc_flags
            self.mod_cast_speed = 1.0
            self.base_attack_time = self.creature_template.base_attack_time
            self.unit_flags = self.creature_template.unit_flags
            self.faction = self.creature_template.faction

            if 0 < self.creature_template.rank < 4:
                self.unit_flags = self.unit_flags | UnitFlags.UNIT_FLAG_PLUS_MOB

            self.model_info_loaded = False

        if self.creature_instance:
            self.health = int((self.creature_instance.health_percent / 100) *
                              self.max_health)
            self.map_ = self.creature_instance.map
            self.location.x = self.creature_instance.position_x
            self.location.y = self.creature_instance.position_y
            self.location.z = self.creature_instance.position_z
            self.location.o = self.creature_instance.orientation

        self.object_type.append(ObjectTypes.TYPE_UNIT)
Beispiel #4
0
    def __init__(self,
                 owner,
                 item_template=None,
                 item_instance=None,
                 is_backpack=False,
                 **kwargs):
        super().__init__(item_template, item_instance, **kwargs)

        self.update_packet_factory = UpdatePacketFactory([
            ObjectTypes.TYPE_OBJECT, ObjectTypes.TYPE_ITEM,
            ObjectTypes.TYPE_CONTAINER
        ])

        self.owner = owner
        self.is_backpack = is_backpack

        self.sorted_slots = dict()

        if not self.is_backpack:
            self.total_slots = self.item_template.container_slots
            self.is_contained = self.guid
        else:
            self.total_slots = InventorySlots.SLOT_BANK_END
            self.is_contained = self.owner

        self.object_type.append(ObjectTypes.TYPE_CONTAINER)
    def __init__(self,
                 owner,
                 item_template=None,
                 item_instance=None,
                 is_backpack=False,
                 **kwargs):
        super().__init__(item_template, item_instance, **kwargs)

        self.update_packet_factory = UpdatePacketFactory([
            ObjectTypes.TYPE_OBJECT, ObjectTypes.TYPE_ITEM,
            ObjectTypes.TYPE_CONTAINER
        ])

        self.guid = (item_instance.guid
                     if item_instance else 0) | HighGuid.HIGHGUID_CONTAINER
        self.owner = owner
        self.is_backpack = is_backpack
        if self.is_backpack:
            self.current_slot = InventorySlots.SLOT_INBACKPACK.value

        self.sorted_slots = dict()

        if not self.is_backpack:
            self.total_slots = self.item_template.container_slots
            self.start_slot = 0
            self.max_slot = self.total_slots
            self.is_contained = self.guid
        else:
            self.total_slots = InventorySlots.SLOT_ITEM_END - InventorySlots.SLOT_ITEM_START
            self.start_slot = InventorySlots.SLOT_ITEM_START
            self.max_slot = InventorySlots.SLOT_BANK_END
            self.is_contained = self.owner

        self.object_type.append(ObjectTypes.TYPE_CONTAINER)
 def send_update_surrounding(self, update_type=UpdateTypes.UPDATE_FULL):
     update_packet = UpdatePacketFactory.compress_if_needed(
         PacketWriter.get_packet(
             OpCode.SMSG_UPDATE_OBJECT,
             self.get_update_packet(update_type=update_type,
                                    is_self=False)))
     GridManager.send_surrounding(update_packet, self, include_self=False)
Beispiel #7
0
    def update_surrounding(self, destroy=False):
        if destroy:
            grid = GRIDS[self.current_grid]

            for guid, player in list(grid.players.items()):
                if player.guid != self.guid:
                    self.session.request.sendall(player.get_destroy_packet())

        update_packet = UpdatePacketFactory.compress_if_needed(
            PacketWriter.get_packet(
                OpCode.SMSG_UPDATE_OBJECT,
                self.get_update_packet(update_type=UpdateTypes.UPDATE_FULL,
                                       is_self=False)))
        GridManager.send_surrounding(update_packet, self, include_self=False)
        GridManager.send_surrounding(NameQueryHandler.get_query_details(
            self.player),
                                     self,
                                     include_self=True)

        for guid, player in list(
                GridManager.get_surrounding_players(self).items()):
            if self.guid != guid:
                self.session.request.sendall(
                    PacketWriter.get_packet(
                        OpCode.SMSG_UPDATE_OBJECT,
                        player.get_update_packet(
                            update_type=UpdateTypes.UPDATE_FULL,
                            is_self=False)))
                self.session.request.sendall(
                    NameQueryHandler.get_query_details(player.player))
Beispiel #8
0
    def __init__(self,
                 guid=0,
                 entry=0,
                 object_type=None,
                 walk_speed=2.5,
                 running_speed=7.0,
                 swim_speed=4.72222223,
                 turn_rate=pi,
                 movement_flags=0,
                 unit_flags=0,
                 dynamic_flags=0,
                 shapeshift_form=0,
                 display_id=0,
                 scale=1,
                 bounding_radius=config.Unit.Defaults.bounding_radius,
                 location=None,
                 transport_id=0,
                 transport=None,
                 pitch=0,
                 zone=0,
                 map_=0):
        self.guid = guid
        self.entry = entry
        self.walk_speed = walk_speed
        self.running_speed = running_speed
        self.swim_speed = swim_speed
        self.turn_rate = turn_rate
        self.movement_flags = movement_flags
        self.unit_flags = unit_flags
        self.dynamic_flags = dynamic_flags
        self.shapeshift_form = shapeshift_form
        self.display_id = display_id
        self.scale = scale
        self.bounding_radius = bounding_radius
        self.location = Vector()
        self.transport_id = transport_id
        self.transport = Vector()
        self.pitch = pitch
        self.zone = zone
        self.map_ = map_

        self.object_type = [ObjectTypes.TYPE_OBJECT]
        self.update_packet_factory = UpdatePacketFactory(
            [ObjectTypes.TYPE_OBJECT])

        self.current_grid = ''
        self.last_tick = 0
Beispiel #9
0
 def send_update_self(self,
                      is_self=True,
                      update_type=UpdateTypes.UPDATE_FULL):
     self.session.request.sendall(
         UpdatePacketFactory.compress_if_needed(
             PacketWriter.get_packet(
                 OpCode.SMSG_UPDATE_OBJECT,
                 self.get_update_packet(update_type=update_type.UPDATE_FULL,
                                        is_self=is_self))))
 def send_single_item_update(self, world_session, item, is_self):
     update_packet = UpdatePacketFactory.compress_if_needed(
         PacketWriter.get_packet(
             OpCode.SMSG_UPDATE_OBJECT,
             item.get_full_update_packet(is_self=False)))
     if is_self:
         world_session.request.sendall(update_packet)
         world_session.request.sendall(item.query_details())
     else:
         GridManager.send_surrounding(update_packet,
                                      world_session.player_mgr,
                                      include_self=False)
         GridManager.send_surrounding(item.query_details(),
                                      world_session.player_mgr,
                                      include_self=False)
Beispiel #11
0
    def handle(world_session, socket, reader):
        if len(reader.data) < 8:  # Avoid handling wrong player login packet
            return -1

        guid = unpack('<Q', reader.data[:8])[0]

        world_session.player_mgr = PlayerManager(
            RealmDatabaseManager.character_get_by_guid(guid), world_session)
        world_session.player_mgr.session = world_session
        if not world_session.player_mgr.player:
            Logger.anticheat('Character with wrong guid (%u) tried to login.' % guid)
            return -1

        socket.sendall(PacketWriter.get_packet(OpCode.SMSG_LOGIN_SETTIMESPEED,
                                               PlayerLoginHandler._get_login_timespeed()))

        world_session.player_mgr.load_skills()
        world_session.player_mgr.load_spells()

        socket.sendall(world_session.player_mgr.get_tutorial_packet())
        socket.sendall(world_session.player_mgr.get_initial_spells())
        socket.sendall(world_session.player_mgr.get_action_buttons())

        # MotD
        ChatManager.send_system_message(world_session, config.Server.General.motd)

        # Clear Who list on login, otherwise the last search will appear
        PlayerLoginHandler._clear_who_list(socket)

        world_session.player_mgr.inventory.load_items()

        update_packet = UpdatePacketFactory.compress_if_needed(PacketWriter.get_packet(
            OpCode.SMSG_UPDATE_OBJECT,
            world_session.player_mgr.get_update_packet(update_type=UpdateTypes.UPDATE_FULL)))
        socket.sendall(update_packet)

        PlayerLoginHandler._send_cinematic(world_session, world_session.player_mgr.player, socket)
        world_session.player_mgr.complete_login()

        return 0
Beispiel #12
0
    def __init__(
            self,
            player=None,
            session=None,
            num_inv_slots=0x89,  # Paperdoll + Bag slots + Bag space
            player_bytes=0,  # skin, face, hair style, hair color
            xp=0,
            next_level_xp=0,
            player_bytes_2=0,  # player flags, facial hair, bank slots, 0
            talent_points=0,
            skill_points=0,
            block_percentage=0,
            dodge_percentage=0,
            parry_percentage=0,
            base_mana=0,
            sheath_state=0,
            combo_points=0,
            chat_flags=0,
            is_online=False,
            **kwargs):
        super().__init__(**kwargs)

        self.update_packet_factory = UpdatePacketFactory([
            ObjectTypes.TYPE_OBJECT, ObjectTypes.TYPE_UNIT,
            ObjectTypes.TYPE_PLAYER
        ])
        self.session = session
        self.flagged_for_update = False

        self.player = player
        self.is_online = is_online
        self.num_inv_slots = num_inv_slots
        self.xp = xp
        self.next_level_xp = next_level_xp
        self.talent_points = talent_points
        self.skill_points = skill_points
        self.block_percentage = block_percentage
        self.dodge_percentage = dodge_percentage
        self.parry_percentage = parry_percentage
        self.base_mana = base_mana
        self.sheath_state = sheath_state
        self.combo_points = combo_points

        self.chat_flags = chat_flags
        self.group_status = WhoPartyStatuses.WHO_PARTY_STATUS_NOT_IN_PARTY
        self.race_mask = 0
        self.class_mask = 0
        self.spells = []
        self.skills = []

        if self.player:
            self.set_player_variables()

            self.guid = self.player.guid
            self.inventory = InventoryManager(self)
            self.level = self.player.level
            self.object_type.append(ObjectTypes.TYPE_PLAYER)
            self.bytes_0 = unpack(
                '<I',
                pack('<4B', self.player.race, self.player.class_,
                     self.player.gender, self.power_type))[0]
            self.bytes_1 = unpack(
                '<I',
                pack('<4B', self.stand_state, 0, self.shapeshift_form,
                     self.sheath_state))[0]
            self.bytes_2 = unpack('<I', pack('<4B', self.combo_points, 0, 0,
                                             0))[0]
            self.player_bytes = unpack(
                '<I',
                pack('<4B', self.player.skin, self.player.face,
                     self.player.hairstyle, self.player.haircolour))[0]
            self.player_bytes_2 = unpack(
                '>I',
                pack('>4B', self.player.extra_flags, self.player.bankslots,
                     self.player.facialhair, 0))[0]
            self.map_ = self.player.map
            self.zone = self.player.zone
            self.location.x = self.player.position_x
            self.location.y = self.player.position_y
            self.location.z = self.player.position_z
            self.location.o = self.player.orientation

            self.is_gm = self.session.account_mgr.account.gmlevel > 0

            if self.is_gm:
                self.set_gm()

            # test
            self.xp = 0
            self.next_level_xp = 200
            self.health = 1
            self.max_health = 1
            self.max_power_1 = 100
            self.power_1 = 100
            self.max_power_2 = 1000
            self.power_2 = 0
            self.max_power_3 = 100
            self.power_4 = 100
            self.max_power_4 = 100
            self.power_4 = 100
            self.guild_manager = GuildManager()
Beispiel #13
0
class PlayerManager(UnitManager):
    def __init__(
            self,
            player=None,
            session=None,
            num_inv_slots=0x89,  # Paperdoll + Bag slots + Bag space
            player_bytes=0,  # skin, face, hair style, hair color
            xp=0,
            next_level_xp=0,
            player_bytes_2=0,  # player flags, facial hair, bank slots, 0
            talent_points=0,
            skill_points=0,
            block_percentage=0,
            dodge_percentage=0,
            parry_percentage=0,
            base_mana=0,
            sheath_state=0,
            combo_points=0,
            chat_flags=0,
            is_online=False,
            **kwargs):
        super().__init__(**kwargs)

        self.update_packet_factory = UpdatePacketFactory([
            ObjectTypes.TYPE_OBJECT, ObjectTypes.TYPE_UNIT,
            ObjectTypes.TYPE_PLAYER
        ])
        self.session = session
        self.flagged_for_update = False

        self.player = player
        self.is_online = is_online
        self.num_inv_slots = num_inv_slots
        self.xp = xp
        self.next_level_xp = next_level_xp
        self.talent_points = talent_points
        self.skill_points = skill_points
        self.block_percentage = block_percentage
        self.dodge_percentage = dodge_percentage
        self.parry_percentage = parry_percentage
        self.base_mana = base_mana
        self.sheath_state = sheath_state
        self.combo_points = combo_points

        self.chat_flags = chat_flags
        self.group_status = WhoPartyStatuses.WHO_PARTY_STATUS_NOT_IN_PARTY
        self.race_mask = 0
        self.class_mask = 0
        self.spells = []
        self.skills = []

        if self.player:
            self.set_player_variables()

            self.guid = self.player.guid
            self.inventory = InventoryManager(self)
            self.level = self.player.level
            self.object_type.append(ObjectTypes.TYPE_PLAYER)
            self.bytes_0 = unpack(
                '<I',
                pack('<4B', self.player.race, self.player.class_,
                     self.player.gender, self.power_type))[0]
            self.bytes_1 = unpack(
                '<I',
                pack('<4B', self.stand_state, 0, self.shapeshift_form,
                     self.sheath_state))[0]
            self.bytes_2 = unpack('<I', pack('<4B', self.combo_points, 0, 0,
                                             0))[0]
            self.player_bytes = unpack(
                '<I',
                pack('<4B', self.player.skin, self.player.face,
                     self.player.hairstyle, self.player.haircolour))[0]
            self.player_bytes_2 = unpack(
                '>I',
                pack('>4B', self.player.extra_flags, self.player.bankslots,
                     self.player.facialhair, 0))[0]
            self.map_ = self.player.map
            self.zone = self.player.zone
            self.location.x = self.player.position_x
            self.location.y = self.player.position_y
            self.location.z = self.player.position_z
            self.location.o = self.player.orientation

            self.is_gm = self.session.account_mgr.account.gmlevel > 0

            if self.is_gm:
                self.set_gm()

            # test
            self.xp = 0
            self.next_level_xp = 200
            self.health = 1
            self.max_health = 1
            self.max_power_1 = 100
            self.power_1 = 100
            self.max_power_2 = 1000
            self.power_2 = 0
            self.max_power_3 = 100
            self.power_4 = 100
            self.max_power_4 = 100
            self.power_4 = 100
            self.guild_manager = GuildManager()

    def get_native_display_id(self, is_male, race_data=None):
        if not race_data:
            race_data = DbcDatabaseManager.chr_races_get_by_race(
                self.player.race)
        return race_data.MaleDisplayId if is_male else race_data.FemaleDisplayId

    def set_player_variables(self):
        race = DbcDatabaseManager.chr_races_get_by_race(self.player.race)

        self.faction = race.FactionID

        is_male = self.player.gender == Genders.GENDER_MALE

        self.display_id = self.get_native_display_id(is_male, race)

        if self.player.class_ == Classes.CLASS_WARRIOR:
            self.power_type = PowerTypes.TYPE_RAGE
        elif self.player.class_ == Classes.CLASS_HUNTER:
            self.power_type = PowerTypes.TYPE_FOCUS
        elif self.player.class_ == Classes.CLASS_ROGUE:
            self.power_type = PowerTypes.TYPE_ENERGY
        else:
            self.power_type = PowerTypes.TYPE_MANA

        if self.player.race == Races.RACE_HUMAN:
            self.bounding_radius = 0.306 if is_male else 0.208
        elif self.player.race == Races.RACE_ORC:
            self.bounding_radius = 0.372 if is_male else 0.236
        elif self.player.race == Races.RACE_DWARF:
            self.bounding_radius = 0.347
        elif self.player.race == Races.RACE_NIGHT_ELF:
            self.bounding_radius = 0.389 if is_male else 0.306
        elif self.player.race == Races.RACE_UNDEAD:
            self.bounding_radius = 0.383
        elif self.player.race == Races.RACE_TAUREN:
            self.bounding_radius = 0.9747 if is_male else 0.8725
            self.scale = 1.3 if is_male else 1.25
        elif self.player.race == Races.RACE_GNOME:
            self.bounding_radius = 0.3519
        elif self.player.race == Races.RACE_TROLL:
            self.bounding_radius = 0.306

        self.race_mask = 1 << self.player.race
        self.class_mask = 1 << self.player.class_

    def set_gm(self, on=True):
        self.player.extra_flags |= PlayerFlags.PLAYER_FLAGS_GM
        self.faction = 35  # Friendly to all
        self.chat_flags = ChatFlags.CHAT_TAG_GM

    def complete_login(self):
        self.is_online = True
        GridManager.update_object(self)
        self.update_surrounding()

    def logout(self):
        self.session.save_character()
        GridManager.remove_object(self)
        self.session.player_mgr = None
        self.session = None
        self.is_online = False

    def get_tutorial_packet(self):
        # Not handling any tutorial (are them even implemented?)
        return PacketWriter.get_packet(OpCode.SMSG_TUTORIAL_FLAGS,
                                       pack('<5I', 0, 0, 0, 0, 0))

    def get_initial_spells(self):
        data = pack('<BH', 0, len(self.spells))
        for spell in self.spells:
            data += pack('<2H', spell.ID, 0)
        data += pack('<H', 0)

        return PacketWriter.get_packet(OpCode.SMSG_INITIAL_SPELLS, data)

    def get_action_buttons(self):
        data = b''
        for x in range(0, MAX_ACTION_BUTTONS):
            data += pack('<I', 0)  # TODO: Handle action buttons later
        return PacketWriter.get_packet(OpCode.SMSG_ACTION_BUTTONS, data)

    def update_surrounding(self, destroy=False):
        if destroy:
            grid = GRIDS[self.current_grid]

            for guid, player in list(grid.players.items()):
                if player.guid != self.guid:
                    self.session.request.sendall(player.get_destroy_packet())

        update_packet = UpdatePacketFactory.compress_if_needed(
            PacketWriter.get_packet(
                OpCode.SMSG_UPDATE_OBJECT,
                self.get_update_packet(update_type=UpdateTypes.UPDATE_FULL,
                                       is_self=False)))
        GridManager.send_surrounding(update_packet, self, include_self=False)
        GridManager.send_surrounding(NameQueryHandler.get_query_details(
            self.player),
                                     self,
                                     include_self=True)

        for guid, player in list(
                GridManager.get_surrounding_players(self).items()):
            if self.guid != guid:
                self.session.request.sendall(
                    PacketWriter.get_packet(
                        OpCode.SMSG_UPDATE_OBJECT,
                        player.get_update_packet(
                            update_type=UpdateTypes.UPDATE_FULL,
                            is_self=False)))
                self.session.request.sendall(
                    NameQueryHandler.get_query_details(player.player))

    def sync_player(self):
        if self.player and self.player.guid == self.guid:
            self.player.level = self.level
            self.player.xp = self.xp
            self.player.talent_points = self.talent_points
            self.player.skillpoints = self.skill_points
            self.player.position_x = self.location.x
            self.player.position_y = self.location.y
            self.player.position_z = self.location.z
            self.player.map = self.map_
            self.player.orientation = self.location.o
            self.player.zone = self.zone
            self.player.health = self.health
            self.player.power1 = self.power_1
            self.player.power2 = self.power_2
            self.player.power3 = self.power_3
            self.player.power4 = self.power_4

    def teleport(self, map_, location):
        GridManager.send_surrounding(self.get_destroy_packet(),
                                     self,
                                     include_self=False)

        # Same map and not inside instance
        if self.map_ == map_ and self.map_ <= 1:
            data = pack(
                '<Q9fI',
                self.transport_id,
                self.transport.x,
                self.transport.y,
                self.transport.z,
                self.transport.o,
                location.x,
                location.y,
                location.z,
                location.o,
                0,  # ?
                0  # MovementFlags
            )
            self.session.request.sendall(
                PacketWriter.get_packet(OpCode.SMSG_MOVE_WORLDPORT_ACK, data))
        # Loading screen
        else:
            data = pack('<I', map_)
            self.session.request.sendall(
                PacketWriter.get_packet(OpCode.SMSG_TRANSFER_PENDING, data))

            data = pack('<B4f', map_, location.x, location.y, location.z,
                        location.o)

            self.session.request.sendall(
                PacketWriter.get_packet(OpCode.SMSG_NEW_WORLD, data))

        self.map_ = map_
        self.location.x = location.x
        self.location.y = location.y
        self.location.z = location.z
        self.location.o = location.o

    def mount(self, mount_display_id):
        if mount_display_id > 0 and self.mount_display_id == 0 and \
                DbcDatabaseManager.creature_display_info_get_by_model_id(mount_display_id):
            self.mount_display_id = mount_display_id
            self.unit_flags |= UnitFlags.UNIT_FLAG_MOUNTED
            self.flagged_for_update = True

    def unmount(self):
        if self.mount_display_id > 0:
            self.mount_display_id = 0
            self.unit_flags &= ~UnitFlags.UNIT_FLAG_MOUNTED
            self.flagged_for_update = True

    def set_weapon_mode(self, weapon_mode):
        # TODO: Not working
        if weapon_mode == 0:
            self.unit_flags |= UnitFlags.UNIT_FLAG_SHEATHE
        elif weapon_mode == 1:
            self.unit_flags &= ~UnitFlags.UNIT_FLAG_SHEATHE
        elif weapon_mode == 2:
            self.unit_flags &= ~UnitFlags.UNIT_FLAG_SHEATHE

        self.flagged_for_update = True

    def morph(self, display_id):
        if display_id > 0 and \
                DbcDatabaseManager.creature_display_info_get_by_model_id(display_id):
            self.display_id = display_id
            self.flagged_for_update = True

    def demorph(self):
        self.morph(self.get_native_display_id(self.player.gender == 0))

    # TODO Maybe merge all speed changes in one method
    def change_speed(self, speed=0):
        if speed <= 0:
            speed = 7.0  # Default run speed
        elif speed >= 56:
            speed = 56  # Max speed without glitches
        self.running_speed = speed
        data = pack('<f', speed)
        self.session.request.sendall(
            PacketWriter.get_packet(OpCode.SMSG_FORCE_SPEED_CHANGE, data))

    def change_swim_speed(self, swim_speed=0):
        if swim_speed <= 0:
            swim_speed = 4.7222223  # Default swim speed
        elif swim_speed >= 56:
            swim_speed = 56  # Max possible swim speed
        self.swim_speed = swim_speed
        data = pack('<f', swim_speed)
        self.session.request.sendall(
            PacketWriter.get_packet(OpCode.SMSG_FORCE_SWIM_SPEED_CHANGE, data))

    def change_walk_speed(self, walk_speed=0):
        if walk_speed <= 0:
            walk_speed = 2.5  # Default walk speed
        elif walk_speed >= 56:
            walk_speed = 56  # Max speed without glitches
        self.swim_speed = walk_speed
        data = pack('<f', walk_speed)
        self.session.request.sendall(
            PacketWriter.get_packet(OpCode.MSG_MOVE_SET_WALK_SPEED, data))

    def change_turn_speed(self, turn_speed=0):
        if turn_speed <= 0:
            turn_speed = pi  # Default turn rate speed
        self.turn_rate = turn_speed
        data = pack('<f', turn_speed)
        # TODO NOT WORKING
        self.session.request.sendall(
            PacketWriter.get_packet(OpCode.MSG_MOVE_SET_TURN_RATE_CHEAT, data))

    def load_skills(self):
        for skill in WorldDatabaseManager.player_create_skill_get(
                self.player.race, self.player.class_):
            skill_to_add = DbcDatabaseManager.skill_get_by_id(skill.Skill)
            self.skills.append(skill_to_add)

    def load_spells(self):
        for spell in WorldDatabaseManager.player_create_spell_get(
                self.player.race, self.player.class_):
            spell_to_load = DbcDatabaseManager.spell_get_by_id(spell.Spell)
            if spell_to_load:
                self.spells.append(spell_to_load)

    def send_equip_error(self, error, item_1=None, item_2=None):
        data = pack('<B', error)
        if error != InventoryError.EQUIP_ERR_OK:
            if error == InventoryError.EQUIP_ERR_CANT_EQUIP_LEVEL_I:
                data += pack(
                    '<I', item_1.item_template.required_level if item_1 else 0)
            data += pack('<2QB', item_1.guid if item_1 else self.guid,
                         item_2.guid if item_2 else self.guid, 0)
        self.session.request.sendall(
            PacketWriter.get_packet(OpCode.SMSG_INVENTORY_CHANGE_FAILURE,
                                    data))

    # TODO: UPDATE_PARTIAL is not being used anywhere (it's implemented but not sure if it works correctly).
    # override
    def get_update_packet(self,
                          update_type=UpdateTypes.UPDATE_FULL,
                          is_self=True):
        self.inventory.send_inventory_update(self.session, is_self)

        self.bytes_1 = unpack(
            '<I',
            pack('<4B', self.stand_state, 0, self.shapeshift_form,
                 self.sheath_state))[0]
        self.bytes_2 = unpack('<I', pack('<4B', self.combo_points, 0, 0, 0))[0]
        self.player_bytes_2 = unpack(
            '<I',
            pack('<4B', self.player.extra_flags, self.player.facialhair,
                 self.player.bankslots, 0))[0]

        # Object fields
        self.update_packet_factory.update(
            self.update_packet_factory.object_values,
            self.update_packet_factory.updated_object_fields,
            ObjectFields.OBJECT_FIELD_GUID, self.player.guid, 'Q')
        self.update_packet_factory.update(
            self.update_packet_factory.object_values,
            self.update_packet_factory.updated_object_fields,
            ObjectFields.OBJECT_FIELD_TYPE, self.get_object_type_value(), 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.object_values,
            self.update_packet_factory.updated_object_fields,
            ObjectFields.OBJECT_FIELD_ENTRY, self.entry, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.object_values,
            self.update_packet_factory.updated_object_fields,
            ObjectFields.OBJECT_FIELD_SCALE_X, self.scale, 'f')

        # Unit fields
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_CHANNEL_SPELL, self.channel_spell, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_CHANNEL_OBJECT, self.channel_object, 'Q')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_HEALTH, self.health, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_POWER1, self.power_1, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_POWER2, self.power_2, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_POWER3, self.power_3, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_POWER4, self.power_4, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_MAXHEALTH, self.max_health, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_MAXPOWER1, self.max_power_1, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_MAXPOWER2, self.max_power_2, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_MAXPOWER3, self.max_power_3, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_MAXPOWER4, self.max_power_4, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_LEVEL, self.level, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_FACTIONTEMPLATE, self.faction, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_BYTES_0, self.bytes_0, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_STAT0, self.stat_0, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_STAT1, self.stat_1, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_STAT2, self.stat_2, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_STAT3, self.stat_3, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_STAT4, self.stat_4, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_BASESTAT0, self.base_stat_0, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_BASESTAT1, self.base_stat_1, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_BASESTAT2, self.base_stat_2, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_BASESTAT3, self.base_stat_3, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_BASESTAT4, self.base_stat_4, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_FLAGS, self.unit_flags, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_COINAGE, self.coinage, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_BASEATTACKTIME, self.base_attack_time, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_BASEATTACKTIME + 1, self.offhand_attack_time,
            'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCES, self.resistance_0, 'q')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCES + 1, self.resistance_1, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCES + 2, self.resistance_2, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCES + 3, self.resistance_3, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCES + 4, self.resistance_4, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCES + 5, self.resistance_5, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_BOUNDINGRADIUS, self.bounding_radius, 'f')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_COMBATREACH, self.combat_reach, 'f')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_DISPLAYID, self.display_id, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_MOUNTDISPLAYID, self.mount_display_id, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE,
            self.resistance_buff_mods_positive_0, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE + 1,
            self.resistance_buff_mods_positive_1, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE + 2,
            self.resistance_buff_mods_positive_2, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE + 3,
            self.resistance_buff_mods_positive_3, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE + 4,
            self.resistance_buff_mods_positive_4, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE + 5,
            self.resistance_buff_mods_positive_5, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE,
            self.resistance_buff_mods_negative_0, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE + 1,
            self.resistance_buff_mods_negative_1, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE + 2,
            self.resistance_buff_mods_negative_2, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE + 3,
            self.resistance_buff_mods_negative_3, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE + 4,
            self.resistance_buff_mods_negative_4, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE + 5,
            self.resistance_buff_mods_negative_5, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_BYTES_1, self.bytes_1, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_MOD_CAST_SPEED, self.mod_cast_speed, 'f')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_DYNAMIC_FLAGS, self.dynamic_flags, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_DAMAGE, self.damage, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            self.update_packet_factory.updated_unit_fields,
            UnitFields.UNIT_FIELD_BYTES_2, self.bytes_2, 'I')

        # Player fields
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            self.update_packet_factory.updated_player_fields,
            PlayerFields.PLAYER_FIELD_NUM_INV_SLOTS, self.num_inv_slots, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            self.update_packet_factory.updated_player_fields,
            PlayerFields.PLAYER_BYTES, self.player_bytes, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            self.update_packet_factory.updated_player_fields,
            PlayerFields.PLAYER_XP, self.xp, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            self.update_packet_factory.updated_player_fields,
            PlayerFields.PLAYER_NEXT_LEVEL_XP, self.next_level_xp, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            self.update_packet_factory.updated_player_fields,
            PlayerFields.PLAYER_BYTES_2, self.player_bytes_2, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            self.update_packet_factory.updated_player_fields,
            PlayerFields.PLAYER_CHARACTER_POINTS1, self.talent_points, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            self.update_packet_factory.updated_player_fields,
            PlayerFields.PLAYER_CHARACTER_POINTS2, self.skill_points, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            self.update_packet_factory.updated_player_fields,
            PlayerFields.PLAYER_BLOCK_PERCENTAGE, self.block_percentage, 'f')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            self.update_packet_factory.updated_player_fields,
            PlayerFields.PLAYER_DODGE_PERCENTAGE, self.dodge_percentage, 'f')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            self.update_packet_factory.updated_player_fields,
            PlayerFields.PLAYER_PARRY_PERCENTAGE, self.parry_percentage, 'f')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            self.update_packet_factory.updated_player_fields,
            PlayerFields.PLAYER_BASE_MANA, self.base_mana, 'I')

        self.inventory.build_update(self.update_packet_factory)

        packet = b''
        if update_type == UpdateTypes.UPDATE_FULL:
            packet += self.create_update_packet(is_self)
        else:
            packet += self.create_partial_update_packet(
                self.update_packet_factory)

        update_packet = packet + self.update_packet_factory.build_packet()
        return update_packet

    # override
    def update(self):
        now = time.time()

        if now > self.last_tick > 0:
            elapsed = now - self.last_tick
            self.player.totaltime += elapsed
            self.player.leveltime += elapsed
        self.last_tick = now

        if self.flagged_for_update:
            self.session.request.sendall(
                PacketWriter.get_packet(
                    OpCode.SMSG_UPDATE_OBJECT,
                    self.get_update_packet(update_type=UpdateTypes.UPDATE_FULL,
                                           is_self=True)))

            GridManager.send_surrounding(PacketWriter.get_packet(
                OpCode.SMSG_UPDATE_OBJECT,
                self.get_update_packet(update_type=UpdateTypes.UPDATE_FULL,
                                       is_self=False)),
                                         self,
                                         include_self=False)

            GridManager.update_object(self)

            self.flagged_for_update = False

    # override
    def get_type(self):
        return ObjectTypes.TYPE_PLAYER

    # override
    def get_type_id(self):
        return ObjectTypeIds.TYPEID_PLAYER
Beispiel #14
0
    def __init__(
            self,
            player=None,
            num_inv_slots=0x89,  # Paperdoll + Bag slots + Bag space
            player_bytes=0,  # skin, face, hair style, hair color
            xp=0,
            next_level_xp=0,
            player_bytes_2=0,  # player flags, facial hair, bank slots, 0
            talent_points=0,
            skill_points=0,
            block_percentage=0,
            dodge_percentage=0,
            parry_percentage=0,
            base_mana=0,
            sheath_state=0,
            combo_points=0,
            is_online=False,
            **kwargs):
        super().__init__(**kwargs)

        self.update_packet_factory = UpdatePacketFactory([
            ObjectTypes.TYPE_OBJECT.value, ObjectTypes.TYPE_UNIT.value,
            ObjectTypes.TYPE_PLAYER.value
        ])

        self.player = player
        self.is_online = is_online
        self.num_inv_slots = num_inv_slots
        self.xp = xp
        self.next_level_xp = next_level_xp
        self.talent_points = talent_points
        self.skill_points = skill_points
        self.block_percentage = block_percentage
        self.dodge_percentage = dodge_percentage
        self.parry_percentage = parry_percentage
        self.base_mana = base_mana
        self.sheath_state = sheath_state
        self.combo_points = combo_points

        if player:
            self.guid = player.guid
            self.level = player.level
            self.object_type.append(ObjectTypes.TYPE_PLAYER)
            self.bytes_0 = unpack(
                '<I', pack('<4B', player.race, player.class_, player.gender,
                           1))[0]  # power type, handle later
            self.bytes_1 = unpack(
                '<I',
                pack('<4B', self.stand_state, 0, self.shapeshift_form,
                     self.sheath_state))[0]
            self.bytes_2 = unpack('<I', pack('<4B', self.combo_points, 0, 0,
                                             0))[0]
            self.player_bytes = unpack(
                '<I',
                pack('<4B', player.skin, player.face, player.hairstyle,
                     player.haircolour))[0]
            self.player_bytes_2 = unpack(
                '<I',
                pack('<4B', player.extra_flags, player.bankslots,
                     player.facialhair, 0))[0]
            self.map_ = player.map
            self.zone = player.zone
            self.location.x = player.position_x
            self.location.y = player.position_y
            self.location.z = player.position_z
            self.orientation = player.orientation

            # test
            self.health = 1
            self.max_health = 1
            self.display_id = 278
            self.movement_flags = 0x08000000
Beispiel #15
0
class PlayerManager(UnitManager):
    def __init__(
            self,
            player=None,
            num_inv_slots=0x89,  # Paperdoll + Bag slots + Bag space
            player_bytes=0,  # skin, face, hair style, hair color
            xp=0,
            next_level_xp=0,
            player_bytes_2=0,  # player flags, facial hair, bank slots, 0
            talent_points=0,
            skill_points=0,
            block_percentage=0,
            dodge_percentage=0,
            parry_percentage=0,
            base_mana=0,
            sheath_state=0,
            combo_points=0,
            is_online=False,
            **kwargs):
        super().__init__(**kwargs)

        self.update_packet_factory = UpdatePacketFactory([
            ObjectTypes.TYPE_OBJECT.value, ObjectTypes.TYPE_UNIT.value,
            ObjectTypes.TYPE_PLAYER.value
        ])

        self.player = player
        self.is_online = is_online
        self.num_inv_slots = num_inv_slots
        self.xp = xp
        self.next_level_xp = next_level_xp
        self.talent_points = talent_points
        self.skill_points = skill_points
        self.block_percentage = block_percentage
        self.dodge_percentage = dodge_percentage
        self.parry_percentage = parry_percentage
        self.base_mana = base_mana
        self.sheath_state = sheath_state
        self.combo_points = combo_points

        if player:
            self.guid = player.guid
            self.level = player.level
            self.object_type.append(ObjectTypes.TYPE_PLAYER)
            self.bytes_0 = unpack(
                '<I', pack('<4B', player.race, player.class_, player.gender,
                           1))[0]  # power type, handle later
            self.bytes_1 = unpack(
                '<I',
                pack('<4B', self.stand_state, 0, self.shapeshift_form,
                     self.sheath_state))[0]
            self.bytes_2 = unpack('<I', pack('<4B', self.combo_points, 0, 0,
                                             0))[0]
            self.player_bytes = unpack(
                '<I',
                pack('<4B', player.skin, player.face, player.hairstyle,
                     player.haircolour))[0]
            self.player_bytes_2 = unpack(
                '<I',
                pack('<4B', player.extra_flags, player.bankslots,
                     player.facialhair, 0))[0]
            self.map_ = player.map
            self.zone = player.zone
            self.location.x = player.position_x
            self.location.y = player.position_y
            self.location.z = player.position_z
            self.orientation = player.orientation

            # test
            self.health = 1
            self.max_health = 1
            self.display_id = 278
            self.movement_flags = 0x08000000

    def complete_login(self):
        self.is_online = True

    def logout(self):
        self.is_online = False
        self._sync_player()

    def get_tutorial_packet(self):
        # Not handling any tutorial (are them even implemented?)
        return PacketWriter.get_packet(OpCode.SMSG_TUTORIAL_FLAGS,
                                       pack('<8I', 0, 0, 0, 0, 0, 0, 0, 0))

    def get_initial_spells(self):
        return PacketWriter.get_packet(OpCode.SMSG_INITIAL_SPELLS,
                                       pack('<BHHHH', 0, 1, 133, 1,
                                            0))  # TODO Test with spell 133

    def get_query_details(self):
        name_bytes = PacketWriter.string_to_bytes(self.player.name)
        player_data = pack('<Q%usIII' % len(name_bytes), self.player.guid,
                           name_bytes, self.player.race, self.player.gender,
                           self.player.class_)
        return PacketWriter.get_packet(OpCode.SMSG_NAME_QUERY_RESPONSE,
                                       player_data)

    def get_update_packet(self):
        self._sync_player()

        # Object fields
        self.update_packet_factory.update(
            self.update_packet_factory.object_values,
            ObjectFields.OBJECT_FIELD_GUID.value, self.player.guid, 'Q')
        self.update_packet_factory.update(
            self.update_packet_factory.object_values,
            ObjectFields.OBJECT_FIELD_TYPE.value, self.get_object_type_value(),
            'I')
        self.update_packet_factory.update(
            self.update_packet_factory.object_values,
            ObjectFields.OBJECT_FIELD_ENTRY.value, self.entry, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.object_values,
            ObjectFields.OBJECT_FIELD_SCALE_X.value, self.scale, 'f')

        # Unit fields
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_CHANNEL_SPELL.value, self.channel_spell, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_CHANNEL_OBJECT.value, self.channel_object,
            'Q')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_HEALTH.value, self.health, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_POWER1.value, self.power_1, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_POWER2.value, self.power_2, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_POWER3.value, self.power_3, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_POWER4.value, self.power_4, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_MAXHEALTH.value, self.max_health, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_MAXPOWER1.value, self.max_power_1, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_MAXPOWER2.value, self.max_power_2, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_MAXPOWER3.value, self.max_power_3, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_MAXPOWER4.value, self.max_power_4, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_LEVEL.value, self.level, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_FACTIONTEMPLATE.value, self.faction, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_BYTES_0.value, self.bytes_0, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_STAT0.value, self.stat_0, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_STAT1.value, self.stat_1, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_STAT2.value, self.stat_2, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_STAT3.value, self.stat_3, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_STAT4.value, self.stat_4, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_BASESTAT0.value, self.base_stat_0, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_BASESTAT1.value, self.base_stat_1, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_BASESTAT2.value, self.base_stat_2, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_BASESTAT3.value, self.base_stat_3, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_BASESTAT4.value, self.base_stat_4, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_FLAGS.value, self.flags, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_COINAGE.value, self.coinage, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_BASEATTACKTIME.value, self.base_attack_time,
            'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_BASEATTACKTIME.value + 1,
            self.offhand_attack_time, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCES.value, self.resistance_0, 'q')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCES.value + 1, self.resistance_1,
            'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCES.value + 2, self.resistance_2,
            'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCES.value + 3, self.resistance_3,
            'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCES.value + 4, self.resistance_4,
            'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCES.value + 5, self.resistance_5,
            'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_BOUNDINGRADIUS.value, self.bounding_radius,
            'f')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_COMBATREACH.value, self.combat_reach, 'f')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_DISPLAYID.value, self.display_id, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_MOUNTDISPLAYID.value, self.mount_display_id,
            'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE.value,
            self.resistance_buff_mods_positive_0, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE.value + 1,
            self.resistance_buff_mods_positive_1, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE.value + 2,
            self.resistance_buff_mods_positive_2, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE.value + 3,
            self.resistance_buff_mods_positive_3, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE.value + 4,
            self.resistance_buff_mods_positive_4, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE.value + 5,
            self.resistance_buff_mods_positive_5, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE.value,
            self.resistance_buff_mods_negative_0, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE.value + 1,
            self.resistance_buff_mods_negative_1, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE.value + 2,
            self.resistance_buff_mods_negative_2, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE.value + 3,
            self.resistance_buff_mods_negative_3, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE.value + 4,
            self.resistance_buff_mods_negative_4, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE.value + 5,
            self.resistance_buff_mods_negative_5, 'i')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_BYTES_1.value, self.bytes_1, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_MOD_CAST_SPEED.value, self.mod_cast_speed, 'f')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_DYNAMIC_FLAGS.value, self.dynamic_flags, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_DAMAGE.value, self.damage, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.unit_values,
            UnitFields.UNIT_FIELD_BYTES_2.value, self.bytes_2, 'I')

        # Player fields
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            PlayerFields.PLAYER_FIELD_NUM_INV_SLOTS.value, self.num_inv_slots,
            'I')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            PlayerFields.PLAYER_BYTES.value, self.player_bytes, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            PlayerFields.PLAYER_XP.value, self.xp, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            PlayerFields.PLAYER_NEXT_LEVEL_XP.value, self.next_level_xp, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            PlayerFields.PLAYER_BYTES_2.value, self.player_bytes_2, 'I')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            PlayerFields.PLAYER_CHARACTER_POINTS1.value, self.talent_points,
            'I')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            PlayerFields.PLAYER_CHARACTER_POINTS2.value, self.skill_points,
            'I')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            PlayerFields.PLAYER_BLOCK_PERCENTAGE.value, self.block_percentage,
            'f')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            PlayerFields.PLAYER_DODGE_PERCENTAGE.value, self.dodge_percentage,
            'f')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            PlayerFields.PLAYER_PARRY_PERCENTAGE.value, self.parry_percentage,
            'f')
        self.update_packet_factory.update(
            self.update_packet_factory.player_values,
            PlayerFields.PLAYER_BASE_MANA.value, self.base_mana, 'I')

        return self.update_packet_factory.build_packet()

    def _sync_player(self):
        if self.player and self.player.guid == self.guid:
            self.player.level = self.level
            self.player.xp = self.xp
            self.player.talent_points = self.talent_points
            self.player.skillpoints = self.skill_points
            self.player.position_x = self.location.x
            self.player.position_y = self.location.y
            self.player.position_z = self.location.z
            self.player.map = self.map_
            self.player.orientation = self.orientation
            self.player.zone = self.zone
            self.player.health = self.health
            self.player.power1 = self.power_1
            self.player.power2 = self.power_2
            self.player.power3 = self.power_3
            self.player.power4 = self.power_4
class CreatureManager(UnitManager):
    def __init__(self, creature_template, creature_instance=None, **kwargs):
        super().__init__(**kwargs)

        self.update_packet_factory = UpdatePacketFactory(
            [ObjectTypes.TYPE_OBJECT, ObjectTypes.TYPE_UNIT])

        self.creature_template = creature_template
        self.creature_instance = creature_instance

        self.guid = (creature_instance.spawn_id
                     if creature_instance else 0) | HighGuid.HIGHGUID_UNIT

        if self.creature_template:
            self.entry = self.creature_template.entry
            self.scale = self.creature_template.scale if self.creature_template.scale > 0 else 1
            self.max_health = self.creature_template.health_max
            self.level = randrange(self.creature_template.level_min,
                                   self.creature_template.level_max + 1)
            self.resistance_0 = self.creature_template.armor
            self.resistance_1 = self.creature_template.holy_res
            self.resistance_2 = self.creature_template.fire_res
            self.resistance_3 = self.creature_template.nature_res
            self.resistance_4 = self.creature_template.frost_res
            self.resistance_5 = self.creature_template.shadow_res
            display_id_list = list(
                filter((0).__ne__, [
                    self.creature_template.display_id1,
                    self.creature_template.display_id2,
                    self.creature_template.display_id3,
                    self.creature_template.display_id4
                ]))
            self.display_id = choice(
                display_id_list) if len(display_id_list) > 0 else 4  # 4 = cube
            self.npc_flags = self.creature_template.npc_flags
            self.mod_cast_speed = 1.0
            self.base_attack_time = self.creature_template.base_attack_time
            self.unit_flags = self.creature_template.unit_flags
            self.faction = self.creature_template.faction

            if 0 < self.creature_template.rank < 4:
                self.unit_flags = self.unit_flags | UnitFlags.UNIT_FLAG_PLUS_MOB

            self.model_info_loaded = False

        if self.creature_instance:
            self.health = int((self.creature_instance.health_percent / 100) *
                              self.max_health)
            self.map_ = self.creature_instance.map
            self.location.x = self.creature_instance.position_x
            self.location.y = self.creature_instance.position_y
            self.location.z = self.creature_instance.position_z
            self.location.o = self.creature_instance.orientation

        self.object_type.append(ObjectTypes.TYPE_UNIT)

    def load(self):
        GridManager.add_or_get(self, True)

    def send_inventory_list(self, world_session):
        vendor_data, session = WorldDatabaseManager.creature_get_vendor_data(
            self.entry)
        item_count = len(vendor_data) if vendor_data else 0

        data = pack('<QB', self.guid, item_count)

        if item_count == 0:
            data += pack('<B', 0)
        else:
            for vendor_data_entry in vendor_data:
                data += pack(
                    '<7I',
                    1,  # mui
                    vendor_data_entry.item,
                    vendor_data_entry.item_template.display_id,
                    0xFFFFFFFF if vendor_data_entry.maxcount <= 0 else
                    vendor_data_entry.maxcount,
                    vendor_data_entry.item_template.buy_price,
                    0,  # durability
                    0,  # stack count
                )
                world_session.request.sendall(
                    ItemManager(item_template=vendor_data_entry.item_template).
                    query_details())

        session.close()
        world_session.request.sendall(
            PacketWriter.get_packet(OpCode.SMSG_LIST_INVENTORY, data))

    # override
    def get_update_packet(self,
                          update_type=UpdateTypes.UPDATE_FULL,
                          is_self=True):
        if self.creature_template and self.creature_instance:
            if not self.model_info_loaded:
                creature_model_info = WorldDatabaseManager.creature_get_model_info(
                    self.display_id)
                if creature_model_info:
                    self.bounding_radius = creature_model_info.bounding_radius
                    self.combat_reach = creature_model_info.combat_reach
                self.model_info_loaded = True

            self.bytes_1 = unpack(
                '<I', pack('<4B', self.stand_state, self.npc_flags, 0, 0))[0]
            self.damage = int(self.creature_template.dmg_max)  # temp

            # Object fields
            self.update_packet_factory.update(
                self.update_packet_factory.object_values,
                self.update_packet_factory.updated_object_fields,
                ObjectFields.OBJECT_FIELD_GUID, self.guid, 'Q')
            self.update_packet_factory.update(
                self.update_packet_factory.object_values,
                self.update_packet_factory.updated_object_fields,
                ObjectFields.OBJECT_FIELD_TYPE, self.get_object_type_value(),
                'I')
            self.update_packet_factory.update(
                self.update_packet_factory.object_values,
                self.update_packet_factory.updated_object_fields,
                ObjectFields.OBJECT_FIELD_ENTRY, self.entry, 'I')
            self.update_packet_factory.update(
                self.update_packet_factory.object_values,
                self.update_packet_factory.updated_object_fields,
                ObjectFields.OBJECT_FIELD_SCALE_X, self.scale, 'f')

            # Unit fields
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_CHANNEL_SPELL, self.channel_spell, 'I')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_CHANNEL_OBJECT, self.channel_object, 'Q')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_HEALTH, self.health, 'I')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_MAXHEALTH, self.max_health, 'I')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_LEVEL, self.level, 'I')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_FACTIONTEMPLATE, self.faction, 'I')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_FLAGS, self.unit_flags, 'I')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_COINAGE, self.coinage, 'I')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_BASEATTACKTIME, self.base_attack_time,
                'f')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_BASEATTACKTIME + 1, 0, 'f')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_RESISTANCES, self.resistance_0, 'q')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_RESISTANCES + 1, self.resistance_1, 'i')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_RESISTANCES + 2, self.resistance_2, 'i')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_RESISTANCES + 3, self.resistance_3, 'i')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_RESISTANCES + 4, self.resistance_4, 'i')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_RESISTANCES + 5, self.resistance_5, 'i')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_BOUNDINGRADIUS, self.bounding_radius,
                'f')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_COMBATREACH, self.combat_reach, 'f')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_DISPLAYID, self.display_id, 'I')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_BYTES_1, self.bytes_1, 'I')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_MOD_CAST_SPEED, self.mod_cast_speed, 'f')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_DYNAMIC_FLAGS, self.dynamic_flags, 'I')
            self.update_packet_factory.update(
                self.update_packet_factory.unit_values,
                self.update_packet_factory.updated_unit_fields,
                UnitFields.UNIT_FIELD_DAMAGE, self.damage, 'I')

            packet = b''
            if update_type == UpdateTypes.UPDATE_FULL:
                packet += self.create_update_packet(is_self)
            else:
                packet += self.create_partial_update_packet(
                    self.update_packet_factory)

            update_packet = packet + self.update_packet_factory.build_packet()
            return update_packet

    def query_details(self):
        name_bytes = PacketWriter.string_to_bytes(self.creature_template.name)
        subname_bytes = PacketWriter.string_to_bytes(
            self.creature_template.subname)
        data = pack('<I%ussss%us3I' % (len(name_bytes), len(subname_bytes)),
                    self.entry, name_bytes, b'\x00', b'\x00', b'\x00',
                    subname_bytes, self.creature_template.type_flags,
                    self.creature_template.type,
                    self.creature_template.beast_family)
        return PacketWriter.get_packet(OpCode.SMSG_CREATURE_QUERY_RESPONSE,
                                       data)

    # override
    def get_type(self):
        return ObjectTypes.TYPE_UNIT

    # override
    def get_type_id(self):
        return ObjectTypeIds.ID_UNIT
Beispiel #17
0
 def send_update_self(self, is_self=True):
     self.session.request.sendall(UpdatePacketFactory.compress_if_needed(
         PacketWriter.get_packet(
             OpCode.SMSG_UPDATE_OBJECT,
             self.get_full_update_packet(is_self=is_self))))
class GameObjectManager(ObjectManager):
    def __init__(self, gobject_template, gobject_instance=None, **kwargs):
        super().__init__(**kwargs)

        self.update_packet_factory = UpdatePacketFactory(
            [ObjectTypes.TYPE_OBJECT, ObjectTypes.TYPE_GAMEOBJECT])

        self.gobject_template = gobject_template
        self.gobject_instance = gobject_instance

        self.guid = (gobject_instance.spawn_id
                     if gobject_instance else 0) | HighGuid.HIGHGUID_GAMEOBJECT

        if self.gobject_template:
            self.display_id = self.gobject_template.display_id

        if gobject_instance:
            self.state = self.gobject_instance.spawn_state
            self.location.x = self.gobject_instance.spawn_positionX
            self.location.y = self.gobject_instance.spawn_positionY
            self.location.z = self.gobject_instance.spawn_positionZ
            self.location.o = self.gobject_instance.spawn_orientation
            self.map_ = self.gobject_instance.spawn_map
            self.scale = self.gobject_template.scale

        self.object_type.append(ObjectTypes.TYPE_GAMEOBJECT)

    def load(self):
        GridManager.add_or_get(self, True)

    def use(self, player):
        if self.gobject_template.type == GameObjectTypes.TYPE_DOOR or \
                self.gobject_template.type == GameObjectTypes.TYPE_BUTTON:
            # TODO: Check locks for doors
            if self.state == GameObjectStates.GO_STATE_READY:
                self.state = GameObjectStates.GO_STATE_ACTIVE
                # TODO: Trigger sripts / events on cooldown restart
                self.send_update_surrounding()
        elif self.gobject_template.type == GameObjectTypes.TYPE_CAMERA:
            cinematic_id = self.gobject_template.data2
            if DbcDatabaseManager.cinematic_sequences_get_by_id(cinematic_id):
                data = pack('<I', cinematic_id)
                player.session.request.sendall(
                    PacketWriter.get_packet(OpCode.SMSG_TRIGGER_CINEMATIC,
                                            data))
        elif self.gobject_template.type == GameObjectTypes.TYPE_CHAIR:
            slots = self.gobject_template.data1
            height = self.gobject_template.data2

            lowest_distance = 90.0
            x_lowest = self.location.x
            y_lowest = self.location.y

            if slots > 0:
                orthogonal_orientation = self.location.o + pi * 0.5
                for x in range(0, slots):
                    relative_distance = (self.scale * x) - (self.scale *
                                                            (slots - 1) / 2.0)
                    x_i = self.location.x + relative_distance * cos(
                        orthogonal_orientation)
                    y_i = self.location.y + relative_distance * sin(
                        orthogonal_orientation)

                    player_slot_distance = player.location.distance(
                        Vector(x_i, y_i, player.location.z))
                    if player_slot_distance <= lowest_distance:
                        lowest_distance = player_slot_distance
                        x_lowest = x_i
                        y_lowest = y_i
                player.teleport(
                    player.map_,
                    Vector(x_lowest, y_lowest, self.location.z,
                           self.location.o))
                player.stand_state = StandState.UNIT_SITTINGCHAIRLOW.value + height

    # override
    def get_update_packet(self,
                          update_type=UpdateTypes.UPDATE_FULL,
                          is_self=True):
        if self.gobject_template and self.gobject_instance:
            # Object fields
            self.update_packet_factory.update(
                self.update_packet_factory.object_values,
                self.update_packet_factory.updated_object_fields,
                ObjectFields.OBJECT_FIELD_GUID, self.guid, 'Q')
            self.update_packet_factory.update(
                self.update_packet_factory.object_values,
                self.update_packet_factory.updated_object_fields,
                ObjectFields.OBJECT_FIELD_TYPE, self.get_object_type_value(),
                'I')
            self.update_packet_factory.update(
                self.update_packet_factory.object_values,
                self.update_packet_factory.updated_object_fields,
                ObjectFields.OBJECT_FIELD_ENTRY, self.gobject_template.entry,
                'I')
            self.update_packet_factory.update(
                self.update_packet_factory.object_values,
                self.update_packet_factory.updated_object_fields,
                ObjectFields.OBJECT_FIELD_SCALE_X, self.scale, 'f')
            self.update_packet_factory.update(
                self.update_packet_factory.object_values,
                self.update_packet_factory.updated_object_fields,
                ObjectFields.OBJECT_FIELD_PADDING, 0, 'I')

            # Gameobject fields
            self.update_packet_factory.update(
                self.update_packet_factory.gameobject_values,
                self.update_packet_factory.updated_gameobject_fields,
                GameObjectFields.GAMEOBJECT_DISPLAYID, self.display_id, 'I')
            self.update_packet_factory.update(
                self.update_packet_factory.gameobject_values,
                self.update_packet_factory.updated_gameobject_fields,
                GameObjectFields.GAMEOBJECT_FLAGS, self.gobject_template.flags,
                'I')
            self.update_packet_factory.update(
                self.update_packet_factory.gameobject_values,
                self.update_packet_factory.updated_gameobject_fields,
                GameObjectFields.GAMEOBJECT_FACTION,
                self.gobject_template.faction, 'I')
            self.update_packet_factory.update(
                self.update_packet_factory.gameobject_values,
                self.update_packet_factory.updated_gameobject_fields,
                GameObjectFields.GAMEOBJECT_STATE, self.state, 'I')
            self.update_packet_factory.update(
                self.update_packet_factory.gameobject_values,
                self.update_packet_factory.updated_gameobject_fields,
                GameObjectFields.GAMEOBJECT_ROTATION,
                self.gobject_instance.spawn_rotation0, 'f')
            self.update_packet_factory.update(
                self.update_packet_factory.gameobject_values,
                self.update_packet_factory.updated_gameobject_fields,
                GameObjectFields.GAMEOBJECT_ROTATION + 1,
                self.gobject_instance.spawn_rotation1, 'f')
            self.update_packet_factory.update(
                self.update_packet_factory.gameobject_values,
                self.update_packet_factory.updated_gameobject_fields,
                GameObjectFields.GAMEOBJECT_ROTATION + 2,
                self.gobject_instance.spawn_rotation2, 'f')
            self.update_packet_factory.update(
                self.update_packet_factory.gameobject_values,
                self.update_packet_factory.updated_gameobject_fields,
                GameObjectFields.GAMEOBJECT_ROTATION + 3,
                self.gobject_instance.spawn_rotation3, 'f')
            self.update_packet_factory.update(
                self.update_packet_factory.gameobject_values,
                self.update_packet_factory.updated_gameobject_fields,
                GameObjectFields.GAMEOBJECT_POS_X, self.location.x, 'f')
            self.update_packet_factory.update(
                self.update_packet_factory.gameobject_values,
                self.update_packet_factory.updated_gameobject_fields,
                GameObjectFields.GAMEOBJECT_POS_Y, self.location.y, 'f')
            self.update_packet_factory.update(
                self.update_packet_factory.gameobject_values,
                self.update_packet_factory.updated_gameobject_fields,
                GameObjectFields.GAMEOBJECT_POS_Z, self.location.z, 'f')
            self.update_packet_factory.update(
                self.update_packet_factory.gameobject_values,
                self.update_packet_factory.updated_gameobject_fields,
                GameObjectFields.GAMEOBJECT_FACING, self.location.o, 'f')

            packet = b''
            if update_type == UpdateTypes.UPDATE_FULL:
                packet += self.create_update_packet(is_self)
            else:
                packet += self.create_partial_update_packet(
                    self.update_packet_factory)

            update_packet = packet + self.update_packet_factory.build_packet()
            return update_packet

    def query_details(self):
        name_bytes = PacketWriter.string_to_bytes(self.gobject_template.name)
        data = pack(
            '<3I%ussss10I' % len(name_bytes),
            self.gobject_template.entry,
            self.gobject_template.type,
            self.display_id,
            name_bytes,
            b'\x00',
            b'\x00',
            b'\x00',
            self.gobject_template.data1,
            self.gobject_template.data2,
            self.gobject_template.data3,
            self.gobject_template.data4,
            self.gobject_template.data5,
            self.gobject_template.data6,
            self.gobject_template.data7,
            self.gobject_template.data8,
            self.gobject_template.data9,
            self.gobject_template.data10,
        )
        return PacketWriter.get_packet(OpCode.SMSG_GAMEOBJECT_QUERY_RESPONSE,
                                       data)

    def send_update_surrounding(self, update_type=UpdateTypes.UPDATE_FULL):
        update_packet = UpdatePacketFactory.compress_if_needed(
            PacketWriter.get_packet(
                OpCode.SMSG_UPDATE_OBJECT,
                self.get_update_packet(update_type=update_type,
                                       is_self=False)))
        GridManager.send_surrounding(update_packet, self, include_self=False)

    # override
    def get_type(self):
        return ObjectTypes.TYPE_GAMEOBJECT

    # override
    def get_type_id(self):
        return ObjectTypeIds.ID_GAMEOBJECT
Beispiel #19
0
class ItemManager(ObjectManager):
    def __init__(self,
                 item_template,
                 item_instance=None,
                 current_slot=0,
                 **kwargs):
        super().__init__(**kwargs)

        self.update_packet_factory = UpdatePacketFactory([ObjectTypes.TYPE_OBJECT,
                                                          ObjectTypes.TYPE_ITEM])

        self.item_template = item_template
        self.item_instance = item_instance
        self.guid = (item_instance.guid if item_instance else 0) | HighGuid.HIGHGUID_ITEM
        self.current_slot = item_instance.slot if item_instance else 0
        self.is_contained = item_instance.owner if item_instance else 0
        self.is_backpack = False

        self.stats = []
        self.damage_stats = []
        self.spell_stats = []

        if item_template:
            self.display_id = item_template.display_id
            self.equip_slot = self.get_inv_slot_by_type(self.item_template.inventory_type)

            self.stats.append(ItemManager.Stat(self.item_template.stat_type1, self.item_template.stat_value1))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type2, self.item_template.stat_value2))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type3, self.item_template.stat_value3))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type4, self.item_template.stat_value4))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type5, self.item_template.stat_value5))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type6, self.item_template.stat_value6))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type7, self.item_template.stat_value7))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type8, self.item_template.stat_value8))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type9, self.item_template.stat_value9))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type10, self.item_template.stat_value10))

            self.damage_stats.append(ItemManager.DamageStat(self.item_template.dmg_min1, self.item_template.dmg_max1,
                                                            self.item_template.dmg_type1))
            self.damage_stats.append(ItemManager.DamageStat(self.item_template.dmg_min2, self.item_template.dmg_max2,
                                                            self.item_template.dmg_type2))
            self.damage_stats.append(ItemManager.DamageStat(self.item_template.dmg_min3, self.item_template.dmg_max3,
                                                            self.item_template.dmg_type3))
            self.damage_stats.append(ItemManager.DamageStat(self.item_template.dmg_min4, self.item_template.dmg_max4,
                                                            self.item_template.dmg_type4))
            self.damage_stats.append(ItemManager.DamageStat(self.item_template.dmg_min5, self.item_template.dmg_max5,
                                                            self.item_template.dmg_type5))

            self.spell_stats.append(
                ItemManager.SpellStat(self.item_template.spellid_1, self.item_template.spelltrigger_1,
                                      self.item_template.spellcharges_1, self.item_template.spellcooldown_1,
                                      self.item_template.spellcategory_1, self.item_template.spellcategorycooldown_1))
            self.spell_stats.append(
                ItemManager.SpellStat(self.item_template.spellid_2, self.item_template.spelltrigger_2,
                                      self.item_template.spellcharges_2, self.item_template.spellcooldown_2,
                                      self.item_template.spellcategory_2, self.item_template.spellcategorycooldown_2))
            self.spell_stats.append(
                ItemManager.SpellStat(self.item_template.spellid_3, self.item_template.spelltrigger_3,
                                      self.item_template.spellcharges_3, self.item_template.spellcooldown_3,
                                      self.item_template.spellcategory_3, self.item_template.spellcategorycooldown_3))
            self.spell_stats.append(
                ItemManager.SpellStat(self.item_template.spellid_4, self.item_template.spelltrigger_4,
                                      self.item_template.spellcharges_4, self.item_template.spellcooldown_4,
                                      self.item_template.spellcategory_4, self.item_template.spellcategorycooldown_4))
            self.spell_stats.append(
                ItemManager.SpellStat(self.item_template.spellid_5, self.item_template.spelltrigger_5,
                                      self.item_template.spellcharges_5, self.item_template.spellcooldown_5,
                                      self.item_template.spellcategory_5, self.item_template.spellcategorycooldown_5))

        self.object_type.append(ObjectTypes.TYPE_ITEM)

    class Stat(object):
        def __init__(self, stat_type, value):
            self.stat_type = stat_type
            self.value = value

    class DamageStat(object):
        def __init__(self, minimum, maximum, stat_type):
            self.minimum = minimum
            self.maximum = maximum
            self.stat_type = stat_type

    class SpellStat(object):
        def __init__(self, spell_id, trigger, charges, cooldown, category, category_cooldown):
            self.spell_id = spell_id
            self.trigger = trigger
            self.charges = charges
            self.cooldown = cooldown
            self.category = category
            self.category_cooldown = category_cooldown

    def is_container(self):
        if self.item_template:
            return self.item_template.inventory_type == InventoryTypes.BAG
        return False

    def is_equipped(self):
        return self.current_slot < InventorySlots.SLOT_BAG1

    @staticmethod
    def get_inv_slot_by_type(inventory_type):
        return AVAILABLE_EQUIP_SLOTS[inventory_type if inventory_type <= 26 else 0].value

    @staticmethod
    def generate_starting_item(owner, entry, last_bag_slot):
        item_template = WorldDatabaseManager.item_template_get_by_entry(entry)
        if item_template:
            slot = ItemManager.get_inv_slot_by_type(item_template.inventory_type)
            if slot >= InventorySlots.SLOT_INBACKPACK:
                slot = last_bag_slot
            bag = InventorySlots.SLOT_INBACKPACK.value
            count = 1
            if item_template.inventory_type == 0 and item_template.class_ == 0:
                count = 2 if item_template.spellid_1 == 430 else 4
            elif item_template.inventory_type == 24:
                count = 200
            return ItemManager.generate_item(item_template, owner, bag, slot, count=count)
        return None

    @staticmethod
    def generate_item(item_template, owner, bag, slot, creator=0, count=1):
        if item_template and item_template.entry > 0:
            item = CharacterInventory(
                owner=owner,
                creator=creator,
                item_template=item_template.entry,
                stackcount=count,
                slot=slot,
                bag=bag
            )
            RealmDatabaseManager.character_inventory_add_item(item)

            if item_template.inventory_type == InventoryTypes.BAG:
                from game.world.managers.objects.item.ContainerManager import ContainerManager
                item_mgr = ContainerManager(
                    owner=owner,
                    item_template=item_template,
                    item_instance=item
                )
            else:
                item_mgr = ItemManager(
                    item_template=item_template,
                    item_instance=item
                )

            return item_mgr
        return None

    def query_details(self):
        item_name_bytes = PacketWriter.string_to_bytes(self.item_template.name)
        data = pack(
            '<3I%ussss6I2i7I' % len(item_name_bytes),
            self.item_template.entry,
            self.item_template.class_,
            self.item_template.subclass,
            item_name_bytes, b'\x00', b'\x00', b'\x00',
            self.item_template.display_id,
            self.item_template.quality,
            self.item_template.flags,
            self.item_template.buy_price,
            self.item_template.sell_price,
            self.item_template.inventory_type,
            self.item_template.allowable_class,
            self.item_template.allowable_race,
            self.item_template.item_level,
            self.item_template.required_level,
            self.item_template.required_skill,
            self.item_template.required_skill_rank,
            self.item_template.max_count,
            self.item_template.stackable,
            self.item_template.container_slots
        )

        for stat in self.stats:
            data += pack('<Ii', stat.stat_type, stat.value)

        for damage_stat in self.damage_stats:
            data += pack('<3i', int(damage_stat.minimum), int(damage_stat.maximum), damage_stat.stat_type)

        data += pack(
            '<6i3I',
            self.item_template.armor,
            self.item_template.holy_res,
            self.item_template.fire_res,
            self.item_template.nature_res,
            self.item_template.frost_res,
            self.item_template.shadow_res,
            self.item_template.delay,
            self.item_template.ammo_type,
            0  # TODO: Durability, not implemented
        )

        for spell_stat in self.spell_stats:
            data += pack(
                '<Q4i',
                spell_stat.spell_id,
                spell_stat.trigger,
                spell_stat.charges,
                spell_stat.cooldown,
                spell_stat.category_cooldown
            )

        description_bytes = PacketWriter.string_to_bytes(self.item_template.description)
        data += pack(
            '<I%us5IiI' % len(description_bytes),
            self.item_template.bonding,
            description_bytes,
            self.item_template.page_text,
            self.item_template.page_language,
            self.item_template.page_material,
            self.item_template.start_quest,
            self.item_template.lock_id,
            self.item_template.material,
            self.item_template.sheath
        )

        return PacketWriter.get_packet(OpCode.SMSG_ITEM_QUERY_SINGLE_RESPONSE, data)

    # override
    def get_update_packet(self, update_type=UpdateTypes.UPDATE_FULL, is_self=True):
        if self.item_template and self.item_instance:
            from game.world.managers.objects.item.ContainerManager import MAX_BAG_SLOTS, ContainerManager

            # Object fields
            self.update_packet_factory.update(self.update_packet_factory.object_values, self.update_packet_factory.updated_object_fields, ObjectFields.OBJECT_FIELD_GUID, self.guid, 'Q')
            self.update_packet_factory.update(self.update_packet_factory.object_values, self.update_packet_factory.updated_object_fields, ObjectFields.OBJECT_FIELD_TYPE, self.get_object_type_value(), 'I')
            self.update_packet_factory.update(self.update_packet_factory.object_values, self.update_packet_factory.updated_object_fields, ObjectFields.OBJECT_FIELD_ENTRY, self.item_template.entry, 'I')
            self.update_packet_factory.update(self.update_packet_factory.object_values, self.update_packet_factory.updated_object_fields, ObjectFields.OBJECT_FIELD_SCALE_X, 1, 'f')
            self.update_packet_factory.update(self.update_packet_factory.object_values, self.update_packet_factory.updated_object_fields, ObjectFields.OBJECT_FIELD_PADDING, 0, 'I')

            # Item fields
            self.update_packet_factory.update(self.update_packet_factory.item_values, self.update_packet_factory.updated_item_fields, ItemFields.ITEM_FIELD_OWNER, self.item_instance.owner, 'Q')
            self.update_packet_factory.update(self.update_packet_factory.item_values, self.update_packet_factory.updated_item_fields, ItemFields.ITEM_FIELD_CREATOR, self.item_instance.creator, 'Q')
            self.update_packet_factory.update(self.update_packet_factory.item_values, self.update_packet_factory.updated_item_fields, ItemFields.ITEM_FIELD_CONTAINED, self.is_contained, 'Q')
            self.update_packet_factory.update(self.update_packet_factory.item_values, self.update_packet_factory.updated_item_fields, ItemFields.ITEM_FIELD_STACK_COUNT, self.item_instance.stackcount, 'I')
            self.update_packet_factory.update(self.update_packet_factory.item_values, self.update_packet_factory.updated_item_fields, ItemFields.ITEM_FIELD_FLAGS, self.item_template.flags, 'I')

            self.update_packet_factory.update(self.update_packet_factory.item_values, self.update_packet_factory.updated_item_fields, ItemFields.ITEM_FIELD_SPELL_CHARGES, self.item_instance.SpellCharges1, 'i')
            self.update_packet_factory.update(self.update_packet_factory.item_values, self.update_packet_factory.updated_item_fields, ItemFields.ITEM_FIELD_SPELL_CHARGES + 1, self.item_instance.SpellCharges2, 'i')
            self.update_packet_factory.update(self.update_packet_factory.item_values, self.update_packet_factory.updated_item_fields, ItemFields.ITEM_FIELD_SPELL_CHARGES + 2, self.item_instance.SpellCharges3, 'i')
            self.update_packet_factory.update(self.update_packet_factory.item_values, self.update_packet_factory.updated_item_fields, ItemFields.ITEM_FIELD_SPELL_CHARGES + 3, self.item_instance.SpellCharges4, 'i')
            self.update_packet_factory.update(self.update_packet_factory.item_values, self.update_packet_factory.updated_item_fields, ItemFields.ITEM_FIELD_SPELL_CHARGES + 4, self.item_instance.SpellCharges5, 'i')

            # Container fields
            if self.is_container() and isinstance(self, ContainerManager):
                self.update_packet_factory.update(self.update_packet_factory.container_values,
                                                  self.update_packet_factory.updated_container_fields,
                                                  ContainerFields.CONTAINER_FIELD_NUM_SLOTS,
                                                  self.item_template.container_slots, 'I')

                for x in range(0, MAX_BAG_SLOTS):
                    guid = self.sorted_slots[x].guid if x in self.sorted_slots else 0
                    self.update_packet_factory.update(self.update_packet_factory.container_values,
                                                      self.update_packet_factory.updated_container_fields,
                                                      ContainerFields.CONTAINER_FIELD_SLOT_1 + x * 2,
                                                      guid, 'Q')

            packet = b''
            if update_type == UpdateTypes.UPDATE_FULL:
                packet += self.create_update_packet(is_self)
            else:
                packet += self.create_partial_update_packet(self.update_packet_factory)

            update_packet = packet + self.update_packet_factory.build_packet()
            return update_packet

    # override
    def get_type(self):
        return ObjectTypes.TYPE_ITEM

    # override
    def get_type_id(self):
        return ObjectTypeIds.ID_ITEM
Beispiel #20
0
class ObjectManager(object):
    TYPES_WITH_OBJECT_TYPE = (UpdateTypes.CREATE_OBJECT, )
    TYPES_WITH_MOVEMENT = (UpdateTypes.MOVEMENT, UpdateTypes.CREATE_OBJECT)
    TYPES_WITH_MISC = (UpdateTypes.CREATE_OBJECT, )
    TYPES_WITH_FIELDS = (UpdateTypes.PARTIAL, UpdateTypes.MOVEMENT,
                         UpdateTypes.CREATE_OBJECT)

    def __init__(self,
                 guid=0,
                 entry=0,
                 object_type=None,
                 walk_speed=2.5,
                 running_speed=7.0,
                 swim_speed=4.72222223,
                 turn_rate=pi,
                 movement_flags=0,
                 unit_flags=0,
                 dynamic_flags=0,
                 shapeshift_form=0,
                 display_id=0,
                 scale=1,
                 bounding_radius=config.Unit.Defaults.bounding_radius,
                 location=None,
                 transport_id=0,
                 transport=None,
                 pitch=0,
                 zone=0,
                 map_=0):
        self.guid = guid
        self.entry = entry
        self.walk_speed = walk_speed
        self.running_speed = running_speed
        self.swim_speed = swim_speed
        self.turn_rate = turn_rate
        self.movement_flags = movement_flags
        self.unit_flags = unit_flags
        self.dynamic_flags = dynamic_flags
        self.shapeshift_form = shapeshift_form
        self.display_id = display_id
        self.scale = scale
        self.bounding_radius = bounding_radius
        self.location = Vector()
        self.transport_id = transport_id
        self.transport = Vector()
        self.pitch = pitch
        self.zone = zone
        self.map_ = map_

        self.object_type = [ObjectTypes.TYPE_OBJECT]
        self.update_packet_factory = UpdatePacketFactory(
            [ObjectTypes.TYPE_OBJECT])

        self.current_grid = ''
        self.last_tick = 0

    def get_object_type_value(self):
        type_value = 0
        for type_ in self.object_type:
            type_value |= type_
        return type_value

    def get_update_mask(self):
        mask = 0
        if ObjectTypes.TYPE_CONTAINER in self.object_type:
            mask += ContainerFields.CONTAINER_END
        if ObjectTypes.TYPE_ITEM in self.object_type:
            mask += ItemFields.ITEM_END
        if ObjectTypes.TYPE_PLAYER in self.object_type:
            mask += PlayerFields.PLAYER_END
        if ObjectTypes.TYPE_UNIT in self.object_type:
            mask += UnitFields.UNIT_END
        if ObjectTypes.TYPE_OBJECT in self.object_type:
            mask += ObjectFields.OBJECT_END
        if ObjectTypes.TYPE_GAMEOBJECT in self.object_type:
            mask += GameObjectFields.GAMEOBJECT_END

        return (mask + 31) / 32

    def create_update_packet(self,
                             update_packet_factory,
                             is_self=True,
                             update_type=UpdateTypes.CREATE_OBJECT):
        from game.world.managers.objects import UnitManager
        merged_update_values = update_packet_factory.get_merged_update_values()
        update_mask = int(self.get_update_mask())

        data = pack(
            '<IBQ',
            1,  # Number of transactions
            update_type,
            self.guid,
        )

        if update_type in self.TYPES_WITH_OBJECT_TYPE:
            data += pack('<B', self.get_type_id())

        if update_type in self.TYPES_WITH_MOVEMENT:
            data += pack(
                '<QfffffffffIIffff',
                self.transport_id,
                self.transport.x,
                self.transport.y,
                self.transport.z,
                self.transport.o,
                self.location.x,
                self.location.y,
                self.location.z,
                self.location.o,
                self.pitch,
                self.movement_flags,
                0,  # Fall Time?
                self.walk_speed,
                self.running_speed,
                self.swim_speed,
                self.turn_rate)

        if update_type in self.TYPES_WITH_MISC:
            data += pack(
                '<3IQ',
                1 if is_self else
                0,  # Flags, 1 - Current player, 0 - Other player
                1 if self.get_type_id() == ObjectTypeIds.ID_PLAYER else
                0,  # AttackCycle
                0,  # TimerId
                UnitManager.UnitManager(self).combat_target if isinstance(
                    self, UnitManager.UnitManager) else 0,  # Victim GUID
            )

        if update_type in self.TYPES_WITH_FIELDS:
            data += pack('<B', update_mask)

            for x in range(0, update_mask):
                data += pack('<I', 0xFFFFFFFF)

            data += merged_update_values

        self.update_packet_factory.init_lists()

        return data

    def set_obj_uint32(self, index, value):
        self.update_packet_factory.update(
            self.update_packet_factory.object_values,
            self.update_packet_factory.updated_object_fields, index, value,
            'I')

    def set_obj_uint64(self, index, value):
        self.update_packet_factory.update(
            self.update_packet_factory.object_values,
            self.update_packet_factory.updated_object_fields, index, value,
            'Q')

    def set_obj_float(self, index, value):
        self.update_packet_factory.update(
            self.update_packet_factory.object_values,
            self.update_packet_factory.updated_object_fields, index, value,
            'f')

    # override
    def update(self):
        pass

    # override
    def get_full_update_packet(self, is_self=True):
        pass

    # override
    def get_type(self):
        return ObjectTypes.TYPE_OBJECT

    # override
    def get_type_id(self):
        return ObjectTypeIds.ID_OBJECT

    def get_destroy_packet(self):
        data = pack('<Q', self.guid)
        return PacketWriter.get_packet(OpCode.SMSG_DESTROY_OBJECT, data)
Beispiel #21
0
 def send_update_surrounding(self, is_self=False, include_self=False):
     update_packet = UpdatePacketFactory.compress_if_needed(PacketWriter.get_packet(
         OpCode.SMSG_UPDATE_OBJECT, self.get_full_update_packet(is_self=is_self)))
     GridManager.send_surrounding(update_packet, self, include_self=include_self)
Beispiel #22
0
    def __init__(self,
                 item_template,
                 item_instance=None,
                 current_slot=0,
                 **kwargs):
        super().__init__(**kwargs)

        self.update_packet_factory = UpdatePacketFactory([ObjectTypes.TYPE_OBJECT,
                                                          ObjectTypes.TYPE_ITEM])

        self.item_template = item_template
        self.item_instance = item_instance
        self.guid = (item_instance.guid if item_instance else 0) | HighGuid.HIGHGUID_ITEM
        self.current_slot = item_instance.slot if item_instance else 0
        self.is_contained = item_instance.owner if item_instance else 0
        self.is_backpack = False

        self.stats = []
        self.damage_stats = []
        self.spell_stats = []

        if item_template:
            self.display_id = item_template.display_id
            self.equip_slot = self.get_inv_slot_by_type(self.item_template.inventory_type)

            self.stats.append(ItemManager.Stat(self.item_template.stat_type1, self.item_template.stat_value1))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type2, self.item_template.stat_value2))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type3, self.item_template.stat_value3))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type4, self.item_template.stat_value4))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type5, self.item_template.stat_value5))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type6, self.item_template.stat_value6))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type7, self.item_template.stat_value7))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type8, self.item_template.stat_value8))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type9, self.item_template.stat_value9))
            self.stats.append(ItemManager.Stat(self.item_template.stat_type10, self.item_template.stat_value10))

            self.damage_stats.append(ItemManager.DamageStat(self.item_template.dmg_min1, self.item_template.dmg_max1,
                                                            self.item_template.dmg_type1))
            self.damage_stats.append(ItemManager.DamageStat(self.item_template.dmg_min2, self.item_template.dmg_max2,
                                                            self.item_template.dmg_type2))
            self.damage_stats.append(ItemManager.DamageStat(self.item_template.dmg_min3, self.item_template.dmg_max3,
                                                            self.item_template.dmg_type3))
            self.damage_stats.append(ItemManager.DamageStat(self.item_template.dmg_min4, self.item_template.dmg_max4,
                                                            self.item_template.dmg_type4))
            self.damage_stats.append(ItemManager.DamageStat(self.item_template.dmg_min5, self.item_template.dmg_max5,
                                                            self.item_template.dmg_type5))

            self.spell_stats.append(
                ItemManager.SpellStat(self.item_template.spellid_1, self.item_template.spelltrigger_1,
                                      self.item_template.spellcharges_1, self.item_template.spellcooldown_1,
                                      self.item_template.spellcategory_1, self.item_template.spellcategorycooldown_1))
            self.spell_stats.append(
                ItemManager.SpellStat(self.item_template.spellid_2, self.item_template.spelltrigger_2,
                                      self.item_template.spellcharges_2, self.item_template.spellcooldown_2,
                                      self.item_template.spellcategory_2, self.item_template.spellcategorycooldown_2))
            self.spell_stats.append(
                ItemManager.SpellStat(self.item_template.spellid_3, self.item_template.spelltrigger_3,
                                      self.item_template.spellcharges_3, self.item_template.spellcooldown_3,
                                      self.item_template.spellcategory_3, self.item_template.spellcategorycooldown_3))
            self.spell_stats.append(
                ItemManager.SpellStat(self.item_template.spellid_4, self.item_template.spelltrigger_4,
                                      self.item_template.spellcharges_4, self.item_template.spellcooldown_4,
                                      self.item_template.spellcategory_4, self.item_template.spellcategorycooldown_4))
            self.spell_stats.append(
                ItemManager.SpellStat(self.item_template.spellid_5, self.item_template.spelltrigger_5,
                                      self.item_template.spellcharges_5, self.item_template.spellcooldown_5,
                                      self.item_template.spellcategory_5, self.item_template.spellcategorycooldown_5))

        self.object_type.append(ObjectTypes.TYPE_ITEM)