rpg_stat/
lib.rs

1/*!
2# RPG Stat library
3
4[![Documentation](https://docs.rs/rpg-stat/badge.svg)](https://docs.rs/rpg-stat)
5[![Crates.io](https://img.shields.io/crates/v/rpg-stat.svg)](https://crates.io/crates/rpg-stat)
6
7Cargo.toml
8
9Versioning numbering was changed to `year.month.day` format
10
11`rpg_stat="2021.12"`
12
13## Only SPECIFIC stats are supported for FLTK
14
15This is due to limitations of abstraction, namely Vectors and primitives being practically the same as a generic type
16FLTK uses `f64` so the `rpg_stat::stats::Stats` implements [fltk-form](https://crates.io/crates/fltk-form)
17
18# Stats
19
20The Stats are broken down into categories `Basic`, `Normal`, and `Advanced`
21
22`Basic` contains only the most needed for a generic game
23Your file needs:
24`use rpg_stat::stats::Basic as Stats`
25 * id
26 * xp
27 * xp_next
28 * level
29 * gp
30 * hp
31 * mp
32 * hp_max
33 * mp_max
34 * speed
35
36`Normal` includes a few more for the generic RPG battle system as well as everything in `Basic`
37Your file needs:
38`use rpg_stat::stats::Normal as Stats`
39 * atk
40 * def
41 * m_atk
42 * m_def
43
44`Advanced` contains the finer details seen in tabletop RPG stats as well as everything in `Normal` and `Basic`
45Your file needs:
46`use rpg_stat::stats::Advanced as Stats`
47 * agility
48 * strength
49 * dexterity
50 * constitution
51 * intelligence
52 * charisma
53 * wisdom
54 * age
55
56You can easily **ANY** of build these to populate however you like:
57```
58// choose Normal or Basic if you'd rather...
59use rpg_stat::stats::Advanced as Stats;
60let stats:Stats<f64> = Stats::empty::<f64>();
61```
62
63## Serde + TOML/INI
64
65Yes you can use serde with any of the assets/characters/ files provided.  You can use them in your custom structs.
66
67## Custom toml/ini with serde
68
69```
70use serde::{Deserialize, Serialize};
71use rpg_stat::attributes::{Effectiveness, Value};
72use rpg_stat::class::Basic as Class;
73use rpg_stat::stats::Basic as Stats;
74
75// example program
76const INI_FILE:&str = r#"name="test"
77class="Hero"
78effectiveness="None"
79image="/path/to/file"
80[stats]
81id = 1
82hp = 10
83mp = 10
84xp = 10
85level = 1
86hp_max = 10
87mp_max = 10
88xp_next = 10
89gp = 10
90speed = 10
91atk = 10
92def = 10
93m_atk = 10
94m_def = 10
95agi = 10
96str = 10
97int = 10
98dex = 10
99con = 10
100char = 10
101wis = 10
102age = 10"#;
103
104#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
105pub struct OccasionalEnemy {
106    pub name:String,
107    pub image:String,
108    pub stats:Stats<f64>,
109    pub effectiveness:Effectiveness,
110    pub class:Class,
111}
112let decoded: OccasionalEnemy = toml::from_str(INI_FILE).unwrap();
113assert_eq!(decoded.stats.hp, 10.0);
114assert_eq!(decoded.effectiveness, Effectiveness::None);
115// Value trait used here:
116assert_eq!(0.0, Effectiveness::None.value(decoded.stats.hp));
117assert_eq!(decoded.name, String::from("test"));
118assert_eq!(decoded.class.to_string(), String::from("Hero"));
119```
120## Builder
121Since the 1.X version `rpg-stat` has come with a `Builder` trait.
122The builder trait is being implemented for all the enumerations like the `rpg_stat::class::*` as well as `rpg_stat::creature::*`
123
124This allows you to do:
125```
126// feel free to use `Normal` or `Advanced` instead of `Basic`
127use rpg_stat::stats::Basic as Stats;
128use rpg_stat::class::Basic as Class;
129
130// this is the thing we need!
131use rpg_stat::stats::Builder;
132
133// get Hero stats for our program
134fn hero_stats () -> Stats<f64> {
135    // make the hero enum
136    let hero:Class = Class::Hero;
137    // this number only matters if you want
138    let id:f64 = 0.0;
139    // this effects the stats returned
140    let level:f64 = 1.0;
141    // use the basic `Builder`
142    let hero_stats:Stats<f64> = hero.build_basic(id, level);
143    // that was easy!
144    hero_stats
145}
146
147// TODO make them meet...
148```
149
150## Build your own!
151If you are not into making stats from things I made, you can implement your own builder:
152```toml
153num = "0.2"
154rpg-stat = "4.0"
155toml = "0.5"
156```
157
158# Classes
159
160The Classes are broken down into categories `Basic`, `Normal`, and `Advanced`
161
162The `Basic` class is either `Hero` or `Enemy`
163Your file needs:
164`use rpg_stat::class::Basic as Class`
165
166The `Normal` class includes a range of character classes for a battle game.
167Your file needs:
168`use rpg_stat::class::Normal as Class`
169
170`Advanced` includes more characters for a game with interactive roles, not simply a game of battle.
171Your file needs:
172`use rpg_stat::class::Advanced as Class`
173
174The stat `Builder` is implemented for all the classes and can be used easily:
175
176```
177use rpg_stat::stats::Normal as Stats;
178use rpg_stat::class::Normal as Class;
179// *Use this*
180use rpg_stat::stats::Builder;
181
182// get Hero stats for our program
183fn hero_stats () -> Stats<f64> {
184    // make the hero enum
185    let hero:Class = Class::Alchemist;
186    // this number only matters if you want
187    let id:f64 = 0.0;
188    // this effects the stats returned
189    let level:f64 = 1.0;
190    // use the basic `Builder`
191    let hero_stats:Stats<f64> = hero.build_normal(id, level);
192    // that was easy!
193    hero_stats
194}
195
196```
197
198# Creatures
199
200
201
202# Types
203
204This includes various enums related to the type of character you have
205
206`use rpg_stat::types::Basic as Type`
207
208 * `Basic` is the basic type `Good` or `Bad`
209 * `Normal` has elemental types
210 * `Advanced` has elemental types
211
212## Compare
213
214The Compare trait is implemented for `Normal`
215according to this chart:
216 
217```
218use rpg_stat::types::Normal as Type;
219// to check effectiveness
220use rpg_stat::types::Compare;
221// need effectiveness too!
222use rpg_stat::attributes::Effectiveness;
223
224let rock = Type::Rock;
225let wind = Type::Wind;
226assert_eq!(rock.effectiveness(wind), Effectiveness::None);
227assert_eq!(wind.effectiveness(rock), Effectiveness::Double);
228```
229
230# Special
231
232These are names of `Special` moves.
233
234```
235use rpg_stat::special::Normal as Special;
236let grind:Special = Special::Grind;
237```
238
239# Effect
240This composes the various Effects in-game related to a character's Stats
241
242
243# Attributes
244
245These are definitions of abstract terms into code
246
247## Rate
248Rate of occurance
249```
250use rpg_stat::attributes::Rate;
251let yes:Rate = Rate::Always;
252assert_eq!(yes.worked(), true);
253let no:Rate = Rate::None;
254assert_eq!(no.worked(), false);
255let hmmm:Rate = Rate::Some;
256// who knows....
257```
258
259## Effectiveness
260
261This effectiveness can be stored in a struct and you could implement a wrapper for `value(T)`:
262```
263use rpg_stat::attributes::{Effectiveness, Value};
264
265pub struct Item {
266    pub name:String,
267    pub amount:i32,
268    pub effectiveness:Effectiveness,
269}
270impl Item {
271    // much easier to use now!
272    pub fn value(&self) -> i32 {
273        self.effectiveness.value(self.amount)
274    }
275}
276```
277
278```
279use rpg_stat::attributes::{Effectiveness, Value};
280let hp:i32 = 50;
281// later on we use an item and check the effectiveness of it
282assert_eq!(Effectiveness::Half.value(hp), 25);
283
284```
285
286## Stage
287
288```
289use rpg_stat::attributes::Stage;
290
291```
292This includes the `Stage` of life.  This is similar to things like "evolution" in creature raising games, but based on reality.  In real life no creature evolves randomly in front of someone, however they do get older and change their "form".  There are eight forms:
293 * Baby
294 * Toddler
295 * Kid
296 * Teen
297 * Young
298 * Grown
299 * Older
300 * Old
301
302# Body
303This is to collect all the information about armor, stats, status, etc, based on each body part.  This will be some serious numeric control over the simulation.
304
305
306# RPG Stat command line tool
307 WIP
308 Ideally, this will use `clap` and support some very specific stat traits only.
309
310 AFAIK the interface will end up looking like:
311 `rpg_stat class normal Archer stat normal hp`
312 
313 That said none of the work has been started yet, and I am open to input.
314
315
316*/
317pub mod stats;
318pub mod class;
319pub mod creature;
320pub mod armor;
321pub mod body;
322pub mod types;
323pub mod random;
324pub mod equation;
325pub mod npc;
326pub mod special;
327pub mod attributes;
328pub mod effect;
329pub mod item;
330pub mod material;
331pub mod compass;
332pub mod chemistry;