YesNoOk
avatar

AI Detect Enemy's (Helper) Projectile System (Read 230616 times)

Started by inktrebuchet, May 17, 2017, 08:30:27 pm
Share this topic:
AI Detect Enemy's (Helper) Projectile System
New #1  May 17, 2017, 08:30:27 pm
  • ****
    • USA
    • twitter.com/inktrebuchet
NOTE: This code replaces the one that I have found people are currently using in MUGEN: trigger? = (enemy, numhelper) . That code may seem to works for some characters but it actually detects any helper being used, not just projectiles! So an enemy with a helper on screen at all times, such as Megaman and his dog Rush will always trigger that code or any enemy that uses a helper for an effect will also trigger that code.

This is a helper that stays bound to the character to detect enemy spawned (Helper) Projectile and captures its playerid. That PlayerId can then be used to find out a lot more about the projectile. Including velocity, distance, position on screen, etc.

This system does use one blank animation of your choice that can be changed in the codes "config section".

There are plenty of notes included. If anyone thinks of a way to improve this let me know!
My second post has some simple codes to use with this system.
Also check out my AI Detect Enemy's (sctrl) Projectile System

This goes in [statedef -3]
Code:
[state -3, AI Detect Projectile System]
type = helper
trigger1 = ailevel ;M.U.G.E.N 1.0+
;trigger1 = var(59) = 1 ;M.U.G.E.N below 1.0 that uses Winane AI Activation Method.
trigger1 = !numhelper(33333333)
name = "AI Detect Projectile System"
ID = 33333333
stateno = 33333333
postype = p1
ownpal = 1
keyctrl = 0
size.xscale = 1.0
size.yscale = 1.0
supermovetime = 2147483647
pausemovetime = 2147483647
ignorehitpause = 1

This goes in CNS
Code:
;==========================================================================
;[Info]
;author = "Inktrebuchet"
;versiondate = 12/13/2018                 
;goal = Detect enemy projectile (helper). For use with AI. ( M.U.G.E.N | IKEMEN )
;       敵の発射物(helper)を検出する。 AIで使用する場合。
;==========================================================================
;                Notes
;==========================================================================
;notes:
;-Enemy projectile now has a PlayerID use PlayerID(helper(33333333),var(3)) as a redirect.
;
;base examples of trigger use:
;
;;Enemy projectile helper distance from character.
;trigger1 = PlayerIDExist(helper(33333333),var(3))
;trigger1 = PlayerID(helper(33333333),var(3)), p2bodydist x
;
;;Enemy projectile helper velocity.
;trigger1 = PlayerIDExist(helper(33333333),var(3))
;trigger1 = PlayerID(helper(33333333),var(3)), Vel X
;
;==========================================================================
;                Helper var usage.
;==========================================================================
; numhelper(33333333) Variable usage:
; This is a record of the variables that are used
;
; var(0) - highest playerid + 1
; var(3) - projectile player id while it exists
;
;==========================================================================
[Statedef 33333333]
type = A
movetype = I
physics = N
ctrl = 0
velset = 0, 0

;==========================================================================
;                Config Section
;==========================================================================
anim = 9741                   ; blank animation
 
;==========================================================================
[state 33333333, Clipboard]
type = DisplayToClipboard
trigger1 = 1
text = "Highest Playerid = %d , Projectile helper's PlayerId = %d\nBy Inktrebuchet"
params = var(0)-1, var(3)

;==========================================================================
;                Detect Enemy Projectile Helper
;==========================================================================
[State 33333333, 0]
type = Null
trigger1 = var(0) = 0
trigger1 = (var(0) := id)
ignorehitpause = 1
 
[state 33333333, 1]
type = varadd
trigger1 = PlayerIdExist(var(0))
trigger2 = PlayerIdExist(var(0)+1)
trigger3 = PlayerIdExist(var(0)+2)
trigger4 = PlayerIdExist(var(0)+3)
trigger5 = PlayerIdExist(var(0)+4)
trigger6 = PlayerIdExist(var(0)+5)
trigger7 = PlayerIdExist(var(0)+6)
trigger8 = PlayerIdExist(var(0)+7)
trigger9 = PlayerIdExist(var(0)+8)
trigger10 = PlayerIdExist(var(0)+9)
trigger11 = PlayerIdExist(var(0)+10)
trigger12 = PlayerIdExist(var(0)+11)
trigger13 = PlayerIdExist(var(0)+12)
trigger14 = PlayerIdExist(var(0)+13)
trigger15 = PlayerIdExist(var(0)+14)
trigger16 = PlayerIdExist(var(0)+15)
trigger17 = PlayerIdExist(var(0)+16)
trigger18 = PlayerIdExist(var(0)+17)
trigger19 = PlayerIdExist(var(0)+18)
trigger20 = PlayerIdExist(var(0)+19)
trigger21 = PlayerIdExist(var(0)+20)
trigger22 = PlayerIdExist(var(0)+21)
trigger23 = PlayerIdExist(var(0)+22)
trigger24 = PlayerIdExist(var(0)+23)
trigger25 = PlayerIdExist(var(0)+24)
trigger26 = PlayerIdExist(var(0)+25)
v = 0
value = 1
ignorehitpause = 1
 
[State 33333333, 2]
type = Null
triggerall = PlayerIdExist(Root,ID)
trigger1 = PlayerIdExist(var(0)-1)
trigger1 = IfElse(root,teamside = 1, PlayerID(var(0)-1),teamside = 2, PlayerID(var(0)-1),teamside = 1)
trigger1 = PlayerID(var(0)-1),hitdefattr = ASC, NP, SP, HP
trigger1 = var(3) := (var(0)-1)
trigger2 = PlayerIdExist(var(0)-2)
trigger2 = IfElse(root,teamside = 1, PlayerID(var(0)-2),teamside = 2, PlayerID(var(0)-2),teamside = 1)
trigger2 = PlayerID(var(0)-2),hitdefattr = ASC, NP, SP, HP
trigger2 = var(3) := (var(0)-2)
trigger3 = PlayerIdExist(var(0)-3)
trigger3 = IfElse(root,teamside = 1, PlayerID(var(0)-3),teamside = 2, PlayerID(var(0)-3),teamside = 1)
trigger3 = PlayerID(var(0)-3),hitdefattr = ASC, NP, SP, HP
trigger3 = var(3) := (var(0)-3)
trigger4 = PlayerIdExist(var(0)-4)
trigger4 = IfElse(root,teamside = 1, PlayerID(var(0)-4),teamside = 2, PlayerID(var(0)-4),teamside = 1)
trigger4 = PlayerID(var(0)-4),hitdefattr = ASC, NP, SP, HP
trigger4 = var(3) := (var(0)-4)
trigger5 = PlayerIdExist(var(0)-5)
trigger5 = IfElse(root,teamside = 1, PlayerID(var(0)-5),teamside = 2, PlayerID(var(0)-5),teamside = 1)
trigger5 = PlayerID(var(0)-5),hitdefattr = ASC, NP, SP, HP
trigger5 = var(3) := (var(0)-5)
trigger6 = PlayerIdExist(var(0)-6)
trigger6 = IfElse(root,teamside = 1, PlayerID(var(0)-6),teamside = 2, PlayerID(var(0)-6),teamside = 1)
trigger6 = PlayerID(var(0)-6),hitdefattr = ASC, NP, SP, HP
trigger6 = var(3) := (var(0)-6)
trigger7 = PlayerIdExist(var(0)-7)
trigger7 = IfElse(root,teamside = 1, PlayerID(var(0)-7),teamside = 2, PlayerID(var(0)-7),teamside = 1)
trigger7 = PlayerID(var(0)-7),hitdefattr = ASC, NP, SP, HP
trigger7 = var(3) := (var(0)-7)
trigger8 = PlayerIdExist(var(0)-8)
trigger8 = IfElse(root,teamside = 1, PlayerID(var(0)-8),teamside = 2, PlayerID(var(0)-8),teamside = 1)
trigger8 = PlayerID(var(0)-8),hitdefattr = ASC, NP, SP, HP
trigger8 = var(3) := (var(0)-8)
trigger9 = PlayerIdExist(var(0)-9)
trigger9 = IfElse(root,teamside = 1, PlayerID(var(0)-9),teamside = 2, PlayerID(var(0)-9),teamside = 1)
trigger9 = PlayerID(var(0)-9),hitdefattr = ASC, NP, SP, HP
trigger9 = var(3) := (var(0)-9)
trigger10 = PlayerIdExist(var(0)-10)
trigger10 = IfElse(root,teamside = 1, PlayerID(var(0)-10),teamside = 2, PlayerID(var(0)-10),teamside = 1)
trigger10 = PlayerID(var(0)-10),hitdefattr = ASC, NP, SP, HP
trigger10 = var(3) := (var(0)-10)
ignorehitpause = 1

[State 33333333, BindToRoot]
type = BindToRoot
trigger1 = PlayerIdExist(Root,ID)
time = 1
facing = 1
pos =0,-2
ignorehitpause = 1


This goes in Air file
*If you don't have a blank animation already
Code:
; Blank
[Begin Action 9741]
-1,0, 0,0, -1







Spoiler: Old Versions. (all compatible with example code in 2nd post.) (click to see content)
Last Edit: November 26, 2023, 06:04:34 am by inktrebuchet
Re: AI Detect Enemy's (Helper) Projectile System
#2  May 23, 2017, 08:17:15 pm
  • ****
    • USA
    • twitter.com/inktrebuchet

A list of codes that can be used in [statedef -1] with this system.


Counter enemy's projectile with projectile, if possible. (Standing)
[No root var needed]
*"If possible" means, if there is enough time to counter without getting hit by enemy's projectile. Will not trigger, if not possible.
Code:
[State -1, AI projectile against enemy projectile] ;by Inktrebuchet
type = ChangeState
value = 220
triggerall = ailevel 
triggerall = ctrl
triggerall = statetype = S
trigger1 = PlayerIdExist(helper(33333333),var(3)) ;enemy projectile exists
trigger1 = PlayerID(helper(33333333),var(3)), pos y > -100 ; Avoid attempt to counter projectiles that are to high. 100 = char height
trigger1 = PlayerID(helper(33333333),var(3)), vel x != 0 ; Avoid "Division by Zero" debug overflow
;distance / velocity = time >= startup time
trigger1 = (((PlayerID(helper(33333333),var(3)), pos x - pos x )* facing) - const(size.ground.front) - PlayerID(helper(33333333),var(3)),const(size.ground.front)) / (PlayerId(helper(33333333),var(3)),vel x) >= 5 ;5= startup time


Counter enemy's projectile with projectile (last second), if possible
[No root var needed]
*"If possible" means, if there is enough time to counter without getting hit by enemy's projectile. Will not trigger, if not possible.
Code:
[State -1, AI projectile against enemy projectile] ;by Inktrebuchet
type = ChangeState
value = 220
triggerall = ailevel 
triggerall = ctrl
triggerall = statetype = S
trigger1 = PlayerIdExist(helper(33333333),var(3)) ;enemy projectile exists
trigger1 = PlayerID(helper(33333333),var(3)), pos y > -100 || PlayerID(helper(33333333),var(3)), vel y > 0 ; Avoid attempt to counter projectiles that are to high. 100 = char height, unless the enemy projectile is moving downwards.
trigger1 = PlayerID(helper(33333333),var(3)), vel x != 0 ; Avoid "Division by Zero" debug overflow
;distance / velocity = time = startup time + active
trigger1 = (((PlayerID(helper(33333333),var(3)), pos x - pos x )* facing) - const(size.ground.front) - PlayerID(helper(33333333),var(3)),const(size.ground.front)) / (PlayerId(helper(33333333),var(3)),vel x) = [5,22] ; 5 = startup time, 22 = active ; [0,5] for last second


Reflect enemy's projectile, if possible
[No root var needed]
*"If possible" means, if there is enough time to reflect enemy's projectile without getting hit by enemy's projectile. Will not trigger, if not possible.
Code:
[State -1, AI Reflect enemy projectile] ;by Inktrebuchet
type = ChangeState
value = 1200
triggerall = ailevel 
triggerall = ctrl
triggerall = statetype = S
trigger1 = PlayerIdExist(helper(33333333),var(3)) ;enemy projectile exists
trigger1 = PlayerID(helper(33333333),var(3)), pos y > -100 || PlayerID(helper(33333333),var(3)), vel y > 0 ; Avoid attempt to reflect projectiles that are to high. 100 = char height or reflector height, unless the enemy projectile is moving downwards.
trigger1 = PlayerID(helper(33333333),var(3)), vel x != 0 ; Avoid "Division by Zero" debug overflow
;distance / velocity = time = startup time + active
trigger1 = (((PlayerID(helper(33333333),var(3)), pos x - pos x )* facing) - const(size.ground.front) - PlayerID(helper(33333333),var(3)),const(size.ground.front)) / (PlayerId(helper(33333333),var(3)),vel x) = [5,22] ; 5 = startup time, 22 = active ; [0,5] for last second reflect.


Slide under enemy's projectile
[No root var needed]
*This code assumes the character is able to be low enough to avoid the projectile. It would be wise to add a trigger that stops the character's slide attempts, if they are hit when trying to slide. This is because it's not possible to know where the bottom of the projectiles clsn box is until contact. Check the Safeguards section for more info.
Code:
[State -1, AI Slide under enemy projectile] ;by Inktrebuchet
type = ChangeState
value = 1100
triggerall = ailevel 
triggerall = ctrl
triggerall = statetype = S || statetype = C
trigger1 = PlayerIdExist(helper(33333333),var(3)) ;enemy projectile exists
trigger1 = PlayerID(helper(33333333),var(3)), pos y > -100 ; Avoid sliding under projectiles that are high enough to walk under. 100 = char height
trigger1 = PlayerID(helper(33333333),var(3)), vel x != 0 ; Avoid "Division by Zero" debug overflow
trigger1 = ((PlayerID(helper(33333333),var(3)), pos x - pos x )* facing) / (PlayerId(helper(33333333),var(3)), vel x) > 9 ; 9 = lowest point of moves hitbox .
trigger1 = ((PlayerID(helper(33333333),var(3)), pos x - pos x )* facing) / (PlayerId(helper(33333333),var(3)), vel x) < 35 ; 35 = when hitboxs lowest point changes to a higher point.


Hop backwards to avoid enemy's projectile, if possible.
[No root var needed]
*"If possible" means, if there is enough time to land the hop without getting hit by enemy's projectile.  Will not trigger, if not possible.
Code:
[State -1, AI Hop backwards to avoid enemy projectile, when possible] ;by Inktrebuchet
type = changestate
Value = 105 ;This value is based on default MUGEN common1.cns "Hop backwards" state.
triggerall = ailevel
triggerall = ctrl
triggerall = statetype = S
trigger1 = PlayerIdExist(helper(33333333),var(3)) ;enemy projectile exists
trigger1 = PlayerID(helper(33333333),var(3)), pos y > -100 || PlayerID(helper(33333333),var(3)), vel y > 0 ; Avoid attempt to reflect projectiles that are to high. 100 = char height or reflector height, unless the enemy projectile is moving downwards.
trigger1 = PlayerID(helper(33333333),var(3)), vel x != 0 ; Avoid "Division by Zero" debug overflow
;(distance / velocity)  =  (hop.y/yaccel) + ((((hop.y^2 - 0^2) / (2 * yaccel)) /yaccel) / hop.x)    ||      time = Max height time + ((max height / yaccel ) / hop.x)
;trigger1 = ceil((((PlayerID(helper(33333333),var(3)), pos x - pos x )* facing) - const(size.ground.front) - PlayerID(helper(33333333),var(3)),const(size.ground.front)) / (PlayerId(helper(33333333),var(3)),vel x)) = floor(((abs(const(velocity.run.back.y)) / const(movement.yaccel)) + ((abs(const(velocity.run.back.y))**2 - 0**2) / (2*const(movement.yaccel)) / const(movement.yaccel))) / abs(const(velocity.run.back.x)))
;alternative to above trigger.
trigger1 = ceil((((PlayerID(helper(33333333),var(3)), pos x - pos x )* facing) - const(size.ground.front) - PlayerID(helper(33333333),var(3)),const(size.ground.front)) / (PlayerId(helper(33333333),var(3)),vel x)) = [0,16] ; 16 = the time it takes to start and land the hop.


Neu jump over enemy's projectile
[No root var needed], [No editing needed]
*This code assumes the character is able to jump high enough to avoid the projectile. It would be wise to add a trigger that stops the character's jump attempts, if they are hit when trying to jump.  This is because it's not possible to know where the top of the projectiles clsn box is until contact. Check the Safeguards section for more info.
Code:
[State -1, AI Neu jump over enemy projectile] ;by Inktrebuchet
type = ChangeState
value = 40 ;This value is based on default MUGEN common1.cns "Jump Start" state.
triggerall = ailevel
triggerall = ctrl
triggerall = stateno != 40
triggerall = statetype = S || statetype = C
trigger1 = PlayerIDExist(helper(33333333),var(3)) ; enemy projectile exist?
trigger1 = PlayerID(helper(33333333),var(3)), pos y > -100 ; Avoid jumping over projectiles that are to high. 100 = char height
trigger1 = PlayerID(helper(33333333),var(3)), vel x != 0 ; Avoid "Division by Zero" debug overflow.
;distance/speed = time
trigger1 = ceil(((PlayerID(helper(33333333),var(3)), pos x - pos x )* facing) / PlayerID(helper(33333333),var(3)), vel x ) = floor(abs(const(velocity.jump.y)) / const(movement.yaccel))


Fwd jump over enemy's projectile
[No root var needed], [No editing needed]
*This code assumes the character is able to jump high enough to avoid the projectile. It would be wise to add a trigger that stops the character's jump attempts, if they are hit when trying to jump.  This is because it's not possible to know where the top of the projectiles clsn box is until contact. Check the Safeguards section for more info.
*This code assumes the character uses sysvar(1) in [statedef 40](jump). This is what's used in default MUGEN's common1.cns for "holdfwd".
Code:
[State -1, AI fwd jump over enemy projectile part 1 of 4] ;by Inktrebuchet
type = explod
triggerall = ailevel
triggerall = ctrl
triggerall = stateno != [40,52] ; not already jumping
triggerall = statetype = S || statetype = C
triggerall = numexplod(33330001) = 0
trigger1 = PlayerIdExist(helper(33333333),var(3)) ;enemy projectile exists
trigger1 = PlayerID(helper(33333333),var(3)), pos y > -100 ; Avoid jumping over projectiles that are to high. 100 = char height
trigger1 = PlayerID(helper(33333333),var(3)), vel x != 0 ; Avoid "Division by Zero" debug overflow.
;distance / vel x = ((time) * vel x) / vel x
trigger1 = ceil(((PlayerID(helper(33333333),var(3)), pos x - pos x )* facing) / PlayerID(helper(33333333),var(3)), vel x ) = floor(abs(const(velocity.jump.y)) / const(movement.yaccel))
anim = helper(33333333), anim ; blank anim
ID = 33330001

[State -1, AI fwd jump over enemy projectile part 2 of 4]
type = varset
trigger1 = numexplod(33330001) = 1
sysvar(1) = 1

[State -1, AI fwd jump over enemy projectile part 3 of 4]
type = ChangeState
value = 40 ;This value is based on default MUGEN common1.cns "Jump Start" state.
triggerall = ctrl
triggerall = stateno != [40,52] ; not already jumping
triggerall = statetype = S || statetype = C
trigger1 = numexplod(33330001) = 1
trigger1 = sysvar(1) = 1 ; holding fwd

[State -1, AI fwd jump over enemy projectile part 4 of 4]
type = removeexplod
triggerall = numexplod(33330001) = 1
trigger1 = prevstateno = 40
trigger2 = movetype = H
ID = 33330001
ignorehitpause = 1



Safeguards "a measure taken to protect someone or something or to prevent something undesirable."

Safeguard code is used to ensure a move that resulted in being hit by the enemy projectile isn't used in response to that same projectile again.

Safeguard Example 1 1.0+ ONLY
[No root var needed]
This should go at the end of [statedef 33333333].
*This code uses 2 var in [statedef 33333333] if added. no editing needed here.
*be sure to update [statedef 33333333]'s "helper var usage" section if used! var(20) & var(21)

Code:
[state safeguard 0] ;similar to prevprevstateno ;by Inktrebuchet
type = null
trigger1 = root, movetype != h
trigger1 = var(21) := root,stateno

[state safeguard 1] ;safeguard, saves move number and enemy projectile vel x. ;by Inktrebuchet
type = explod
trigger1 = var(21) != 0 ;similar to prevprevstateno != 0
trigger1 = PlayerIDExist(var(3))
trigger1 = cond(playerid(var(3)),prevstateno = 0, var(2) := abs(floor(playerid(var(3)),vel x)), 1)
trigger1 = playerid(var(3)),Cond(NumTarget, Target, Cond(1, ID, 0), 0) = root,ID ; enemy,proj,target,ID = ID
trigger1 = numexplod((var(20)*100000000) + var(2)) = 0
anim = anim ;This anim is blank as long as this stctrl is in "AI Detect Projectile System"
ID = (var(20)*100000000) + var(2)
removetime = -1

[state safeguard 2] ;safeguard, saves move number and enemy projectile stateno. ;by Inktrebuchet
type = explod
trigger1 = var(21) != 0 ;similar to prevprevstateno != 0
trigger1 = PlayerIDExist(var(3))
trigger1 = playerid(var(3)),Cond(NumTarget, Target, Cond(1, ID, 0), 0) = root,ID ; enemy,proj,target,ID = ID
trigger1 = numexplod((var(20)*100000000) + playerid(var(3)),prevstateno) = 0
anim = anim ;This anim is blank as long as this stctrl is in "AI Detect Projectile System"
ID = (var(20)*100000000) + playerid(var(3)),prevstateno
removetime = -1

This can be added to the triggers used in [statedef -1].
*the first trigger should be edited for each move that it's added to. notes added to the first trigger.
Code:
;safeguard
trigger1 = cond(numhelper(33333333),helper(33333333), cond(1, var(20) := 15, 0), 0) ; the 15 in "var(20) := 15" represents the 15th time this trigger was used. the number should be different everytime this is added/used.
trigger1 = cond(helper(33333333),numexplod((helper(33333333),var(20)*100000000)+PlayerID(helper(33333333),var(3)),stateno) = 0, 1, helper(33333333),numexplod((helper(33333333),var(20)*100000000)+abs(floor(PlayerID(helper(33333333),var(3)),vel x))) = 0)




Snippets


Enemy,Proj,P2Dist X Alternative
Code:
;Enemy,Proj,P2Dist X:
;ProjDist X:
((PlayerID(helper(33333333),var(3)), pos x - pos x )* facing)
;this is an alternative to using PlayerID(helper(33333333),var(3)),P2Dist X.

Enemy,Proj,P2BodyDist X Alternative
Code:
;Enemy,Proj,P2BodyDist X:
;ProjBodyDist X:
(((PlayerID(helper(33333333),var(3)), pos x - pos x )* facing) - const(size.ground.front) - PlayerID(helper(33333333),var(3)),const(size.ground.front))
;this is an alternative to using PlayerID(helper(33333333),var(3)),P2BodyDist X.

Enemy,Projectile Made Contact With You. 1.0+ ONLY
Code:
;enemy,projectile made contact with you, not your partner or anyone else.
trigger1 = playerid(helper(33333333),var(3)),Cond(NumTarget, Target, Cond(1, ID, 0), 0) = ID ; enemy,proj,target,ID = ID
;This is accurate with partners as well.

Enemy,Projectile Hit You. 1.0+ ONLY
Code:
;enemy,projectile hit you, not your partner or anyone else.
trigger1 = playerid(helper(33333333),var(3)),Cond(NumTarget, Target, Cond(1, ID, 0), 0) = ID ; enemy,proj,target,ID = ID
trigger1 = playerid(helper(33333333),var(3)),movehit
;This is accurate with partners as well.
Last Edit: August 01, 2022, 07:54:09 pm by inktrebuchet
Re: AI Detect Enemy's (Helper) Projectile System
#3  May 31, 2017, 08:13:15 pm
  • avatar
  • *****
  • Sr. Black Person
  • Mess with the chuchu you get the pewpew
    • USA
    • Kamekaze.world
Yeah the main issue is clsns. I never bothered with in depth projectile detection because outside of full games there's too many variables involved. Solid idea though.
Want to feel useful for a useless show? click here
119/150 Chars, I'm not dead yet....the true surprise is in my thread.
Hahahah fuck you photobucket.
Re: AI Detect Enemy's (Helper) Projectile System
#4  June 01, 2017, 09:41:39 pm
  • ****
    • USA
    • twitter.com/inktrebuchet
Yeah, pretty much. I was building a projectile reflector system based off this code, now that all of that helpers data is easily accessed but then realized how broken it would actually be. The only realistic application this one has outside of a full game is knowing when a projectile is coming at the AI and what its speed and distance from the AI is.



Last Edit: June 15, 2017, 04:31:27 pm by ink
Re: AI Detect Enemy's (Helper) Projectile System
#5  June 12, 2017, 04:23:24 pm
  • ****
    • USA
    • twitter.com/inktrebuchet
Updated this today, fixed a small bug that would break everything for some characters when a intro was skipped.
Please let me know if you find anything weird or have questions.

     Posted: June 15, 2017, 04:32:46 pm
Updated again with a condensed version of the code.
Re: AI Detect Enemy's (Helper) Projectile System
#6  June 19, 2018, 03:52:21 am
  • **
  • Sr. Símio Enfermo
    • Brazil
    • www.facebook.com/people/Manson-Rees/100027897993934
Sorry for the bump, but that is to a good cause  ;D
I want to share a C O N D E N S E D version of this awesome code made by Ink.

To accomplish this result I had to use two more variables and some Phantom States techniques to make iterations be possible(and some ridiculous tricks eheh).
Well, here is the code (some explanations in spoiler):

Spoiler, click to toggle visibilty

This goes to State -3:
Code:
[state -3, AI Detect Projectile System]
type = Helper
trigger1 = !NumHelper(33333333)
name = "AI Detect Projectile System"
ID =33333333
stateno = 33333333
postype = p1
ownpal = 1
keyctrl = 0
supermovetime = 2147483647
pausemovetime = 2147483647
ignorehitpause = 1

Code:
[Statedef 33333333]
type = A
movetype = I
physics = N
anim = 9741 ; blank
velset = 0, 0&(var(58):=var(58)+1)
ctrl = 0&(var(0):=Cond(parent,var(48)>0,parent,var(48),58))
 
[state 33333333, clip board] ; AI Common System Helper
type = DisplayToClipboard
trigger1 = 1
text = " Highest Playerid + 1 = %d , Projectile helper's PlayerId = %d"
params = var(0), var(3)
 
[state 33333333, 1] ;keeps track of player ids
type = varadd
trigger1 = PlayerIdExist(var(0)+var(58))
var(0) = 1
 
[state 33333333, 15] ;
type = varset
trigger1 = PlayerIdExist(var(0)-var(59))
trigger1 = cond(root,teamside = 1, PlayerID(var(0)-var(59)),teamside = 2, PlayerID(var(0)-var(59)),teamside = 1)
trigger1 = PlayerID(var(0)-var(59)),hitdefattr = ASC, NP, SP, HP
var(3) = (var(0)-var(59)) ;projectiles ID
 
[state 33333333, 0] ; needed to use past round 1!
type = ParentVarSet
trigger1 = 1
var(48) =  var(0)
 
[State 33333333, 7]
type = ChangeState
trigger1 = 1
value = 33333333+(var(58)=25)
 
;---------------------------------------------------------------------------------
[Statedef 33333334]
type = A
movetype = I
physics = N
velset = 0&(var(59):=var(59)+1), 0&(var(58):=0)
ctrl = 0&(var(59):=var(59)*(var(59)<=10))
 
[State 33333334, BindToRoot]
type = BindToRoot
trigger1 =1
time = 1
facing = 1
pos =0,-2
persistent =1
 
[State 33333334, 7]
type = ChangeState
trigger1 = Time
value = 33333333
Last Edit: June 25, 2018, 10:53:43 pm by Manson Rees
Re: AI Detect Enemy's (Helper) Projectile System
#7  June 25, 2018, 05:01:08 pm
  • ****
    • USA
    • twitter.com/inktrebuchet
@Manson Rees: I've come across something weird with your version. For some reason it does not detect projectiles from certain characters, one you could check it against is P.o.T.S.'s Shin Gouki. I looked into this a little but your version's a little more complicated to read, I'll try again when I have more free time. I bet it's from a new playerid spawning before the projectiles playerid is saved, possibly from the 1 tick state change.

Also, I strongly suggest keeping the helperID and state number (33333333) and your var(1) to var(3). This would help keep these two versions compatible if people decide to switch one out to the other. Also, the idea is for this piece of code to be easily copy and pasted to any character with very little effort, which is why (33333333) was chosen. Chances are that's not already being used in any characters, where there is a chance (10000) is being used.

Ink changed to Inktrebuchet in the credits would be appreciated too, if you find a fix.



-edit-
Tried to reapply your code to a different kfm and found another problem. It looks like you updated your code from the one I originally tested.

changing this from the original:
Code:
ctrl = 0&(Cond(parent,var(48)=0,var(0):=58,Cond(parent,var(48)>0,var(0):=parent,var(48),0)))
to this:
Code:
ctrl = 0&(var(48):=Cond(parent,var(48)>0,parent,var(48),58))
has made it not count the playerids at all.

 
Last Edit: June 25, 2018, 08:12:15 pm by ink
Re: AI Detect Enemy's (Helper) Projectile System
#8  June 25, 2018, 10:49:17 pm
  • **
  • Sr. Símio Enfermo
    • Brazil
    • www.facebook.com/people/Manson-Rees/100027897993934
@Manson Rees: I've come across something weird with your version. For some reason it does not detect projectiles from certain characters, one you could check it against is P.o.T.S.'s Shin Gouki. I looked into this a little but your version's a little more complicated to read, I'll try again when I have more free time. I bet it's from a new playerid spawning before the projectiles playerid is saved, possibly from the 1 tick state change.
Fixed.
Just replacing this line:
Code:
velset = 0&(var(59):=var(59)+(!var(59))), 0&(var(58):=var(58)+(PrevStateNo=[10000,10001]))
by that:
Code:
velset = 0, 0&(var(58):=var(58)+1)

In some cases, var(0) isn't actually equals to highest playerID + 1, because var(59) was incrementing before it really needed.

Also, I strongly suggest keeping the helperID and state number (33333333) and your var(1) to var(3). This would help keep these two versions compatible if people decide to switch one out to the other. Also, the idea is for this piece of code to be easily copy and pasted to any character with very little effort, which is why (33333333) was chosen. Chances are that's not already being used in any characters, where there is a chance (10000) is being used.
Yeah, you have a point.
Fixed!

Ink changed to Inktrebuchet in the credits would be appreciated too, if you find a fix.
Of course!

-edit-
Tried to reapply your code to a different kfm and found another problem. It looks like you updated your code from the one I originally tested.

changing this from the original:
Code:
ctrl = 0&(Cond(parent,var(48)=0,var(0):=58,Cond(parent,var(48)>0,var(0):=parent,var(48),0)))
to this:
Code:
ctrl = 0&(var(48):=Cond(parent,var(48)>0,parent,var(48),58))
has made it not count the playerids at all.
Well, the second code I set the wrong var... Because var(0) is the correct one. XD
Fixed.


Instead posting new code in this post, I'll just edit the previous one.
Thanks for your feedback, it is really appreciated. :)
Re: AI Detect Enemy's (Helper) Projectile System
#9  October 07, 2018, 09:47:25 pm
  • ****
    • USA
    • twitter.com/inktrebuchet
Last Edit: October 10, 2018, 05:57:28 pm by ink
Re: AI Detect Enemy's (Helper) Projectile System
#10  October 10, 2018, 05:57:40 pm
  • ****
    • USA
    • twitter.com/inktrebuchet
Updated this system with a config section to simplify installment.
Last Edit: November 19, 2018, 10:01:22 pm by ink
Re: AI Detect Enemy's (Helper) Projectile System
#11  November 19, 2018, 10:03:06 pm
  • ****
    • USA
    • twitter.com/inktrebuchet
Updated this system. No root,var is need now, which means no messing with IntPersistIndex either!

Small config section still included for blank animation.
Last Edit: February 20, 2019, 04:10:17 pm by ink
Re: AI Detect Enemy's (Helper) Projectile System
#12  February 20, 2019, 04:14:19 pm
  • ****
    • USA
    • twitter.com/inktrebuchet
I've updated the second post with codes that can be used in statedef -1. All have been updated to avoid debug overflows that would happen with some projectiles and some new ones added.

      Posted: February 21, 2019, 09:29:36 pm
Updated codes in second post. "p2bodydist x" has been replaced to allow code to work with partners.
Last Edit: February 23, 2019, 12:00:49 am by ink
Re: AI Detect Enemy's (Helper) Projectile System
#13  March 19, 2019, 12:26:05 am
  • ****
    • USA
    • twitter.com/inktrebuchet
Snippets and Safeguard sections added to second post!

Last Edit: March 27, 2019, 04:03:23 am by ink
Re: AI Detect Enemy's (Helper) Projectile System
#14  April 02, 2019, 04:59:35 am
  • ****
    • USA
    • twitter.com/inktrebuchet
Updated the first post with a new version of "AI Detect Projectile System". This version is much faster and more simple, thanks to a loop I learned from Vans.

As always, everything is still compatible with previous versions.


Recalled that version and put the last one back up. The recalled version was not able to keep up with in some rare instances.

      Posted: April 28, 2019, 04:08:52 am
Small update to make this code compatible with all versions of MUGEN!





Last Edit: August 17, 2020, 02:15:38 am by inktrebuchet
Re: AI Detect Enemy's (Helper) Projectile System
#15  June 24, 2022, 04:27:49 pm
  • **
This is actually more useful than you'd think. From testing though, a helper projectile with the projectile sctrl instead of the normal hitdef sctrl doesn't return a value for var(3) thereby making it go undetected.  It could be sort of factored into the triggers though not sure what the best way would be for mugen.
Something like;
trigger1 = (PlayerID(var(0)-1),HitDefAttr=ASC,NP,SP,HP) || (PlayerID(var(0)-1),MoveType=A && Enemy,NumProj>0)
seems to work fine 1v1 but not sure how effective it is in simultaneous mode with projectiles flying around all over the place.

In Ikemem Go, something like; Enemy,NumProj>0 could be replaced with PlayerID(var(0)-1),NumProj>0) which would solve the problem but this doesn't work with mugen 1.1. *Havent tested for any version below that.
Re: AI Detect Enemy's (Helper) Projectile System
#16  June 30, 2022, 05:02:29 pm
  • ****
    • USA
    • twitter.com/inktrebuchet
Unfortunately, that is true. I did put together a separate detection system that will work for projectile sctrl. http://mugenguild.com/forum/msg.2419897

The trigger you posted won't work reliable because people us helpers for attacks on other things besides projectiles and projectile sctrl is used for thing outside of projectiles so that could trigger at times that you wouldn't want it to. Also projectiles sctrl is always owned by the root, even if its called by a helper so the playerid redirect won't work since it points at a helper.

The best case for a projectile in my opinion, is to have the helper use its own hitdef but also call a projectile sctrl with a blank animation, using the helpers  x and y and removing it every tick, no vel needed. This way AI without these systems can still check for a projectile and AI using this system can also check for a projectile easily.


Last Edit: July 05, 2022, 04:02:07 pm by inktrebuchet
Re: AI Detect Enemy's (Helper) Projectile System
#17  June 19, 2023, 09:44:45 pm
  • avatar
    • Egypt
where do you put the state -3?
Re: AI Detect Enemy's (Helper) Projectile System
#18  June 20, 2023, 04:37:39 am
  • ****
    • USA
    • twitter.com/inktrebuchet
you can paste [state -3, AI Detect Projectile System] anywhere in statedef -3