mIRC Home    About    Download    Register    News    Help

Print Thread
#263201 13/06/18 05:53 PM
Joined: Jan 2018
Posts: 23
R
Ryntovy Offline OP
Ameglian cow
OP Offline
Ameglian cow
R
Joined: Jan 2018
Posts: 23
Hello everyone,

I am trying to make a points system for Twitch. So far I have this:

Code:
[script]
on *:text:!gamble*:#: {
  if (%floodgamble) { return }
  set -u0 %floodgamble On

  if ($2 isnum 1-1000000000) {
    var %wager = $floor($2)
    var %randgamble = $rand(1,100)
    if (%randgamble <= 50) {
      writeini -n Points.ini $+(#,.,$nick) Points $calc($readini(Points.ini,$+(#,.,$nick),Points) - %wager)
      msg $chan /me @ $+ $msgtags(display-name).key lost $2 points in roulette and now has $readini(Points.ini,$+(#,.,$nick),Points) points.
    }
    elseif (%randgamble >= 50) {
      writeini -n Points.ini $+(#,.,$nick) Points $calc($readini(Points.ini,$+(#,.,$nick),Points) + (%wager * 1))
      msg $chan /me @ $+ $msgtags(display-name).key won $2 points in roulette and now has $readini(Points.ini,$+(#,.,$nick),Points) points.
    }
    else {
      writeini -n Points.ini $+(#,.,$nick) Points $calc($readini(Points.ini,$+(#,.,$nick),Points) + (%wager * 1))
      msg $chan /me @ $+ $msgtags(display-name).key won $2 points in roulette and now has $readini(Points.ini,$+(#,.,$nick),Points) points.
    }
    SET -ze %gamble_CD. $+ $nick 0
  }

  else msg $chan /me @ $+ $msgtags(display-name).key To gamble points, use the form !gamble <amount>
n23=}


Combined with this script:

Code:
[script]
alias -1 addPoints {
  if {$1 !isnum) { echo 2 -st $1 is not a number. It need to be a number. | halt }
  var %topic $+($chan,.,$nick)
  var %points $calc($readini(Points.ini,%topic,Points) + $1)
  writeini -n Points.ini %topic Points %points
  return %points
}
alias -l lookUpPoints {
  var %topic $+($chan,.,$nick)
  var %points $readini(Points.ini,%topic,Points)
  return %points
}
alias doaddpoints {
  if ($3 !isnum) { echo 2 -st $3 is not a number. It needs to be a number. | halt }
  var %topic $+($1,.,$2)
  var %points $calc($readini(Points.ini,%topic,Points) + $3)
  writeini -n Points.ini %topic Points %points
  echo -a Added points for %topic
}
alias dorempoints {
  var %topic $+($1,.,$2)
  remini -n Points.ini %topic Points
  echo -a Removed points for %topic
}
on *:text:!points:#:{
  if ((%floodpoints) || ($($+(%,floodpoints.,$nick),2))) { return }
  set -u10 %floodpoints On
  set -u30 %floodpoints. $+ $nick On
  msg # $nick has $readini(Points.ini,$+(#,.,$nick),Points) total points.
}

on $*:text:/!points (add|remove)/Si:#:{
  if ($nick isop #) {
    if ($0 < 3) { msg # Insufficient parameters: Use !points <add|remove> <user> [number] | return }
    writeini -n Points.ini $+(#,.,$3) Points $calc($readini(Points.ini,$+(#,.,$3),Points) $iif($2 == add,+,-) $iif($4 isnum,$4,1))
    { msg $chan $3 now has $readini(Points.ini,$+(#,.,$3),Points) total points. }
  }
  else { msg $chan This command is only available to moderators. }
}
on !*:join:#:{
  $+(.timerpoints.,#,.,$nick) 0 300 add.pts $+(#,.,$nick)
  add.pts $+(#,.,$nick)
  if ((%floodjoin) || ($($+(%,floodjoin.,$nick),2))) { return }
  set -u10 %floodjoin On
  set -u30 %floodjoin. $+ $nick On
  msg $chan $nick has joined and is now earning points.
}
on !*:part:#:$+(.timerpoints.,#,.,$nick) off
alias -l add.pts {
  writeini -n Points.ini $1 Points $calc($readini(Points.ini,$1,Points) + 1)
  if ((%floodpart) || ($($+(%,floodpart.,$nick),2))) { return }
  set -u10 %floodpart On
  set -u30 %floodpart. $+ $nick On
  msg $chan $nick has left the channel and is no longer earning points.
n54=}


It all works fine and is responding the way I want it to. However, people can !gamble points that they don't have and my guess is this happens because the first part of the script doesn't check in Points.ini if they in fact have the points. They can also !gamble below 0 which will result in people just gambling millions over and over.

My question is if you can fill in the blanks to check if the user has enough points in Points.ini so that the user can't gamble more than he/she has.
They also shouldn't be able to go below 0.

I am new to this and I tried my hardest but I can't figure it out.
Thank you very much for reading this,
Ry

Last edited by Ryntovy; 13/06/18 05:54 PM.
Joined: Jan 2004
Posts: 2,127
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 2,127
Code:
  set -u0 %floodgamble On
    var %wager = $floor($2)
    var %randgamble = $rand(1,100)
var %BankBalance $calc($readini(Points.ini,$+(#,.,$nick),Points))
if (%BankBalance <= 0) { stuff to do if zero balance | return }
if (%wager > %bankbalance) { stuff to do if betting more than balance | return }


I used $calc() around the returned value, because if it were blank, it is neither less than or greater than 0.
For positive numbers, $floor() is the same as $int().
Your else-if condition uses ">= 50" which would have let the gambler win 51% of the time. However since the first condition makes them lose for 1-50, it's behaving the same as "> 50".
For the remainder of your script, it's a little faster to refer to %BankBalance instead of reading from disk again.
Your 3rd 'else' condition can never happen. The result of $rand(1,100) is always a number from 1 to 100, so it's either going to be <= 50 or greater than 50.
Your %floodgamble will never do anything, because your -u0 immediately unsets the variable as it exits the TEXT event. The variable is not dynamically using the $nick so if you change the -u0 to -uNUMBER it will be a shared flood flag among all users. It looks like "%gamble_CD. $+ $nick" is trying to limit the frequency per nick, but again is starting at 0 instead of N seconds, and needs something similar at the top of the script:

if ( %gamble_CD. [ $+ [ $nick ] ] ) return

Joined: Jan 2018
Posts: 23
R
Ryntovy Offline OP
Ameglian cow
OP Offline
Ameglian cow
R
Joined: Jan 2018
Posts: 23
Yes that's it! Thank you, thank you, thank you!

Joined: Jan 2004
Posts: 2,127
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 2,127
* I noticed where you incorrectly used the number One instead of a small L.
Code:
alias -1 addPoints {

mIRC tends to ignore undefined switches for most identifiers, so this would behave like no switch were used. In case you haven't done it already, the /file menu of the script editor lets you change the font for the script editor independent from channel fonts. Especially if you're using a proportional font, you should probably switch to a fixed font. Especially one which makes it easier to see the difference between numbers 017 and letters OlI.

Your events all use :#: which means they react in all channels you happen to be in. You can change it to be :#channel: or :#channel1,#channel2: to restrict them further.
Code:
on *:text:!gamble*:#: {


this triggers for any string beginning with !gamble including "!gamblers's anonymous". To make it respond only when !gamble is followed by a space or the end of line, change to:
Code:
on $*:TEXT:/^!gamble( |$)/i:#:{


* If someone wants to burn their entire bankroll, change from:


Code:
var %wager = $floor($2)
var %randgamble = $rand(1,100)
var %BankBalance $calc($readini(Points.ini,$+(#,.,$nick),Points))

modify to:
Code:
var %BankBalance $calc($readini(Points.ini,$+(#,.,$nick),Points))
if ($1 == all) var %wager %BankBalance | else var %wager $floor($2)
var %randgamble = $rand(1,100)

* to have top3 listing, this trigger responds to "!top3", and includes a changeable 30 seconds countdown before it will show the list again. It's a little simpler to use hash tables than global variables, because you can avoid using the square braces to access dynamic variables, using $hget(table,item $+ $nick) instead of %var. [ $+ [ $nick ] ] where it gets complicated when your dynamic variable needs to nest $nick and $chan and possibly other things.
Code:
on *:text:!top3:#: {
  if (!$istok(nick1 nick2,$nick,32)) return
  if ( !$hget(flood,topN $+ #) ) topN 3
  else echo $chan !top3 available in $hget(flood,topN $+ #) seconds
  hadd -mz flood topN $+ # 30
}

For the topN alias, you can add color formatting, as it now has none. "topN 3" gives the top 3, "topN 10" gives the top 10.

%min can change from 1 to another number to indicate the lowest number possible that could appear on the top list, so if you give people 50 points to start out with, changing %min to 51 keeps the non gamblers and the losers from being on the list. I didn't add code to handle a super long list of tied nicks causing the list to be longer than a valid channel message length or too long for the length of a variable, but that's unlikely without dozens of people tied for the same score. As long as you don't issue a lot of people the same number of points at the same time, this shouldn't be a problem. Another way is to change "%DontShow 0" to the default gift, so the top10 list could still show people with less than the default amount without showing anyone who either has not gambled or has a net zero profit.

Even if there are too-few nicks in the list, or if most people run out of points, it won't list anyone at zero points. If there's a tie for any position in the top list, it lists all the nicks at that score, even if that causes more than 10 nicks to list. i.e. if there's a tie for 1st place, it lists both as 1st place, and the next person lists at 3rd place. If there's a 3-way tie for 9th place, it lists all 3, and won't list the next person since they're really in 12th place.

Your gamble is basically a coin flip. You can have another method of gambling like a lotto.

!lotto A B

... which lets someone gamble A amount with 1/B odds of getting B-to-1 payout.

After you set bounds on how large B can be, and a minimum of B no less than 2, winner would be if $rand(1,B) is B (you could instead check if it's 1). If winner, Balance=Balance + A*B. If loser, Balance=Balance - A.
Code:
alias topN {
  hfree -w topN | hmake topN
  var %offset $len(#) + 2 , %LastPlace 0 , %min 1 , %DontShow 0 , %standings $iif($1 isnum 1-10,$int($1),10) , %TopN $str($calc(%min) $chr(32),%standings)
  var %i $ini(points.ini,0) , %full_list | while (%i) {
    var %section $ini(points.ini,%i) , %points $readini(points.ini,%section,points)
    if (# $+ .* iswm %section) {
      var %nick $mid(%section,%offset)
      if ((%Points > 0) && (%Points != %DontShow) && (%Points >= %LastPlace)) {
        hadd TopN %nick %Points
        var %TopN $gettok($sorttok($addtok(%TopN,%Points,32),32,rn),1- $+ %standings,32) , %LastPlace $gettok(%TopN,$numtok(%TopN,32),32)
      }
    }
    dec %i
  }
  if (%TopN != $null) {
    var %place 1 , %place2 1 | while (%place isnum 1- $+ %standings) {
      var %i 1 , %list , %i2
      while ($hfind(TopN,$gettok(%TopN,%place,32),%i).data) {
        var %list %list $v1 $hget(TopN,$v1) | inc %i2 | hdel TopN $v1
      }
      if (%list != $null) { var %full_list %full_list $ord(%place2) Place: %list | inc %place2 %i2 }
      inc %place | if (%place2 > %standings) break | var %list
    }
    msg # %full_list
  }
  hfree -w TopN
}



Link Copied to Clipboard