Skip to content

Commit 06aa7dc

Browse files
authored
Merge pull request #3756 from potsmugen/push2
fix: shadows, playerpush, ontop, sound panning, attack/defence triggers
2 parents 87689c8 + 4326cac commit 06aa7dc

7 files changed

Lines changed: 68 additions & 35 deletions

File tree

src/bytecode.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3276,7 +3276,7 @@ func (be BytecodeExp) run_ex(c *Char, i *int, oc *Char) {
32763276
case OC_ex_spriteplayerno:
32773277
sys.bcStack.PushI(int32(c.spritePN) + 1)
32783278
case OC_ex_attack:
3279-
sys.bcStack.PushF(float32(c.gi().attackBase) * c.attackMul[0])
3279+
sys.bcStack.PushF(c.attackTrigger())
32803280
case OC_ex_clsnoverlap:
32813281
c2 := sys.bcStack.Pop().ToI()
32823282
id := sys.bcStack.Pop().ToI()
@@ -3289,7 +3289,7 @@ func (be BytecodeExp) run_ex(c *Char, i *int, oc *Char) {
32893289
case OC_ex_decisiveround:
32903290
sys.bcStack.PushB(sys.decisiveRound[c.playerNo&1])
32913291
case OC_ex_defence:
3292-
sys.bcStack.PushF(float32(c.finalDefense * 100))
3292+
sys.bcStack.PushF(c.defenceTrigger())
32933293
case OC_ex_dizzy:
32943294
sys.bcStack.PushB(c.scf(SCF_dizzy))
32953295
case OC_ex_dizzypoints:
@@ -5068,10 +5068,6 @@ const (
50685068
)
50695069

50705070
func (sc playSnd) Run(c *Char, _ []int32) bool {
5071-
if sys.noSoundFlg {
5072-
return false
5073-
}
5074-
50755071
crun := getRedirectedChar(c, StateControllerBase(sc), playSnd_redirectid, "PlaySnd")
50765072
if crun == nil {
50775073
return false
@@ -12971,10 +12967,6 @@ const (
1297112967
)
1297212968

1297312969
func (sc modifySnd) Run(c *Char, _ []int32) bool {
12974-
if sys.noSoundFlg {
12975-
return false
12976-
}
12977-
1297812970
crun := getRedirectedChar(c, StateControllerBase(sc), modifySnd_redirectid, "ModifySnd")
1297912971
if crun == nil {
1298012972
return false

src/char.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6278,7 +6278,7 @@ func (c *Char) getOwnChannels(chNo int32) (found []*SoundChannel) {
62786278
}
62796279

62806280
func (c *Char) playSound(params *PlaySndParams) {
6281-
if params.group < 0 {
6281+
if params.group < 0 || sys.noCharSoundFlg {
62826282
return
62836283
}
62846284
current_ffx := params.ffx
@@ -8492,6 +8492,29 @@ func (c *Char) targetDrop(excludeid int32, excludechar int32, keepone bool) {
84928492
}
84938493
}
84948494

8495+
// We do the extra steps to prevent the internal multiplication by 100 from exposing garbage float digits
8496+
// https://github.com/ikemen-engine/Ikemen-GO/issues/1386
8497+
func (c *Char) attackTrigger() float32 {
8498+
// Do the multiplication in float64
8499+
base := float64(c.gi().attackBase)
8500+
mul := float64(c.attackMul[0])
8501+
result := base * mul
8502+
8503+
// Snap to a 3-decimal grid to kill the garbage (e.g. 120.000008 -> 120.0)
8504+
// 3 because default attack/defence values have 3 significant digits
8505+
cleaned := math.Round(result*1e3) / 1e3
8506+
8507+
return float32(cleaned)
8508+
}
8509+
8510+
// See attackTrigger()
8511+
func (c *Char) defenceTrigger() float32 {
8512+
def := float64(c.finalDefense)
8513+
result := def * 100
8514+
clean := math.Round(result*1e3) / 1e3
8515+
return float32(clean)
8516+
}
8517+
84958518
// Process raw damage into the value that will actually be used
84968519
// Calculations are done in float64 for the sake of precision
84978520
func (c *Char) computeDamage(damage float64, kill, absolute bool, atkmul float32, attacker *Char, bounds bool) int32 {
@@ -11565,7 +11588,7 @@ func (c *Char) actionPrepare() {
1156511588
if c.alive() || c.ss.no != 5150 || c.numPartner() == 0 {
1156611589
c.setCSF(CSF_screenbound | CSF_movecamera_x | CSF_movecamera_y)
1156711590
}
11568-
if sys.roundState() > 0 && (c.alive() || c.numPartner() == 0) {
11591+
if sys.roundState() > 0 && sys.roundState() < 4 && (c.alive() || c.numPartner() == 0) {
1156911592
c.setCSF(CSF_playerpush)
1157011593
}
1157111594
}

src/motif.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3653,7 +3653,7 @@ func (co *MotifContinue) init(m *Motif) {
36533653

36543654
if !m.ContinueScreen.Sounds.Enabled {
36553655
sys.clearAllSound()
3656-
sys.noSoundFlg = true
3656+
sys.noCharSoundFlg = true
36573657
}
36583658

36593659
m.Music.Play("continue", sys.motif.Def)
@@ -3811,7 +3811,7 @@ func (co *MotifContinue) step(m *Motif) {
38113811
}
38123812
co.active = false
38133813
if !m.ContinueScreen.Sounds.Enabled {
3814-
sys.noSoundFlg = false
3814+
sys.noCharSoundFlg = false
38153815
}
38163816
return
38173817
}
@@ -6183,7 +6183,7 @@ func (vi *MotifVictory) init(m *Motif) {
61836183

61846184
if !m.VictoryScreen.Sounds.Enabled {
61856185
sys.clearAllSound()
6186-
sys.noSoundFlg = true
6186+
sys.noCharSoundFlg = true
61876187
}
61886188

61896189
// If match/stage/select.def defines victory.music, it should keep playing
@@ -6311,7 +6311,7 @@ func (vi *MotifVictory) step(m *Motif) {
63116311
}
63126312
vi.active = false
63136313
if !m.VictoryScreen.Sounds.Enabled {
6314-
sys.noSoundFlg = false
6314+
sys.noCharSoundFlg = false
63156315
}
63166316
return
63176317
}
@@ -6628,7 +6628,7 @@ func (wi *MotifWin) init(m *Motif) {
66286628

66296629
if !wi.soundsEnabled {
66306630
sys.clearAllSound()
6631-
sys.noSoundFlg = true
6631+
sys.noCharSoundFlg = true
66326632
}
66336633

66346634
m.Music.Play("results", sys.motif.Def)
@@ -6811,7 +6811,7 @@ func (wi *MotifWin) step(m *Motif) {
68116811
}
68126812
wi.active = false
68136813
if !wi.soundsEnabled {
6814-
sys.noSoundFlg = false
6814+
sys.noCharSoundFlg = false
68156815
}
68166816
return
68176817
}

src/render.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -483,12 +483,13 @@ func renderSpriteQuad(modelview mgl.Mat4, rp RenderParams) {
483483
// pers = Abs(rp.xbs) / Abs(rp.xts)
484484
//}
485485
if !rp.rot.IsZero() && rp.tile.xflag == 0 && rp.tile.yflag == 0 {
486-
if rp.vs != 1 {
487-
y1 = rp.rcy + ((rp.y - rp.ys*float32(rp.size[1])) - rp.rcy)
488-
y2 = y1
489-
y3 = rp.y
490-
y4 = y3
491-
}
486+
// This block makes shadows ignore their own yscale when in perspective
487+
//if rp.vs != 1 {
488+
// y1 = rp.rcy + ((rp.y - rp.ys*float32(rp.size[1])) - rp.rcy)
489+
// y2 = y1
490+
// y3 = rp.y
491+
// y4 = y3
492+
//}
492493
modelview = applyProjection(modelview, rp, 0, 1, 0)
493494
modelview = applyShear(modelview, rp.rxadd, rp.ys*float32(rp.size[1]))
494495
modelview = applyRotation(modelview, rp)

src/script.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3268,7 +3268,7 @@ func systemScriptInit(l *lua.LState) {
32683268
sys.resetGblEffect()
32693269
sys.dialogueForce = 0
32703270
sys.dialogueHideBars = false
3271-
sys.noSoundFlg = false
3271+
sys.noCharSoundFlg = false
32723272
sys.postMatchFlg = false
32733273
sys.preMatchTime += sys.matchTime
32743274
sys.matchTime = 0
@@ -7666,9 +7666,9 @@ func systemScriptInit(l *lua.LState) {
76667666
@tparam[opt] boolean state If provided, sets mute on/off; otherwise toggles it.
76677667
function toggleNoSound(state) end*/
76687668
if !nilArg(l, 1) {
7669-
sys.noSoundFlg = boolArg(l, 1)
7669+
sys.noCharSoundFlg = boolArg(l, 1)
76707670
} else {
7671-
sys.noSoundFlg = !sys.noSoundFlg
7671+
sys.noCharSoundFlg = !sys.noCharSoundFlg
76727672
}
76737673
return 0
76747674
})

src/sound.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -931,12 +931,24 @@ func (s *SoundEffect) Stream(samples [][2]float64) (n int, ok bool) {
931931
// TODO: Test mugen panning in relation to PanningWidth and zoom settings
932932
lv, rv := s.volume, s.volume
933933
if sys.cfg.Sound.StereoEffects && (s.x != nil || s.pan != 0) {
934+
// Use the camera viewport for panning, not the playable area
935+
//screen := sys.xmax - sys.xmin
936+
leftEdge := sys.cam.ScreenPos[0] + sys.cam.Offset[0]
937+
screenWidth := float32(sys.gameWidth) / sys.cam.Scale
938+
rightEdge := leftEdge + screenWidth
939+
940+
// Position ratio, where 0 is all the way right and 1 is all the way left
934941
var r float32
935-
if s.x != nil { // pan
936-
r = ((sys.xmax - s.localscl**s.x) - s.pan) / (sys.xmax - sys.xmin)
937-
} else { // abspan
938-
r = ((sys.xmax-sys.xmin)/2 - s.pan) / (sys.xmax - sys.xmin)
942+
943+
// Determine panning position
944+
if s.x != nil {
945+
// Pan: pan based on the sound's position relative to the screen edges
946+
r = ((rightEdge - s.localscl**s.x) - s.pan) / screenWidth
947+
} else {
948+
// Absolute pan: treat pan as an offset from center of screen
949+
r = ((rightEdge-leftEdge)/2 - s.pan) / screenWidth
939950
}
951+
940952
sc := sys.cfg.Sound.PanningRange / 100
941953
of := (100 - sys.cfg.Sound.PanningRange) / 200
942954
lv = Clamp(s.volume*2*(r*sc+of), 0, 512)

src/system.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ type SystemStateVars struct {
137137
uiRepeatFrame int32
138138

139139
endMatch bool
140-
noSoundFlg bool
140+
noCharSoundFlg bool
141141
fightLoopEnd bool
142142
continueFlg bool
143143
matchResetFlg bool
@@ -934,7 +934,7 @@ func (s *System) update() bool {
934934

935935
func (s *System) tickSound() {
936936
s.soundChannels.Tick()
937-
if !s.noSoundFlg {
937+
if !s.noCharSoundFlg {
938938
for i := range sys.charSoundChannels {
939939
sys.charSoundChannels[i].Tick()
940940
}
@@ -2310,6 +2310,9 @@ func (s *System) resetRound() {
23102310
s.roundResetFlg = false
23112311
s.reloadFlg, s.reloadStageFlg, s.reloadFightScreenFlg = false, false, false
23122312

2313+
// https://github.com/ikemen-engine/Ikemen-GO/issues/1400
2314+
s.noCharSoundFlg = false
2315+
23132316
s.resetGblEffect()
23142317
s.fightScreen.reset()
23152318
s.motif.reset()
@@ -2868,11 +2871,13 @@ func (s *System) explodCueDraw() {
28682871
if a.ontop != b.ontop {
28692872
return a.ontop
28702873
}
2871-
// If both are ontop, the age logic is the same as normal, but the index tiebreaker is inverted
2874+
// If both are ontop, the normal logic is inverted in order to emulate Mugen's memory layout
2875+
// However, it's impossible to cover all of Mugen's quirks without making our layout worse
28722876
// https://github.com/ikemen-engine/Ikemen-GO/issues/3737
2877+
// https://github.com/ikemen-engine/Ikemen-GO/issues/3749
28732878
if a.ontop && b.ontop {
28742879
if a.timestamp != b.timestamp {
2875-
return a.timestamp < b.timestamp
2880+
return a.timestamp >= b.timestamp
28762881
}
28772882
return a.sortindex >= b.sortindex
28782883
}

0 commit comments

Comments
 (0)