Creating new AI fighting.

Users who are viewing this thread

This is my new AI fighting on native mod. 1 hero vs a lot of bot. He block good, run back when necessary and attack with random parameters but these parameters are one of the good choice. Not the bad choice.

I will make 10 way of AI fighting, and the best AI fighting is use for super heroes and super boss of enemy. The worst AI fighting is use for a captain of a small group of troop. Also, All of AI fighting must better than or original.

Sorry, i am bad at English.
 
CTCCoco said:
Are you going to release it as OSP so we can make Michael Jackson simulation mod?
Sorry i don't know What is Michael Jackson simulation mod? can you explain it?
It's free when complete. And i also show my code for you to create more AI easily.
 
hacbachvothuong said:
Sorry i don't know What is Michael Jackson simulation mod? can you explain it?
It's free when complete. And i also show my code for you to create more AI easily.

It's a joke :smile: Michael Jackson popularised the 'Moonwalk' dance move. which is what the AI  was doing.
 
Zephilinox said:
hacbachvothuong said:
Sorry i don't know What is Michael Jackson simulation mod? can you explain it?
It's free when complete. And i also show my code for you to create more AI easily.

It's a joke :smile: Michael Jackson popularised the 'Moonwalk' dance move. which is what the AI  was doing.
im sort of amazed that that needed explaining.  :roll:
 
For some reason I found it really satisfying see a bot beat up a bunch of other bots thanks to footwork, timing and blocking instead of high stats.

Love this stuff, keep it up! :smile:
 
I am really liking this idea, to keep regular troops regular, naturally, or fights would last years.  Quite possibly, literally if you just let it sit that long.

I cannot wait until this is released, and a tutorial for this as well from what I understand?
 
Just a friendly advise: A perfect AI is based on unpredictability, amazeness and steadiness, my opinion. The over-walking bots(Moving double faster compared to an agent-feet, not nice really.) , blocking in uber speed...etc. You need to spice up some random events during the fight. Like agents are moving right/left when player attacks overhead or thrust, so predictable.

I appreciate the effort, really handsome work but what you got right now would only help to people who wants to practice over their gameplay technique. Noone wants a unkillable BOSS, blocking 3 player same time and killing them eventually. Don't stick with the greatness of AI, have it reasonable and within the range of realism.
 
I am bad at english, so don't joke anything as micheal jackson dance, i don't know  :grin:

Belendor said:
Just a friendly advise: A perfect AI is based on unpredictability, amazeness and steadiness, my opinion. The over-walking bots(Moving double faster compared to an agent-feet, not nice really.) , blocking in uber speed...etc. You need to spice up some random events during the fight. Like agents are moving right/left when player attacks overhead or thrust, so predictable.

I appreciate the effort, really handsome work but what you got right now would only help to people who wants to practice over their gameplay technique. Noone wants a unkillable BOSS, blocking 3 player same time and killing them eventually. Don't stick with the greatness of AI, have it reasonable and within the range of realism.


yes i know. Moving double faster is only a bug when i create an animation using acf_displace_position. Because i can't code the bot use original walking back while attack or defend. moving double faster or normally is not important because the bot can measure the safe distance before walking backward. moving right/left is my next step.

However, i think some mod need a double faster speed for a boss move when needed. Because some mod doesn't need a reality fight. so, i release two AI fighting's way. the choice is yours.
My next step is multi kill.
 
Code:
common_AIfight = (
    0.2, 0, 0, [],
  [
      (try_begin),#1
(try_for_agents, ":agent41"),
    (agent_is_human, ":agent41"),
      (agent_is_alive, ":agent41"),

      (try_begin),#1,5
      (agent_has_item_equipped, ":agent41", "itm_sword_two_handed_a"), #agent who have that sword will use this AI fighting. he is a hero
      (assign, ":agent40", ":agent41"), #and he become agent41
      (agent_get_position, pos40, ":agent40"),
   (else_try),#1.5
(assign, ":agent42", ":agent41"), #enemy is agent42 (include player and bot)
(agent_get_position, pos42, ":agent42"),

(try_end),#1.5

(get_distance_between_positions, reg41, pos40, pos42), #reg41 is distance between hero and enemy
      (le, reg41, 500),
      (agent_is_alive, ":agent42"),
(agent_get_attack_action, reg40, ":agent40"),  #reg40 is hero attack action
(agent_get_attack_action, reg42, ":agent42"),  #reg42 is enenmy attack action
      (try_begin),#1.7
(eq, reg40, 0),#agent40 free
(eq, reg42, 0),#agent42 free
(try_begin),#4.1
(ge, reg41, 400),     
(agent_set_animation, ":agent40", "anim_runforward1"),      
(else_try),
(gt, reg41, 180),
(agent_set_animation, ":agent40", "anim_runbackwardleft1"),
(else_try),
(le, reg41, 180),
(agent_set_attack_action, ":agent40", 2, 0),            
(try_end),#4.1

(else_try), #1.7
(eq, reg40, 0),#agent40 free
(this_or_next|eq, reg42, 1),#agent42 ready
(this_or_next|eq, reg42, 2),#agent42 release      
(agent_get_action_dir, reg43, ":agent42"),#reg43 is enemy attack direction
(try_begin),#4.3
(eq, reg43, 0),
(agent_set_animation, ":agent40", "anim_runbackwardleft1"),
(agent_set_defend_action, ":agent40", 0, 100),
(else_try),#4.3
(eq, reg43, 3),
(agent_set_animation, ":agent40", "anim_runbackwardleft1"),
(agent_set_defend_action, ":agent40", 3, 100),      
(else_try),#4.3
(eq, reg43, 1),
(agent_set_animation, ":agent40", "anim_runforward1"),      
(agent_set_defend_action, ":agent40", 1, 100),
(else_try),#4.3
(eq, reg43, 2),
(agent_set_animation, ":agent40", "anim_runforward1"),      
(agent_set_defend_action, ":agent40", 2, 100),
(try_end), #4.3      

(else_try), #1.7
(eq, reg40, 2),#agent40 release
(eq, reg42, 1),#agent42 ready
(display_message, "@release vs ready"),

(else_try), #1.7
(eq, reg40, 1),#agent40 ready
(eq, reg42, 1),#agent42 ready
(try_begin),#4.3
(eq, reg43, 0),
(agent_set_animation, ":agent40", "anim_runbackwardleft1"),
(agent_set_defend_action, ":agent40", 0, 100),
(else_try),#4.3
(eq, reg43, 3),
(agent_set_animation, ":agent40", "anim_runbackwardleft1"),
(agent_set_defend_action, ":agent40", 3, 100),      
(else_try),#4.3
(eq, reg43, 1),
(agent_set_animation, ":agent40", "anim_runforward1"),      
(agent_set_defend_action, ":agent40", 1, 100),
(else_try),#4.3
(eq, reg43, 2),
(agent_set_animation, ":agent40", "anim_runforward1"),      
(agent_set_defend_action, ":agent40", 2, 100),
(try_end), #4.3 

(else_try), #1.7
(display_message, "@These remaining case is the next AI"),      


  

(try_end),#1.7
(try_end),      #1
   
   ])
This is my tutorial code in mission_template. I need you help me to make it better because i'm bad at coding (i have just learned python by myself for a month by web search).i don't know how to make try_for_agent do once for all agent in scene and then make it looping when check their stance and decide what they do. My code make try_for_agent checking all agent every time and waste cpu time.

 
hacbachvothuong said:
This is my tutorial code in mission_template. I need you help me to make it better because i'm bad at coding (i have just learned python by myself for a month by web search).i don't know how to make try_for_agent do once for all agent in scene and then make it looping when check their stance and decide what they do. My code make try_for_agent checking all agent every time and waste cpu time.
Your module system skills are commendable (and learning actual Python is certainly a plus), but you might need to work on indentation and variable names. The usage of registers isn't really recommend especially in a time-sensitive context like mission triggers, although you are using ones that are unlikely to be overwritten. A couple of comments about your code: (try_begin), #1 is redundant as it isn't closed at the bottom - the entire [] is a code block to begin with so you don't need to start it off with another one. Some of the code blocks could be combined (of course, if you want more complex reactions for each category it's always good to separate them), but here's a slightly more streamlined version (here, ":action_dir" replaces reg43)
Code:
        (try_begin),#4.3
          (this_or_next|eq, ":action_dir", 3),
          (eq, ":action_dir", 0),
          (agent_set_animation, ":agent40", "anim_runbackwardleft1"),
        (else_try),#4.3
          (ethis_or_next|eq, ":action_dir", 1),
          (eq, ":action_dir", 2),
          (agent_set_animation, ":agent40", "anim_runforward1"),      
        (try_end), #4.3 
        (agent_set_defend_action, ":agent40", ":action_dir", 100),

I noticed that in the video the bot would only do slashes - obviously this is easily countered by holding down right block. Here's a small blurb to add more variety (if you have modded weapons to have different itc then you can adjust this however you want with edge cases).
Code:
        (agent_get_wielded_item, ":weapon", ":agent_no", 0),
        (item_get_type, ":type", ":weapon"),
        (assign, ":attack_dir", -1),
        (try_begin), #random slashing (axes, sabres can't stab)
          (this_or_next|eq, ":type", itp_type_one_handed_wpn),
          (eq, ":type", itp_type_two_handed_wpn),
          (store_random_in_range, ":attack_dir", 1, 4),
        (else_try),
          (eq, ":type", itp_type_polearm),
          (assign, ":attack_dir", 3, 5), #overhead (for pikes and such)
          (try_begin),
            (agent_get_wielded_item, ":shield", ":agent_no", 1),
            (this_or_next|eq, ":attack_dir", 4),
            (gt, ":shield", 0), #shielding means no slashing
            (assign, ":attack_dir", 0), #stabbity stab
          (try_end),
        (try_end),
        (is_between, ":attack_dir", 0, 4),

Lastly, with regards to applying this to multiple agents - historically soldiers fought in groups and warriors fought individually. Group fighting usually involves formations, which doesn't give much room for advancing and manoeuvring. There are already quite a few polished formation kits out there which work fine for that purpose. I'm not trying to discourage you here, but there's no easy way to loop through all agents effectively and make them single out opponents to duel while in the context of a battle (and don't get me started on mounted combat, which your code should exclude). WSE offers some optimization for agent loops, but it's up to you to make sense of them while taking into account parries, obstacles on the ground (and height differences), and other agents barging between them or even attacking them.
 
to Somebody

I'm very grateful to you for this post. i will continue learning with your instructions.
This is my new code and the Bot can 1 vs 8. he will kill alone enemy, slash and block while running backward when a group of enemy attack. I will make Hero's animation fine when complete the code.
PLAYER + ORIGINAL AI VS NEW AI
1 BOSS VS 8  BOT.

Code:
common_AI_fight2 = ( #find hero va enemy
    0.0, 0, 0, [],
  [
(assign, ":count1", 0),
      (try_begin),
(try_for_agents, ":agent_temp"),
    (agent_is_human, ":agent_temp"),
      (try_begin),
(agent_is_alive, ":agent_temp"),
(agent_has_item_equipped, ":agent_temp", "itm_glaive"),  # hero is the man who have this item.
      (assign, "$agent_hero", ":agent_temp"), # $agent_hero is a global variable
      (else_try),
      (agent_is_alive, "$agent_hero"),
      (assign, "$agent_enemy", ":agent_temp"), #$agent_enemy  is a global variable
(agent_get_position, pos12, "$agent_enemy"),
(agent_get_position, pos11, "$agent_hero"),
(get_sq_distance_between_positions, reg15, pos11, pos12), 
(get_distance_between_positions, reg17, pos11, pos12), 
(try_begin),
(agent_is_alive, "$agent_enemy"),
(le, reg15, 6400), # Square in cm2
(store_add, ":count1", ":count1", 1),
      (assign, reg11, ":count1"),
(assign, "$enemy_count1", ":count1"),    #$enemy_count1 is number of enemy
(assign, "$agent_enemy1", "$agent_enemy"), #$agent_enemy1 is the enemy inside Square range.
(else_try),
(agent_is_alive, "$agent_enemy"),
(gt, reg15, 6400),
(store_add, ":count1", ":count1", 0),            
(assign, reg11, ":count1"),
(assign, "$enemy_count1", ":count1"),   
(try_end),
      (try_end),
(try_end),



   
   ])
common_AI_fight3 = ( #Display number of enemy in range of Square
    0.2, 0.1, 0, [],
[
(try_begin),
(agent_is_alive, "$agent_hero"),
(assign, reg12, "$enemy_count1"), #reg12 is number of enemy in range of Square
(val_add, reg16, 0),
(try_begin),
(neg|eq, reg12, reg16),

(try_begin),
(eq, reg12, "$enemy_count_check"),
(display_message, "@there are {reg12} enemies in Square's range"),
(assign, reg16, "$enemy_count1"),
(else_try),
(neg|eq, reg12, "$enemy_count_check"),
(assign, reg12, "$enemy_count_check"),
(display_message, "@there are {reg12} enemies in Square's range"),
(try_end),

(try_end),  
(try_end),  

 ])

common_AI_fight4 = ( #check number of enemy in Square to compare with common_AI_fight3
    0.1, 0.0, 0, [],
  [
(try_begin),
(agent_is_alive, "$agent_hero"),
(assign, "$enemy_count_check", "$enemy_count1"), # check number of enemy every 0,1s
(try_end),  
 ])

common_AI_fight5 = ( #check number enemies in Square's range to decided how to move
    0.3, 0.0, 0, [],
  [
(try_begin),#1
(eq, reg12, 0), #number of enemy in S range is 0
(display_message, "@There is no enemy in range"),
(else_try),
(eq, reg12, 1), #number of enemy in S range is 1
(agent_is_alive, "$agent_hero"),
(agent_is_alive, "$agent_enemy1"),
(agent_get_position, pos21, "$agent_hero"),
(agent_get_position, pos22, "$agent_enemy1"),
(get_distance_between_positions, reg21, pos21, pos22), #reg21 is the distance between hero and the only 1 enemy in S range

(try_begin),
(le, reg21, 300),
(try_begin),
(agent_get_attack_action, reg24, "$agent_enemy1"),  

(try_begin),
(eq, reg24, 0),
(agent_set_attack_action, "$agent_hero", 1, 0),
(else_try),
(is_between, reg24, 1, 4),
(agent_get_action_dir, reg25, "$agent_enemy1"),

(try_begin), 
(eq, reg25, 0),
(agent_set_animation, "$agent_hero", "anim_runbackward_left"),
(else_try),
(eq, reg25, 1),
(agent_set_animation, "$agent_hero", "anim_runbackward_right"),
(else_try),
(eq, reg25, 2),
(agent_set_animation, "$agent_hero", "anim_runbackward_left"),
(else_try),
 (eq, reg25, 3),
(agent_set_animation, "$agent_hero", "anim_runbackward_right"),
(try_end),#1.4

(else_try),
(eq, reg24, 4),
(agent_set_attack_action, "$agent_hero", 2, 0),
(else_try),
(eq, reg24, 6),
(agent_set_attack_action, "$agent_hero", 3, 0),
(try_end),
(try_end),

(else_try),
(is_between, reg21, 301, 600),
(agent_set_attack_action, "$agent_hero", 0, 0),      
(agent_set_animation, "$agent_hero", "anim_run_forward"),
(try_end),

(else_try),
(le, reg12, 3), # If number of enemies is little than 4
(store_random_in_range, reg23, 1, 10), # hero do random move to avoid enemy's attack

(try_begin),
(le, reg23, 4),
(agent_set_animation, "$agent_hero", "anim_runbackward_left"),
(else_try),
(le, reg23, 8),
(agent_set_animation, "$agent_hero", "anim_runbackward_right"),
(else_try),
(eq, reg23, 9),
(agent_set_animation, "$agent_hero", "anim_runbackward"),
(try_end),

(else_try),
(gt, reg12, 3), # If number of enemies is greater than 3
(store_random_in_range, reg23, 1, 11),

(try_begin),
(eq, reg23, 1),
(agent_set_animation, "$agent_hero", "anim_runbackward_left"),
(else_try),
(le, reg23, 4),
(agent_set_animation, "$agent_hero", "anim_runbackward_right"),
(else_try),
(gt, reg23, 4),
(agent_set_animation, "$agent_hero", "anim_runbackward"),
(try_end),


(try_end),


])

common_AI_fight6 = ( #decided how to block or attack.
    0.0, 0.0, 0, [],
  [
(le, reg21, 350),     
(try_begin),
(agent_get_attack_action, reg24, "$agent_enemy1"),  
(agent_get_attack_action, reg26, "$agent_hero"),  
(try_begin),
(eq, reg24, 2),
(le, reg26, 1),
(agent_get_action_dir, reg25, "$agent_enemy1"),
(try_begin), 
(eq, reg25, 0),
(agent_set_defend_action, "$agent_hero", 0, 20),
(else_try),
(eq, reg25, 1),
(agent_set_defend_action, "$agent_hero", 1, 20),
(else_try),
(eq, reg25, 2),
(agent_set_defend_action, "$agent_hero", 2, 20),
(else_try),
 (eq, reg25, 3),
(agent_set_defend_action, "$agent_hero", 3, 20),
(try_end),
(else_try),
(eq, reg24, 4),
(agent_set_attack_action, "$agent_hero", 2, 0),
(else_try),
(eq, reg24, 6),
(agent_set_attack_action, "$agent_hero", 3, 0),
(try_end),
(try_end),
 ])
 
Your coding is nice, but please, for the love of God and your own good health and performance, INDEN-****ING-TATION! Here's your own code back, but fixed:
Code:
common_AI_fight2 = ( #find hero va enemy
    0.0, 0, 0, [], [
	(assign, ":count1", 0),
	# (try_begin), # This is is NOT necessary
	(try_for_agents, ":agent_temp"),
		(agent_is_human, ":agent_temp"),
		(try_begin),
			(agent_is_alive, ":agent_temp"),
			(agent_has_item_equipped, ":agent_temp", "itm_glaive"),  # hero is the man who have this item.
			(assign, "$agent_hero", ":agent_temp"), # $agent_hero is a global variable
		(else_try),
			(agent_is_alive, "$agent_hero"),
			(assign, "$agent_enemy", ":agent_temp"), #$agent_enemy  is a global variable
			(agent_get_position, pos12, "$agent_enemy"),
			(agent_get_position, pos11, "$agent_hero"),
			(get_sq_distance_between_positions, ":sq_dist", pos11, pos12), 
			# (get_distance_between_positions, reg17, pos11, pos12), # This is unused
			(try_begin),
				(agent_is_alive, "$agent_enemy"),
				(le, ":sq_dist", 6400), # Square in cm2
				(store_add, ":count1", ":count1", 1),
				# (assign, reg11, ":count1"), # These two are not used as well
				(assign, "$enemy_count1", ":count1"),    #$enemy_count1 is number of enemy
				(assign, "$agent_enemy1", "$agent_enemy"), #$agent_enemy1 is the enemy inside Square range.
			(else_try),
				(agent_is_alive, "$agent_enemy"),
				(gt, ":sq_dist", 6400),
				(store_add, ":count1", ":count1", 0),            
				# (assign, reg11, ":count1"),
				(assign, "$enemy_count1", ":count1"),
			(try_end),
		(try_end),
	(try_end),
   ])
   
   
common_AI_fight3 = ( #Display number of enemy in range of Square
    0.2, 0.1, 0, [],[ 
	(try_begin),
		(agent_is_alive, "$agent_hero"),
		# (assign, reg12, "$enemy_count1"), #reg12 is number of enemy in range of Square
		# ^ Why would you do that? Makes no sense
		(val_add, reg16, 0),
		(try_begin),
			(neg|eq, "$enemy_count1", reg16),
			(try_begin),
				(eq, "$enemy_count1", "$enemy_count_check"),
				(assign, reg12, "$enemy_count1"), # Allowed for debugging purposes only
				(display_message, "@DEBUG: There are {reg12} enemies in Square's range"),
				(assign, reg16, "$enemy_count1"),
			(else_try),
				(neg|eq, "$enemy_count1", "$enemy_count_check"),
				(assign, "$enemy_count1", "$enemy_count_check"),
				(assign, reg12, "$enemy_count1"), # Once again, for debugging only
				(display_message, "@DEBUG: There are {reg12} enemies in Square's range"), # What "Square"?
			(try_end),
		(try_end),  
	(try_end), 
 ])

common_AI_fight4 = ( #check number of enemy in Square to compare with common_AI_fight3
    0.1, 0.0, 0, [], [
	(try_begin),
		(agent_is_alive, "$agent_hero"),
		(assign, "$enemy_count_check", "$enemy_count1"), # check number of enemy every 0,1s
	(try_end),  
 ])

common_AI_fight5 = ( #check number enemies in Square's range to decided how to move
    0.3, 0.0, 0, [], [
	(try_begin),#1
		(eq, reg12, 0), #number of enemy in S range is 0
		(display_message, "@There is no enemy in range"),
	(else_try),
		(eq, reg12, 1), #number of enemy in S range is 1
		(agent_is_alive, "$agent_hero"),
		(agent_is_alive, "$agent_enemy1"),
		(agent_get_position, pos21, "$agent_hero"),
		(agent_get_position, pos22, "$agent_enemy1"),
		(get_distance_between_positions, reg21, pos21, pos22), #reg21 is the distance between hero and the only 1 enemy in S range
		(try_begin),
			(le, reg21, 300),
			(try_begin),
				(agent_get_attack_action, ":atk_action_enemy", "$agent_enemy1"),  
				(try_begin),
					(eq, ":atk_action_enemy", 0),
					(agent_set_attack_action, "$agent_hero", 1, 0),
				(else_try),
					(is_between, ":atk_action_enemy", 1, 4),
					(agent_get_action_dir, ":action_dir", "$agent_enemy1"),
					(try_begin), 
						(eq, ":action_dir", 0),
						(agent_set_animation, "$agent_hero", "anim_runbackward_left"),
					(else_try),
						(eq, ":action_dir", 1),
						(agent_set_animation, "$agent_hero", "anim_runbackward_right"),
					(else_try),
						(eq, ":action_dir", 2),
						(agent_set_animation, "$agent_hero", "anim_runbackward_left"),
					(else_try),
						(eq, ":action_dir", 3),
						(agent_set_animation, "$agent_hero", "anim_runbackward_right"),
					(try_end),#1.4
				(else_try),
					(eq, ":atk_action_enemy", 4),
					(agent_set_attack_action, "$agent_hero", 2, 0),
				(else_try),
					(eq, ":atk_action_enemy", 6),
					(agent_set_attack_action, "$agent_hero", 3, 0),
				(try_end),
			(try_end),
		(else_try),
			(is_between, reg21, 301, 600),
			(agent_set_attack_action, "$agent_hero", 0, 0),      
			(agent_set_animation, "$agent_hero", "anim_run_forward"),
		(try_end),
	(else_try),
		(le, reg12, 3), # If number of enemies is little than 4
		(store_random_in_range, ":rand", 1, 10), # hero do random move to avoid enemy's attack
		(try_begin),
			(le, ":rand", 4),
			(agent_set_animation, "$agent_hero", "anim_runbackward_left"),
		(else_try),
			(le, ":rand", 8),
			(agent_set_animation, "$agent_hero", "anim_runbackward_right"),
		(else_try),
			(eq, ":rand", 9),
			(agent_set_animation, "$agent_hero", "anim_runbackward"),
		(try_end),
	(else_try),
		(gt, reg12, 3), # If number of enemies is greater than 3
		(store_random_in_range, ":rand", 1, 11),
		(try_begin),
			(eq, ":rand", 1),
			(agent_set_animation, "$agent_hero", "anim_runbackward_left"),
		(else_try),
			(le, ":rand", 4),
			(agent_set_animation, "$agent_hero", "anim_runbackward_right"),
		(else_try),
			(gt, ":rand", 4),
			(agent_set_animation, "$agent_hero", "anim_runbackward"),
		(try_end),
	(try_end),
])

common_AI_fight6 = ( #decided how to block or attack.
    0.0, 0.0, 0, [], [
	(le, reg21, 350),     
	(try_begin),
		(agent_get_attack_action, ":atk_action_enemy", "$agent_enemy1"),  
		(agent_get_attack_action, ":atk_action_hero", "$agent_hero"),  
		(try_begin),
			(eq, ":atk_action_enemy", 2),
			(le, ":atk_action_hero", 1),
			(agent_get_action_dir, ":action_dir", "$agent_enemy1"),
			(try_begin), 
				(eq, ":action_dir", 0),
				(agent_set_defend_action, "$agent_hero", 0, 20),
			(else_try),
				(eq, ":action_dir", 1),
				(agent_set_defend_action, "$agent_hero", 1, 20),
			(else_try),
				(eq, ":action_dir", 2),
				(agent_set_defend_action, "$agent_hero", 2, 20),
			(else_try),
				(eq, ":action_dir", 3),
				(agent_set_defend_action, "$agent_hero", 3, 20),
			(try_end),
		(else_try),
			(eq, ":atk_action_enemy", 4),
			(agent_set_attack_action, "$agent_hero", 2, 0),
		(else_try),
			(eq, ":atk_action_enemy", 6),
			(agent_set_attack_action, "$agent_hero", 3, 0),
		(try_end),
	(try_end),
 ])
Use tabs to outline the try_ blocks and to be able to see what exactly's going on. Do not use registers, use damn local variables. You've also got a very weird way of passing registers between the triggers, and while yes, this is possible, you can never be sure that something else won't overwrite the registers you're using. However, utilising a tonne of global variables is also bad. You may want to flick a troop slot or something and use it accordingly.

TL;DR: Proper indentation is one of the most important things when writing code, make sure you follow it like the example I've given you. Tabs are your friend.
 
Lumos said:
Your coding is nice, but please, for the love of God and your own good health and performance, INDEN-********-TATION! Here's your own code back, but fixed:
Code:
common_AI_fight2 = ( #find hero va enemy
    0.0, 0, 0, [], [
	(assign, ":count1", 0),
	# (try_begin), # This is is NOT necessary
	(try_for_agents, ":agent_temp"),
		(agent_is_human, ":agent_temp"),
		(try_begin),
			(agent_is_alive, ":agent_temp"),
			(agent_has_item_equipped, ":agent_temp", "itm_glaive"),  # hero is the man who have this item.
			(assign, "$agent_hero", ":agent_temp"), # $agent_hero is a global variable
		(else_try),
			(agent_is_alive, "$agent_hero"),
			(assign, "$agent_enemy", ":agent_temp"), #$agent_enemy  is a global variable
			(agent_get_position, pos12, "$agent_enemy"),
			(agent_get_position, pos11, "$agent_hero"),
			(get_sq_distance_between_positions, ":sq_dist", pos11, pos12), 
			# (get_distance_between_positions, reg17, pos11, pos12), # This is unused
			(try_begin),
				(agent_is_alive, "$agent_enemy"),
				(le, ":sq_dist", 6400), # Square in cm2
				(store_add, ":count1", ":count1", 1),
				# (assign, reg11, ":count1"), # These two are not used as well
				(assign, "$enemy_count1", ":count1"),    #$enemy_count1 is number of enemy
				(assign, "$agent_enemy1", "$agent_enemy"), #$agent_enemy1 is the enemy inside Square range.
			(else_try),
				(agent_is_alive, "$agent_enemy"),
				(gt, ":sq_dist", 6400),
				(store_add, ":count1", ":count1", 0),            
				# (assign, reg11, ":count1"),
				(assign, "$enemy_count1", ":count1"),
			(try_end),
		(try_end),
	(try_end),
   ])
   
   
common_AI_fight3 = ( #Display number of enemy in range of Square
    0.2, 0.1, 0, [],[ 
	(try_begin),
		(agent_is_alive, "$agent_hero"),
		# (assign, reg12, "$enemy_count1"), #reg12 is number of enemy in range of Square
		# ^ Why would you do that? Makes no sense
		(val_add, reg16, 0),
		(try_begin),
			(neg|eq, "$enemy_count1", reg16),
			(try_begin),
				(eq, "$enemy_count1", "$enemy_count_check"),
				(assign, reg12, "$enemy_count1"), # Allowed for debugging purposes only
				(display_message, "@DEBUG: There are {reg12} enemies in Square's range"),
				(assign, reg16, "$enemy_count1"),
			(else_try),
				(neg|eq, "$enemy_count1", "$enemy_count_check"),
				(assign, "$enemy_count1", "$enemy_count_check"),
				(assign, reg12, "$enemy_count1"), # Once again, for debugging only
				(display_message, "@DEBUG: There are {reg12} enemies in Square's range"), # What "Square"?
			(try_end),
		(try_end),  
	(try_end), 
 ])

common_AI_fight4 = ( #check number of enemy in Square to compare with common_AI_fight3
    0.1, 0.0, 0, [], [
	(try_begin),
		(agent_is_alive, "$agent_hero"),
		(assign, "$enemy_count_check", "$enemy_count1"), # check number of enemy every 0,1s
	(try_end),  
 ])

common_AI_fight5 = ( #check number enemies in Square's range to decided how to move
    0.3, 0.0, 0, [], [
	(try_begin),#1
		(eq, reg12, 0), #number of enemy in S range is 0
		(display_message, "@There is no enemy in range"),
	(else_try),
		(eq, reg12, 1), #number of enemy in S range is 1
		(agent_is_alive, "$agent_hero"),
		(agent_is_alive, "$agent_enemy1"),
		(agent_get_position, pos21, "$agent_hero"),
		(agent_get_position, pos22, "$agent_enemy1"),
		(get_distance_between_positions, reg21, pos21, pos22), #reg21 is the distance between hero and the only 1 enemy in S range
		(try_begin),
			(le, reg21, 300),
			(try_begin),
				(agent_get_attack_action, ":atk_action_enemy", "$agent_enemy1"),  
				(try_begin),
					(eq, ":atk_action_enemy", 0),
					(agent_set_attack_action, "$agent_hero", 1, 0),
				(else_try),
					(is_between, ":atk_action_enemy", 1, 4),
					(agent_get_action_dir, ":action_dir", "$agent_enemy1"),
					(try_begin), 
						(eq, ":action_dir", 0),
						(agent_set_animation, "$agent_hero", "anim_runbackward_left"),
					(else_try),
						(eq, ":action_dir", 1),
						(agent_set_animation, "$agent_hero", "anim_runbackward_right"),
					(else_try),
						(eq, ":action_dir", 2),
						(agent_set_animation, "$agent_hero", "anim_runbackward_left"),
					(else_try),
						(eq, ":action_dir", 3),
						(agent_set_animation, "$agent_hero", "anim_runbackward_right"),
					(try_end),#1.4
				(else_try),
					(eq, ":atk_action_enemy", 4),
					(agent_set_attack_action, "$agent_hero", 2, 0),
				(else_try),
					(eq, ":atk_action_enemy", 6),
					(agent_set_attack_action, "$agent_hero", 3, 0),
				(try_end),
			(try_end),
		(else_try),
			(is_between, reg21, 301, 600),
			(agent_set_attack_action, "$agent_hero", 0, 0),      
			(agent_set_animation, "$agent_hero", "anim_run_forward"),
		(try_end),
	(else_try),
		(le, reg12, 3), # If number of enemies is little than 4
		(store_random_in_range, ":rand", 1, 10), # hero do random move to avoid enemy's attack
		(try_begin),
			(le, ":rand", 4),
			(agent_set_animation, "$agent_hero", "anim_runbackward_left"),
		(else_try),
			(le, ":rand", 8),
			(agent_set_animation, "$agent_hero", "anim_runbackward_right"),
		(else_try),
			(eq, ":rand", 9),
			(agent_set_animation, "$agent_hero", "anim_runbackward"),
		(try_end),
	(else_try),
		(gt, reg12, 3), # If number of enemies is greater than 3
		(store_random_in_range, ":rand", 1, 11),
		(try_begin),
			(eq, ":rand", 1),
			(agent_set_animation, "$agent_hero", "anim_runbackward_left"),
		(else_try),
			(le, ":rand", 4),
			(agent_set_animation, "$agent_hero", "anim_runbackward_right"),
		(else_try),
			(gt, ":rand", 4),
			(agent_set_animation, "$agent_hero", "anim_runbackward"),
		(try_end),
	(try_end),
])

common_AI_fight6 = ( #decided how to block or attack.
    0.0, 0.0, 0, [], [
	(le, reg21, 350),     
	(try_begin),
		(agent_get_attack_action, ":atk_action_enemy", "$agent_enemy1"),  
		(agent_get_attack_action, ":atk_action_hero", "$agent_hero"),  
		(try_begin),
			(eq, ":atk_action_enemy", 2),
			(le, ":atk_action_hero", 1),
			(agent_get_action_dir, ":action_dir", "$agent_enemy1"),
			(try_begin), 
				(eq, ":action_dir", 0),
				(agent_set_defend_action, "$agent_hero", 0, 20),
			(else_try),
				(eq, ":action_dir", 1),
				(agent_set_defend_action, "$agent_hero", 1, 20),
			(else_try),
				(eq, ":action_dir", 2),
				(agent_set_defend_action, "$agent_hero", 2, 20),
			(else_try),
				(eq, ":action_dir", 3),
				(agent_set_defend_action, "$agent_hero", 3, 20),
			(try_end),
		(else_try),
			(eq, ":atk_action_enemy", 4),
			(agent_set_attack_action, "$agent_hero", 2, 0),
		(else_try),
			(eq, ":atk_action_enemy", 6),
			(agent_set_attack_action, "$agent_hero", 3, 0),
		(try_end),
	(try_end),
 ])
Use tabs to outline the try_ blocks and to be able to see what exactly's going on. Do not use registers, use damn local variables. You've also got a very weird way of passing registers between the triggers, and while yes, this is possible, you can never be sure that something else won't overwrite the registers you're using. However, utilising a tonne of global variables is also bad. You may want to flick a troop slot or something and use it accordingly.

TL;DR: Proper indentation is one of the most important things when writing code, make sure you follow it like the example I've given you. Tabs are your friend.
thank you very much for your instruction about Tabs. I don't know why need to use Tabs until your post. Because i'm bad at english and google translate is too bad, so i don't know all of your instruction about global variables.
Code:
utilising a tonne of global variables is also bad. You may want to flick a troop slot or something and use it accordingly.[/spoiler]
 
Back
Top Bottom