rpg_stat/
stats.rs

1/*!
2# Stats
3
4This module offers a few options.
5
6### FLTK
7
8The use of `fltk-form` allows easy integration into a GUI toolkit via the FLTK specific `Stats`
9
10### Premade traits to add to your own struct
11
12```
13use rpg_stat::stats::Basic as Stats;
14use rpg_stat::stats::BasicPremade as Premade;
15
16struct MyStruct {
17    stats:Stats<f64>,
18    // whatever else you need
19}
20// now you can get the stats `hp` via `my_struct.hp()`, etc..
21impl Premade<f64> for MyStruct {
22    fn stat(&self) -> Stats<f64> {
23        self.stats
24    }
25    fn set_hp(&mut self, amount:f64) {
26        self.stats.hp = amount;
27    }
28    fn set_mp(&mut self, amount:f64) {
29        self.stats.mp = amount;
30    }
31    fn set_xp(&mut self, amount:f64) {
32        self.stats.xp = amount;
33    }
34    fn set_hp_max(&mut self, amount:f64) {
35        self.stats.hp_max = amount;
36    }
37    fn set_mp_max(&mut self, amount:f64) {
38        self.stats.mp_max = amount;
39    }
40    fn set_xp_next(&mut self, amount:f64) {
41        self.stats.xp_next = amount;
42    }
43    fn set_gp(&mut self, amount:f64) {
44        self.stats.gp = amount;
45    }
46    
47}
48```
49
50And for FLTK premade f64:
51
52```
53use rpg_stat::stats::Stats;
54use rpg_stat::stats::Premade;
55
56struct MyStruct {
57    stats:Stats,
58    // whatever else you need
59}
60// now you can get the stats `hp` via `my_struct.hp()`, etc..
61impl Premade for MyStruct {
62    fn stat(&self) -> Stats {
63        self.stats
64    }
65    fn set_hp(&mut self, amount:f64) {
66        self.stats.hp = amount;
67    }
68    fn set_mp(&mut self, amount:f64) {
69        self.stats.mp = amount;
70    }
71    fn set_xp(&mut self, amount:f64) {
72        self.stats.xp = amount;
73    }
74    fn set_hp_max(&mut self, amount:f64) {
75        self.stats.hp_max = amount;
76    }
77    fn set_mp_max(&mut self, amount:f64) {
78        self.stats.mp_max = amount;
79    }
80    fn set_xp_next(&mut self, amount:f64) {
81        self.stats.xp_next = amount;
82    }
83    fn set_gp(&mut self, amount:f64) {
84        self.stats.gp = amount;
85    }
86    fn set_atk(&mut self, amount:f64) {
87        self.stats.atk = amount;
88    }
89    fn set_def(&mut self, amount:f64) {
90        self.stats.def = amount;
91    }
92    fn set_m_atk(&mut self, amount:f64) {
93        self.stats.m_atk = amount;
94    }
95    fn set_m_def(&mut self, amount:f64) {
96        self.stats.m_def = amount;
97    }
98    fn set_level(&mut self, amount:f64) {
99        self.stats.level = amount;
100    }
101    fn set_speed(&mut self, amount:f64) {
102        self.stats.speed = amount;
103    }
104}
105
106```
107
108# Structure
109This contains the basic structures for the RPG statistics library
110
111## `Basic` contains only the most needed for a generic game
112
113### id
114this can be used in any way to ID the stats
115
116### xp
117The experience points the stats currently hold
118
119### xp_next
120the amount needed to reach the next level
121
122### level
123the level of proficiency of the stats
124
125### gp
126the currency the stats currently have
127
128### hp
129the current health in the stats
130
131### mp
132the current mana in the stats
133
134### hp_max
135the total health possible
136
137### mp_max
138the total mana possible
139
140### speed
141the speed the stats move at
142
143## `Normal` includes a few more for the generic RPG battle system as well as everything in `Basic`
144
145### atk
146used specifically in battle as the attack variable
147
148### def
149used specifically in battle as the defense variable
150
151### m_atk
152used specifically in battle as the mana attack variable
153
154### m_def
155used specifically in battle as the mana defense variable
156
157## `Advanced` contains the finer details seen in tabletop RPG stats as well as everything in `Normal` and `Basic`
158
159### agility
160
161Fight mechanics:
162 * Increases dodge
163 * Increases accuracy
164
165Story mechanics:
166 * Increases success rate
167 * Increases options
168 * Decreases confrontation rate
169
170### strength
171
172Fight mechanics:
173 * Increases attack
174 * Increases defense
175
176Story mechanics:
177 * Increases confrontations
178 * Increases special item finds
179 * Increases success rate
180
181### dexterity
182
183Fight mechanics:
184 * Increases accuracy
185
186Story mechanics:
187 * Increases options
188 * Decreases confrontation rate
189
190### constitution
191
192Fight mechanics:
193 * Increases dodge
194 * Increases defense
195
196Story mechanics:
197 * Increases success rate
198 * Decreases confrontation rate
199
200### intelligence
201
202Fight mechanics:
203 * Increases accuracy
204
205Story mechanics:
206 * Increases confrontations
207 * Increases special item finds
208 * Increases success rate
209
210### charisma
211
212Fight mechanics:
213 * Increases dodge
214
215Story mechanics:
216 * Increases options
217 * Increases reward
218 * Decreases confrontation rate
219
220### wisdom
221
222Fight mechanics:
223 * Increases leveling
224
225Story mechanics:
226 * Increases reward
227 * Decreases confrontation rate
228
229### age
230
231Age is really to allow things to grow through a Stage
232
233Fight mechanics:
234 * Items, Weapons, Armor, etc may be formulated for specific age ranges and prevent users who are too young or old to use them.
235
236Story mechanics:
237 * Age could potentially influence story mechanics, being to young to leave an area would promote grinding.
238
239 */
240use std::default::Default;
241use serde::{Deserialize, Serialize};
242extern crate num;
243
244use std::ops::{Add, AddAssign,  Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign};
245use std::fmt::Debug;
246
247#[cfg(feature = "fltkform")]
248use fltk::{prelude::*, *};
249#[cfg(feature = "fltkform")]
250use fltk_form_derive::*;
251#[cfg(feature = "fltkform")]
252use fltk_form::FltkForm;
253
254
255use crate::random::*;
256use crate::equation::Math;
257
258pub trait Functions <T:Copy
259    + Default
260    + Debug
261    + AddAssign
262    + Add<Output = T>
263    + Div<Output = T>
264    + DivAssign
265    + Mul<Output = T>
266    + MulAssign
267    + Neg<Output = T>
268    + Rem<Output = T>
269    + RemAssign
270    + Sub<Output = T>
271    + SubAssign
272    + std::cmp::PartialOrd
273    + num::NumCast> {
274    type Statistics;
275    fn damage(&self);
276}
277/*
278# Builder
279
280The builder trait is how I create `rpg_stat::stats::{Basic,Normal,Advance}` from enums
281
282*/
283pub trait Builder <T:Copy
284    + Default
285    + Debug
286    + AddAssign
287    + Add<Output = T>
288    + Div<Output = T>
289    + DivAssign
290    + Mul<Output = T>
291    + MulAssign
292    + Neg<Output = T>
293    + Rem<Output = T>
294    + RemAssign
295    + Sub<Output = T>
296    + SubAssign
297    + std::cmp::PartialOrd
298    + num::NumCast> {
299    /// Build a `Basic` stat
300    fn build_basic(&self, id:T, level:T) -> Basic<T>;
301    // Build a `Normal` stat
302    fn build_normal(&self, id:T, level:T) -> Normal<T>;
303    // Build an `Advanced` stat
304    fn build_advanced(&self, id:T, level:T) -> Advanced<T>;
305}
306
307/*
308Premade trait for Basic Stat
309You simply define the function `stat()` to return the `Basic<T>` associated with your code.
310*/
311pub trait BasicPremade<T:Copy
312    + Default
313    + Debug
314    + AddAssign
315    + Add<Output = T>
316    + Div<Output = T>
317    + DivAssign
318    + Mul<Output = T>
319    + MulAssign
320    + Neg<Output = T>
321    + Rem<Output = T>
322    + RemAssign
323    + Sub<Output = T>
324    + SubAssign
325    + std::cmp::PartialOrd
326    + num::NumCast> {
327    /// # Function you need to imlement
328    /// stat returns the `Basic<T>` you created
329    fn stat(&self) -> Basic<T>;
330    /// # Function you need to imlement
331    /// Set the `Basic<T>` Health Points
332    fn set_hp(&mut self, amount:T);
333    /// # Function you need to imlement
334    /// Set the `Basic<T>` Mana Points
335    fn set_mp(&mut self, amount:T);
336    /// # Function you need to imlement
337    /// Set the `Basic<T>` Experience Points
338    fn set_xp(&mut self, amount:T);
339    /// # Function you need to imlement
340    /// Set the `Basic<T>` Max Health Points
341    fn set_hp_max(&mut self, amount:T);
342    /// # Function you need to imlement
343    /// Set the `Basic<T>` Max Mana Points
344    fn set_mp_max(&mut self, amount:T);
345    /// # Function you need to imlement
346    /// Set the `Basic<T>` Next Experience Points
347    fn set_xp_next(&mut self, amount:T);
348    /// # Function you need to imlement
349    /// Set the `Basic<T>` Gold Points
350    fn set_gp(&mut self, amount:T);
351    /// Return  the `Basic<T>` id number
352
353// PREMADE FUNCTIONS   
354    fn id(&self) -> T {
355        self.stat().id
356    }
357    /// Return  the `Basic<T>` Health Points
358    fn hp(&self) -> T {
359        self.stat().hp
360    }
361    /// Return  the `Basic<T>` Mana Points
362    fn mp(&self) -> T {
363        self.stat().mp
364    }
365    /// Return  the `Basic<T>` Experience Points
366    fn xp(&self) -> T {
367        self.stat().xp
368    }
369    /// Return  the `Basic<T>` Max Health Points
370    fn hp_max(&self) -> T {
371        self.stat().hp_max
372    }
373    /// Return  the `Basic<T>` Max Mana Points
374    fn mp_max(&self) -> T {
375        self.stat().mp_max
376    }
377    /// Return  the `Basic<T>` Next Experience Points
378    fn xp_next(&self) -> T {
379        self.stat().xp_next
380    }
381    /// Return  the `Basic<T>` Level
382    fn level(&self) -> T {
383        self.stat().level
384    }
385    /// Return  the `Basic<T>` Speed
386    fn speed(&self) -> T {
387        self.stat().level
388    }
389    /// Return  the `Basic<T>` Gold Points
390    fn gp(&self) -> T {
391        self.stat().gp
392    }
393    /// Damage the character by an amount
394    fn damage(&mut self, amount:T) {
395        let mut val = self.hp();
396        val -= amount;
397        let none = num::cast(0).unwrap();
398        if val < none {
399            val = none;
400        }
401        self.set_hp(val)
402    }
403    /// Add health to character but not beyond their Max Healh Points
404    fn heal(&mut self, amount:T) {
405        let mut val = self.hp();
406        val += amount;
407        let max = self.hp_max();
408        if val > max {
409            val = max;
410        }
411        self.set_hp(val)
412    }
413}
414
415/*
416# The Basic HP/MP/XP stat model
417
418This basic model of stats is easy to work with for beginners, but powerful enough to be used by the most experienced.
419*/
420
421#[derive( Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
422pub struct Basic<T:Copy
423    + Default
424    + Debug
425    + AddAssign
426    + Add<Output = T>
427    + Div<Output = T>
428    + DivAssign
429    + Mul<Output = T>
430    + MulAssign
431    + Neg<Output = T>
432    + Rem<Output = T>
433    + RemAssign
434    + Sub<Output = T>
435    + SubAssign
436    + std::cmp::PartialOrd
437    + num::NumCast> {
438    /// Identification Number
439    pub id:T,
440    /// Experience Points
441    pub xp:T,
442    /// Health Points
443    pub hp:T,
444    /// Mana Points
445    pub mp:T,
446    /// Experience Points multiplier for next level
447    pub xp_next:T,
448    /// Max Health Points
449    pub hp_max:T,
450    /// Max Mana Points
451    pub mp_max:T,
452    /// Current Level
453    pub level:T,
454    /// The speed
455    pub speed:T,
456    /// your currency points
457    pub gp:T,
458}
459impl<T:Copy
460    + Default
461    + Debug
462    + AddAssign
463    + Add<Output = T>
464    + Div<Output = T>
465    + DivAssign
466    + Mul<Output = T>
467    + MulAssign
468    + Neg<Output = T>
469    + Rem<Output = T>
470    + RemAssign
471    + Sub<Output = T>
472    + SubAssign
473    + std::cmp::PartialOrd
474    + num::NumCast> Basic<T> {
475
476    /// make empty stats
477    pub fn empty() -> Self where Self:Sized {
478        Basic {
479            id:Default::default(),
480            xp:Default::default(),
481            xp_next:Default::default(),
482            mp:Default::default(),
483            hp:Default::default(),
484            mp_max:Default::default(),
485            hp_max:Default::default(),
486            level:Default::default(),
487            speed:Default::default(),
488            gp:Default::default(),
489        }
490    }
491    /// People like new
492    #[allow(unused)]
493    pub fn new() -> Self {
494        Self::empty()
495    }
496    #[allow(unused)]
497    /// Get the next amount of XP needed to level up
498    pub fn next(&self) -> T {
499        self.level * self.xp_next
500    }
501    #[allow(unused)]
502    /// a vector of stats used to get the standard deviation
503    pub fn stats_vec(&self) -> Vec<T>{
504        vec![
505            self.hp_max,
506            self.mp_max,
507            self.speed,
508        ]
509    }
510
511    #[allow(unused)]
512    /// This function levels up our stats
513    pub fn level_up(&mut self) -> bool {
514        if self.xp > self.next() {
515            let stats_vec:Vec<T> = self.stats_vec();
516            let mut num:T = Math::population_standard_deviation(stats_vec);
517            let one:T = num::cast::<u32, T>(1).unwrap();
518            if num < one {
519                num = one;
520            }
521            num *= self.level;
522            self.level += num;
523            self.mp_max += num;
524            self.hp_max += num;
525            self.speed += num;
526            return true;
527        }
528        false
529    }
530}
531impl<T:Copy
532    + Default
533    + Debug
534    + AddAssign
535    + Add<Output = T>
536    + Div<Output = T>
537    + DivAssign
538    + Mul<Output = T>
539    + MulAssign
540    + Neg<Output = T>
541    + Rem<Output = T>
542    + RemAssign
543    + Sub<Output = T>
544    + SubAssign
545    + std::cmp::PartialOrd
546    + num::NumCast> Default for Basic<T> {
547    /// Default to empty
548    fn default() -> Self where Self:Sized {
549        Self::empty()
550    }
551}
552
553/*
554Premade trait for Normal Stat
555You simply define the function `stat()` to return the `Normal<T>` associated with your code.
556*/
557pub trait NormalPremade<T:Copy
558    + Default
559    + Debug
560    + AddAssign
561    + Add<Output = T>
562    + Div<Output = T>
563    + DivAssign
564    + Mul<Output = T>
565    + MulAssign
566    + Neg<Output = T>
567    + Rem<Output = T>
568    + RemAssign
569    + Sub<Output = T>
570    + SubAssign
571    + std::cmp::PartialOrd
572    + num::NumCast> {
573    /// # Function you need to imlement
574    /// stat returns the `Normal<T>` you created
575    fn stat(&self) -> Normal<T>;
576    /// # Function you need to imlement
577    /// Set the `Normal<T>` Health Points
578    fn set_hp(&mut self, amount:T);
579    /// # Function you need to imlement
580    /// Set the `Normal<T>` Mana Points
581    fn set_mp(&mut self, amount:T);
582    /// # Function you need to imlement
583    /// Set the `Normal<T>` Experience Points
584    fn set_xp(&mut self, amount:T);
585    /// # Function you need to imlement
586    /// Set the `Normal<T>` Max Health Points
587    fn set_hp_max(&mut self, amount:T);
588    /// # Function you need to imlement
589    /// Set the `Normal<T>` Max Mana Points
590    fn set_mp_max(&mut self, amount:T);
591    /// # Function you need to imlement
592    /// Set the `Normal<T>` Next Experience Points
593    fn set_xp_next(&mut self, amount:T);
594    /// # Function you need to imlement
595    /// Set the `Normal<T>` Gold Points
596    fn set_gp(&mut self, amount:T);
597    /// # Function you need to imlement
598    /// Set the `Normal<T>` Attack Points
599    fn set_atk(&mut self, amount:T);
600    /// # Function you need to imlement
601    /// Set the `Normal<T>` Defense Points
602    fn set_def(&mut self, amount:T);
603    /// # Function you need to imlement
604    /// Set the `Normal<T>` Mana Attack Points
605    fn set_m_atk(&mut self, amount:T);
606    /// # Function you need to imlement
607    /// Set the `Normal<T>` Mana Defense Points
608    fn set_m_def(&mut self, amount:T);
609
610// PREMADE FUNCTIONS   
611    /// Return  the `Normal<T>` id number
612    fn id(&self) -> T {
613        self.stat().id
614    }
615    /// Return  the `Normal<T>` Health Points
616    fn hp(&self) -> T {
617        self.stat().hp
618    }
619    /// Return  the `Normal<T>` Mana Points
620    fn mp(&self) -> T {
621        self.stat().mp
622    }
623    /// Return  the `Normal<T>` Experience Points
624    fn xp(&self) -> T {
625        self.stat().xp
626    }
627    /// Return  the `Normal<T>` Max Health Points
628    fn hp_max(&self) -> T {
629        self.stat().hp_max
630    }
631    /// Return  the `Normal<T>` Max Mana Points
632    fn mp_max(&self) -> T {
633        self.stat().mp_max
634    }
635    /// Return  the `Normal<T>` Next Experience Points
636    fn xp_next(&self) -> T {
637        self.stat().xp_next
638    }
639    /// Return  the `Normal<T>` Level
640    fn level(&self) -> T {
641        self.stat().level
642    }
643    /// Return  the `Normal<T>` Speed
644    fn speed(&self) -> T {
645        self.stat().level
646    }
647    /// Return  the `Normal<T>` Gold Points
648    fn gp(&self) -> T {
649        self.stat().gp
650    }
651    /// Return  the `Normal<T>` Attack Points
652    fn atk(&self) -> T {
653        self.stat().atk
654    }
655    /// Return  the `Normal<T>` Defense Points
656    fn def(&self) -> T {
657        self.stat().def
658    }
659    /// Return  the `Normal<T>` Mana Attack Points
660    fn m_atk(&self) -> T {
661        self.stat().m_atk
662    }
663    /// Return  the `Normal<T>` Mana Defense Points
664    fn m_def(&self) -> T {
665        self.stat().m_def
666    }
667
668    /// Damage the character by an amount
669    fn damage(&mut self, amount:T) {
670        let mut val = self.hp();
671        val -= amount;
672        let none = num::cast(0).unwrap();
673        if val < none {
674            val = none;
675        }
676        self.set_hp(val)
677    }
678    /// Add health to character but not beyond their Max Healh Points
679    fn heal(&mut self, amount:T) {
680        let mut val = self.hp();
681        val += amount;
682        let max = self.hp_max();
683        if val > max {
684            val = max;
685        }
686        self.set_hp(val)
687    }
688    /// Stable attack forumla
689    /// [attack*(100/(100+defense))](https://rpg.fandom.com/wiki/Damage_Formula)
690    fn attack_stable(&self, other:Normal<T>) -> T { 
691        let hundred = num::cast(100).unwrap();
692        let val = self.atk();
693        let def = other.def + hundred;
694        let res = hundred / def;
695        val * res
696    }
697    /// Scalable attack forumla
698    /// [damage = att * att / (att + def)](https://gamedev.stackexchange.com/questions/129319/rpg-formula-attack-and-defense)
699    fn attack(&self, other:Normal<T>) -> T {
700        let val = self.atk();
701        let mut res = val * val;
702        let def = other.def + val;
703        res /= def;
704        res
705    }
706}
707/*
708# The Normal
709
710This model provides fine tuning of attack and defense without needing all the fine tuning of a full stat sheet
711*/
712#[derive( Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
713pub struct Normal<T:Copy 
714                 + Default
715                 + AddAssign
716                 + Add<Output = T>
717                 + Div<Output = T>
718                 + DivAssign
719                 + Mul<Output = T>
720                 + MulAssign
721                 + Neg<Output = T>
722                 + Rem<Output = T>
723                 + RemAssign
724                 + Sub<Output = T>
725                 + SubAssign
726                 + std::cmp::PartialOrd
727                 + num::NumCast> {
728    /// Identification Number
729    pub id:T,
730    // Name
731    //pub name:str,
732    /// Experience Points
733    pub xp:T,
734    /// Health Points
735    pub hp:T,
736    /// Mana Points
737    pub mp:T,
738    /// Experience Points multiplier for next level
739    pub xp_next:T,
740    /// Max Health Points
741    pub hp_max:T,
742    /// Max Mana Points
743    pub mp_max:T,
744    /// Current Level
745    pub level:T,
746    /// The speed
747    pub speed:T,
748    /// your currency points
749    pub gp:T,
750    /// Attack
751    pub atk:T,
752    /// Defense
753    pub def:T,
754    /// Mana Attack
755    pub m_atk:T,
756    /// Mana Defense
757    pub m_def:T,
758
759}
760impl<T:Copy 
761    + Default
762    + AddAssign
763    + Add<Output = T>
764    + Div<Output = T>
765    + DivAssign
766    + Mul<Output = T>
767    + MulAssign
768    + Neg<Output = T>
769    + Rem<Output = T>
770    + RemAssign
771    + Sub<Output = T>
772    + SubAssign
773    + std::cmp::PartialOrd
774    + num::NumCast> Normal<T> {
775    
776    /// make empty stats
777    pub fn empty<U:Default>() -> Self {
778        Normal {
779            //name: "Ferris",
780            id:Default::default(),
781            xp:Default::default(),
782            xp_next:Default::default(),
783            mp:Default::default(),
784            hp:Default::default(),
785            mp_max:Default::default(),
786            hp_max:Default::default(),
787            level:Default::default(),
788            speed:Default::default(),
789            gp:Default::default(),
790            atk:Default::default(),
791            def:Default::default(),
792            m_atk:Default::default(),
793            m_def:Default::default(),
794        }
795    }/// People like new
796    #[allow(unused)]
797    pub fn new() -> Self {
798        Self::empty::<T>()
799    }
800    #[allow(unused)]
801    /// Get the next amount of XP needed to level up
802    pub fn next(&self) -> T {
803        self.level * self.xp_next
804    }
805    #[allow(unused)]
806    /// a vector of stats used to get the standard deviation
807    pub fn stats_vec(&self) -> Vec<T>{
808        vec![
809            self.hp_max,
810            self.mp_max,
811            self.speed,
812            self.atk,
813            self.def,
814            self.m_atk,
815            self.m_def,
816        ]
817    }
818
819    #[allow(unused)]
820    /// This function levels up our stats
821    pub fn level_up(&mut self) -> bool {
822        if self.xp > self.next() {
823            let stats_vec:Vec<T> = self.stats_vec();
824            let mut num:T = Math::population_standard_deviation(stats_vec);
825            let one:T = num::cast::<u32, T>(1).unwrap();
826            if num < one {
827                num = one;
828            }
829            num *= self.level;
830            self.level += num;
831            self.mp_max += num;
832            self.hp_max += num;
833            self.speed += num;
834            self.atk += num;
835            self.def += num;
836            self.m_atk += num;
837            self.m_def += num;
838            return true;
839        }
840        false
841    }
842}
843
844impl<T:Copy 
845    + Default
846    + AddAssign
847    + Add<Output = T>
848    + Div<Output = T>
849    + DivAssign
850    + Mul<Output = T>
851    + MulAssign
852    + Neg<Output = T>
853    + Rem<Output = T>
854    + RemAssign
855    + Sub<Output = T>
856    + SubAssign
857    + std::cmp::PartialOrd
858    + num::NumCast> Default for Normal<T> {
859    /// Default to empty
860    fn default() -> Self {
861        Self::empty::<T>()
862    }
863}
864
865/*
866Premade trait for Advanced Stat
867You simply define the function `stat()` to return the `Advanced<T>` associated with your code.
868*/
869pub trait AdvancedPremade<T:Copy
870    + Default
871    + Debug
872    + AddAssign
873    + Add<Output = T>
874    + Div<Output = T>
875    + DivAssign
876    + Mul<Output = T>
877    + MulAssign
878    + Neg<Output = T>
879    + Rem<Output = T>
880    + RemAssign
881    + Sub<Output = T>
882    + SubAssign
883    + std::cmp::PartialOrd
884    + num::NumCast> {
885    /// # Function you need to imlement
886    /// stat returns the `Advanced<T>` you created
887    fn stat(&self) -> Advanced<T>;
888    /// # Function you need to imlement
889    /// Set the `Advanced<T>` Health Points
890    fn set_hp(&mut self, amount:T);
891    /// # Function you need to imlement
892    /// Set the `Advanced<T>` Mana Points
893    fn set_mp(&mut self, amount:T);
894    /// # Function you need to imlement
895    /// Set the `Advanced<T>` Experience Points
896    fn set_xp(&mut self, amount:T);
897    /// # Function you need to imlement
898    /// Set the `Advanced<T>` Max Health Points
899    fn set_hp_max(&mut self, amount:T);
900    /// # Function you need to imlement
901    /// Set the `Advanced<T>` Max Mana Points
902    fn set_mp_max(&mut self, amount:T);
903    /// # Function you need to imlement
904    /// Set the `Advanced<T>` Next Experience Points
905    fn set_xp_next(&mut self, amount:T);
906    /// # Function you need to imlement
907    /// Set the `Advanced<T>` Gold Points
908    fn set_gp(&mut self, amount:T);
909    /// # Function you need to imlement
910    /// Set the `Advanced<T>` Attack Points
911    fn set_atk(&mut self, amount:T);
912    /// # Function you need to imlement
913    /// Set the `Advanced<T>` Defense Points
914    fn set_def(&mut self, amount:T);
915    /// # Function you need to imlement
916    /// Set the `Advanced<T>` Mana Attack Points
917    fn set_m_atk(&mut self, amount:T);
918    /// # Function you need to imlement
919    /// Set the `Advanced<T>` Mana Defense Points
920    fn set_m_def(&mut self, amount:T);
921
922// PREMADE FUNCTIONS
923    /// Get the id number
924    fn id(&self) -> T {
925        self.stat().id
926    }
927    /// Get the Health Points
928    fn hp(&self) -> T {
929        self.stat().hp
930    }
931    /// Get the Mana Points
932    fn mp(&self) -> T {
933        self.stat().mp
934    }
935    /// Get the Experience Points
936    fn xp(&self) -> T {
937        self.stat().xp
938    }
939    /// Get the Max Health Points
940    fn hp_max(&self) -> T {
941        self.stat().hp_max
942    }
943    /// Get the Max Mana Points
944    fn mp_max(&self) -> T {
945        self.stat().mp_max
946    }
947    /// Get the Experience Points
948    fn xp_next(&self) -> T {
949        self.stat().xp_next
950    }
951    /// Get the Current Level
952    fn level(&self) -> T {
953        self.stat().level
954    }
955    /// Get the Speed
956    fn speed(&self) -> T {
957        self.stat().level
958    }
959    /// Get the Attack Points
960    fn atk(&self) -> T {
961        self.stat().atk
962    }
963    /// Get the Defense Points
964    fn def(&self) -> T {
965        self.stat().def
966    }
967    /// Get the Mana Attack Points
968    fn m_atk(&self) -> T {
969        self.stat().m_atk
970    }
971    /// Get the Mana Defense Points
972    fn m_def(&self) -> T {
973        self.stat().m_def
974    }
975    /// Get the Gold Points
976    fn gp(&self) -> T {
977        self.stat().gp
978    }
979    /// Get the agility Points
980    fn agi(&self) -> T {
981        self.stat().agility
982    }
983    /// Get the strength Points
984    fn str(&self) -> T {
985        self.stat().strength
986    }
987    /// Get the intelligence Points
988    fn int(&self) -> T {
989        self.stat().intelligence
990    }
991    /// Get the dexterity Points
992    fn dex(&self) -> T {
993        self.stat().dexterity
994    }
995    /// Get the constitution Points
996    fn con(&self) -> T {
997        self.stat().constitution
998    }
999    /// Get the charisma Points
1000    fn char(&self) -> T {
1001        self.stat().charisma
1002    }
1003    /// Get the wisdom Points
1004    fn wis(&self) -> T {
1005        self.stat().wisdom
1006    }
1007    /// Get the Age
1008    fn age(&self) -> T {
1009        self.stat().age
1010    }
1011    /// Damage the character by an amount
1012    fn damage(&mut self, amount:T) {
1013        let mut val = self.hp();
1014        val -= amount;
1015        let none = num::cast(0).unwrap();
1016        if val < none {
1017            val = none;
1018        }
1019        self.set_hp(val)
1020    }
1021    /// Add health to character but not beyond their Max Healh Points
1022    fn heal(&mut self, amount:T) {
1023        let mut val = self.hp();
1024        val += amount;
1025        let max = self.hp_max();
1026        if val > max {
1027            val = max;
1028        }
1029        self.set_hp(val)
1030    }
1031    // TODO taken from `Normal`
1032    /// Stable attack forumla
1033    /// [attack*(100/(100+defense))](https://rpg.fandom.com/wiki/Damage_Formula)
1034    fn attack_stable(&self, other:Advanced<T>) -> T { 
1035        let hundred = num::cast(100).unwrap();
1036        let val = self.atk();
1037        let def = other.def + hundred;
1038        let res = hundred / def;
1039        val * res
1040    }
1041    /// Scalable attack forumla
1042    /// [damage = att * att / (att + def)](https://gamedev.stackexchange.com/questions/129319/rpg-formula-attack-and-defense)
1043    fn attack(&self, other:Advanced<T>) -> T {
1044        let val = self.atk();
1045        let mut res = val * val;
1046        let mut def = other.def;
1047        def += val;
1048        res /= def;
1049        res
1050    }
1051}
1052/*
1053# The Advanced stat model
1054The entire stat sheet for fine tuned algorithms using all the information possible!
1055*/
1056#[allow(unused)]
1057#[derive( Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
1058pub struct Advanced<T:Copy
1059    + Default
1060    + Debug
1061    + AddAssign
1062    + Add<Output = T>
1063    + Div<Output = T>
1064    + DivAssign
1065    + Mul<Output = T>
1066    + MulAssign
1067    + Neg<Output = T>
1068    + Rem<Output = T>
1069    + RemAssign
1070    + Sub<Output = T>
1071    + SubAssign
1072    + std::cmp::PartialOrd
1073    + num::NumCast> {
1074    /// Identification Number
1075    pub id:T,
1076    /// Experience Points
1077    pub xp:T,
1078    /// Health Points
1079    pub hp:T,
1080    /// Mana Points
1081    pub mp:T,
1082    /// Experience Points multiplier for next level
1083    pub xp_next:T,
1084    /// Max Health Points
1085    pub hp_max:T,
1086    /// Max Mana Points
1087    pub mp_max:T,
1088    /// Current Level
1089    pub level:T,
1090    /// The speed
1091    pub speed:T,
1092    /// your currency points
1093    pub gp:T,
1094    /// Attack
1095    pub atk:T,
1096    /// Defense
1097    pub def:T,
1098    /// Mana Attack
1099    pub m_atk:T,
1100    /// Mana Defense
1101    pub m_def:T,
1102    /// The agility Points
1103    pub agility:T,
1104    /// The strength Points
1105    pub strength:T,
1106    /// The dexterity Points
1107    pub dexterity:T,
1108    /// The constitution Points
1109    pub constitution:T,
1110    /// The intelligence Points
1111    pub intelligence:T,
1112    /// The charisma Points
1113    pub charisma:T,
1114    /// The wisdom Points
1115    pub wisdom:T,
1116    /// The current age
1117    pub age:T,
1118    
1119}
1120impl<T:Copy
1121    + Default
1122    + Debug
1123    + AddAssign
1124    + Add<Output = T>
1125    + Div<Output = T>
1126    + DivAssign
1127    + Mul<Output = T>
1128    + MulAssign
1129    + Neg<Output = T>
1130    + Rem<Output = T>
1131    + RemAssign
1132    + Sub<Output = T>
1133    + SubAssign
1134    + std::cmp::PartialOrd
1135    + num::NumCast> Advanced<T> {
1136    /// make empty stats
1137    #[allow(unused)]
1138    pub fn empty<U:Default>() -> Self {
1139        Advanced {
1140            id:Default::default(),
1141            xp:Default::default(),
1142            xp_next:Default::default(),
1143            mp:Default::default(),
1144            hp:Default::default(),
1145            mp_max:Default::default(),
1146            hp_max:Default::default(),
1147            level:Default::default(),
1148            speed:Default::default(),
1149            gp:Default::default(),
1150            atk:Default::default(),
1151            def:Default::default(),
1152            m_atk:Default::default(),
1153            m_def:Default::default(),
1154            agility:Default::default(),
1155            strength:Default::default(),
1156            dexterity:Default::default(),
1157            constitution:Default::default(),
1158            intelligence:Default::default(),
1159            charisma:Default::default(),
1160            wisdom:Default::default(),
1161            age:Default::default(),
1162        }
1163    }
1164    /// People like new
1165    #[allow(unused)]
1166    pub fn new<U:Default>() -> Self {
1167        Self::empty::<U>()
1168    }
1169    #[allow(unused)]
1170    /// Get the next amount of XP needed to level up
1171    pub fn next(&self) -> T {
1172        self.level * self.xp_next
1173    }
1174    #[allow(unused)]
1175    /// a vector of stats used to get the standard deviation
1176    pub fn stats_vec(&self) -> Vec<T>{
1177        vec![
1178            self.hp_max,
1179            self.mp_max,
1180            self.speed,
1181            self.atk,
1182            self.def,
1183            self.m_atk,
1184            self.m_def,
1185            self.agility,
1186            self.strength,
1187            self.dexterity,
1188            self.constitution,
1189            self.intelligence,
1190            self.charisma,
1191        ]
1192    }
1193
1194    #[allow(unused)]
1195    /// This function levels up our stats
1196    pub fn level_up(&mut self) -> bool {
1197        if self.xp > self.next() {
1198            let stats_vec:Vec<T> = self.stats_vec();
1199            let mut value:T = Math::population_standard_deviation(stats_vec);
1200            self.level += value;
1201            self.mp_max += value;
1202            self.hp_max += value;
1203            self.speed += value;
1204            self.atk += value;
1205            self.def += value;
1206            self.m_atk += value;
1207            self.m_def += value;
1208            self.agility += value;
1209            self.strength += value;
1210            self.dexterity += value;
1211            self.constitution += value;
1212            self.intelligence += value;
1213            self.charisma += value;
1214            return true;
1215        }
1216        false
1217    }
1218}
1219impl<T:Copy
1220    + Default
1221    + Debug
1222    + AddAssign
1223    + Add<Output = T>
1224    + Div<Output = T>
1225    + DivAssign
1226    + Mul<Output = T>
1227    + MulAssign
1228    + Neg<Output = T>
1229    + Rem<Output = T>
1230    + RemAssign
1231    + Sub<Output = T>
1232    + SubAssign
1233    + std::cmp::PartialOrd
1234    + num::NumCast> Default for Advanced<T> {
1235    /// Default to empty
1236    fn default() -> Self {
1237        Self::empty::<T>()
1238    }
1239}
1240
1241/*
1242# The FLTK Stats
1243This is designed to be used with FLTK, but can be used without FLTK
1244*/
1245#[derive( Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
1246#[cfg_attr(feature = "fltkform", derive(FltkForm))]
1247pub struct Stats {
1248    /// Identification Number
1249    pub id:f64,
1250    /// Experience Points
1251    pub xp:f64,
1252    /// Health Points
1253    pub hp:f64,
1254    /// Mana Points
1255    pub mp:f64,
1256    /// Experience Points multiplier for next level
1257    pub xp_next:f64,
1258    /// Max Health Points
1259    pub hp_max:f64,
1260    /// Max Mana Points
1261    pub mp_max:f64,
1262    /// Current Level
1263    pub level:f64,
1264    /// The speed
1265    pub speed:f64,
1266    /// your currency points
1267    pub gp:f64,
1268    /// Attack
1269    pub atk:f64,
1270    /// Defense
1271    pub def:f64,
1272    /// Mana Attack
1273    pub m_atk:f64,
1274    /// Mana Defense
1275    pub m_def:f64,
1276
1277}
1278impl Random for Stats {
1279    type Type = Stats;
1280    fn random_type(&self) -> Self::Type {
1281        let hp = self.random(10.0,50.0);
1282        let atk = self.random(5.0,50.0);
1283        let def = self.random(5.0,50.0);
1284        let mp = self.random(10.0,50.0);
1285        let m_atk = self.random(5.0,50.0);
1286        let m_def = self.random(5.0,50.0);
1287        let speed = self.random(5.0,50.0);
1288        let gp = self.random(0.0, 30.0);
1289        Stats {
1290            id:self.random(0.0, 100.0),
1291            xp:0.0,
1292            xp_next:10.0,
1293            level:1.0,
1294            hp_max:hp,
1295            hp,
1296            mp_max:mp,
1297            mp,
1298            atk,
1299            def,
1300            m_atk,
1301            m_def,
1302            speed,
1303            gp,
1304            
1305        }
1306    }
1307    
1308}
1309impl Stats {
1310    
1311    /// make empty stats
1312    #[allow(unused)]
1313    pub fn empty() -> Self {
1314        Stats {
1315            id:0.0,
1316            xp:0.0,
1317            xp_next:0.0,
1318            mp:0.0,
1319            hp:0.0,
1320            mp_max:0.0,
1321            hp_max:0.0,
1322            level:0.0,
1323            speed:0.0,
1324            gp:0.0,
1325            atk:0.0,
1326            def:0.0,
1327            m_atk:0.0,
1328            m_def:0.0,
1329        }
1330    }
1331    /// People like new
1332    #[allow(unused)]
1333    pub fn new() -> Self {
1334        Self::empty()
1335    }
1336    #[allow(unused)]
1337    /// Get the next amount of XP needed to level up
1338    pub fn next(&self) -> f64 {
1339        self.level * self.xp_next
1340    }
1341    #[allow(unused)]
1342    /// a vector of stats used to get the standard deviation
1343    pub fn stats_vec(&self) -> Vec<f64>{
1344        vec![
1345            self.hp_max,
1346            self.mp_max,
1347            self.speed,
1348            self.atk,
1349            self.def,
1350            self.m_atk,
1351            self.m_def,
1352        ]
1353    }
1354
1355    #[allow(unused)]
1356    /// This function levels up our stats
1357    pub fn level_up(&mut self) {
1358        println!("xp:{} next:{}", self.xp, self.next());
1359        if self.xp > self.next() {
1360            let stats_vec:Vec<f64> = self.stats_vec();
1361            let mut num:f64 = Math::population_standard_deviation(stats_vec);
1362            let one = num::cast(1).unwrap();
1363            if num < one {
1364                num = one;
1365            }
1366            num *= self.level;
1367            self.level += num;
1368            self.mp_max += num;
1369            self.hp_max += num;
1370            self.speed += num;
1371            self.atk += num;
1372            self.def += num;
1373            self.m_atk += num;
1374            self.m_def += num;
1375        }
1376    }
1377}
1378
1379impl Default for Stats {
1380    /// Default to empty
1381    fn default() -> Self {
1382        Self::empty()
1383    }
1384}
1385
1386/*
1387# Premade trait for the f64/FLTK Stat
1388Define the function `stat()` to return the `Stats` associated with your code.
1389Define the methods to set the stats, and the getter functions already exist
1390
1391
1392*/
1393pub trait Premade {
1394    /// # Function you need to imlement
1395    /// stat returns the `Stats` you created
1396    fn stat(&self) -> Stats;
1397    /// # Function you need to imlement
1398    /// Set the `Stats` Health Points
1399    fn set_hp(&mut self, amount:f64);
1400    /// # Function you need to imlement
1401    /// Set the `Stats` Mana Points
1402    fn set_mp(&mut self, amount:f64);
1403    /// # Function you need to imlement
1404    /// Set the `Stats` Experience Points
1405    fn set_xp(&mut self, amount:f64);
1406    /// # Function you need to imlement
1407    /// Set the `Stats` Max Health Points
1408    fn set_hp_max(&mut self, amount:f64);
1409    /// # Function you need to imlement
1410    /// Set the `Stats` Max Mana Points
1411    fn set_mp_max(&mut self, amount:f64);
1412    /// # Function you need to imlement
1413    /// Set the `Stats` Next Experience Points
1414    fn set_xp_next(&mut self, amount:f64);
1415    /// # Function you need to imlement
1416    /// Set the `Stats` Gold Points
1417    fn set_gp(&mut self, amount:f64);
1418    /// # Function you need to imlement
1419    /// Set the `Stats` Attack Points
1420    fn set_atk(&mut self, amount:f64);
1421    /// # Function you need to imlement
1422    /// Set the `Stats` Defense Points
1423    fn set_def(&mut self, amount:f64);
1424    /// # Function you need to imlement
1425    /// Set the `Stats` Mana Attack Points
1426    fn set_m_atk(&mut self, amount:f64);
1427    /// # Function you need to imlement
1428    /// Set the `Stats` Mana Defense Points
1429    fn set_m_def(&mut self, amount:f64);
1430    /// # Function you need to imlement
1431    /// Set the `Stats` Level
1432    fn set_level(&mut self, amount:f64);
1433    /// # Function you need to imlement
1434    /// Set the `Stats` Level
1435    fn set_speed(&mut self, amount:f64);
1436
1437// PREMADE FUNCf64IONS   
1438    /// Return  the `Stats` id number
1439    fn id(&self) -> f64 {
1440        self.stat().id
1441    }
1442    /// Return  the `Stats` Health Points
1443    fn hp(&self) -> f64 {
1444        self.stat().hp
1445    }
1446    /// Return  the `Stats` Mana Points
1447    fn mp(&self) -> f64 {
1448        self.stat().mp
1449    }
1450    /// Return  the `Stats` Experience Points
1451    fn xp(&self) -> f64 {
1452        self.stat().xp
1453    }
1454    /// Return  the `Stats` Max Health Points
1455    fn hp_max(&self) -> f64 {
1456        self.stat().hp_max
1457    }
1458    /// Return  the `Stats` Max Mana Points
1459    fn mp_max(&self) -> f64 {
1460        self.stat().mp_max
1461    }
1462    /// Return  the `Stats` Next Experience Points
1463    fn xp_next(&self) -> f64 {
1464        self.stat().xp_next
1465    }
1466    /// Return  the `Stats` Level
1467    fn level(&self) -> f64 {
1468        self.stat().level
1469    }
1470    /// Return  the `Stats` Speed
1471    fn speed(&self) -> f64 {
1472        self.stat().speed
1473    }
1474    /// Return  the `Stats` Gold Points
1475    fn gp(&self) -> f64 {
1476        self.stat().gp
1477    }
1478    /// Return  the `Stats` Attack Points
1479    fn atk(&self) -> f64 {
1480        self.stat().atk
1481    }
1482    /// Return  the `Stats` Defense Points
1483    fn def(&self) -> f64 {
1484        self.stat().def
1485    }
1486    /// Return  the `Stats` Mana Attack Points
1487    fn m_atk(&self) -> f64 {
1488        self.stat().m_atk
1489    }
1490    /// Return  the `Stats` Mana Defense Points
1491    fn m_def(&self) -> f64 {
1492        self.stat().m_def
1493    }
1494    /// Return  the `Stats` Attack Points
1495    fn add_atk(&mut self, amount:f64) {
1496        self.set_atk(self.stat().atk + amount);
1497    }
1498    /// Return  the `Stats` Defense Points
1499    fn add_def(&mut self, amount:f64) {
1500        self.set_def(self.stat().def + amount);
1501    }
1502    /// Return  the `Stats` Mana Attack Points
1503    fn add_m_atk(&mut self, amount:f64) {
1504        self.set_m_atk(self.stat().m_atk + amount);
1505    }
1506    /// Return  the `Stats` Mana Defense Points
1507    fn add_m_def(&mut self, amount:f64) {
1508        self.set_m_def(self.stat().m_def + amount);
1509    }/// Return  the `Stats` Experience Points
1510    fn add_xp(&mut self, amount:f64) {
1511        self.set_xp(self.stat().xp + amount);
1512    }
1513    /// Return  the `Stats` Max Health Points
1514    fn add_hp_max(&mut self, amount:f64) {
1515        self.set_hp_max(self.stat().hp_max + amount);
1516    }
1517    /// Return  the `Stats` Max Mana Points
1518    fn add_mp_max(&mut self, amount:f64) {
1519       self.set_mp_max( self.stat().mp_max + amount);
1520    }
1521    /// Return  the `Stats` Level
1522    fn add_level(&mut self, amount:f64) {
1523        self.set_level(self.stat().level + amount);
1524    }
1525    /// Return  the `Stats` Speed
1526    fn add_speed(&mut self, amount:f64) {
1527        self.set_speed(self.stat().speed + amount);
1528    }
1529    /// Damage the character by an amount
1530    fn damage(&mut self, amount:f64) {
1531        let mut val = self.hp();
1532        val -= amount;
1533        let none = 0.0;
1534        if val < none {
1535            val = none;
1536        }
1537        self.set_hp(val)
1538    }
1539    /// Add health to character but not beyond their Max Healh Points
1540    fn heal(&mut self, amount:f64) {
1541        let mut val = self.hp();
1542        val += amount;
1543        let max = self.hp_max();
1544        if val > max {
1545            val = max;
1546        }
1547        self.set_hp(val)
1548    }
1549    /// Stable attack forumla
1550    /// [attack*(100/(100+defense))](https://rpg.fandom.com/wiki/Damage_Formula)
1551    fn attack_stable(&self, other:Stats) -> f64 { 
1552        let hundred = 100.0;
1553        let val = self.atk();
1554        let def = other.def + hundred;
1555        let res = hundred / def;
1556        val * res
1557    }
1558    /// Scalable attack forumla
1559    /// [damage = att * att / (att + def)](https://gamedev.stackexchange.com/questions/129319/rpg-formula-attack-and-defense)
1560    fn attack(&self, other:Stats) -> f64 {
1561        let val = self.atk();
1562        let mut res = val * val;
1563        let def = other.def + val;
1564        res /= def;
1565        res
1566    }
1567    fn buy(&mut self, price:f64) -> bool {
1568        let total = self.gp() - price;
1569        if total <= 0.0 {
1570            return false;
1571        }
1572        self.set_gp(total);
1573        true
1574    }
1575    fn earn(&mut self, price:f64) {
1576        let total = self.gp() + price;
1577        self.set_gp(total);
1578    }    #[allow(unused)]
1579    /// Get the next amount of XP needed to level up
1580    fn next(&self) -> f64 {
1581        self.level() * self.xp_next()
1582    }
1583    /// a vector of stats used to get the standard deviation
1584    fn stats_vec(&self) -> Vec<f64>{
1585        vec![
1586            self.hp_max(),
1587            self.mp_max(),
1588            self.speed(),
1589            self.atk(),
1590            self.def(),
1591            self.m_atk(),
1592            self.m_def(),
1593        ]
1594    }
1595
1596    #[allow(unused)]
1597    fn level_up(&mut self) -> bool{
1598        if self.xp() > self.next() {
1599            let stats_vec:Vec<f64> = self.stats_vec();
1600            let mut num:f64 = Math::population_standard_deviation(stats_vec);
1601            let one = 1.0;
1602            if num < one {
1603                num = one;
1604            }
1605            self.add_level(num);
1606            self.add_mp_max(num);
1607            self.add_hp_max(num);
1608            self.add_speed(num);
1609            self.add_atk(num);
1610            self.add_def(num);
1611            self.add_m_atk(num);
1612            self.add_m_def(num);
1613            return true;
1614        }
1615        false
1616    }
1617}