rpg_stat/
types.rs

1/*!
2# Types
3
4This includes various enums related to the type of character you have
5
6`Basic` is the basic type `Good` or `Bad`
7
8`Normal` has elemental types
9
10`Advanced` has elemental types
11
12# Effectiveness
13
14`Basic` has no need for effectiveness against types, so you can implement your own `Compare` if you like
15
16```
17use rpg_stat::types::Basic;
18use rpg_stat::types::Compare;
19use rpg_stat::attributes::Effectiveness;
20use std::fmt;
21use std::fmt::Debug;
22use std::fmt::Display;
23use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign};
24extern crate num;
25use num::NumCast;
26
27// Work around it
28struct MyType(Basic);
29// here it is.
30impl Compare for MyType {
31    type Type = Basic;
32    // Plant Effectiveness against a target
33    fn plant(other:Basic) -> Effectiveness {
34        Effectiveness::Normal
35    }
36    /// Rock Effectiveness against a target
37    fn rock(other:Basic) -> Effectiveness {
38        Effectiveness::Normal
39    }
40    /// Water Effectiveness against a target
41    fn water(other:Basic) -> Effectiveness {
42        Effectiveness::Normal
43    }
44    /// Fire Effectiveness against a target
45    fn fire(other:Basic) -> Effectiveness {
46        Effectiveness::Normal
47    }
48    /// Electric Effectiveness against a target
49    fn electric(other:Basic) -> Effectiveness {
50        Effectiveness::Normal
51    }
52    /// Spirit Effectiveness against a target
53    fn spirit(other:Basic) -> Effectiveness {
54        Effectiveness::Normal
55    }
56    /// Light Effectiveness against a target
57    fn light(other:Basic) -> Effectiveness {
58        Effectiveness::Normal
59    }
60    /// Wind Effectiveness against a target
61    fn wind(other:Basic) -> Effectiveness {
62        Effectiveness::Normal
63    }
64    /// None Effectiveness against a target
65    fn none(other:Basic) -> Effectiveness {
66        Effectiveness::Normal
67    }
68    ///  Effectiveness against a target
69    fn effectiveness(&self, other:Basic) -> Effectiveness {
70        Effectiveness::Normal
71    }
72}
73```
74
75`Normal` implements this, see the `Compare` trait
76
77This can be compared easily using the Compare trait
78
79`Advanced` is currently the same as `Normal`
80*/
81use std::fmt;
82use std::fmt::Debug;
83extern crate num;
84use serde::{Deserialize, Serialize};
85
86#[cfg(feature = "fltkform")]
87use fltk::{prelude::*, *};
88#[cfg(feature = "fltkform")]
89use fltk_form_derive::*;
90#[cfg(feature = "fltkform")]
91use fltk_form::FltkForm;
92
93//module stuff
94use crate::attributes::Effectiveness;
95use crate::random::Random;
96
97/*
98# Compare
99This trait is used by `Normal` and `Advanced`
100*/
101pub trait Compare {
102    type Type;
103    // Plant Effectiveness against a target
104    fn plant(other:Self::Type) -> Effectiveness;
105    /// Rock Effectiveness against a target
106    fn rock(other:Self::Type) -> Effectiveness;
107    /// Water Effectiveness against a target
108    fn water(other:Self::Type) -> Effectiveness;
109    /// Fire Effectiveness against a target
110    fn fire(other:Self::Type) -> Effectiveness;
111    /// Electric Effectiveness against a target
112    fn electric(other:Self::Type) -> Effectiveness;
113    /// Spirit Effectiveness against a target
114    fn spirit(other:Self::Type) -> Effectiveness;
115    /// Light Effectiveness against a target
116    fn light(other:Self::Type) -> Effectiveness;
117    /// Wind Effectiveness against a target
118    fn wind(other:Self::Type) -> Effectiveness;
119    /// None Effectiveness against a target
120    fn none(other:Self::Type) -> Effectiveness;
121    ///  Effectiveness against a target
122    fn effectiveness(&self, other:Self::Type) -> Effectiveness;
123}
124#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
125///  `Basic`
126///```rs:no_run                       
127///    ------   _  __ __     
128///      |  \ / |) |_ |_     
129///      |   |  |  |_ _/     
130///```
131/// 
132/// * Good     - good
133/// * Bad    - bad
134pub enum Basic {
135    /// Good
136    Good,
137    Bad,
138}
139impl Default for Basic {
140    /// Default to enemy type for games
141    fn default() -> Self {
142        Self::Bad
143    }
144}
145impl fmt::Display for Basic {
146    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
147        let v:String;
148        match *self {
149            Basic::Good => v = String::from("Good"),
150            Basic::Bad => v = String::from("Bad"),
151        }
152        write!(f, "{}", v.as_str())
153    }
154}
155
156/* # `Normal`
157```rs:no_run
158    ------   _  __ __     
159      |  \ / |) |_ |_     
160      |   |  |  |_ _/     
161```
162 
163 * rock     - earth type  
164 * plant    - green type  
165 * water    - liquid type 
166 * fire     - lava type   
167 * electric - lightning type
168 * spirit   - holy type    
169 * light    - laser type   
170 * wind     - tornado type
171
172## Compare
173
174Implemented according to this chart:
175<div>
176<img src="https://raw.githubusercontent.com/1sra3l/rpg-stat/main/assets/type-effectiveness-chart.png" />
177</div>
178
179```
180use rpg_stat::types::Normal as Type;
181// to check effectiveness
182use rpg_stat::types::Compare;
183// need effectiveness too!
184use rpg_stat::attributes::Effectiveness;
185
186let rock = Type::Rock;
187let wind = Type::Wind;
188assert_eq!(rock.effectiveness(wind), Effectiveness::None);
189assert_eq!(wind.effectiveness(rock), Effectiveness::Double);
190
191```
192*/
193
194#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
195#[cfg_attr(feature = "fltkform", derive(FltkForm))]
196pub enum Normal {
197    Rock,
198    Plant,
199    Water,
200    Fire,
201    Electric,
202    Spirit,
203    Light,
204    Wind,
205    None,
206}
207impl Normal {
208    #[allow(unused)]
209    pub fn level_threshold(&self, current_level:f64) -> f64 {
210        let mut threshold:f64 = current_level;
211        let mut counter:u32 = 0;
212        while threshold > 10.0 {
213            threshold /= 10.0;
214            counter += 1;
215        }
216        match *self {
217            //TODO type based level 
218            Normal::Rock => threshold += 0.0,
219            Normal::Plant => threshold += 0.0,
220            Normal::Water => threshold += 0.0,
221            Normal::Fire => threshold += 0.0,
222            Normal::Electric => threshold += 0.0,
223            Normal::Spirit => threshold += 0.0,
224            Normal::Light => threshold += 0.0,
225            Normal::Wind => threshold += 0.0,
226            _=> threshold += 0.0,
227        }
228        for _div in 0..counter {
229            threshold *= 10.0;
230        }
231        threshold
232    }
233}
234impl Random for Normal {
235    type Type = Normal;
236    fn random_type(&self) -> Self::Type {
237        let max = 8;
238        let val = self.random_rate(max);
239        match val {
240            0 => Normal::Rock,
241            1 => Normal::Plant,
242            2 => Normal::Water,
243            3 => Normal::Fire,
244            4 => Normal::Electric,
245            5 => Normal::Spirit,
246            7 => Normal::Light,
247            8 => Normal::Wind,
248            _=> Normal::None,
249        }
250    }
251}
252impl Default for Normal {
253    /// Default to empty
254    fn default() -> Self {
255        Self::Rock
256    }
257}
258impl fmt::Display for Normal {
259    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
260        let v:String;
261        match *self {
262            Normal::Rock => v = String::from("Rock"),
263            Normal::Plant => v = String::from("Plant"),
264            Normal::Water => v = String::from("Water"),
265            Normal::Fire => v = String::from("Fire"),
266            Normal::Electric => v = String::from("Electric"),
267            Normal::Spirit => v = String::from("Spirit"),
268            Normal::Light => v = String::from("Light"),
269            Normal::Wind => v = String::from("Wind"),
270            Normal::None => v = String::from("None"),
271        }
272        write!(f, "{}", v.as_str())
273    }
274}
275impl Compare for Normal {
276    type Type = Normal;
277    ///  Plant Effectiveness against a target
278    fn plant(other:Normal) -> Effectiveness {
279        match other {
280            Normal::Rock => Effectiveness::HalfExtra,
281            Normal::Water => Effectiveness::Half,
282            Normal::Fire => Effectiveness::None,
283            Normal::Light => Effectiveness::Double,
284            Normal::Wind => Effectiveness::Half,
285            _=> Effectiveness::Normal,
286        }
287    }
288    /// Rock Effectiveness against a target
289    fn rock(other:Normal) -> Effectiveness {
290        match other {
291            Normal::Plant => Effectiveness::Half,
292            Normal::Water => Effectiveness::HalfExtra,
293            Normal::Fire => Effectiveness::Double,
294            Normal::Electric => Effectiveness::Double,
295            Normal::Light => Effectiveness::Half,
296            Normal::Wind => Effectiveness::None,
297            _=> Effectiveness::Normal,
298        }
299    }
300    /// Water Effectiveness against a target
301    fn water(other:Normal) -> Effectiveness {
302        match other {
303            Normal::Rock => Effectiveness::Double,
304            Normal::Plant => Effectiveness::HalfExtra,
305            Normal::Fire => Effectiveness::Double,
306            Normal::Electric => Effectiveness::Half,
307            Normal::Light => Effectiveness::None,
308            Normal::Wind => Effectiveness::Half,
309            _=> Effectiveness::Normal,
310        }
311    }
312    /// Fire Effectiveness against a target
313    fn fire(other:Normal) -> Effectiveness {
314        match other {
315            Normal::Rock => Effectiveness::Half,
316            Normal::Plant => Effectiveness::Double,
317            Normal::Water => Effectiveness::HalfExtra,
318            Normal::Spirit => Effectiveness::None,
319            Normal::Wind => Effectiveness::Half,
320            _=> Effectiveness::Normal,
321        }
322    }
323    /// Electric Effectiveness against a target
324    fn electric(other:Normal) -> Effectiveness {
325        match other {
326            Normal::Rock => Effectiveness::Half,
327            Normal::Plant => Effectiveness::HalfExtra,
328            Normal::Water => Effectiveness::Double,
329            Normal::Light => Effectiveness::None,
330            Normal::Wind => Effectiveness::Half,
331            _=> Effectiveness::Normal,
332        }
333    }
334    /// Spirit Effectiveness against a target
335    fn spirit(other:Normal) -> Effectiveness {
336        match other {
337            Normal::Water => Effectiveness::None,
338            Normal::Fire => Effectiveness::Double,
339            Normal::Electric => Effectiveness::Half,
340            Normal::Spirit => Effectiveness::HalfExtra,
341            Normal::Light => Effectiveness::Half,
342            Normal::Wind => Effectiveness::Double,
343            Normal::None => Effectiveness::None,
344            _=> Effectiveness::Normal,
345        }
346    }
347    /// Light Effectiveness against a target
348    fn light(other:Normal) -> Effectiveness {
349        match other {
350            Normal::Rock => Effectiveness::Double,
351            Normal::Plant => Effectiveness::None,
352            Normal::Water => Effectiveness::Double,
353            Normal::Fire => Effectiveness::None,
354            Normal::Electric => Effectiveness::Half,
355            Normal::Wind => Effectiveness::HalfExtra,
356            Normal::None => Effectiveness::Half,
357            _=> Effectiveness::Normal,
358        }
359    }
360    ///  Effectiveness against a target
361    fn wind(other:Normal) -> Effectiveness {
362        match other {
363            Normal::Rock => Effectiveness::Double,
364            Normal::Plant => Effectiveness::Half,
365            Normal::Water => Effectiveness::Double,
366            Normal::Fire => Effectiveness::None,
367            Normal::Spirit => Effectiveness::Half,
368            Normal::Wind => Effectiveness::HalfExtra,
369            _=> Effectiveness::Normal,
370        }
371    }
372    ///  Effectiveness against a target
373    fn none(other:Normal) -> Effectiveness {
374        match other {
375            Normal::Water => Effectiveness::Half,
376            Normal::Fire => Effectiveness::Half,
377            Normal::Electric => Effectiveness::Half,
378            Normal::Spirit => Effectiveness::None,
379            Normal::Light => Effectiveness::None,
380            Normal::Wind => Effectiveness::Half,
381            _=> Effectiveness::Normal,
382        }
383    }
384    
385    /// Match current Type to find effectiveness of the value
386    fn effectiveness(&self, other:Normal) -> Effectiveness {
387        match *self {
388            Normal::Rock => Normal::rock(other),
389            Normal::Plant => Normal::plant(other),
390            Normal::Water => Normal::water(other),
391            Normal::Fire => Normal::fire(other),
392            Normal::Electric => Normal::electric(other),
393            Normal::Spirit => Normal::spirit(other),
394            Normal::Light => Normal::light(other),
395            Normal::Wind => Normal::wind(other),
396            Normal::None => Normal::none(other),
397        }
398    }
399}
400#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
401#[cfg_attr(feature = "fltkform", derive(FltkForm))]
402///  `Advanced`
403pub enum Advanced {
404    /// Feline - Cat type
405    Feline,
406    /// Canine - Dog type
407    Canine,
408    /// Rodent - mouse type
409    Rodent,
410    /// Primate - monkey type
411    Primate,
412    /// Bug - creepy crawly type
413    Bug,
414    /// Amphibian - frog/salamander type
415    Amphibian,
416    /// Reptile -  type
417    Reptile,
418    /// Fish - 
419    Fish,
420    /// Dragon - 
421    Dragon,
422    /// Legendary - 
423    Legendary,
424    /// Plasma - 
425    Plasma,
426    /// Magma - 
427    Magma,
428    /// Crystal - 
429    Crystal,
430    /// Laser - 
431    Laser,
432    /// Tech - 
433    Tech,
434    /// Leaf - 
435    Leaf,
436    /// Patch - 
437    Patch,
438    /// Undead - 
439    Undead,
440    /// Star - 
441    Star,
442    /// Galactic - 
443    Galactic,
444    /// Kaiju - 
445    Kaiju,
446    /// Xeno - 
447    Xeno,
448    /// Paper - 
449    Paper,
450    /// Shifter - 
451    Shifter,
452    /// Gravity - 
453    Gravity,
454    /// Life - 
455    Life,
456    /// Food - 
457    Food,
458    /// Death - 
459    Death,
460    /// Mana - 
461    Mana,
462    /// Bubble - 
463    Bubble,
464    /// Seed - 
465    Seed,
466    /// Bean - 
467    Bean,
468    /// Clay - 
469    Clay,
470    /// Steel - 
471    Steel,
472    /// Iron - 
473    Iron,
474    /// Vine - 
475    Vine,
476    /// Tree - 
477    Tree,
478    /// River - 
479    River,
480    /// Ocean - 
481    Ocean,
482    /// Ember - 
483    Ember,
484    /// Lava - 
485    Lava,
486    /// Spark - 
487    Spark,
488    /// Lightning - 
489    Lightning,
490    /// Holy - 
491    Holy,
492    /// Unholy - 
493    Unholy,
494    /// Sunrise - 
495    Sunrise,
496    /// Sunset - 
497    Sunset,
498    /// Moonrise - 
499    Moonrise,
500    /// Moonset - 
501    Moonset,
502    /// Tornado - 
503    Tornado,
504    /// Breeze - 
505    Breeze,
506    /// Blustry - 
507    Blustry,
508    None,
509}
510impl Default for Advanced {
511    fn default() -> Self {
512        Self::None
513    }
514}
515impl fmt::Display for Advanced {
516    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
517        let v:String;
518        match *self {
519            Advanced::Feline => v = String::from("Feline"),
520            Advanced::Canine => v = String::from("Canine"),
521            Advanced::Rodent => v = String::from("Rodent"),
522            Advanced::Primate => v = String::from("Primate"),
523            Advanced::Bug => v = String::from("Bug"),
524            Advanced::Amphibian => v = String::from("Amphibian"),
525            Advanced::Reptile => v = String::from("Reptile"),
526            Advanced::Fish => v = String::from("Fish"),
527            Advanced::Dragon => v = String::from("Dragon"),
528            Advanced::Legendary => v = String::from("Legendary"),
529            Advanced::Plasma => v = String::from("Plasma"),
530            Advanced::Magma => v = String::from("Magma"),
531            Advanced::Crystal => v = String::from("Crystal"),
532            Advanced::Laser => v = String::from("Laser"),
533            Advanced::Tech => v = String::from("Tech"),
534            Advanced::Leaf => v = String::from("Leaf"),
535            Advanced::Patch => v = String::from("Patch"),
536            Advanced::Undead => v = String::from("Undead"),
537            Advanced::Star => v = String::from("Star"),
538            Advanced::Galactic => v = String::from("Galactic"),
539            Advanced::Kaiju => v = String::from("Kaiju"),
540            Advanced::Xeno => v = String::from("Xeno"),
541            Advanced::Paper => v = String::from("Paper"),
542            Advanced::Shifter => v = String::from("Shifter"),
543            Advanced::Gravity => v = String::from("Gravity"),
544            Advanced::Life => v = String::from("Life"),
545            Advanced::Food => v = String::from("Food"),
546            Advanced::Death => v = String::from("Death"),
547            Advanced::Mana => v = String::from("Mana"),
548            Advanced::Bubble => v = String::from("Bubble"),
549            Advanced::Seed => v = String::from("Seed"),
550            Advanced::Bean => v = String::from("Bean"),
551            Advanced::Clay => v = String::from("Clay"),
552            Advanced::Steel => v = String::from("Steel"),
553            Advanced::Iron => v = String::from("Iron"),
554            Advanced::Vine => v = String::from("Vine"),
555            Advanced::Tree => v = String::from("Tree"),
556            Advanced::River => v = String::from("River"),
557            Advanced::Ocean => v = String::from("Ocean"),
558            Advanced::Ember => v = String::from("Ember"),
559            Advanced::Lava => v = String::from("Lava"),
560            Advanced::Spark => v = String::from("Spark"),
561            Advanced::Lightning => v = String::from("Lightning"),
562            Advanced::Holy => v = String::from("Holy"),
563            Advanced::Unholy => v = String::from("Unholy"),
564            Advanced::Sunrise => v = String::from("Sunrise"),
565            Advanced::Sunset => v = String::from("Sunset"),
566            Advanced::Moonrise => v = String::from("Moonrise"),
567            Advanced::Moonset => v = String::from("Moonset"),
568            Advanced::Tornado => v = String::from("Tornado"),
569            Advanced::Breeze => v = String::from("Breeze"),
570            Advanced::Blustry => v = String::from("Blustry"),
571            _=> v = String::from("None"),
572        }
573        write!(f, "{}", v.as_str())
574    }
575}
576impl Random for Advanced {
577    type Type = Advanced;
578    fn random_type(&self) -> Self::Type {
579        let max = 52;
580        let val = self.random_rate(max);
581        match val {
582            0 => Advanced::Feline,
583            1 => Advanced::Canine,
584            2 => Advanced::Rodent,
585            3 => Advanced::Primate,
586            4 => Advanced::Bug,
587            5 => Advanced::Amphibian,
588            6 => Advanced::Reptile,
589            7 => Advanced::Fish,
590            8 => Advanced::Dragon,
591            9 => Advanced::Legendary,
592            10 => Advanced::Plasma,
593            11 => Advanced::Magma,
594            12 => Advanced::Crystal,
595            13 => Advanced::Laser,
596            14 => Advanced::Tech,
597            15 => Advanced::Leaf,
598            16 => Advanced::Patch,
599            17 => Advanced::Undead,
600            18 => Advanced::Star,
601            19 => Advanced::Galactic,
602            20 => Advanced::Kaiju,
603            21 => Advanced::Xeno,
604            22 => Advanced::Paper,
605            23 => Advanced::Shifter,
606            24 => Advanced::Gravity,
607            25 => Advanced::Life,
608            26 => Advanced::Food,
609            27 => Advanced::Death,
610            28 => Advanced::Mana,
611            29 => Advanced::Bubble,
612            30 => Advanced::Seed,
613            31 => Advanced::Bean,
614            32 => Advanced::Clay,
615            33 => Advanced::Steel,
616            34 => Advanced::Iron,
617            35 => Advanced::Vine,
618            36 => Advanced::Tree,
619            37 => Advanced::River,
620            38 => Advanced::Ocean,
621            39 => Advanced::Ember,
622            40 => Advanced::Lava,
623            41 => Advanced::Spark,
624            42 => Advanced::Lightning,
625            43 => Advanced::Holy,
626            44 => Advanced::Unholy,
627            45 => Advanced::Sunrise,
628            46 => Advanced::Sunset,
629            47 => Advanced::Moonrise,
630            48 => Advanced::Moonset,
631            49 => Advanced::Tornado,
632            50 => Advanced::Breeze,
633            51 => Advanced::Blustry,
634            _=> Advanced::None,
635        }
636    }
637    
638}