drops for zones

This commit is contained in:
ntr 2019-01-13 18:13:15 +11:00
parent feacd368a1
commit e05b7e05b9
10 changed files with 98 additions and 52 deletions

View File

@ -114,7 +114,7 @@ class MenuNavigation extends Phaser.Scene {
.setOrigin(0)
.on('pointerdown', () => {
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();
});
this.add

View File

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

View File

@ -188,6 +188,9 @@ impl Cryp {
let stat_min = 128u64.saturating_mul(self.lvl.into());
let stat_max = 256u64.saturating_mul(self.lvl.into());
let evasion_min = 1u64;
let evasion_max = 25;
match stat {
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)),
@ -196,6 +199,9 @@ impl Cryp {
self.stamina.set(rng.gen_range(stam_min, stam_max));
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),
};
@ -525,15 +531,14 @@ impl Cryp {
}
pub fn evade(&self, skill: Skill) -> Option<ResolutionResult> {
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);
if evasion_rating == 0 {
if self.evasion.base == 0 {
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);
match roll > evasion_rating {

View File

@ -13,7 +13,7 @@ use cryp::{Cryp, cryp_get};
use skill::{Skill, Cast, ResolutionResult};
use item::{item_drop};
use zone::{node_finish};
use mob::{PveMode, generate_mob_team};
use mob::{generate_mob_team};
pub type Log = Vec<String>;
@ -60,6 +60,16 @@ pub enum Phase {
Finish,
}
#[derive(Debug,Clone,Copy,Serialize,Deserialize)]
pub enum GameMode {
Normal,
Pvp,
Zone3v2Attack,
Zone2v2Caster,
Zone3v3MeleeMiniboss,
Zone3v3HealerBoss,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Game {
pub id: Uuid,
@ -72,6 +82,7 @@ pub struct Game {
pub resolved: Vec<Cast>,
pub log: Vec<String>,
pub zone: Option<(Uuid, u32)>,
pub mode: GameMode,
}
impl Game {
@ -87,6 +98,7 @@ impl Game {
resolved: vec![],
log: vec![],
zone: None,
mode: GameMode::Normal,
};
}
@ -110,6 +122,11 @@ impl Game {
self
}
pub fn set_mode(&mut self, mode: GameMode) -> &mut Game {
self.mode = mode;
self
}
fn already_joined(&self, team_id: Uuid) -> bool {
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 let Some(t) = game.winner() {
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(());
}
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 {
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
.set_pve(true)
.set_team_num(2)
.set_team_size(cryps.len());
.set_team_size(cryps.len())
.set_mode(mode);
// create the mob team
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> {
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
game_write(&game, tx)?;
@ -747,7 +765,8 @@ pub fn game_pvp(params: GamePvpParams, tx: &mut Transaction, account: &Account)
game
.set_pve(false)
.set_team_num(2)
.set_team_size(cryps.len());
.set_team_size(cryps.len())
.set_mode(GameMode::Pvp);
// create the initiators team
let mut team = Team::new(account.id);

View File

@ -20,7 +20,7 @@ use zone::{node_finish};
pub type Log = Vec<String>;
#[derive(Debug,Clone,Serialize,Deserialize)]
pub enum PveMode {
pub enum GameMode {
Boss,
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());
// Default settings
@ -775,11 +775,11 @@ fn generate_mob_team(mode: PveMode, cryps: &Vec<Cryp>) -> Team {
// Modify the NPC cryps for game mode settings
let mob_lvl = match mode {
PveMode::Normal => {
GameMode::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,
GameMode::Boss => cryps.iter().max_by_key(|c| c.lvl).unwrap().lvl + 2,
};
// 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
.iter()
.map(|id| cryp_get(tx, *id, account.id))

View File

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

View File

@ -5,19 +5,9 @@ use rand::distributions::Alphanumeric;
use std::iter;
use cryp::{Cryp};
use game::{Team};
use game::{Team, GameMode};
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();
@ -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 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),
GameMode::Normal => quick_game(cryp_lvl, team_size),
GameMode::Zone3v2Attack => zone_3v2_attack(cryp_lvl),
GameMode::Zone2v2Caster => zone_2v2_caster(cryp_lvl),
GameMode::Zone3v3MeleeMiniboss => zone_3v3_melee_miniboss(cryp_lvl),
GameMode::Zone3v3HealerBoss => zone_3v3_healer_boss(cryp_lvl),
_ => panic!("{:?} not handled for pve mobs", mode),
};
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 skill::{Skill};
use zone::{Zone, zone_create, zone_join, zone_close};
use mob::{PveMode};
pub struct Rpc;
@ -443,7 +442,6 @@ struct GamePveMsg {
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct GamePveParams {
pub cryp_ids: Vec<Uuid>,
pub mode: PveMode,
}
#[derive(Debug,Clone,Serialize,Deserialize)]

View File

@ -277,6 +277,7 @@ impl Effect {
Effect::Amplify => 2,
Effect::Silence => 2,
Effect::Curse => 2,
Effect::Haste => 2,
Effect::Slow => 2,

View File

@ -9,9 +9,8 @@ use postgres::transaction::Transaction;
use failure::Error;
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 mob::{PveMode};
#[derive(Debug,Clone,Serialize,Deserialize)]
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"))?;
let mode = match encounter.tag.as_ref() {
"ZONE0" => PveMode::Zone3v2Attack,
"ZONE1" => PveMode::Zone2v2Caster,
"ZONE2" => PveMode::Zone3v3MeleeMiniboss,
"BOSS" => PveMode::Zone3v3HealerBoss,
"ZONE0" => GameMode::Zone3v2Attack,
"ZONE1" => GameMode::Zone2v2Caster,
"ZONE2" => GameMode::Zone3v3MeleeMiniboss,
"BOSS" => GameMode::Zone3v3HealerBoss,
_ => return Err(err_msg("unknown zone tag")),
};
game = game_pve_new(params.cryp_ids, mode, tx, account)?;