Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Due to spam on this forum, all posts now need moderator approval.
Entire forum
➜ MUSHclient
➜ General
➜ Party Leading
It is now over 60 days since the last post. This thread is closed.
Refresh page
Pages: 1 2
Posted by
| Funkenstein
(17 posts) Bio
|
Date
| Sun 15 Mar 2009 01:02 PM (UTC) |
Message
| Hi everyone, I'm fairly new to MUSHclient but am hoping to set up various
triggers/aliases that would be useful to leading a party.
The general premise of what I am trying to achieve is add players
who join my group into a table which will contain the number of hits
they do as well as storing a number they will tell me when rolling
for items/equipment of certain mobs. Upon removal of the group, their
entry in the table is also removed. I am hoping to use my rescue
trigger based off this table if it can be searched through and triggered
fast enough.
Players are recognised as being added/removed to/from the group by:
e.g. Trogdor joins your group.
e.g. Trogdor leaves your group.
The hits I wish to count are:
e.g. Trogdor MUTILATES a small fluffy bunny with his deadly cleave.
Rescue trigger matches "turns to fight *!"
Where the wildcard is the player in the group.
I have tried sifting through the FAQ and search the forums for the bits
and pieces I am looking for but can't exactly fit it all together.
If anyone can point me in the right direction it would be great.
Thanks in advance | Top |
|
Posted by
| Nick Gammon
Australia (23,158 posts) Bio
Forum Administrator |
Date
| Reply #1 on Sun 15 Mar 2009 08:13 PM (UTC) Amended on Sun 15 Mar 2009 08:14 PM (UTC) by Nick Gammon
|
Message
| Well this is an interesting question. Using Lua tables makes it quite simple, however there are some fiddly points to get right.
See http://mushclient.com/pasting for how to copy all these examples into the client.
Let's handle someone joining the group:
<triggers>
<trigger
custom_colour="3"
enabled="y"
match="* joins your group."
send_to="12"
sequence="100"
>
<send>
group = group or {} -- ensure table exists
group ["%1"] = 0 -- now in group
-- sort group into alphabetic order
sorted_group = {}
for name in pairs (group) do table.insert (sorted_group, name) end
table.insert (sorted_group, GetInfo (3)) -- add self
table.sort (sorted_group)
-- show group members
if next (group) then
ColourNote ("green", "", "Group now consists of " ..
table.concat (sorted_group, ", "))
end
</send>
</trigger>
</triggers>
This matches on the joining message and adds them to the "group" table (creating it if necessary).
Note that this matches someone joining your group, not you joining someone else's group.
Most of the script is devoted to showing you the group membership - this is a sort-of check that the trigger worked.
Now if someone leaves the group, or you remove them, we need another trigger:
<triggers>
<trigger
custom_colour="14"
enabled="y"
match="^(?J)((?P<name>\w+) leaves your group\.|You remove (?P<name>\w+) from your group\.)$"
regexp="y"
send_to="12"
sequence="100"
>
<send>
group = group or {} -- ensure table exists
group ["%<name>"] = nil -- not in group
-- sort group into alphabetic order
sorted_group = {}
for name in pairs (group) do table.insert (sorted_group, name) end
table.insert (sorted_group, GetInfo (3)) -- add self
table.sort (sorted_group)
-- show group members
if next (group) then
ColourNote ("green", "", "Group now consists of " ..
table.concat (sorted_group, ", "))
else
ColourNote ("orange", "", "Your group has been disbanded.")
end
</send>
</trigger>
</triggers>
We mark them as not in the group by setting their entry to nil. Then we display who is left, if anyone.
Also, to handle disbanding the group:
<triggers>
<trigger
enabled="y"
match="You disband your group."
send_to="12"
sequence="100"
>
<send>group = {}</send>
</trigger>
</triggers>
Now to count hits:
<triggers>
<trigger
enabled="y"
match="* MUTILATES * with *."
send_to="12"
sequence="100"
>
<send>
group = group or {} -- ensure table exists
name = "%1"
-- if in group, count hits
if group [name] then
group [name] = group [name] + 1
end -- if in group
</send>
</trigger>
</triggers>
This matches anyone doing a "mutilates" but then checks if they are in the group. If so, it adds 1 to their hit count.
And for the rescue:
<triggers>
<trigger
enabled="y"
match="* turns to fight *!"
send_to="12"
sequence="100"
>
<send>
group = group or {} -- ensure table exists
name = "%2"
-- if in group, rescue him
if group [name] then
Send ("rescue " .. name)
end -- if in group
</send>
</trigger>
</triggers>
You can change "rescue" in the Send to whatever you want.
Finally, to print the hit count, an alias that goes through the table and shows the count for each member:
<aliases>
<alias
match="show_counts"
enabled="y"
send_to="12"
sequence="100"
>
<send>
group = group or {} -- ensure table exists
require "pairsbykeys"
for k, v in pairsByKeys (group) do
print (string.format ("%s did %i hit(s)", k, v))
end -- for
</send>
</alias>
</aliases>
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Funkenstein
(17 posts) Bio
|
Date
| Reply #2 on Mon 16 Mar 2009 08:00 AM (UTC) |
Message
| Thanks Nick, works a treat. Am impressed with the speed of the rescue trigger :)
Only problem im having is sometimes the prompt syntax throws in a
> or something like MV:Tired> on the same line when I add a player into
the group resulting in:
Group now consists of , >Trogdor, MV:Tired>Ben, etc.
I've been fiddling around with wildcards trying to figure out how to ignore
the > or MV:Tired> but not having much luck.
Also, after testing the triggers and asking around players what they want,
a damage counter is more useful in determining how much damage the
player is putting out. I have added a few more triggers that capture
different hit types and added a different score count for them accordingly.
e.g. a MUTILATE adds 5 to the count
a severly wound adds 4 to the count
a deeply wound adds 3 to the count
etc.
I was wondering though, could the count for the different types of hits be
stored separately for each player in the group and then added together to
display their total damage count as well as being able to independantly being
able to display specific hit counts?
This would also give me a heads up on trying to add a bid value to assign to each
player in the group table when they tell me a number which I can call later on to determine who is the closest to a random number.
Thanks in advance. | Top |
|
Posted by
| Nick Gammon
Australia (23,158 posts) Bio
Forum Administrator |
Date
| Reply #3 on Mon 16 Mar 2009 08:07 PM (UTC) |
Message
| For the prompt, a change to the trigger will do it. A regular expression lets you have an optional prefix, like this:
<triggers>
<trigger
custom_colour="3"
enabled="y"
match="^(?:.*>)?(\w+) joins your group\.$"
regexp="y"
send_to="12"
sequence="100"
>
<send>
group = group or {} -- ensure table exists
group ["%1"] = 0 -- now in group
-- sort group into alphabetic order
sorted_group = {}
for name in pairs (group) do table.insert (sorted_group, name) end
table.insert (sorted_group, GetInfo (3)) -- add self
table.sort (sorted_group)
-- show group members
if next (group) then
ColourNote ("green", "", "Group now consists of " ..
table.concat (sorted_group, ", "))
end
</send>
</trigger>
</triggers>
The important part is "(?:.*>)?" which says a non-capture group consists of .* (any characters) followed by >. Then the final ? means the whole thing is optional.
Do you really want the different types of hits to be stored separately? I suppose if you were keen to do this you could make each hit type a sub-table. At present each player's hits are stored separately, and you could then work out the total in a loop, and then calculate the percentage damage each player does. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Funkenstein
(17 posts) Bio
|
Date
| Reply #4 on Mon 16 Mar 2009 09:17 PM (UTC) |
Message
| Thanks!
I'm gonna have a go at storing them as sub-tables.
Will help me learn the code a bit better. | Top |
|
Posted by
| Funkenstein
(17 posts) Bio
|
Date
| Reply #5 on Wed 18 Mar 2009 10:57 AM (UTC) |
Message
| After giving sub-tables a fair go, the old way is a lot easier for me to understand.
Is there a way to group tell to the party the total damage of each
individual person in the group (basically the output of the show_counts
alias) in a single line?.
Is it also possible to add myself into the group? and be able to show my damage? | Top |
|
Posted by
| Nick Gammon
Australia (23,158 posts) Bio
Forum Administrator |
Date
| Reply #6 on Wed 18 Mar 2009 09:58 PM (UTC) |
Message
| To add yourself to the group, change things around a bit:
group = group or {} -- ensure table exists
group ["%1"] = 0 -- now in group
group [GetInfo (3)] = group [GetInfo (3)] or 0 -- add self
-- sort group into alphabetic order
sorted_group = {}
for name in pairs (group) do table.insert (sorted_group, name) end
table.sort (sorted_group)
Now the group always consists of at least yourself (by adding yourself every time you add someone else). This isn't a problem as you are adding by key, so you won't end up there twice.
You are going to eventually hit a problem because since you are always in the group, your hit count will keep going up. I can see a solution or two, but I'll leave that as an exercise. ;)
As for telling everyone, it could look like this:
<aliases>
<alias
match="show_counts"
enabled="y"
send_to="12"
sequence="100"
>
<send>group = group or {} -- ensure table exists
require "pairsbykeys"
message = "gtell hit counts are: "
for k, v in pairsByKeys (group) do
message = message .. string.format ("%s (%i) ", k, v)
end -- for
Send (message)</send>
</alias>
</aliases>
Example output is:
Nick tells the group 'hit counts are: Funkenstein (44) Nick (100) '.
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Funkenstein
(17 posts) Bio
|
Date
| Reply #7 on Fri 20 Mar 2009 08:11 AM (UTC) |
Message
| I currently have a separate table with party members
that handles numbers that people tell me as their bid.
e.g. t = {
Trogdor = 12,
Ben = 79,
Guy = 82,
Dumble = 4
}
I am trying to sort or extract the player whose bid is
the closest to a random number between 1-100.
So far my idea is to sort through the table to find
who has the smallest absolute number when subtracting
the bid from the random number which leaves the person
at the start (assuming sorting from lowest difference
to highest difference) as the person closest to the
random number.
I was wondering if there is an easier way than this to
get this information (the person closest to the random
number) and how can i cope with people
in the party guessing the same number or having
the same difference and getting both their details?
Thanks in advance | Top |
|
Posted by
| Erendir
Germany (47 posts) Bio
|
Date
| Reply #8 on Fri 20 Mar 2009 08:59 AM (UTC) |
Message
| With a small change to the structure of t, i would use somethink like this:
t = {
{'Trogdor' ,12},
{'Ben' ,79},
{'Guy' , 82},
{'Dumble' , 4}
}
math.randomseed((os.time()%10000)^2)
local r = math.random(100)
print(r)
local function compare(a,b)
return math.abs(a[2]-r)<math.abs(b[2]-r)
end
table.sort(t, compare)
for i = 1, #t do
print(t[1])
end
| Top |
|
Posted by
| Funkenstein
(17 posts) Bio
|
Date
| Reply #9 on Sat 21 Mar 2009 01:08 AM (UTC) |
Message
| After modifying it slightly, I seem to get back is a nil value.
<aliases>
<alias
match="test"
enabled="y"
send_to="12"
sequence="100"
>
<send> t = {
["Trogdor"] = 12,
["Ben"] = 79,
["Guy"] = 82,
["Dumble"] = 4,
}
require "pairsbykeys"
randomnumber = math.random (0, 100)
print (randomnumber)
function compare (a,b)
return math.abs(a[2]-randomnumber) < math.abs(b[2]-randomnumber)
end
for k, v in pairsByKeys (t) do
table.sort(t, compare)
end
end
print(t[1])
</send>
</alias>
</aliases>
The above table is the is the format that the real
group I have is stored as.
Couple of questions, I don't understand the [2] in the
compare function and print (t[1])... won't that print
the entry into table t with the key of "1" or will
it print the first key in the table?
Thanks in advance | Top |
|
Posted by
| Erendir
Germany (47 posts) Bio
|
Date
| Reply #10 on Sat 21 Mar 2009 01:41 AM (UTC) Amended on Sat 21 Mar 2009 01:50 AM (UTC) by Erendir
|
Message
|
- Lua is case-sensitive, so if you do
so correct function name is "pairsbykeys", and "pairsByKeys" is nil.
Or you can use this code:
pairsByKeys = require "pairsbykeys"
-
Quote: pairsbykeys.lua - iterator to traverse a table, sorted by key order in your example sorted by name of player, not the number.
-
Quote: table.sort (table [, comp])
Sorts table elements in a given order, in-place, from table[1] to table[n], where n is the length of the table. [...]
this function sorts only arrays, the part of lua-table with number as key. And there's no need in doing this operation more than once :)
Oh, i got the problem: in my last post, note
it's italic. Damn. It should be read as
Question: is it important to have the t-table in the form t.Ben = 79 and so on? If no, you can really use my code with the fix above.
-
Quote: Couple of questions, I don't understand the [2] in the
compare function and print (t[1])... won't that print
the entry into table t with the key of "1" or will
it print the first key in the table?
the compare function receives two elements of table being sorted, and should return true or false. The elements of table t looks like this:
this is again a table, with first field string 'Trogdor' and 2nd - number 12. So to access the 2nd value i write a[2], b[2].
And t[1] was a mistake (see above), but t[ i ][1] works like this:
get i-th field of table t, the table {'Trogdor' ,12}
get 1st field of table {'Trogdor' ,12}, the string 'Trogdor'
| Top |
|
Posted by
| Nick Gammon
Australia (23,158 posts) Bio
Forum Administrator |
Date
| Reply #11 on Sat 21 Mar 2009 07:46 PM (UTC) |
Message
|
Quote:
in my last post, note
print(t[1])
end
it's italic. Damn. It should be read as
print(t[ i ][1])
end
Whenever you post code, copy it to the clipboard and then select Edit menu -> Convert Clipboard Forum Codes (Shift+Ctrl+Alt+Q) in MUSHclient. That fixes up issues like that. Otherwise things like [i] come out wrongly, and double backslashes get converted to single backslashes, and other stuff that makes your code tend to not work. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Funkenstein
(17 posts) Bio
|
Date
| Reply #12 on Sat 21 Mar 2009 10:18 PM (UTC) |
Message
| Thanks Erendir,
I have tested your code and it works fine. However
I am still wondering if it is possible to use format for
the table without having to make tables within tables(only
reason is because all my other tables are in that same
format).
The problem I am running into is accessing the value not
the key of that particular table with the compare function
and to sort the table via the values and rearrange
the keys as well? | Top |
|
Posted by
| Nick Gammon
Australia (23,158 posts) Bio
Forum Administrator |
Date
| Reply #13 on Sun 22 Mar 2009 01:43 AM (UTC) |
Message
| Not sure what you mean by rearrange the keys.
Here is another way of finding the closest, keep the original table structure and find the closest value. Since more than one player may match it, then go through a second time and show who they are:
t = {
Trogdor = 12,
Ben = 79,
Guy = 82,
Dumble = 4
}
local r = math.random(100)
print(r)
local dist = 100
for k, v in pairs (t) do
if math.abs (r - v) < dist then
dist = math.abs (r - v)
end -- if close
end -- for
print ("closest is", dist)
print ("Matching player(s) is(are):")
-- now work out who that was
for k, v in pairs (t) do
if math.abs (r - v) == dist then
print (k)
end -- if close
end -- for
Example output:
81
closest is 1
Matching player(s) is(are):
Guy
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Onoitsu2
USA (248 posts) Bio
|
Date
| Reply #14 on Sun 22 Mar 2009 05:25 AM (UTC) |
Message
| Um ... the "closest" is 81, yet in the data it says 82, was this a typo, in the data, or an error in the code?
Just seemed odd to me :)
-Onoitsu2 | Top |
|
The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).
To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.
58,628 views.
This is page 1, subject is 2 pages long: 1 2
It is now over 60 days since the last post. This thread is closed.
Refresh page
top