• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Go で書き直した Ikemen


コミットメタ情報

リビジョンc43f10a98fee857ae9d7986c82e9add4f680d5cf (tree)
日時2019-01-07 23:55:39
作者neatunsou <sisiy4excite@gmai...>
コミッターneatunsou

ログメッセージ

HitFallDamageを通るとFall.Damageが初期化するようにした
地上ヒット時にyvelが0でない時はair.hittimeを参照するようにした
HitdefのAnimTypeのBは地上ではHになるようにした
Hitdefに新パラメータteamsideを追加
ステージ側でキャラを一人読み込めるようにした

変更サマリ

差分

--- a/src/bytecode.go
+++ b/src/bytecode.go
@@ -1121,10 +1121,14 @@ func (be BytecodeExp) run(c *Char) BytecodeValue {
11211121 sys.bcStack.PushB(c.ss.stateType == StateType(be[i]))
11221122 i++
11231123 case OC_teammode:
1124- sys.bcStack.PushB(sys.tmode[c.playerNo&1] == TeamMode(be[i]))
1124+ if c.teamside == 2 {
1125+ sys.bcStack.PushB(TM_Single == TeamMode(be[i]))
1126+ } else {
1127+ sys.bcStack.PushB(sys.tmode[c.playerNo&1] == TeamMode(be[i]))
1128+ }
11251129 i++
11261130 case OC_teamside:
1127- sys.bcStack.PushI(int32(c.playerNo)&1 + 1)
1131+ sys.bcStack.PushI(int32(c.teamside) + 1)
11281132 case OC_time:
11291133 sys.bcStack.PushI(c.time())
11301134 case OC_topedge:
@@ -1450,7 +1454,7 @@ func (be BytecodeExp) run_ex(c *Char, i *int, oc *Char) {
14501454 case OC_ex_drawgame:
14511455 sys.bcStack.PushB(c.drawgame())
14521456 case OC_ex_ishometeam:
1453- sys.bcStack.PushB(c.playerNo&1 == sys.home)
1457+ sys.bcStack.PushB(c.teamside == sys.home)
14541458 case OC_ex_lose:
14551459 sys.bcStack.PushB(c.lose())
14561460 case OC_ex_loseko:
@@ -3139,6 +3143,7 @@ const (
31393143 hitDef_air_animtype
31403144 hitDef_fall_animtype
31413145 hitDef_affectteam
3146+ hitDef_teamside
31423147 hitDef_id
31433148 hitDef_chainid
31443149 hitDef_nochainid
@@ -3234,6 +3239,15 @@ func (sc hitDef) runSub(c *Char, hd *HitDef, id byte, exp []BytecodeExp) bool {
32343239 hd.fall.animtype = Reaction(exp[0].evalI(c))
32353240 case hitDef_affectteam:
32363241 hd.affectteam = exp[0].evalI(c)
3242+ case hitDef_teamside:
3243+ n := exp[0].evalI(c)
3244+ if n > 3 {
3245+ hd.teamside = 3
3246+ } else if n < 1 {
3247+ hd.teamside = 1
3248+ } else {
3249+ hd.teamside = int(n)
3250+ }
32373251 case hitDef_id:
32383252 hd.id = Max(0, exp[0].evalI(c))
32393253 case hitDef_chainid:
--- a/src/char.go
+++ b/src/char.go
@@ -428,6 +428,7 @@ type HitDef struct {
428428 hitflag int32
429429 guardflag int32
430430 affectteam int32
431+ teamside int
431432 animtype Reaction
432433 air_animtype Reaction
433434 priority int32
@@ -1235,8 +1236,8 @@ func (p *Projectile) clsn(playerNo int) {
12351236 }
12361237 for i := 0; i < playerNo && p.hits >= 0; i++ {
12371238 for j, pr := range sys.projs[i] {
1238- if pr.hits < 0 || pr.id < 0 || pr.hitdef.affectteam != 0 &&
1239- (playerNo&1 != i&1) != (pr.hitdef.affectteam > 0) ||
1239+ if pr.hits < 0 || pr.id < 0 || (pr.hitdef.affectteam != 0 &&
1240+ (p.hitdef.teamside-1 != pr.hitdef.teamside-1) != (pr.hitdef.affectteam > 0)) ||
12401241 pr.ani == nil || len(pr.ani.frames) == 0 {
12411242 continue
12421243 }
@@ -1457,6 +1458,7 @@ type Char struct {
14571458 helperIndex int32
14581459 parentIndex int32
14591460 playerNo int
1461+ teamside int
14601462 keyctrl bool
14611463 player bool
14621464 animPN int
@@ -1579,7 +1581,7 @@ func (c *Char) clear1() {
15791581 }
15801582 func (c *Char) copyParent(p *Char) {
15811583 c.parentIndex = p.helperIndex
1582- c.name, c.key, c.size = p.name+"'s helper", p.key, p.size
1584+ c.name, c.key, c.size, c.teamside = p.name+"'s helper", p.key, p.size, p.teamside
15831585 c.life, c.lifeMax, c.power, c.powerMax = p.lifeMax, p.lifeMax, 0, p.powerMax
15841586 c.clear2()
15851587 }
@@ -2180,7 +2182,7 @@ func (c *Char) partner(n int32) *Char {
21802182 p += 2
21812183 }
21822184 }
2183- if len(sys.chars[p]) > 0 {
2185+ if len(sys.chars[p]) > 0 && sys.chars[p][0].teamside < 2 {
21842186 return sys.chars[p][0]
21852187 }
21862188 return nil
@@ -2189,6 +2191,9 @@ func (c *Char) enemy(n int32) *Char {
21892191 if n < 0 || n >= c.numEnemy() {
21902192 return nil
21912193 }
2194+ if c.teamside == 3-1 {
2195+ return sys.chars[n][0]
2196+ }
21922197 return sys.chars[n*2+int32(^c.playerNo&1)][0]
21932198 }
21942199 func (c *Char) enemyNear(n int32) *Char {
@@ -2345,7 +2350,7 @@ func (c *Char) leftEdge() float32 {
23452350 return sys.cam.ScreenPos[0] / c.localscl
23462351 }
23472352 func (c *Char) lose() bool {
2348- return sys.winTeam == ^c.playerNo&1
2353+ return sys.winTeam == ^c.teamside
23492354 }
23502355 func (c *Char) loseKO() bool {
23512356 return c.lose() && sys.finish == FT_KO
@@ -2381,6 +2386,9 @@ func (c *Char) numEnemy() int32 {
23812386 if sys.tmode[^c.playerNo&1] != TM_Simul {
23822387 return 1
23832388 }
2389+ if c.teamside == 3-1 {
2390+ return sys.numSimul[0] + sys.numSimul[1]
2391+ }
23842392 return sys.numSimul[^c.playerNo&1]
23852393 }
23862394 func (c *Char) numExplod(eid BytecodeValue) BytecodeValue {
@@ -2408,7 +2416,7 @@ func (c *Char) numHelper(hid BytecodeValue) BytecodeValue {
24082416 return BytecodeInt(n)
24092417 }
24102418 func (c *Char) numPartner() int32 {
2411- if sys.tmode[c.playerNo&1] != TM_Simul {
2419+ if sys.tmode[c.playerNo&1] != TM_Simul || c.teamside >= 2 {
24122420 return 0
24132421 }
24142422 return sys.numSimul[c.playerNo&1] - 1
@@ -2460,7 +2468,7 @@ func (c *Char) palno() int32 {
24602468 return c.gi().palno
24612469 }
24622470 func (c *Char) getPower() int32 {
2463- if sys.powerShare[c.playerNo&1] {
2471+ if sys.powerShare[c.playerNo&1] && c.teamside < 2 {
24642472 return sys.chars[c.playerNo&1][0].power
24652473 }
24662474 return sys.chars[c.playerNo][0].power
@@ -2509,6 +2517,9 @@ func (c *Char) rightEdge() float32 {
25092517 return sys.cam.ScreenPos[0]/c.localscl + c.gameWidth()
25102518 }
25112519 func (c *Char) roundsExisted() int32 {
2520+ if c.teamside >= 2 {
2521+ return sys.round - 1
2522+ }
25122523 return sys.roundsExisted[c.playerNo&1]
25132524 }
25142525 func (c *Char) roundState() int32 {
@@ -2546,6 +2557,9 @@ func (c *Char) topEdge() float32 {
25462557 return sys.cam.ScreenPos[1] / c.localscl
25472558 }
25482559 func (c *Char) win() bool {
2560+ if c.teamside >= 2 {
2561+ return false
2562+ }
25492563 return sys.winTeam == c.playerNo&1
25502564 }
25512565 func (c *Char) winKO() bool {
@@ -2555,6 +2569,9 @@ func (c *Char) winTime() bool {
25552569 return c.win() && sys.finish == FT_TO
25562570 }
25572571 func (c *Char) winPerfect() bool {
2572+ if c.teamside >= 2 {
2573+ return false
2574+ }
25582575 return c.win() && sys.winType[c.playerNo&1] >= WT_PN
25592576 }
25602577 func (c *Char) newChannel(ch int32, lowpriority bool) *Sound {
@@ -2979,9 +2996,14 @@ func (c *Char) setPosY(y float32) {
29792996 c.pos[1] = y
29802997 }
29812998 func (c *Char) posReset() {
2982- c.facing = 1 - 2*float32(c.playerNo&1)
2983- c.setX((float32(sys.stage.p[c.playerNo&1].startx-sys.cam.startx)*
2984- sys.stage.localscl - c.facing*float32(c.playerNo>>1)*P1P3Dist) / c.localscl)
2999+ if c.teamside >= 2 {
3000+ c.facing = 1
3001+ c.setX(0)
3002+ } else {
3003+ c.facing = 1 - 2*float32(c.playerNo&1)
3004+ c.setX((float32(sys.stage.p[c.playerNo&1].startx-sys.cam.startx)*
3005+ sys.stage.localscl - c.facing*float32(c.playerNo>>1)*P1P3Dist) / c.localscl)
3006+ }
29853007 c.setY(0)
29863008 c.setXV(0)
29873009 c.setYV(0)
@@ -3112,6 +3134,9 @@ func (c *Char) setHitdefDefault(hd *HitDef, proj bool) {
31123134 if hd.air_animtype == RA_Unknown {
31133135 hd.air_animtype = hd.animtype
31143136 }
3137+ if hd.animtype == RA_Back {
3138+ hd.animtype = RA_Hard
3139+ }
31153140 if hd.air_type == HT_Unknown {
31163141 if hd.ground_type == HT_Trip {
31173142 hd.air_type = HT_High
@@ -3143,6 +3168,9 @@ func (c *Char) setHitdefDefault(hd *HitDef, proj bool) {
31433168 if !math.IsNaN(float64(hd.snap[1])) {
31443169 hd.maxdist[1], hd.mindist[1] = hd.snap[1], hd.snap[1]
31453170 }
3171+ if hd.teamside == 0 {
3172+ hd.teamside = c.teamside + 1
3173+ }
31463174 hd.playerNo = c.ss.sb.playerNo
31473175 }
31483176 func (c *Char) setFEdge(fe float32) {
@@ -3479,7 +3507,7 @@ func (c *Char) lifeAdd(add float64, kill, absolute bool) {
34793507 }
34803508 func (c *Char) lifeSet(life int32) {
34813509 if c.life = Max(0, Min(c.lifeMax, life)); c.life == 0 {
3482- if c.player {
3510+ if c.player && c.teamside < 2 {
34833511 if c.alive() && c.helperIndex == 0 {
34843512 if c.ss.moveType != MT_H {
34853513 if c.playerNo == c.ss.sb.playerNo {
@@ -3514,14 +3542,14 @@ func (c *Char) setPower(pow int32) {
35143542 }
35153543 }
35163544 func (c *Char) powerAdd(add int32) {
3517- if sys.powerShare[c.playerNo&1] {
3545+ if sys.powerShare[c.playerNo&1] && c.teamside < 2 {
35183546 sys.chars[c.playerNo&1][0].setPower(c.getPower() + add)
35193547 } else {
35203548 sys.chars[c.playerNo][0].setPower(c.getPower() + add)
35213549 }
35223550 }
35233551 func (c *Char) powerSet(pow int32) {
3524- if sys.powerShare[c.playerNo&1] {
3552+ if sys.powerShare[c.playerNo&1] && c.teamside < 2 {
35253553 sys.chars[c.playerNo&1][0].setPower(pow)
35263554 } else {
35273555 sys.chars[c.playerNo][0].setPower(pow)
@@ -3684,6 +3712,7 @@ func (c *Char) makeDust(x, y float32) {
36843712 func (c *Char) hitFallDamage() {
36853713 if c.ss.moveType == MT_H {
36863714 c.lifeAdd(-float64(c.ghv.fall.damage), c.ghv.fall.kill, false)
3715+ c.ghv.fall.damage = 0
36873716 }
36883717 }
36893718 func (c *Char) hitFallVel() {
@@ -4600,7 +4629,7 @@ func (c *Char) cueDraw() {
46004629 if c.roundState() == 4 {
46014630 c.exitTarget(false)
46024631 }
4603- if sys.supertime < 0 && c.playerNo&1 != sys.superplayer&1 {
4632+ if sys.supertime < 0 && c.teamside != sys.superplayer&1 {
46044633 c.defenceMul *= sys.superp2defmul
46054634 }
46064635 c.minus = 2
@@ -4856,7 +4885,6 @@ func (cl *CharList) clsn(getter *Char, proj bool) {
48564885 ghv.fall.yvelocity = 0
48574886 }
48584887 } else {
4859- ghv.hittime = hd.ground_hittime
48604888 ghv.ctrltime = hd.ground_hittime
48614889 ghv.xvel = hd.ground_velocity[0] * c.localscl / getter.localscl
48624890 ghv.yvel = hd.ground_velocity[1] * c.localscl / getter.localscl
@@ -4864,6 +4892,11 @@ func (cl *CharList) clsn(getter *Char, proj bool) {
48644892 if ghv.fallf && ghv.yvel == 0 {
48654893 ghv.yvel = -0.001 * c.localscl / getter.localscl //新MUGENだとウィンドウサイズを大きくするとここに入る数値が小さくなるが、再現しないほうがよいと思う。
48664894 }
4895+ if ghv.yvel != 0 {
4896+ ghv.hittime = hd.air_hittime
4897+ } else {
4898+ ghv.hittime = hd.ground_hittime
4899+ }
48674900 }
48684901 if ghv.hittime < 0 {
48694902 ghv.hittime = 0
@@ -5201,7 +5234,7 @@ func (cl *CharList) clsn(getter *Char, proj bool) {
52015234 for j := range pr {
52025235 p := &pr[j]
52035236 if p.id < 0 || p.hits < 0 || p.hitdef.affectteam != 0 &&
5204- (getter.playerNo&1 != i&1) != (p.hitdef.affectteam > 0) {
5237+ (getter.teamside != p.hitdef.teamside-1) != (p.hitdef.affectteam > 0) {
52055238 continue
52065239 }
52075240 if dist := (getter.pos[0]*getter.localscl - p.pos[0]*p.localscl) * p.facing; dist >= 0 &&
@@ -5212,7 +5245,7 @@ func (cl *CharList) clsn(getter *Char, proj bool) {
52125245 continue
52135246 }
52145247 if getter.atktmp != 0 && (getter.hitdef.affectteam == 0 ||
5215- (i&1 != getter.playerNo&1) == (getter.hitdef.affectteam > 0)) &&
5248+ (p.hitdef.teamside-1 != getter.teamside) == (getter.hitdef.affectteam > 0)) &&
52165249 getter.hitdef.hitflag&int32(ST_P) != 0 &&
52175250 getter.projClsnCheck(p, false) {
52185251 p.hits = -2
@@ -5281,7 +5314,7 @@ func (cl *CharList) clsn(getter *Char, proj bool) {
52815314 for _, c := range cl.runOrder {
52825315 contact := 0
52835316 if c.atktmp != 0 && c.id != getter.id && (c.hitdef.affectteam == 0 ||
5284- (getter.playerNo&1 != c.playerNo&1) == (c.hitdef.affectteam > 0)) {
5317+ (getter.teamside != c.hitdef.teamside-1) == (c.hitdef.affectteam > 0)) {
52855318 dist := -getter.distX(c, getter) * c.facing
52865319 if c.ss.moveType == MT_A && dist >= 0 && dist <= c.attackDist {
52875320 getter.inguarddist = true
@@ -5350,7 +5383,7 @@ func (cl *CharList) clsn(getter *Char, proj bool) {
53505383 }
53515384 }
53525385 }
5353- if getter.playerNo&1 != c.playerNo&1 && getter.sf(CSF_playerpush) &&
5386+ if getter.teamside != c.teamside && getter.sf(CSF_playerpush) &&
53545387 c.sf(CSF_playerpush) && (getter.ss.stateType == ST_A ||
53555388 getter.pos[1]*getter.localscl-c.pos[1]*c.localscl < getter.height()*c.localscl) &&
53565389 (c.ss.stateType == ST_A || c.pos[1]*c.localscl-getter.pos[1]*getter.localscl < c.height()*(320/float32(c.localcoord))) {
@@ -5457,7 +5490,7 @@ func (cl *CharList) enemyNear(c *Char, n int32, p2 bool) *Char {
54575490 }
54585491 }
54595492 for _, e := range cl.runOrder {
5460- if e.player && e.playerNo&1 != c.playerNo&1 &&
5493+ if e.player && e.teamside != c.teamside &&
54615494 (p2 && !e.scf(SCF_ko_round_middle) || !p2 && e.helperIndex == 0) {
54625495 add(e, 0)
54635496 }
--- a/src/compiler.go
+++ b/src/compiler.go
@@ -4088,6 +4088,10 @@ func (c *Compiler) hitDefSub(is IniSection,
40884088 }); err != nil {
40894089 return err
40904090 }
4091+ if err := c.paramValue(is, sc, "teamside",
4092+ hitDef_teamside, VT_Int, 1, false); err != nil {
4093+ return err
4094+ }
40914095 if err := c.paramValue(is, sc, "id",
40924096 hitDef_id, VT_Int, 1, false); err != nil {
40934097 return err
@@ -7211,7 +7215,7 @@ func (c *Compiler) Compile(pn int, def string) (map[int32]StateBytecode,
72117215 return nil, err
72127216 }
72137217 if sys.chars[pn][0].cmd == nil {
7214- sys.chars[pn][0].cmd = make([]CommandList, MaxSimul*2)
7218+ sys.chars[pn][0].cmd = make([]CommandList, MaxSimul*2+MaxAttachedChar)
72157219 b := NewCommandBuffer()
72167220 for i := range sys.chars[pn][0].cmd {
72177221 sys.chars[pn][0].cmd[i] = *NewCommandList(b)
--- a/src/input.go
+++ b/src/input.go
@@ -1011,7 +1011,7 @@ type NetInput struct {
10111011 st NetState
10121012 sendEnd chan bool
10131013 recvEnd chan bool
1014- buf [MaxSimul * 2]NetBuffer
1014+ buf [MaxSimul*2 + MaxAttachedChar]NetBuffer
10151015 locIn int
10161016 remIn int
10171017 time int32
--- a/src/script.go
+++ b/src/script.go
@@ -207,7 +207,7 @@ func scriptCommonInit(l *lua.LState) {
207207 })
208208 luaRegister(l, "setAutoguard", func(l *lua.LState) int {
209209 pn := int(numArg(l, 1))
210- if pn < 1 || pn > MaxSimul*2 {
210+ if pn < 1 || pn > MaxSimul*2+MaxAttachedChar {
211211 l.RaiseError("プレイヤー番号(%v)が不正です。", pn)
212212 }
213213 sys.autoguard[pn-1] = boolArg(l, 2)
@@ -454,7 +454,7 @@ func systemScriptInit(l *lua.LState) {
454454 })
455455 luaRegister(l, "setCom", func(*lua.LState) int {
456456 pn := int(numArg(l, 1))
457- if pn < 1 || pn > MaxSimul*2 {
457+ if pn < 1 || pn > MaxSimul*2+MaxAttachedChar {
458458 l.RaiseError("プレイヤー番号(%v)が不正です。", pn)
459459 }
460460 sys.com[pn-1] = Max(0, int32(numArg(l, 2)))
@@ -1713,7 +1713,7 @@ func triggerScriptInit(l *lua.LState) {
17131713 return 1
17141714 })
17151715 luaRegister(l, "ishometeam", func(*lua.LState) int {
1716- l.Push(lua.LBool(sys.debugWC.playerNo&1 == sys.home))
1716+ l.Push(lua.LBool(sys.debugWC.teamside == sys.home))
17171717 return 1
17181718 })
17191719 luaRegister(l, "leftedge", func(*lua.LState) int {
--- a/src/system.go
+++ b/src/system.go
@@ -19,9 +19,10 @@ import (
1919 )
2020
2121 const (
22- MaxSimul = 4
23- FPS = 60
24- P1P3Dist = 25
22+ MaxSimul = 4
23+ MaxAttachedChar = 2
24+ FPS = 60
25+ P1P3Dist = 25
2526 )
2627
2728 var sys = System{
@@ -96,15 +97,15 @@ type System struct {
9697 keySatate map[glfw.Key]bool
9798 netInput *NetInput
9899 fileInput *FileInput
99- aiInput [MaxSimul * 2]AiInput
100+ aiInput [MaxSimul*2 + MaxAttachedChar]AiInput
100101 keyConfig []KeyConfig
101102 JoystickConfig []KeyConfig
102- com [MaxSimul * 2]int32
103+ com [MaxSimul*2 + MaxAttachedChar]int32
103104 autolevel bool
104105 home int
105106 gameTime int32
106107 match int32
107- inputRemap [MaxSimul * 2]int
108+ inputRemap [MaxSimul*2 + MaxAttachedChar]int
108109 listenPort string
109110 round int32
110111 intro int32
@@ -115,15 +116,15 @@ type System struct {
115116 roundsExisted [2]int32
116117 draws int32
117118 loader Loader
118- chars [MaxSimul * 2][]*Char
119+ chars [MaxSimul*2 + MaxAttachedChar][]*Char
119120 charList CharList
120- cgi [MaxSimul * 2]CharGlobalInfo
121+ cgi [MaxSimul*2 + MaxAttachedChar]CharGlobalInfo
121122 tmode [2]TeamMode
122123 numSimul, numTurns [2]int32
123124 esc bool
124125 loadMutex sync.Mutex
125126 ignoreMostErrors bool
126- stringPool [MaxSimul * 2]StringPool
127+ stringPool [MaxSimul*2 + MaxAttachedChar]StringPool
127128 bcStack, bcVarStack BytecodeStack
128129 bcVar []BytecodeValue
129130 workingChar *Char
@@ -153,7 +154,7 @@ type System struct {
153154 envcol [3]int32
154155 envcol_time int32
155156 envcol_under bool
156- clipboardText [MaxSimul * 2][]string
157+ clipboardText [MaxSimul*2 + MaxAttachedChar][]string
157158 stage *Stage
158159 helperMax int32
159160 nextCharId int32
@@ -183,10 +184,10 @@ type System struct {
183184 finish FinishType
184185 waitdown int32
185186 shuttertime int32
186- projs [MaxSimul * 2][]Projectile
187- explods [MaxSimul * 2][]Explod
188- explDrawlist [MaxSimul * 2][]int
189- topexplDrawlist [MaxSimul * 2][]int
187+ projs [MaxSimul*2 + MaxAttachedChar][]Projectile
188+ explods [MaxSimul*2 + MaxAttachedChar][]Explod
189+ explDrawlist [MaxSimul*2 + MaxAttachedChar][]int
190+ topexplDrawlist [MaxSimul*2 + MaxAttachedChar][]int
190191 changeStateNest int32
191192 sprites DrawList
192193 topSprites DrawList
@@ -196,7 +197,7 @@ type System struct {
196197 drawc2sp ClsnRect
197198 drawc2mtk ClsnRect
198199 drawwh ClsnRect
199- autoguard [MaxSimul * 2]bool
200+ autoguard [MaxSimul*2 + MaxAttachedChar]bool
200201 clsnDraw bool
201202 accel float32
202203 statusDraw bool
@@ -910,7 +911,7 @@ func (s *System) action(x, y *float32, scl float32) (leftest, rightest,
910911 ko := [...]bool{true, true}
911912 for ii := range ko {
912913 for i := ii; i < len(s.chars); i += 2 {
913- if len(s.chars[i]) > 0 && s.chars[i][0].alive() {
914+ if len(s.chars[i]) > 0 && s.chars[i][0].alive() && s.chars[i][0].teamside < 2 {
914915 ko[ii] = false
915916 break
916917 }
@@ -1679,7 +1680,7 @@ type SelectChar struct {
16791680 sportrait, lportrait, vsportrait, vportrait *Sprite
16801681 }
16811682 type SelectStage struct {
1682- def, name, zoomout, zoomin, bgmusic, bgmvolume string
1683+ def, name, zoomout, zoomin, bgmusic, bgmvolume, attachedchardef string
16831684 }
16841685 type Select struct {
16851686 columns, rows int
@@ -1869,6 +1870,7 @@ func (s *Select) AddStage(def string) error {
18691870 ss.name = def
18701871 }
18711872 }
1873+ ss.attachedchardef, ok = is.getString("attachedchar")
18721874 }
18731875 case "camera":
18741876 if camera {
@@ -1993,6 +1995,7 @@ func (l *Loader) loadChar(pn int) int {
19931995 }
19941996 p.memberNo = memberNo
19951997 p.selectNo = sys.sel.selected[pn&1][memberNo][0]
1998+ p.teamside = p.playerNo & 1
19961999 sys.chars[pn] = make([]*Char, 1)
19972000 sys.chars[pn][0] = p
19982001 if sys.cgi[pn].sff == nil {
@@ -2026,13 +2029,53 @@ func (l *Loader) loadChar(pn int) int {
20262029 }
20272030 return 1
20282031 }
2032+
2033+func (l *Loader) loadAttachedChar(atcpn int, def string) int {
2034+ pn := atcpn + MaxSimul*2
2035+ cdef := def
2036+ var p *Char
2037+ if len(sys.chars[pn]) > 0 && cdef == sys.cgi[pn].def {
2038+ p = sys.chars[pn][0]
2039+ p.key = -pn
2040+ } else {
2041+ p = newChar(pn, 0)
2042+ sys.cgi[pn].sff = nil
2043+ if len(sys.chars[pn]) > 0 {
2044+ p.power = sys.chars[pn][0].power
2045+ }
2046+ }
2047+ p.memberNo = -atcpn
2048+ p.selectNo = -atcpn
2049+ p.teamside = 2
2050+ sys.com[pn] = 8
2051+ sys.chars[pn] = make([]*Char, 1)
2052+ sys.chars[pn][0] = p
2053+ if sys.cgi[pn].sff == nil {
2054+ if sys.cgi[pn].states, l.err =
2055+ newCompiler().Compile(p.playerNo, cdef); l.err != nil {
2056+ sys.chars[pn] = nil
2057+ return -1
2058+ }
2059+ if l.err = p.load(cdef); l.err != nil {
2060+ sys.chars[pn] = nil
2061+ return -1
2062+ }
2063+ }
2064+ if sys.roundsExisted[pn&1] == 0 {
2065+ sys.cgi[pn].palno = 1
2066+ }
2067+ return 1
2068+}
2069+
20292070 func (l *Loader) loadStage() bool {
20302071 if sys.round == 1 {
20312072 var def string
20322073 if sys.sel.selectedStageNo == 0 {
2033- def = sys.sel.stagelist[Rand(0, int32(len(sys.sel.stagelist))-1)].def
2074+ randomstageno := Rand(0, int32(len(sys.sel.stagelist))-1)
2075+ def = sys.sel.stagelist[randomstageno].def
20342076 } else {
20352077 def = sys.sel.stagelist[sys.sel.selectedStageNo-1].def
2078+ l.loadAttachedChar(0, sys.sel.stagelist[sys.sel.selectedStageNo-1].attachedchardef)
20362079 }
20372080 if sys.stage != nil && sys.stage.def == def {
20382081 return true