Noob looking for help

By LoneStoner on Sep 17, 2017

I was trying to make a rpg sorta thing for my chat bot, and was wondering how I would go about claiming a winner for the battle. For example, $nick swings for 1 damage, while $2 does 3 damage making $2 the winner and maybe a winning message for the winner as well, also how I would go about it if there were a tie. Sorry if I confused the crap out of you. : ) I'm new as hell. Thanks in advance! (If the tie things is too much of a pain, it don't matter I can just make them re-swing. I'm just really looking how to determine a winner, and have them crowned the victor.)

on :TEXT:!swing:#:{
var %swing = $rand(1,3)
if (%swing == 1) msg $chan $nick attacks $2 for $rand(1,3) dmg $2 does $rand(1,3) back.


Sign in to comment.
blackvenomm666   -  Sep 17, 2017

you can set it to two variables and have them compared. so
on:text::: { !fight .set %dmgnick1 $rand(1,10) .set %dmgnick2 $rand(1,10) if %dmgnick1
if (%dmgnick1 < %dmgnick2) {
so on and so forth

blackvenomm666  -  Sep 17, 2017

i haven't really done much in scripting for irc in a while this is just a quick throw together example and i honestly have no clue if it will work or not. was just to give you an idea

LoneStoner  -  Sep 17, 2017

thanks for the response, much appreciated. I'll try it now.

blackvenomm666  -  Sep 17, 2017

if you have the mIRC help file you can look up the greater than or equal stuff. < > == != !< !> etc

LoneStoner  -  Sep 18, 2017

Okay I got it sorted out, not I just need it to read random winning messages.

on 1:TEXT:!Battle*:#: {
if ((%floodBATTLE) || ($($+(%,floodBATTLE.,$nick),2))) { return }
set -u10 %floodBATTLE On
set -u30 %floodBATTLE. $+ $nick On
var %battle2 = $rand(1,500)
set %battle $rand(1,500)
set %battle2 $rand(1,500)
if %battle === %battle2 {
msg $chan $nick has swung against $2 and did %battle dmg while $2 did %battle2 damage, declaring it a tie.
if %battle > %battle2 msg $chan $nick has won against $2 dealing %battle dmg while $2 delt %battle2 dmg.
if %battle < %battle2 msg $chan $nick has lost. $2 delt %battle2 dmg while $nick only did %battle dmg.

So as of now it will find a winner and declare them victor. Now I'm just working on how to have a few different messages win rather than the static winning message I have now.

blackvenomm666  -  Sep 18, 2017

just use a .txt and have it randomize the answer from there i'll give you an example unless they've changed it if you just use the $read it should just randomly choose a line from the .txt file you have it read from. so make your txt file in where you want it then add different responses one per line. and use the $read

LoneStoner  -  Sep 18, 2017

Yeah the $read still works in mirc so I'll work on making that happen today, and keep you posted. Again, thanks for all the help, brother.

blackvenomm666  -  Sep 18, 2017

anytime. if need be i can dig out some old stuff i had set up to use the $read in the way you need done had some stuff for a bot i never posted anywhere. also feel free to look through my snippets to get ideas how to do stuff if you need to

blackvenomm666  -  Sep 19, 2017

did you get it all sorted out?

LoneStoner  -  Sep 20, 2017

I got most of it sorted out, the vars call the right numbers when the battle is initiated, the winner is claimed, and I have the winners in a notepad with scores kept, I however didn't get the randomize messages up just yet, because I been reading up on mirc coding so I can figure out how to mmmm sort scores to call back in numerical order descending... So let's say you won and want to check your score you'd do like !score and it would read it back from a txt and tell you the score... I got it semi reading me back the stats just not filtered from highest score to lowest. So the actual !fight is working correctly, once I get the scores to actually save and read back right I'll start working on the multiple vars with diff winning messages. I'm way new to this so it'll be a little. Between streaming and sleep I have a limited time to play around till the weekend comes. : ) Initially what I'm trying to do is slowly write a mirc bot for my twitch stream so my viewers will eventually be able to play/fight and other things to collect points, then be able to spend them on like song requests, or game codes from a shop. So I already have points being given out just for loyalty or time being spent in the room. Eventually I plan to make it to where only followers can collect points and use the points to buy items as like a thank you. I'll keep you posted for sure.

blackvenomm666  -  Sep 20, 2017

for storing scores it would be worth looking up how to use .ini files instead of just the .txt files they are cleaner and it's easier to pull specific stuff from them as for doing it in order a while loop would work perfectly along with the greater than lesser than equal to etc

here is an example of how i used .ini to create a simple pass saver

Degausser  -  Sep 20, 2017

For sorting files, check out /filter. Example:

/filter -ffctue 2 32 file.txt file.txt

"The -e specifies a descending sort, and -u a numeric sort."

"The -t switch sorts the output based on [c s], column C using character S as the columns separator." - this is: 2 32, assuming file.txt holds scores per line as: username N

blackvenomm666  -  Sep 20, 2017

ty degausser forgot about that command. isn't there a $sort as well? could be mistaken lol

LoneStoner  -  Sep 21, 2017

Thanks Degausser, I will try that later on today. That would help me out a ton to get my point leaders sorted correct. Right now for some reason my points are being saved with the stream room name b4 the persons name so for example..

and so on, so this sorting will help me something major. Thanks a ton. I'll keep you updated. I'll probably play with this tonight and let you know if it worked. Thanks!

LoneStoner  -  Sep 21, 2017

Okay, so the /filter -ffctue code worked perfect... Only problem was the points were like this


then under the points were all the names... it def worked legit (thanks a million) but the names got separated from the points themselves. ALSO, I said the points were in a .txt they're actually going to an ini file. Would this be the reason they got separated? If so I can just change where the points/players are being wrote.

Degausser  -  Sep 22, 2017

yes, my reply assumed you were storing data line by line in a txt file. You can keep the ini file if it makes reading and writing easier (and in fact the ability to store user properties in an orderly fashion). Every time you update the points in your ini file, write them to a separate txt file in the form of: nickname points. So like: Julian 100

Then filter the file each time you update a batch of points. for example when the fight is finished, you can update the points of both users, then apply a single /filter command to the txt file.

One problem you may come across is the need to overwrite a line if the users already exists in the txt file. The best way to go about doing this would be something like this:

; you should have these variables available somehow when updating points
var %username = ?, %points = ?
; check if the user already exists in the file by searching all lines by wildcard. w flag specifies this
var %optional = $read(file.txt,w,%username *)
; write the points to the file. $readn returns the line number of the last $read call, so we check if the call was successful
; using an inline if statement. if successful, the -l flag is specified followed directly by the line number, signifying you want to overwrite said line
write $iif($readn,$+(-l,$readn)) file.txt %username %points
LoneStoner  -  Sep 23, 2017

Damn man, much appreciated for the help. I'll implement this today and show you what I have going on. This is what my code looks like right now... This adds points and will read back your score.

on *:text:!sausage:#:{
if ((%floodSAUSAGE) || ($($+(%,floodSAUSAGE.,$nick),2))) { return }
set -u10 %floodSAUSAGE On
set -u30 %floodSAUSAGE. $+ $nick On
msg # ( %sc ) $nick has $readini(Points.ini,$+(#,.,$nick),Points) sausage.
inc %sc

on $:text:/!sausage (add|remove)/Si:#:{
if ($nick isop #) {
if ($0 < 3) { msg # Insufficient parameters: Use !points <add|remove> [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 !
$+(.timerpoints.,#,.,$nick) 0 1200 add.pts $+(#,.,$nick)
add.pts $+(#,.,$nick)
on !*:part:#:$+(.timerpoints.,#,.,$nick) off
alias -l add.pts {
writeini -n Points.ini $1 Points $calc($readini(Points.ini,$1,Points) + $rand(1,20))

So ATM I think every 20 minutes everyone in the stream gets 1-50 points. They each get a different number of points.

Update 2:04 PM EST 9/23/17: It's still writing to an ini file but I figured out how to stop it from writing the room name with the points, so now all it's writing is the name of the player and their points like so...

Points = 59

[Another Player]

I tried to change it to writetxt Points.txt but that didn't seem to work and got a status msg that said

WRITETXT Unknown Command

(Anytime you get sick of me just tell me to fuck off. : ) )

Degausser  -  Sep 23, 2017

There are two basic write commands, /write and /writeini. In general you'd use ini files with /writeini and $readini/$ini, and txt files with /write and $read. You can write line by line to an ini file by using /write, but the file wouldn't conform to ini standards. You can also store ini based data in a txt file, but again we tend to use txt files for pieces of data separated by lines.

For example, in your add.pts alias, replace this line:

writeini -n Points.ini $1 Points $calc($readini(Points.ini,$1,Points) + $rand(1,20))

With all of this:

var %points = $iif($2,$2,$rand(1,20)), %optional = $read(Points.txt,w,$1 *)
writeini -n Points.ini $1 Points $calc($iif($readini(Points.ini,$1,Points),$v1,0) + %points)
write $iif($readn,$+(-l,$readn)) Points.txt $1 %points

So I think using 2 files is okay, one for easily reading and writing user properties, and the other for listing an ordered list of points per user. If $2 is specified in the add.pts alias, then that is used as the number of points. This way, you can use it from other parts of your script, for example by replacing:

writeini -n Points.ini $+(#,.,$3) Points $calc($readini(Points.ini,$+(#,.,$3),Points) $iif($2 == add,+,-) $iif($4 isnum,$4,1))


add.pts $3 $iif($4 isnum,$+($iif($2 == remove,-),$4),1)

So add.pts can now be used in 2 ways. Random points 1-20, or specified.

/add.pts user
/add.pts user N

In case you don't quite understand, this is why in the add.pts alias, $1 represents the username, and $2 MAY represent points, but may be $null. In the add.pts alias, the logic is taken care of to deal with either possibility

If you specify points, you're specifying the number of points to increase or decrease the user total by, not the new number of points. So if Kyle has 40 points, and you run /add.pts Kyle -10, Kyle will now have 30 points. This would of course be done with the channel comand: !sausage remove Kyle 10

Lastly, if you store user points in a txt file in the format: user points, you'll want to filter it with this:

/filter -ffctue 2 32 Points.txt Points.txt

You can filter at the end of your add.pts alias, but i think you'd be doing a lot of filtering. A better way would probably involve issuing the /filter command before displaying requested statistics. This way it's always sorted when being used, without wasting resources by constantly filtering.

One more thing, in your current Points.ini file, you have a user named "Another Player". Nicknames on IRC don't contain spaces, and part of the logic in ordering your list of users by points in the txt file relies on that principal. Currently, you'd be filtering based on the second token (second word), which is normally the number of points the user has, but would become the 2nd part of the username if spaces were prohibited or used within the username. You could store the username and matching point total in your txt file as: points username, this way filtering based on the first token (first word) would be consistent. OR you can just use "Another_Player" as the test name instead, and assume names will not contain spaces.

Edit: Edited to assume you don't want to write stats with channel.player, but instead just player. If you're having trouble doing this, just replace all occurrences of: $+(#,.,$nick) with: $nick

You'll also need to have a look at your JOIN and PART events, as your timers incorporate channel.nickname in the name. This means users can join many channels you're on, again and again, collecting more coins. You also have a problem managing the timer, as there are more ways for users to leave than just parting the channel. They can also quit, or disconnect.

You should ALSO think about doing something when YOU join the channel. Like cycling through all the users already there, and starting a timer for each one if not already started. An alternative is to to all of this would be a check that you share a channel with said user in your timer event. This way you wouldn't have to worry about starting and stopping timers. Having said all that, you can remove your JOIN and PART event, and replace 'em with these pieces of code. This ONLY requires a JOIN event:

on *:JOIN:#:{
  if ($nick == $me) {
    ; commands to start timers for all users in room if not already started.
    var %x = 1, %nick
    while ($nick($chan,%x)) {
      %nick = $v1
      if (!$timer($+(points.,%nick))) {
        ; you just joined, dont give out points directly, dish out points every 20 minutes
        $+(.timerpoints.,%nick) 0 1200 add.chk %nick
      inc %x
  else {
      ; commands to start timer for user who joined if not already started
      if (!$timer($+(points.,$nick))) {
        ; user just joined, give him points directly, then dish out points every 20 minutes
        add.pts $nick
        $+(.timerpoints.,$nick) 0 1200 add.chk $nick

You already have an add.pts alias. Now we need to make an add.chk alias, which makes sure the user is on a common channel, THEN calls the original add.pts alias. Here is how the add.chk alias can look:

; /add.chk username
alias -l add.chk {
  var %x = 1
  while (%x <= $chan(0)) {
    if ($1 ison $chan(%x)) {
      ; check is successful, add points and return
      add.pts $1
    inc %x
  ; check not successful, stop timer
  $+(.timerpoints.,$1) off
LoneStoner  -  Sep 24, 2017

Okay thanks a million. I'll add that in and tell you what I got. As for the join/part part I'll replace it like you said because I did notice an exploit in the code... If someone leaves then joins they get points again, so if someone figures this out they can just exploit it like that for points and it would be unfair to others who are actually sitting in the room looking to collect points the real way. Thanks again for the help I can't explain how much appreciation I have for your help. Again, I'm still just a noob with minimal knowledge so you 2 helping me is awesome. I'll put this in tonight, and let you know what I get. I rather use what you said since again I'm new to this all and I'm sure your way is better. Thanks again guys! Much appreciated, truly!

Degausser  -  Sep 24, 2017

Okay. I did notice a mistake i made though. I've edited the JOIN event to fix this. I was checking timer status without the . in the name, so $false would only be returned.

I took occurrences of: if (!$timer($+(points,
and replaced with: if (!$timer($+(points.,

Should be okay now. Have not actually tested, so if something still isn't running properly, just let me know.

LoneStoner  -  Sep 24, 2017

Ty sir!

Sign in to comment

Are you sure you want to unfollow this person?
Are you sure you want to delete this?
Click "Unsubscribe" to stop receiving notices pertaining to this post.
Click "Subscribe" to resume notices pertaining to this post.