def from_bytes(spline_bytes): if len(spline_bytes < 42): return None bytes_read = 0 spline = MovementSpline() spline.flags = unpack('<I', spline_bytes[:4])[0] bytes_read += 4 if spline.flags & SplineFlags.SPLINEFLAG_SPOT: spline.spot = Vector.from_bytes(spline_bytes[bytes_read:12]) bytes_read += 12 if spline.flags & SplineFlags.SPLINEFLAG_TARGET: spline.guid = unpack('<Q', spline_bytes[bytes_read:8])[0] bytes_read += 8 if spline.flags & SplineFlags.SPLINEFLAG_FACING: spline.facing = unpack('<f', spline_bytes[bytes_read:4])[0] bytes_read += 4 spline.elapsed, spline.total_time = unpack('<2I', spline_bytes[bytes_read:8]) bytes_read += 8 points_length = unpack('<I', spline_bytes[bytes_read:4])[0] bytes_read += 4 for i in range(points_length): spline.points.append(Vector.from_bytes( spline_bytes[bytes_read:12])) bytes_read += 12 return spline
def get_target_info(world_session, target_mask, target_bytes): caster = world_session.player_mgr if target_mask & SpellTargetMask.CAN_TARGET_TERRAIN != 0 and len( target_bytes) == 12: target_info = Vector.from_bytes( target_bytes) # Terrain, target is vector. elif len(target_bytes) == 8: target_info = unpack('<Q', target_bytes)[0] # Some object (read guid). else: target_info = caster # Self if target_mask & SpellTargetMask.CAN_TARGET_TERRAIN: return target_info if target_mask & SpellTargetMask.UNIT and target_info != caster: return MapManager.get_surrounding_unit_by_guid( caster, target_info, include_players=True) if target_mask & SpellTargetMask.ITEM_TARGET_MASK and not target_mask & SpellTargetMask.TRADE_ITEM: return caster.inventory.get_item_info_by_guid(target_info)[ 3] # (container_slot, container, slot, item). if target_mask & SpellTargetMask.CAN_TARGET_OBJECTS: # Can also include items, so we check for that first. return MapManager.get_surrounding_gameobject_by_guid( caster, target_info) if target_mask & SpellTargetMask.ITEM_TARGET_MASK and target_mask & SpellTargetMask.TRADE_ITEM: if caster.trade_data and caster.trade_data.other_player and caster.trade_data.other_player.trade_data: return caster.trade_data.other_player.trade_data.get_item_by_slot( target_info) return caster # Assume self cast for now. Invalid target will be resolved later.
def handle(world_session, socket, reader): if len(reader.data) >= 6: # Avoid handling empty cast spell packet. spell_id, target_mask = unpack('<IH', reader.data[:6]) caster = world_session.player_mgr if target_mask & SpellTargetMask.CAN_TARGET_TERRAIN != 0 and len( reader.data) >= 18: target_info = Vector.from_bytes( reader.data[-12:]) # Terrain, target is vector elif len(reader.data) == 14: target_info = unpack( '<Q', reader.data[-8:])[0] # some object (read guid) else: target_info = caster # Self if target_mask & SpellTargetMask.CAN_TARGET_TERRAIN: spell_target = target_info elif target_mask & SpellTargetMask.UNIT and target_info != caster: spell_target = MapManager.get_surrounding_unit_by_guid( caster, target_info, include_players=True) elif target_mask & SpellTargetMask.ITEM_TARGET_MASK: spell_target = caster.inventory.get_item_info_by_guid( target_info)[3] # (container_slot, container, slot, item) elif target_mask & SpellTargetMask.CAN_TARGET_OBJECTS: # Can also include items so we check for that first spell_target = MapManager.get_surrounding_gameobject_by_guid( caster, target_info) else: spell_target = caster # Assume self cast for now. Invalid target will be resolved later world_session.player_mgr.spell_manager.handle_cast_attempt( spell_id, world_session.player_mgr, spell_target, target_mask) return 0