Compare commits
9 Commits
fa3c80105f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02b74c8ee5 | ||
|
|
42831b71a1 | ||
|
|
8e3cecdc6a | ||
|
|
e94a802034 | ||
|
|
9130797eec | ||
|
|
61f7299e42 | ||
|
|
5bf7d3b1d8 | ||
|
|
dfc99e97e3 | ||
|
|
dcbdc29f78 |
27
src/rust/Cargo.lock → src/gmon/Cargo.lock
generated
27
src/rust/Cargo.lock → src/gmon/Cargo.lock
generated
@@ -237,6 +237,18 @@ version = "0.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
|
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gmon"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"futures",
|
||||||
|
"godot",
|
||||||
|
"mon",
|
||||||
|
"native_db",
|
||||||
|
"native_model",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "godot"
|
name = "godot"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
@@ -344,6 +356,10 @@ version = "2.7.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mon"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nanoserde"
|
name = "nanoserde"
|
||||||
version = "0.1.37"
|
version = "0.1.37"
|
||||||
@@ -436,17 +452,6 @@ version = "0.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mon"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"futures",
|
|
||||||
"godot",
|
|
||||||
"native_db",
|
|
||||||
"native_model",
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.93"
|
version = "1.0.93"
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "mon"
|
name = "gmon"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
@@ -9,6 +9,7 @@ godot = "0.2.4"
|
|||||||
native_db = "0.8.1"
|
native_db = "0.8.1"
|
||||||
native_model = "0.4.20"
|
native_model = "0.4.20"
|
||||||
serde = "1.0.218"
|
serde = "1.0.218"
|
||||||
|
mon = { path = "../mon" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
26
src/gmon/src/battle.rs
Normal file
26
src/gmon/src/battle.rs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
use ::mon::*;
|
||||||
|
use godot::classes::{ISprite2D, Sprite2D};
|
||||||
|
use godot::prelude::*;
|
||||||
|
|
||||||
|
pub type Instance = mon::battle::Instance;
|
||||||
|
pub type Team = mon::battle::Team;
|
||||||
|
pub type Event = mon::battle::Event;
|
||||||
|
pub type Move = mon::battle::Move;
|
||||||
|
|
||||||
|
#[derive(GodotClass)]
|
||||||
|
#[class(base=Sprite2D)]
|
||||||
|
struct Engine {
|
||||||
|
instance: mon::battle::Engine,
|
||||||
|
|
||||||
|
base: Base<Sprite2D>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[godot_api]
|
||||||
|
impl ISprite2D for Engine {
|
||||||
|
fn init(base: Base<Sprite2D>) -> Self {
|
||||||
|
Self {
|
||||||
|
instance: mon::battle::Engine::new(),
|
||||||
|
base: base,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/gmon/src/lib.rs
Executable file
9
src/gmon/src/lib.rs
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
use godot::prelude::*;
|
||||||
|
|
||||||
|
struct MyExtension;
|
||||||
|
|
||||||
|
#[gdextension]
|
||||||
|
unsafe impl ExtensionLibrary for MyExtension {}
|
||||||
|
|
||||||
|
pub mod battle;
|
||||||
|
pub mod mon;
|
||||||
5
src/gmon/src/mon.rs
Normal file
5
src/gmon/src/mon.rs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
use ::mon::*;
|
||||||
|
|
||||||
|
pub type Instance = mon::mon::Instance;
|
||||||
|
pub type Species = mon::mon::Species;
|
||||||
|
pub type Dex = mon::mon::Dex;
|
||||||
@@ -4,11 +4,11 @@ compatibility_minimum = 4.1
|
|||||||
reloadable = true
|
reloadable = true
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
linux.debug.x86_64 = "res://../rust/target/debug/libmon.so"
|
linux.debug.x86_64 = "res://../gmon/target/debug/libgmon.so"
|
||||||
linux.release.x86_64 = "res://../rust/target/release/libmon.so"
|
linux.release.x86_64 = "res://../gmon/target/release/libgmon.so"
|
||||||
windows.debug.x86_64 = "res://../rust/target/debug/mon.dll"
|
windows.debug.x86_64 = "res://../gmon/target/debug/gmon.dll"
|
||||||
windows.release.x86_64 = "res://../rust/target/release/mon.dll"
|
windows.release.x86_64 = "res://../gmon/target/release/gmon.dll"
|
||||||
macos.debug = "res://../rust/target/debug/libmon.dylib"
|
macos.debug = "res://../gmon/target/debug/libgmon.dylib"
|
||||||
macos.release = "res://../rust/target/release/libmon.dylib"
|
macos.release = "res://../gmon/target/release/libgmon.dylib"
|
||||||
macos.debug.arm64 = "res://../rust/target/debug/libmon.dylib"
|
macos.debug.arm64 = "res://../gmon/target/debug/libgmon.dylib"
|
||||||
macos.release.arm64 = "res://../rust/target/release/libmon.dylib"
|
macos.release.arm64 = "res://../gmon/target/release/libgmon.dylib"
|
||||||
|
|||||||
1
src/mon/src/lib.rs
Executable file
1
src/mon/src/lib.rs
Executable file
@@ -0,0 +1 @@
|
|||||||
|
pub mod mon;
|
||||||
@@ -150,11 +150,44 @@ pub mod battle {
|
|||||||
self.teams.push(Team::new(third));
|
self.teams.push(Team::new(third));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enqueue(&mut self, m: Move) {
|
pub fn enqueue(&mut self, m: Move) -> Result<(), String> {
|
||||||
|
match m {
|
||||||
|
Move::Attack(w_idx, r_idx) => {
|
||||||
|
if self.teams()[w_idx].lost {
|
||||||
|
return Err(format!("team[{w_idx}] lost"));
|
||||||
|
}
|
||||||
|
if !self.teams()[w_idx].any_can_attack() {
|
||||||
|
return Err(format!("team[{w_idx}] cannot attack"));
|
||||||
|
}
|
||||||
|
if !self.teams()[r_idx].any_can_be_attacked() {
|
||||||
|
return Err(format!("team[{r_idx}] cannot be attacked"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Move::Pass(team_idx) => {
|
||||||
|
if self.teams()[team_idx].lost {
|
||||||
|
return Err(format!("team[{team_idx}] lost"));
|
||||||
|
}
|
||||||
|
if !self.teams()[team_idx].any_can_attack() {
|
||||||
|
return Err(format!("team[{team_idx}] cannot move"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Move::Swap(team_idx, mon_idx) => {
|
||||||
|
if self.teams()[team_idx].lost {
|
||||||
|
return Err(format!("team[{team_idx}] lost"));
|
||||||
|
}
|
||||||
|
if !self.teams()[team_idx].mons()[mon_idx].alive() {
|
||||||
|
return Err(format!("team[{team_idx}].mons[{mon_idx}] cannot swap in"));
|
||||||
|
}
|
||||||
|
if self.teams()[team_idx].mons()[mon_idx].out {
|
||||||
|
return Err(format!("team[{team_idx}].mons[{mon_idx}] already in"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
self.q.push(m);
|
self.q.push(m);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exec(&mut self) {
|
pub fn exec(&mut self) -> Vec<Event> {
|
||||||
self.turn_order().iter().for_each(|idx| {
|
self.turn_order().iter().for_each(|idx| {
|
||||||
match self.q[*idx].clone() {
|
match self.q[*idx].clone() {
|
||||||
Move::Pass(_) => {}
|
Move::Pass(_) => {}
|
||||||
@@ -162,28 +195,30 @@ pub mod battle {
|
|||||||
let r_team = self.teams[r_team_idx].clone();
|
let r_team = self.teams[r_team_idx].clone();
|
||||||
let w_team = &mut self.teams[w_team_idx];
|
let w_team = &mut self.teams[w_team_idx];
|
||||||
|
|
||||||
for r_mon_idx in 0..r_team.mons.len() {
|
for r_mon_idx in 0..r_team.mons().len() {
|
||||||
let r_mon = &r_team.mons[r_mon_idx];
|
let r_mon = &r_team.mons()[r_mon_idx];
|
||||||
if !r_mon.can_attack() {
|
if !r_mon.can_attack() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for w_mon_idx in 0..w_team.mons.len() {
|
for w_mon_idx in 0..w_team.mons().len() {
|
||||||
let w_mon = &w_team.mons[w_mon_idx];
|
let w_mon = &w_team.mons()[w_mon_idx];
|
||||||
if !w_mon.can_be_attacked() {
|
if !w_mon.can_be_attacked() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let r_mon = &r_mon.mon;
|
let r_mon = &r_mon.mon;
|
||||||
let w_mon = &w_mon.mon;
|
let w_mon = &w_mon.mon;
|
||||||
w_team.mons[w_mon_idx].mon = Engine::attack(w_mon, r_mon);
|
w_team.mons[w_mon_idx].mon = Engine::attack(w_mon, r_mon);
|
||||||
|
w_team.mons[w_mon_idx].out =
|
||||||
|
w_team.mons[w_mon_idx].out && w_team.mons[w_mon_idx].alive()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.teams[w_team_idx] = w_team.to_owned();
|
self.teams[w_team_idx] = w_team.to_owned();
|
||||||
}
|
}
|
||||||
Move::Swap(to_idx) => {
|
Move::Swap(team_idx, mon_idx) => {
|
||||||
let mut team = self.teams[to_idx.team].clone();
|
let mut team = self.teams[team_idx].clone();
|
||||||
team.mons = team
|
team.mons = team
|
||||||
.mons
|
.mons()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|m| {
|
.map(|m| {
|
||||||
let mut m = m.clone();
|
let mut m = m.clone();
|
||||||
@@ -191,20 +226,47 @@ pub mod battle {
|
|||||||
m
|
m
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
team.mons[to_idx.mon].out = true;
|
team.mons[mon_idx].out = true;
|
||||||
self.teams[to_idx.team] = team;
|
self.teams[team_idx] = team;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
self.new_turn();
|
self.new_turn()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn teams(&self) -> Vec<Team> {
|
pub fn teams(&self) -> Vec<Team> {
|
||||||
self.teams.iter().map(|t| t.clone()).collect()
|
self.teams.iter().map(|t| t.clone()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_turn(&mut self) {
|
fn new_turn(&mut self) -> Vec<Event> {
|
||||||
self.q = vec![];
|
self.q = vec![];
|
||||||
|
|
||||||
|
let mut result = vec![];
|
||||||
|
|
||||||
|
let teams = self.teams();
|
||||||
|
let mut teams_not_lost = vec![];
|
||||||
|
for i in 0..teams.len() {
|
||||||
|
let has_mon_out = teams[i].mons().iter().filter(|m| m.out).count() > 0;
|
||||||
|
let has_mon_alive = teams[i].mons().iter().filter(|m| m.alive()).count() > 0;
|
||||||
|
let lost_before = teams[i].lost;
|
||||||
|
|
||||||
|
if !has_mon_out && has_mon_alive {
|
||||||
|
result.push(Event::MustSwap(i));
|
||||||
|
} else if !has_mon_alive && !lost_before {
|
||||||
|
self.teams[i].lost = true;
|
||||||
|
result.push(Event::Lose(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.teams()[i].lost {
|
||||||
|
teams_not_lost.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if teams_not_lost.len() == 1 {
|
||||||
|
result.push(Event::Win(teams_not_lost[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn turn_order(&self) -> Vec<usize> {
|
fn turn_order(&self) -> Vec<usize> {
|
||||||
@@ -214,7 +276,7 @@ pub mod battle {
|
|||||||
i,
|
i,
|
||||||
match &self.q[i] {
|
match &self.q[i] {
|
||||||
Move::Pass(_) => 0,
|
Move::Pass(_) => 0,
|
||||||
Move::Swap(_) => -10,
|
Move::Swap(_, _) => -10,
|
||||||
Move::Attack(r_team, _) => self.teams[r_team.to_owned()]
|
Move::Attack(r_team, _) => self.teams[r_team.to_owned()]
|
||||||
.mons
|
.mons
|
||||||
.iter()
|
.iter()
|
||||||
@@ -281,15 +343,17 @@ pub mod battle {
|
|||||||
engine.join(team_b());
|
engine.join(team_b());
|
||||||
|
|
||||||
// player 0 mon 0 attacks team 1 mon 0
|
// player 0 mon 0 attacks team 1 mon 0
|
||||||
engine.enqueue(Move::Attack(0, 1));
|
engine
|
||||||
|
.enqueue(Move::Attack(0, 1))
|
||||||
|
.expect("failed to attack");
|
||||||
// player 1 mon 0 passes
|
// player 1 mon 0 passes
|
||||||
engine.enqueue(Move::Pass(1));
|
engine.enqueue(Move::Pass(1)).expect("failed to pass");
|
||||||
// player 1 mon 1 not out
|
// player 1 mon 1 not out
|
||||||
engine.exec();
|
assert_eq!(0, engine.exec().len());
|
||||||
|
|
||||||
assert_eq!(0, engine.teams[0].mons[0].mon.damage);
|
assert_eq!(0, engine.teams()[0].mons()[0].mon.damage);
|
||||||
assert_eq!(1, engine.teams[1].mons[0].mon.damage);
|
assert_eq!(1, engine.teams()[1].mons()[0].mon.damage);
|
||||||
assert_eq!(0, engine.teams[1].mons[1].mon.damage);
|
assert_eq!(0, engine.teams()[1].mons()[1].mon.damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn team_a() -> Vec<mon::Instance> {
|
fn team_a() -> Vec<mon::Instance> {
|
||||||
@@ -307,6 +371,7 @@ pub mod battle {
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Team {
|
pub struct Team {
|
||||||
mons: Vec<Instance>,
|
mons: Vec<Instance>,
|
||||||
|
lost: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Team {
|
impl Team {
|
||||||
@@ -320,18 +385,29 @@ pub mod battle {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
mons[0].out = true;
|
mons[0].out = true;
|
||||||
Self { mons: mons }
|
Self {
|
||||||
|
mons: mons.clone(),
|
||||||
|
lost: mons.len() == 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mons(&self) -> Vec<Instance> {
|
pub fn mons(&self) -> Vec<Instance> {
|
||||||
self.mons.iter().map(|i| i.clone()).collect()
|
self.mons.iter().map(|i| i.clone()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn any_can_attack(&self) -> bool {
|
||||||
|
self.mons().iter().filter(|m| m.can_attack()).count() > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn any_can_be_attacked(&self) -> bool {
|
||||||
|
self.mons().iter().filter(|m| m.can_be_attacked()).count() > 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Instance {
|
pub struct Instance {
|
||||||
mon: mon::Instance,
|
pub mon: mon::Instance,
|
||||||
out: bool,
|
pub out: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Instance {
|
impl Instance {
|
||||||
@@ -372,17 +448,18 @@ pub mod battle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct Idx {
|
|
||||||
pub team: usize,
|
|
||||||
pub mon: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Move {
|
pub enum Move {
|
||||||
Pass(usize),
|
Pass(usize),
|
||||||
Attack(usize, usize),
|
Attack(usize, usize),
|
||||||
Swap(Idx),
|
Swap(usize, usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub enum Event {
|
||||||
|
MustSwap(usize),
|
||||||
|
Lose(usize),
|
||||||
|
Win(usize),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,9 +483,13 @@ mod mon_tests {
|
|||||||
let mut engine = battle::Engine::new(my_mons, they_mons);
|
let mut engine = battle::Engine::new(my_mons, they_mons);
|
||||||
|
|
||||||
// team0mon0 trades attacks with team1mon0
|
// team0mon0 trades attacks with team1mon0
|
||||||
engine.enqueue(battle::Move::Attack(1, 0));
|
engine
|
||||||
engine.enqueue(battle::Move::Attack(0, 1));
|
.enqueue(battle::Move::Attack(1, 0))
|
||||||
engine.exec();
|
.expect("failed to attack");
|
||||||
|
engine
|
||||||
|
.enqueue(battle::Move::Attack(0, 1))
|
||||||
|
.expect("failed to attack");
|
||||||
|
assert_eq!(0, engine.exec().len());
|
||||||
assert_eq!(6, engine.teams()[0].mons()[0].damage());
|
assert_eq!(6, engine.teams()[0].mons()[0].damage());
|
||||||
assert_eq!(0, engine.teams()[0].mons()[1].damage());
|
assert_eq!(0, engine.teams()[0].mons()[1].damage());
|
||||||
assert_eq!(1, engine.teams()[1].mons()[0].damage());
|
assert_eq!(1, engine.teams()[1].mons()[0].damage());
|
||||||
@@ -417,13 +498,77 @@ mod mon_tests {
|
|||||||
|
|
||||||
// team0mon0 swaps with team0mon0
|
// team0mon0 swaps with team0mon0
|
||||||
// team1mon0 attacks team0
|
// team1mon0 attacks team0
|
||||||
engine.enqueue(battle::Move::Attack(1, 0));
|
engine
|
||||||
engine.enqueue(battle::Move::Swap(battle::Idx { team: 0, mon: 1 }));
|
.enqueue(battle::Move::Attack(1, 0))
|
||||||
engine.exec();
|
.expect("failed to attack");
|
||||||
|
engine
|
||||||
|
.enqueue(battle::Move::Swap(0, 1))
|
||||||
|
.expect("failed to swap");
|
||||||
|
assert_eq!(0, engine.exec().len());
|
||||||
assert_eq!(6, engine.teams()[0].mons()[0].damage());
|
assert_eq!(6, engine.teams()[0].mons()[0].damage());
|
||||||
assert_eq!(1, engine.teams()[0].mons()[1].damage());
|
assert_eq!(1, engine.teams()[0].mons()[1].damage());
|
||||||
assert_eq!(1, engine.teams()[1].mons()[0].damage());
|
assert_eq!(1, engine.teams()[1].mons()[0].damage());
|
||||||
assert_eq!(0, engine.teams()[1].mons()[1].damage());
|
assert_eq!(0, engine.teams()[1].mons()[1].damage());
|
||||||
assert_eq!(0, engine.teams()[1].mons()[2].damage());
|
assert_eq!(0, engine.teams()[1].mons()[2].damage());
|
||||||
|
|
||||||
|
// team1mon0 wears down team0mon1
|
||||||
|
for i in 2..engine.teams()[0].mons()[1].mon.dex.hp() {
|
||||||
|
engine
|
||||||
|
.enqueue(battle::Move::Attack(1, 0))
|
||||||
|
.expect("failed to attack");
|
||||||
|
assert_eq!(0, engine.exec().len());
|
||||||
|
assert_eq!(i, engine.teams()[0].mons()[1].damage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// team1mon0 downs team0mon1
|
||||||
|
engine
|
||||||
|
.enqueue(battle::Move::Attack(1, 0))
|
||||||
|
.expect("failed to kill");
|
||||||
|
let turn_results = engine.exec();
|
||||||
|
assert_eq!(1, turn_results.len());
|
||||||
|
assert_eq!(battle::Event::MustSwap(0), turn_results[0]);
|
||||||
|
assert_eq!(
|
||||||
|
engine.teams()[0].mons()[1].mon.dex.hp(),
|
||||||
|
engine.teams()[0].mons()[1].damage()
|
||||||
|
);
|
||||||
|
assert!(!engine.teams()[0].mons()[1].out);
|
||||||
|
|
||||||
|
// team0 must swap
|
||||||
|
assert!(engine.enqueue(battle::Move::Attack(0, 1)).is_err());
|
||||||
|
assert!(engine.enqueue(battle::Move::Pass(0)).is_err());
|
||||||
|
engine
|
||||||
|
.enqueue(battle::Move::Swap(0, 0))
|
||||||
|
.expect("failed to swap on MustSwap");
|
||||||
|
assert!(engine.enqueue(battle::Move::Attack(1, 0)).is_err());
|
||||||
|
assert_eq!(0, engine.exec().len());
|
||||||
|
|
||||||
|
// team1mon0 wears down team0mon0
|
||||||
|
for i in 7..engine.teams()[0].mons()[0].mon.dex.hp() {
|
||||||
|
engine
|
||||||
|
.enqueue(battle::Move::Attack(1, 0))
|
||||||
|
.expect("failed to attack");
|
||||||
|
assert_eq!(0, engine.exec().len());
|
||||||
|
assert_eq!(i, engine.teams()[0].mons()[0].damage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// team1mon0 downs team0mon0
|
||||||
|
// team0 loses
|
||||||
|
// team1 wins
|
||||||
|
engine
|
||||||
|
.enqueue(battle::Move::Attack(1, 0))
|
||||||
|
.expect("failed to kill");
|
||||||
|
let turn_results = engine.exec();
|
||||||
|
assert_eq!(2, turn_results.len(), "{:?}", turn_results);
|
||||||
|
assert_eq!(
|
||||||
|
battle::Event::Lose(0),
|
||||||
|
turn_results[0],
|
||||||
|
"{:?}",
|
||||||
|
turn_results
|
||||||
|
);
|
||||||
|
assert_eq!(battle::Event::Win(1), turn_results[1], "{:?}", turn_results);
|
||||||
|
assert_eq!(
|
||||||
|
engine.teams()[0].mons()[0].mon.dex.hp(),
|
||||||
|
engine.teams()[0].mons()[0].damage()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
pub mod src;
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use godot::prelude::*;
|
|
||||||
|
|
||||||
struct MyExtension;
|
|
||||||
|
|
||||||
#[gdextension]
|
|
||||||
unsafe impl ExtensionLibrary for MyExtension {
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod src;
|
|
||||||
Reference in New Issue
Block a user