def handle_interaction(self, event_data, registry): """Presents options window when another player has interacted with this player. :param event_data: Information on the type of interaction and who sent it. :param registry: :type event_data: Dictionary :type registry: Dictionary :rtype: None :returns: None """ print(event_data) target = registry[event_data["target"]]["sprite"] target_name = str(target.name) networking.update_client(target, event_data["char_dict"], self.game) if event_data["interaction"] == "DUEL": if not event_data["response"]: self.interaction_menu.visible = True self.interaction_menu.interactable = True self.interaction_menu.player = target self.interaction_menu.interaction = "DUEL" self.interaction_menu.menu_items = [ target_name + " would like to Duel!", "Accept", "Decline" ] else: if self.wants_duel: if event_data["response"] == "Accept": world = self.game.current_state pd = world.player1.__dict__ event_data = { "type": "CLIENT_INTERACTION", "interaction": "START_DUEL", "target": [event_data["target"]], "response": None, "char_dict": { "monsters": pd["monsters"], "inventory": pd["inventory"] } } self.game.server.notify_client_interaction( cuuid, event_data)
def broadcast_player_teleport_change(self): """ Tell clients/host that player has moved or changed map after teleport :return: """ # Set the transition variable in event_data to false when we're done self.game.event_data["transition"] = False # Update the server/clients of our new map and populate any other players. if self.game.isclient or self.game.ishost: self.game.add_clients_to_map(self.game.client.client.registry) self.game.client.update_player(self.player1.facing) # Update the location of the npcs. Doesn't send network data. for npc in self.npcs.values(): char_dict = {"tile_pos": npc.tile_pos} networking.update_client(npc, char_dict, self.game) for npc in self.npcs_off_map.values(): char_dict = {"tile_pos": npc.tile_pos} networking.update_client(npc, char_dict, self.game)
def handle_interaction(self, event_data, registry): """Presents options window when another player has interacted with this player. :param event_data: Information on the type of interaction and who sent it. :param registry: :type event_data: Dictionary :type registry: Dictionary :rtype: None :returns: None """ print(event_data) target = registry[event_data["target"]]["sprite"] target_name = str(target.name) networking.update_client(target, event_data["char_dict"], self.game) if event_data["interaction"] == "DUEL": if not event_data["response"]: self.interaction_menu.visible = True self.interaction_menu.interactable = True self.interaction_menu.player = target self.interaction_menu.interaction = "DUEL" self.interaction_menu.menu_items = [target_name+" would like to Duel!","Accept","Decline"] else: if self.wants_duel: if event_data["response"] == "Accept": world = self.game.current_state pd = world.player1.__dict__ event_data = {"type": "CLIENT_INTERACTION", "interaction": "START_DUEL", "target": [event_data["target"]], "response": None, "char_dict": {"monsters": pd["monsters"], "inventory": pd["inventory"] } } self.game.server.notify_client_interaction(cuuid, event_data)
def move_npcs(self): """ Move NPCs and Players around according to their state This function may be moved to a server :return: """ # Draw any game NPC's for npc in self.npcs.values(): if npc.running: npc.moverate = npc.runrate else: npc.moverate = npc.walkrate # Get the NPC's tile position based on his pixel position. Since the NPC's sprite is 1 x 2 # tiles in size, we add 1 to the 'y' position so the NPC's actual position will be on the bottom # portion of the sprite. npc.tile_pos = (float((npc.position[0] - self.global_x)) / float( self.tile_size[0]), (float((npc.position[1] - self.global_y)) / float(self.tile_size[1])) + 1) # Move the NPC with the map as it moves npc.position[0] -= self.global_x_diff npc.position[1] -= self.global_y_diff # if the npc has a path, move it along its path if npc.path: npc.move_by_path() npc.move(self.tile_size, self.time_passed_seconds, self) # Reset our directions after moving. if not npc.isplayer: npc.direction["up"] = False npc.direction["down"] = False npc.direction["left"] = False npc.direction["right"] = False if npc.update_location: char_dict = {"tile_pos": npc.final_move_dest} networking.update_client(npc, char_dict, self.game) npc.update_location = False # Move any multiplayer characters that are off map so we know where they should be when we change maps. for npc in self.npcs_off_map.values(): if npc.running: npc.moverate = npc.runrate else: npc.moverate = npc.walkrate # Get the NPC's tile position based on his pixel position. Since the NPC's sprite is 1 x 2 # tiles in size, we add 1 to the 'y' position so the NPC's actual position will be on the bottom # portion of the sprite. npc.tile_pos = (float((npc.position[0] - self.global_x)) / float( self.tile_size[0]), (float((npc.position[1] - self.global_y)) / float(self.tile_size[1])) + 1) # Move the NPC with the map as it moves npc.position[0] -= self.global_x_diff npc.position[1] -= self.global_y_diff # if the npc has a path, move it along its path if npc.path: npc.move_by_path() npc.move(self.tile_size, self.time_passed_seconds, self)
def move_npcs(self): """ Move NPCs and Players around according to their state This function may be moved to a server :return: """ # Draw any game NPC's for npc in self.npcs.values(): if npc.running: npc.moverate = npc.runrate else: npc.moverate = npc.walkrate # Get the NPC's tile position based on his pixel position. Since the NPC's sprite is 1 x 2 # tiles in size, we add 1 to the 'y' position so the NPC's actual position will be on the bottom # portion of the sprite. npc.tile_pos = (float( (npc.position[0] - self.global_x)) / float(self.tile_size[0]), (float((npc.position[1] - self.global_y)) / float(self.tile_size[1])) + 1) # Move the NPC with the map as it moves npc.position[0] -= self.global_x_diff npc.position[1] -= self.global_y_diff # if the npc has a path, move it along its path if npc.path: npc.move_by_path() npc.move(self.tile_size, self.time_passed_seconds, self) # Reset our directions after moving. if not npc.isplayer: npc.direction["up"] = False npc.direction["down"] = False npc.direction["left"] = False npc.direction["right"] = False if npc.update_location: char_dict = {"tile_pos": npc.final_move_dest} networking.update_client(npc, char_dict, self.game) npc.update_location = False # Move any multiplayer characters that are off map so we know where they should be when we change maps. for npc in self.npcs_off_map.values(): if npc.running: npc.moverate = npc.runrate else: npc.moverate = npc.walkrate # Get the NPC's tile position based on his pixel position. Since the NPC's sprite is 1 x 2 # tiles in size, we add 1 to the 'y' position so the NPC's actual position will be on the bottom # portion of the sprite. npc.tile_pos = (float( (npc.position[0] - self.global_x)) / float(self.tile_size[0]), (float((npc.position[1] - self.global_y)) / float(self.tile_size[1])) + 1) # Move the NPC with the map as it moves npc.position[0] -= self.global_x_diff npc.position[1] -= self.global_y_diff # if the npc has a path, move it along its path if npc.path: npc.move_by_path() npc.move(self.tile_size, self.time_passed_seconds, self)
def fullscreen_animations(self, surface): """Handles fullscreen animations such as transitions, cutscenes, etc. :param surface: Surface to draw onto :rtype: None :returns: None """ # artificially set the time passed to make up for case # when map loads drop fps and causes the fade to be skipped td = 0.016 # 60 fps # F****N' MATH! 0 = NO ALPHA NOT 255 DAMNIT BILLY! # if the value of start_transition event is set to true if self.start_transition: if self.transition_alpha == 0: self.SAVE_THIS_FUCKING_SCREEN = surface.copy() self.transition_surface = self.SAVE_THIS_FUCKING_SCREEN.copy() # f*****g dumb ass math wont let me do less than 1 second so I had to speed that shit up so # I multiplied time_passed_seconds testing around making the fade faster because Billys' # teleport is TOO F*****G FAST self.transition_alpha += 255 * (td / self.transition_time) if self.transition_alpha >= 255: self.transition_alpha = 255 # created a black screen variable so it actually looks like he teleported, gotta figure out # how to make the event start earlier, initial testing proves I need sleep. Also billys' # teleport is STILL TOO F*****G FAST! if self.black_screen >= 50: self.black_screen = 50 self.start_transition_back = True self.start_transition = False self.black_screen += 50 * (td / self.transition_time) self.transition_surface.set_alpha(self.transition_alpha) self.transition_surface.fill((0, 0, 0)) surface.blit(self.transition_surface, (0, 0)) # print(transition_alpha) # Perform a delayed teleport if we're also doing a teleport and we've # faded out completely if self.delayed_teleport and self.start_transition_back: self.global_x = self.delayed_x self.global_y = self.delayed_y if self.delayed_facing: self.player1.facing = self.delayed_facing self.delayed_facing = None # check if map has changed, and if so, change it map_name = prepare.BASEDIR + "resources/maps/" + self.delayed_mapname if map_name != self.current_map.filename: self.change_map(map_name) self.delayed_teleport = False # Replace this SAVE_THIS_FUCKING_SCREEN with the value of the blit of # the new map if self.start_transition_back: self.transition_back_surface = self.SAVE_THIS_FUCKING_SCREEN.copy() # same shit as above down here as well, except i slowed that shit # down self.transition_alpha -= 255 * (td / self.transition_time) if self.transition_alpha <= 0: self.transition_alpha = 0 self.start_transition_back = False self.black_screen = 0 self.transition_back_surface.set_alpha(self.transition_alpha) self.transition_back_surface.fill((0, 0, 0)) surface.blit(self.transition_back_surface, (0, 0)) self.game.event_data[ "transition"] = False # Set the transition variable in event_data to false when we're done # Update the server/clients of our new map and populate any other players. if self.game.isclient or self.game.ishost: self.game.add_clients_to_map(self.game.client.client.registry) self.game.client.update_player(self.player1.facing) # Update the location of the npcs. Doesn't send network data. for npc in self.npcs: char_dict = {"tile_pos": npc.tile_pos} networking.update_client(npc, char_dict, self.game) for npc in self.npcs_off_map: char_dict = {"tile_pos": npc.tile_pos} networking.update_client(npc, char_dict, self.game)
def player_movement(self): """Handles player's movement, collision, and drawing. Also draws map tiles that are on a layer above the player. :param: None :rtype: None :returns: None """ # Get all the keys pressed for modifiers only! pressed = list(pygame.key.get_pressed()) self.ctrl_held = pressed[pygame.K_LCTRL] or pressed[pygame.K_RCTRL] self.alt_held = pressed[pygame.K_LALT] or pressed[pygame.K_RALT] self.shift_held = pressed[pygame.K_LSHIFT] or pressed[pygame.K_RSHIFT] # TODO: phase out in favor of a global game clock self.time_passed_seconds = self.game.time_passed_seconds # Handle tile based movement for the player if self.shift_held: self.player1.moverate = self.player1.runrate else: self.player1.moverate = self.player1.walkrate # Check to see if the player is colliding with anything self.collision_rectmap = [] for item in self.collision_map: self.collision_rectmap.append( pygame.Rect( (item[0] * self.tile_size[0]) + self.global_x, (item[1] * self.tile_size[0]) + self.global_y, self.tile_size[0], self.tile_size[1])) # Add any NPC's to the collision rectangle map. We use this to see if # the player is colliding or not for npc in self.npcs: self.collision_rectmap.append( pygame.Rect(npc.position[0], npc.position[1], self.tile_size[0], self.tile_size[1])) # Set the global_x/y when the player moves around self.global_x, self.global_y = self.player1.move( self.screen, self.tile_size, self.time_passed_seconds, (self.global_x, self.global_y), self) # Find out how many pixels we've moved since we started moving self.global_x_diff = self.orig_global_x - self.global_x self.global_y_diff = self.orig_global_y - self.global_y # Draw any game NPC's for npc in self.npcs: if npc.running: npc.moverate = npc.runrate else: npc.moverate = npc.walkrate # Get the NPC's tile position based on his pixel position. Since the NPC's sprite is 1 x 2 # tiles in size, we add 1 to the 'y' position so the NPC's actual position will be on the bottom # portion of the sprite. npc.tile_pos = (float((npc.position[0] - self.global_x)) / float( self.tile_size[0]), (float((npc.position[1] - self.global_y)) / float(self.tile_size[1])) + 1) # If the NPC is not visible on the screen, don't draw him #if self.screen_rect.colliderect(npc.rect): # npc.move(self.screen, self.tile_size, self.time_passed_seconds, ( #### Disabled for now # npc.position[0], npc.position[1]), self) # Move the NPC with the map as it moves npc.position[0] -= self.global_x_diff npc.position[1] -= self.global_y_diff # debug info #print("npc.tile_pos="+str(npc.tile_pos)) # if the npc has a path, move it along its path if npc.path: npc.move_by_path() npc.move(self.tile_size, self.time_passed_seconds, self) # Reset our directions after moving. if not npc.isplayer: npc.direction["up"] = False npc.direction["down"] = False npc.direction["left"] = False npc.direction["right"] = False if npc.update_location: char_dict ={"tile_pos": npc.final_move_dest, } networking.update_client(npc, char_dict, self.game) npc.update_location = False # Draw the bottom part of the NPC. npc.draw(self.screen, "bottom") # Move any multiplayer characters that are off map so we know where they should be when we change maps. for npc in self.npcs_off_map: if npc.running: npc.moverate = npc.runrate else: npc.moverate = npc.walkrate # Get the NPC's tile position based on his pixel position. Since the NPC's sprite is 1 x 2 # tiles in size, we add 1 to the 'y' position so the NPC's actual position will be on the bottom # portion of the sprite. npc.tile_pos = (float((npc.position[0] - self.global_x)) / float( self.tile_size[0]), (float((npc.position[1] - self.global_y)) / float(self.tile_size[1])) + 1) # Move the NPC with the map as it moves npc.position[0] -= self.global_x_diff npc.position[1] -= self.global_y_diff # if the npc has a path, move it along its path if npc.path: npc.move_by_path() npc.move(self.tile_size, self.time_passed_seconds, self) # Draw the bottom half of the player self.player1.draw(self.screen, "bottom") # Draw the medium level tiles. These tiles will appear above the player's body, # but below the player's head. for tile in self.medlayer_tiles: # Get the rectangle object of the tile that is going to be drawn so # we can see if it is going to be outside the visible screen area # or not if type(tile["surface"]) is pygame.Surface: tile_rect = pygame.Rect(tile["surface"].get_width(), tile["surface"].get_height(), tile[ "position"][0] + self.global_x, tile["position"][1] + self.global_y) else: tile_rect = pygame.Rect(tile["surface"].getMaxSize()[0], tile["surface"].getMaxSize()[1], tile["position"][0] + self.global_x, tile["position"][1] + self.global_y) # If any part of the tile overlaps with the screen, then draw it to # the screen if self.screen_rect.colliderect(tile_rect): med_x = tile["position"][0] + self.orig_global_x med_y = tile["position"][1] + self.orig_global_y if type(tile["surface"]) is pygame.Surface: self.screen.blit(tile["surface"], (med_x, med_y)) else: tile["surface"].blit(self.screen, (med_x, med_y)) # Draw the top half of our NPCs above layer 4. for npc in self.npcs: npc.draw(self.screen, "top") # Draw the top half of the player above layer 4. self.player1.draw(self.screen, "top")