Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: track category to apply per item (and not for the whole ship) #7

Merged
merged 1 commit into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/calculate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ pub struct Ship {
}

impl Ship {
pub fn new(hull_type_id: i32) -> Ship {
pub fn new(ship_type_id: i32) -> Ship {
Ship {
hull: Item::new(hull_type_id),
hull: Item::new_fake(ship_type_id),
items: Vec::new(),
skills: Vec::new(),
char: Item::new(0),
structure: Item::new(0),
char: Item::new_fake(0),
structure: Item::new_fake(0),
}
}
}
Expand All @@ -40,9 +40,9 @@ trait Pass {
fn pass(info: &Info, ship: &mut Ship);
}

pub fn calculate(ship_layout: &super::data_types::ShipLayout, skills: &BTreeMap<i32, i32>) -> Ship {
let info = Info::new(ship_layout, skills);
let mut ship = Ship::new(info.ship_layout.hull);
pub fn calculate(esi_fit: &super::data_types::EsiFit, skills: &BTreeMap<i32, i32>) -> Ship {
let info = Info::new(esi_fit, skills);
let mut ship = Ship::new(info.esi_fit.ship_type_id);

pass_1::PassOne::pass(&info, &mut ship);
pass_2::PassTwo::pass(&info, &mut ship);
Expand Down
12 changes: 3 additions & 9 deletions src/calculate/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,13 @@ extern "C" {
}

pub struct Info<'a> {
pub ship_layout: &'a data_types::ShipLayout,
pub esi_fit: &'a data_types::EsiFit,
pub skills: &'a BTreeMap<i32, i32>,
}

impl Info<'_> {
pub fn new<'a>(
ship_layout: &'a data_types::ShipLayout,
skills: &'a BTreeMap<i32, i32>,
) -> Info<'a> {
Info {
ship_layout,
skills,
}
pub fn new<'a>(esi_fit: &'a data_types::EsiFit, skills: &'a BTreeMap<i32, i32>) -> Info<'a> {
Info { esi_fit, skills }
}

pub fn get_dogma_attributes(&self, type_id: i32) -> Vec<data_types::TypeDogmaAttribute> {
Expand Down
20 changes: 16 additions & 4 deletions src/calculate/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ use serde::Serialize;
use std::collections::BTreeMap;
use strum_macros::EnumIter;

#[derive(Serialize, Debug, Copy, Clone, PartialEq, Eq)]
#[derive(Serialize, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum EffectCategory {
Passive,
Online,
Active,
Overload,
Target,
Area,
Online,
Overload,
Dungeon,
System,
}
Expand Down Expand Up @@ -55,6 +55,10 @@ pub struct Attribute {
#[derive(Serialize, Debug)]
pub struct Item {
pub type_id: i32,
pub quantity: i32,
pub flag: i32,
pub state: EffectCategory,
pub max_state: EffectCategory,
pub attributes: BTreeMap<i32, Attribute>,
pub effects: Vec<i32>,
}
Expand All @@ -70,11 +74,19 @@ impl Attribute {
}

impl Item {
pub fn new(type_id: i32) -> Item {
pub fn new_esi(type_id: i32, quantity: i32, flag: i32, state: EffectCategory) -> Item {
Item {
type_id,
quantity,
flag,
state,
max_state: EffectCategory::Passive,
attributes: BTreeMap::new(),
effects: Vec::new(),
}
}

pub fn new_fake(type_id: i32) -> Item {
return Self::new_esi(type_id, 1, -1, EffectCategory::Active);
}
}
18 changes: 13 additions & 5 deletions src/calculate/pass_1.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::item::{Attribute, Item};
use super::item::{Attribute, EffectCategory, Item};
use super::{Info, Pass, Ship};
use crate::data_types::EsiState;

const ATTRIBUTE_MASS_ID: i32 = 4;
const ATTRIBUTE_CAPACITY_ID: i32 = 38;
Expand All @@ -26,7 +27,7 @@ impl Pass for PassOne {
ship.hull.set_attributes(info);

/* Some attributes of ships come from the TypeID information. */
let type_id = info.get_type_id(info.ship_layout.hull);
let type_id = info.get_type_id(info.esi_fit.ship_type_id);
ship.hull
.set_attribute(ATTRIBUTE_MASS_ID, type_id.mass.unwrap());
ship.hull
Expand All @@ -37,16 +38,23 @@ impl Pass for PassOne {
.set_attribute(ATTRIBUTE_RADIUS_ID, type_id.radius.unwrap());

for (skill_id, skill_level) in info.skills {
let mut skill = Item::new(*skill_id);
let mut skill = Item::new_fake(*skill_id);

skill.set_attributes(info);
skill.set_attribute(ATTRIBUTE_SKILL_LEVEL_ID, *skill_level as f32);

ship.skills.push(skill);
}

for item_id in &info.ship_layout.items {
let mut item = Item::new(*item_id);
for esi_item in &info.esi_fit.items {
let state = match esi_item.state {
None => EffectCategory::Active,
Some(EsiState::Passive) => EffectCategory::Passive,
Some(EsiState::Online) => EffectCategory::Online,
Some(EsiState::Active) => EffectCategory::Active,
Some(EsiState::Overload) => EffectCategory::Overload,
};
let mut item = Item::new_esi(esi_item.type_id, esi_item.quantity, esi_item.flag, state);

item.set_attributes(info);

Expand Down
13 changes: 11 additions & 2 deletions src/calculate/pass_2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ impl Item {
fn collect_effects(&mut self, info: &Info, origin: Object, effects: &mut Vec<Pass2Effect>) {
for dogma_effect in info.get_dogma_effects(self.type_id) {
let type_dogma_effect = info.get_dogma_effect(dogma_effect.effectID);
let category = get_effect_category(type_dogma_effect.effectCategory);

/* Find the highest state an item can be in. */
if category > self.max_state {
self.max_state = category;
}

if !type_dogma_effect.modifierInfo.is_empty() {
for modifier in type_dogma_effect.modifierInfo {
Expand All @@ -133,7 +139,6 @@ impl Item {
let effect_modifier =
get_modifier_func(modifier.func, modifier.skillTypeID, modifier.groupID);
let target = get_target_object(modifier.domain, origin);
let category = get_effect_category(type_dogma_effect.effectCategory);
let operator = get_effect_operator(modifier.operation.unwrap());

effects.push(Pass2Effect {
Expand All @@ -150,6 +155,10 @@ impl Item {
self.effects.push(dogma_effect.effectID);
}
}

if self.state > self.max_state {
self.state = self.max_state;
}
}
}

Expand All @@ -169,7 +178,7 @@ impl Pass for PassTwo {
/* Depending on the modifier, move the effects to the correct attribute. */
for effect in effects {
let source_type_id = match effect.source {
Object::Ship => info.ship_layout.hull,
Object::Ship => info.esi_fit.ship_type_id,
Object::Item(index) => ship.items[index].type_id,
Object::Skill(index) => ship.skills[index].type_id,
_ => panic!("Unknown source object"),
Expand Down
39 changes: 9 additions & 30 deletions src/calculate/pass_3.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::collections::BTreeMap;
use strum::IntoEnumIterator;

use super::item::{Attribute, EffectCategory, EffectOperator, Item, Object};
use super::item::{Attribute, EffectOperator, Item, Object};
use super::{Info, Pass, Ship};

/* Penalty factor: 1 / math.exp((1 / 2.67) ** 2) */
Expand All @@ -28,7 +28,6 @@ impl Attribute {
&self,
info: &Info,
ship: &Ship,
categories: &Vec<EffectCategory>,
cache: &mut Cache,
item: Object,
attribute_id: i32,
Expand Down Expand Up @@ -56,9 +55,6 @@ impl Attribute {
if effect.operator != operator {
continue;
}
if !categories.contains(&effect.source_category) {
continue;
}

let source = match effect.source {
Object::Ship => &ship.hull,
Expand All @@ -67,11 +63,14 @@ impl Attribute {
_ => panic!("Unknown source object"),
};

if effect.source_category > source.state {
continue;
}

let source_value = match source.attributes.get(&effect.source_attribute_id) {
Some(attribute) => attribute.calculate_value(
info,
ship,
categories,
cache,
effect.source,
effect.source_attribute_id,
Expand Down Expand Up @@ -205,23 +204,9 @@ impl Attribute {
}

impl Item {
fn calculate_values(
&self,
info: &Info,
ship: &Ship,
categories: &Vec<EffectCategory>,
cache: &mut Cache,
item: Object,
) {
fn calculate_values(&self, info: &Info, ship: &Ship, cache: &mut Cache, item: Object) {
for attribute_id in self.attributes.keys() {
self.attributes[&attribute_id].calculate_value(
info,
ship,
&categories,
cache,
item,
*attribute_id,
);
self.attributes[&attribute_id].calculate_value(info, ship, cache, item, *attribute_id);
}
}

Expand All @@ -243,22 +228,16 @@ impl Item {

impl Pass for PassThree {
fn pass(info: &Info, ship: &mut Ship) {
let categories = vec![
EffectCategory::Passive,
EffectCategory::Active,
EffectCategory::Online,
];

let mut cache = Cache {
hull: BTreeMap::new(),
items: BTreeMap::new(),
skills: BTreeMap::new(),
};

ship.hull
.calculate_values(info, ship, &categories, &mut cache, Object::Ship);
.calculate_values(info, ship, &mut cache, Object::Ship);
for (index, item) in ship.items.iter().enumerate() {
item.calculate_values(info, ship, &categories, &mut cache, Object::Item(index));
item.calculate_values(info, ship, &mut cache, Object::Item(index));
}
/* No need to calculate skills; recursively they will resolve what is needed. */

Expand Down
6 changes: 3 additions & 3 deletions src/calculate/pass_4.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::item::Attribute;
use super::item::{Attribute, EffectCategory};
use super::{Info, Pass, Ship};

pub struct PassFour {}
Expand Down Expand Up @@ -49,7 +49,7 @@ fn add_cpu_usage(ship: &mut Ship) -> (f32, f32) {

let mut cpu_usage = 0.0;
for item in &ship.items {
if item.attributes.contains_key(&50) {
if item.attributes.contains_key(&50) && item.state != EffectCategory::Passive {
cpu_usage += item.attributes.get(&50).unwrap().value.unwrap();
}
}
Expand All @@ -62,7 +62,7 @@ fn add_pg_usage(ship: &mut Ship) -> (f32, f32) {

let mut pg_usage = 0.0;
for item in &ship.items {
if item.attributes.contains_key(&30) {
if item.attributes.contains_key(&30) && item.state != EffectCategory::Passive {
pg_usage += item.attributes.get(&30).unwrap().value.unwrap();
}
}
Expand Down
24 changes: 21 additions & 3 deletions src/data_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,25 @@ pub struct DogmaEffect {

#[allow(non_snake_case)]
#[derive(Deserialize, Debug)]
pub struct ShipLayout {
pub hull: i32,
pub items: Vec<i32>,
pub enum EsiState {
Passive,
Online,
Active,
Overload,
}

#[allow(non_snake_case)]
#[derive(Deserialize, Debug)]
pub struct EsiItem {
pub type_id: i32,
pub quantity: i32,
pub flag: i32,
pub state: Option<EsiState>,
}

#[allow(non_snake_case)]
#[derive(Deserialize, Debug)]
pub struct EsiFit {
pub ship_type_id: i32,
pub items: Vec<EsiItem>,
}
5 changes: 2 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@ pub fn init() {

#[wasm_bindgen]
pub fn calculate(js_ship_layout: JsValue, js_skills: JsValue) -> JsValue {
let ship_layout: data_types::ShipLayout =
serde_wasm_bindgen::from_value(js_ship_layout).unwrap();
let esi_fit: data_types::EsiFit = serde_wasm_bindgen::from_value(js_ship_layout).unwrap();
let skills: BTreeMap<String, i32> = serde_wasm_bindgen::from_value(js_skills).unwrap();
let skills = skills
.into_iter()
.map(|(k, v)| (k.parse::<i32>().unwrap(), v))
.collect();

let statistics = calculate::calculate(&ship_layout, &skills);
let statistics = calculate::calculate(&esi_fit, &skills);
serde_wasm_bindgen::to_value(&statistics).unwrap()
}