2021-01-25 22:06:12 +00:00
import Command from "../../../core/command" ;
import $ from "../../../core/lib" ;
import { Storage } from "../../../core/structures" ;
import { isAuthorized , getMoneyEmbed , getSendEmbed , ECO_EMBED_COLOR } from "./eco-utils" ;
export const BetCommand = new Command ( {
description : "Bet your Mons with other people [TBD]" ,
usage : "<user> <amount> <duration>" ,
run : "Who are you betting with?" ,
user : new Command ( {
2021-01-26 15:28:04 +00:00
// handles missing amount argument
async run ( { args , author , channel , guild } ) : Promise < any > {
if ( isAuthorized ( guild , channel ) ) {
const target = args [ 0 ] ;
// handle invalid target
if ( target . id == author . id )
return channel . send ( "You can't bet Mons with yourself!" ) ;
else if ( target . bot && process . argv [ 2 ] !== "dev" )
return channel . send ( "You can't bet Mons with a bot!" ) ;
return channel . send ( "How much are you betting?" ) ;
}
} ,
2021-01-25 22:06:12 +00:00
number : new Command ( {
2021-01-26 15:28:04 +00:00
// handles missing duration argument
async run ( { args , author , channel , guild } ) : Promise < any > {
if ( isAuthorized ( guild , channel ) ) {
const sender = Storage . getUser ( author . id ) ;
const target = args [ 0 ] ;
const receiver = Storage . getUser ( target ) ;
const amount = Math . floor ( args [ 1 ] ) ;
// handle invalid target
if ( target . id == author . id )
return channel . send ( "You can't bet Mons with yourself!" ) ;
else if ( target . bot && process . argv [ 2 ] !== "dev" )
return channel . send ( "You can't bet Mons with a bot!" ) ;
// handle invalid amount
if ( amount <= 0 )
return channel . send ( "You must bet at least one Mon!" ) ;
else if ( sender . money < amount )
return channel . send ( "You don't have enough Mons for that." , getMoneyEmbed ( author ) ) ;
return channel . send ( "How long until the bet ends?" ) ;
}
} ,
2021-01-25 22:06:12 +00:00
any : new Command ( {
2021-01-26 15:28:04 +00:00
async run ( { client , args , author , channel , guild } ) : Promise < any > {
2021-01-25 22:06:12 +00:00
if ( isAuthorized ( guild , channel ) ) {
const sender = Storage . getUser ( author . id ) ;
const target = args [ 0 ] ;
const receiver = Storage . getUser ( target ) ;
const amount = Math . floor ( args [ 1 ] ) ;
const duration = parseDuration ( args [ 2 ] . trim ( ) ) ;
2021-01-26 15:28:04 +00:00
// handle invalid target
if ( target . id == author . id )
return channel . send ( "You can't bet Mons with yourself!" ) ;
2021-01-25 22:06:12 +00:00
else if ( target . bot && process . argv [ 2 ] !== "dev" )
return channel . send ( "You can't bet Mons with a bot!" ) ;
2021-01-26 15:28:04 +00:00
// handle invalid amount
if ( amount <= 0 )
return channel . send ( "You must bet at least one Mon!" ) ;
else if ( sender . money < amount )
return channel . send ( "You don't have enough Mons for that." , getMoneyEmbed ( author ) ) ;
// handle invalid duration
2021-01-25 22:06:12 +00:00
if ( duration <= 0 )
return channel . send ( "Invalid duration" ) ;
// else if (duration <= {threshold})
// return channel.send("Too short idk");
// else if (duration >= {threshold})
// return channel.send("Too long idk");
2021-01-26 15:28:04 +00:00
// [Potential pertinence to use the ask later on?]
// Ask target whether or not they want to take the bet.
2021-01-25 22:06:12 +00:00
const msg = await channel . send ( ` <@ ${ target . id } >, do you want to take this bet of ${ $ ( amount ) . pluralise ( "Mon" , "s" ) } ` ) ;
await msg . react ( "✅" ) ;
await msg . react ( "⛔" ) ;
2021-01-26 15:28:04 +00:00
// Wait for a reaction.
msg . awaitReactions (
2021-01-25 22:06:12 +00:00
async ( reaction , user ) = > {
2021-01-26 15:28:04 +00:00
// If target accepts: set bet up.
2021-01-25 22:06:12 +00:00
if ( user . id === target . id && reaction . emoji . name === "✅" ) {
2021-01-26 15:28:04 +00:00
// [ISSUE: volatile storage]
// Remove amount money from both parts to avoid duplication of money.
2021-01-25 22:06:12 +00:00
sender . money -= amount ;
receiver . money -= amount ;
2021-01-26 17:11:50 +00:00
Storage . save ( ) ;
2021-01-25 22:06:12 +00:00
2021-01-26 15:28:04 +00:00
// Notify both users.
await channel . send ( ` <@ ${ target . id } > has taken <@ ${ author . id } >'s bet, the bet amount of ${ $ ( amount ) . pluralise ( "Mon" , "s" ) } has been deducted from each of them. ` ) ;
// Wait for the duration of the bet.
2021-01-25 22:06:12 +00:00
client . setTimeout ( async ( ) = > {
2021-01-26 15:28:04 +00:00
// [Pertinence to reference the invocation message to let people find the bet more easily]
// When bet is over, give a vote to ask people their thoughts.
const voteMsg = await channel . send ( ` VOTE: do you think that <@ ${ target . id } > has won the bet? ` ) ;
2021-01-25 22:06:12 +00:00
await voteMsg . react ( "✅" ) ;
await voteMsg . react ( "⛔" ) ;
2021-01-26 15:28:04 +00:00
// Filter reactions to only collect the pertinent ones.
2021-01-25 22:06:12 +00:00
voteMsg . awaitReactions (
( reaction , user ) = > {
return [ "✅" , "⛔" ] . includes ( reaction . emoji . name ) ;
} ,
2021-01-26 15:28:04 +00:00
// [Pertinence to make configurable on the fly.]
{ time : parseDuration ( "2m" ) }
2021-01-25 22:06:12 +00:00
) . then ( reactions = > {
2021-01-26 15:28:04 +00:00
// Count votes
const ok = reactions . filter ( reaction = > reaction . emoji . name === "✅" ) . size ;
const no = reactions . filter ( reaction = > reaction . emoji . name === "⛔" ) . size ;
if ( ok > no ) {
receiver . money += amount * 2 ;
channel . send ( ` By the people's votes, <@ ${ target . id } > has won the bet that <@ ${ author . id } > had sent them. ` ) ;
}
else if ( ok < no ) {
sender . money += amount * 2 ;
channel . send ( ` By the people's votes, <@ ${ target . id } > has lost the bet that <@ ${ author . id } > had sent them. ` ) ;
}
2021-01-25 22:06:12 +00:00
else {
sender . money += amount ;
receiver . money += amount ;
2021-01-26 15:28:04 +00:00
channel . send ( ` By the people's votes, <@ ${ target . id } > couldn't be determined to have won or lost the bet that <@ ${ author . id } > had sent them. ` ) ;
2021-01-25 22:06:12 +00:00
}
2021-01-26 17:11:50 +00:00
Storage . save ( ) ;
2021-01-25 22:06:12 +00:00
} ) ;
} , duration ) ;
}
2021-01-26 15:28:04 +00:00
// If target refuses: notify and stop.
else if ( user . id === target . id && reaction . emoji . name === "⛔" )
await channel . send ( ` <@ ${ target . id } > has rejected your bet, <@ ${ author . id } > ` ) ;
2021-01-25 22:06:12 +00:00
return false ;
} ,
2021-01-26 15:28:04 +00:00
// [Lesser pertinence to make configurable on the fly.]
// Wait for a minute, and delete the asking message after that.
2021-01-25 22:06:12 +00:00
{ time : 60000 }
2021-01-26 15:28:04 +00:00
) . then ( ( ) = > msg . delete ( ) ) ;
2021-01-25 22:06:12 +00:00
}
}
} )
} )
} )
} ) ;
/ * *
* Parses a duration string into milliseconds
* Examples :
2021-01-26 15:28:04 +00:00
* - 3 d - > 3 days - > 259200000 ms
* - 2 h - > 2 hours - > 7200000 ms
* - 7 m - > 7 minutes - > 420000 ms
2021-01-25 22:06:12 +00:00
* - 3 s - > 3 seconds - > 3000 ms
* /
function parseDuration ( duration : string ) : number {
// extract last char as unit
const unit = duration [ duration . length - 1 ] . toLowerCase ( ) ;
// get the rest as value
let value : number = + duration . substring ( 0 , duration . length - 1 ) ;
if ( ! [ "d" , "h" , "m" , "s" ] . includes ( unit ) || isNaN ( value ) )
return 0 ;
if ( unit === "d" )
value *= 86400000 ; // 1000ms * 60s * 60m * 24h
else if ( unit === "h" )
value *= 3600000 ; // 1000ms * 60s * 60m
else if ( unit === "m" )
value *= 60000 ; // 1000ms * 60s
else if ( unit === "s" )
value *= 1000 ; // 1000ms
return value ;
}