Merge branch 'develop' of ssh://git.mnml.gg:40022/~/mnml into develop
This commit is contained in:
commit
d4ae38e733
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mnml-client",
|
||||
"version": "1.4.4",
|
||||
"version": "1.4.5",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@ -53,7 +53,7 @@ aside {
|
||||
border-color: forestgreen;
|
||||
}
|
||||
|
||||
&:active, &:focus {
|
||||
&:active, &:focus, &.enabled {
|
||||
background: forestgreen;
|
||||
color: black;
|
||||
border-color: forestgreen;
|
||||
|
||||
@ -286,3 +286,9 @@ li {
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
#clipboard {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0px;
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mnml-client",
|
||||
"version": "1.4.4",
|
||||
"version": "1.4.5",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@ -29,6 +29,7 @@
|
||||
"preact-compat": "^3.19.0",
|
||||
"preact-context": "^1.1.3",
|
||||
"preact-redux": "^2.1.0",
|
||||
"query-string": "^6.8.3",
|
||||
"react-string-replace": "^0.4.4",
|
||||
"react-stripe-elements": "^3.0.0",
|
||||
"redux": "^4.0.0"
|
||||
|
||||
@ -19,6 +19,7 @@ export const setConstructRename = value => ({ type: 'SET_CONSTRUCT_RENAME', valu
|
||||
export const setGame = value => ({ type: 'SET_GAME', value });
|
||||
export const setInfo = value => ({ type: 'SET_INFO', value });
|
||||
export const setEmail = value => ({ type: 'SET_EMAIL', value });
|
||||
export const setInvite = value => ({ type: 'SET_INVITE', value });
|
||||
export const setInstance = value => ({ type: 'SET_INSTANCE', value });
|
||||
export const setInstances = value => ({ type: 'SET_INSTANCES', value });
|
||||
export const setItemEquip = value => ({ type: 'SET_ITEM_EQUIP', value });
|
||||
|
||||
@ -76,11 +76,13 @@ function Controls(args) {
|
||||
background: displayColour,
|
||||
};
|
||||
|
||||
const timer = (
|
||||
<div class="timer-container">
|
||||
<div class="timer" style={timerStyles} > </div>
|
||||
</div>
|
||||
);
|
||||
const timer = instance.phase !== 'InProgress'
|
||||
? null
|
||||
: (
|
||||
<div class="timer-container">
|
||||
<div class="timer" style={timerStyles} > </div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const ready = instance.phase !== 'Finished'
|
||||
? <button class="ready" onClick={() => sendReady()}>Ready</button>
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
const preact = require('preact');
|
||||
const { connect } = require('preact-redux');
|
||||
|
||||
const { errorToast, infoToast } = require('../utils');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const {
|
||||
ws,
|
||||
instances,
|
||||
invite,
|
||||
} = state;
|
||||
|
||||
function sendInstanceState(id) {
|
||||
@ -20,12 +23,18 @@ const addState = connect(
|
||||
ws.sendInstanceQueue();
|
||||
}
|
||||
|
||||
function sendInstanceInvite() {
|
||||
ws.sendInstanceInvite();
|
||||
}
|
||||
|
||||
return {
|
||||
instances,
|
||||
invite,
|
||||
|
||||
sendInstanceState,
|
||||
sendInstanceQueue,
|
||||
sendInstancePractice,
|
||||
sendInstanceInvite,
|
||||
};
|
||||
}
|
||||
);
|
||||
@ -33,10 +42,12 @@ const addState = connect(
|
||||
function JoinButtons(args) {
|
||||
const {
|
||||
instances,
|
||||
invite,
|
||||
|
||||
sendInstanceState,
|
||||
sendInstanceQueue,
|
||||
sendInstancePractice,
|
||||
sendInstanceInvite,
|
||||
} = args;
|
||||
|
||||
if (instances.length) {
|
||||
@ -55,6 +66,48 @@ function JoinButtons(args) {
|
||||
);
|
||||
}
|
||||
|
||||
const inviteBtn = () => {
|
||||
if (!invite) {
|
||||
return (
|
||||
<button
|
||||
class='pvp ready'
|
||||
onClick={() => sendInstanceInvite()}
|
||||
type="submit">
|
||||
Invite
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
function copyClick(e) {
|
||||
const link = `${document.location.origin}#join=${invite}`;
|
||||
const textArea = document.createElement('textarea', { id: '#clipboard' });
|
||||
textArea.value = link;
|
||||
document.body.appendChild(textArea);
|
||||
textArea.focus();
|
||||
textArea.select();
|
||||
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
infoToast('Invite link copied.');
|
||||
} catch (err) {
|
||||
console.error('link copy error', err);
|
||||
errorToast('Invite link copy error.');
|
||||
}
|
||||
|
||||
document.body.removeChild(textArea);
|
||||
return true;
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
class='pvp ready enabled'
|
||||
onClick={copyClick}
|
||||
type="submit">
|
||||
Copy Link
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<aside class='play-ctrl'>
|
||||
<div class="timer-container"></div>
|
||||
@ -65,6 +118,7 @@ function JoinButtons(args) {
|
||||
type="submit">
|
||||
PVP
|
||||
</button>
|
||||
{inviteBtn()}
|
||||
<button
|
||||
class='practice ready'
|
||||
onClick={() => sendInstancePractice()}
|
||||
|
||||
@ -92,13 +92,14 @@ function Play(args) {
|
||||
<section class="top">
|
||||
<div class="news">
|
||||
<h1>v{VERSION}</h1>
|
||||
<p>use the buttons on the right to join an instance.</p>
|
||||
<p>Use the buttons on the right to join an instance.</p>
|
||||
<p>
|
||||
select <b>PVP</b> to play against other players.<br />
|
||||
click <b>LEARN</b> to practice the game without time controls.
|
||||
Select <b>PVP</b> to play against other players.<br />
|
||||
Select <b>INVITE</b> then click <b>COPY LINK</b> to generate an instance invitation for a friend.<br />
|
||||
Click <b>LEARN</b> to practice the game without time controls.
|
||||
</p>
|
||||
<p>
|
||||
if you enjoy the game please support its development by <b>subscribing</b> or purchasing <b>credits</b>.<br />
|
||||
If you enjoy the game please support its development by <b>subscribing</b> or purchasing <b>credits</b>.<br />
|
||||
glhf
|
||||
</p>
|
||||
<p>--ntr & mashy</p>
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
const querystring = require('query-string');
|
||||
|
||||
const eachSeries = require('async/eachSeries');
|
||||
const sample = require('lodash/sample');
|
||||
|
||||
@ -168,9 +170,20 @@ function registerEvents(store) {
|
||||
return store.dispatch(actions.setInstances(v));
|
||||
}
|
||||
|
||||
function setInvite(code) {
|
||||
if (!code) return store.dispatch(actions.setInvite(null));
|
||||
|
||||
navigator.clipboard.writeText(code).then(() => {
|
||||
notify(`your invite code ${code} was copied to the clipboard.`);
|
||||
}, () => {});
|
||||
|
||||
return store.dispatch(actions.setInvite(code));
|
||||
}
|
||||
|
||||
function setInstance(v) {
|
||||
const { account, instance, ws } = store.getState();
|
||||
if (v) {
|
||||
setInvite(null);
|
||||
const player = v.players.find(p => p.id === account.id);
|
||||
store.dispatch(actions.setPlayer(player));
|
||||
|
||||
@ -272,6 +285,16 @@ function registerEvents(store) {
|
||||
} */
|
||||
// setup / localstorage
|
||||
|
||||
function urlHashChange() {
|
||||
const { ws } = store.getState();
|
||||
const cmds = querystring.parse(location.hash);
|
||||
|
||||
if (cmds.join) ws.sendInstanceJoin(cmds.join);
|
||||
return true;
|
||||
}
|
||||
|
||||
window.addEventListener('hashchange', urlHashChange, false);
|
||||
|
||||
return {
|
||||
clearCombiner,
|
||||
clearConstructRename,
|
||||
@ -289,12 +312,15 @@ function registerEvents(store) {
|
||||
setEmail,
|
||||
setInstance,
|
||||
setItemInfo,
|
||||
setInvite,
|
||||
setPing,
|
||||
setShop,
|
||||
setTeam,
|
||||
setSubscription,
|
||||
setWs,
|
||||
|
||||
urlHashChange,
|
||||
|
||||
notify,
|
||||
};
|
||||
}
|
||||
|
||||
@ -31,6 +31,7 @@ module.exports = {
|
||||
constructRename: createReducer(null, 'SET_CONSTRUCT_RENAME'),
|
||||
game: createReducer(null, 'SET_GAME'),
|
||||
email: createReducer(null, 'SET_EMAIL'),
|
||||
invite: createReducer(null, 'SET_INVITE'),
|
||||
info: createReducer(null, 'SET_INFO'),
|
||||
instance: createReducer(null, 'SET_INSTANCE'),
|
||||
instances: createReducer([], 'SET_INSTANCES'),
|
||||
|
||||
@ -126,6 +126,14 @@ function createSocket(events) {
|
||||
send(['InstanceQueue', {}]);
|
||||
}
|
||||
|
||||
function sendInstanceInvite() {
|
||||
send(['InstanceInvite', {}]);
|
||||
}
|
||||
|
||||
function sendInstanceJoin(code) {
|
||||
send(['InstanceJoin', { code }]);
|
||||
}
|
||||
|
||||
function sendInstanceReady(instanceId) {
|
||||
send(['InstanceReady', { instance_id: instanceId }]);
|
||||
}
|
||||
@ -239,6 +247,9 @@ function createSocket(events) {
|
||||
|
||||
QueueRequested: () => events.notify('pvp queue request received'),
|
||||
QueueJoined: () => events.notify('you have joined the pvp queue'),
|
||||
InviteRequested: () => events.notify('pvp queue request received'),
|
||||
Invite: code => events.setInvite(code),
|
||||
Joining: () => events.notify('searching for instance...'),
|
||||
|
||||
Error: errHandler,
|
||||
};
|
||||
@ -284,6 +295,8 @@ function createSocket(events) {
|
||||
sendPing();
|
||||
sendItemInfo();
|
||||
|
||||
events.urlHashChange();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -318,6 +331,7 @@ function createSocket(events) {
|
||||
ws.addEventListener('message', onMessage);
|
||||
ws.addEventListener('error', onError);
|
||||
ws.addEventListener('close', onClose);
|
||||
|
||||
return ws;
|
||||
}
|
||||
|
||||
@ -338,6 +352,8 @@ function createSocket(events) {
|
||||
sendInstancePractice,
|
||||
sendInstanceQueue,
|
||||
sendInstanceState,
|
||||
sendInstanceInvite,
|
||||
sendInstanceJoin,
|
||||
|
||||
sendVboxAccept,
|
||||
sendVboxApply,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mnml-ops",
|
||||
"version": "1.4.4",
|
||||
"version": "1.4.5",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "mnml"
|
||||
version = "1.4.4"
|
||||
version = "1.4.5"
|
||||
authors = ["ntr <ntr@smokestack.io>"]
|
||||
|
||||
[dependencies]
|
||||
|
||||
@ -46,7 +46,6 @@ impl Colours {
|
||||
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
||||
pub struct ConstructSkill {
|
||||
pub skill: Skill,
|
||||
pub self_targeting: bool,
|
||||
pub cd: Cooldown,
|
||||
// used for Uon client
|
||||
pub disabled: bool,
|
||||
@ -56,7 +55,6 @@ impl ConstructSkill {
|
||||
pub fn new(skill: Skill) -> ConstructSkill {
|
||||
ConstructSkill {
|
||||
skill,
|
||||
self_targeting: skill.self_targeting(),
|
||||
cd: skill.base_cd(),
|
||||
disabled: false,
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ use account;
|
||||
use account::Account;
|
||||
use game;
|
||||
use instance;
|
||||
use names;
|
||||
|
||||
use pg::{Db, PgPool};
|
||||
use rpc::RpcMessage;
|
||||
@ -54,6 +55,9 @@ pub enum Event {
|
||||
|
||||
// client events
|
||||
Queue(Id),
|
||||
Invite(Id),
|
||||
Join(Id, String),
|
||||
Joined(Id),
|
||||
}
|
||||
|
||||
struct WsClient {
|
||||
@ -62,6 +66,7 @@ struct WsClient {
|
||||
tx: Sender<RpcMessage>,
|
||||
subs: HashSet<Uuid>,
|
||||
pvp: bool,
|
||||
invite: Option<String>,
|
||||
}
|
||||
|
||||
impl Events {
|
||||
@ -115,7 +120,7 @@ impl Events {
|
||||
None => None,
|
||||
};
|
||||
|
||||
let client = WsClient { id, tx, account: account_id, subs: HashSet::new(), pvp: false };
|
||||
let client = WsClient { id, tx, account: account_id, subs: HashSet::new(), pvp: false, invite: None };
|
||||
self.clients.insert(id, client);
|
||||
|
||||
info!("clients={:?}", self.clients.len());
|
||||
@ -223,6 +228,59 @@ impl Events {
|
||||
info!("joined game queue id={:?} account={:?}", requester.id, requester.account);
|
||||
return Ok(());
|
||||
},
|
||||
|
||||
Event::Invite(id) => {
|
||||
// check whether request is valid
|
||||
let c = self.clients.get_mut(&id)
|
||||
.ok_or(format_err!("connection not found id={:?}", id))?;
|
||||
|
||||
if let None = c.account {
|
||||
return Err(err_msg("cannot join pvp queue anonymously"));
|
||||
}
|
||||
|
||||
let code = names::name().split_whitespace().collect::<Vec<&str>>().join("-");
|
||||
info!("pvp invite request id={:?} account={:?} code={:?}", c.id, c.account, code);
|
||||
c.invite = Some(code.clone());
|
||||
c.tx.send(RpcMessage::Invite(code))?;
|
||||
return Ok(());
|
||||
},
|
||||
|
||||
Event::Join(id, code) => {
|
||||
// check whether request is valid
|
||||
let c = self.clients.get(&id)
|
||||
.ok_or(format_err!("connection not found id={:?}", id))?;
|
||||
|
||||
if let None = c.account {
|
||||
return Err(err_msg("cannot join pvp queue anonymously"));
|
||||
}
|
||||
|
||||
info!("pvp join request id={:?} account={:?} code={:?}", c.id, c.account, code);
|
||||
|
||||
let inv = self.clients.iter()
|
||||
.filter(|(_id, c)| c.invite.is_some())
|
||||
.find(|(_id, c)| match c.invite {
|
||||
Some(ref c) => *c == code,
|
||||
None => false,
|
||||
})
|
||||
.map(|(_id, c)| PvpRequest { id: c.id, account: c.account.unwrap(), tx: c.tx.clone() })
|
||||
.ok_or(format_err!("invite not found code={:?}", code))?;
|
||||
|
||||
let join = PvpRequest { id: c.id, account: c.account.unwrap(), tx: c.tx.clone() };
|
||||
|
||||
self.warden.send(GameEvent::Match((join, inv)))?;
|
||||
return Ok(());
|
||||
},
|
||||
|
||||
Event::Joined(id) => {
|
||||
// check whether request is valid
|
||||
let c = self.clients.get_mut(&id)
|
||||
.ok_or(format_err!("connection not found id={:?}", id))?;
|
||||
|
||||
c.pvp = false;
|
||||
c.invite = None;
|
||||
return Ok(());
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,7 +236,7 @@ impl Game {
|
||||
target = find_target();
|
||||
}
|
||||
|
||||
pve_skills.push((mobs.id, mob.id, Some(target.id), s));
|
||||
pve_skills.push((mobs.id, mob.id, target.id, s));
|
||||
},
|
||||
None => continue,
|
||||
};
|
||||
@ -258,7 +258,7 @@ impl Game {
|
||||
self
|
||||
}
|
||||
|
||||
fn add_skill(&mut self, player_id: Uuid, source_construct_id: Uuid, target_construct_id: Option<Uuid>, skill: Skill) -> Result<&mut Game, Error> {
|
||||
fn add_skill(&mut self, player_id: Uuid, source_construct_id: Uuid, target_construct_id: Uuid, skill: Skill) -> Result<&mut Game, Error> {
|
||||
// check player in game
|
||||
self.player_by_id(player_id)?;
|
||||
|
||||
@ -266,17 +266,9 @@ impl Game {
|
||||
return Err(err_msg("game not in skill phase"));
|
||||
}
|
||||
|
||||
let final_target_id = match skill.self_targeting() {
|
||||
true => source_construct_id,
|
||||
false => match target_construct_id {
|
||||
Some(t) => t,
|
||||
None => return Err(err_msg("skill requires a target")),
|
||||
}
|
||||
};
|
||||
|
||||
// target checks
|
||||
{
|
||||
let target = match self.construct_by_id(final_target_id) {
|
||||
let target = match self.construct_by_id(target_construct_id) {
|
||||
Some(c) => c,
|
||||
None => return Err(err_msg("target construct not in game")),
|
||||
};
|
||||
@ -318,7 +310,7 @@ impl Game {
|
||||
self.stack.remove(s);
|
||||
}
|
||||
|
||||
let skill = Cast::new(source_construct_id, player_id, final_target_id, skill);
|
||||
let skill = Cast::new(source_construct_id, player_id, target_construct_id, skill);
|
||||
self.stack.push(skill);
|
||||
|
||||
return Ok(self);
|
||||
@ -887,7 +879,7 @@ fn game_json_file_write(g: &Game) -> Result<String, Error> {
|
||||
Ok(dest)
|
||||
}
|
||||
|
||||
pub fn game_skill(tx: &mut Transaction, account: &Account, game_id: Uuid, construct_id: Uuid, target_construct_id: Option<Uuid>, skill: Skill) -> Result<Game, Error> {
|
||||
pub fn game_skill(tx: &mut Transaction, account: &Account, game_id: Uuid, construct_id: Uuid, target_construct_id: Uuid, skill: Skill) -> Result<Game, Error> {
|
||||
let mut game = game_get(tx, game_id)?;
|
||||
|
||||
game.add_skill(account.id, construct_id, target_construct_id, skill)?;
|
||||
@ -1039,8 +1031,8 @@ mod tests {
|
||||
let x_construct = x_player.constructs[0].clone();
|
||||
let y_construct = y_player.constructs[0].clone();
|
||||
|
||||
game.add_skill(x_player.id, x_construct.id, Some(y_construct.id), Skill::Attack).unwrap();
|
||||
game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::Attack).unwrap();
|
||||
game.add_skill(x_player.id, x_construct.id, y_construct.id, Skill::Attack).unwrap();
|
||||
game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap();
|
||||
|
||||
game.player_ready(x_player.id).unwrap();
|
||||
game.player_ready(y_player.id).unwrap();
|
||||
@ -1068,8 +1060,8 @@ mod tests {
|
||||
game.construct_by_id(x_construct.id).unwrap().reduce_cooldowns();
|
||||
}
|
||||
|
||||
game.add_skill(x_player.id, x_construct.id, Some(y_construct.id), Skill::Stun).unwrap();
|
||||
game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::Attack).unwrap();
|
||||
game.add_skill(x_player.id, x_construct.id, y_construct.id, Skill::Stun).unwrap();
|
||||
game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap();
|
||||
|
||||
game.player_ready(x_player.id).unwrap();
|
||||
game.player_ready(y_player.id).unwrap();
|
||||
@ -1105,8 +1097,8 @@ mod tests {
|
||||
// remove all mitigation
|
||||
game.player_by_id(x_player.id).unwrap().construct_by_id(x_construct.id).unwrap().red_life.force(0);
|
||||
|
||||
game.add_skill(x_player.id, x_construct.id, Some(y_construct.id), Skill::Stun).unwrap();
|
||||
game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::Attack).unwrap();
|
||||
game.add_skill(x_player.id, x_construct.id, y_construct.id, Skill::Stun).unwrap();
|
||||
game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap();
|
||||
|
||||
game.player_ready(x_player.id).unwrap();
|
||||
game.player_ready(y_player.id).unwrap();
|
||||
@ -1135,8 +1127,8 @@ mod tests {
|
||||
assert!(game.player_by_id(y_player.id).unwrap().constructs[0].skill_on_cd(Skill::Stun).is_some());
|
||||
assert!(game.player_by_id(x_player.id).unwrap().constructs[0].skill_on_cd(Skill::Block).is_none());
|
||||
|
||||
game.add_skill(x_player.id, x_construct.id, Some(y_construct.id), Skill::Attack).unwrap();
|
||||
game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::Attack).unwrap();
|
||||
game.add_skill(x_player.id, x_construct.id, y_construct.id, Skill::Attack).unwrap();
|
||||
game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap();
|
||||
|
||||
game.player_ready(x_player.id).unwrap();
|
||||
game.player_ready(y_player.id).unwrap();
|
||||
@ -1149,8 +1141,8 @@ mod tests {
|
||||
|
||||
// second round
|
||||
// now we block and it should go back on cd
|
||||
// game.add_skill(x_player.id, x_construct.id, Some(y_construct.id), Skill::Stun).unwrap();
|
||||
game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::Attack).unwrap();
|
||||
// game.add_skill(x_player.id, x_construct.id, y_construct.id, Skill::Stun).unwrap();
|
||||
game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap();
|
||||
|
||||
game.player_ready(x_player.id).unwrap();
|
||||
game.player_ready(y_player.id).unwrap();
|
||||
@ -1179,8 +1171,8 @@ mod tests {
|
||||
game.construct_by_id(x_construct.id).unwrap().reduce_cooldowns();
|
||||
}
|
||||
|
||||
game.add_skill(x_player.id, x_construct.id, None, Skill::Counter).unwrap();
|
||||
game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::Stun).unwrap();
|
||||
game.add_skill(x_player.id, x_construct.id, x_construct.id, Skill::Counter).unwrap();
|
||||
game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Stun).unwrap();
|
||||
|
||||
game.player_ready(x_player.id).unwrap();
|
||||
game.player_ready(y_player.id).unwrap();
|
||||
@ -1214,14 +1206,14 @@ mod tests {
|
||||
}
|
||||
|
||||
// apply buff
|
||||
game.add_skill(x_player.id, x_construct.id, Some(x_construct.id), Skill::Electrify).unwrap();
|
||||
game.add_skill(x_player.id, x_construct.id, x_construct.id, Skill::Electrify).unwrap();
|
||||
game.player_ready(x_player.id).unwrap();
|
||||
game.player_ready(y_player.id).unwrap();
|
||||
game = game.resolve_phase_start();
|
||||
assert!(game.construct_by_id(x_construct.id).unwrap().affected(Effect::Electric));
|
||||
|
||||
// attack and receive debuff
|
||||
game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::Attack).unwrap();
|
||||
game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap();
|
||||
game.player_ready(x_player.id).unwrap();
|
||||
game.player_ready(y_player.id).unwrap();
|
||||
game = game.resolve_phase_start();
|
||||
@ -1246,7 +1238,7 @@ mod tests {
|
||||
}
|
||||
|
||||
// apply buff
|
||||
game.add_skill(x_player.id, x_construct.id, Some(y_construct.id), Skill::Link).unwrap();
|
||||
game.add_skill(x_player.id, x_construct.id, y_construct.id, Skill::Link).unwrap();
|
||||
game.player_ready(x_player.id).unwrap();
|
||||
game.player_ready(y_player.id).unwrap();
|
||||
game = game.resolve_phase_start();
|
||||
@ -1265,7 +1257,7 @@ mod tests {
|
||||
}
|
||||
|
||||
// attack and receive link hit
|
||||
game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::Attack).unwrap();
|
||||
game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap();
|
||||
game.player_ready(x_player.id).unwrap();
|
||||
game.player_ready(y_player.id).unwrap();
|
||||
game = game.resolve_phase_start();
|
||||
@ -1296,14 +1288,14 @@ mod tests {
|
||||
// }
|
||||
|
||||
// // apply buff
|
||||
// game.add_skill(x_player.id, x_construct.id, Some(x_construct.id), Skill::Absorb).unwrap();
|
||||
// game.add_skill(x_player.id, x_construct.id, x_construct.id, Skill::Absorb).unwrap();
|
||||
// game.player_ready(x_player.id).unwrap();
|
||||
// game.player_ready(y_player.id).unwrap();
|
||||
// game = game.resolve_phase_start();
|
||||
// assert!(game.construct_by_id(x_construct.id).unwrap().affected(Effect::Absorb));
|
||||
|
||||
// // attack and receive debuff
|
||||
// game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::TestAttack).unwrap();
|
||||
// game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::TestAttack).unwrap();
|
||||
// game.player_ready(x_player.id).unwrap();
|
||||
// game.player_ready(y_player.id).unwrap();
|
||||
// game = game.resolve_phase_start();
|
||||
@ -1330,10 +1322,10 @@ mod tests {
|
||||
game.construct_by_id(x_construct.id).unwrap().reduce_cooldowns();
|
||||
}
|
||||
|
||||
game.add_skill(i_player.id, i_construct.id, Some(x_construct.id), Skill::Attack).unwrap();
|
||||
game.add_skill(i_player.id, j_construct.id, Some(x_construct.id), Skill::Attack).unwrap();
|
||||
game.add_skill(x_player.id, x_construct.id, Some(i_construct.id), Skill::Ruin).unwrap();
|
||||
game.add_skill(x_player.id, y_construct.id, Some(i_construct.id), Skill::Attack).unwrap();
|
||||
game.add_skill(i_player.id, i_construct.id, x_construct.id, Skill::Attack).unwrap();
|
||||
game.add_skill(i_player.id, j_construct.id, x_construct.id, Skill::Attack).unwrap();
|
||||
game.add_skill(x_player.id, x_construct.id, i_construct.id, Skill::Ruin).unwrap();
|
||||
game.add_skill(x_player.id, y_construct.id, i_construct.id, Skill::Attack).unwrap();
|
||||
|
||||
game.player_ready(i_player.id).unwrap();
|
||||
game.player_ready(x_player.id).unwrap();
|
||||
@ -1380,10 +1372,10 @@ mod tests {
|
||||
game.construct_by_id(x_construct.id).unwrap().reduce_cooldowns();
|
||||
}
|
||||
|
||||
game.add_skill(i_player.id, i_construct.id, Some(x_construct.id), Skill::Attack).unwrap();
|
||||
game.add_skill(i_player.id, j_construct.id, Some(x_construct.id), Skill::Attack).unwrap();
|
||||
game.add_skill(x_player.id, x_construct.id, Some(i_construct.id), Skill::Intercept).unwrap();
|
||||
game.add_skill(x_player.id, y_construct.id, Some(i_construct.id), Skill::Attack).unwrap();
|
||||
game.add_skill(i_player.id, i_construct.id, x_construct.id, Skill::Attack).unwrap();
|
||||
game.add_skill(i_player.id, j_construct.id, x_construct.id, Skill::Attack).unwrap();
|
||||
game.add_skill(x_player.id, x_construct.id, i_construct.id, Skill::Intercept).unwrap();
|
||||
game.add_skill(x_player.id, y_construct.id, i_construct.id, Skill::Attack).unwrap();
|
||||
|
||||
game.player_ready(i_player.id).unwrap();
|
||||
game.player_ready(x_player.id).unwrap();
|
||||
@ -1411,10 +1403,10 @@ mod tests {
|
||||
let x_construct = x_player.constructs[0].clone();
|
||||
let y_construct = x_player.constructs[1].clone();
|
||||
|
||||
game.add_skill(i_player.id, i_construct.id, Some(x_construct.id), Skill::Attack).unwrap()
|
||||
.add_skill(i_player.id, j_construct.id, Some(x_construct.id), Skill::Attack).unwrap()
|
||||
.add_skill(x_player.id, x_construct.id, Some(i_construct.id), Skill::Attack).unwrap()
|
||||
.add_skill(x_player.id, y_construct.id, Some(i_construct.id), Skill::Attack).unwrap()
|
||||
game.add_skill(i_player.id, i_construct.id, x_construct.id, Skill::Attack).unwrap()
|
||||
.add_skill(i_player.id, j_construct.id, x_construct.id, Skill::Attack).unwrap()
|
||||
.add_skill(x_player.id, x_construct.id, i_construct.id, Skill::Attack).unwrap()
|
||||
.add_skill(x_player.id, y_construct.id, i_construct.id, Skill::Attack).unwrap()
|
||||
.player_ready(i_player.id).unwrap()
|
||||
.player_ready(x_player.id).unwrap();
|
||||
|
||||
@ -1430,10 +1422,10 @@ mod tests {
|
||||
assert!(game.player_by_id(x_player.id).unwrap().skills_required() == 2);
|
||||
|
||||
// add some more skills
|
||||
game.add_skill(i_player.id, j_construct.id, Some(x_construct.id), Skill::Attack).unwrap();
|
||||
game.add_skill(x_player.id, x_construct.id, Some(j_construct.id), Skill::Attack).unwrap();
|
||||
game.add_skill(x_player.id, y_construct.id, Some(j_construct.id), Skill::Attack).unwrap();
|
||||
assert!(game.add_skill(x_player.id, x_construct.id, Some(i_construct.id), Skill::Attack).is_err());
|
||||
game.add_skill(i_player.id, j_construct.id, x_construct.id, Skill::Attack).unwrap();
|
||||
game.add_skill(x_player.id, x_construct.id, j_construct.id, Skill::Attack).unwrap();
|
||||
game.add_skill(x_player.id, y_construct.id, j_construct.id, Skill::Attack).unwrap();
|
||||
assert!(game.add_skill(x_player.id, x_construct.id, i_construct.id, Skill::Attack).is_err());
|
||||
|
||||
game.player_ready(i_player.id).unwrap();
|
||||
game.player_ready(x_player.id).unwrap();
|
||||
@ -1475,7 +1467,7 @@ mod tests {
|
||||
}
|
||||
|
||||
// apply buff
|
||||
game.add_skill(x_player.id, x_construct.id, Some(y_construct.id), Skill::Decay).unwrap();
|
||||
game.add_skill(x_player.id, x_construct.id, y_construct.id, Skill::Decay).unwrap();
|
||||
game.player_ready(x_player.id).unwrap();
|
||||
game.player_ready(y_player.id).unwrap();
|
||||
game = game.resolve_phase_start();
|
||||
@ -1490,7 +1482,7 @@ mod tests {
|
||||
game.resolved.clear();
|
||||
|
||||
// remove
|
||||
game.add_skill(y_player.id, y_construct.id, Some(y_construct.id), Skill::Purify).unwrap();
|
||||
game.add_skill(y_player.id, y_construct.id, y_construct.id, Skill::Purify).unwrap();
|
||||
game.player_ready(x_player.id).unwrap();
|
||||
game.player_ready(y_player.id).unwrap();
|
||||
game = game.resolve_phase_start();
|
||||
@ -1503,14 +1495,14 @@ mod tests {
|
||||
}
|
||||
};
|
||||
|
||||
game.add_skill(y_player.id, x_construct.id, Some(y_construct.id), Skill::Siphon).unwrap();
|
||||
game.add_skill(y_player.id, x_construct.id, y_construct.id, Skill::Siphon).unwrap();
|
||||
game.player_ready(x_player.id).unwrap();
|
||||
game.player_ready(y_player.id).unwrap();
|
||||
game = game.resolve_phase_start();
|
||||
|
||||
game.resolved.clear();
|
||||
|
||||
game.add_skill(y_player.id, y_construct.id, Some(y_construct.id), Skill::Purify).unwrap();
|
||||
game.add_skill(y_player.id, y_construct.id, y_construct.id, Skill::Purify).unwrap();
|
||||
game.player_ready(x_player.id).unwrap();
|
||||
game.player_ready(y_player.id).unwrap();
|
||||
game = game.resolve_phase_start();
|
||||
|
||||
@ -117,7 +117,7 @@ pub fn shapes_write(id: Uuid) -> Result<Uuid, Error> {
|
||||
(ConstructShapes::Circle, 10),
|
||||
(ConstructShapes::Line, 10),
|
||||
(ConstructShapes::V, 10),
|
||||
// (ConstructShapes::Tri, 3),
|
||||
(ConstructShapes::Tri, 10),
|
||||
// (ConstructShapes::Plus, 5),
|
||||
(ConstructShapes::Blank, 1),
|
||||
];
|
||||
@ -155,6 +155,9 @@ pub fn shapes_write(id: Uuid) -> Result<Uuid, Error> {
|
||||
let size = rng.gen_range(20.0, 50.0);
|
||||
write!(&mut svg, "<rect fill=\"{fill}\" x=\"-{x}\" y=\"-{y}\" width=\"{width}\" height=\"{height}\" transform=\"translate({x_t}, {y_t}) rotate({rotation})\" />",
|
||||
fill = colour, x = size / 2.0, y = size / 2.0, width = size, height = size, x_t = x_translate, y_t = y_translate, rotation = rotation)?;
|
||||
if scalar == 0.0 && rng.gen_bool(0.5) {
|
||||
continue;
|
||||
}
|
||||
write!(&mut svg, "<rect fill=\"{fill}\" x=\"-{x}\" y=\"-{y}\" width=\"{width}\" height=\"{height}\" transform=\"translate({x_t}, {y_t}) rotate({rotation})\" />",
|
||||
fill = colour, x = size / 2.0, y = size / 2.0, width = size, height = size, x_t = -x_translate, y_t = -y_translate, rotation = rotation)?;
|
||||
},
|
||||
@ -163,6 +166,9 @@ pub fn shapes_write(id: Uuid) -> Result<Uuid, Error> {
|
||||
let b = rng.gen_range(20.0, 50.0);
|
||||
write!(&mut svg, "<polygon fill=\"{fill}\" x=\"{x}\" y=\"{y}\" points=\"{x0} {y0}, {x1} {y1}, {x2} {y2}\" transform=\"translate({x_translate}, {y_translate}) rotate({rotation})\" />",
|
||||
fill = colour, x = -b / 2.0, y = h / 2.0, x0 = -b / 2.0, y0 = -h / 2.0, x1 = 0, y1 = b / 2.0, x2 = b / 2.0, y2 = -h / 2.0, rotation = rotation, x_translate = x_translate, y_translate = y_translate)?;
|
||||
if scalar == 0.0 && rng.gen_bool(0.5) {
|
||||
continue;
|
||||
}
|
||||
write!(&mut svg, "<polygon fill=\"{fill}\" x=\"{x}\" y=\"{y}\" points=\"{x0} {y0}, {x1} {y1}, {x2} {y2}\" transform=\"translate({x_translate}, {y_translate}) rotate({rotation})\" />",
|
||||
fill = colour, x = -b / 2.0, y = h / 2.0, x0 = -b / 2.0, y0 = -h / 2.0, x1 = 0, y1 = b / 2.0, x2 = b / 2.0, y2 = -h / 2.0, rotation = rotation + 180, x_translate = -x_translate, y_translate = -y_translate)?;
|
||||
},
|
||||
@ -178,6 +184,9 @@ pub fn shapes_write(id: Uuid) -> Result<Uuid, Error> {
|
||||
let height = rng.gen_range(20.0, 50.0);
|
||||
write!(&mut svg, "<rect fill=\"{fill}\" x=\"-{x}\" y=\"-{y}\" width=\"{width}\" height=\"{height}\" transform=\"translate({x_t}, {y_t}) rotate({rotation})\" />",
|
||||
fill = colour, x = width / 2.0, y = height / 2.0, width = width, height = height, x_t = x_translate, y_t = y_translate, rotation = rotation)?;
|
||||
if scalar == 0.0 && rng.gen_bool(0.5) {
|
||||
continue;
|
||||
}
|
||||
write!(&mut svg, "<rect fill=\"{fill}\" x=\"-{x}\" y=\"-{y}\" width=\"{width}\" height=\"{height}\" transform=\"translate({x_t}, {y_t}) rotate({rotation})\" />",
|
||||
fill = colour, x = width / 2.0, y = height / 2.0, width = width, height = height, x_t = -x_translate, y_t = -y_translate, rotation = rotation)?;
|
||||
},
|
||||
@ -188,11 +197,30 @@ pub fn shapes_write(id: Uuid) -> Result<Uuid, Error> {
|
||||
|
||||
write!(&mut svg, "<polyline fill=\"none\" stroke=\"{fill}\" stroke-width=\"{width}\" x=\"{x}\" y=\"{y}\" points=\"{x0} {y0}, {x1} {y1}, {x2} {y2}\" transform=\"translate({x_translate}, {y_translate}) rotate({rotation})\" />",
|
||||
fill = colour, width = width, x = -b / 2.0, y = h / 2.0, x0 = -b / 2.0, y0 = -h / 2.0, x1 = 0, y1 = b / 2.0, x2 = b / 2.0, y2 = -h / 2.0, rotation = rotation, x_translate = x_translate, y_translate = y_translate)?;
|
||||
if scalar == 0.0 && rng.gen_bool(0.5) {
|
||||
continue;
|
||||
}
|
||||
write!(&mut svg, "<polyline fill=\"none\" stroke=\"{fill}\" stroke-width=\"{width}\" x=\"{x}\" y=\"{y}\" points=\"{x0} {y0}, {x1} {y1}, {x2} {y2}\" transform=\"translate({x_translate}, {y_translate}) rotate({rotation})\" />",
|
||||
fill = colour, width = width, x = -b / 2.0, y = h / 2.0, x0 = -b / 2.0, y0 = -h / 2.0, x1 = 0, y1 = b / 2.0, x2 = b / 2.0, y2 = -h / 2.0, rotation = rotation + 180, x_translate = -x_translate, y_translate = -y_translate)?;
|
||||
},
|
||||
ConstructShapes::Tri => {
|
||||
let width = rng.gen_range(2.0, 4.0);
|
||||
let length = rng.gen_range(12.5, 25.0);
|
||||
|
||||
let x0 = (0.0 as f64).cos() * length;
|
||||
let y0 = (0.0 as f64).sin() * length;
|
||||
let x1 = ((f64::consts::PI * 2.0) / 3.0).cos() * length;
|
||||
let y1 = ((f64::consts::PI * 2.0) / 3.0).sin() * length;
|
||||
let x2 = ((f64::consts::PI * 4.0) / 3.0).cos() * length;
|
||||
let y2 = ((f64::consts::PI * 4.0) / 3.0).sin() * length;
|
||||
|
||||
write!(&mut svg, "<path stroke=\"{fill}\" stroke-width=\"{width}\" d=\"M{x0} {y0}L 0 0 M{x1} {y1}L 0 0 M{x2} {y2}L 0 0 \" transform=\"translate({x_translate}, {y_translate}) rotate({rotation})\" />",
|
||||
fill = colour, width = width, x0 = x0, y0 = y0, x1 = x1, y1 = y1, x2 = x2, y2 = y2, rotation = rotation, x_translate = x_translate, y_translate = y_translate)?;
|
||||
if scalar == 0.0 && rng.gen_bool(0.5) {
|
||||
continue;
|
||||
}
|
||||
write!(&mut svg, "<path stroke=\"{fill}\" stroke-width=\"{width}\" d=\"M{x0} {y0}L 0 0 M{x1} {y1}L 0 0 M{x2} {y2}L 0 0 \" transform=\"translate({x_translate}, {y_translate}) rotate({rotation})\" />",
|
||||
fill = colour, width = width, x0 = x0, y0 = y0, x1 = x1, y1 = y1, x2 = x2, y2 = y2, rotation = rotation, x_translate = -x_translate, y_translate = -y_translate)?;
|
||||
},
|
||||
ConstructShapes::Plus => {
|
||||
|
||||
|
||||
@ -62,6 +62,10 @@ pub enum RpcMessage {
|
||||
QueueJoined(()),
|
||||
QueueCancelled(()),
|
||||
|
||||
InviteRequested(()),
|
||||
Invite(String),
|
||||
Joining(()),
|
||||
|
||||
Error(String),
|
||||
}
|
||||
|
||||
@ -78,7 +82,7 @@ pub enum RpcRequest {
|
||||
|
||||
GameState { id: Uuid },
|
||||
GameReady { id: Uuid },
|
||||
GameSkill { game_id: Uuid, construct_id: Uuid, target_construct_id: Option<Uuid>, skill: Skill },
|
||||
GameSkill { game_id: Uuid, construct_id: Uuid, target_construct_id: Uuid, skill: Skill },
|
||||
GameSkillClear { game_id: Uuid },
|
||||
|
||||
AccountState {},
|
||||
@ -91,6 +95,8 @@ pub enum RpcRequest {
|
||||
SubscriptionState {},
|
||||
EmailState {},
|
||||
|
||||
InstanceInvite {},
|
||||
InstanceJoin { code: String },
|
||||
InstanceQueue {},
|
||||
InstancePractice {},
|
||||
InstanceAbandon { instance_id: Uuid },
|
||||
@ -136,99 +142,108 @@ impl Connection {
|
||||
None => return Err(err_msg("auth required")),
|
||||
};
|
||||
|
||||
// evented but authorization required
|
||||
match v {
|
||||
RpcRequest::InstanceQueue {} => {
|
||||
self.events.send(Event::Queue(self.id))?;
|
||||
return Ok(RpcMessage::QueueRequested(()));
|
||||
},
|
||||
_ => (),
|
||||
};
|
||||
|
||||
// all good, let's make a tx and process
|
||||
let mut tx = db.transaction()?;
|
||||
|
||||
let request = v.clone();
|
||||
|
||||
let response = match v {
|
||||
RpcRequest::AccountState {} =>
|
||||
Ok(RpcMessage::AccountState(account.clone())),
|
||||
RpcRequest::AccountConstructs {} =>
|
||||
Ok(RpcMessage::AccountConstructs(account::constructs(&mut tx, &account)?)),
|
||||
RpcRequest::AccountInstances {} =>
|
||||
Ok(RpcMessage::AccountInstances(account::account_instances(&mut tx, account)?)),
|
||||
RpcRequest::AccountSetTeam { ids } =>
|
||||
Ok(RpcMessage::AccountTeam(account::set_team(&mut tx, &account, ids)?)),
|
||||
// evented but authorization required
|
||||
RpcRequest::InstanceQueue {} => {
|
||||
self.events.send(Event::Queue(self.id))?;
|
||||
Ok(RpcMessage::QueueRequested(()))
|
||||
},
|
||||
RpcRequest::InstanceInvite {} => {
|
||||
self.events.send(Event::Invite(self.id))?;
|
||||
Ok(RpcMessage::InviteRequested(()))
|
||||
},
|
||||
RpcRequest::InstanceJoin { code } => {
|
||||
self.events.send(Event::Join(self.id, code))?;
|
||||
Ok(RpcMessage::Joining(()))
|
||||
},
|
||||
_ => {
|
||||
// all good, let's make a tx and process
|
||||
let mut tx = db.transaction()?;
|
||||
|
||||
RpcRequest::EmailState {} =>
|
||||
Ok(RpcMessage::EmailState(mail::select_account(&db, account.id)?)),
|
||||
let res = match v {
|
||||
RpcRequest::AccountState {} =>
|
||||
Ok(RpcMessage::AccountState(account.clone())),
|
||||
RpcRequest::AccountConstructs {} =>
|
||||
Ok(RpcMessage::AccountConstructs(account::constructs(&mut tx, &account)?)),
|
||||
RpcRequest::AccountInstances {} =>
|
||||
Ok(RpcMessage::AccountInstances(account::account_instances(&mut tx, account)?)),
|
||||
RpcRequest::AccountSetTeam { ids } =>
|
||||
Ok(RpcMessage::AccountTeam(account::set_team(&mut tx, &account, ids)?)),
|
||||
|
||||
RpcRequest::SubscriptionState {} =>
|
||||
Ok(RpcMessage::SubscriptionState(payments::account_subscription(&db, &self.stripe, &account)?)),
|
||||
RpcRequest::EmailState {} =>
|
||||
Ok(RpcMessage::EmailState(mail::select_account(&db, account.id)?)),
|
||||
|
||||
// RpcRequest::AccountShop {} =>
|
||||
// Ok(RpcMessage::AccountShop(mtx::account_shop(&mut tx, &account)?)),
|
||||
RpcRequest::SubscriptionState {} =>
|
||||
Ok(RpcMessage::SubscriptionState(payments::account_subscription(&db, &self.stripe, &account)?)),
|
||||
|
||||
// RpcRequest::ConstructDelete" => handle_construct_delete(data, &mut tx, account),
|
||||
// RpcRequest::AccountShop {} =>
|
||||
// Ok(RpcMessage::AccountShop(mtx::account_shop(&mut tx, &account)?)),
|
||||
|
||||
RpcRequest::GameState { id } =>
|
||||
Ok(RpcMessage::GameState(game_state(&mut tx, account, id)?)),
|
||||
// RpcRequest::ConstructDelete" => handle_construct_delete(data, &mut tx, account),
|
||||
|
||||
RpcRequest::GameSkill { game_id, construct_id, target_construct_id, skill } =>
|
||||
Ok(RpcMessage::GameState(game_skill(&mut tx, account, game_id, construct_id, target_construct_id, skill)?)),
|
||||
RpcRequest::GameState { id } =>
|
||||
Ok(RpcMessage::GameState(game_state(&mut tx, account, id)?)),
|
||||
|
||||
RpcRequest::GameSkillClear { game_id } =>
|
||||
Ok(RpcMessage::GameState(game_skill_clear(&mut tx, account, game_id)?)),
|
||||
RpcRequest::GameSkill { game_id, construct_id, target_construct_id, skill } =>
|
||||
Ok(RpcMessage::GameState(game_skill(&mut tx, account, game_id, construct_id, target_construct_id, skill)?)),
|
||||
|
||||
RpcRequest::GameReady { id } =>
|
||||
Ok(RpcMessage::GameState(game_ready(&mut tx, account, id)?)),
|
||||
RpcRequest::GameSkillClear { game_id } =>
|
||||
Ok(RpcMessage::GameState(game_skill_clear(&mut tx, account, game_id)?)),
|
||||
|
||||
RpcRequest::InstancePractice {} =>
|
||||
Ok(RpcMessage::InstanceState(instance_practice(&mut tx, account)?)),
|
||||
RpcRequest::GameReady { id } =>
|
||||
Ok(RpcMessage::GameState(game_ready(&mut tx, account, id)?)),
|
||||
|
||||
// these two can return GameState or InstanceState
|
||||
RpcRequest::InstanceReady { instance_id } =>
|
||||
Ok(instance_ready(&mut tx, account, instance_id)?),
|
||||
RpcRequest::InstanceState { instance_id } =>
|
||||
Ok(instance_state(&mut tx, instance_id)?),
|
||||
RpcRequest::InstanceAbandon { instance_id } =>
|
||||
Ok(instance_abandon(&mut tx, account, instance_id)?),
|
||||
RpcRequest::InstancePractice {} =>
|
||||
Ok(RpcMessage::InstanceState(instance_practice(&mut tx, account)?)),
|
||||
|
||||
RpcRequest::VboxAccept { instance_id, group, index } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_accept(&mut tx, account, instance_id, group, index)?)),
|
||||
// these two can return GameState or InstanceState
|
||||
RpcRequest::InstanceReady { instance_id } =>
|
||||
Ok(instance_ready(&mut tx, account, instance_id)?),
|
||||
RpcRequest::InstanceState { instance_id } =>
|
||||
Ok(instance_state(&mut tx, instance_id)?),
|
||||
RpcRequest::InstanceAbandon { instance_id } =>
|
||||
Ok(instance_abandon(&mut tx, account, instance_id)?),
|
||||
|
||||
RpcRequest::VboxApply { instance_id, construct_id, index } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_apply(&mut tx, account, instance_id, construct_id, index)?)),
|
||||
RpcRequest::VboxAccept { instance_id, group, index } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_accept(&mut tx, account, instance_id, group, index)?)),
|
||||
|
||||
RpcRequest::VboxCombine { instance_id, indices } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_combine(&mut tx, account, instance_id, indices)?)),
|
||||
RpcRequest::VboxApply { instance_id, construct_id, index } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_apply(&mut tx, account, instance_id, construct_id, index)?)),
|
||||
|
||||
RpcRequest::VboxDiscard { instance_id } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_discard(&mut tx, account, instance_id)?)),
|
||||
RpcRequest::VboxCombine { instance_id, indices } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_combine(&mut tx, account, instance_id, indices)?)),
|
||||
|
||||
RpcRequest::VboxReclaim { instance_id, index } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_reclaim(&mut tx, account, instance_id, index)?)),
|
||||
RpcRequest::VboxDiscard { instance_id } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_discard(&mut tx, account, instance_id)?)),
|
||||
|
||||
RpcRequest::VboxUnequip { instance_id, construct_id, target } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_unequip(&mut tx, account, instance_id, construct_id, target)?)),
|
||||
RpcRequest::VboxReclaim { instance_id, index } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_reclaim(&mut tx, account, instance_id, index)?)),
|
||||
|
||||
RpcRequest::MtxConstructSpawn {} =>
|
||||
Ok(RpcMessage::ConstructSpawn(mtx::new_construct(&mut tx, account)?)),
|
||||
RpcRequest::VboxUnequip { instance_id, construct_id, target } =>
|
||||
Ok(RpcMessage::InstanceState(vbox_unequip(&mut tx, account, instance_id, construct_id, target)?)),
|
||||
|
||||
RpcRequest::MtxConstructApply { mtx, construct_id, name } =>
|
||||
Ok(RpcMessage::AccountTeam(mtx::apply(&mut tx, account, mtx, construct_id, name)?)),
|
||||
RpcRequest::MtxConstructSpawn {} =>
|
||||
Ok(RpcMessage::ConstructSpawn(mtx::new_construct(&mut tx, account)?)),
|
||||
|
||||
RpcRequest::MtxBuy { mtx } =>
|
||||
Ok(RpcMessage::AccountShop(mtx::buy(&mut tx, account, mtx)?)),
|
||||
RpcRequest::MtxConstructApply { mtx, construct_id, name } =>
|
||||
Ok(RpcMessage::AccountTeam(mtx::apply(&mut tx, account, mtx, construct_id, name)?)),
|
||||
|
||||
RpcRequest::SubscriptionEnding { ending } =>
|
||||
Ok(RpcMessage::SubscriptionState(payments::subscription_ending(&mut tx, &self.stripe, account, ending)?)),
|
||||
RpcRequest::MtxBuy { mtx } =>
|
||||
Ok(RpcMessage::AccountShop(mtx::buy(&mut tx, account, mtx)?)),
|
||||
|
||||
_ => Err(format_err!("unknown request request={:?}", request)),
|
||||
RpcRequest::SubscriptionEnding { ending } =>
|
||||
Ok(RpcMessage::SubscriptionState(payments::subscription_ending(&mut tx, &self.stripe, account, ending)?)),
|
||||
|
||||
_ => Err(format_err!("unknown request request={:?}", request)),
|
||||
};
|
||||
|
||||
tx.commit()?;
|
||||
res
|
||||
}
|
||||
};
|
||||
|
||||
tx.commit()?;
|
||||
|
||||
info!("request={:?} account={:?} duration={:?}", request, account.name, begin.elapsed());
|
||||
|
||||
return response;
|
||||
|
||||
@ -1213,20 +1213,6 @@ impl Skill {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn self_targeting(&self) -> bool {
|
||||
match self {
|
||||
Skill::Block |
|
||||
Skill::Sustain|
|
||||
Skill::SustainPlus |
|
||||
Skill::SustainPlusPlus |
|
||||
Skill::Counter|
|
||||
Skill::CounterPlus |
|
||||
Skill::CounterPlusPlus => true,
|
||||
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn defensive(&self) -> bool {
|
||||
let mut rng = thread_rng();
|
||||
|
||||
|
||||
@ -90,6 +90,10 @@ impl Warden {
|
||||
fn on_match(&mut self, pair: Pair) -> Result<(), Error> {
|
||||
info!("received pair={:?}", pair);
|
||||
|
||||
// clear pvp status
|
||||
self.events.send(Event::Joined(pair.0.id))?;
|
||||
self.events.send(Event::Joined(pair.1.id))?;
|
||||
|
||||
let db = self.pool.get()?;
|
||||
let mut tx = db.transaction()?;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user