Cornerpush

From mugen-net
Jump to navigation Jump to search

Cornerpush refers to the pushback that happens when a character is pushed up against the wall after a hit, typically in the corner. The purpose of cornerpush is to prevent infinite combos in the corner by ensuring that the exact same distance is applied on hit in the corner as it would be anywhere else on the screen[1].

Cornerpush in M.U.G.E.N[edit]

M.U.G.E.N, out of the box, provides no suitable implementation for cornerpush. The way it behaves in M.U.G.E.N is unlike any commercial fighter because setting the same velocity as a hit does not result in the same distance as a regular hit. For this reason, it is recommended to use a custom cornerpush system such as the one by Vans.

Overriding M.U.G.E.N's Implementation[edit]

The first step in implementing a custom cornerpush system involves setting all cornerpush parameters in all hitdefs to 0. Next, a formula is applied to a series of PosAdds based on the actual hit velocity when the opponent is against the edge of the screen. PosAdd is used because it can be applied at the same time as a regular velocity (two VelSets, VelAdds, VelMuls, or any combination of the three cannot be active at the same time).

A typical implementation of Vans's cornerpush system looks as follows:

;===============================================================================
; ------- Cornerpush System by Vans --------
;===============================================================================
[State -2, Kill Cornerpush]
type = VarSet
trigger1 = StateNo = 3110 && AnimElem = 5
fvar(39) = 0

[State -2, Reset Time counter]
type = VarSet
trigger1 = MoveContact = 1
var(56) = 0

[State -2, Accel]
type = VarSet
triggerall = RoundState = 2
triggerall = numTarget
triggerall = Target, HitShakeOver
trigger1 = StateNo != 970 && StateNo != 975 && StateNo != 3000 && StateNo != 3100 && StateNo != 3200 ; Cornerpush should not be applied
trigger2 = (StateNo = [3000,3200]) && !Var(48)                                                       ; during superpause.
fvar(39) = (Target,GetHitVar(XVel)*exp((-0.1886)*((Var(56)))))

[State -2, Push]
type = PosAdd
triggerall = RoundState = 2
triggerall = numtarget >= 1
triggerall = (Target, BackEdgeBodyDist <= 0) || (Target, FrontEdgeBodyDist <= 0)
triggerall = cond(numHelper(1000), (helper(1000), MoveContact = 0), 1) ; Do not apply if a projectile just made contact
triggerall = P2StateType != A
triggerall = StateNo != [800,839]
triggerall = StateNo != [102,106]
triggerall = P2StateType != A
triggerall = StateType != A                                            ; Do not apply for air attacks (may change based on system requirements)
trigger1 = StateNo != 970 && StateNo != 975 && StateNo != 3000 && StateNo != 3100 && StateNo != 3200
trigger2 = (StateNo = [3000,3200]) && !Var(48)
x = ifelse(facing = -1,FVar(39),-FVar(39))

[State -2, Increase]
type = VarSet
triggerall = numtarget ;>= 1
triggerall = target, HitShakeOver
triggerall = Var(56)
trigger1 = !Var(48)
var(56) = Var(56)+1

[State -2, Time counter]
type = VarSet
trigger1 = !Var(56)
trigger1 = FVar(39)
var(56) = 1

[State -2, Freeze Pos During Superpause]
type = PosFreeze
trigger1 = Var(48)
value = 1

[State -2, Drop]
type = VarSet
triggerall = FVar(39)
trigger1 = !numTarget
trigger2 = numHelper(1000)
trigger2 = Helper(1000), MoveContact = 1 ; Kill cornerpush if a projectile just made contact
fvar(39) = 0

In this implementation, Var(48) is a timer that is set for the time of the super pause at the time the super pause is applied.