mob modes
This commit is contained in:
parent
aaf2991a13
commit
9fa2a94ade
@ -17,6 +17,10 @@ strangle
|
||||
## SOON
|
||||
* aoe skills
|
||||
|
||||
* hash cryp name for avatar
|
||||
|
||||
* order cryps based on id
|
||||
|
||||
* keep track of games joined
|
||||
* concede game on leave
|
||||
* ko all cryps on team, check status
|
||||
@ -28,6 +32,8 @@ strangle
|
||||
* skills
|
||||
* private fields for opponents
|
||||
|
||||
* flavour text
|
||||
|
||||
## LATER
|
||||
* redis for game events
|
||||
* chat
|
||||
|
||||
@ -117,7 +117,7 @@ impl Cryp {
|
||||
hp: CrypStat { base: 0, stat: Stat::Hp },
|
||||
lvl: 0,
|
||||
xp: 0,
|
||||
skills: vec![CrypSkill::new(Skill::Attack)],
|
||||
skills: vec![],
|
||||
effects: vec![],
|
||||
name: String::new(),
|
||||
ko_logged: false,
|
||||
@ -268,6 +268,23 @@ impl Cryp {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn mob_select_skill(&self) -> Option<Skill> {
|
||||
let available = self.available_skills();
|
||||
|
||||
if available.len() == 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let highest_cd = available.iter()
|
||||
.filter(|s| s.skill.base_cd().is_some())
|
||||
.max_by_key(|s| s.skill.base_cd().unwrap());
|
||||
|
||||
return match highest_cd {
|
||||
Some(s) => Some(s.skill),
|
||||
None => Some(available[0].skill),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn knows(&self, skill: Skill) -> bool {
|
||||
self.skills.iter().any(|s| s.skill == skill)
|
||||
}
|
||||
@ -499,6 +516,7 @@ pub fn cryp_get(tx: &mut Transaction, id: Uuid, account_id: Uuid) -> Result<Cryp
|
||||
pub fn cryp_spawn(params: CrypSpawnParams, tx: &mut Transaction, account: &Account) -> Result<Cryp, Error> {
|
||||
let cryp = Cryp::new()
|
||||
.named(¶ms.name)
|
||||
.learn(Skill::Attack)
|
||||
.level(10)
|
||||
.set_account(account.id)
|
||||
.create();
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
use uuid::Uuid;
|
||||
use rand::prelude::*;
|
||||
use rand::distributions::Alphanumeric;
|
||||
|
||||
use std::iter;
|
||||
use uuid::Uuid;
|
||||
|
||||
// Db Commons
|
||||
use serde_cbor::{from_slice, to_vec};
|
||||
@ -16,15 +13,10 @@ use cryp::{Cryp, cryp_get};
|
||||
use skill::{Skill, Cast, ResolutionResult};
|
||||
use item::{item_drop};
|
||||
use zone::{node_finish};
|
||||
use mob::{PveMode, generate_mob_team};
|
||||
|
||||
pub type Log = Vec<String>;
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub enum PveMode {
|
||||
Boss,
|
||||
Normal,
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub struct Team {
|
||||
pub id: Uuid,
|
||||
@ -214,13 +206,27 @@ impl Game {
|
||||
let mob_team_id = Uuid::nil();
|
||||
let mobs = self.team_by_id(mob_team_id).clone();
|
||||
|
||||
// TODO attack multiple players based on some criteria
|
||||
let player_team = self.teams.iter().find(|t| t.id != mob_team_id).unwrap().clone();
|
||||
let player_len = player_team.cryps.len();
|
||||
|
||||
for (i, mob) in mobs.cryps.iter().enumerate() {
|
||||
// doesn't matter if the cryp can't cast
|
||||
self.add_skill(mob_team_id, mob.id, Some(player_team.cryps[player_len % (i + 1)].id), Skill::Attack).ok();
|
||||
for mob in mobs.cryps.iter() {
|
||||
let skill = mob.mob_select_skill();
|
||||
// println!("{:?} {:?}", mob.name, skill);
|
||||
match skill {
|
||||
Some(s) => {
|
||||
let mut rng = thread_rng();
|
||||
let mut target = &player_team.cryps[rng.gen_range(0, player_len)];
|
||||
while target.is_ko() {
|
||||
target = &player_team.cryps[rng.gen_range(0, player_len)];
|
||||
}
|
||||
match self.add_skill(mob_team_id, mob.id, Some(target.id), s) {
|
||||
Ok(_) => (),
|
||||
Err(e) => println!("{:?} could not add pve skill", e),
|
||||
}
|
||||
// println!("{:?}", cast);
|
||||
},
|
||||
None => continue,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,10 +248,15 @@ impl Game {
|
||||
|
||||
// target checks
|
||||
{
|
||||
let _target = match self.cryp_by_id(final_target_id) {
|
||||
let target = match self.cryp_by_id(final_target_id) {
|
||||
Some(c) => c,
|
||||
None => return Err(err_msg("target cryp not in game")),
|
||||
};
|
||||
|
||||
// fixme for rez
|
||||
if target.is_ko() {
|
||||
return Err(err_msg("target cryp is ko"));
|
||||
}
|
||||
}
|
||||
|
||||
// cryp checks
|
||||
@ -275,12 +286,6 @@ impl Game {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME
|
||||
// let (target_cryp_id, target_team_id) = match skill.self_targeting() {
|
||||
// true => (Some(source_cryp_id), source_team_id),
|
||||
// false => (None, target_team_id.unwrap())
|
||||
// };
|
||||
|
||||
// replace cryp skill
|
||||
if let Some(s) = self.stack.iter_mut().position(|s| s.source_cryp_id == source_cryp_id) {
|
||||
self.stack.remove(s);
|
||||
@ -304,129 +309,6 @@ impl Game {
|
||||
)
|
||||
}
|
||||
|
||||
// fn target_phase_start(&mut self) -> &mut Game {
|
||||
// assert!(self.skill_phase_finished());
|
||||
// self.log.push("<Target Phase>".to_string());
|
||||
|
||||
// if self.phase != Phase::Skill {
|
||||
// panic!("game not in skill phase");
|
||||
// }
|
||||
|
||||
// self.phase = Phase::Target;
|
||||
|
||||
// if self.is_pve {
|
||||
// self.pve_add_targets();
|
||||
// }
|
||||
|
||||
// // all cryps are stunned or otherwise inactive
|
||||
// if self.target_phase_finished() {
|
||||
// self.resolve_phase_start();
|
||||
// }
|
||||
|
||||
// self
|
||||
// }
|
||||
|
||||
// fn pve_add_targets(&mut self) -> &mut Game {
|
||||
// {
|
||||
// let mob_team_id = Uuid::nil();
|
||||
// let mobs = self.team_by_id(mob_team_id).clone();
|
||||
|
||||
// // TODO attack multiple players based on some criteria
|
||||
// for (i, incoming_skill_id) in self.stack.clone().iter()
|
||||
// .filter(|s| s.target_cryp_id.is_none() && s.target_team_id == mob_team_id)
|
||||
// .enumerate()
|
||||
// .map(|(i, s)| (i, s.id)) {
|
||||
// let targets = mobs.cryps
|
||||
// .iter()
|
||||
// .filter(|c| self.cryp_targetable(mob_team_id, c.id).is_ok())
|
||||
// .collect::<Vec<&Cryp>>();
|
||||
|
||||
// if targets.len() == 0 {
|
||||
// panic!("could not find a targetable pve cryp");
|
||||
// }
|
||||
|
||||
// let target_id = targets[i % targets.len()].id;
|
||||
// self.add_target(mob_team_id, target_id, incoming_skill_id).unwrap();
|
||||
// }
|
||||
// }
|
||||
|
||||
// self
|
||||
// }
|
||||
|
||||
// each cryp can be the target of
|
||||
// incomingSkills / activeCryps rounded up
|
||||
// maybe a problem with friendly / self targeting skills
|
||||
fn cryp_targetable(&mut self, team_id: Uuid, cryp_id: Uuid) -> Result<(), Error> {
|
||||
// whose team is this?
|
||||
let team = self.teams.iter()
|
||||
.find(|t| t.id == team_id)
|
||||
.ok_or(err_msg("team not found"))?;
|
||||
|
||||
// is the target in the team?
|
||||
let cryp = team.cryps.iter()
|
||||
.find(|c| c.id == cryp_id)
|
||||
.ok_or(err_msg("cryp not in team"))?;
|
||||
|
||||
if cryp.is_ko() {
|
||||
return Err(err_msg("you cannot target ko cryps"));
|
||||
}
|
||||
|
||||
// let incoming = self.stack.iter()
|
||||
// .filter(|i| i.target_team_id == team.id)
|
||||
// .count();
|
||||
|
||||
// let incoming = incoming as u32 as f64;
|
||||
|
||||
// let active_cryps = team.cryps.iter()
|
||||
// .filter(|c| !c.is_ko())
|
||||
// .count();
|
||||
|
||||
// let active_cryps = active_cryps as u32 as f64;
|
||||
// let max_targets = (incoming / active_cryps).ceil();
|
||||
|
||||
// // println!("targets {:} / {:} = {:}", incoming, active_cryps, max_targets);
|
||||
|
||||
// let targeted = self.stack.iter()
|
||||
// .filter(|s| s.target_cryp_id.is_some())
|
||||
// .filter(|s| s.target_cryp_id.unwrap() == cryp_id)
|
||||
// .count();
|
||||
|
||||
// if targeted >= max_targets as usize {
|
||||
// return Err(format_err!("cryp target of maximum number of skills ({:})", max_targets));
|
||||
// }
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// targets can only be added by the owner of the team
|
||||
// fn add_target(&mut self, team_id: Uuid, cryp_id: Uuid, skill_id: Uuid) -> Result<&mut Cast, Error> {
|
||||
// if self.phase != Phase::Target {
|
||||
// return Err(err_msg("game not in target phase"));
|
||||
// }
|
||||
|
||||
// self.cryp_targetable(team_id, cryp_id)?;
|
||||
|
||||
// // set the target
|
||||
// let cast = match self.stack.iter_mut().find(|s| s.id == skill_id) {
|
||||
// Some(c) => c,
|
||||
// None => return Err(err_msg("skill_id not found")),
|
||||
// };
|
||||
|
||||
// if cast.skill.self_targeting() {
|
||||
// return Err(err_msg("skill is self targeting"));
|
||||
// }
|
||||
|
||||
// if cast.target_team_id != team_id {
|
||||
// return Err(err_msg("you cannot target that skill"));
|
||||
// }
|
||||
|
||||
// Ok(cast.set_target(cryp_id))
|
||||
// }
|
||||
|
||||
// fn target_phase_finished(&self) -> bool {
|
||||
// self.stack.iter().all(|s| s.target_cryp_id.is_some())
|
||||
// }
|
||||
|
||||
// requires no input
|
||||
// just do it
|
||||
fn resolve_phase_start(&mut self) -> &mut Game {
|
||||
@ -760,52 +642,6 @@ pub fn game_update(game: &Game, tx: &mut Transaction) -> Result<(), Error> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn generate_mob(lvl: u8) -> Cryp {
|
||||
let mut rng = thread_rng();
|
||||
|
||||
let name: String = iter::repeat(())
|
||||
.map(|()| rng.sample(Alphanumeric))
|
||||
.take(8)
|
||||
.collect();
|
||||
|
||||
// rng panics on min == max
|
||||
// let mob_lvl: u8 = match lvl {
|
||||
// 1 => 1,
|
||||
// _ => rng.gen_range(lvl.saturating_sub(2), lvl)
|
||||
// };
|
||||
|
||||
return Cryp::new()
|
||||
.named(&name)
|
||||
.level(lvl)
|
||||
.create();
|
||||
|
||||
}
|
||||
|
||||
fn generate_mob_team(mode: PveMode, cryps: &Vec<Cryp>) -> Team {
|
||||
let mut mob_team = Team::new(Uuid::nil());
|
||||
|
||||
// Default settings
|
||||
let mut team_size = 1;
|
||||
|
||||
// Modify the NPC cryps for game mode settings
|
||||
let mob_lvl = match mode {
|
||||
PveMode::Normal => {
|
||||
team_size = cryps.len();
|
||||
cryps.iter().max_by_key(|c| c.lvl).unwrap().lvl
|
||||
},
|
||||
PveMode::Boss => cryps.iter().max_by_key(|c| c.lvl).unwrap().lvl + 2,
|
||||
};
|
||||
|
||||
// Generate and return the NPC team based on settings
|
||||
let mobs = iter::repeat_with(|| generate_mob(mob_lvl).set_account(Uuid::nil()))
|
||||
.take(team_size)
|
||||
.collect::<Vec<Cryp>>();
|
||||
mob_team.set_cryps(mobs);
|
||||
|
||||
return mob_team;
|
||||
|
||||
}
|
||||
|
||||
pub fn game_pve_new(cryp_ids: Vec<Uuid>, mode: PveMode, tx: &mut Transaction, account: &Account) -> Result<Game, Error> {
|
||||
let cryps = cryp_ids
|
||||
.iter()
|
||||
@ -948,6 +784,7 @@ mod tests {
|
||||
let x = Cryp::new()
|
||||
.named(&"pronounced \"creeep\"".to_string())
|
||||
.level(8)
|
||||
.learn(Skill::Attack)
|
||||
.learn(Skill::TestStun)
|
||||
.learn(Skill::TestTouch)
|
||||
.learn(Skill::TestBlock)
|
||||
@ -960,6 +797,7 @@ mod tests {
|
||||
let y = Cryp::new()
|
||||
.named(&"lemongrass tea".to_string())
|
||||
.level(8)
|
||||
.learn(Skill::Attack)
|
||||
.learn(Skill::TestStun)
|
||||
.learn(Skill::TestTouch)
|
||||
.learn(Skill::TestBlock)
|
||||
@ -1001,24 +839,28 @@ mod tests {
|
||||
let i = Cryp::new()
|
||||
.named(&"pretaliate".to_string())
|
||||
.level(8)
|
||||
.learn(Skill::Attack)
|
||||
.learn(Skill::TestTouch)
|
||||
.create();
|
||||
|
||||
let j = Cryp::new()
|
||||
.named(&"poy sian".to_string())
|
||||
.level(8)
|
||||
.learn(Skill::Attack)
|
||||
.learn(Skill::TestTouch)
|
||||
.create();
|
||||
|
||||
let x = Cryp::new()
|
||||
.named(&"pronounced \"creeep\"".to_string())
|
||||
.level(8)
|
||||
.learn(Skill::Attack)
|
||||
.learn(Skill::TestTouch)
|
||||
.create();
|
||||
|
||||
let y = Cryp::new()
|
||||
.named(&"lemongrass tea".to_string())
|
||||
.level(8)
|
||||
.learn(Skill::Attack)
|
||||
.learn(Skill::TestTouch)
|
||||
.create();
|
||||
|
||||
@ -1113,8 +955,6 @@ mod tests {
|
||||
assert!(game.skill_phase_finished());
|
||||
game.resolve_phase_start();
|
||||
|
||||
// resolution should have been prevented by KO
|
||||
// println!("{:#?}", game);
|
||||
assert!(!game.team_by_id(y_team.id).cryps[0].is_stunned());
|
||||
assert!(game.phase == Phase::Finish);
|
||||
}
|
||||
@ -1220,18 +1060,20 @@ mod tests {
|
||||
// kill a cryp
|
||||
game.team_by_id(i_team.id).cryp_by_id(i_cryp.id).unwrap().hp.reduce(u64::max_value());
|
||||
|
||||
assert!(game.team_by_id(i_team.id).skills_required() == 1);
|
||||
assert!(game.team_by_id(x_team.id).skills_required() == 2);
|
||||
|
||||
// add some more skills
|
||||
game.add_skill(i_team.id, j_cryp.id, Some(x_cryp.id), Skill::TestTouch).unwrap();
|
||||
game.add_skill(x_team.id, x_cryp.id, Some(i_cryp.id), Skill::TestTouch).unwrap();
|
||||
game.add_skill(x_team.id, y_cryp.id, Some(i_cryp.id), Skill::TestTouch).unwrap();
|
||||
game.add_skill(x_team.id, x_cryp.id, Some(j_cryp.id), Skill::TestTouch).unwrap();
|
||||
game.add_skill(x_team.id, y_cryp.id, Some(j_cryp.id), Skill::TestTouch).unwrap();
|
||||
assert!(game.add_skill(x_team.id, x_cryp.id, Some(i_cryp.id), Skill::TestTouch).is_err());
|
||||
|
||||
assert!(game.skill_phase_finished());
|
||||
game.resolve_phase_start();
|
||||
|
||||
assert!(game.team_by_id(i_team.id).skills_required() == 1);
|
||||
assert!(game.cryp_targetable(i_team.id, i_cryp.id).is_err());
|
||||
assert!(game.cryp_targetable(i_team.id, j_cryp.id).is_ok());
|
||||
|
||||
assert!(game.team_by_id(x_team.id).skills_required() == 2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@ mod rpc;
|
||||
mod account;
|
||||
mod item;
|
||||
mod zone;
|
||||
mod mob;
|
||||
|
||||
use dotenv::dotenv;
|
||||
use net::{start};
|
||||
|
||||
152
server/src/mob.rs
Normal file
152
server/src/mob.rs
Normal file
@ -0,0 +1,152 @@
|
||||
use uuid::Uuid;
|
||||
|
||||
use rand::prelude::*;
|
||||
use rand::distributions::Alphanumeric;
|
||||
use std::iter;
|
||||
|
||||
use cryp::{Cryp};
|
||||
use game::{Team};
|
||||
use skill::{Skill};
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub enum PveMode {
|
||||
Boss,
|
||||
Normal,
|
||||
Zone3v2Attack,
|
||||
Zone2v2Caster,
|
||||
Zone3v3MeleeMiniboss,
|
||||
Zone3v3HealerBoss,
|
||||
}
|
||||
|
||||
fn generate_mob(lvl: u8) -> Cryp {
|
||||
let mut rng = thread_rng();
|
||||
|
||||
let name: String = iter::repeat(())
|
||||
.map(|()| rng.sample(Alphanumeric))
|
||||
.take(8)
|
||||
.collect();
|
||||
|
||||
// rng panics on min == max
|
||||
// let mob_lvl: u8 = match lvl {
|
||||
// 1 => 1,
|
||||
// _ => rng.gen_range(lvl.saturating_sub(2), lvl)
|
||||
// };
|
||||
|
||||
return Cryp::new()
|
||||
.named(&name)
|
||||
.level(lvl)
|
||||
.create();
|
||||
}
|
||||
|
||||
fn quick_game(mob_lvl: u8, team_size: usize) -> Vec<Cryp> {
|
||||
iter::repeat_with(||
|
||||
generate_mob(mob_lvl)
|
||||
.set_account(Uuid::nil())
|
||||
.learn(Skill::Attack))
|
||||
.take(team_size)
|
||||
.collect::<Vec<Cryp>>()
|
||||
}
|
||||
|
||||
fn zone_3v2_attack(player_lvl: u8) -> Vec<Cryp> {
|
||||
let x = Cryp::new()
|
||||
.named(&"hench".to_string())
|
||||
.level(player_lvl)
|
||||
.learn(Skill::Attack)
|
||||
.create();
|
||||
|
||||
let y = Cryp::new()
|
||||
.named(&"bench".to_string())
|
||||
.level(player_lvl)
|
||||
.learn(Skill::Attack)
|
||||
.create();
|
||||
|
||||
return vec![x, y];
|
||||
}
|
||||
|
||||
fn zone_2v2_caster(player_lvl: u8) -> Vec<Cryp> {
|
||||
let x = Cryp::new()
|
||||
.named(&"robe".to_string())
|
||||
.level(player_lvl)
|
||||
.learn(Skill::Blast)
|
||||
.create();
|
||||
|
||||
let y = Cryp::new()
|
||||
.named(&"wizard hat".to_string())
|
||||
.level(player_lvl)
|
||||
.learn(Skill::Blast)
|
||||
.create();
|
||||
|
||||
return vec![x, y];
|
||||
}
|
||||
|
||||
fn zone_3v3_melee_miniboss(player_lvl: u8) -> Vec<Cryp> {
|
||||
let x = Cryp::new()
|
||||
.named(&"jungle juice".to_string())
|
||||
.level(player_lvl)
|
||||
.learn(Skill::Attack)
|
||||
.create();
|
||||
|
||||
let y = Cryp::new()
|
||||
.named(&"bamboo basher".to_string())
|
||||
.level(player_lvl)
|
||||
.learn(Skill::Attack)
|
||||
.learn(Skill::Stun)
|
||||
.create();
|
||||
|
||||
let z = Cryp::new()
|
||||
.named(&"lemongrass tea".to_string())
|
||||
.level(player_lvl)
|
||||
.learn(Skill::Attack)
|
||||
.create();
|
||||
|
||||
return vec![x, y, z];
|
||||
}
|
||||
|
||||
fn zone_3v3_healer_boss(player_lvl: u8) -> Vec<Cryp> {
|
||||
let x = Cryp::new()
|
||||
.named(&"coinage".to_string())
|
||||
.level(player_lvl)
|
||||
.learn(Skill::Attack)
|
||||
.learn(Skill::Block)
|
||||
.create();
|
||||
|
||||
let y = Cryp::new()
|
||||
.named(&"wololo".to_string())
|
||||
.level(player_lvl + 1)
|
||||
// big strong
|
||||
// .learn(Skill::Blast)
|
||||
.learn(Skill::Heal)
|
||||
.learn(Skill::Triage)
|
||||
.create();
|
||||
|
||||
let z = Cryp::new()
|
||||
.named(&"quarry".to_string())
|
||||
.level(player_lvl)
|
||||
.learn(Skill::Attack)
|
||||
.learn(Skill::Stun)
|
||||
.create();
|
||||
|
||||
return vec![x, y, z];
|
||||
}
|
||||
|
||||
|
||||
pub fn generate_mob_team(mode: PveMode, cryps: &Vec<Cryp>) -> Team {
|
||||
let mut mob_team = Team::new(Uuid::nil());
|
||||
|
||||
let cryp_lvl = cryps.iter().max_by_key(|c| c.lvl).unwrap().lvl;
|
||||
let team_size = cryps.len();
|
||||
|
||||
let mobs = match mode {
|
||||
PveMode::Normal => quick_game(cryp_lvl, team_size),
|
||||
PveMode::Boss => quick_game(cryp_lvl + 2, 1),
|
||||
PveMode::Zone3v2Attack => zone_3v2_attack(cryp_lvl),
|
||||
PveMode::Zone2v2Caster => zone_2v2_caster(cryp_lvl),
|
||||
PveMode::Zone3v3MeleeMiniboss => zone_3v3_melee_miniboss(cryp_lvl),
|
||||
PveMode::Zone3v3HealerBoss => zone_3v3_healer_boss(cryp_lvl),
|
||||
};
|
||||
|
||||
mob_team.set_cryps(mobs);
|
||||
|
||||
return mob_team;
|
||||
|
||||
}
|
||||
@ -16,11 +16,12 @@ use failure::err_msg;
|
||||
|
||||
use net::Db;
|
||||
use cryp::{Cryp, cryp_spawn, cryp_learn, cryp_forget};
|
||||
use game::{Game, PveMode, game_state, game_pve, game_pvp, game_join, game_joinable_list, game_skill};
|
||||
use game::{Game, game_state, game_pve, game_pvp, game_join, game_joinable_list, game_skill};
|
||||
use account::{Account, account_create, account_login, account_from_token, account_cryps, account_zone};
|
||||
use item::{Item, items_list, item_use};
|
||||
use skill::{Skill};
|
||||
use zone::{Zone, zone_create, zone_join, zone_close};
|
||||
use mob::{PveMode};
|
||||
|
||||
pub struct Rpc;
|
||||
|
||||
|
||||
@ -9,8 +9,9 @@ use postgres::transaction::Transaction;
|
||||
use failure::Error;
|
||||
use failure::err_msg;
|
||||
|
||||
use game::{Game, PveMode, game_pve_new, game_write};
|
||||
use game::{Game, game_pve_new, game_write};
|
||||
use rpc::{ZoneJoinParams, ZoneCloseParams};
|
||||
use mob::{PveMode};
|
||||
|
||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||
pub struct Zone {
|
||||
@ -140,20 +141,28 @@ pub fn zone_update(zone: &Zone, tx: &mut Transaction) -> Result<(), Error> {
|
||||
|
||||
pub fn zone_join(params: ZoneJoinParams, tx: &mut Transaction, account: &Account) -> Result<Game, Error> {
|
||||
let mut zone = zone_get(tx, params.zone_id)?;
|
||||
let mut game;
|
||||
|
||||
// check node joinable
|
||||
node_joinable(&zone.graph, NodeIndex::from(params.node_id))?;
|
||||
|
||||
let mut game = game_pve_new(params.cryp_ids, PveMode::Normal, tx, account)?;
|
||||
game.set_zone(zone.id, params.node_id);
|
||||
|
||||
// borrow zone to update the encounter
|
||||
// borrow zone.graph to make the game
|
||||
{
|
||||
let node_index = NodeIndex::from(params.node_id);
|
||||
let encounter = zone.graph
|
||||
.node_weight_mut(node_index)
|
||||
.ok_or(err_msg("invalid encounter id"))?;
|
||||
|
||||
let mode = match encounter.tag.as_ref() {
|
||||
"ZONE0" => PveMode::Zone3v2Attack,
|
||||
"ZONE1" => PveMode::Zone2v2Caster,
|
||||
"ZONE2" => PveMode::Zone3v3MeleeMiniboss,
|
||||
"BOSS" => PveMode::Zone3v3HealerBoss,
|
||||
_ => return Err(err_msg("unknown zone tag")),
|
||||
};
|
||||
game = game_pve_new(params.cryp_ids, mode, tx, account)?;
|
||||
game.set_zone(zone.id, params.node_id);
|
||||
|
||||
encounter.game_id = Some(game.id);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user