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を追加
ステージ側でキャラを一人読み込めるようにした
@@ -1121,10 +1121,14 @@ func (be BytecodeExp) run(c *Char) BytecodeValue { | ||
1121 | 1121 | sys.bcStack.PushB(c.ss.stateType == StateType(be[i])) |
1122 | 1122 | i++ |
1123 | 1123 | 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 | + } | |
1125 | 1129 | i++ |
1126 | 1130 | case OC_teamside: |
1127 | - sys.bcStack.PushI(int32(c.playerNo)&1 + 1) | |
1131 | + sys.bcStack.PushI(int32(c.teamside) + 1) | |
1128 | 1132 | case OC_time: |
1129 | 1133 | sys.bcStack.PushI(c.time()) |
1130 | 1134 | case OC_topedge: |
@@ -1450,7 +1454,7 @@ func (be BytecodeExp) run_ex(c *Char, i *int, oc *Char) { | ||
1450 | 1454 | case OC_ex_drawgame: |
1451 | 1455 | sys.bcStack.PushB(c.drawgame()) |
1452 | 1456 | case OC_ex_ishometeam: |
1453 | - sys.bcStack.PushB(c.playerNo&1 == sys.home) | |
1457 | + sys.bcStack.PushB(c.teamside == sys.home) | |
1454 | 1458 | case OC_ex_lose: |
1455 | 1459 | sys.bcStack.PushB(c.lose()) |
1456 | 1460 | case OC_ex_loseko: |
@@ -3139,6 +3143,7 @@ const ( | ||
3139 | 3143 | hitDef_air_animtype |
3140 | 3144 | hitDef_fall_animtype |
3141 | 3145 | hitDef_affectteam |
3146 | + hitDef_teamside | |
3142 | 3147 | hitDef_id |
3143 | 3148 | hitDef_chainid |
3144 | 3149 | hitDef_nochainid |
@@ -3234,6 +3239,15 @@ func (sc hitDef) runSub(c *Char, hd *HitDef, id byte, exp []BytecodeExp) bool { | ||
3234 | 3239 | hd.fall.animtype = Reaction(exp[0].evalI(c)) |
3235 | 3240 | case hitDef_affectteam: |
3236 | 3241 | 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 | + } | |
3237 | 3251 | case hitDef_id: |
3238 | 3252 | hd.id = Max(0, exp[0].evalI(c)) |
3239 | 3253 | case hitDef_chainid: |
@@ -428,6 +428,7 @@ type HitDef struct { | ||
428 | 428 | hitflag int32 |
429 | 429 | guardflag int32 |
430 | 430 | affectteam int32 |
431 | + teamside int | |
431 | 432 | animtype Reaction |
432 | 433 | air_animtype Reaction |
433 | 434 | priority int32 |
@@ -1235,8 +1236,8 @@ func (p *Projectile) clsn(playerNo int) { | ||
1235 | 1236 | } |
1236 | 1237 | for i := 0; i < playerNo && p.hits >= 0; i++ { |
1237 | 1238 | 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)) || | |
1240 | 1241 | pr.ani == nil || len(pr.ani.frames) == 0 { |
1241 | 1242 | continue |
1242 | 1243 | } |
@@ -1457,6 +1458,7 @@ type Char struct { | ||
1457 | 1458 | helperIndex int32 |
1458 | 1459 | parentIndex int32 |
1459 | 1460 | playerNo int |
1461 | + teamside int | |
1460 | 1462 | keyctrl bool |
1461 | 1463 | player bool |
1462 | 1464 | animPN int |
@@ -1579,7 +1581,7 @@ func (c *Char) clear1() { | ||
1579 | 1581 | } |
1580 | 1582 | func (c *Char) copyParent(p *Char) { |
1581 | 1583 | 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 | |
1583 | 1585 | c.life, c.lifeMax, c.power, c.powerMax = p.lifeMax, p.lifeMax, 0, p.powerMax |
1584 | 1586 | c.clear2() |
1585 | 1587 | } |
@@ -2180,7 +2182,7 @@ func (c *Char) partner(n int32) *Char { | ||
2180 | 2182 | p += 2 |
2181 | 2183 | } |
2182 | 2184 | } |
2183 | - if len(sys.chars[p]) > 0 { | |
2185 | + if len(sys.chars[p]) > 0 && sys.chars[p][0].teamside < 2 { | |
2184 | 2186 | return sys.chars[p][0] |
2185 | 2187 | } |
2186 | 2188 | return nil |
@@ -2189,6 +2191,9 @@ func (c *Char) enemy(n int32) *Char { | ||
2189 | 2191 | if n < 0 || n >= c.numEnemy() { |
2190 | 2192 | return nil |
2191 | 2193 | } |
2194 | + if c.teamside == 3-1 { | |
2195 | + return sys.chars[n][0] | |
2196 | + } | |
2192 | 2197 | return sys.chars[n*2+int32(^c.playerNo&1)][0] |
2193 | 2198 | } |
2194 | 2199 | func (c *Char) enemyNear(n int32) *Char { |
@@ -2345,7 +2350,7 @@ func (c *Char) leftEdge() float32 { | ||
2345 | 2350 | return sys.cam.ScreenPos[0] / c.localscl |
2346 | 2351 | } |
2347 | 2352 | func (c *Char) lose() bool { |
2348 | - return sys.winTeam == ^c.playerNo&1 | |
2353 | + return sys.winTeam == ^c.teamside | |
2349 | 2354 | } |
2350 | 2355 | func (c *Char) loseKO() bool { |
2351 | 2356 | return c.lose() && sys.finish == FT_KO |
@@ -2381,6 +2386,9 @@ func (c *Char) numEnemy() int32 { | ||
2381 | 2386 | if sys.tmode[^c.playerNo&1] != TM_Simul { |
2382 | 2387 | return 1 |
2383 | 2388 | } |
2389 | + if c.teamside == 3-1 { | |
2390 | + return sys.numSimul[0] + sys.numSimul[1] | |
2391 | + } | |
2384 | 2392 | return sys.numSimul[^c.playerNo&1] |
2385 | 2393 | } |
2386 | 2394 | func (c *Char) numExplod(eid BytecodeValue) BytecodeValue { |
@@ -2408,7 +2416,7 @@ func (c *Char) numHelper(hid BytecodeValue) BytecodeValue { | ||
2408 | 2416 | return BytecodeInt(n) |
2409 | 2417 | } |
2410 | 2418 | 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 { | |
2412 | 2420 | return 0 |
2413 | 2421 | } |
2414 | 2422 | return sys.numSimul[c.playerNo&1] - 1 |
@@ -2460,7 +2468,7 @@ func (c *Char) palno() int32 { | ||
2460 | 2468 | return c.gi().palno |
2461 | 2469 | } |
2462 | 2470 | func (c *Char) getPower() int32 { |
2463 | - if sys.powerShare[c.playerNo&1] { | |
2471 | + if sys.powerShare[c.playerNo&1] && c.teamside < 2 { | |
2464 | 2472 | return sys.chars[c.playerNo&1][0].power |
2465 | 2473 | } |
2466 | 2474 | return sys.chars[c.playerNo][0].power |
@@ -2509,6 +2517,9 @@ func (c *Char) rightEdge() float32 { | ||
2509 | 2517 | return sys.cam.ScreenPos[0]/c.localscl + c.gameWidth() |
2510 | 2518 | } |
2511 | 2519 | func (c *Char) roundsExisted() int32 { |
2520 | + if c.teamside >= 2 { | |
2521 | + return sys.round - 1 | |
2522 | + } | |
2512 | 2523 | return sys.roundsExisted[c.playerNo&1] |
2513 | 2524 | } |
2514 | 2525 | func (c *Char) roundState() int32 { |
@@ -2546,6 +2557,9 @@ func (c *Char) topEdge() float32 { | ||
2546 | 2557 | return sys.cam.ScreenPos[1] / c.localscl |
2547 | 2558 | } |
2548 | 2559 | func (c *Char) win() bool { |
2560 | + if c.teamside >= 2 { | |
2561 | + return false | |
2562 | + } | |
2549 | 2563 | return sys.winTeam == c.playerNo&1 |
2550 | 2564 | } |
2551 | 2565 | func (c *Char) winKO() bool { |
@@ -2555,6 +2569,9 @@ func (c *Char) winTime() bool { | ||
2555 | 2569 | return c.win() && sys.finish == FT_TO |
2556 | 2570 | } |
2557 | 2571 | func (c *Char) winPerfect() bool { |
2572 | + if c.teamside >= 2 { | |
2573 | + return false | |
2574 | + } | |
2558 | 2575 | return c.win() && sys.winType[c.playerNo&1] >= WT_PN |
2559 | 2576 | } |
2560 | 2577 | func (c *Char) newChannel(ch int32, lowpriority bool) *Sound { |
@@ -2979,9 +2996,14 @@ func (c *Char) setPosY(y float32) { | ||
2979 | 2996 | c.pos[1] = y |
2980 | 2997 | } |
2981 | 2998 | 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 | + } | |
2985 | 3007 | c.setY(0) |
2986 | 3008 | c.setXV(0) |
2987 | 3009 | c.setYV(0) |
@@ -3112,6 +3134,9 @@ func (c *Char) setHitdefDefault(hd *HitDef, proj bool) { | ||
3112 | 3134 | if hd.air_animtype == RA_Unknown { |
3113 | 3135 | hd.air_animtype = hd.animtype |
3114 | 3136 | } |
3137 | + if hd.animtype == RA_Back { | |
3138 | + hd.animtype = RA_Hard | |
3139 | + } | |
3115 | 3140 | if hd.air_type == HT_Unknown { |
3116 | 3141 | if hd.ground_type == HT_Trip { |
3117 | 3142 | hd.air_type = HT_High |
@@ -3143,6 +3168,9 @@ func (c *Char) setHitdefDefault(hd *HitDef, proj bool) { | ||
3143 | 3168 | if !math.IsNaN(float64(hd.snap[1])) { |
3144 | 3169 | hd.maxdist[1], hd.mindist[1] = hd.snap[1], hd.snap[1] |
3145 | 3170 | } |
3171 | + if hd.teamside == 0 { | |
3172 | + hd.teamside = c.teamside + 1 | |
3173 | + } | |
3146 | 3174 | hd.playerNo = c.ss.sb.playerNo |
3147 | 3175 | } |
3148 | 3176 | func (c *Char) setFEdge(fe float32) { |
@@ -3479,7 +3507,7 @@ func (c *Char) lifeAdd(add float64, kill, absolute bool) { | ||
3479 | 3507 | } |
3480 | 3508 | func (c *Char) lifeSet(life int32) { |
3481 | 3509 | if c.life = Max(0, Min(c.lifeMax, life)); c.life == 0 { |
3482 | - if c.player { | |
3510 | + if c.player && c.teamside < 2 { | |
3483 | 3511 | if c.alive() && c.helperIndex == 0 { |
3484 | 3512 | if c.ss.moveType != MT_H { |
3485 | 3513 | if c.playerNo == c.ss.sb.playerNo { |
@@ -3514,14 +3542,14 @@ func (c *Char) setPower(pow int32) { | ||
3514 | 3542 | } |
3515 | 3543 | } |
3516 | 3544 | func (c *Char) powerAdd(add int32) { |
3517 | - if sys.powerShare[c.playerNo&1] { | |
3545 | + if sys.powerShare[c.playerNo&1] && c.teamside < 2 { | |
3518 | 3546 | sys.chars[c.playerNo&1][0].setPower(c.getPower() + add) |
3519 | 3547 | } else { |
3520 | 3548 | sys.chars[c.playerNo][0].setPower(c.getPower() + add) |
3521 | 3549 | } |
3522 | 3550 | } |
3523 | 3551 | func (c *Char) powerSet(pow int32) { |
3524 | - if sys.powerShare[c.playerNo&1] { | |
3552 | + if sys.powerShare[c.playerNo&1] && c.teamside < 2 { | |
3525 | 3553 | sys.chars[c.playerNo&1][0].setPower(pow) |
3526 | 3554 | } else { |
3527 | 3555 | sys.chars[c.playerNo][0].setPower(pow) |
@@ -3684,6 +3712,7 @@ func (c *Char) makeDust(x, y float32) { | ||
3684 | 3712 | func (c *Char) hitFallDamage() { |
3685 | 3713 | if c.ss.moveType == MT_H { |
3686 | 3714 | c.lifeAdd(-float64(c.ghv.fall.damage), c.ghv.fall.kill, false) |
3715 | + c.ghv.fall.damage = 0 | |
3687 | 3716 | } |
3688 | 3717 | } |
3689 | 3718 | func (c *Char) hitFallVel() { |
@@ -4600,7 +4629,7 @@ func (c *Char) cueDraw() { | ||
4600 | 4629 | if c.roundState() == 4 { |
4601 | 4630 | c.exitTarget(false) |
4602 | 4631 | } |
4603 | - if sys.supertime < 0 && c.playerNo&1 != sys.superplayer&1 { | |
4632 | + if sys.supertime < 0 && c.teamside != sys.superplayer&1 { | |
4604 | 4633 | c.defenceMul *= sys.superp2defmul |
4605 | 4634 | } |
4606 | 4635 | c.minus = 2 |
@@ -4856,7 +4885,6 @@ func (cl *CharList) clsn(getter *Char, proj bool) { | ||
4856 | 4885 | ghv.fall.yvelocity = 0 |
4857 | 4886 | } |
4858 | 4887 | } else { |
4859 | - ghv.hittime = hd.ground_hittime | |
4860 | 4888 | ghv.ctrltime = hd.ground_hittime |
4861 | 4889 | ghv.xvel = hd.ground_velocity[0] * c.localscl / getter.localscl |
4862 | 4890 | ghv.yvel = hd.ground_velocity[1] * c.localscl / getter.localscl |
@@ -4864,6 +4892,11 @@ func (cl *CharList) clsn(getter *Char, proj bool) { | ||
4864 | 4892 | if ghv.fallf && ghv.yvel == 0 { |
4865 | 4893 | ghv.yvel = -0.001 * c.localscl / getter.localscl //新MUGENだとウィンドウサイズを大きくするとここに入る数値が小さくなるが、再現しないほうがよいと思う。 |
4866 | 4894 | } |
4895 | + if ghv.yvel != 0 { | |
4896 | + ghv.hittime = hd.air_hittime | |
4897 | + } else { | |
4898 | + ghv.hittime = hd.ground_hittime | |
4899 | + } | |
4867 | 4900 | } |
4868 | 4901 | if ghv.hittime < 0 { |
4869 | 4902 | ghv.hittime = 0 |
@@ -5201,7 +5234,7 @@ func (cl *CharList) clsn(getter *Char, proj bool) { | ||
5201 | 5234 | for j := range pr { |
5202 | 5235 | p := &pr[j] |
5203 | 5236 | 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) { | |
5205 | 5238 | continue |
5206 | 5239 | } |
5207 | 5240 | 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) { | ||
5212 | 5245 | continue |
5213 | 5246 | } |
5214 | 5247 | 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)) && | |
5216 | 5249 | getter.hitdef.hitflag&int32(ST_P) != 0 && |
5217 | 5250 | getter.projClsnCheck(p, false) { |
5218 | 5251 | p.hits = -2 |
@@ -5281,7 +5314,7 @@ func (cl *CharList) clsn(getter *Char, proj bool) { | ||
5281 | 5314 | for _, c := range cl.runOrder { |
5282 | 5315 | contact := 0 |
5283 | 5316 | 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)) { | |
5285 | 5318 | dist := -getter.distX(c, getter) * c.facing |
5286 | 5319 | if c.ss.moveType == MT_A && dist >= 0 && dist <= c.attackDist { |
5287 | 5320 | getter.inguarddist = true |
@@ -5350,7 +5383,7 @@ func (cl *CharList) clsn(getter *Char, proj bool) { | ||
5350 | 5383 | } |
5351 | 5384 | } |
5352 | 5385 | } |
5353 | - if getter.playerNo&1 != c.playerNo&1 && getter.sf(CSF_playerpush) && | |
5386 | + if getter.teamside != c.teamside && getter.sf(CSF_playerpush) && | |
5354 | 5387 | c.sf(CSF_playerpush) && (getter.ss.stateType == ST_A || |
5355 | 5388 | getter.pos[1]*getter.localscl-c.pos[1]*c.localscl < getter.height()*c.localscl) && |
5356 | 5389 | (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 { | ||
5457 | 5490 | } |
5458 | 5491 | } |
5459 | 5492 | for _, e := range cl.runOrder { |
5460 | - if e.player && e.playerNo&1 != c.playerNo&1 && | |
5493 | + if e.player && e.teamside != c.teamside && | |
5461 | 5494 | (p2 && !e.scf(SCF_ko_round_middle) || !p2 && e.helperIndex == 0) { |
5462 | 5495 | add(e, 0) |
5463 | 5496 | } |
@@ -4088,6 +4088,10 @@ func (c *Compiler) hitDefSub(is IniSection, | ||
4088 | 4088 | }); err != nil { |
4089 | 4089 | return err |
4090 | 4090 | } |
4091 | + if err := c.paramValue(is, sc, "teamside", | |
4092 | + hitDef_teamside, VT_Int, 1, false); err != nil { | |
4093 | + return err | |
4094 | + } | |
4091 | 4095 | if err := c.paramValue(is, sc, "id", |
4092 | 4096 | hitDef_id, VT_Int, 1, false); err != nil { |
4093 | 4097 | return err |
@@ -7211,7 +7215,7 @@ func (c *Compiler) Compile(pn int, def string) (map[int32]StateBytecode, | ||
7211 | 7215 | return nil, err |
7212 | 7216 | } |
7213 | 7217 | 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) | |
7215 | 7219 | b := NewCommandBuffer() |
7216 | 7220 | for i := range sys.chars[pn][0].cmd { |
7217 | 7221 | sys.chars[pn][0].cmd[i] = *NewCommandList(b) |
@@ -1011,7 +1011,7 @@ type NetInput struct { | ||
1011 | 1011 | st NetState |
1012 | 1012 | sendEnd chan bool |
1013 | 1013 | recvEnd chan bool |
1014 | - buf [MaxSimul * 2]NetBuffer | |
1014 | + buf [MaxSimul*2 + MaxAttachedChar]NetBuffer | |
1015 | 1015 | locIn int |
1016 | 1016 | remIn int |
1017 | 1017 | time int32 |
@@ -207,7 +207,7 @@ func scriptCommonInit(l *lua.LState) { | ||
207 | 207 | }) |
208 | 208 | luaRegister(l, "setAutoguard", func(l *lua.LState) int { |
209 | 209 | pn := int(numArg(l, 1)) |
210 | - if pn < 1 || pn > MaxSimul*2 { | |
210 | + if pn < 1 || pn > MaxSimul*2+MaxAttachedChar { | |
211 | 211 | l.RaiseError("プレイヤー番号(%v)が不正です。", pn) |
212 | 212 | } |
213 | 213 | sys.autoguard[pn-1] = boolArg(l, 2) |
@@ -454,7 +454,7 @@ func systemScriptInit(l *lua.LState) { | ||
454 | 454 | }) |
455 | 455 | luaRegister(l, "setCom", func(*lua.LState) int { |
456 | 456 | pn := int(numArg(l, 1)) |
457 | - if pn < 1 || pn > MaxSimul*2 { | |
457 | + if pn < 1 || pn > MaxSimul*2+MaxAttachedChar { | |
458 | 458 | l.RaiseError("プレイヤー番号(%v)が不正です。", pn) |
459 | 459 | } |
460 | 460 | sys.com[pn-1] = Max(0, int32(numArg(l, 2))) |
@@ -1713,7 +1713,7 @@ func triggerScriptInit(l *lua.LState) { | ||
1713 | 1713 | return 1 |
1714 | 1714 | }) |
1715 | 1715 | 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)) | |
1717 | 1717 | return 1 |
1718 | 1718 | }) |
1719 | 1719 | luaRegister(l, "leftedge", func(*lua.LState) int { |
@@ -19,9 +19,10 @@ import ( | ||
19 | 19 | ) |
20 | 20 | |
21 | 21 | const ( |
22 | - MaxSimul = 4 | |
23 | - FPS = 60 | |
24 | - P1P3Dist = 25 | |
22 | + MaxSimul = 4 | |
23 | + MaxAttachedChar = 2 | |
24 | + FPS = 60 | |
25 | + P1P3Dist = 25 | |
25 | 26 | ) |
26 | 27 | |
27 | 28 | var sys = System{ |
@@ -96,15 +97,15 @@ type System struct { | ||
96 | 97 | keySatate map[glfw.Key]bool |
97 | 98 | netInput *NetInput |
98 | 99 | fileInput *FileInput |
99 | - aiInput [MaxSimul * 2]AiInput | |
100 | + aiInput [MaxSimul*2 + MaxAttachedChar]AiInput | |
100 | 101 | keyConfig []KeyConfig |
101 | 102 | JoystickConfig []KeyConfig |
102 | - com [MaxSimul * 2]int32 | |
103 | + com [MaxSimul*2 + MaxAttachedChar]int32 | |
103 | 104 | autolevel bool |
104 | 105 | home int |
105 | 106 | gameTime int32 |
106 | 107 | match int32 |
107 | - inputRemap [MaxSimul * 2]int | |
108 | + inputRemap [MaxSimul*2 + MaxAttachedChar]int | |
108 | 109 | listenPort string |
109 | 110 | round int32 |
110 | 111 | intro int32 |
@@ -115,15 +116,15 @@ type System struct { | ||
115 | 116 | roundsExisted [2]int32 |
116 | 117 | draws int32 |
117 | 118 | loader Loader |
118 | - chars [MaxSimul * 2][]*Char | |
119 | + chars [MaxSimul*2 + MaxAttachedChar][]*Char | |
119 | 120 | charList CharList |
120 | - cgi [MaxSimul * 2]CharGlobalInfo | |
121 | + cgi [MaxSimul*2 + MaxAttachedChar]CharGlobalInfo | |
121 | 122 | tmode [2]TeamMode |
122 | 123 | numSimul, numTurns [2]int32 |
123 | 124 | esc bool |
124 | 125 | loadMutex sync.Mutex |
125 | 126 | ignoreMostErrors bool |
126 | - stringPool [MaxSimul * 2]StringPool | |
127 | + stringPool [MaxSimul*2 + MaxAttachedChar]StringPool | |
127 | 128 | bcStack, bcVarStack BytecodeStack |
128 | 129 | bcVar []BytecodeValue |
129 | 130 | workingChar *Char |
@@ -153,7 +154,7 @@ type System struct { | ||
153 | 154 | envcol [3]int32 |
154 | 155 | envcol_time int32 |
155 | 156 | envcol_under bool |
156 | - clipboardText [MaxSimul * 2][]string | |
157 | + clipboardText [MaxSimul*2 + MaxAttachedChar][]string | |
157 | 158 | stage *Stage |
158 | 159 | helperMax int32 |
159 | 160 | nextCharId int32 |
@@ -183,10 +184,10 @@ type System struct { | ||
183 | 184 | finish FinishType |
184 | 185 | waitdown int32 |
185 | 186 | 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 | |
190 | 191 | changeStateNest int32 |
191 | 192 | sprites DrawList |
192 | 193 | topSprites DrawList |
@@ -196,7 +197,7 @@ type System struct { | ||
196 | 197 | drawc2sp ClsnRect |
197 | 198 | drawc2mtk ClsnRect |
198 | 199 | drawwh ClsnRect |
199 | - autoguard [MaxSimul * 2]bool | |
200 | + autoguard [MaxSimul*2 + MaxAttachedChar]bool | |
200 | 201 | clsnDraw bool |
201 | 202 | accel float32 |
202 | 203 | statusDraw bool |
@@ -910,7 +911,7 @@ func (s *System) action(x, y *float32, scl float32) (leftest, rightest, | ||
910 | 911 | ko := [...]bool{true, true} |
911 | 912 | for ii := range ko { |
912 | 913 | 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 { | |
914 | 915 | ko[ii] = false |
915 | 916 | break |
916 | 917 | } |
@@ -1679,7 +1680,7 @@ type SelectChar struct { | ||
1679 | 1680 | sportrait, lportrait, vsportrait, vportrait *Sprite |
1680 | 1681 | } |
1681 | 1682 | type SelectStage struct { |
1682 | - def, name, zoomout, zoomin, bgmusic, bgmvolume string | |
1683 | + def, name, zoomout, zoomin, bgmusic, bgmvolume, attachedchardef string | |
1683 | 1684 | } |
1684 | 1685 | type Select struct { |
1685 | 1686 | columns, rows int |
@@ -1869,6 +1870,7 @@ func (s *Select) AddStage(def string) error { | ||
1869 | 1870 | ss.name = def |
1870 | 1871 | } |
1871 | 1872 | } |
1873 | + ss.attachedchardef, ok = is.getString("attachedchar") | |
1872 | 1874 | } |
1873 | 1875 | case "camera": |
1874 | 1876 | if camera { |
@@ -1993,6 +1995,7 @@ func (l *Loader) loadChar(pn int) int { | ||
1993 | 1995 | } |
1994 | 1996 | p.memberNo = memberNo |
1995 | 1997 | p.selectNo = sys.sel.selected[pn&1][memberNo][0] |
1998 | + p.teamside = p.playerNo & 1 | |
1996 | 1999 | sys.chars[pn] = make([]*Char, 1) |
1997 | 2000 | sys.chars[pn][0] = p |
1998 | 2001 | if sys.cgi[pn].sff == nil { |
@@ -2026,13 +2029,53 @@ func (l *Loader) loadChar(pn int) int { | ||
2026 | 2029 | } |
2027 | 2030 | return 1 |
2028 | 2031 | } |
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 | + | |
2029 | 2070 | func (l *Loader) loadStage() bool { |
2030 | 2071 | if sys.round == 1 { |
2031 | 2072 | var def string |
2032 | 2073 | 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 | |
2034 | 2076 | } else { |
2035 | 2077 | def = sys.sel.stagelist[sys.sel.selectedStageNo-1].def |
2078 | + l.loadAttachedChar(0, sys.sel.stagelist[sys.sel.selectedStageNo-1].attachedchardef) | |
2036 | 2079 | } |
2037 | 2080 | if sys.stage != nil && sys.stage.def == def { |
2038 | 2081 | return true |