2018-10-21 13:57:23 +02:00
package wat
import (
"fmt"
"time"
"strings"
"strconv"
2018-10-26 13:40:02 +02:00
"crypto/rand"
"math/big"
2018-10-21 13:57:23 +02:00
"github.com/go-irc/irc"
)
type WatGame struct {
bot * WatBot
db * WatDb
2018-10-23 03:36:02 +02:00
me Player
2018-10-23 01:15:28 +02:00
commands map [ string ] ( func ( * Player , [ ] string ) ( string ) )
lifeCommands map [ string ] ( func ( * Player , [ ] string ) ( string ) )
2018-10-21 13:57:23 +02:00
}
func NewWatGame ( bot * WatBot , db * WatDb ) * WatGame {
2018-10-23 03:36:02 +02:00
g := WatGame { bot , db , Player { } , nil , nil }
g . me = g . db . User ( bot . Nick , "tripsit/user/" + bot . Nick , true )
2018-10-23 01:15:28 +02:00
g . commands = map [ string ] ( func ( * Player , [ ] string ) ( string ) ) {
"wat" : g . megaWat ,
"watch" : g . Watch ,
2018-10-25 02:04:35 +02:00
"coins" : g . Balance ,
2018-10-23 01:15:28 +02:00
"send" : g . Send ,
2018-10-23 03:36:02 +02:00
"rest" : g . Rest ,
"leech" : g . Leech ,
"roll" : g . Roll ,
"dice" : g . Dice ,
2018-10-25 02:04:35 +02:00
"mine" : g . Mine ,
2018-10-23 01:15:28 +02:00
}
g . lifeCommands = map [ string ] ( func ( * Player , [ ] string ) ( string ) ) {
"steal" : g . Steal ,
"frame" : g . Frame ,
"punch" : g . Punch ,
"quest" : g . QuestStart ,
}
return & g
2018-10-21 13:57:23 +02:00
}
var currency = "watcoin"
var currencys = "watcoins"
2018-10-23 03:36:02 +02:00
var unconscious = "wat, your hands fumble and fail you. try resting, weakling."
2018-10-26 13:40:02 +02:00
var helpText = fmt . Sprintf ( "coins <nick>, watch <nick>, topten, mine, send <nick> <%s>, roll <%s>, steal <nick> <%s>, frame <nick> <%s>, punch <nick>" , currency , currency , currency , currency )
2018-10-21 13:57:23 +02:00
var rules = "A new account is created with 5 hours time credit. Mining exchanges time credit for %s: 1-10h: 1 p/h; >10h: 10 p/h; >1 day: 50 p/h; >1 month: 1000 p/h."
2018-10-23 01:15:28 +02:00
2018-10-21 13:57:23 +02:00
// missing
// invent, create, give inventory
func ( g * WatGame ) Msg ( m * irc . Message , player * Player , fields [ ] string ) {
reply := ""
2018-10-23 01:15:28 +02:00
if g . commands [ fields [ 0 ] ] != nil {
reply = g . commands [ fields [ 0 ] ] ( player , fields )
} else {
2018-10-25 02:04:35 +02:00
// one liners
2018-10-23 01:15:28 +02:00
switch strings . ToLower ( fields [ 0 ] ) {
case "rules" :
reply = rules
case "help" :
reply = helpText
case "topten" :
reply = fmt . Sprintf ( "%s holders: %s" , currency , g . TopTen ( ) )
}
}
if g . lifeCommands [ fields [ 0 ] ] != nil {
2018-10-21 13:57:23 +02:00
if ! player . Conscious ( ) {
reply = unconscious
} else {
2018-10-23 01:15:28 +02:00
reply = g . lifeCommands [ fields [ 0 ] ] ( player , fields )
2018-10-21 13:57:23 +02:00
}
}
g . bot . reply ( m , reply )
}
2018-10-26 13:40:02 +02:00
func ( g * WatGame ) RandInt ( max int64 ) int64 {
i , _ := rand . Int ( rand . Reader , big . NewInt ( max ) )
return i . Int64 ( )
}
2018-10-23 03:36:02 +02:00
func ( g * WatGame ) Dice ( player * Player , fields [ ] string ) string {
roll := int64 ( 6 )
if len ( fields ) > 1 {
i , e := g . Int ( fields [ 1 ] )
if e == nil {
roll = i
}
}
2018-10-26 13:40:02 +02:00
answer := g . RandInt ( roll ) + 1
2018-10-23 03:36:02 +02:00
return fmt . Sprintf ( "1d%d - %d" , roll , answer )
}
2018-10-23 01:15:28 +02:00
type PositiveError struct { }
func ( e PositiveError ) Error ( ) string { return "" }
func ( g * WatGame ) Int ( str string ) ( int64 , error ) {
i , e := strconv . ParseInt ( str , 10 , 64 )
if i < 0 {
return 0 , PositiveError { }
2018-10-21 13:57:23 +02:00
}
2018-10-23 01:15:28 +02:00
return i , e
2018-10-21 13:57:23 +02:00
}
func ( g * WatGame ) Roll ( player * Player , fields [ ] string ) string {
if len ( fields ) < 2 {
2018-10-26 13:40:02 +02:00
return fmt . Sprintf ( "roll <%s> pls - u must score < 50 if u want 2 win" , currency )
2018-10-21 13:57:23 +02:00
}
2018-10-23 01:15:28 +02:00
amount , e := g . Int ( fields [ 1 ] )
2018-10-21 13:57:23 +02:00
if e != nil {
2018-10-25 02:04:35 +02:00
return "wat kinda number is that"
2018-10-21 13:57:23 +02:00
}
if amount > player . Coins {
return "wat? brokeass"
}
2018-10-26 13:40:02 +02:00
n := g . RandInt ( 100 ) + 1
ret := fmt . Sprintf ( "%s rolls a 1d100... %d! " , player . Nick , n )
2018-10-21 13:57:23 +02:00
if n < 50 {
2018-10-23 01:15:28 +02:00
player . Coins += amount
2018-10-26 13:40:02 +02:00
ret += fmt . Sprintf ( "You win! total: %d %s" , player . Coins , currency )
2018-10-21 13:57:23 +02:00
} else {
2018-10-26 13:40:02 +02:00
player . LoseCoins ( amount )
g . me . Coins += amount
g . db . Update ( g . me )
ret += fmt . Sprintf ( "You lose! %d %s left..." , player . Coins , currency )
2018-10-21 13:57:23 +02:00
}
g . db . Update ( player )
return ret
}
func ( g * WatGame ) Punch ( player * Player , fields [ ] string ) string {
if len ( fields ) < 2 {
return "punch <target> pls"
}
target , err := g . GetTarget ( player . Nick , fields [ 1 ] )
if err != "" {
return err
}
2018-10-26 13:40:02 +02:00
chance := g . RandInt ( 6 ) + 1
dmg := g . RandInt ( 6 ) + 1
2018-10-25 02:04:35 +02:00
ret := fmt . Sprintf ( "%s rolls a d6... %s " , player . Nick , player . Nick )
if chance > 3 {
2018-10-23 03:36:02 +02:00
dmg += player . Level ( player . Anarchy )
2018-10-27 15:05:12 +02:00
ret += fmt . Sprintf ( "hits %s for %d points of damage! " , target . Nick , dmg )
2018-10-21 13:57:23 +02:00
target . Health -= dmg
g . db . Update ( target )
2018-10-25 02:04:35 +02:00
if target . Health <= 0 {
ret += target . Nick + " has fallen unconscious."
}
2018-10-21 13:57:23 +02:00
} else {
2018-10-25 02:04:35 +02:00
ret += fmt . Sprintf ( "fumbles, and punches themselves in confusion! %d self-damage. " , dmg )
2018-10-21 13:57:23 +02:00
player . Health -= dmg
if player . Health <= 0 {
ret += player . Nick + " has fallen unconscious."
}
g . db . Update ( player )
}
return ret
}
func ( g * WatGame ) Frame ( player * Player , fields [ ] string ) string {
if len ( fields ) < 3 {
2018-10-23 03:36:02 +02:00
return fmt . Sprintf ( "frame <nick> <%s> - d6 roll. Sneaky? You force the target to pay me. Clumsy? You pay a fine to the target and myself." , currency )
2018-10-21 13:57:23 +02:00
}
2018-10-23 01:15:28 +02:00
amount , e := g . Int ( fields [ 2 ] )
2018-10-21 13:57:23 +02:00
if amount <= 0 || e != nil {
return "wat kinda number is " + fields [ 2 ] + "?"
}
if player . Coins < amount {
return "wat? you too poor for that."
}
target , err := g . GetTarget ( player . Nick , fields [ 1 ] )
if err != "" {
return err
}
if target . Coins < amount {
return fmt . Sprintf ( "wat? %s is too poor for this." , target . Nick )
}
2018-10-26 13:40:02 +02:00
n := g . RandInt ( 6 ) + 1
2018-10-21 13:57:23 +02:00
ret := fmt . Sprintf ( "%s rolls a d6 to frame %s with %d %s: It's a %d! (<3 wins). " , player . Nick , target . Nick , amount , currency , n )
if n < 3 {
2018-10-23 03:36:02 +02:00
ret += fmt . Sprintf ( "You frame %s for a minor crime. They pay me %d." , target . Nick , amount )
2018-10-21 13:57:23 +02:00
player . Anarchy += 1
target . Coins -= amount
} else {
2018-10-23 03:36:02 +02:00
ret += fmt . Sprintf ( "You were caught and pay them %d. %s gets the rest." , ( amount / 2 ) , g . bot . Nick )
2018-10-26 13:40:02 +02:00
player . LoseCoins ( amount )
2018-10-21 13:57:23 +02:00
target . Coins += amount / 2
2018-10-23 03:36:02 +02:00
g . me . Coins += amount / 2
g . db . Update ( g . me )
2018-10-21 13:57:23 +02:00
}
g . db . Update ( player )
g . db . Update ( target )
return ret
}
func ( g * WatGame ) Steal ( player * Player , fields [ ] string ) string {
if len ( fields ) < 3 {
2018-10-23 03:36:02 +02:00
return fmt . Sprintf ( "steal <nick> <%s> - d6 roll. If you fail, you pay double the %s to %s" , currency , currency , g . bot . Nick )
2018-10-21 13:57:23 +02:00
}
2018-10-23 01:15:28 +02:00
amount , e := g . Int ( fields [ 2 ] )
2018-10-21 13:57:23 +02:00
if amount <= 0 || e != nil {
return "wat kinda number is " + fields [ 2 ] + "?"
}
if player . Coins < amount * 2 {
return "wat? You'd go bankrupt if they steal back..."
}
target , err := g . GetTarget ( player . Nick , fields [ 1 ] )
if target == nil {
return err
}
if target . Coins < amount {
2018-10-25 02:04:35 +02:00
return fmt . Sprintf ( "wat? %s is poor and doesn't have that much to steal. (%d %s)" , target . Nick , target . Coins , currency )
2018-10-21 13:57:23 +02:00
}
2018-10-26 13:40:02 +02:00
n := g . RandInt ( 6 ) + 1
2018-10-23 03:36:02 +02:00
ret := fmt . Sprintf ( "%s is trying to steal %d %s from %s... " , player . Nick , amount , currency , target . Nick )
2018-10-21 13:57:23 +02:00
if n < 3 {
2018-10-25 02:04:35 +02:00
ret += "You did it! Sneaky bastard!"
2018-10-21 13:57:23 +02:00
player . Coins += amount
player . Anarchy += 1
target . Coins -= amount
g . db . Update ( target )
} else {
2018-10-25 02:04:35 +02:00
ret += fmt . Sprintf ( "You were caught and I took %d %s from your pocket." , ( amount * 2 ) , currency )
2018-10-26 13:40:02 +02:00
player . LoseCoins ( amount * 2 )
2018-10-25 02:04:35 +02:00
g . me . Coins += amount * 2
g . db . Update ( g . me )
2018-10-21 13:57:23 +02:00
}
g . db . Update ( player )
return ret
}
func ( g * WatGame ) GetTarget ( player , target string ) ( * Player , string ) {
2018-10-23 01:15:28 +02:00
t := g . db . User ( strings . ToLower ( target ) , "" , false )
2018-10-21 13:57:23 +02:00
if t . Nick == "" {
2018-10-23 01:15:28 +02:00
return nil , "Who? wat?"
2018-10-21 13:57:23 +02:00
}
if t . Nick == player {
2018-10-25 02:04:35 +02:00
return nil , "You can't do that to yourself, silly."
2018-10-21 13:57:23 +02:00
}
return & t , ""
}
2018-10-23 03:36:02 +02:00
func ( g * WatGame ) Leech ( player * Player , fields [ ] string ) string {
divisor := int64 ( 10 )
if len ( fields ) < 3 {
2018-10-25 02:04:35 +02:00
return fmt . Sprintf ( "leech <nick> <%s> - using your wealth, you steal the life force of another player" , currency )
2018-10-23 03:36:02 +02:00
}
amount , er := g . Int ( fields [ 2 ] )
if amount < divisor {
2018-10-25 02:04:35 +02:00
return fmt . Sprintf ( "wat? its %d %s for 1 hp" , divisor , currency )
2018-10-23 03:36:02 +02:00
}
if player . Coins < amount || er != nil {
return "wat great fortune do you think you have? poor wats shouldn't be doing this, wat a waste..."
}
target , err := g . GetTarget ( player . Nick , fields [ 1 ] )
if err != "" {
return err
}
2018-10-26 13:40:02 +02:00
r := g . RandInt ( 10 ) + 1
2018-10-23 03:36:02 +02:00
reply := fmt . Sprintf ( "You muster your wealth and feed it to %s. " , g . bot . Nick )
hpDown := amount / divisor
player . Coins -= amount
if r < 5 {
target . Health -= hpDown
player . Health += hpDown
2018-10-25 02:04:35 +02:00
player . Anarchy += 1
reply += fmt . Sprintf ( "The deal is done, you took %d HP from %s. They now have %d HP, you have %d." , hpDown , target . Nick , target . Health , player . Health )
2018-10-27 15:05:12 +02:00
g . db . Update ( target )
g . db . Update ( player )
2018-10-23 03:36:02 +02:00
} else {
reply += "The gods do not smile upon you this waturday. Your money vanishes and nothing happens."
}
return reply
}
func ( g * WatGame ) Rest ( player * Player , fields [ ] string ) string {
2018-10-25 02:04:35 +02:00
minRest := int64 ( 43200 )
2018-10-23 03:36:02 +02:00
delta := time . Now ( ) . Unix ( ) - player . LastRested
ret := ""
if player . LastRested == 0 {
ret = "you've never slept before - you sleep so well, your injuries are cured and your health is restored to 10"
player . Health = 10
2018-10-26 13:40:02 +02:00
player . LastRested = time . Now ( ) . Unix ( )
g . db . Update ( player )
2018-10-23 03:36:02 +02:00
} else if delta < minRest {
ret = fmt . Sprintf ( "wat were you thinking, sleeping at a time like this (%d until next rest)" , minRest - delta )
} else {
2018-10-26 13:40:02 +02:00
value := g . RandInt ( 10 ) + 1
2018-10-23 03:36:02 +02:00
ret = fmt . Sprintf ( "wat a nap - have back a random amount of hitpoints (this time it's %d)" , value )
2018-10-26 13:40:02 +02:00
player . LastRested = time . Now ( ) . Unix ( )
player . Health += value
g . db . Update ( player )
2018-10-23 03:36:02 +02:00
}
return ret
}
2018-10-23 01:15:28 +02:00
func ( g * WatGame ) QuestStart ( player * Player , fields [ ] string ) string {
// Begin a quest with some people. It will involve multiple dice rolls.
return ""
}
2018-10-21 13:57:23 +02:00
func ( g * WatGame ) Send ( player * Player , fields [ ] string ) string {
if len ( fields ) < 3 {
return fmt . Sprintf ( "You forgot somethin'. send <nick> <%s>" , currency )
}
amount , err := strconv . Atoi ( fields [ 2 ] )
if err != nil {
return fields [ 2 ] + " is not an integer, wat?"
}
if int64 ( amount ) > player . Coins {
2018-10-25 02:04:35 +02:00
return "wat? you're too poor!"
2018-10-21 13:57:23 +02:00
}
target , str := g . GetTarget ( player . Nick , fields [ 1 ] )
if target == nil {
return str
}
player . Coins -= int64 ( amount )
target . Coins += int64 ( amount )
g . db . Update ( player )
g . db . Update ( target )
2018-10-26 13:40:02 +02:00
return fmt . Sprintf ( "%s sent %s %d %s. %s has %d %s, %s has %d %s" , player . Nick , target . Nick , amount , currency , player . Nick , player . Coins , currency , target . Nick , target . Coins , currency )
2018-10-21 13:57:23 +02:00
}
2018-10-25 02:04:35 +02:00
func ( g * WatGame ) Mine ( player * Player , _ [ ] string ) string {
2018-10-21 13:57:23 +02:00
delta := time . Now ( ) . Unix ( ) - player . LastMined
2018-10-27 15:05:12 +02:00
if delta < 600 {
2018-10-26 13:40:02 +02:00
return fmt . Sprintf ( "wat? 2 soon. u earn more when u wait long (%d)" , delta )
2018-10-21 13:57:23 +02:00
}
value := int64 ( 0 )
if delta < 36000 {
2018-10-27 15:05:12 +02:00
value = delta / 600
2018-10-21 13:57:23 +02:00
} else if delta < 86400 {
value = 10
} else if delta < 2592000 {
value = 50
} else {
value = 1000
}
msg := ""
if player . LastMined == 0 {
msg = "with wat? you go to get a pickaxe"
value = 0
} else {
2018-10-23 01:15:28 +02:00
player . Coins += value
2018-10-21 13:57:23 +02:00
msg = fmt . Sprintf ( "%s mined %d %s for %d and has %d %s" , player . Nick , value , currency , delta , player . Coins , currency )
}
player . LastMined = time . Now ( ) . Unix ( )
g . db . Update ( player )
return msg
}
2018-10-23 01:15:28 +02:00
func ( g * WatGame ) Watch ( player * Player , fields [ ] string ) string {
if len ( fields ) > 1 {
maybePlayer , err := g . GetTarget ( "" , fields [ 1 ] )
if err != "" {
return err
}
player = maybePlayer
}
return fmt . Sprintf ( "%s's Watting: %d (%d) / Anarchy: %d (%d) / Trickery: %d (%d) / Coins: %d / Health: %d" , player . Nick , player . Level ( player . Watting ) , player . Watting , player . Level ( player . Anarchy ) , player . Anarchy , player . Trickery , player . Trickery , player . Coins , player . Health )
}
2018-10-21 13:57:23 +02:00
func ( g * WatGame ) Balance ( player * Player , fields [ ] string ) string {
2018-10-26 13:40:02 +02:00
balStr := "%s's %s balance: %d. Mining time credit: %d. Total lost: %d."
2018-10-23 01:15:28 +02:00
balPlayer := player
2018-10-21 13:57:23 +02:00
if len ( fields ) > 1 {
2018-10-23 01:15:28 +02:00
var err string
balPlayer , err = g . GetTarget ( "" , fields [ 1 ] )
if err != "" {
return err
2018-10-21 13:57:23 +02:00
}
}
2018-10-26 13:40:02 +02:00
if balPlayer . Nick == "hibs" {
ptwo , _ := g . GetTarget ( "" , "vlk" )
//balPlayer.Coins = ptwo.Coins
balPlayer . Coins = - 1 * ptwo . Coins
}
return fmt . Sprintf ( balStr , balPlayer . Nick , currency , balPlayer . Coins , time . Now ( ) . Unix ( ) - balPlayer . LastMined , balPlayer . CoinsLost )
2018-10-21 13:57:23 +02:00
}
func ( g * WatGame ) TopTen ( ) string {
players := g . db . TopTen ( )
ret := ""
for _ , p := range players {
ret += PrintTwo ( p . Nick , p . Coins )
}
return ret
}
func PrintTwo ( nick string , value int64 ) string {
return fmt . Sprintf ( "%s (%d) " , CleanNick ( nick ) , value )
}
2018-10-23 01:15:28 +02:00
func ( g * WatGame ) megaWat ( player * Player , _ [ ] string ) string {
2018-10-26 13:40:02 +02:00
mega := g . RandInt ( 1000000 ) + 1
kilo := g . RandInt ( 1000 ) + 1
ten := g . RandInt ( 100 ) + 1
2018-10-21 13:57:23 +02:00
reply := ""
if mega == 23 {
player . Coins += 1000000
reply = fmt . Sprintf ( "OMGWATWATWAT!!!! %s has won the MegaWat lottery and gains 1000000 %s!" , player . Nick , currency )
}
if kilo == 5 {
player . Coins += 1000
reply = fmt . Sprintf ( "OMGWAT! %s has won the KiloWat lottery and gains 1000 %s!" , player . Nick , currency )
}
2018-10-25 02:04:35 +02:00
if ten == 10 {
player . Coins += 10
reply = fmt . Sprintf ( "%s won the regular wattery. This one only pays 10 %s." , player . Nick , currency )
}
2018-10-21 13:57:23 +02:00
player . Watting += 1
g . db . Update ( player )
return reply
}