Register forum user name Search FAQ

Gammon Forum

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 ➜ Lua ➜ Multi-hit counter and sum

Multi-hit counter and sum

You need to log onto the forum to reply or create new threads.

  Refresh page


Posted by Xandler   (55 posts)  Bio
Date Tue 12 Aug 2025 09:40 PM (UTC)

Amended on Wed 13 Aug 2025 11:05 PM (UTC) by Nick Gammon

Message
Okay, the gist of this is simple. I'm trying to build out a multi-hit function that will count the number of hits then sum it up on the end. For example, Your high kick hits X amount of times for y damage.

I've been trying to rely on chatgpt (yes it is useful in some instances...but not this it seems.)

I can post the entirety of the lua script/triggers I'm using and hopefully I can find an answer to this... (I am a complete newb at this scripting thing so bear with me)

I basically get compile errors when multi-hit things happen, ie

You hold your hand away from your body while concentrating on collecting ki around your hand. Slowly the ki forms a three foot blade. Quickly you perform a series of slashes at Blix.
[========]=-=[45875152]=-=[90%]
The energy in your Sauzer Blade intensifies as you continue to slash Blix.
Compile error
World: Dragonball Evolution
Immediate execution
[string "Trigger: "]:1: '=' expected near '<eof>'
[========]=-=[1887777]=-=[90%]
You violently slice through Blix with your Sauzer Blade.
Compile error
World: Dragonball Evolution
Immediate execution
[string "Trigger: "]:1: '=' expected near '<eof>'
[========]=-=[1887777]=-=[90%]


Script:


mh = {
  active = false,
  hits = 0,
  sum = 0,
  label = nil,        -- e.g., "Sauzer Blade"
  target = nil,       -- optional target name
  last_hit_time = 0,
  debounce = 0.6,     -- seconds of quiet before we print the summary
}

local function fmt(n)
  local s = tostring(n or 0)
  s = s:reverse():gsub("(%d%d%d)", "%1,"):reverse():gsub("^,", "")
  return s
end

function mh_on_damage(name, line, wildcards)
  local dmg = tonumber(wildcards[1]) or 0
  mh.sum   = (mh.sum or 0) + dmg
  mh.hits  = (mh.hits or 0) + 1
  mh.active = true
  mh.last_hit_time = utils.timer()
  DoAfterSpecial(mh.debounce, 'mh__try_flush()', sendto.script)
end

function mh_capture_label(name, line, wildcards)
  local lbl = wildcards[1]
  if lbl and #lbl > 0 then mh.label = lbl end
end

function mh_capture_target(name, line, wildcards)
  local tgt = wildcards[1]
  if tgt and #tgt > 0 then mh.target = tgt end
end

function mh_force_flush(name, line, wildcards)
  mh__flush(true)
end

function mh__try_flush()
  if not mh.active then return end
  if utils.timer() - (mh.last_hit_time or 0) < (mh.debounce - 0.05) then return end
  mh__flush(false)
end

function mh__flush(_forced)
  if not mh.active or (mh.hits or 0) == 0 then mh__reset(); return end
  local label = mh.label or "attack"
  local times = (mh.hits == 1) and "time" or "times"
  local tgt   = mh.target and (" on " .. mh.target) or ""
  ColourNote("gold", "", string.format(
    "Your %s hit %d %s%s for %s total damage.",
    label, mh.hits, times, tgt, fmt(mh.sum)
  ))
  mh__reset()
end

function mh__reset()
  mh.active = false
  mh.hits   = 0
  mh.sum    = 0
  mh.label  = nil
  mh.target = nil
  mh.last_hit_time = 0
end

Triggers:

<triggers>
  <trigger
   enabled="y"
   group="multi-hit"
   match="^.* with your (.+?)\.$"
   regexp="y"
   script="mh_capture_label"
   send_to="12"
   sequence="100"
  >
  <send>return 0</send>
  </trigger>
  <trigger
   enabled="y"
   group="multi-hit"
   match="^\[[^\]]+\]=-\[(\d+)\]=-\[[^\]]+\]$"
   regexp="y"
   script="mh_on_damage"
   send_to="12"
   sequence="100"
  >
  <send>return 0</send>
  </trigger>
  <trigger
   enabled="y"
   group="multi-hit"
   match="^Quickly you .* slashes? at (.+?)\.$"
   regexp="y"
   script="mh_capture_target"
   send_to="12"
   sequence="100"
  >
  <send>return 0</send>
  </trigger>
  <trigger
   enabled="y"
   group="multi-hit"
   match="^The .* in your (.+?) intensifies\b.*$"
   regexp="y"
   script="mh_capture_label"
   send_to="12"
   sequence="100"
  >
  <send>return 0</send>
  </trigger>
  <trigger
   enabled="y"
   group="multi-hit"
   match="^You .* slash .* (.+?)\.$"
   regexp="y"
   script="mh_capture_target"
   send_to="12"
   sequence="100"
  >
  <send>return 0</send>
  </trigger>
  <trigger
   enabled="y"
   group="multi-hit"
   match="^You stop fighting\.$"
   regexp="y"
   script="mh_force_flush"
   send_to="12"
   sequence="100"
  >
  <send>return 0</send>
  </trigger>
</triggers>
Top

Posted by Nick Gammon   Australia  (23,162 posts)  Bio   Forum Administrator
Date Reply #1 on Wed 13 Aug 2025 06:45 AM (UTC)
Message
Quote:




<triggers>
  <trigger
   enabled="y"
   group="multi-hit"
   match="^.* with your (.+?)\.$"
   regexp="y"
   script="mh_capture_label"
   send_to="12"
   sequence="100"
  >
  <send>return 0</send>
  </trigger>



I don't understand why you have "return 0" in the send part. I suggest you leave the send part empty, and then just send to output.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,162 posts)  Bio   Forum Administrator
Date Reply #2 on Wed 13 Aug 2025 06:53 AM (UTC)
Message
When testing your posted script and trigger, I don't get any errors. Do you have other things that might be firing?

Try turning on trace : Game menu -> Trace.

See what is actually happening.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Xandler   (55 posts)  Bio
Date Reply #3 on Wed 13 Aug 2025 07:57 AM (UTC)

Amended on Wed 13 Aug 2025 11:04 PM (UTC) by Nick Gammon

Message
Yea....I figured out the error, apparently I had an extra set of "triggers" that was causing it to have compile errors. To answer the question about the return 0 part. It was a troubleshooting step that chatgpt made me do to figure out why it was having said compile error. I've since just abandoned the whole scripting/triggers portion and through it all into an xml file and using it via plug-in. It has debugging features that set the label and the target (per chatgpt). Example:

The energy in your Sauzer Blade intensifies as you continue to slash Super Saiyan Cabba.
[MH] Label set to: Sauzer Blade
[=====---]=-=[1072222]=-=[61%]
You violently slice through Super Saiyan Cabba with your Sauzer Blade.
[MH] Finisher seen. target='Super Saiyan Cabba', label='Sauzer Blade'
[=====---]=-=[1072222]=-=[61%]


However, it still won't print out number of hits or total yet (I'm trying to do that after the last hit), since it was funny and using a nonsensical trigger that it made up that thought ended combat and put the print-out on that when it shouldn't have.

The file is this now:

<?xml version="1.0" encoding="utf-8"?>
<muclient>
  <plugin
    name="MultiHitAggregator"
    author="Xandler"
    id="c0ffee1234deadbeef001122"
    language="Lua"
    purpose="Sum multi-hit damage and print a summary line (flush on last hit)"
    save_state="y"
    date_written="2025-08-12"
  />

  <script><![CDATA[
-- ========= Multi-hit damage aggregator (flush on last hit) =========
mh = {
  active=false, hits=0, sum=0,
  label=nil, target=nil,
  last_hit_time=0, debounce=0.6,
  pending_final=false,     -- finisher seen; next damage is the last
  debug=true,              -- set false to hide [MH] lines
}

local function fmt(n)
  local s = tostring(n or 0)
  s = s:reverse():gsub("(%d%d%d)","%1,"):reverse():gsub("^,","")
  return s
end

local function dbg(msg)
  if mh.debug then ColourNote("silver","", "[MH] "..msg) end
end

-- Damage line: [bar]=-[12345]=-[xx%]
function mh_on_damage(name, line, wc)
  local dmg = tonumber(wc[1]) or 0
  mh.sum = (mh.sum or 0) + dmg
  mh.hits = (mh.hits or 0) + 1
  mh.active = true
  mh.last_hit_time = utils.timer()
  dbg("DMG "..dmg.." (hits="..mh.hits..", sum="..mh.sum..")")

  -- If finisher already seen, this is the last hit: flush now
  if mh.pending_final then
    mh.pending_final = false
    dbg("Flushing immediately on last hit")
    mh__flush(true)
    return
  end

  -- Fallback: quiet-time flush in case finisher text doesn't appear
  DoAfterSpecial(mh.debounce, 'mh__try_flush()', 12)  -- 12 = send to script
end

-- Label capture: "The energy in your X intensifies ..."
function mh_capture_label(name, line, wc)
  local lbl = wc[1]
  if lbl and #lbl > 0 then mh.label = lbl end
  dbg("Label set to: "..(mh.label or "nil"))
end

-- Finisher marker:
-- Matches both "violently slice through" and "slice through".
function mh_mark_final(name, line, wc)
  local tgt, lbl = wc[1], wc[2]
  if tgt and #tgt > 0 then mh.target = tgt end
  if lbl and #lbl > 0 then mh.label  = lbl end
  mh.pending_final = true
  dbg("Finisher seen. target='"..(mh.target or "?").."', label='"..(mh.label or "?").."'")
end

function mh__try_flush()
  if not mh.active then return end
  if utils.timer() - (mh.last_hit_time or 0) < (mh.debounce - 0.05) then return end
  dbg("Quiet-time flush")
  mh__flush(false)
end

function mh__flush(_forced)
  if not mh.active or (mh.hits or 0) == 0 then mh__reset(); return end
  local label = mh.label or "attack"
  local times = (mh.hits == 1) and "time" or "times"
  local tgt   = mh.target and (" on " .. mh.target) or ""
  ColourNote("gold","",string.format(
    "Your %s hit %d %s%s for %s total damage.",
    label, mh.hits, times, tgt, fmt(mh.sum)))
  mh__reset()
end

function mh__reset()
  mh.active=false; mh.hits=0; mh.sum=0
  mh.label=nil; mh.target=nil
  mh.last_hit_time=0; mh.pending_final=false
  dbg("State reset")
end
  ]]></script>

  <triggers>
    <!-- DAMAGE: run EARLY and keep evaluating -->
    <trigger enabled="y" group="multi-hit"
             match="^\[[^\]]+\]=-\[(\d+)\]=-\[[^\]]+\]$"
             regexp="y" script="mh_on_damage"
             keep_evaluating="y" send_to="0" sequence="1" />

    <!-- FINISHER cue: "... slice through TARGET with your LABEL." -->
    <trigger enabled="y" group="multi-hit"
             match="^You .*slice through (.+?) with your (.+?)\.$"
             regexp="y" script="mh_mark_final"
             keep_evaluating="y" send_to="0" sequence="2" />

    <!-- Optional label capture (intensifies) -->
    <trigger enabled="y" group="multi-hit"
             match="^The energy in your (.+?) intensifies\b.*$"
             regexp="y" script="mh_capture_label"
             keep_evaluating="y" send_to="0" sequence="3" />
  </triggers>
</muclient>
Top

Posted by Nick Gammon   Australia  (23,162 posts)  Bio   Forum Administrator
Date Reply #4 on Wed 13 Aug 2025 08:36 PM (UTC)
Message
You will note that you aren't getting the debug message for a damage hit, which means your regexp for the damage line was wrong. I corrected it to:


    <!-- DAMAGE: run EARLY and keep evaluating -->
    <trigger enabled="y" group="multi-hit"
             match="^\[[^\]]+\]=\-=\[(\d+)\]=-\=\[[^\]]+\]$"
             regexp="y" script="mh_on_damage"
             keep_evaluating="y" send_to="0" sequence="1" />



Now I see the messages:


The energy in your Sauzer Blade intensifies as you continue to slash Super Saiyan Cabba.
[MH] Label set to: Sauzer Blade
[=====---]=-=[1072222]=-=[61%]
[MH] DMG 1072222 (hits=1, sum=1072222)
You violently slice through Super Saiyan Cabba with your Sauzer Blade.
[MH] Finisher seen. target='Super Saiyan Cabba', label='Sauzer Blade'

[MH] Quiet-time flush
Your Sauzer Blade hit 1 time on Super Saiyan Cabba for 1,072,222 total damage.
[MH] State reset



I'm impressed that ChatGPT managed to get this far, sometimes it just invents things for MUSHclient. However I note that a human was needed to get it to actually work. :)

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Xandler   (55 posts)  Bio
Date Reply #5 on Thu 14 Aug 2025 12:08 AM (UTC)
Message
Perfect, works like a charm! Also yea, it tends to invent things for mushclient, like when I was trying to troubleshoot this issue it told me to sort the triggers by the send to field (to find the rogue trigger causing the compile error), which doesn't exist in the trigger menu....
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.


1,625 views.

You need to log onto the forum to reply or create new threads.

  Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.