flip4clip
This commit is contained in:
		
							parent
							
								
									5a83daed48
								
							
						
					
					
						commit
						f6cc869cdc
					
				| @ -406,6 +406,7 @@ where | ||||
| // TODO: convenience function for giving exp and checking levelups (un-duplicate code here and `request_exp`)
 | ||||
| // TODO: use real errors (Idunnoman)
 | ||||
| // TODO: create InventoryError::CannotGetItemHandle or something
 | ||||
| #[allow(clippy::too_many_arguments)] | ||||
| pub async fn player_steals_exp<EG> (id: ClientId, | ||||
|                                     expsteal: &ExperienceSteal, | ||||
|                                     entity_gateway: &mut EG, | ||||
| @ -433,87 +434,87 @@ where | ||||
|             let monster_stats = room.monster_stats.get(&monster.monster).ok_or(ShipError::UnknownMonster(monster.monster))?; | ||||
| 
 | ||||
|             let remaining_exp = monster_stats.exp - monster.stolen_exp[area_client.local_client.id() as usize]; | ||||
|             if remaining_exp <= 0 { | ||||
|                 Ok(Box::new(None.into_iter())) | ||||
|             } else { | ||||
|             let char_special_modifier: f32 = if client.character.char_class.is_android()  { | ||||
|                 if room.mode.difficulty() == crate::ship::room::Difficulty::Ultimate { | ||||
|                     0.3 | ||||
|             if remaining_exp > 0 { | ||||
|                 let char_special_modifier: f32 = if client.character.char_class.is_android()  { | ||||
|                     if room.mode.difficulty() == crate::ship::room::Difficulty::Ultimate { | ||||
|                         0.3 | ||||
|                     } else { | ||||
|                         0.0 | ||||
|                     } | ||||
|                 } else { | ||||
|                     0.0 | ||||
|                 } | ||||
|             } else { | ||||
|                 0.0 | ||||
|             }; | ||||
| 
 | ||||
|             let equipped_weapon_handle = item_manager | ||||
|                 .get_character_inventory_mut(&client.character)? | ||||
|                 .get_equipped_weapon_handle() | ||||
|                 .ok_or(ItemManagerError::CannotGetIndividualItem)?; 
 | ||||
| 
 | ||||
|             let equipped_weapon = &equipped_weapon_handle | ||||
|                 .item() | ||||
|                 .ok_or(ItemManagerError::Idunnoman)? | ||||
|                 .individual() | ||||
|                 .ok_or(ItemManagerError::Idunnoman)?.item; | ||||
| 
 | ||||
|             let special_exp_ratio: f32 = { | ||||
|                 match equipped_weapon { | ||||
|                     ItemDetail::Weapon(weapon) => match weapon.special { | ||||
|                         Some(WeaponSpecial::Masters) => 0.08, | ||||
|                         Some(WeaponSpecial::Lords) => 0.10, | ||||
|                         Some(WeaponSpecial::Kings) => 0.12, | ||||
|                         _ => 0.0, // TODO: error - stealing exp with wrong special
 | ||||
|                     }, | ||||
|                     ItemDetail::ESWeapon(esweapon) => match esweapon.special { | ||||
|                         Some(ESWeaponSpecial::Kings) => 0.12, | ||||
|                         _ => 0.0, // TODO: error - stealing exp with wrong special
 | ||||
|                     }, | ||||
|                     _ => 0.0, // TODO: error - stealing exp without a weapon!!
 | ||||
|                 } | ||||
|             }; | ||||
| 
 | ||||
|             let weapon_special_reduction: f32 = { | ||||
|                 match equipped_weapon { | ||||
|                     ItemDetail::Weapon(weapon) => weapon.weapon.special_penalty(), | ||||
|                     ItemDetail::ESWeapon(_esweapon) => 0.0, | ||||
|                     _ => 1.0, // unreachable?
 | ||||
|                 } | ||||
|             }; | ||||
| 
 | ||||
|             let exp_earned = std::cmp::min( | ||||
|                 ((monster_stats.exp as f32 * (char_special_modifier + special_exp_ratio)).clamp(1.0, 80.0) * (1.0 - weapon_special_reduction)) as u32, | ||||
|                 remaining_exp); | ||||
| 
 | ||||
|             monster.steal_exp(exp_earned, area_client.local_client.id() as usize); | ||||
|             println!("monster info: {:?}", monster); | ||||
| 
 | ||||
|             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, exp_earned); | ||||
|             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 + exp_earned); | ||||
|             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 + exp_earned); | ||||
| 
 | ||||
|                 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() | ||||
|                 }; | ||||
|     
 | ||||
|                 let equipped_weapon_handle = item_manager | ||||
|                     .get_character_inventory_mut(&client.character)? | ||||
|                     .get_equipped_weapon_handle() | ||||
|                     .ok_or(ItemManagerError::CannotGetIndividualItem)?; 
 | ||||
|     
 | ||||
|                 let equipped_weapon = &equipped_weapon_handle | ||||
|                     .item() | ||||
|                     .ok_or(ItemManagerError::Idunnoman)? | ||||
|                     .individual() | ||||
|                     .ok_or(ItemManagerError::Idunnoman)?.item; | ||||
|     
 | ||||
|                 let special_exp_ratio: f32 = { | ||||
|                     match equipped_weapon { | ||||
|                         ItemDetail::Weapon(weapon) => match weapon.special { | ||||
|                             Some(WeaponSpecial::Masters) => 0.08, | ||||
|                             Some(WeaponSpecial::Lords) => 0.10, | ||||
|                             Some(WeaponSpecial::Kings) => 0.12, | ||||
|                             _ => 0.0, // TODO: error - stealing exp with wrong special
 | ||||
|                         }, | ||||
|                         ItemDetail::ESWeapon(esweapon) => match esweapon.special { | ||||
|                             Some(ESWeaponSpecial::Kings) => 0.12, | ||||
|                             _ => 0.0, // TODO: error - stealing exp with wrong special
 | ||||
|                         }, | ||||
|                         _ => 0.0, // TODO: error - stealing exp without a weapon!!
 | ||||
|                     } | ||||
|                 }; | ||||
|     
 | ||||
|                 let weapon_special_reduction: f32 = { | ||||
|                     match equipped_weapon { | ||||
|                         ItemDetail::Weapon(weapon) => weapon.weapon.special_penalty(), | ||||
|                         ItemDetail::ESWeapon(_esweapon) => 0.0, | ||||
|                         _ => 1.0, // unreachable?
 | ||||
|                     } | ||||
|                 }; | ||||
|     
 | ||||
|                 let exp_earned = std::cmp::min( | ||||
|                     ((monster_stats.exp as f32 * (char_special_modifier + special_exp_ratio)).clamp(1.0, 80.0) * (1.0 - weapon_special_reduction)) as u32, | ||||
|                     remaining_exp); | ||||
|     
 | ||||
|                 monster.steal_exp(exp_earned, area_client.local_client.id() as usize); | ||||
|                 println!("monster info: {:?}", monster); | ||||
|     
 | ||||
|                 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, exp_earned); | ||||
|                 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::PlayerLevelUp(level_up_pkt.clone())))) | ||||
|                     }))) | ||||
|             } | ||||
| 
 | ||||
|             client.character.exp += exp_earned; | ||||
|             entity_gateway.save_character(&client.character).await?; | ||||
| 
 | ||||
|             Ok(exp_pkts) | ||||
|                         (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 + exp_earned); | ||||
|                 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 + exp_earned); | ||||
|     
 | ||||
|                     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 += exp_earned; | ||||
|                 entity_gateway.save_character(&client.character).await?; | ||||
|     
 | ||||
|                 Ok(exp_pkts) | ||||
|             } else { | ||||
|                 Ok(Box::new(None.into_iter())) | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user