mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added function to automatically generate a combat rating. Currently, it is used to calculate exp.
This commit is contained in:
parent
933a413879
commit
d904e20ffa
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -5995,6 +5995,7 @@ dependencies = [
|
|||||||
"hashbrown 0.9.1",
|
"hashbrown 0.9.1",
|
||||||
"image",
|
"image",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
|
"inline_tweak",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"num-derive",
|
"num-derive",
|
||||||
"num-traits 0.2.14",
|
"num-traits 0.2.14",
|
||||||
@ -6099,6 +6100,7 @@ dependencies = [
|
|||||||
"futures-timer 3.0.2",
|
"futures-timer 3.0.2",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"hashbrown 0.9.1",
|
"hashbrown 0.9.1",
|
||||||
|
"inline_tweak",
|
||||||
"itertools",
|
"itertools",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libsqlite3-sys",
|
"libsqlite3-sys",
|
||||||
|
@ -28,6 +28,7 @@ spin_sleep = "1.0"
|
|||||||
tracing = { version = "0.1", default-features = false }
|
tracing = { version = "0.1", default-features = false }
|
||||||
vek = { version = "0.12.0", features = ["serde"] }
|
vek = { version = "0.12.0", features = ["serde"] }
|
||||||
uuid = { version = "0.8.1", default-features = false, features = ["serde", "v4"] }
|
uuid = { version = "0.8.1", default-features = false, features = ["serde", "v4"] }
|
||||||
|
inline_tweak = "1.0.2"
|
||||||
|
|
||||||
# Assets
|
# Assets
|
||||||
assets_manager = {version = "0.4.2", features = ["bincode", "ron", "json", "hot-reloading"]}
|
assets_manager = {version = "0.4.2", features = ["bincode", "ron", "json", "hot-reloading"]}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{
|
comp::{
|
||||||
inventory::{item::{armor::Protection, tool::ToolKind, ItemKind}, slot::EquipSlot},
|
inventory::{item::{armor::Protection, tool::ToolKind, ItemKind}, slot::EquipSlot},
|
||||||
BuffKind, HealthChange, HealthSource, Inventory,
|
Body, BuffKind, Health, HealthChange, HealthSource, Inventory,
|
||||||
},
|
},
|
||||||
uid::Uid,
|
uid::Uid,
|
||||||
util::Dir,
|
util::Dir,
|
||||||
};
|
};
|
||||||
|
use inline_tweak::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
@ -224,4 +225,37 @@ pub fn get_weapons(inv: &Inventory) -> (Option<ToolKind>, Option<ToolKind>) {
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn get_weapon_damage(inv: &Inventory) -> f32 {
|
||||||
|
let active_power = inv.equipped(EquipSlot::Mainhand).map_or(0.0, |i| {
|
||||||
|
if let ItemKind::Tool(tool) = &i.kind() {
|
||||||
|
tool.base_power() * tool.base_speed()
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let second_power = inv.equipped(EquipSlot::Offhand).map_or(0.0, |i| {
|
||||||
|
if let ItemKind::Tool(tool) = &i.kind() {
|
||||||
|
tool.base_power() * tool.base_speed()
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
active_power.max(second_power).max(0.1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn combat_rating(inventory: &Inventory, health: &Health, body: &Body) -> f32 {
|
||||||
|
let defensive_weighting = tweak!(1.0);
|
||||||
|
let offensive_weighting = tweak!(1.0);
|
||||||
|
let defensive_rating = health.maximum() as f32 / (1.0 - Damage::compute_damage_reduction(inventory)) / 100.0;
|
||||||
|
let offensive_rating = get_weapon_damage(inventory);
|
||||||
|
//let combined_rating = 2.0 / ((1.0 / offensive_rating) + (1.0 /
|
||||||
|
// defensive_rating)); let combined_rating = offensive_rating *
|
||||||
|
// defensive_rating / (offensive_rating + defensive_rating);
|
||||||
|
let combined_rating = (offensive_rating * offensive_weighting
|
||||||
|
+ defensive_rating * defensive_weighting)
|
||||||
|
/ (2.0 * offensive_weighting.max(defensive_weighting));
|
||||||
|
combined_rating * body.combat_multiplier()
|
||||||
|
}
|
||||||
|
@ -425,6 +425,11 @@ impl Body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a multiplier representing increased difficulty not accounted for
|
||||||
|
/// due to AI or not using an actual weapon
|
||||||
|
// TODO: Match on species
|
||||||
|
pub fn combat_multiplier(&self) -> f32 { 1.0 }
|
||||||
|
|
||||||
#[allow(unreachable_patterns)]
|
#[allow(unreachable_patterns)]
|
||||||
pub fn base_exp(&self) -> u32 {
|
pub fn base_exp(&self) -> u32 {
|
||||||
match self {
|
match self {
|
||||||
|
@ -49,6 +49,7 @@ diesel_migrations = "1.4.0"
|
|||||||
dotenv = "0.15.0"
|
dotenv = "0.15.0"
|
||||||
slab = "0.4"
|
slab = "0.4"
|
||||||
const-tweaker = {version = "0.3.1", optional = true}
|
const-tweaker = {version = "0.3.1", optional = true}
|
||||||
|
inline_tweak = "1.0.2"
|
||||||
|
|
||||||
# Plugins
|
# Plugins
|
||||||
plugin-api = { package = "veloren-plugin-api", path = "../plugin/api"}
|
plugin-api = { package = "veloren-plugin-api", path = "../plugin/api"}
|
||||||
|
@ -29,6 +29,7 @@ use common_net::{msg::ServerGeneral, sync::WorldSyncExt};
|
|||||||
use common_sys::state::BlockChange;
|
use common_sys::state::BlockChange;
|
||||||
use comp::item::Reagent;
|
use comp::item::Reagent;
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
|
use inline_tweak::*;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use specs::{join::Join, saveload::MarkerAllocator, Entity as EcsEntity, WorldExt};
|
use specs::{join::Join, saveload::MarkerAllocator, Entity as EcsEntity, WorldExt};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
@ -162,6 +163,7 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
|||||||
(|| {
|
(|| {
|
||||||
let mut stats = state.ecs().write_storage::<Stats>();
|
let mut stats = state.ecs().write_storage::<Stats>();
|
||||||
let healths = state.ecs().read_storage::<Health>();
|
let healths = state.ecs().read_storage::<Health>();
|
||||||
|
let inventories = state.ecs().read_storage::<Inventory>();
|
||||||
let by = if let HealthSource::Damage { by: Some(by), .. } = cause {
|
let by = if let HealthSource::Damage { by: Some(by), .. } = cause {
|
||||||
by
|
by
|
||||||
} else {
|
} else {
|
||||||
@ -172,13 +174,14 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
|||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let (entity_stats, entity_health) = if let (Some(entity_stats), Some(entity_health)) =
|
let (entity_stats, entity_health, entity_inventory) =
|
||||||
(stats.get(entity), healths.get(entity))
|
if let (Some(entity_stats), Some(entity_health), Some(entity_inventory)) =
|
||||||
{
|
(stats.get(entity), healths.get(entity), inventories.get(entity))
|
||||||
(entity_stats, entity_health)
|
{
|
||||||
} else {
|
(entity_stats, entity_health, entity_inventory)
|
||||||
return;
|
} else {
|
||||||
};
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
let groups = state.ecs().read_storage::<Group>();
|
let groups = state.ecs().read_storage::<Group>();
|
||||||
let attacker_group = groups.get(attacker);
|
let attacker_group = groups.get(attacker);
|
||||||
@ -194,8 +197,12 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
|||||||
const ATTACKER_EXP_WEIGHT: f32 = 1.0;
|
const ATTACKER_EXP_WEIGHT: f32 = 1.0;
|
||||||
// TODO: Scale xp from skillset rather than health, when NPCs have their own
|
// TODO: Scale xp from skillset rather than health, when NPCs have their own
|
||||||
// skillsets
|
// skillsets
|
||||||
let mut exp_reward = entity_stats.body_type.base_exp() as f32
|
/*let mut exp_reward = entity_stats.body_type.base_exp() as f32
|
||||||
* (entity_health.maximum() as f32 / entity_stats.body_type.base_health() as f32);
|
* (entity_health.maximum() as f32 / entity_stats.body_type.base_health() as
|
||||||
|
* f32); */
|
||||||
|
let mut exp_reward =
|
||||||
|
combat::combat_rating(entity_inventory, entity_health, &entity_stats.body_type)
|
||||||
|
* tweak!(2.5);
|
||||||
|
|
||||||
// Distribute EXP to group
|
// Distribute EXP to group
|
||||||
let positions = state.ecs().read_storage::<Pos>();
|
let positions = state.ecs().read_storage::<Pos>();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user