mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Correctly set the exp target for the next level when spawning a character.
Removed the unwrap_or from the update method for stats persistence, and have a dedicated method for updating single rows with a new connection.
This commit is contained in:
parent
cbfe3d52fc
commit
a41576e767
@ -85,17 +85,16 @@ impl fmt::Display for StatChangeError {
|
||||
impl Error for StatChangeError {}
|
||||
|
||||
impl Exp {
|
||||
/// Used to determine how much exp is required to reach the next level. When
|
||||
/// a character levels up, the next level target is increased by this value
|
||||
const EXP_INCREASE_FACTOR: u32 = 25;
|
||||
|
||||
pub fn current(&self) -> u32 { self.current }
|
||||
|
||||
pub fn maximum(&self) -> u32 { self.maximum }
|
||||
|
||||
pub fn set_current(&mut self, current: u32) { self.current = current; }
|
||||
|
||||
// TODO: Uncomment when needed
|
||||
// pub fn set_maximum(&mut self, maximum: u32) {
|
||||
// self.maximum = maximum;
|
||||
// }
|
||||
|
||||
pub fn change_by(&mut self, current: i64) {
|
||||
self.current = ((self.current as i64) + current) as u32;
|
||||
}
|
||||
@ -103,6 +102,10 @@ impl Exp {
|
||||
pub fn change_maximum_by(&mut self, maximum: i64) {
|
||||
self.maximum = ((self.maximum as i64) + maximum) as u32;
|
||||
}
|
||||
|
||||
pub fn update_maximum(&mut self, level: u32) {
|
||||
self.maximum = Self::EXP_INCREASE_FACTOR + (level * Self::EXP_INCREASE_FACTOR);
|
||||
}
|
||||
}
|
||||
|
||||
impl Level {
|
||||
|
@ -64,8 +64,8 @@ impl<'a> System<'a> for Sys {
|
||||
let stat = stats.get_mut_unchecked();
|
||||
while stat.exp.current() >= stat.exp.maximum() {
|
||||
stat.exp.change_by(-(stat.exp.maximum() as i64));
|
||||
stat.exp.change_maximum_by(25);
|
||||
stat.level.change_by(1);
|
||||
stat.exp.update_maximum(stat.level.level());
|
||||
}
|
||||
|
||||
stat.update_max_hp();
|
||||
|
@ -78,7 +78,7 @@ pub fn handle_client_disconnect(server: &mut Server, entity: EcsEntity) -> Event
|
||||
state.read_storage::<comp::Stats>().get(entity),
|
||||
) {
|
||||
if let Some(character_id) = player.character_id {
|
||||
persistence::stats::update(character_id, stats, None, db_dir);
|
||||
persistence::stats::update_item(character_id, stats, db_dir);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,9 +87,13 @@ pub struct Stats {
|
||||
|
||||
impl From<StatsJoinData<'_>> for comp::Stats {
|
||||
fn from(data: StatsJoinData) -> comp::Stats {
|
||||
let level = data.stats.level as u32;
|
||||
|
||||
let mut base_stats = comp::Stats::new(String::from(data.alias), *data.body);
|
||||
|
||||
base_stats.level.set_level(data.stats.level as u32);
|
||||
base_stats.level.set_level(level);
|
||||
base_stats.exp.update_maximum(level);
|
||||
|
||||
base_stats.exp.set_current(data.stats.exp as u32);
|
||||
|
||||
base_stats.update_max_hp();
|
||||
@ -155,4 +159,36 @@ mod tests {
|
||||
willpower: 4,
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn loads_stats_with_correct_level() {
|
||||
let data = StatsJoinData {
|
||||
alias: "test",
|
||||
body: &comp::Body::from(&Body {
|
||||
character_id: 0,
|
||||
race: 0,
|
||||
body_type: comp::humanoid::BodyType::Female as i16,
|
||||
hair_style: 0,
|
||||
beard: 0,
|
||||
eyebrows: 0,
|
||||
accessory: 0,
|
||||
hair_color: 0,
|
||||
skin: 0,
|
||||
eye_color: 0,
|
||||
}),
|
||||
stats: &Stats {
|
||||
character_id: 0,
|
||||
level: 3,
|
||||
exp: 70,
|
||||
endurance: 0,
|
||||
fitness: 2,
|
||||
willpower: 3,
|
||||
},
|
||||
};
|
||||
|
||||
let stats = comp::Stats::from(data);
|
||||
|
||||
assert_eq!(stats.level.level(), 3);
|
||||
assert_eq!(stats.exp.current(), 70);
|
||||
}
|
||||
}
|
||||
|
@ -4,18 +4,11 @@ use super::{establish_connection, models::StatsUpdate, schema};
|
||||
use crate::comp;
|
||||
use diesel::prelude::*;
|
||||
|
||||
pub fn update(
|
||||
character_id: i32,
|
||||
stats: &comp::Stats,
|
||||
conn: Option<&SqliteConnection>,
|
||||
db_dir: &str,
|
||||
) {
|
||||
log::warn!("stats persisting...");
|
||||
|
||||
fn update(character_id: i32, stats: &comp::Stats, connection: &SqliteConnection) {
|
||||
if let Err(error) =
|
||||
diesel::update(schema::stats::table.filter(schema::stats::character_id.eq(character_id)))
|
||||
.set(&StatsUpdate::from(stats))
|
||||
.execute(conn.unwrap_or(&establish_connection(db_dir)))
|
||||
.execute(connection)
|
||||
{
|
||||
log::warn!(
|
||||
"Failed to update stats for character: {:?}: {:?}",
|
||||
@ -25,8 +18,12 @@ pub fn update(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn batch_update<'a>(updates: impl Iterator<Item = (i32, &'a comp::Stats)>, db_dir: &str) {
|
||||
let connection = &establish_connection(db_dir);
|
||||
|
||||
updates.for_each(|(character_id, stats)| update(character_id, stats, Some(connection), db_dir));
|
||||
pub fn update_item(character_id: i32, stats: &comp::Stats, db_dir: &str) {
|
||||
update(character_id, stats, &establish_connection(db_dir));
|
||||
}
|
||||
|
||||
pub fn batch_update<'a>(updates: impl Iterator<Item = (i32, &'a comp::Stats)>, db_dir: &str) {
|
||||
let connection = establish_connection(db_dir);
|
||||
|
||||
updates.for_each(|(character_id, stats)| update(character_id, stats, &connection));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user