def apply_script(protocol, connection, config): protocol, connection = cbc.apply_script(protocol, connection, config) class FloorMakerConnection(connection): def __init__(self, *arg, **kw): connection.__init__(self, *arg, **kw) self.flooring = 0 self.floor_x = 0 self.floor_y = 0 self.floor_z = 0 def on_block_build(self, x, y, z): if self.flooring == 2: self.flooring = 0 if self.floor_z != z: self.send_chat('Surface is uneven! Using first height.') buildbox.build_filled(self.protocol , self.floor_x, self.floor_y, self.floor_z , x, y, self.floor_z , self.color, self.god, self.god_build) if self.flooring == 1: self.floor_x = x self.floor_y = y self.floor_z = z self.send_chat('Now place opposite corner block') self.flooring = 2 return connection.on_block_build(self, x, y, z) class FloorMakerProtocol(protocol): def on_map_change(self, map): for connection in self.clients: connection.flooring = 0 protocol.on_map_change(self, map) return FloorMakerProtocol, FloorMakerConnection
def apply_script(protocol, connection, config): protocol, connection = cbc.apply_script(protocol, connection, config) class ClearFloorMakerConnection(connection): def __init__(self, *args, **kwargs): connection.__init__(self, *args, **kwargs) self.deflooring = 0 self.clearfloor_x = 0 self.clearfloor_y = 0 self.clearfloor_z = 0 def on_block_removed(self, x, y, z): if self.deflooring == 2: self.deflooring = 0 if self.clearfloor_z != z: self.send_chat('Surface is uneven! Using first height.') clearbox.clear_solid(self.protocol, self.clearfloor_x, self.clearfloor_y, self.clearfloor_z, x, y, self.clearfloor_z, self.god) self.send_chat('Floor destroyed!') if self.deflooring == 1: self.clearfloor_x = x self.clearfloor_y = y self.clearfloor_z = z self.send_chat('Now break opposite corner block') self.deflooring = 2 return connection.on_block_removed(self, x, y, z) class ClearFloorMakerProtocol(protocol): def on_map_change(self, map): for connection in self.clients: connection.deflooring = 0 protocol.on_map_change(self, map) return ClearFloorMakerProtocol, ClearFloorMakerConnection
def apply_script(protocol, connection, config): protocol, connection = cbc.apply_script(protocol, connection, config) def try_add_node(map, x, y, z, list): if x < 0 or x >= 512 or y < 0 or y >= 512 or z < 0 or z >= 62: return if map.get_solid(x, y, z): return list.append((x, y, z)) class DirtGrenadeConnection(connection): def dirtnade_generator(self, x, y, z, blocks): map = self.protocol.map list = [] try_add_node(map, x, y, z, list) block_action.value = BUILD_BLOCK block_action.player_id = self.player_id while list: x, y, z = list.pop(0) if connection.on_block_build_attempt(self, x, y, z) == False: continue block_action.x = x block_action.y = y block_action.z = z self.protocol.send_contained(block_action, save=True) map.set_point(x, y, z, self.color) yield 1, 0 blocks -= 1 if blocks == 0: break try_add_node(map, x, y, z - 1, list) try_add_node(map, x, y - 1, z, list) try_add_node(map, x, y + 1, z, list) try_add_node(map, x - 1, y, z, list) try_add_node(map, x + 1, y, z, list) try_add_node(map, x, y, z + 1, list) self.protocol.update_entities() def grenade_exploded(self, grenade): if self.name is None: return if self.weapon != 1: return connection.grenade_exploded(self, grenade) position = grenade.position x = int(position.x) y = int(position.y) z = int(position.z) self.protocol.cbc_add( self.dirtnade_generator(x, y, z, DIRTNADE_BLOCKS)) return protocol, DirtGrenadeConnection
def apply_script(protocol, connection, config): protocol, connection = cbc.apply_script(protocol, connection, config) def try_add_node(map, x, y, z, list): if x < 0 or x >= 512 or y < 0 or y >= 512 or z < 0 or z >= 62: return if map.get_solid(x, y, z): return list.append((x, y, z)) class DirtGrenadeConnection(connection): def dirtnade_generator(self, x, y, z, blocks): map = self.protocol.map list = [] try_add_node(map, x, y, z, list) block_action.value = BUILD_BLOCK block_action.player_id = self.player_id while list: x, y, z = list.pop(0) if connection.on_block_build_attempt(self, x, y, z) == False: continue block_action.x = x block_action.y = y block_action.z = z self.protocol.send_contained(block_action, save=True) map.set_point(x, y, z, self.color) yield 1, 0 blocks -= 1 if blocks == 0: break try_add_node(map, x, y, z - 1, list) try_add_node(map, x, y - 1, z, list) try_add_node(map, x, y + 1, z, list) try_add_node(map, x - 1, y, z, list) try_add_node(map, x + 1, y, z, list) try_add_node(map, x, y, z + 1, list) self.protocol.update_entities() def grenade_exploded(self, grenade): if self.name is None: return if self.weapon != 1: return connection.grenade_exploded(self, grenade) position = grenade.position x = int(position.x) y = int(position.y) z = int(position.z) self.protocol.cbc_add(self.dirtnade_generator(x, y, z, DIRTNADE_BLOCKS)) return protocol, DirtGrenadeConnection
def apply_script(protocol, connection, config): protocol, connection = cbc.apply_script(protocol, connection, config) class WallMakerConnection(connection): def __init__(self, *arg, **kw): connection.__init__(self, *arg, **kw) self.walling = None def on_block_build(self, x, y, z): if self.walling is not None: z2 = min(61, max(0, z - self.walling + sign(self.walling))) buildbox.build_filled(self.protocol, x, y, z, x, y, z2, self.color, self.god, self.god_build) return connection.on_block_build(self, x, y, z) return protocol, WallMakerConnection
def apply_script(protocol, connection, config): protocol, connection = cbc.apply_script(protocol, connection, config) class DeWallMakerConnection(connection): def __init__(self, *args, **kwargs): connection.__init__(self, *args, **kwargs) self.dewalling = None def on_block_removed(self, x, y, z): if self.dewalling is not None: z2 = min(61, max(0, z - self.dewalling + sign(self.dewalling))) clearbox.clear_solid(self.protocol, x, y, z, x, y, z2, self.god) return connection.on_block_removed(self, x, y, z) return protocol, DeWallMakerConnection
def apply_script(protocol, connection, config): boxing = 0 protocol, connection = cbc.apply_script(protocol, connection, config) class BoxMakerConnection(connection): def __init__(self, *arg, **kw): connection.__init__(self, *arg, **kw) self.boxing = 0 self.boxing_filled = 0 self.box_x = 0 self.box_y = 0 self.box_z = 0 def build_box_filled(self, x1, y1, z1, x2, y2, z2, color=None): buildbox.build_filled(self.protocol, x1, y1, z1, x2, y2, z2, color or self.color, self.god, self.god_build) def build_box(self, x1, y1, z1, x2, y2, z2, color=None): buildbox.build_empty(self.protocol, x1, y1, z1, x2, y2, z2, color or self.color, self.god, self.god_build) def on_block_build(self, x, y, z): if self.boxing == 2: self.boxing = 0 if self.boxing_filled == 0: self.build_box(self.box_x, self.box_y, self.box_z, x, y, z) else: self.build_box_filled(self.box_x, self.box_y, self.box_z, x, y, z) self.send_chat('Box created!') if self.boxing == 1: self.box_x = x self.box_y = y self.box_z = z self.send_chat('Now place opposite corner block') self.boxing = 2 return connection.on_block_build(self, x, y, z) class BoxMakerProtocol(protocol): def on_map_change(self, map): for connection in self.clients: connection.boxing = 0 protocol.on_map_change(self, map) return BoxMakerProtocol, BoxMakerConnection
def apply_script(protocol, connection, config): boxing = 0 protocol, connection = cbc.apply_script(protocol, connection, config) class BoxMakerConnection(connection): def __init__(self, *arg, **kw): connection.__init__(self, *arg, **kw) self.boxing = 0 self.boxing_filled = 0 self.box_x = 0 self.box_y = 0 self.box_z = 0 def build_box_filled(self, x1, y1, z1, x2, y2, z2, color = None): buildbox.build_filled(self.protocol, x1, y1, z1, x2, y2, z2, color or self.color, self.god, self.god_build) def build_box(self, x1, y1, z1, x2, y2, z2, color = None): buildbox.build_empty(self.protocol, x1, y1, z1, x2, y2, z2, color or self.color, self.god, self.god_build) def on_block_build(self, x, y, z): if self.boxing == 2: self.boxing = 0 if self.boxing_filled == 0: self.build_box(self.box_x, self.box_y, self.box_z, x, y, z) else: self.build_box_filled(self.box_x, self.box_y, self.box_z, x, y, z) self.send_chat('Box created!') if self.boxing == 1: self.box_x = x self.box_y = y self.box_z = z self.send_chat('Now place opposite corner block') self.boxing = 2 return connection.on_block_build(self, x, y, z) class BoxMakerProtocol(protocol): def on_map_change(self, map): for connection in self.clients: connection.boxing = 0 protocol.on_map_change(self, map) return BoxMakerProtocol, BoxMakerConnection
def apply_script(protocol, connection, config): protocol, connection = cbc.apply_script(protocol, connection, config) class ClearBoxMakerConnection(connection): def __init__(self, *arg, **kw): connection.__init__(self, *arg, **kw) self.deboxing = 0 self.clearbox_x = 0 self.clearbox_y = 0 self.clearbox_z = 0 def clear_box_solid(self, x1, y1, z1, x2, y2, z2): clearbox.clear_solid(self.protocol, x1, y1, z1, x2, y2, z2, self.god) def clear_box(self, x1, y1, z1, x2, y2, z2): clearbox.clear(self.protocol, x1, y1, z1, x2, y2, z2, self.god) def on_block_removed(self, x, y, z): if self.deboxing == 2: self.deboxing = 0 self.clear_box(self.clearbox_x, self.clearbox_y, self.clearbox_z, x, y, z) self.send_chat('Destroying box!') if self.deboxing == 1: self.clearbox_x = x self.clearbox_y = y self.clearbox_z = z self.send_chat('Now break opposite corner block') self.deboxing = 2 return connection.on_block_removed(self, x, y, z) class ClearBoxMakerProtocol(protocol): def on_map_change(self, map): for connection in self.clients: connection.deboxing = 0 protocol.on_map_change(self, map) return ClearBoxMakerProtocol, ClearBoxMakerConnection
def apply_script(protocol, connection, config): protocol, connection = cbc.apply_script(protocol, connection, config) rollback_on_game_end = config.get('rollback_on_game_end', False) class RollbackConnection(connection): def on_block_destroy(self, x, y, z, value): if self.protocol.rollback_handle is not None: return False return connection.on_block_destroy(self, x, y, z, value) class RollbackProtocol(protocol): rollback_time_between_progress_updates = 10.0 rollback_map = None rollback_handle = None def start_rollback(self, connection, mapname, start_x, start_y, end_x, end_y, ignore_indestructable = True): if self.rollback_handle is not None: return S_ROLLBACK_IN_PROGRESS if mapname is None: map = self.rollback_map else: try: maps = check_rotation([mapname]) if not maps: return S_INVALID_MAP_NAME map = Map(maps[0]).data except MapNotFound as error: return error.message name = (connection.name if connection is not None else S_AUTOMATIC_ROLLBACK_PLAYER_NAME) message = S_ROLLBACK_COMMENCED.format(player = name) self.send_chat(message, irc = True) generator = self.create_rollback_generator(self.map, map, start_x, start_y, end_x, end_y, ignore_indestructable) self.rollback_handle = self.cbc_add(generator , self.rollback_time_between_progress_updates , self.rollback_callback , connection) def rollback_cancel(self, connection): if self.rollback_handle is None: return S_NO_ROLLBACK_IN_PROGRESS self.cbc_cancel(self.rollback_handle) #should call rollback_callback automatically def rollback_callback(self, cbctype, progress, elapsed, connection): message = '' if cbctype == self.CBC_CANCELLED: message = S_ROLLBACK_CANCELLED.format(player = connection.name) self.rollback_handle = None elif cbctype == self.CBC_FINISHED: message = S_ROLLBACK_ENDED.format(result = '') + '\n' + S_ROLLBACK_TIME_TAKEN.format(seconds = elapsed) self.rollback_handle = None elif cbctype == self.CBC_UPDATE and progress >= 0.0: message = S_ROLLBACK_PROGRESS.format(percent = progress) elif cbctype == self.CBC_UPDATE and progress < 0.0: message = S_ROLLBACK_COLOR_PASS.format(percent = abs(progress)) if message != '': self.send_chat(message, irc = True) def create_rollback_generator(self, cur, new, start_x, start_y, end_x, end_y, ignore_indestructable): surface = {} block_action = BlockAction() block_action.player_id = 31 set_color = SetColor() set_color.value = make_color(*NON_SURFACE_COLOR) set_color.player_id = 31 self.send_contained(set_color, save = True) old = cur.copy() check_protected = hasattr(protocol, 'protected') x_count = abs(start_x - end_x) for x in xrange(start_x, end_x): block_action.x = x for y in xrange(start_y, end_y): block_action.y = y if check_protected and self.is_protected(x, y, 0): continue for z in xrange(63): action = None cur_solid = cur.get_solid(x, y, z) new_solid = new.get_solid(x, y, z) if cur_solid and not new_solid: if (not ignore_indestructable and self.is_indestructable(x, y, z)): continue else: action = DESTROY_BLOCK cur.remove_point(x, y, z) elif new_solid: new_is_surface = new.is_surface(x, y, z) if new_is_surface: new_color = new.get_color(x, y, z) if not cur_solid and new_is_surface: surface[(x, y, z)] = new_color elif not cur_solid and not new_is_surface: action = BUILD_BLOCK cur.set_point(x, y, z, NON_SURFACE_COLOR) elif cur_solid and new_is_surface: old_is_surface = old.is_surface(x, y, z) if old_is_surface: old_color = old.get_color(x, y, z) if not old_is_surface or old_color != new_color: surface[(x, y, z)] = new_color action = DESTROY_BLOCK cur.remove_point(x, y, z) if action is not None: block_action.z = z block_action.value = action self.send_contained(block_action, save = True) yield action is not None, ((x-start_x+0.0) / x_count) last_color = None block_action.value = BUILD_BLOCK i = 0.0 for pos, color in sorted(surface.iteritems()): x, y, z = pos packets_sent = 0 if color != last_color: set_color.value = make_color(*color) self.send_contained(set_color, save = True) packets_sent += 1 last_color = color cur.set_point(x, y, z, color) block_action.x = x block_action.y = y block_action.z = z self.send_contained(block_action, save = True) packets_sent += 1 i += 1 yield packets_sent, -(i / len(surface)) def on_map_change(self, map): self.rollback_map = map.copy() protocol.on_map_change(self, map) def on_game_end(self): if self.rollback_on_game_end: self.start_rollback(None, None, 0, 0, 512, 512, False) protocol.on_game_end(self) return RollbackProtocol, RollbackConnection
def apply_script(protocol, connection, config): protocol, connection = cbc.apply_script(protocol, connection, config) class BuildConnection(connection): def __init__(self, *arg, **kw): connection.__init__(self, *arg, **kw) self.quickbuild_allowed = True self.qb_info = None self.qb_points = 0 self.qb_building = Q_OFF self.qb_recording = Q_STOPPED self.qb_record_colors = False self.qb_record_origin = None self.qb_record_dir = None self.qb_recorded = dict() def get_direction(self): orientation = self.world_object.orientation return int(round(atan2(orientation.y, orientation.x) / pi * 2) % 4) def on_kill(self, killer, type, grenade): ret = connection.on_kill(self, killer, type, grenade) if ret is None: if killer is not None and self.team is not killer.team and self != killer: killer.qb_points += 1 return ret def on_line_build(self, points): for x, y, z in points: self.quickbuild_block_build(x, y, z) return connection.on_line_build(self, points) def on_block_build(self, x, y, z): self.quickbuild_block_build(x, y, z) return connection.on_block_build(self, x, y, z) def on_block_removed(self, x, y, z): connection.on_block_removed(self, x, y, z) if self.qb_recording and self.qb_recorded: xyz = shift_origin((x,y,z),self.qb_record_origin) self.qb_recorded.pop(xyz, 'Not popped') def quickbuild_block_build(self, x, y, z): if self.qb_recording: if self.qb_record_origin is None: self.qb_record_origin = (x, y, z) self.qb_record_dir = self.get_direction() xyz = shift_origin((x,y,z), self.qb_record_origin) xyz = rotate(xyz, self.qb_record_dir, EAST) self.qb_recorded[xyz] = self.color if self.qb_record_colors else None def on_block_build_attempt(self, x, y, z): cont = True if self.qb_recording and not self.qb_record_origin: self.qb_record_origin = (x, y, z) self.qb_record_dir = self.get_direction() if self.qb_recording == Q_COPYING: self.send_chat('Now place the opposite corner block!') else: self.send_chat('Now start building!') cont = False elif self.qb_recording == Q_COPYING: blocks = get_blocks(self.protocol.map, self.qb_record_origin, (x,y,z), self.qb_record_colors) blocks = shift_origin_all(blocks, self.qb_record_origin) blocks = rotate_all(blocks, self.qb_record_dir, EAST) self.qb_recorded = dict(blocks) self.qb_recording = Q_STOPPED self.send_chat('Copied area to buffer!') cont = False if self.qb_building: if self.qb_building == Q_BUILD_RECORDED: structure = rotate_all(self.qb_recorded, EAST, self.get_direction()) color = DIRT_COLOR if self.qb_record_colors else self.color else: self.qb_points -= self.qb_info.get('cost', 0) vx = AVX.fromfile(qb_fname(self.qb_info['name'])) structure = vx.tosparsedict() structure = shift_origin_all(structure, self.qb_info['origin']) structure = rotate_all(structure, EAST, self.get_direction()) color = DIRT_COLOR if vx.has_colors else self.color self.protocol.cbc_add(self.quickbuild_generator((x, y, z), structure, color)) self.qb_building = Q_OFF self.qb_info = None self.send_chat('Building structure!') cont = False if self.qb_recording == Q_ORIGINATING: new_origin = (x,y,z) shift = shift_origin(self.qb_record_origin, new_origin) self.qb_recorded = dict(shift_origin_all(self.qb_recorded, shift)) self.qb_record_origin = new_origin self.send_chat('New origin saved!') cont = False if not cont: return False return connection.on_block_build_attempt(self, x, y, z) def quickbuild_generator(self, origin, structure, default_color): map = self.protocol.map protocol = self.protocol splayer = cbc.ServerPlayer() block_action = BlockAction() block_action.value = BUILD_BLOCK block_action.player_id = splayer.player_id set_color = SetColor() set_color.value = make_color(*default_color) set_color.player_id = splayer.player_id pcolor = default_color protocol.send_contained(set_color, save = True) if not isinstance(structure, dict): structure = dict(structure) for xyz, color in structure.iteritems(): x, y, z = [a+b for a,b in zip(xyz, origin)] if (x < 0 or x >= 512 or y < 0 or y >= 512 or z < 0 or z >= 62): continue if map.get_solid(x, y, z): continue color = color or default_color if color != pcolor: set_color.value = make_color(*color) protocol.send_contained(set_color, save = True) pcolor = color yield 1, 0 self.on_block_build(x, y, z) block_action.x, block_action.y, block_action.z = x, y, z protocol.send_contained(block_action, save = True) map.set_point(x, y, z, pcolor) yield 1, 0 return protocol, BuildConnection
def apply_script(protocol, connection, config): protocol, connection = cbc.apply_script(protocol, connection, config) class BuildConnection(connection): def __init__(self, *arg, **kw): connection.__init__(self, *arg, **kw) self.quickbuild_allowed = True self.qb_info = None self.qb_points = 0 self.qb_building = Q_OFF self.qb_recording = Q_STOPPED self.qb_record_colors = False self.qb_record_origin = None self.qb_record_dir = None self.qb_recorded = dict() def get_direction(self): orientation = self.world_object.orientation return int(round(atan2(orientation.y, orientation.x) / pi * 2) % 4) def on_kill(self, killer, type, grenade): ret = connection.on_kill(self, killer, type, grenade) if ret is None: if killer is not None and self.team is not killer.team and self != killer: killer.qb_points += 1 return ret def on_line_build(self, points): for x, y, z in points: self.quickbuild_block_build(x, y, z) return connection.on_line_build(self, points) def on_block_build(self, x, y, z): self.quickbuild_block_build(x, y, z) return connection.on_block_build(self, x, y, z) def on_block_removed(self, x, y, z): connection.on_block_removed(self, x, y, z) if self.qb_recording and self.qb_recorded: xyz = shift_origin((x, y, z), self.qb_record_origin) self.qb_recorded.pop(xyz, 'Not popped') def quickbuild_block_build(self, x, y, z): if self.qb_recording: if self.qb_record_origin is None: self.qb_record_origin = (x, y, z) self.qb_record_dir = self.get_direction() xyz = shift_origin((x, y, z), self.qb_record_origin) xyz = rotate(xyz, self.qb_record_dir, EAST) self.qb_recorded[ xyz] = self.color if self.qb_record_colors else None def on_block_build_attempt(self, x, y, z): cont = True if self.qb_recording and not self.qb_record_origin: self.qb_record_origin = (x, y, z) self.qb_record_dir = self.get_direction() if self.qb_recording == Q_COPYING: self.send_chat('Now place the opposite corner block!') else: self.send_chat('Now start building!') cont = False elif self.qb_recording == Q_COPYING: blocks = get_blocks(self.protocol.map, self.qb_record_origin, (x, y, z), self.qb_record_colors) blocks = shift_origin_all(blocks, self.qb_record_origin) blocks = rotate_all(blocks, self.qb_record_dir, EAST) self.qb_recorded = dict(blocks) self.qb_recording = Q_STOPPED self.send_chat('Copied area to buffer!') cont = False if self.qb_building: if self.qb_building == Q_BUILD_RECORDED: structure = rotate_all(self.qb_recorded, EAST, self.get_direction()) color = DIRT_COLOR if self.qb_record_colors else self.color else: self.qb_points -= self.qb_info.get('cost', 0) vx = AVX.fromfile(qb_fname(self.qb_info['name'])) structure = vx.tosparsedict() structure = shift_origin_all(structure, self.qb_info['origin']) structure = rotate_all(structure, EAST, self.get_direction()) color = DIRT_COLOR if vx.has_colors else self.color self.protocol.cbc_add( self.quickbuild_generator((x, y, z), structure, color)) self.qb_building = Q_OFF self.qb_info = None self.send_chat('Building structure!') cont = False if self.qb_recording == Q_ORIGINATING: new_origin = (x, y, z) shift = shift_origin(self.qb_record_origin, new_origin) self.qb_recorded = dict( shift_origin_all(self.qb_recorded, shift)) self.qb_record_origin = new_origin self.send_chat('New origin saved!') cont = False if not cont: return False return connection.on_block_build_attempt(self, x, y, z) def quickbuild_generator(self, origin, structure, default_color): map = self.protocol.map protocol = self.protocol splayer = cbc.ServerPlayer() block_action = BlockAction() block_action.value = BUILD_BLOCK block_action.player_id = splayer.player_id set_color = SetColor() set_color.value = make_color(*default_color) set_color.player_id = splayer.player_id pcolor = default_color protocol.send_contained(set_color, save=True) if not isinstance(structure, dict): structure = dict(structure) for xyz, color in structure.iteritems(): x, y, z = [a + b for a, b in zip(xyz, origin)] if (x < 0 or x >= 512 or y < 0 or y >= 512 or z < 0 or z >= 62): continue if map.get_solid(x, y, z): continue color = color or default_color if color != pcolor: set_color.value = make_color(*color) protocol.send_contained(set_color, save=True) pcolor = color yield 1, 0 self.on_block_build(x, y, z) block_action.x, block_action.y, block_action.z = x, y, z protocol.send_contained(block_action, save=True) map.set_point(x, y, z, pcolor) yield 1, 0 return protocol, BuildConnection
def apply_script(protocol, connection, config): protocol, connection = cbc.apply_script(protocol, connection, config) rollback_on_game_end = config.get('rollback_on_game_end', False) class RollbackConnection(connection): def on_block_destroy(self, x, y, z, value): if self.protocol.rollback_handle is not None: return False return connection.on_block_destroy(self, x, y, z, value) class RollbackProtocol(protocol): rollback_time_between_progress_updates = 10.0 rollback_map = None rollback_handle = None def start_rollback(self, connection, mapname, start_x, start_y, end_x, end_y, ignore_indestructable=True): if self.rollback_handle is not None: return S_ROLLBACK_IN_PROGRESS if mapname is None: map = self.rollback_map else: try: maps = check_rotation([mapname]) if not maps: return S_INVALID_MAP_NAME map = Map(maps[0]).data except MapNotFound as error: return error.message name = (connection.name if connection is not None else S_AUTOMATIC_ROLLBACK_PLAYER_NAME) message = S_ROLLBACK_COMMENCED.format(player=name) self.send_chat(message, irc=True) generator = self.create_rollback_generator(self.map, map, start_x, start_y, end_x, end_y, ignore_indestructable) self.rollback_handle = self.cbc_add( generator, self.rollback_time_between_progress_updates, self.rollback_callback, connection) def rollback_cancel(self, connection): if self.rollback_handle is None: return S_NO_ROLLBACK_IN_PROGRESS self.cbc_cancel(self.rollback_handle ) #should call rollback_callback automatically def rollback_callback(self, cbctype, progress, elapsed, connection): message = '' if cbctype == self.CBC_CANCELLED: message = S_ROLLBACK_CANCELLED.format(player=connection.name) self.rollback_handle = None elif cbctype == self.CBC_FINISHED: message = S_ROLLBACK_ENDED.format( result='') + '\n' + S_ROLLBACK_TIME_TAKEN.format( seconds=elapsed) self.rollback_handle = None elif cbctype == self.CBC_UPDATE and progress >= 0.0: message = S_ROLLBACK_PROGRESS.format(percent=progress) elif cbctype == self.CBC_UPDATE and progress < 0.0: message = S_ROLLBACK_COLOR_PASS.format(percent=abs(progress)) if message != '': self.send_chat(message, irc=True) def create_rollback_generator(self, cur, new, start_x, start_y, end_x, end_y, ignore_indestructable): surface = {} block_action = BlockAction() block_action.player_id = 31 set_color = SetColor() set_color.value = make_color(*NON_SURFACE_COLOR) set_color.player_id = 31 self.send_contained(set_color, save=True) old = cur.copy() check_protected = hasattr(protocol, 'protected') x_count = abs(start_x - end_x) for x in xrange(start_x, end_x): block_action.x = x for y in xrange(start_y, end_y): block_action.y = y if check_protected and self.is_protected(x, y, 0): continue for z in xrange(63): action = None cur_solid = cur.get_solid(x, y, z) new_solid = new.get_solid(x, y, z) if cur_solid and not new_solid: if (not ignore_indestructable and self.is_indestructable(x, y, z)): continue else: action = DESTROY_BLOCK cur.remove_point(x, y, z) elif new_solid: new_is_surface = new.is_surface(x, y, z) if new_is_surface: new_color = new.get_color(x, y, z) if not cur_solid and new_is_surface: surface[(x, y, z)] = new_color elif not cur_solid and not new_is_surface: action = BUILD_BLOCK cur.set_point(x, y, z, NON_SURFACE_COLOR) elif cur_solid and new_is_surface: old_is_surface = old.is_surface(x, y, z) if old_is_surface: old_color = old.get_color(x, y, z) if not old_is_surface or old_color != new_color: surface[(x, y, z)] = new_color action = DESTROY_BLOCK cur.remove_point(x, y, z) if action is not None: block_action.z = z block_action.value = action self.send_contained(block_action, save=True) yield action is not None, ((x - start_x + 0.0) / x_count) last_color = None block_action.value = BUILD_BLOCK i = 0.0 for pos, color in sorted(surface.iteritems()): x, y, z = pos packets_sent = 0 if color != last_color: set_color.value = make_color(*color) self.send_contained(set_color, save=True) packets_sent += 1 last_color = color cur.set_point(x, y, z, color) block_action.x = x block_action.y = y block_action.z = z self.send_contained(block_action, save=True) packets_sent += 1 i += 1 yield packets_sent, -(i / len(surface)) def on_map_change(self, map): self.rollback_map = map.copy() protocol.on_map_change(self, map) def on_game_end(self): if self.rollback_on_game_end: self.start_rollback(None, None, 0, 0, 512, 512, False) protocol.on_game_end(self) return RollbackProtocol, RollbackConnection
def apply_script(protocol, connection, config): protocol, connection = cbc.apply_script(protocol, connection, config) class IntelPowerConnection(connection): def __init__(self, *args, **kwargs): self.intel_p_lvl = [0,0,0,0,0,0,0,0] connection.__init__(self, *args, **kwargs) def on_login(self, name): self.intel_clear() self.headshot_splode = False self.power_kills = 0 self.erector_uses = 0 self.Ttoggle_erector = True self.Ttoggle_teleport = True self.grenade_immunity_msg_timeout = False return connection.on_login(self, name) def _grenade_immunity_timout(self): if (self.grenade_immunity_msg_timeout): self.grenade_immunity_msg_timeout = False def explain_temp(self): message = "" message = ("Armor level %s" % self.intel_p_lvl[0]) if self.intel_temp == 0 else message message = ("Deadly Dice level %s" % self.intel_p_lvl[1]) if self.intel_temp == 1 else message message = ("Good Teammate level %s" % self.intel_p_lvl[2]) if self.intel_temp == 2 else message message = ("Teleportation level %s" % self.intel_p_lvl[3]) if self.intel_temp == 3 else message message = ("Regeneration level %s" % self.intel_p_lvl[4]) if self.intel_temp == 4 else message message = ("Poison Bullets level %s" % self.intel_p_lvl[5]) if self.intel_temp == 5 else message message = ("Nadesplosion level %s" % self.intel_p_lvl[6]) if self.intel_temp == 6 else message message = ("Erector level %s" % self.intel_p_lvl[7]) if self.intel_temp == 7 else message return(message) def explain_power(self): message = "powers: " message += ("Armor level %s, " % self.intel_p_lvl[0]) if self.intel_p_lvl[0] > 0 else "" message += ("Deadly Dice level %s, " % self.intel_p_lvl[1]) if self.intel_p_lvl[1] > 0 else "" message += ("Good Teammate level %s, " % self.intel_p_lvl[2]) if self.intel_p_lvl[2] > 0 else "" message += ("Teleportation level %s, " % self.intel_p_lvl[3]) if self.intel_p_lvl[3] > 0 else "" message += ("Regeneration level %s, " % self.intel_p_lvl[4]) if self.intel_p_lvl[4] > 0 else "" message += ("Poison Bullets level %s, " % self.intel_p_lvl[5]) if self.intel_p_lvl[5] > 0 else "" message += ("Nadesplosion level %s, " % self.intel_p_lvl[6]) if self.intel_p_lvl[6] > 0 else "" message += ("Erector level %s, " % self.intel_p_lvl[7]) if self.intel_p_lvl[7] > 0 else "" if message == "powers: ": message = "no powers" else: message = message[:-2] return(message) def nadesplode(self, hit_player): self.protocol.world.create_object(Grenade, 0.0, hit_player.world_object.position, None, Vertex3(), self.nadepl_exploded) grenade_packet.value = 0.1 grenade_packet.player_id = self.player_id grenade_packet.position = (hit_player.world_object.position.x, hit_player.world_object.position.y, hit_player.world_object.position.z) grenade_packet.velocity = (0.0, 0.0, 0.0) self.protocol.send_contained(grenade_packet) def nadepl_exploded(self, grenade): self.headshot_splode = True connection.grenade_exploded(self, grenade) def on_hit(self, hit_amount, hit_player, type, grenade): value = connection.on_hit(self, hit_amount, hit_player, type, grenade) if (self.intel_p_lvl[6] and grenade and self.player_id == hit_player.player_id): if not self.grenade_immunity_msg_timeout: self.send_chat("You are immunized against all danger!") self.grenade_immunity_msg_timeout = True callLater(3, self._grenade_immunity_timout) return 0 if value is not None or hit_player.team == self.team: return value value = hit_amount if hit_player.intel_p_lvl[0] > 0: if type != HEADSHOT_KILL and type != MELEE_KILL: if hit_player.intel_p_lvl[0] == 3: value *= .125 if hit_player.intel_p_lvl[0] == 2: value *= .25 if hit_player.intel_p_lvl[0] == 1: value *= .50 else: self.send_chat("%s is wearing armor! Aim for the head!" % hit_player.name ) if self.intel_p_lvl[1] > 0: dice_roll = random.randint(1, 100) if dice_roll <= 20 and self.intel_p_lvl[1] == 3: value = 100 hit_player.send_chat("You have been instakilled by %s !" % self.name) self.send_chat("Alea iacta est... You have rolled the dice of life and instakilled %s!" % hit_player.name) if dice_roll <= 15 and self.intel_p_lvl[1] == 2: value = 100 hit_player.send_chat("You have been instakilled by %s !" % self.name) self.send_chat("Alea iacta est... You have rolled the dice of life and instakilled %s!" % hit_player.name) if dice_roll <= 10 and self.intel_p_lvl[1] == 1: value = 100 hit_player.send_chat("You have been instakilled by %s !" % self.name) self.send_chat("Alea iacta est... You have rolled the dice of life and instakilled %s!" % hit_player.name) if self.intel_p_lvl[5] > 0: hit_player.send_chat("You have been poisoned by %s ! Get to the tent to cure it!" % self.name) hit_player.poisoner = self hit_player.poison = self.intel_p_lvl[5] return value def on_kill(self, killer, type, grenade): if killer != self and killer is not None: self.send_chat("Type /power for more info on Intel Powers") self.send_chat("You were killed by %s who had %s" % (killer.name, killer.explain_power())) if killer.intel_p_lvl[2] > 0: healcount = 0 if killer.intel_p_lvl[2] != 2 and type == HEADSHOT_KILL: healcount += 1 killer.heal_team(10) if killer.intel_p_lvl[2] > 1: healcount += 1 killer.heal_team(30) if healcount > 0: killer.send_chat("Your kill has healed you and your teammates!") if killer.intel_p_lvl[6] > 0 and type == HEADSHOT_KILL: dice_roll = random.randint(1, 100) if dice_roll <= 50 and killer.intel_p_lvl[6] == 3: killer.nadesplode(self) if dice_roll <= 25 and killer.intel_p_lvl[6] == 2: killer.nadesplode(self) if dice_roll <= 10 and killer.intel_p_lvl[6] == 1: killer.nadesplode(self) killer.power_kills = killer.power_kills + 1 if killer.power_kills == 10: killer.power_kills = 0 killer.send_chat("You have reached 10 kills, you get a power-up!") killer.intel_upgrade() return connection.on_kill(self, killer, type, grenade) def on_spawn(self, pos): if self.intel_p_lvl[3] == 3: self.teleport_uses = 3 else: self.teleport_uses = 2 if self.intel_p_lvl[7] == 1: self.erector_uses = 25 elif self.intel_p_lvl[7] == 2: self.erector_uses = 25 else: self.erector_uses = 25 self.power_kills = 0 self.poisoner = None self.poison = 0 self.intel_downgrade() self.send_chat("Type /power for more information!") self.send_chat("You have %s" % self.explain_power()) return connection.on_spawn(self, pos) def heal_team(self, value): for player in self.team.get_players(): if player is None or player.hp <= 0: return dist = distance_3d_vector(self.world_object.position, player.world_object.position) if dist <= 16.0 or player == self: player.poison = 0 player.poisoner = None player.set_hp(player.hp + value, type = FALL_KILL) if player != self: player.send_chat("You have been healed by %s " % self.name) def intel_every_second(self): if self is None or self.hp <= 0: return self.headshot_splode = False if self.poison > 0 and self.poisoner is not None and self.poisoner.world_object is not None: self.hit(self.poison, self.poisoner) elif self.intel_p_lvl[4] > 0: if self.intel_p_lvl[4] == 3: self.set_hp(self.hp + 10, type = FALL_KILL) if self.intel_p_lvl[4] == 2: self.set_hp(self.hp + 5, type = FALL_KILL) if self.intel_p_lvl[4] == 1: self.set_hp(self.hp + 2, type = FALL_KILL) def on_refill(self): if self.intel_p_lvl[3] == 3: self.send_chat("3 teleport uses refilled.") self.teleport_uses = 3 elif self.intel_p_lvl[3] == 2: self.send_chat("2 teleport uses refilled.") self.teleport_uses = 2 if self.poison > 0: self.send_chat("You have been cured of the poison!") self.poison = 0 self.poisoner = None if self.intel_p_lvl[7] == 1: self.erector_uses = 25 self.send_chat("You have 25 Erector uses (2 high)") elif self.intel_p_lvl[7] == 2: self.erector_uses = 25 self.send_chat("You have 25 Erector uses (4 high)") elif self.intel_p_lvl[7] == 3: self.erector_uses = 25 self.send_chat("You have 25 Erector uses (6 high)") return connection.on_refill(self) def on_flag_take(self): if connection.on_flag_take(self) is not False: self.intel_temporary() self.send_chat("Bring intel to your base to keep it!") self.send_chat("You have temporarily gained power: %s" % self.explain_temp()) def on_color_set(self, color): if (self.tool != BLOCK_TOOL and self.intel_p_lvl[3] and self.intel_p_lvl[3] >= 1): self.send_chat("Switch to BLOCK TOOL to use teleport!") return connection.on_color_set(self, color) try: if self.intel_p_lvl[3] and self.intel_p_lvl[3] >= 1: if self.world_object.sneak: ray_dist = TP_RANGE[self.intel_p_lvl[3]] location = self.world_object.cast_ray(ray_dist) if location: x, y, z = location self.do_teleport(x, y, z) else: self.send_chat("Teleport out of range!") except AttributeError as e: # This shouldn't be reached under normal conditions print "self.intel_p_lvl not found for player #%d, player is a bot perhaps?" % self.player_id print "If you see this message, please report it lol" self.intel_clear() return connection.on_color_set(self, color) def on_flag_capture(self): if connection.on_flag_capture(self) is not False: self.intel_temp = False self.send_chat("Type /power for more information!") self.send_chat("You have %s" % self.explain_power()) connection.on_flag_capture(self) def do_teleport(self, x, y, z): if (self.Ttoggle_teleport): if self != self.team.other.flag.player: if self.teleport_uses == 0: self.send_chat("You've run out of teleport uses!") if self.teleport_uses > 0: self.teleport_uses -= 1 self.send_chat("%s teleport uses remaining." % self.teleport_uses) self.clear_tele_area(x, y, z) self.set_location_safe((x, y, z-1)) msg = "%s (#%d) used Teleport!" % (self.name, self.player_id) msg2 = "%s used Teleport!" % (self.name) self.protocol.irc_say(msg) self.protocol.send_chat(msg2) print msg else: self.send_chat("You can't teleport while holding intel!") return def sign(self, x): return (x > 0) - (x < 0) def erect(self, x, y, z, height): z2 = min(61, max(0, z - height + self.sign(height))) buildbox.build_filled(self.protocol, x, y, z, x, y, z2, self.color, self.god, self.god_build) def on_block_build(self, x, y ,z): if (self.Ttoggle_erector): if self.intel_p_lvl[7] != 0: if self.erector_uses > 0: if self.intel_p_lvl[7] == 1: self.erect(x, y, z, 2) elif self.intel_p_lvl[7] == 2: self.erect(x, y, z, 4) elif self.intel_p_lvl[7] == 3: self.erect(x, y, z, 6) self.erector_uses = self.erector_uses-1 if self.erector_uses == 0: self.send_chat("You've run out of erector uses!") return connection.on_block_build(self, x, y, z) def clear_tele_area(self, x, y, z): return map = self.protocol.map for nade_x in xrange(x - 1, x + 2): for nade_y in xrange(y - 1, y + 2): for nade_z in xrange(z - 1, z + 2): if nade_x > 0 and nade_x < 512 and nade_y > 0 and nade_y < 512 and nade_z > 0 and nade_z < 63: map.remove_point(nade_x, nade_y, nade_z) block_action.x = x block_action.y = y block_action.z = z block_action.value = 3 block_action.player_id = self.player_id self.protocol.send_contained(block_action, save = True) def intel_temporary(self): self.intel_temp = self.intel_upgrade() def intel_upgrade(self): say = self.send_chat if sum(self.intel_p_lvl) >= 24: say("You have every power maxed out!") return False dice_roll = random.randint(0, 7) if self.intel_power_pref != 8 and sum(self.intel_p_lvl) != 0: dice_roll = self.intel_power_pref if self.intel_p_lvl[dice_roll] < 3: self.intel_p_lvl[dice_roll] += 1 return dice_roll while (self.intel_p_lvl[dice_roll] == 3): dice_roll = random.randint(0, 7) self.intel_power_pref = dice_roll if sum(self.intel_p_lvl) != 0 or self.intel_power_pref == 7 else self.intel_power_pref self.intel_p_lvl[dice_roll] += 1 return dice_roll def intel_downgrade(self): if self.intel_temp is False: return self.intel_p_lvl[self.intel_temp] -= 1 self.intel_temp = False def intel_clear(self): self.poisoner = None self.poison = 0 self.intel_p_lvl = [0,0,0,0,0,0,0,0] self.intel_power_pref = 8 self.intel_temp = False class IntelPowerProtocol(protocol): intel_second_counter = 0 def on_game_end(self): for player in self.players.values(): player.intel_clear() self.send_chat("Round is over! Intel Powers have been reset!") protocol.on_game_end(self) def on_world_update(self): self.intel_second_counter += 1 if self.intel_second_counter >= 90: for player in self.players.values(): player.intel_every_second() self.intel_second_counter = 0 protocol.on_world_update(self) return IntelPowerProtocol, IntelPowerConnection