Have problems with Parrying bot ( Full blocker bot )

Users who are viewing this thread

ardaarsen01

Sergeant
 
        Hiya crowd ,

                  Today i will share my problem and reasonable codes  about adding a "Parrying bot" to multiplayer servers .

Once I used to  train myself with Champion bot  which  is located at Nditions duel server . Then i got bored of  its poor algorithm . But i  deduced that  it was  the fastest way of getting warmed (up to a point of course ) . I said ,  this champion bred might have great use for recruiting if i had it . So i became half modder ( i mean im pretty beginner at this ) .This is realy weird . None of users have opened a topic that handles Aİ ( except improved commander codes ) .

Now , let me share my knowledge ,
Champion bot and the others are taken from tutorial . At first i tried basic spawn_agent and set_visitor functions but they didnt work . By the way you can have a champion bot in your tutorial mode by  disabling the function that can be found in Module_mission_templates.py  (Line:5650)
Here ,
# (agent_set_scripted_destination_no_attack, ":trainer_agent", pos1), #This is the function that makes  training bot pure blocker  while you are interacting with it . İf you disable this , bot will both attack and  block

Here is algorithm of tutorial bots .
(0, 0, 0,
      [
        (get_player_agent_no, ":player_agent"),
        (neq, "$g_tutorial_training_ground_melee_trainer_attack", -1),
        (mission_disable_talk),
        (try_for_agents, ":cur_agent"),
          (agent_get_troop_id, ":cur_agent_troop", ":cur_agent"),
          (eq, ":cur_agent_troop", "$g_tutorial_training_ground_melee_trainer_attack"),
          (assign, ":trainer_agent", ":cur_agent"),
        (try_end),
        (try_begin),
          (eq, "$g_tutorial_training_ground_melee_state", 0),
          (try_begin),
            (try_for_agents, ":cur_agent"),                                                      #Visitor bots have training functions now
              (agent_get_troop_id, ":cur_agent_troop", ":cur_agent"),
              (this_or_next|eq, ":cur_agent_troop", "trp_tutorial_fighter_1"),
              (this_or_next|eq, ":cur_agent_troop", "trp_tutorial_fighter_2"),
              (this_or_next|eq, ":cur_agent_troop", "trp_tutorial_fighter_3"),
              (eq, ":cur_agent_troop", "trp_tutorial_fighter_4"),
              (agent_set_team, ":cur_agent", 7),
              (agent_get_slot, ":spawn_point", ":cur_agent", slot_agent_spawn_entry_point),
              (entry_point_get_position, pos1, ":spawn_point"),           
              (agent_set_scripted_destination, ":cur_agent", pos1),
              (agent_force_rethink, ":cur_agent"),    # bot reacts and starts to attack
            (try_end),
            (agent_set_wielded_item, ":trainer_agent", "itm_practice_sword"), #TODO: change this  ( Bot wields wooden thingie)
            (store_random_in_range, "$g_tutorial_training_ground_melee_state", 1, 5),
#random attack direction(this causes random swings , left/right/overhead/stab)
            (assign, "$g_tutorial_update_mouse_presentation", 1),
            (assign, "$g_tutorial_training_ground_next_score_time", 0),
          (try_end),
        (else_try),
          (gt, "$g_tutorial_training_ground_melee_state", 0),
          (try_begin),
            (agent_set_team, ":player_agent", 1),
            (agent_set_team, ":trainer_agent", 2),
            (agent_get_position, pos1, ":player_agent"),
            (agent_set_scripted_destination_no_attack, ":trainer_agent", pos1),  # bot always goes to its initial spawnpoint after each duel. İf you hit bot , it wont care untill it gets its spawn .
            (agent_get_attack_action, ":attack_action", ":player_agent"),
            (try_begin),
              (eq, ":attack_action", 2), # attack action equals to 2 if user releases its sword , i mean  bot is seeking for your swing released in order to block .
              (agent_get_action_dir, ":action_dir_attacker", ":player_agent"), # bot is supposed to block our swings
             

              (try_begin),                                                                    #Here is blocking code which is very simple .
                (eq, ":action_dir_attacker", 0), #down
                (agent_set_defend_action, ":trainer_agent", 0, 1),
              (else_try),
                (eq, ":action_dir_attacker", 3), #up
                (agent_set_defend_action, ":trainer_agent", 3, 1),
              (else_try),
                (eq, ":action_dir_attacker", 1), #right
                (agent_set_defend_action, ":trainer_agent", 2, 1),
              (else_try),
                (eq, ":action_dir_attacker", 2), #left
                (agent_set_defend_action, ":trainer_agent", 1, 1),
              (try_end),
            (try_end),
            (try_begin),
              (ge, "$g_tutorial_training_ground_current_score", 5),
              (tutorial_message, -1),
              (assign, "$g_tutorial_training_ground_melee_state", 0),
              (agent_set_team, ":player_agent", 0),
              (agent_set_team, ":trainer_agent", 7),
              (agent_set_hit_points, ":player_agent", 100, 0),      #Healing both side after challenge .
              (agent_set_hit_points, ":trainer_agent", 100, 0),
##              (assign, "$g_tutorial_training_ground_melee_trainer_attack_completed", 1), #not used
              (assign, "$g_tutorial_training_ground_conversation_state", 9), #attack complete
              (start_mission_conversation, "$g_tutorial_training_ground_melee_trainer_attack"),
              (assign, "$g_tutorial_training_ground_melee_trainer_attack", -1),
            (try_end),
          (try_end),
        (try_end),

And i took fresh usable part
# Agent represents parrying bot and player is player ...

(agent_is_active, ":duelist_agent_no"),
(neg|eq,":duelist_agent_no",":duelist_player_no"),
(agent_get_player_id, ":duelist_player_no", ":duelist_agent_no"),

            (try_for_agents, ":duelist_agent_no"),
          (agent_get_attack_action, ":attack_action", ":duelist_player_no"),
           
            (try_begin),
              (eq, ":attack_action", 2), #release 
              (agent_get_action_dir, ":action_dir_attacker", ":duelist_player_no"),
             
            (try_begin),
                (eq, ":action_dir_attacker", 0), #down
                (agent_set_defend_action, ":duelist_agent_no", 0, 1),
              (else_try),
                (eq, ":action_dir_attacker", 3), #up
                (agent_set_defend_action, ":duelist_agent_no", 3, 1),
              (else_try),
                (eq, ":action_dir_attacker", 1), #right
                (agent_set_defend_action, ":duelist_agent_no", 2, 1),
              (else_try),
                (eq, ":action_dir_attacker", 2), #left
                (agent_set_defend_action, ":duelist_agent_no", 1, 1),
              (try_end),
       
            (try_end),
        (try_end),

And copied it right into duel mode section ( Line :14300)  . (  exactly  patched up  to end of  the script starts with  "  (ti_on_agent_killed_or_wounded, 0, 0, [], ..... " (Line : 14420)
After this point  , i lost my control as a newbie codder  ...
(ti_on_agent_killed_or_wounded, 0, 0, [],
      [
        (store_trigger_param_1, ":dead_agent_no"),
        (store_trigger_param_2, ":killer_agent_no"),

        (call_script, "script_multiplayer_server_on_agent_killed_or_wounded_common", ":dead_agent_no", ":killer_agent_no"),

        (try_begin),
          (get_player_agent_no, ":player_agent"),
          (agent_is_active, ":player_agent"),
          (agent_slot_ge, ":player_agent", slot_agent_in_duel_with, 0),
          (try_begin),
            (eq, ":dead_agent_no", ":player_agent"),
            (display_message, "str_you_have_lost_a_duel"),
          (else_try),
            (agent_slot_eq, ":player_agent", slot_agent_in_duel_with, ":dead_agent_no"),
            (display_message, "str_you_have_won_a_duel"),
          (try_end),
        (try_end),
        (try_begin),
          (agent_slot_ge, ":dead_agent_no", slot_agent_in_duel_with, 0),
          (agent_get_slot, ":duelist_agent_no", ":dead_agent_no", slot_agent_in_duel_with),
          (agent_set_slot, ":dead_agent_no", slot_agent_in_duel_with, -1),
          (try_begin),
            (agent_is_active, ":duelist_agent_no"),
            (agent_set_slot, ":duelist_agent_no", slot_agent_in_duel_with, -1),
            (agent_clear_relations_with_agents, ":duelist_agent_no"),
            (try_begin),
              (agent_get_player_id, ":duelist_player_no", ":duelist_agent_no"),
              (neg|player_is_active, ":duelist_player_no"), #might be AI 
              (agent_force_rethink, ":duelist_agent_no"),
########       
## (neg|eq,":duelist_agent_no",":duelist_player_no"),    Dont know why i added this ...lol

(agent_get_player_id, ":duelist_player_no", ":duelist_agent_no"),   

            (try_for_agents, ":duelist_agent_no"),
          (agent_get_attack_action, ":attack_action", ":duelist_player_no"),
            (try_begin),
              (eq, ":attack_action", 2), #release
              (agent_get_action_dir, ":action_dir_attacker", ":duelist_player_no"),
              (try_begin),
                (eq, ":action_dir_attacker", 0), #down
                (agent_set_defend_action, ":duelist_agent_no", 0, 1),
              (else_try),
                (eq, ":action_dir_attacker", 3), #up
                (agent_set_defend_action, ":duelist_agent_no", 3, 1),
              (else_try),
                (eq, ":action_dir_attacker", 1), #right
                (agent_set_defend_action, ":duelist_agent_no", 2, 1),
              (else_try),
                (eq, ":action_dir_attacker", 2), #left
                (agent_set_defend_action, ":duelist_agent_no", 1, 1),
              (try_end),
        (try_end),
        (try_end),
##############
(try_end),
          (try_end),
        (try_end),
        ]),
             

Bots should  behave like champion bot .  But  when i hosted , bots were as dumb as what they were . I think  hardcoded Aİ codes dominate  other opensource codes if it colides with other  . ( dont make fun of me , its just  an assumption ... ) I also tried to create independent script next to other duel scripts  in  module_mission_templates.py  ( but failed again) .Maybe i should  modify  tutorial scene  with some multiplayer codes  instead  of modifying  multiplayer scenes  with other external/tutorial codes ... thats why Nditions  have max 4 bots , isnt it ...  They are only able to bring 4 trainer bots ...

Guys , whether i am a cool modder  or not , the subject of topic is assessable i think .Add comments please tell me if i got either wrong way  or true path  ...I am glad if you post your feedbacks . Sincerely  , a new member  :smile: .

Edit : by the way , i will modify my post with better less fugly codes soon
 
Hmm... firstly, why did you put it in the "ti_on_agent_killed_or_wound"? The codes will only be executed when agents are killed or wound in this case. Instead, like the tutorial bot, you should add a new trigger tuple with trigger interval "0", which means happening every frame, and add the code instead.

Tell me if I'm going too fast, and btw, this is a really really good attempt for a starter! Good luck!
 
Thanks mate for appreciating me . I know i made  a mistake by adding codes inside it . I will add much clear code soon after some trials . And i got what you said  ( 0, 0, ...
 
Hello again

I have codes working ( but not properly ) . I have some problems too ...

I have added this to the end of the duel mode section (At the bottom of the module_mission_templates.py (Line around ~14600) )

(0, 0, 0,
      [
        (get_player_agent_no, ":player_agent"),
          (try_for_agents, ":trainer_agent"),
       
              (agent_get_troop_id, ":cur_agent_troop", ":trainer_agent"),
              (this_or_next|eq, ":cur_agent_troop", "trp_swadian_infantry_multiplayer_ai"),
              (this_or_next|eq, ":cur_agent_troop", "trp_swadian_crossbowman_multiplayer_ai"),
              (this_or_next|eq, ":cur_agent_troop", "trp_vaegir_spearman_multiplayer_ai"),
              (eq, ":cur_agent_troop", "trp_vaegir_horseman_multiplayer_ai"),

      (agent_get_attack_action, ":attack_action", ":player_agent"),
           
        (try_begin),
              (eq, ":attack_action", 2), #release
              (agent_get_action_dir, ":action_dir_attacker", ":player_agent"),
     
                      (try_begin),
                (eq, ":action_dir_attacker", 0), #down
                (agent_set_defend_action, ":trainer_agent", 0, 1),
              (else_try),
                (eq, ":action_dir_attacker", 3), #up
                (agent_set_defend_action, ":trainer_agent", 3, 1),
              (else_try),
                (eq, ":action_dir_attacker", 1), #right
                (agent_set_defend_action, ":trainer_agent", 2, 1),
              (else_try),
                (eq, ":action_dir_attacker", 2), #left
                (agent_set_defend_action, ":trainer_agent", 1, 1),
              (try_end),
            (try_end),
        (try_end),

], []),

It works if you host a Lan_game ( via hamachi etc ) . Aye it works well all bots turned into block maniac unless you open a dedicated server .
I tried to spawn a bot for multiplayer server .  I tried all functions , but i couldn't achieve . Then i forced codes to use existing multiplayer soldiers .Here we go :

Problem 1: When i release my sword , ALL bots try to block my swings . This is terrible , bot will want to block more than a player if more than a player joins .And also bots do not turn into enemy in duel mode . I tried to create diplomacy-hostility loop .(Duelist and other bots are ally to me , so i am not able to separate other bots via team functions (all of agents ally anyway ... )
Picture 1:

Problem 2: I could not  keep down this error **** .  No 1763 ,  matching code is  (agent_get_attack_action, <destination>, <agent_id>), . So the game wants me to release my weapon at all . But when i stop releasing script gives error ? Any solution ?
Picture 2:
Problem 3: I have run "Dedicated Server" and observed bots . Bots werent blocking ...  And the script error i showed above is making server busy . ( ping is like 200 constantly ...) . Why did bots stop blocking at dedicated server ?
Picture 3:

Line no :9 or 7 isn't important , i just tried few changes that cost 2 lines before i got last screenshot
                                                                                                S u g g e s t i o n s ?
 
The problem is with your agent_id, you have to find the appropriate agent id for the bots you are duelling against (which is different to the scenario in the trainer place).

It should be something like:
Code:
(try_for_players, ":player_id"),
	player_get_agent_id ":player_id", "player_agent"   [Something like this]
	(agent_is_active, ":player_agent"),
	(agent_get_slot, ":player_agent", slot_agent_in_duel_with, ":bot_agent")   [Check parameter orders in header_operations.py]
	
	(neg|agent_is_player, ":bot_agent")   [Something like this]

       (agent_get_attack_action, ":attack_action", ":player_agent"),
             
         (try_begin),
               (eq, ":attack_action", 2), #release
               (agent_get_action_dir, ":action_dir_attacker", ":player_agent"),
       
                             (try_begin),
                 (eq, ":action_dir_attacker", 0), #down
                 (agent_set_defend_action, ":bot_agent", 0, 1),
               (else_try),
                 (eq, ":action_dir_attacker", 3), #up
                 (agent_set_defend_action, ":bot_agent", 3, 1),
               (else_try),
                 (eq, ":action_dir_attacker", 1), #right
                 (agent_set_defend_action, ":bot_agent", 2, 1),
               (else_try),
                 (eq, ":action_dir_attacker", 2), #left
                 (agent_set_defend_action, ":bot_agent", 1, 1),
               (try_end),
             (try_end),
         (try_end),

(try_end),

You'll have to edit my first few lines of code though, cause I forgot the exact commands.

Check header_operations.py for them.
 
Allright master. I could only gather some useful functions from Caba'drin's modified header_operations.py .It helps me alot .  I have added small set of useful functions  to the bottom of this post .
I tried to edit your code . But its a little messy , because the functions you have recognized have loads of variations in range of additional tags . This post is not an advance . I just wanted to summarize a little bit .

Here we go .
(try_for_agents, ":player_id"),    #there is no operation called (try_for_players, "xxx"),  so i put the traditional one
(player_get_agent_id, ":player_id", ":player_agent"),
(agent_is_active, ":player_id"),
(agent_get_slot, ":player_agent", slot_agent_in_duel_with, ":trainer_agent"),
(agent_is_non_player, ":trainer_agent"),

(agent_get_attack_action, ":attack_action", ":player_agent"),
       
                      (try_begin),
              (eq, ":attack_action", 2), #release
              (agent_get_action_dir, ":action_dir_attacker", ":player_agent"),
     
                      (try_begin),
                (eq, ":action_dir_attacker", 0), #down
                (agent_set_defend_action, ":trainer_agent", 0, 1),
              (else_try),
                (eq, ":action_dir_attacker", 3), #up
                (agent_set_defend_action, ":trainer_agent", 3, 1),
              (else_try),
                (eq, ":action_dir_attacker", 1), #right
                (agent_set_defend_action, ":trainer_agent", 2, 1),
              (else_try),
                (eq, ":action_dir_attacker", 2), #left
                (agent_set_defend_action, ":trainer_agent", 1, 1),
              (try_end),       
          (try_end),
        (try_end)


I had no time. I was able to edit and assert your codes for once . I will try similar derivatives with other codes i mentioned at the bottom.
I will continue editing . But first  i want to dump all useful codes here  for the case :
player_get_troop_id                          =  404  # (player_get_troop_id, <destination>, <player_id>),
player_set_troop_id                          =  405  # (player_get_troop_id, <destination>, <player_id>),

agent_get_player_id                      = 1724  # (agent_get_player_id, <destination>, <agent_id>),
player_get_agent_id                          =  406  # (player_get_agent_id, <destination>, <player_id>),

player_get_unique_id                        =  441  # (player_get_unique_id, <destination>, <player_id>), #can only be used on server side. (being unique is needed at multiplayer game . I can use this instead , it may solve my multiplayer problem

player_control_agent                        =  421  # (player_control_agent, <player_id>, <agent_id>),  # I dont get it ...

# Player slot operations
player_set_slot                              =  508  # (player_set_slot, <player_id>, <slot_no>, <value>),
player_get_slot                              =  528  # (player_get_slot, <destination>, <player_id>, <slot_no>),
player_slot_eq                              =  548  # (player_slot_eq, <player_id>, <slot_no>, <value>),
player_slot_ge                              =  568  # (player_slot_ge, <player_id>, <slot_no>, <value>),

This is an other option  ===>  player_get_slot 
Example :
(player_get_slot, ":player_agent", slot_agent_in_duel_with, ":trainer_agent"),
(agent_get_slot, ":player_agent", slot_agent_in_duel_with, ":trainer_agent"),

# Conditional check operations
multiplayer_is_server                        =  417 # (multiplayer_is_server),
multiplayer_is_dedicated_server              =  418 # (multiplayer_is_dedicated_server),              #The difference between these 2 may solve the multilayer problem .

player_is_active                            =  401  # (player_is_active, <player_id>),
agent_is_active                          = 1712 # (agent_is_active, <agent_id>),

get_player_agent_no                      = 1700  # (get_player_agent_no, <destination>),        # Retrieves the reference to the player-controlled agent. Apparently only makes sense in singleplayer mode.
 
Great! I could really actually just look up everything and write up the script for you; but where's the learning in that? So I hope you don't mind me leading you in a spiral ^^. Anyway, you're picking up this fast.

So firstly, we need to distingush between players and agents. Agents are the moving humans, horses, and even dead humans and horses - they are every living or ceased thing in the scene. While players are the people sitting behind the keyboard. In single player, there is only one player, so we use:  (get_player_agent_no, ":player_agent"), . But for multiplayer, there are lots of so we use: (player_get_agent_id, ":player_id", ":player_agent"), - and pass in the player number we want.

So, as you pointed out (and I forgotten), there is no (try_for_players), loop. We have to find another way to loop though all the players [note that we CAN loop through all the agents, but then the script would be different, and it would be less efficient]. Another piece of information you should know is that all player id's are unique that can be from 1-250 (i think, maybe 0-250). To be safe, lets use 0-250.

Hence the script:

Code:
(try_for_range, ":player_id", 0, 251),  # loop through 0-251 using variable player_id             (try_for_range,<destination>,<lower_bound>,<upper_bound>),
	(player_is_active, ":player_id"),   # see if player_id is used
	(player_get_agent_id, ":player_id", ":player_agent"),             # get agent_id of player_id
	(agent_is_active, ":player_agent"),                                
	(agent_get_slot,":trainer_agent",":player_agent",slot_agent_in_duel_with),             # who the player is duelling with is stored at slot_agent_in_duel_with, hence we save it at ":trainer_agent"
	                                                                 # # (agent_get_slot,<destination>,<agent_id>,<slot_no>), BECAREFUL WITH PARAMETER ORDERS!
	(agent_is_non_player, ":trainer_agent"),                            # auto block for non-players only

	(agent_get_attack_action, ":attack_action", ":player_agent"),  # AI Start here
	(try_begin),
		(eq, ":attack_action", 2), #release
		(agent_get_action_dir, ":action_dir_attacker", ":player_agent"),
	(try_begin),
		(eq, ":action_dir_attacker", 0), #down
		(agent_set_defend_action, ":trainer_agent", 0, 1),
	(else_try),
		(eq, ":action_dir_attacker", 3), #up
		(agent_set_defend_action, ":trainer_agent", 3, 1),
	(else_try),
		(eq, ":action_dir_attacker", 1), #right
		(agent_set_defend_action, ":trainer_agent", 2, 1),
	(else_try),
		(eq, ":action_dir_attacker", 2), #left
		(agent_set_defend_action, ":trainer_agent", 1, 1),
	(try_end),    
(try_end),

 
Caba`drin said:
Player 0 is the server.

So  you are saying that  my player ID will be 0 since im both client and server.

I should edit try_for_range to  this ??:
(try_for_range, ":player_id", 1, 251), #  so the loop will skip 0 .
Or i had better turn it into this ?
(get_max_players, ":num_players"),
(try_for_range, ":player_id", 0, ":num_players"),
(ge, ":player_id", 0),

By the way  this rare function may have use  ( im totaly not sure ,  i was digging some in header_operations.py and  found this meaningful words )

(multiplayer_get_my_player, ":player_id"),
(is_between, ":player_id", 0, multiplayer_max_possible_player_id),

Im going to do more experiments  if i finish my meal  :smile:)
 
Code:
(get_max_players, ":num_players"),
(try_for_range, ":player_id", 0, ":num_players"),

cant rmb if players are in continuous numbers... someone else might enlighten you on this matter.

Anyway, I would just include 0, since my player_is_active, will eliminate all invalid player_ids.

As for multiplayer_get_my_player, that doesn't work, because that has to be called from the client rather than the server, coz the server holds "all" players, there is no concept such as "my player" in a dedicated server.
 
Allright , AI right. It works fine on both LAN server and Dedicated server .

Edit module_mission_templates.py and search for "duel mode" (at the bottom).
Put this into duel mode section among other triggers in module_mission_templates.py.
(0, 0, 0,                        #Trigger will be checked at every frame
[
(store_trigger_param_1, ":trainer_agent"),   

(try_for_range, ":player_id", 0, 251),  # loop through 0-251 using variable player_id           
(player_get_agent_id, ":player_agent", ":player_id"),            # get agent_id of player_id
(agent_is_active, ":player_agent"),

  (try_begin),
  (agent_get_slot, ":trainer_agent", ":player_agent", slot_agent_in_duel_with),  # who the player is duelling with is stored at slot_agent_in_duel_with, hence we save it at ":trainer_agent"
  (agent_is_active, ":trainer_agent"),                                                             
  (agent_get_attack_action, ":attack_action", ":player_agent"),  # AI Start here
 
              (try_begin),
(eq, ":attack_action", 2), #release
(agent_get_action_dir, ":action_dir_attacker", ":player_agent"),
     
                      (try_begin),
(eq, ":action_dir_attacker", 0), #down
(agent_set_defend_action, ":trainer_agent", 0, 1),
        (else_try),
(eq, ":action_dir_attacker", 3), #up
(agent_set_defend_action, ":trainer_agent", 3, 1),
        (else_try),
(eq, ":action_dir_attacker", 1), #right
(agent_set_defend_action, ":trainer_agent", 2, 1),
        (else_try),
(eq, ":action_dir_attacker", 2), #left
(agent_set_defend_action, ":trainer_agent", 1, 1),
      (try_end),
   
              (try_end),
      (try_end),
(try_end),
], []),
Additional autohealing lines
For  PvP : Search for (display_message, "str_you_have_won_a_duel"),. And add  (agent_set_hit_points, ":player_agent", 100, 0), under the line we have searched for.

For PvE : Search for  (agent_force_rethink, ":duelist_agent_no"), . And add (agent_set_hit_points, ":duelist_agent_no", 100, 0), under the line we have searched for. (Bot will be healed after each duel it won. )
Here is last changes:
At first trial  i got error: Player_agent is  unassigned
Then i switched "player_id" and "player_agent".==>  (player_get_agent_id, ":player_agent", ":player_id"), Problem is fixed.

At second trial i got error: Trainer_agent is not defined .Added (try_for_agents "trainer_agent"), . But that didnt work .Then i added (store_trigger_param_1, ":trainer_agent"), at the top of condition block .Problem is fixed.

At third i got no error from exporter thingie. When i set game(duel mode) , i tried few feints (sword got relased) . Then i got errors : Agent id was not invalid for operations : #(agent_is_non_player, ":trainer_agent"),                           
                    #(agent_is_human, ":trainer_agent"),
                    #(agent_is_alive, ":trainer_agent"),

I tried to push these codes into different loops , different positions . Ingame errors were still existing. I decided to delete these codes. Surprise! it's working .
It is not over ! . I would like to load additional abilities to Parrying bot and improve  its poor algorithm.
Distancing : It is easy to kick parrying bot .
                    Making little traps for players using distance .
                    Bot can also kick if i add dammage and animation operations

Other combat abilities : Hitslash ( delayed left + right swing combo )
                                      Delayed swings
                                      Special annoying feints ( By letting bot follow a scene object simultaneously )
                                      Maybe some special buffs for hard players ( For instance: After a point bots stats will be buffed for a while (with some particle_systems work).
                                      And more ...
 
Hello guys , today i have brand new problems . When i set a bot to chamber , it fails ... Bot holds its weapon when i release (we do action at same time). It is too early thus  bot cant chamber all my  swings. Bot should hold its weapon after my release completed but how .  I want to fix this problem with your help .

Here what i made
(store_mission_timer_b, ":timer"),
(eq, ":timer", 3),
(try_begin),
(store_random_in_range, ":chance", 0, 100),
(store_sub, ":timer", 3),
(reset_mission_timer_b),
(try_end),

(store_trigger_param_1, ":trainer_agent"),
(try_for_range, ":player_id", 0, 251),
(player_is_active, ":player_id"), 
(player_get_agent_id, ":player_agent", ":player_id"),         
(agent_is_active, ":player_agent"),

(try_begin),
(agent_get_slot, ":trainer_agent", ":player_agent", slot_agent_in_duel_with), 
  (agent_is_active, ":trainer_agent"),                                                             
    (agent_get_attack_action, ":attack_action", ":player_agent"),  # AI Start here

  (try_begin),
(is_between, ":chance", 0, 60),
(eq, ":attack_action", 2), #release
(agent_get_action_dir, ":action_dir_attacker", ":player_agent"),

(try_begin),
(eq, ":action_dir_attacker", 0), #down
(agent_set_defend_action, ":trainer_agent", 0, 1),
(else_try),
(eq, ":action_dir_attacker", 3), #up
(agent_set_defend_action, ":trainer_agent", 3, 1),
(else_try),
(eq, ":action_dir_attacker", 1), #right
(agent_set_defend_action, ":trainer_agent", 2, 1),
(else_try),
(eq, ":action_dir_attacker", 2), #left
(agent_set_defend_action, ":trainer_agent", 1, 1),
(try_end),

(else_try),

  (is_between, ":chance", 60, 100),
(eq, ":attack_action", 2), #release
(agent_get_action_dir, ":action_dir_attacker", ":player_agent"),

(try_begin),
(eq, ":action_dir_attacker", 0), #down
(agent_set_attack_action, ":trainer_agent", 0, 0),
(else_try),
(eq, ":action_dir_attacker", 3), #up
(agent_set_attack_action, ":trainer_agent", 3, 0),
(else_try),
(eq, ":action_dir_attacker", 1), #right
(agent_set_attack_action, ":trainer_agent", 2, 0),
(else_try),
(eq, ":action_dir_attacker", 2), #left
(agent_set_attack_action, ":trainer_agent", 1, 0),
(try_end),

(try_end),
(try_end),
(try_end),
Simple expression of the code :
Chance factor ( %60 block probability  , %40 chamber probability ), Bot will revise it's action per 3 seconds .
Player and the bot that player will use are defined ( each player has ticket between 0 and 251 )

if ( Bot is in duel with player    and      Bot is active  )
{

      Realize player's attack action 
              If ( Chance indicates blocking skill    and      Player releases it's weapon  )
              {  Bot will block all your swings  }
              else if ( Chance indicates chamber skill    and    Player releases it's weapon  )
              {  Bot will  chamber all your swings. }
                                                                                                                                              }

But chance factor does not work well .
Bot holds its weapon too fast . i tried to add delay in miliseconds (using mission timer_c) to each  chamber attempt but it didnt work aswell  because different bots have different weapons  . One of them utilize but on the other hand other bot gets harmed by delay. Thats why i need a little  help to calibrate those bots ))

Here is one more little problem too :
I typed a section that does not allow duelist bot to get too closer ( you wont be able to kick it )

(store_trigger_param_1, ":trainer_agent"),
(try_for_range, ":player_id", 0, 251),
(player_is_active, ":player_id"),
(player_get_agent_id, ":player_agent", ":player_id"),
(agent_is_active, ":player_agent"),
(try_begin),
(agent_get_slot, ":trainer_agent", ":player_agent", slot_agent_in_duel_with),
  (agent_is_active, ":trainer_agent"),

(try_begin),
(agent_get_position, pos1, ":player_agent"),
(position_move_y, pos1, 100,0),
(try_begin),
(agent_get_scripted_destination, pos1, ":trainer_agent"),
(try_end),

(try_end),
(try_end),
(try_end),   
It seems like bots cant stop their hardcoded duties and they pass the limitation ( i mean they get too close ). I need to prevent this .But i know  code is working , because bots  sometimes get 100 cm of distance to player and they do not attack ( kinda bug i have seen it before at nord invasion servers ). I will try to spawn an AI barrier to stop the bot  if i cant improve the last code i showed

I am glad  if someone could help !
 
Back
Top Bottom