exp gain
This commit is contained in:
		
							parent
							
								
									07a91436b4
								
							
						
					
					
						commit
						5097d4292b
					
				| @ -1,4 +1,5 @@ | |||||||
| use libpso::packet::messages::*; | use libpso::packet::messages::*; | ||||||
|  | use crate::common::leveltable::CharacterStats; | ||||||
| use crate::ship::ship::{ShipError}; | use crate::ship::ship::{ShipError}; | ||||||
| use crate::ship::items::{FloorItem}; | use crate::ship::items::{FloorItem}; | ||||||
| use crate::ship::location::AreaClient; | use crate::ship::location::AreaClient; | ||||||
| @ -63,3 +64,25 @@ pub fn drop_split_stack(area_client: AreaClient, item: &FloorItem) -> Result<Dro | |||||||
|         unknown2: 0, |         unknown2: 0, | ||||||
|     }) |     }) | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | pub fn character_gained_exp(area_client: AreaClient, exp: u32) -> GiveCharacterExp { | ||||||
|  |     GiveCharacterExp { | ||||||
|  |         client: area_client.local_client.id(), | ||||||
|  |         target: 0, | ||||||
|  |         exp: exp, | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn character_leveled_up(area_client: AreaClient, level: u32, before_stats: CharacterStats, after_stats: CharacterStats) -> PlayerLevelUp { | ||||||
|  |     PlayerLevelUp { | ||||||
|  |         client: area_client.local_client.id(), | ||||||
|  |         target: 0, | ||||||
|  |         atp: after_stats.atp - before_stats.atp, | ||||||
|  |         mst: after_stats.mst - before_stats.mst, | ||||||
|  |         evp: after_stats.evp - before_stats.evp, | ||||||
|  |         hp: after_stats. hp - before_stats. hp, | ||||||
|  |         dfp: after_stats.dfp - before_stats.dfp, | ||||||
|  |         ata: after_stats.ata - before_stats.ata, | ||||||
|  |         lvl: level, | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | |||||||
| @ -3,26 +3,58 @@ use libpso::packet::ship::*; | |||||||
| use libpso::packet::messages::*; | use libpso::packet::messages::*; | ||||||
| use crate::entity::gateway::EntityGateway; | use crate::entity::gateway::EntityGateway; | ||||||
| use crate::common::serverstate::ClientId; | use crate::common::serverstate::ClientId; | ||||||
|  | use crate::common::leveltable::CharacterLevelTable; | ||||||
| use crate::ship::ship::{SendShipPacket, ShipError, Rooms, Clients, ItemDropLocation}; | use crate::ship::ship::{SendShipPacket, ShipError, Rooms, Clients, ItemDropLocation}; | ||||||
| use crate::ship::location::{ClientLocation, ClientLocationError, RoomLobby}; | use crate::ship::location::{ClientLocation, ClientLocationError, RoomLobby}; | ||||||
| use crate::ship::map::{MapArea}; | use crate::ship::map::{MapArea}; | ||||||
| use crate::ship::items::{ItemManager, ClientItemId}; | use crate::ship::items::{ItemManager, ClientItemId}; | ||||||
| use crate::ship::packet::builder; | use crate::ship::packet::builder; | ||||||
| 
 | 
 | ||||||
| pub fn request_exp(id: ClientId, | pub async fn request_exp<EG: EntityGateway>(id: ClientId, | ||||||
|                    request_exp: &RequestExp, |                                             request_exp: &RequestExp, | ||||||
|                    client_location: &ClientLocation, |                                             entity_gateway: &mut EG, | ||||||
|                    rooms: &Rooms) |                                             client_location: &ClientLocation, | ||||||
|                    -> Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send> { |                                             clients: &mut Clients, | ||||||
|     
 |                                             rooms: &mut Rooms, | ||||||
|     match client_location.get_area(id).unwrap() { |                                             level_table: &CharacterLevelTable) | ||||||
|         RoomLobby::Room(room) => { |                                             -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> { | ||||||
|             let r  = rooms[room.0].as_ref().unwrap(); |     let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?; | ||||||
|             warn!("killed a {:?}", r.maps.enemy_by_id(request_exp.enemy_id as usize).unwrap().monster); |     let area_client = client_location.get_local_client(id).map_err(|err| -> ClientLocationError { err.into() })?; | ||||||
|         }, |     let room_id = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() })?; | ||||||
|         _ => {} |     let room = rooms.get_mut(room_id.0) | ||||||
|     }; |         .ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))? | ||||||
|     Box::new(None.into_iter()) |         .as_mut() | ||||||
|  |         .ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?; | ||||||
|  | 
 | ||||||
|  |     let monster = room.maps.enemy_by_id(request_exp.enemy_id as usize)?; | ||||||
|  |     let monster_stats = room.monster_stats.get(&monster.monster).unwrap(); | ||||||
|  | 
 | ||||||
|  |     let clients_in_area = client_location.get_clients_in_room(room_id).map_err(|err| -> ClientLocationError { err.into() })?; | ||||||
|  |     let gain_exp_pkt = builder::message::character_gained_exp(area_client, monster_stats.exp); | ||||||
|  |     let mut exp_pkts: Box<dyn Iterator<Item = _> + Send> = Box::new(clients_in_area.clone().into_iter() | ||||||
|  |         .map(move |c| { | ||||||
|  |             (c.client, SendShipPacket::Message(Message::new(GameMessage::GiveCharacterExp(gain_exp_pkt.clone())))) | ||||||
|  |         })); | ||||||
|  | 
 | ||||||
|  |     let before_level = level_table.get_level_from_exp(client.character.char_class, client.character.exp); | ||||||
|  |     let after_level = level_table.get_level_from_exp(client.character.char_class, client.character.exp + monster_stats.exp); | ||||||
|  |     let level_up = before_level != after_level; | ||||||
|  | 
 | ||||||
|  |     if level_up { | ||||||
|  |         let (_, before_stats) = level_table.get_stats_from_exp(client.character.char_class, client.character.exp); | ||||||
|  |         let (after_level, after_stats) = level_table.get_stats_from_exp(client.character.char_class, client.character.exp + monster_stats.exp); | ||||||
|  | 
 | ||||||
|  |         let level_up_pkt = builder::message::character_leveled_up(area_client, after_level, before_stats, after_stats); | ||||||
|  |         exp_pkts = Box::new(exp_pkts.chain(clients_in_area.into_iter() | ||||||
|  |             .map(move |c| { | ||||||
|  |                 (c.client, SendShipPacket::Message(Message::new(GameMessage::PlayerLevelUp(level_up_pkt.clone())))) | ||||||
|  |             }))) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     client.character.exp += monster_stats.exp; | ||||||
|  |     entity_gateway.save_character(&client.character).await; | ||||||
|  | 
 | ||||||
|  |     Ok(exp_pkts) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub async fn player_drop_item<EG>(id: ClientId, | pub async fn player_drop_item<EG>(id: ClientId, | ||||||
|  | |||||||
| @ -242,7 +242,7 @@ pub struct ShipServerState<EG: EntityGateway> { | |||||||
|     client_location: ClientLocation, |     client_location: ClientLocation, | ||||||
|     level_table: CharacterLevelTable, |     level_table: CharacterLevelTable, | ||||||
|     name: String, |     name: String, | ||||||
|     rooms: Rooms, |     pub rooms: Rooms, | ||||||
|     pub item_manager: items::ItemManager, |     pub item_manager: items::ItemManager, | ||||||
|     quests: quests::QuestList, |     quests: quests::QuestList, | ||||||
| } | } | ||||||
| @ -264,7 +264,7 @@ impl<EG: EntityGateway> ShipServerState<EG> { | |||||||
|     async fn message(&mut self, id: ClientId, msg: &Message) -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> { |     async fn message(&mut self, id: ClientId, msg: &Message) -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError> { | ||||||
|         match &msg.msg { |         match &msg.msg { | ||||||
|             GameMessage::RequestExp(request_exp) => { |             GameMessage::RequestExp(request_exp) => { | ||||||
|                 Ok(handler::message::request_exp(id, request_exp, &self.client_location, &self.rooms)) |                 handler::message::request_exp(id, request_exp, &mut self.entity_gateway, &self.client_location, &mut self.clients, &mut self.rooms, &self.level_table).await | ||||||
|             }, |             }, | ||||||
|             GameMessage::PlayerDropItem(player_drop_item) => { |             GameMessage::PlayerDropItem(player_drop_item) => { | ||||||
|                 handler::message::player_drop_item(id, player_drop_item, &mut self.entity_gateway, &mut self.client_location, &mut self.clients, &mut self.rooms, &mut self.item_manager).await |                 handler::message::player_drop_item(id, player_drop_item, &mut self.entity_gateway, &mut self.client_location, &mut self.clients, &mut self.rooms, &mut self.item_manager).await | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user