Merge branch 'master' of ssh://cryps.gg:40022/~/cryps

This commit is contained in:
Mashy 2019-01-13 18:49:40 +10:00
commit e0660c31a3
10 changed files with 109 additions and 60 deletions

View File

@ -114,7 +114,7 @@ class MenuNavigation extends Phaser.Scene {
.setOrigin(0) .setOrigin(0)
.on('pointerdown', () => { .on('pointerdown', () => {
const team = this.registry.get('cryps').filter(c => c.active).map(c => c.id); const team = this.registry.get('cryps').filter(c => c.active).map(c => c.id);
ws.sendGamePve(team, 'Normal'); ws.sendGamePve(team);
return this.scene.restart(); return this.scene.restart();
}); });
this.add this.add

View File

@ -25,7 +25,7 @@ strangle
## NOW ## NOW
* rolls as a drop item * rolls as a drop item
* evasion is a % function of the hp value * check zone completion
## SOON ## SOON
* clean up categories * clean up categories

View File

@ -188,6 +188,9 @@ impl Cryp {
let stat_min = 128u64.saturating_mul(self.lvl.into()); let stat_min = 128u64.saturating_mul(self.lvl.into());
let stat_max = 256u64.saturating_mul(self.lvl.into()); let stat_max = 256u64.saturating_mul(self.lvl.into());
let evasion_min = 1u64;
let evasion_max = 25;
match stat { match stat {
Stat::PhysicalDamage => self.phys_dmg.set(rng.gen_range(stat_min, stat_max)), Stat::PhysicalDamage => self.phys_dmg.set(rng.gen_range(stat_min, stat_max)),
Stat::SpellDamage => self.spell_dmg.set(rng.gen_range(stat_min, stat_max)), Stat::SpellDamage => self.spell_dmg.set(rng.gen_range(stat_min, stat_max)),
@ -196,6 +199,9 @@ impl Cryp {
self.stamina.set(rng.gen_range(stam_min, stam_max)); self.stamina.set(rng.gen_range(stam_min, stam_max));
self.hp.set(self.stamina.base) self.hp.set(self.stamina.base)
}, },
Stat::SpellShield => self.spell_shield.set(rng.gen_range(stat_min, stat_max)),
Stat::Armour => self.armour.set(rng.gen_range(stat_min, stat_max)),
Stat::Evasion => self.evasion.set(rng.gen_range(evasion_min, evasion_max)),
_ => panic!("{:?} not a rollable stat", stat), _ => panic!("{:?} not a rollable stat", stat),
}; };
@ -525,15 +531,14 @@ impl Cryp {
} }
pub fn evade(&self, skill: Skill) -> Option<ResolutionResult> { pub fn evade(&self, skill: Skill) -> Option<ResolutionResult> {
let mut rng = thread_rng(); if self.evasion.base == 0 {
let hp_pct = (self.hp.base * 100) / self.stamina.base;
let evasion_rating = (self.evasion.base * hp_pct) / 100;
println!("{:?}", evasion_rating);
if evasion_rating == 0 {
return None; return None;
} }
let mut rng = thread_rng();
let hp_pct = (self.hp.base * 100) / self.stamina.base;
let evasion_rating = (self.evasion.base * hp_pct) / 100;
// println!("{:?}", evasion_rating);
let roll = rng.gen_range(0, 100); let roll = rng.gen_range(0, 100);
match roll > evasion_rating { match roll > evasion_rating {

View File

@ -13,7 +13,7 @@ use cryp::{Cryp, cryp_get};
use skill::{Skill, Cast, ResolutionResult}; use skill::{Skill, Cast, ResolutionResult};
use item::{item_drop}; use item::{item_drop};
use zone::{node_finish}; use zone::{node_finish};
use mob::{PveMode, generate_mob_team}; use mob::{generate_mob_team};
pub type Log = Vec<String>; pub type Log = Vec<String>;
@ -60,6 +60,16 @@ pub enum Phase {
Finish, Finish,
} }
#[derive(Debug,Clone,Copy,Serialize,Deserialize)]
pub enum GameMode {
Normal,
Pvp,
Zone3v2Attack,
Zone2v2Caster,
Zone3v3MeleeMiniboss,
Zone3v3HealerBoss,
}
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Game { pub struct Game {
pub id: Uuid, pub id: Uuid,
@ -72,6 +82,7 @@ pub struct Game {
pub resolved: Vec<Cast>, pub resolved: Vec<Cast>,
pub log: Vec<String>, pub log: Vec<String>,
pub zone: Option<(Uuid, u32)>, pub zone: Option<(Uuid, u32)>,
pub mode: GameMode,
} }
impl Game { impl Game {
@ -87,6 +98,7 @@ impl Game {
resolved: vec![], resolved: vec![],
log: vec![], log: vec![],
zone: None, zone: None,
mode: GameMode::Normal,
}; };
} }
@ -110,6 +122,11 @@ impl Game {
self self
} }
pub fn set_mode(&mut self, mode: GameMode) -> &mut Game {
self.mode = mode;
self
}
fn already_joined(&self, team_id: Uuid) -> bool { fn already_joined(&self, team_id: Uuid) -> bool {
self.teams.iter().any(|t| t.id == team_id) self.teams.iter().any(|t| t.id == team_id)
} }
@ -670,7 +687,7 @@ pub fn game_update(game: &Game, tx: &mut Transaction) -> Result<(), Error> {
if game.finished() { if game.finished() {
if let Some(t) = game.winner() { if let Some(t) = game.winner() {
if !t.id.is_nil() { if !t.id.is_nil() {
item_drop(tx, t.id)?; item_drop(tx, t.id, game.mode)?;
} }
} }
@ -684,7 +701,7 @@ pub fn game_update(game: &Game, tx: &mut Transaction) -> Result<(), Error> {
return Ok(()); return Ok(());
} }
pub fn game_pve_new(cryp_ids: Vec<Uuid>, mode: PveMode, tx: &mut Transaction, account: &Account) -> Result<Game, Error> { pub fn game_pve_new(cryp_ids: Vec<Uuid>, mode: GameMode, tx: &mut Transaction, account: &Account) -> Result<Game, Error> {
if cryp_ids.len() == 0 { if cryp_ids.len() == 0 {
return Err(err_msg("no cryps selected")); return Err(err_msg("no cryps selected"));
} }
@ -705,7 +722,8 @@ pub fn game_pve_new(cryp_ids: Vec<Uuid>, mode: PveMode, tx: &mut Transaction, ac
game game
.set_pve(true) .set_pve(true)
.set_team_num(2) .set_team_num(2)
.set_team_size(cryps.len()); .set_team_size(cryps.len())
.set_mode(mode);
// create the mob team // create the mob team
let mob_team = generate_mob_team(mode, &cryps); let mob_team = generate_mob_team(mode, &cryps);
@ -726,7 +744,7 @@ pub fn game_pve_new(cryp_ids: Vec<Uuid>, mode: PveMode, tx: &mut Transaction, ac
} }
pub fn game_pve(params: GamePveParams, tx: &mut Transaction, account: &Account) -> Result<Game, Error> { pub fn game_pve(params: GamePveParams, tx: &mut Transaction, account: &Account) -> Result<Game, Error> {
let game = game_pve_new(params.cryp_ids, params.mode, tx, account)?; let game = game_pve_new(params.cryp_ids, GameMode::Normal, tx, account)?;
// persist // persist
game_write(&game, tx)?; game_write(&game, tx)?;
@ -747,7 +765,8 @@ pub fn game_pvp(params: GamePvpParams, tx: &mut Transaction, account: &Account)
game game
.set_pve(false) .set_pve(false)
.set_team_num(2) .set_team_num(2)
.set_team_size(cryps.len()); .set_team_size(cryps.len())
.set_mode(GameMode::Pvp);
// create the initiators team // create the initiators team
let mut team = Team::new(account.id); let mut team = Team::new(account.id);

View File

@ -20,7 +20,7 @@ use zone::{node_finish};
pub type Log = Vec<String>; pub type Log = Vec<String>;
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub enum PveMode { pub enum GameMode {
Boss, Boss,
Normal, Normal,
} }
@ -767,7 +767,7 @@ fn generate_mob(lvl: u8) -> Cryp {
} }
fn generate_mob_team(mode: PveMode, cryps: &Vec<Cryp>) -> Team { fn generate_mob_team(mode: GameMode, cryps: &Vec<Cryp>) -> Team {
let mut mob_team = Team::new(Uuid::nil()); let mut mob_team = Team::new(Uuid::nil());
// Default settings // Default settings
@ -775,11 +775,11 @@ fn generate_mob_team(mode: PveMode, cryps: &Vec<Cryp>) -> Team {
// Modify the NPC cryps for game mode settings // Modify the NPC cryps for game mode settings
let mob_lvl = match mode { let mob_lvl = match mode {
PveMode::Normal => { GameMode::Normal => {
team_size = cryps.len(); team_size = cryps.len();
cryps.iter().max_by_key(|c| c.lvl).unwrap().lvl cryps.iter().max_by_key(|c| c.lvl).unwrap().lvl
}, },
PveMode::Boss => cryps.iter().max_by_key(|c| c.lvl).unwrap().lvl + 2, GameMode::Boss => cryps.iter().max_by_key(|c| c.lvl).unwrap().lvl + 2,
}; };
// Generate and return the NPC team based on settings // Generate and return the NPC team based on settings
@ -792,7 +792,7 @@ fn generate_mob_team(mode: PveMode, cryps: &Vec<Cryp>) -> Team {
} }
pub fn game_pve_new(cryp_ids: Vec<Uuid>, mode: PveMode, tx: &mut Transaction, account: &Account) -> Result<Game, Error> { pub fn game_pve_new(cryp_ids: Vec<Uuid>, mode: GameMode, tx: &mut Transaction, account: &Account) -> Result<Game, Error> {
let cryps = cryp_ids let cryps = cryp_ids
.iter() .iter()
.map(|id| cryp_get(tx, *id, account.id)) .map(|id| cryp_get(tx, *id, account.id))

View File

@ -12,6 +12,7 @@ use rand::distributions::{WeightedIndex};
use account::Account; use account::Account;
use rpc::{ItemUseParams}; use rpc::{ItemUseParams};
use cryp::{Stat, cryp_get, cryp_write}; use cryp::{Stat, cryp_get, cryp_write};
use game::{GameMode};
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
pub enum ItemAction { pub enum ItemAction {
@ -19,6 +20,9 @@ pub enum ItemAction {
RerollSpellDamage, RerollSpellDamage,
RerollSpeed, RerollSpeed,
RerollStamina, RerollStamina,
RerollArmour,
RerollSpellShield,
RerollEvasion,
} }
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
@ -45,6 +49,9 @@ impl Item {
ItemAction::RerollPhysDamage => reroll(self, tx, target, Stat::PhysicalDamage), ItemAction::RerollPhysDamage => reroll(self, tx, target, Stat::PhysicalDamage),
ItemAction::RerollSpellDamage => reroll(self, tx, target, Stat::SpellDamage), ItemAction::RerollSpellDamage => reroll(self, tx, target, Stat::SpellDamage),
ItemAction::RerollSpeed => reroll(self, tx, target, Stat::Speed), ItemAction::RerollSpeed => reroll(self, tx, target, Stat::Speed),
ItemAction::RerollArmour => reroll(self, tx, target, Stat::Armour),
ItemAction::RerollSpellShield => reroll(self, tx, target, Stat::SpellShield),
ItemAction::RerollEvasion => reroll(self, tx, target, Stat::Evasion),
} }
} }
} }
@ -63,15 +70,42 @@ fn reroll(item: &mut Item, tx: &mut Transaction, target: Uuid, stat: Stat) -> Re
return Ok(()); return Ok(());
} }
pub fn item_drop(tx: &mut Transaction, account_id: Uuid) -> Result<Item, Error> { fn mode_drops(mode: GameMode) -> Vec<(ItemAction, usize)> {
let mut rng = thread_rng(); match mode {
GameMode::Normal => vec![
let actions = [ (ItemAction::RerollStamina, 1),
(ItemAction::RerollPhysDamage, 1),
(ItemAction::RerollSpellDamage, 1),
],
GameMode::Pvp => vec![
(ItemAction::RerollSpeed, 1),
],
GameMode::Zone3v2Attack |
GameMode::Zone2v2Caster |
GameMode::Zone3v3MeleeMiniboss => vec![
(ItemAction::RerollSpeed, 1),
(ItemAction::RerollArmour, 1),
(ItemAction::RerollSpellShield, 1),
],
GameMode::Zone3v3HealerBoss => vec![
(ItemAction::RerollSpeed, 1),
],
_ => vec![
(ItemAction::RerollStamina, 1), (ItemAction::RerollStamina, 1),
(ItemAction::RerollPhysDamage, 1), (ItemAction::RerollPhysDamage, 1),
(ItemAction::RerollSpellDamage, 1), (ItemAction::RerollSpellDamage, 1),
(ItemAction::RerollSpeed, 1), (ItemAction::RerollSpeed, 1),
]; (ItemAction::RerollArmour, 1),
(ItemAction::RerollSpellShield, 1),
(ItemAction::RerollEvasion, 1),
],
}
}
pub fn item_drop(tx: &mut Transaction, account_id: Uuid, mode: GameMode) -> Result<Item, Error> {
let mut rng = thread_rng();
let actions = mode_drops(mode);
let dist = WeightedIndex::new(actions.iter().map(|item| item.1)).unwrap(); let dist = WeightedIndex::new(actions.iter().map(|item| item.1)).unwrap();
let kind = actions[dist.sample(&mut rng)].0; let kind = actions[dist.sample(&mut rng)].0;

View File

@ -5,19 +5,9 @@ use rand::distributions::Alphanumeric;
use std::iter; use std::iter;
use cryp::{Cryp}; use cryp::{Cryp};
use game::{Team}; use game::{Team, GameMode};
use skill::{Skill}; use skill::{Skill};
#[derive(Debug,Clone,Serialize,Deserialize)]
pub enum PveMode {
Boss,
Normal,
Zone3v2Attack,
Zone2v2Caster,
Zone3v3MeleeMiniboss,
Zone3v3HealerBoss,
}
fn generate_mob(lvl: u8) -> Cryp { fn generate_mob(lvl: u8) -> Cryp {
let mut rng = thread_rng(); let mut rng = thread_rng();
@ -134,19 +124,19 @@ fn zone_3v3_healer_boss(player_lvl: u8) -> Vec<Cryp> {
} }
pub fn generate_mob_team(mode: PveMode, cryps: &Vec<Cryp>) -> Team { pub fn generate_mob_team(mode: GameMode, cryps: &Vec<Cryp>) -> Team {
let mut mob_team = Team::new(Uuid::nil()); let mut mob_team = Team::new(Uuid::nil());
let cryp_lvl = cryps.iter().max_by_key(|c| c.lvl).unwrap().lvl; let cryp_lvl = cryps.iter().max_by_key(|c| c.lvl).unwrap().lvl;
let team_size = cryps.len(); let team_size = cryps.len();
let mobs = match mode { let mobs = match mode {
PveMode::Normal => quick_game(cryp_lvl, team_size), GameMode::Normal => quick_game(cryp_lvl, team_size),
PveMode::Boss => quick_game(cryp_lvl + 2, 1), GameMode::Zone3v2Attack => zone_3v2_attack(cryp_lvl),
PveMode::Zone3v2Attack => zone_3v2_attack(cryp_lvl), GameMode::Zone2v2Caster => zone_2v2_caster(cryp_lvl),
PveMode::Zone2v2Caster => zone_2v2_caster(cryp_lvl), GameMode::Zone3v3MeleeMiniboss => zone_3v3_melee_miniboss(cryp_lvl),
PveMode::Zone3v3MeleeMiniboss => zone_3v3_melee_miniboss(cryp_lvl), GameMode::Zone3v3HealerBoss => zone_3v3_healer_boss(cryp_lvl),
PveMode::Zone3v3HealerBoss => zone_3v3_healer_boss(cryp_lvl), _ => panic!("{:?} not handled for pve mobs", mode),
}; };
mob_team.set_cryps(mobs); mob_team.set_cryps(mobs);

View File

@ -21,7 +21,6 @@ use account::{Account, account_create, account_login, account_from_token, accoun
use item::{Item, items_list, item_use}; use item::{Item, items_list, item_use};
use skill::{Skill}; use skill::{Skill};
use zone::{Zone, zone_create, zone_join, zone_close}; use zone::{Zone, zone_create, zone_join, zone_close};
use mob::{PveMode};
pub struct Rpc; pub struct Rpc;
@ -443,7 +442,6 @@ struct GamePveMsg {
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct GamePveParams { pub struct GamePveParams {
pub cryp_ids: Vec<Uuid>, pub cryp_ids: Vec<Uuid>,
pub mode: PveMode,
} }
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]

View File

@ -260,26 +260,30 @@ impl Effect {
pub fn duration(&self) -> u8 { pub fn duration(&self) -> u8 {
match self { match self {
Effect::Stun => 1,
Effect::Block => 1, Effect::Block => 1,
Effect::Parry => 1, Effect::Parry => 1,
Effect::Stun => 2,
Effect::Vulnerable => 2, Effect::Vulnerable => 2,
Effect::Snare => 1, Effect::Snare => 2,
Effect::Empower => 2, Effect::Empower => 2,
Effect::Shield => 2, Effect::Hex => 2,
Effect::Curse => 2,
Effect::Banish => 1,
Effect::Decay => 2, Effect::Slow => 2,
Effect::Drain => 2, Effect::Haste => 2,
Effect::Triage => 2,
Effect::Amplify => 2, Effect::Amplify => 2,
Effect::Silence => 2, Effect::Silence => 2,
Effect::Haste => 2, Effect::Shield => 2,
Effect::Slow => 2,
Effect::Triage => 3,
Effect::Decay => 3,
Effect::Drain => 2,
_ => { _ => {
println!("{:?} does not have a duration", self); println!("{:?} does not have a duration", self);

View File

@ -9,9 +9,8 @@ use postgres::transaction::Transaction;
use failure::Error; use failure::Error;
use failure::err_msg; use failure::err_msg;
use game::{Game, game_pve_new, game_write}; use game::{Game, GameMode, game_pve_new, game_write};
use rpc::{ZoneJoinParams, ZoneCloseParams}; use rpc::{ZoneJoinParams, ZoneCloseParams};
use mob::{PveMode};
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Zone { pub struct Zone {
@ -154,10 +153,10 @@ pub fn zone_join(params: ZoneJoinParams, tx: &mut Transaction, account: &Account
.ok_or(err_msg("invalid encounter id"))?; .ok_or(err_msg("invalid encounter id"))?;
let mode = match encounter.tag.as_ref() { let mode = match encounter.tag.as_ref() {
"ZONE0" => PveMode::Zone3v2Attack, "ZONE0" => GameMode::Zone3v2Attack,
"ZONE1" => PveMode::Zone2v2Caster, "ZONE1" => GameMode::Zone2v2Caster,
"ZONE2" => PveMode::Zone3v3MeleeMiniboss, "ZONE2" => GameMode::Zone3v3MeleeMiniboss,
"BOSS" => PveMode::Zone3v3HealerBoss, "BOSS" => GameMode::Zone3v3HealerBoss,
_ => return Err(err_msg("unknown zone tag")), _ => return Err(err_msg("unknown zone tag")),
}; };
game = game_pve_new(params.cryp_ids, mode, tx, account)?; game = game_pve_new(params.cryp_ids, mode, tx, account)?;