OSP Code Combat AI Kicking!

Users who are viewing this thread

Zarthas

Knight at Arms
Hello,

So there's no code around the forums for making AI combatants kick each other or you.  Here's a code snippet for mission_templates that makes AI agents occasionally kick people that are super close to them.  The AI tries to kick when he either parries or gets parried, meaning he wants to open up some space between you and him, which seems like a reasonable implementation.

There's no experience quite like being kicked to death by 30 angry farmers.

It works nicely, but you may have to adjust the ":kickchance" or the timer for your personal liking.  There's a 10% chance every 3 seconds, meaning under the best circumstances every 30 seconds in a melee an agent will kick someone.

To any coders out there, this is the first time I've used the agent_ai_get_look_target operation.  Are there any potential problems with using this?  I like that its much less CPU expensive than running another loop to check for targets, and it ensures that the target he's trying to attack is the same one he'll try to kick.

Also, does anyone know if Power Strike affects agent_deliver_damage_to_agent?

Code:
AI_kick =  (
         2, 0, 0,
       [], [
	(get_player_agent_no,":player"),
	(try_for_agents, ":agent"),
		(neq, ":agent", ":player"),
		(agent_is_alive, ":agent"),
		(agent_is_human, ":agent"),#Only humans can kick....FOR NOW
		(agent_is_active, ":agent"),
		(agent_slot_eq, ":agent", slot_agent_is_running_away, 0),#Isn't fleeing the battle.
		##He's an eligible human.  Now see if he's in a position to kick.
		(agent_get_attack_action, ":attack_action", ":agent"), #returned values: free = 0, readying_attack = 1, releasing_attack = 2, completing_attack_after_hit = 3, attack_parried = 4, reloading = 5, after_release = 6, cancelling_attack = 7
		(agent_get_defend_action, ":defend_action", ":agent"),#
		(this_or_next|eq,":attack_action",4),#Just got parried
		(this_or_next|eq,":defend_action",1),#Parrying an enemy
		##So he'll only try to kick if he just parried an enemy attack, or his own attack just got parried.
		(agent_get_team, ":team", ":agent"),
		(assign, ":maximum_distance", 100),
		#Target Acquisition
		(agent_ai_get_look_target,":suspect",":agent"),
		(gt,":suspect",0),#Make sure there is someone.
		(agent_is_alive, ":suspect"),
		(agent_is_human, ":suspect"),#Only kick humans
		(agent_is_active, ":suspect"),
		(agent_get_team, ":suspect_team", ":suspect"),
		(neq, ":suspect_team", ":team"),#Friends don't let friends kick friends.
		(agent_get_position, pos1, ":agent"),#Distance check
		(agent_get_position, pos2, ":suspect"),
		(neg|position_is_behind_position, pos2, pos1), #Suspect can't be behind kicker.
		(get_distance_between_positions, ":distance", pos1, pos2),
		(le, ":distance", ":maximum_distance"),
		#Check chance
		(store_random_in_range,":kickchance", 1, 10),
		(try_begin),
			(eq,":kickchance",1), #10% chance per check
				(display_message, "@Agent kicks."),
				(agent_set_animation, ":agent", "anim_prepare_kick_0"),
				(agent_deliver_damage_to_agent, ":agent", ":suspect", 3),
				(agent_set_animation, ":suspect", "anim_strike3_abdomen_front"),#Get Kicked
			(try_end),
	   (try_end),])

Presently, from a Game Design perspective, its a "no-risk" option for the AI, unlike it being a fairly high-risk option for the player due to the long animation time.  I suppose this is fine, since the AI doesn't know that and can't exploit it, but I think I'll write in a chance to have a poorly timed kick that has no effect, exposes him to attacks.

edit:  Realized AI would occasionally try to kick something that no longer exists, should be fixed now.
edit again: Animation was slightly wonky, should look better now.
 
Okay, no worries, thanks for trying to help!  I've started one, behavior is in, just needs to actually affect people who get kicked now  :party:  I'll post it up when I've got it working nicely.
 
Looks pretty cool. I'm all up for giving the player more variety in which he can be attacked. I wonder what else could be done with this to make the game more challenging for players.
 
  It flows pretty well, especially for enemies armed with polearms.  Maybe I should make agents wielding two-handed polearms more likely to kick. If you think up a feature or tweak that would make sense, give me a shout and I can work it in.

Let me know how it works for you.
 
Hello,

Just toss it in a mission where you want them to be able to kick.

The common recommendation is to search for "common_battle_tab_press" and then put it behind that, like so:

Code:
common_battle_tab_press,
AI_kick,
 
I didn't make the animation or anything, its just an unused one in Native, which now that I look at it is actually the same as the one the player uses.

Alternatively, you could set him to use "anim_prepare_kick_0", gives you 0.05 more seconds in the animation, might look a little smoother.

edit:  Just realized that I'd actually been using this on my end, but hadn't changed it here.  :shock:  Check the first post for the newest version.
 
I'm not sure exactly what is going on. I followed your guide to the very end and the AI still does not kick. I've raised numbers and everything, still no kicking. I guess I'll let someone show me the code, but is there a way to make it 100% chance to kick? I've tried
#Check chance
(store_random_in_range,":kickchance", 90, 100),
(try_begin),
(eq,":kickchance",1), #10% chance per check

and I tried

#Check chance
(store_random_in_range,":kickchance", 90, 100),
(try_begin),
(eq,":kickchance",90), #10% chance per check

I understand though that eq,":kickchance",1 is just saying that it was called, but I gave it a shot.
 
Oh, just remove that logic altogether then, like so:

Code:
AI_kick =  (
         2, 0, 0,
       [], [
	(get_player_agent_no,":player"),
	(try_for_agents, ":agent"),
		(neq, ":agent", ":player"),
		(agent_is_alive, ":agent"),
		(agent_is_human, ":agent"),#Only humans can kick....FOR NOW
		(agent_is_active, ":agent"),
		(agent_slot_eq, ":agent", slot_agent_is_running_away, 0),#Isn't fleeing the battle.
		##He's an eligible human.  Now see if he's in a position to kick.
		(agent_get_attack_action, ":attack_action", ":agent"), #returned values: free = 0, readying_attack = 1, releasing_attack = 2, completing_attack_after_hit = 3, attack_parried = 4, reloading = 5, after_release = 6, cancelling_attack = 7
		(agent_get_defend_action, ":defend_action", ":agent"),#
		(this_or_next|eq,":attack_action",4),#Just got parried
		(this_or_next|eq,":defend_action",1),#Parrying an enemy
		##So he'll only try to kick if he just parried an enemy attack, or his own attack just got parried.
		(agent_get_team, ":team", ":agent"),
		(assign, ":maximum_distance", 100),
		#Target Acquisition
		(agent_ai_get_look_target,":suspect",":agent"),
		(gt,":suspect",0),#Make sure there is someone.
		(agent_is_alive, ":suspect"),
		(agent_is_human, ":suspect"),#Only kick humans
		(agent_is_active, ":suspect"),
		(agent_get_team, ":suspect_team", ":suspect"),
		(neq, ":suspect_team", ":team"),#Friends don't let friends kick friends.
		(agent_get_position, pos1, ":agent"),#Distance check
		(agent_get_position, pos2, ":suspect"),
		(neg|position_is_behind_position, pos2, pos1), #Suspect can't be behind kicker.
		(get_distance_between_positions, ":distance", pos1, pos2),
		(le, ":distance", ":maximum_distance"),
		#Check chance
		#(store_random_in_range,":kickchance", 1, 10),
		#(try_begin),
			#(eq,":kickchance",1), #10% chance per check
				(display_message, "@Agent kicks."),
				(agent_set_animation, ":agent", "anim_prepare_kick_0"),
				(agent_deliver_damage_to_agent, ":agent", ":suspect", 3),
				(agent_set_animation, ":suspect", "anim_strike3_abdomen_front"),#Get Kicked
			#(try_end),
	   (try_end),])


Are you sure that AI_kick is actually getting called in the mission type in question?  I don't mind checking your mission_templates if you post it here.
 
Thank you, this code works for me. It's weird how the other code didn't before, I'll mess around with it and see what happens. Thank you!

Edit - RAWR - Never mind, I got it working. Brain is tired from all the coding today.
 
Very nice and simple :wink: You should try to make AI kick more often when someone is wielding two handed or polearm weapon. It should be easy for you :smile:

Edit

I've made some changes to your code. You should take a look:

Code:
# AI Kick by Zarthas (modified by Garedyr)
AI_kick =  (2, 0, 0,
    [], [
	(get_player_agent_no,":player"),
		(try_for_agents, ":agent"),
			(neq, ":agent", ":player"),
			(agent_is_alive, ":agent"),
			(agent_is_human, ":agent"),#Only humans can kick....FOR NOW
			(agent_is_active, ":agent"),
			#-----------------------------------Garedyr begin
			(agent_get_horse, ":horse", ":agent"),
			(eq, ":horse", -1), #agent cannot be mounted
			#-----------------------------------Garedyr end
			(agent_slot_eq, ":agent", slot_agent_is_running_away, 0),#Isn't fleeing the battle.
			##He's an eligible human.  Now see if he's in a position to kick.
			(agent_get_attack_action, ":attack_action", ":agent"), #returned values: free = 0, readying_attack = 1, releasing_attack = 2, completing_attack_after_hit = 3, attack_parried = 4, reloading = 5, after_release = 6, cancelling_attack = 7
			(agent_get_defend_action, ":defend_action", ":agent"),#
			(this_or_next|eq,":attack_action",4),#Just got parried
			(this_or_next|eq,":defend_action",1),#Parrying an enemy
			##So he'll only try to kick if he just parried an enemy attack, or his own attack just got parried.
			(agent_get_team, ":team", ":agent"),
			(assign, ":maximum_distance", 100),
			#Target Acquisition
			(agent_ai_get_look_target,":suspect",":agent"),
			(gt,":suspect",0),#Make sure there is someone.
			(agent_is_alive, ":suspect"),
			(agent_is_human, ":suspect"),#Only kick humans
			(agent_is_active, ":suspect"),
			#-----------------------------------Garedyr begin
			(agent_get_horse, ":suspect_horse", ":suspect"),
			(eq, ":suspect_horse", -1), #suspect agent cannot be mounted too
			#-----------------------------------Garedyr end
			(agent_get_team, ":suspect_team", ":suspect"),
			(teams_are_enemies, ":suspect_team", ":team"),#Friends don't let friends kick friends. #Garedyr edit- Yes but we need to prevent neutral teams from kicking each other
			(agent_get_position, pos1, ":agent"),#Distance check
			(agent_get_position, pos2, ":suspect"),
			(neg|position_is_behind_position, pos2, pos1), #Suspect can't be behind kicker.
			(get_distance_between_positions, ":distance", pos1, pos2),
			(le, ":distance", ":maximum_distance"),
			#Check chance
			(store_random_in_range,":kickchance", 1, 10),
				(try_begin),
					(eq,":kickchance",1), #10% chance per check
					#(display_message, "@Agent kicks."), #useless information
					(agent_set_animation, ":agent", "anim_kick_right_leg"),
					(agent_play_sound, ":suspect", "snd_blunt_hit"),
					(agent_deliver_damage_to_agent, ":agent", ":suspect", 3),
					(agent_set_animation, ":suspect", "anim_strike3_abdomen_front"),#Get Kicked
				(try_end),
		(try_end),
	   ])
 
So I used your code, to make AI shield bashing as well. I released it all as OSP. Thanks!

https://forums.taleworlds.com/index.php/topic,353860.0.html
 
Back
Top Bottom