Auto walker which can judge player/mob then fight

Posted by Hidelensman on Sat 26 Nov 2022 11:42 AM — 2 posts, 9,962 views.

#0
Hi all,

I'd like to seek for your advice on the issues I cannot resolve by myself after spent many time on trail and error.

I want to develop an auto walker which can achieve following features:
  • Judge if the room already has a player or mob(s) I want to kill
  • If there is a player entered the room before my char does, then my char will directly move to the next room
  • If no player in the room but the mob(s) I want to kill are there, my char will fight with the mob, then move to the next room after the mob(s) are killed
  • If a player enters the room later than my char, my char will continue fighting with the mob(s) in the room instead of moving to the next room

    I referred to Nick's reply in this post to have the auto walker as the base (the 3rd reply)
    https://gammon.com.au/forum/?id=8613&reply=3#reply3

    Plus the function to judge player/mob following Nick and Fiendish's instruction in this post (thanks for the great guidance again!)
    https://gammon.com.au/forum/?id=14987

    Then come out my codes as below (separate in several parts for easy reading; some words in Chinese since the MUD I play is in Chinese):

    Auto walker by timer
    
    <timers>
      <timer second="2.75" offset_second="0.00"    send_to="12"
    group="潛能1" >
      <send>route_check()
    pplroom = nil
    EnableTrigger("check_player", true)
    
    Note(pplroom)
    Note(fighting)
    Note(loc)
    
    -- stay here if we are fighting or recovering
    
    if fighting then
      return
    end  -- if
    
    loc = (loc or 0) + 1  -- next way to walk
    
      -- if past end, go to next wave
    if loc &gt; #route then
      loc = 0
      pot_wave = GetVariable("pot_wave") + 1
      SetVariable("pot_wave", pot_wave)
      next_wave = pot_wave + 1
      if route_current[pot_wave] then
         DoAfterSpecial(2, 'Execute("move " .. next_wave)', 12)
      else
         route_check()
         Execute("move 1;exert force;deposit 10000 coin")
         DoAfterSpecial(8, 'Execute("deposit 100 silver")', 12)
         --DoAfterSpecial(8, 'Execute("w;s;w")', 12)
         loc=0
         timer_end("潛能1")
         --timer_start("練武")
      end -- if
    else
      DoAfterSpecial(1, 'Send(route [loc])', 12)
      Note(fighting)
    end -- if</send>
    
      </timer>
    </timers>
    


    Trigger used to judge player/mob then define "fighting" is true of false
    
    <triggers>
      <trigger
       group="查玩家"
       match="^[&gt; ]*.*\((?P&lt;char_name&gt;.*)\).*$"
       name="check_player"
       regexp="y"
       send_to="12"
       sequence="100"
      >
      <send>Char_Name = string.lower("%1")
    
    pplroom = find_in_list(Char_Name, players)
    
    if pplroom then
       fighting = false
       Note ("Warning, player " .. pplroom .. " here.")
       EnableTrigger("check_player", false)
       return 
    else
       mobroom = find_in_list(Char_Name, mobs)
       if mobroom then
          fighting = true
          Execute ("say Mob " .. mobroom .. " here.")
          EnableTrigger("check_player", false)
          timer_end("潛能1")
       else
          fighting = false
       end -- if
    end -- if</send>
      </trigger>
    </triggers>
    


    Trigger to re-active the timer
    
    <triggers>
      <trigger
       custom_colour="2"
       enabled="y"
       group="統計"
       match="^吒]為你殺死了(.*),得到了\s+(\d+)點經驗值和\s+(\d+)點潛能以及\s+(\d+)點聲望。$"
       regexp="y"
       send_to="12"
       sequence="100"
      >
    <send>
    -- check state --
    EnableTrigger("check_player", true)
    check_state ()
    DoAfterSpecial (0.5, 'heal()',12)
    DoAfterSpecial (0.75, 'pot_threshold()',12)
    timer_start("潛能1")</send>
      </trigger>
    </triggers>
    


    Some self-defined functions used (less relevant ones are excluded)
    
    function find_in_list(find_what, the_list)
       for k, v in pairs(the_list) do
          if find_what:lower() == k:lower() then
             return k
          end -- if
       end -- for
    end -- function
    
    
    function pot_threshold()
        if my_pot > 150 then
           timer_end ("潛能1")
           -- trigger_end ("潛能1")
           fighting = false
           loc = 0
           Execute ("move 1")
           DoAfterSpecial (1, 'timer_start("學習")',12)
        else
           Execute ("look")
        end -- if
    end -- function
    
    
    function frozen_blade()
    
        Execute ("wield blade;perform blade.kill;unwield blade")
    
    end -- function
    


    Issues bumped
    1. The walker usually works fine, while sometimes it makes my char move to the next room when the fighting is still on-going
    2. Once my char moves as mentioned in #1, since the walker has already been temporarily turned off, my char will be idled there until the timer is fired by another trigger after 15 mins
    3. If another player enter the room after my char, when my char sees the player, the timer will move my char into the next room - this is not the ideal behavior I want


May I have your help/guidance on the possible solutions? Thanks in advance.
Amended on Sat 26 Nov 2022 02:36 PM by Hidelensman
USA Global Moderator #1
Don't automatically set fighting to false just because you see a person in the room. That's why you keep moving during a fight.