def tick(this, delta_time): super().tick(delta_time) if this.owner.attributes["keys"][display.KEY_I] and ( not world.out_of_bounds(this.owner.X, this.owner.Y - 1)): world.objects.append( frostshot_obj.frostshot_atk( this.owner.X, this.owner.Y - 1, 0, -1, .5 * this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0 if this.owner.attributes["keys"][display.KEY_J] and ( not world.out_of_bounds(this.owner.X - 1, this.owner.Y)): world.objects.append( frostshot_obj.frostshot_atk( this.owner.X - 1, this.owner.Y, -1, 0, .5 * this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0 if this.owner.attributes["keys"][display.KEY_K] and ( not world.out_of_bounds(this.owner.X, this.owner.Y + 1)): world.objects.append( frostshot_obj.frostshot_atk( this.owner.X, this.owner.Y + 1, 0, 1, .5 * this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0 if this.owner.attributes["keys"][display.KEY_L] and ( not world.out_of_bounds(this.owner.X + 1, this.owner.Y)): world.objects.append( frostshot_obj.frostshot_atk( this.owner.X + 1, this.owner.Y, 1, 0, .5 * this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0
def tick(this, delta_time): super().tick(delta_time) if display.keyDown(ord('I')) and (not world.out_of_bounds( this.owner.X, this.owner.Y - 1)): world.objects.append( frostshot_obj.frostshot_atk( this.owner.X, this.owner.Y - 1, 0, -1, 1.25 * this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0 if display.keyDown(ord('J')) and (not world.out_of_bounds( this.owner.X - 1, this.owner.Y)): world.objects.append( frostshot_obj.frostshot_atk( this.owner.X - 1, this.owner.Y, -1, 0, 1.25 * this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0 if display.keyDown(ord('K')) and (not world.out_of_bounds( this.owner.X, this.owner.Y + 1)): world.objects.append( frostshot_obj.frostshot_atk( this.owner.X, this.owner.Y + 1, 0, 1, 1.25 * this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0 if display.keyDown(ord('L')) and (not world.out_of_bounds( this.owner.X + 1, this.owner.Y)): world.objects.append( frostshot_obj.frostshot_atk( this.owner.X + 1, this.owner.Y, 1, 0, 1.25 * this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0
def tick(this, delta_time): super().tick(delta_time) if this.owner.attributes["keys"][display.KEY_ATK_UP] and (not world.out_of_bounds(this.owner.X, this.owner.Y - 1)): world.objects.append(fireball_obj.fireball_atk(this.owner.X, this.owner.Y - 1, 0, -1, 1.25*this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0 elif this.owner.attributes["keys"][display.KEY_ATK_LEFT] and (not world.out_of_bounds(this.owner.X - 1, this.owner.Y)): world.objects.append(fireball_obj.fireball_atk(this.owner.X - 1, this.owner.Y, -1, 0, 1.25*this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0 elif this.owner.attributes["keys"][display.KEY_ATK_DOWN] and (not world.out_of_bounds(this.owner.X, this.owner.Y + 1)): world.objects.append(fireball_obj.fireball_atk(this.owner.X, this.owner.Y + 1, 0, 1, 1.25*this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0 elif this.owner.attributes["keys"][display.KEY_ATK_RIGHT] and (not world.out_of_bounds(this.owner.X + 1, this.owner.Y)): world.objects.append(fireball_obj.fireball_atk(this.owner.X + 1, this.owner.Y, 1, 0, 1.25*this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0
def tick(this, delta_time): super().tick(delta_time) if display.keyDown(ord('I')) and (not world.out_of_bounds(this.owner.X, this.owner.Y - 1)): world.objects.append(frostshot_obj.frostshot_atk(this.owner.X, this.owner.Y - 1, 0, -1, 1.25*this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0 if display.keyDown(ord('J')) and (not world.out_of_bounds(this.owner.X - 1, this.owner.Y)): world.objects.append(frostshot_obj.frostshot_atk(this.owner.X - 1, this.owner.Y, -1, 0, 1.25*this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0 if display.keyDown(ord('K')) and (not world.out_of_bounds(this.owner.X, this.owner.Y + 1)): world.objects.append(frostshot_obj.frostshot_atk(this.owner.X, this.owner.Y + 1, 0, 1, 1.25*this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0 if display.keyDown(ord('L')) and (not world.out_of_bounds(this.owner.X + 1, this.owner.Y)): world.objects.append(frostshot_obj.frostshot_atk(this.owner.X + 1, this.owner.Y, 1, 0, 1.25*this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0
def tick(this, delta_time): super().tick(delta_time) if this.owner.attributes["keys"][display.KEY_I] and (not world.out_of_bounds(this.owner.X, this.owner.Y - 1)): world.objects.append(frostshot_obj.frostshot_atk(this.owner.X, this.owner.Y - 1, 0, -1, .5*this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0 if this.owner.attributes["keys"][display.KEY_J] and (not world.out_of_bounds(this.owner.X - 1, this.owner.Y)): world.objects.append(frostshot_obj.frostshot_atk(this.owner.X - 1, this.owner.Y, -1, 0, .5*this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0 if this.owner.attributes["keys"][display.KEY_K] and (not world.out_of_bounds(this.owner.X, this.owner.Y + 1)): world.objects.append(frostshot_obj.frostshot_atk(this.owner.X, this.owner.Y + 1, 0, 1, .5*this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0 if this.owner.attributes["keys"][display.KEY_L] and (not world.out_of_bounds(this.owner.X + 1, this.owner.Y)): world.objects.append(frostshot_obj.frostshot_atk(this.owner.X + 1, this.owner.Y, 1, 0, .5*this.owner.attributes["magic"], 7, 100, this.owner)) this.time = 0
def fire_rain(player): for x in range(-2, 3): for y in range(-2, 3): if not world.out_of_bounds(x + player.X, y + player.Y): world.objects.append( frain.fire_rain(x + player.X, y + player.Y, 1.0 * player.attributes["magic"], player))
def knockback(player): hit_enemies = [] # List of all enemies close enough to hit range_sq = 9 # Hits everything within 3 tiles for obj in world.objects: if obj.type == "enemy" and ((player.X - obj.X)**2 + (player.Y - obj.Y)**2) <= range_sq: hit_enemies.append(obj) for hit in hit_enemies: hit.attributes["HP"] -= 10 # Knockback diff_x = hit.X - player.X diff_y = hit.Y - player.Y if diff_x != 0: # Normalize x knockback diff_x = int(diff_x / abs(diff_x)) if diff_y != 0: # Normalize y knockback diff_y = int(diff_y / abs(diff_y)) if diff_x == 0 and diff_y == 0: diff_x = 1 if not world.out_of_bounds( hit.X + diff_x, hit.Y + diff_y) and world.map[hit.X + diff_x][ hit.Y + diff_y][3]: # Enemy can move that way hit.X += diff_x hit.Y += diff_y
def update(this, delta_time): this.attributes["to_move"] += delta_time if this.attributes["to_move"] >= this.attributes["speed"]: this.attributes["to_move"] = 0 this.X += this.attributes["movex"] this.Y += this.attributes["movey"] this.attributes["range"] -= 1 if (this.attributes["range"] <= 0) or world.out_of_bounds(this.X, this.Y) or (not world.map[this.X][this.Y][3]): # Hit something or out of range. world.to_del.append(this)
def update(this, delta_time): this.attributes["sincemove"] += delta_time if this.attributes["sincemove"] > this.attributes["speed"]: this.attributes["sincemove"] = 0 this.X += this.attributes["move_x"] this.Y += this.attributes["move_y"] this.attributes["range"] -= 1 if this.attributes["range"] <= 0: world.to_del.append(this) if not world.out_of_bounds(this.X, this.Y) and not world.map[this.X][this.Y][3] and this.attributes["die_on_walls"]: # Hit a wall. world.to_del.append(this)
def knockback(player): hit_enemies = [] # List of all enemies close enough to hit range_sq = 9 # Hits everything within 3 tiles for obj in world.objects: if obj.type == "enemy" and ((player.X - obj.X) ** 2 + (player.Y - obj.Y) ** 2) <= range_sq: hit_enemies.append(obj) for hit in hit_enemies: hit.attributes["HP"] -= 10 # Knockback diff_x = hit.X - player.X diff_y = hit.Y - player.Y if diff_x != 0: # Normalize x knockback diff_x = int(diff_x / abs(diff_x)) if diff_y != 0: # Normalize y knockback diff_y = int(diff_y / abs(diff_y)) if diff_x == 0 and diff_y == 0: diff_x = 1 if not world.out_of_bounds(hit.X + diff_x, hit.Y + diff_y) and world.map[hit.X + diff_x][hit.Y + diff_y][3]: # Enemy can move that way hit.X += diff_x hit.Y += diff_y
def run_map(map_name, pipe): try: display.init_logger(map_name) world.load(map_name.split(';')[0]) # Only load everything before first ; world.world_name = map_name display.log("Map started") start_time = time.clock() since_start = 0 time_until_messages = 0 # How many ms before we send out messages again. Let's not overload the client # We handle messages before entering the loop to avoid a race condition as # the map is started before any message is sent (as not to overflow pipe's buffer) handle_messages(pipe) while True: # Calculate delta time delta_time = int((time.clock() - start_time) * 1000) - since_start if delta_time > 100: display.log("Capped tick at " + str(delta_time) + "ms. " + str(len(world.objects)) + "objects, "+ str(len(world.players)) + " players total") delta_time = 100 delta_time = max(0, delta_time) # Don't have ticks with negative time! since_start += delta_time time_until_messages -= delta_time print(delta_time, " ", end="\r") # If there are messages, handle them. if (pipe.poll()): if handle_messages(pipe): display.end_logger() return world.to_del.clear() world.to_del_plr.clear() continue_loop = False # Update objects obj_update_list = world.players + world.objects for index in range(len(obj_update_list)): obj = obj_update_list[index] # Update it obj.update(delta_time) if obj.type != "player": # Don't check player collisions as they can only collide with other players. for coll in obj_update_list[:index]: # Check for collision if coll.X == obj.X and coll.Y == obj.Y: obj.collide(coll) # Call collisions coll.collide(obj) #Check if out of bounds if world.out_of_bounds(obj.X, obj.Y): world.to_del.append(obj) if obj.blocks_map_exit: continue_loop = True # Delete objects that need to be deleted. for obj in set(world.to_del): # Set to remove duplicates world.objects.remove(obj) # Remove players that left for plr in set(world.to_del_plr): world.save_player(plr) world.players.remove(plr) # Handle move requests. for req in world.move_requests: pipe.send(("mov", req)) # Send request world.move_requests.clear() if time_until_messages <= 0: # Send data to players. send_data = {"type" : "update", "tiles" : []} for obj in world.objects + world.players: if obj.char() != '\0': send_data["tiles"].append({"color" : obj.color(), "chr" : obj.char(), "x": obj.X, "y": obj.Y}) # Send update to all players for plr in world.players: try: if plr.attributes["using_inv"]: pass # TODO: what now? else: plr.attributes["pipe"].send(JSON.dumps(send_data)) plr.send_extra_data() except Exception as ex: pass time_until_messages = 16 # Reset time if not continue_loop: # Nothing blocking. pipe.send(("end", )) display.log("Ending map") display.end_logger() while pipe.recv() != ("end",): # Wait for acknowledge of end. pass return except Exception as ex: pipe.send(("end", )) display.log("Ending map due to error!") display.log(str(traceback.format_exc())) display.end_logger() while pipe.recv() != ("end",): # Wait for acknowledge of end. pass return
# Redraw world tile, unless the object is invisible if obj.char() != '\0': display.printc(obj.X, obj.Y + 5, world.map[obj.X][obj.Y][2], world.map[obj.X][obj.Y][0]) # Update it if obj.update(delta_time) is not None: new_map_loaded = True for coll in world.objects: # Check for collision if ((coll.X, coll.Y) == (obj.X, obj.Y)) and (not coll is obj) : if obj.collide(coll) is not None: new_map_loaded = True break # Stop collide check, new map was loaded if new_map_loaded: break #Check if out of bounds if world.out_of_bounds(obj.X, obj.Y): world.to_del.append(obj) else: # And now redraw it display.printc(obj.X, obj.Y + 5, obj.char(), obj.color(), world.map[obj.X][obj.Y][1]) if new_map_loaded: if display.current_menu is not None: # End menu on new map load, don't want extra stuff left over. display.current_menu.clear() display.current_menu = None continue # Delete objects that need to be deleted. for obj in set(world.to_del): # Set to remove duplicates # Only print if in bounds if not world.out_of_bounds(obj.X, obj.Y): display.printc(obj.X, obj.Y + 5, world.map[obj.X][obj.Y][2], world.map[obj.X][obj.Y][0]) world.objects.remove(obj)
def fire_rain(player): for x in range(-2, 3): for y in range(-2, 3): if not world.out_of_bounds(x + player.X, y + player.Y): world.objects.append(frain.fire_rain(x + player.X, y + player.Y, 1.0 * player.attributes["magic"], player))