Skip to content

Commit

Permalink
Merge pull request #1316 from Lazin3ss/development
Browse files Browse the repository at this point in the history
fix: make ModifyExplod updating more like MUGEN
  • Loading branch information
K4thos committed Jul 10, 2023
2 parents 22a9004 + 87fd009 commit d846d13
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 110 deletions.
97 changes: 61 additions & 36 deletions src/bytecode.go
Original file line number Diff line number Diff line change
Expand Up @@ -3610,10 +3610,8 @@ func (sc explod) Run(c *Char, _ []int32) bool {
}
case explod_space:
e.space = Space(exp[0].evalI(c))
e.reset()
case explod_postype:
e.postype = PosType(exp[0].evalI(c))
e.reset()
case explod_velocity:
e.velocity[0] = exp[0].evalF(c) * lclscround
if len(exp) > 1 {
Expand Down Expand Up @@ -3742,8 +3740,9 @@ func (sc modifyExplod) Run(c *Char, _ []int32) bool {
eid := int32(-1)
var expls []*Explod
rp := [...]int32{-1, 0}
sp := Space_none
remap := false
var f, vf float32 = 1, 1
sp, pos, vel, accel := Space_none, [2]float32{0, 0}, [2]float32{0, 0}, [2]float32{0, 0}
eachExpl := func(f func(e *Explod)) {
for _, e := range expls {
f(e)
Expand Down Expand Up @@ -3781,64 +3780,90 @@ func (sc modifyExplod) Run(c *Char, _ []int32) bool {
switch id {
case explod_facing:
if exp[0].evalI(c) < 0 {
eachExpl(func(e *Explod) { e.relativef = -1 })
} else {
eachExpl(func(e *Explod) { e.relativef = 1 })
f = -1
}
if c.stCgi().ikemenver[0] > 0 || c.stCgi().ikemenver[1] > 0 {
eachExpl(func(e *Explod) {
e.relativef = f
})
}
case explod_vfacing:
if exp[0].evalI(c) < 0 {
eachExpl(func(e *Explod) { e.vfacing = -1 })
} else {
eachExpl(func(e *Explod) { e.vfacing = 1 })
vf = -1
}
if c.stCgi().ikemenver[0] > 0 || c.stCgi().ikemenver[1] > 0 {
eachExpl(func(e *Explod) {
e.vfacing = vf
})
}
case explod_pos:
x := exp[0].evalF(c) * lclscround
eachExpl(func(e *Explod) { e.relativePos[0] = x })
pos[0] = exp[0].evalF(c) * lclscround
if c.stCgi().ikemenver[0] > 0 || c.stCgi().ikemenver[1] > 0 {
eachExpl(func(e *Explod) { e.relativePos[0] = pos[0] })
}
if len(exp) > 1 {
y := exp[1].evalF(c) * lclscround
eachExpl(func(e *Explod) { e.relativePos[1] = y })
pos[1] = exp[1].evalF(c) * lclscround
if c.stCgi().ikemenver[0] > 0 || c.stCgi().ikemenver[1] > 0 {
eachExpl(func(e *Explod) { e.relativePos[1] = pos[1] })
}
}
case explod_random:
rndx := (exp[0].evalF(c) / 2) * lclscround
rndx = RandF(-rndx, rndx)
eachExpl(func(e *Explod) { e.relativePos[0] += rndx })
pos[0] += rndx
if c.stCgi().ikemenver[0] > 0 || c.stCgi().ikemenver[1] > 0 {
eachExpl(func(e *Explod) { e.relativePos[0] += rndx })
}
if len(exp) > 1 {
rndy := (exp[1].evalF(c) / 2) * lclscround
rndy = RandF(-rndy, rndy)
eachExpl(func(e *Explod) { e.relativePos[1] += rndy })
pos[1] += rndy
if c.stCgi().ikemenver[0] > 0 || c.stCgi().ikemenver[1] > 0 {
eachExpl(func(e *Explod) { e.relativePos[1] += rndy })
}
}
case explod_velocity:
vel[0] = exp[0].evalF(c) * lclscround
if c.stCgi().ikemenver[0] > 0 || c.stCgi().ikemenver[1] > 0 {
eachExpl(func(e *Explod) { e.velocity[0] = vel[0] })
}
if len(exp) > 1 {
vel[1] = exp[1].evalF(c) * lclscround
if c.stCgi().ikemenver[0] > 0 || c.stCgi().ikemenver[1] > 0 {
eachExpl(func(e *Explod) { e.velocity[1] = vel[1] })
}
}
case explod_accel:
accel[0] = exp[0].evalF(c) * lclscround
if c.stCgi().ikemenver[0] > 0 || c.stCgi().ikemenver[1] > 0 {
eachExpl(func(e *Explod) { e.accel[0] = accel[0] })
}
if len(exp) > 1 {
accel[1] = exp[1].evalF(c) * lclscround
if c.stCgi().ikemenver[0] > 0 || c.stCgi().ikemenver[1] > 0 {
eachExpl(func(e *Explod) { e.accel[1] = accel[1] })
}
}
case explod_space:
// Space handling in ModifyExplod has room for some optimization
sp = Space(exp[0].evalI(c))
if c.stCgi().ikemenver[0] > 0 || c.stCgi().ikemenver[1] > 0 {
eachExpl(func(e *Explod) { e.space = sp })
sp = Space_none
}
case explod_postype:
pt := PosType(exp[0].evalI(c))
eachExpl(func(e *Explod) {
if sp != Space_none {
e.space = sp
}
e.postype = pt
e.reset()
e.postype = pt
// Non-ikemen characters update certain values only when postype is declared
if c.stCgi().ikemenver[0] == 0 && c.stCgi().ikemenver[1] == 0 {
e.relativef, e.vfacing = f, vf
e.relativePos, e.velocity, e.accel = pos, vel, accel
if sp != Space_none {
e.space = sp
}
}
e.setPos(crun)
// e.relativef = 1 // In Mugen facing is updated by default
})
case explod_velocity:
x := exp[0].evalF(c) * lclscround
eachExpl(func(e *Explod) { e.velocity[0] = x })
if len(exp) > 1 {
y := exp[1].evalF(c) * lclscround
eachExpl(func(e *Explod) { e.velocity[1] = y })
}
case explod_accel:
x := exp[0].evalF(c) * lclscround
eachExpl(func(e *Explod) { e.accel[0] = x })
if len(exp) > 1 {
y := exp[1].evalF(c) * lclscround
eachExpl(func(e *Explod) { e.accel[1] = y })
}
case explod_scale:
x := exp[0].evalF(c)
eachExpl(func(e *Explod) { e.scale[0] = x })
Expand Down
137 changes: 75 additions & 62 deletions src/char.go
Original file line number Diff line number Diff line change
Expand Up @@ -990,7 +990,7 @@ type Explod struct {
pos [2]float32
relativePos [2]float32
offset [2]float32
relativef int32
relativef float32
facing float32
vfacing float32
scale [2]float32
Expand Down Expand Up @@ -1020,6 +1020,7 @@ type Explod struct {
palfx *PalFX
palfxdef PalFXDef
window [4]float32
lockSpriteFacing bool
localscl float32
}

Expand All @@ -1031,9 +1032,11 @@ func (e *Explod) clear() {
alpha: [...]int32{-1, 0}, playerId: -1, bindId: -2, ignorehitpause: true}
}
func (e *Explod) reset() {
e.facing = 1
e.offset[0], e.offset[1] = 0, 0
e.setX(e.offset[0])
e.setY(e.offset[1])
e.relativePos[0], e.relativePos[1] = 0, 0
e.velocity[0], e.velocity[1] = 0, 0
e.accel[0], e.accel[1] = 0, 0
e.bindId = -2
Expand All @@ -1053,36 +1056,33 @@ func (e *Explod) setBind(bId int32) {
}
e.bindId = bId
}

// Initial pos setting based on postype and space. This function probably needs a heavy refactor.
func (e *Explod) setPos(c *Char) {
pPos := func(c *Char) {
e.bindId, e.facing = c.id, c.facing*float32(e.relativef)
e.bindId, e.facing = c.id, c.facing
e.relativePos[0] *= c.facing
if e.space == Space_screen {
e.offset[0] = e.relativePos[0] + c.pos[0]*c.localscl/e.localscl + c.offsetX()*c.localscl/e.localscl
e.offset[1] = e.relativePos[1] + sys.cam.GroundLevel()*e.localscl +
e.offset[0] = c.pos[0]*c.localscl/e.localscl + c.offsetX()*c.localscl/e.localscl
e.offset[1] = sys.cam.GroundLevel()*e.localscl +
c.pos[1]*c.localscl/e.localscl + c.offsetY()*c.localscl/e.localscl
} else {
e.setX(c.pos[0]*c.localscl/e.localscl + c.offsetX()*c.localscl/e.localscl + e.relativePos[0])
e.setY(c.pos[1]*c.localscl/e.localscl + c.offsetY()*c.localscl/e.localscl + e.relativePos[1])
e.setX(c.pos[0]*c.localscl/e.localscl + c.offsetX()*c.localscl/e.localscl)
e.setY(c.pos[1]*c.localscl/e.localscl + c.offsetY()*c.localscl/e.localscl)
}
}
lPos := func() {
if e.space == Space_screen {
e.offset[0] = e.relativePos[0] - float32(sys.gameWidth)/e.localscl/2
e.offset[0] = -(float32(sys.gameWidth)/e.localscl/2)
} else {
e.offset[0] = e.relativePos[0]/sys.cam.Scale + sys.cam.ScreenPos[0]/e.localscl
e.offset[0] = sys.cam.ScreenPos[0]/e.localscl
}
e.offset[1] = e.relativePos[1]
}
rPos := func() {
if e.space == Space_screen {
e.offset[0] = e.relativePos[0] + float32(sys.gameWidth)/e.localscl/2
e.offset[0] = float32(sys.gameWidth)/e.localscl/2
} else {
e.offset[0] = (e.relativePos[0]+float32(sys.gameWidth))/sys.cam.Scale + sys.cam.ScreenPos[0]/e.localscl
e.offset[0] = sys.cam.ScreenPos[0]/e.localscl
}
e.offset[1] = e.relativePos[1]
}
// Set space based on postype in case it's missing
if e.space == Space_none {
Expand All @@ -1094,48 +1094,52 @@ func (e *Explod) setPos(c *Char) {
}
}
switch e.postype {
case PT_P1:
pPos(c)
case PT_P2:
if p2 := sys.charList.enemyNear(c, 0, true, true, false); p2 != nil {
pPos(p2)
}
case PT_Front, PT_Back:
e.facing = c.facing * float32(e.relativef)
// front と back はバインドの都合で left か right になおす
// "Due to binding constraints, adjust the front and back to either left or right."
if c.facing > 0 && e.postype == PT_Front || c.facing < 0 && e.postype == PT_Back {
case PT_P1:
pPos(c)
case PT_P2:
if p2 := sys.charList.enemyNear(c, 0, true, true, false); p2 != nil {
pPos(p2)
}
case PT_Front, PT_Back:
if e.postype == PT_Back {
e.relativePos[0] *= -1
e.facing = c.facing
}
e.postype = PT_Right
rPos()
} else {
// explod の postype = front はキャラの向きで pos が反転しない
// "The postype "front" of "explod" does not invert the pos based on the character's orientation"
//if e.postype == PT_Front && c.gi().ver[0] != 1 {
// 旧バージョンだと front は キャラの向きが facing に反映されない
// 1.1でも反映されてない模様
// "In the previous version, "front" does not reflect the character's orientation in facing."
// "It appears that it is still not reflected even in version 1.1."
e.facing = float32(e.relativef)
//}
e.postype = PT_Left
// front と back はバインドの都合で left か right になおす
// "Due to binding constraints, adjust the front and back to either left or right."
if c.facing > 0 && e.postype == PT_Front || c.facing < 0 && e.postype == PT_Back {
if e.postype == PT_Back {
e.relativePos[0] *= -1
}
e.postype = PT_Right
rPos()
} else {
// explod の postype = front はキャラの向きで pos が反転しない
// "The postype "front" of "explod" does not invert the pos based on the character's orientation"
//if e.postype == PT_Front && c.gi().ver[0] != 1 {
// 旧バージョンだと front は キャラの向きが facing に反映されない
// 1.1でも反映されてない模様
// "In the previous version, "front" does not reflect the character's orientation in facing."
// "It appears that it is still not reflected even in version 1.1."
// e.facing = e.relativef
//}
e.postype = PT_Left
lPos()
}
case PT_Left:
lPos()
}
case PT_Left:
e.facing = float32(e.relativef)
lPos()
case PT_Right:
e.facing = float32(e.relativef)
rPos()
case PT_None:
e.facing = float32(e.relativef)
e.offset[0] = e.relativePos[0]
e.offset[1] = e.relativePos[1]
if e.space == Space_screen {
e.offset[0] -= float32(sys.gameWidth) / e.localscl / 2
}
case PT_Right:
rPos()
case PT_None:
if e.space == Space_screen {
e.offset[0] = -(float32(sys.gameWidth) / e.localscl / 2)
}
}
// In MUGEN 1.1, there's a bug where, when an explod gets to face left
// The engine will leave the sprite facing to that side indefinitely.
// Ikemen chars aren't affected by this.
if c.stCgi().ikemenver[0] == 0 && c.stCgi().ikemenver[0] == 0 && !e.lockSpriteFacing &&
e.facing*e.relativef < 0 {
e.lockSpriteFacing = true
}
}
func (e *Explod) matchId(eid, pid int32) bool {
Expand Down Expand Up @@ -1192,10 +1196,6 @@ func (e *Explod) update(oldVer bool, playerNo int) {
if c := sys.playerID(e.bindId); c != nil {
e.pos[0] = c.drawPos[0]*c.localscl/e.localscl + c.offsetX()*c.localscl/e.localscl
e.pos[1] = c.drawPos[1]*c.localscl/e.localscl + c.offsetY()*c.localscl/e.localscl
if e.space == Space_stage && e.postype <= PT_P2 {
e.pos[0] += e.relativePos[0]
e.pos[1] += e.relativePos[1]
}
} else {
// Doesn't seem necessary to do this, since MUGEN 1.1 seems to carry bindtime even if
// you change bindId to something that doesn't point to any character
Expand All @@ -1209,6 +1209,19 @@ func (e *Explod) update(oldVer bool, playerNo int) {
(e.newPos[i]-e.oldPos[i])*(1-sys.tickInterpola())
}
}
off := e.relativePos
// Left and right pos types change relative position depending on stage camera zoom and game width
if e.space == Space_stage {
if e.postype == PT_Left {
off[0] = off[0] / sys.cam.Scale
} else if e.postype == PT_Right {
off[0] = (off[0]+float32(sys.gameWidth)) / sys.cam.Scale
}
}
var facing float32 = e.facing*e.relativef
if e.lockSpriteFacing {
facing = -1
}
if sys.tickFrame() && act {
e.anim.UpdateSprite()
}
Expand All @@ -1231,7 +1244,7 @@ func (e *Explod) update(oldVer bool, playerNo int) {
alp[0] = -1
}
rot := e.rot
if (e.facing < 0) != (e.vfacing < 0) {
if (e.facing*e.relativef < 0) != (e.vfacing < 0) {
rot.angle *= -1
rot.yangle *= -1
}
Expand All @@ -1246,11 +1259,11 @@ func (e *Explod) update(oldVer bool, playerNo int) {
fLength = 2048
}
fLength = fLength * e.localscl
var epos = [2]float32{(e.pos[0] + e.offset[0]) * e.localscl, (e.pos[1] + e.offset[1]) * e.localscl}
var ewin = [4]float32{e.window[0] * e.localscl * e.facing, e.window[1] * e.localscl * e.vfacing, e.window[2] * e.localscl * e.facing, e.window[3] * e.localscl * e.vfacing}
sprs.add(&SprData{e.anim, pfx, epos, [...]float32{e.facing * e.scale[0] * e.localscl,
var epos = [2]float32{(e.pos[0]+e.offset[0]+off[0]) * e.localscl, (e.pos[1]+e.offset[1]+off[1]) * e.localscl}
var ewin = [4]float32{e.window[0] * e.localscl * facing, e.window[1] * e.localscl * e.vfacing, e.window[2] * e.localscl * facing, e.window[3] * e.localscl * e.vfacing}
sprs.add(&SprData{e.anim, pfx, epos, [...]float32{facing * e.scale[0] * e.localscl,
e.vfacing * e.scale[1] * e.localscl}, alp, e.sprpriority, rot, [...]float32{1, 1},
e.space == Space_screen, playerNo == sys.superplayer, oldVer, e.facing, 1, int32(e.projection), fLength, ewin},
e.space == Space_screen, playerNo == sys.superplayer, oldVer, facing, 1, int32(e.projection), fLength, ewin},
e.shadow[0]<<16|e.shadow[1]&0xff<<8|e.shadow[0]&0xff, sdwalp, 0, 0)
if sys.tickNextFrame() {

Expand Down Expand Up @@ -1281,7 +1294,7 @@ func (e *Explod) update(oldVer bool, playerNo int) {
e.palfx.step()
}
e.oldPos = e.pos
e.newPos[0] = e.pos[0] + e.velocity[0]*e.facing*float32(e.relativef)
e.newPos[0] = e.pos[0] + e.velocity[0]*e.facing
e.newPos[1] = e.pos[1] + e.velocity[1]
for i := range e.velocity {
e.velocity[i] += e.accel[i]
Expand Down
Loading

0 comments on commit d846d13

Please sign in to comment.