• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

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

Go で書き直した Ikemen


Commit MetaInfo

Revisãod8bc640e1564e1f073a8a643ad8a6d3fbe3c22af (tree)
Hora2017-01-04 00:26:06
AutorSUEHIRO <supersuehiro@user...>
CommiterSUEHIRO

Mensagem de Log

スタンドアロンで動かすために必要な common1 を書いていく

Mudança Sumário

Diff

--- a/data/common1.cns.zss
+++ b/data/common1.cns.zss
@@ -6,6 +6,9 @@
66 # ignorehitpause{} を含んでいる if も実行される
77 # Explod は ignorehitpause を任意に指定できる
88 # ignorehitpause persistent(2) if 1 {} ブロックの特性を複数指定 if は最後に
9+# VarSet, VarAdd は使えない代わりに := による代入を含む式を書ける
10+# 代入式は末尾に ; をつける
11+
912
1013 [Statedef 0; type: S; physics: S;
1114 sprpriority: 0;]
@@ -15,7 +18,7 @@ if cond(Anim = 5, AnimTime = 0, Anim != 0) {
1518 if Time = 0 {
1619 VelSet{y: 0}
1720 }
18-if Time = 4 || abs(vel x) < cond(MajorVersion = 1,
21+if Time = 4 || abs(vel x) < ifelse(MajorVersion = 1,
1922 Const(movement.stand.friction.threshold), 2) {
2023 VelSet{x: 0}
2124 }
@@ -23,6 +26,7 @@ if !alive {
2326 ChangeState{value: 5050; ctrl: 0}
2427 }
2528
29+
2630 [Statedef 10; type: C; physics: C;
2731 anim: 10;]
2832 if Time = 0 {
@@ -35,6 +39,7 @@ if AnimTime = 0 {
3539 ChangeState{value: 11}
3640 }
3741
42+
3843 [Statedef 11; type: C; physics: C;
3944 anim: 11; sprpriority: 0;]
4045 if Anim = 6 && AnimTime = 0 {
@@ -44,12 +49,14 @@ if abs(vel x) < Const(movement.crouch.friction.threshold) {
4449 VelSet{x: 0}
4550 }
4651
52+
4753 [Statedef 12; type: S; physics: S;
4854 anim: 12;]
4955 if AnimTime = 0 {
5056 ChangeState{value: 0}
5157 }
5258
59+
5360 [Statedef 20; type: S; physics: S;
5461 sprpriority: 0;]
5562 if command = "holdback" {
@@ -67,3 +74,123 @@ if vel x > 0 {
6774 }
6875 }
6976
77+
78+[Statedef 40; type: S; physics: S;
79+ anim: 40; ctrl: 0; sprpriority: 1; facep2: 1;]
80+if Time = 0 {
81+ sysvar(1) := 0;
82+}
83+if command = "holdback" {
84+ sysvar(1) := -1;
85+} else if command = "holdfwd" {
86+ sysvar(1) := 1;
87+}
88+if AnimTime = 0 {
89+ if sysvar(1) = 0 {
90+ VelSet{x: const(velocity.jump.neu.x)}
91+ } else if sysvar(1) = 1 {
92+ if prevstateno = 100 {
93+ VelSet{x: const(velocity.runjump.fwd.x)}
94+ } else {
95+ VelSet{x: const(velocity.jump.fwd.x)}
96+ }
97+ } else {
98+ VelSet{x: const(velocity.jump.back.x)}
99+ }
100+ VelSet{y: const(velocity.jump.y)}
101+ ChangeState{value: 50; ctrl: 1}
102+}
103+
104+
105+[Statedef 45; type: A; physics: N;
106+ ctrl: 0; velset: 0, 0;]
107+ChangeAnim{value: ifelse(SelfAnimExist(44), 44, 41)}
108+if Time = 0 {
109+ sysvar(1) := 0;
110+}
111+if command = "holdback" {
112+ sysvar(1) := -1;
113+} else if command = "holdfwd" {
114+ sysvar(1) := 1;
115+}
116+if Time = 2 {
117+ if sysvar(1) = 0 {
118+ VelSet{x: const(velocity.airjump.neu.x)}
119+ } else if sysvar(1) = 1 {
120+ VelSet{x: const(velocity.airjump.fwd.x)}
121+ } else {
122+ VelSet{x: const(velocity.airjump.back.x)}
123+ }
124+ VelSet{y: const(velocity.airjump.y)}
125+ ChangeState{value: 50; ctrl: 1}
126+}
127+
128+
129+[Statedef 50; type: A; physics: A;]
130+if Time = 0 {
131+ sysvar(1) := 0;
132+ ChangeAnim{value: cond((vel x) = 0, 41, ifelse((vel x) > 0, 42, 43))}
133+}
134+if Vel y > Const240p(-2) && SelfAnimExist(anim + 3) && anim = [41, 43] {
135+ ChangeAnim{value: Anim + 3}
136+}
137+
138+
139+[Statedef 51; type: A; physics: A;]
140+
141+
142+[Statedef 52; type: S; physics: S;
143+ ctrl: 0; anim: 47;]
144+if Time = 0 {
145+ VelSet{y: 0}
146+ PosSet{y: 0}
147+} else if Time = 3 {
148+ CtrlSet{value: 1}
149+}
150+if MajorVersion = 1 && abs(vel x) < Const(movement.stand.friction.threshold){
151+ VelSet{x: 0}
152+}
153+if AnimTime = 0 {
154+ ChangeState{value: 0; ctrl: 1}
155+}
156+
157+
158+[Statedef 100; type: S; physics: S;
159+ anim: 100; sprpriority: 1;]
160+VelSet{x: const(velocity.run.fwd.x)}
161+AssertSpecial{flag: NoWalk; flag2: NoAutoTurn}
162+if command != "holdfwd" {
163+ ChangeState{value: 0}
164+}
165+
166+
167+[Statedef 105; type: A; physics: A;
168+ ctrl: 0; anim: 105; sprpriority: 1;]
169+if Time = 0 {
170+ VelSet{x: const(velocity.run.back.x); y: const(velocity.run.back.y)}
171+}else if Time = 2 {
172+ CtrlSet{value: 1}
173+}
174+if Vel Y > 0 && Pos Y >= 0 {
175+ ChangeState{value: 106}
176+}
177+
178+
179+[Statedef 106; type: S; physics: S;
180+ ctrl: 0; anim: 47;]
181+if MajorVersion = 1 && abs(vel x) < Const(movement.stand.friction.threshold) {
182+ VelSet{x: 0}
183+}
184+if Time = 0 {
185+ VelSet{y: 0}
186+ PosSet{y: 0}
187+} else if Time = 2 {
188+ if MajorVersion = 1 {
189+ MakeDust{pos: 0, 0; spacing: 1}
190+ } else {
191+ MakeDust{pos: -5, -2; spacing: 1}
192+ }
193+} else if Time = 7 {
194+ ChangeState{value: 0; ctrl: 1}
195+}
196+
--- a/src/bytecode.go
+++ b/src/bytecode.go
@@ -953,6 +953,8 @@ func (be BytecodeExp) run(c *Char) BytecodeValue {
953953 sys.bcStack.PushI(c.time())
954954 case OC_alive:
955955 sys.bcStack.PushB(c.alive())
956+ case OC_ctrl:
957+ sys.bcStack.PushB(c.canCtrl())
956958 case OC_random:
957959 sys.bcStack.PushI(Rand(0, 999))
958960 case OC_roundstate:
@@ -1019,17 +1021,28 @@ func (be BytecodeExp) run(c *Char) BytecodeValue {
10191021 sys.bcStack.PushF(c.bottomEdge())
10201022 case OC_power:
10211023 sys.bcStack.PushI(c.getPower())
1024+ case OC_roundsexisted:
1025+ sys.bcStack.PushI(c.roundsExisted())
1026+ case OC_gametime:
1027+ sys.bcStack.PushI(sys.gameTime)
1028+ case OC_hitfall:
1029+ sys.bcStack.PushB(c.ghv.fallf)
10221030 case OC_ishelper:
10231031 *sys.bcStack.Top() = c.isHelper(*sys.bcStack.Top())
10241032 case OC_numhelper:
10251033 *sys.bcStack.Top() = c.numHelper(*sys.bcStack.Top())
1026- case OC_roundsexisted:
1027- sys.bcStack.PushI(c.roundsExisted())
10281034 case OC_teammode:
10291035 sys.bcStack.PushB(sys.tmode[c.playerNo&1] == TeamMode(be[i]))
10301036 i++
1031- case OC_ctrl:
1032- sys.bcStack.PushB(c.canCtrl())
1037+ case OC_statetype:
1038+ sys.bcStack.PushB(c.ss.sb.stateType == StateType(be[i]))
1039+ i++
1040+ case OC_movetype:
1041+ sys.bcStack.PushB(c.ss.sb.moveType == MoveType(be[i]))
1042+ i++
1043+ case OC_hitdefattr:
1044+ sys.bcStack.PushB(c.hitDefAttr(*(*int32)(unsafe.Pointer(&be[i]))))
1045+ i += 4
10331046 case OC_st_:
10341047 be.run_st(c, &i)
10351048 case OC_const_:
@@ -1459,6 +1472,13 @@ func (b StateBlock) Run(c *Char, ps []int32) (changeState bool) {
14591472 return false
14601473 }
14611474
1475+type StateExpr BytecodeExp
1476+
1477+func (se StateExpr) Run(c *Char, _ []int32) (changeState bool) {
1478+ BytecodeExp(se).run(c)
1479+ return false
1480+}
1481+
14621482 type StateControllerBase []byte
14631483
14641484 func newStateControllerBase() *StateControllerBase {
@@ -3964,6 +3984,56 @@ func (sc envColor) Run(c *Char, _ []int32) bool {
39643984 return false
39653985 }
39663986
3987+type displayToClipboard StateControllerBase
3988+
3989+const (
3990+ displayToClipboard_params byte = iota
3991+ displayToClipboard_text
3992+)
3993+
3994+func (sc displayToClipboard) Run(c *Char, _ []int32) bool {
3995+ params := []interface{}{}
3996+ StateControllerBase(sc).run(c, func(id byte, exp []BytecodeExp) bool {
3997+ switch id {
3998+ case displayToClipboard_params:
3999+ for _, e := range exp {
4000+ if bv := e.run(c); bv.t == VT_Float {
4001+ params = append(params, bv.ToF())
4002+ } else {
4003+ params = append(params, bv.ToI())
4004+ }
4005+ }
4006+ case displayToClipboard_text:
4007+ sys.clipboardText[c.ss.sb.playerNo] = nil
4008+ sys.appendToClipboard(c.ss.sb.playerNo, int(exp[0].evalI(c)), params...)
4009+ }
4010+ return true
4011+ })
4012+ return false
4013+}
4014+
4015+type appendToClipboard displayToClipboard
4016+
4017+func (sc appendToClipboard) Run(c *Char, _ []int32) bool {
4018+ params := []interface{}{}
4019+ StateControllerBase(sc).run(c, func(id byte, exp []BytecodeExp) bool {
4020+ switch id {
4021+ case displayToClipboard_params:
4022+ for _, e := range exp {
4023+ if bv := e.run(c); bv.t == VT_Float {
4024+ params = append(params, bv.ToF())
4025+ } else {
4026+ params = append(params, bv.ToI())
4027+ }
4028+ }
4029+ case displayToClipboard_text:
4030+ sys.appendToClipboard(c.ss.sb.playerNo, int(exp[0].evalI(c)), params...)
4031+ }
4032+ return true
4033+ })
4034+ return false
4035+}
4036+
39674037 type StateBytecode struct {
39684038 stateType StateType
39694039 moveType MoveType
--- a/src/char.go
+++ b/src/char.go
@@ -478,6 +478,10 @@ func (hd *HitDef) invalidate(stateType StateType) {
478478 hd.reversal_attr |= -1 << 31
479479 hd.lhit = false
480480 }
481+func (hd *HitDef) testAttr(attr int32) bool {
482+ attr &= hd.attr
483+ return attr&int32(ST_MASK) != 0 && attr&^int32(ST_MASK)&^(-1<<31) != 0
484+}
481485
482486 type GetHitVar struct {
483487 hitBy [][2]int32
@@ -1881,3 +1885,6 @@ func (c *Char) canCtrl() bool {
18811885 func (c *Char) win() bool {
18821886 return sys.winTeam == c.playerNo&1
18831887 }
1888+func (c *Char) hitDefAttr(attr int32) bool {
1889+ return c.ss.sb.moveType == MT_A && c.hitdef.testAttr(attr)
1890+}
--- a/src/compiler.go
+++ b/src/compiler.go
@@ -30,67 +30,69 @@ type Compiler struct {
3030 func newCompiler() *Compiler {
3131 c := &Compiler{}
3232 c.scmap = map[string]scFunc{
33- "hitby": c.hitBy,
34- "nothitby": c.notHitBy,
35- "assertspecial": c.assertSpecial,
36- "playsnd": c.playSnd,
37- "changestate": c.changeState,
38- "selfstate": c.selfState,
39- "tagin": c.tagIn,
40- "tagout": c.tagOut,
41- "destroyself": c.destroySelf,
42- "changeanim": c.changeAnim,
43- "changeanim2": c.changeAnim2,
44- "helper": c.helper,
45- "ctrlset": c.ctrlSet,
46- "explod": c.explod,
47- "modifyexplod": c.modifyExplod,
48- "gamemakeanim": c.gameMakeAnim,
49- "posset": c.posSet,
50- "posadd": c.posAdd,
51- "velset": c.velSet,
52- "veladd": c.velAdd,
53- "velmul": c.velMul,
54- "palfx": c.palFX,
55- "allpalfx": c.allPalFX,
56- "bgpalfx": c.bgPalFX,
57- "afterimage": c.afterImage,
58- "afterimagetime": c.afterImageTime,
59- "hitdef": c.hitDef,
60- "reversaldef": c.reversalDef,
61- "projectile": c.projectile,
62- "width": c.width,
63- "sprpriority": c.sprPriority,
64- "varset": c.varSet,
65- "varadd": c.varAdd,
66- "parentvarset": c.parentVarSet,
67- "parentvaradd": c.parentVarAdd,
68- "turn": c.turn,
69- "targetfacing": c.targetFacing,
70- "targetbind": c.targetBind,
71- "bindtotarget": c.bindToTarget,
72- "targetlifeadd": c.targetLifeAdd,
73- "targetstate": c.targetState,
74- "targetvelset": c.targetVelSet,
75- "targetveladd": c.targetVelAdd,
76- "targetpoweradd": c.targetPowerAdd,
77- "targetdrop": c.targetDrop,
78- "lifeadd": c.lifeAdd,
79- "lifeset": c.lifeSet,
80- "poweradd": c.powerAdd,
81- "powerset": c.powerSet,
82- "hitvelset": c.hitVelSet,
83- "screenbound": c.screenBound,
84- "posfreeze": c.posFreeze,
85- "envshake": c.envShake,
86- "hitoverride": c.hitOverride,
87- "pause": c.pause,
88- "superpause": c.superPause,
89- "trans": c.trans,
90- "playerpush": c.playerPush,
91- "statetypeset": c.stateTypeSet,
92- "angledraw": c.angleDraw,
93- "envcolor": c.envColor,
33+ "hitby": c.hitBy,
34+ "nothitby": c.notHitBy,
35+ "assertspecial": c.assertSpecial,
36+ "playsnd": c.playSnd,
37+ "changestate": c.changeState,
38+ "selfstate": c.selfState,
39+ "tagin": c.tagIn,
40+ "tagout": c.tagOut,
41+ "destroyself": c.destroySelf,
42+ "changeanim": c.changeAnim,
43+ "changeanim2": c.changeAnim2,
44+ "helper": c.helper,
45+ "ctrlset": c.ctrlSet,
46+ "explod": c.explod,
47+ "modifyexplod": c.modifyExplod,
48+ "gamemakeanim": c.gameMakeAnim,
49+ "posset": c.posSet,
50+ "posadd": c.posAdd,
51+ "velset": c.velSet,
52+ "veladd": c.velAdd,
53+ "velmul": c.velMul,
54+ "palfx": c.palFX,
55+ "allpalfx": c.allPalFX,
56+ "bgpalfx": c.bgPalFX,
57+ "afterimage": c.afterImage,
58+ "afterimagetime": c.afterImageTime,
59+ "hitdef": c.hitDef,
60+ "reversaldef": c.reversalDef,
61+ "projectile": c.projectile,
62+ "width": c.width,
63+ "sprpriority": c.sprPriority,
64+ "varset": c.varSet,
65+ "varadd": c.varAdd,
66+ "parentvarset": c.parentVarSet,
67+ "parentvaradd": c.parentVarAdd,
68+ "turn": c.turn,
69+ "targetfacing": c.targetFacing,
70+ "targetbind": c.targetBind,
71+ "bindtotarget": c.bindToTarget,
72+ "targetlifeadd": c.targetLifeAdd,
73+ "targetstate": c.targetState,
74+ "targetvelset": c.targetVelSet,
75+ "targetveladd": c.targetVelAdd,
76+ "targetpoweradd": c.targetPowerAdd,
77+ "targetdrop": c.targetDrop,
78+ "lifeadd": c.lifeAdd,
79+ "lifeset": c.lifeSet,
80+ "poweradd": c.powerAdd,
81+ "powerset": c.powerSet,
82+ "hitvelset": c.hitVelSet,
83+ "screenbound": c.screenBound,
84+ "posfreeze": c.posFreeze,
85+ "envshake": c.envShake,
86+ "hitoverride": c.hitOverride,
87+ "pause": c.pause,
88+ "superpause": c.superPause,
89+ "trans": c.trans,
90+ "playerpush": c.playerPush,
91+ "statetypeset": c.stateTypeSet,
92+ "angledraw": c.angleDraw,
93+ "envcolor": c.envColor,
94+ "displaytoclipboard": c.displayToClipboard,
95+ "appendtoclipboard": c.appendToClipboard,
9496 }
9597 return c
9698 }
@@ -406,6 +408,80 @@ func (c *Compiler) attr(text string, hitdef bool) (int32, error) {
406408 }
407409 return flg, nil
408410 }
411+func (c *Compiler) trgAttr(in *string) (int32, error) {
412+ flg := int32(0)
413+ *in = strings.TrimSpace(*in)
414+ i := strings.IndexAny(*in, kuuhaktokigou)
415+ var att string
416+ if i >= 0 {
417+ att = (*in)[:i]
418+ *in = strings.TrimSpace((*in)[i:])
419+ } else {
420+ att = *in
421+ *in = ""
422+ }
423+ for _, a := range att {
424+ switch a {
425+ case 'S', 's':
426+ flg |= int32(ST_S)
427+ case 'C', 'c':
428+ flg |= int32(ST_C)
429+ case 'A', 'a':
430+ flg |= int32(ST_A)
431+ default:
432+ return 0, Error(att + "が不正な属性値です")
433+ }
434+ }
435+ for len(*in) > 0 && (*in)[0] == ',' {
436+ oldin := *in
437+ *in = strings.TrimSpace((*in)[1:])
438+ i := strings.IndexAny(*in, kuuhaktokigou)
439+ var att string
440+ if i >= 0 {
441+ att = (*in)[:i]
442+ *in = strings.TrimSpace((*in)[i:])
443+ } else {
444+ att = *in
445+ *in = ""
446+ }
447+ switch strings.ToLower(att) {
448+ case "na":
449+ flg |= int32(AT_NA)
450+ case "nt":
451+ flg |= int32(AT_NT)
452+ case "np":
453+ flg |= int32(AT_NP)
454+ case "sa":
455+ flg |= int32(AT_SA)
456+ case "st":
457+ flg |= int32(AT_ST)
458+ case "sp":
459+ flg |= int32(AT_SP)
460+ case "ha":
461+ flg |= int32(AT_HA)
462+ case "ht":
463+ flg |= int32(AT_HT)
464+ case "hp":
465+ flg |= int32(AT_HP)
466+ case "aa":
467+ flg |= int32(AT_AA)
468+ case "at":
469+ flg |= int32(AT_AT)
470+ case "ap":
471+ flg |= int32(AT_AP)
472+ case "n":
473+ flg |= int32(AT_NA | AT_NT | AT_NP)
474+ case "s":
475+ flg |= int32(AT_SA | AT_ST | AT_SP)
476+ case "h", "a":
477+ flg |= int32(AT_HA | AT_HT | AT_HP)
478+ default:
479+ *in = oldin
480+ return flg, nil
481+ }
482+ }
483+ return flg, nil
484+}
409485 func (c *Compiler) kakkohiraku(in *string) error {
410486 if c.tokenizer(in) != "(" {
411487 return Error(c.token + "の次に'('がありません")
@@ -657,15 +733,13 @@ func (c *Compiler) expValue(out *BytecodeExp, in *string,
657733 c.token = c.tokenizer(in)
658734 return bv, nil
659735 }
660- if !sys.ignoreMostErrors {
661- defer func() { c.usiroOp = false }()
662- }
663736 _var := func(sys, f bool) error {
664737 bv1, err := c.oneArg(out, in, rd, false)
665738 if err != nil {
666739 return err
667740 }
668741 var oc OpCode
742+ c.token = c.tokenizer(in)
669743 set, _else := c.token == ":=", false
670744 if !bv1.IsNone() && bv1.ToI() >= 0 {
671745 switch [2]bool{sys, f} {
@@ -751,6 +825,16 @@ func (c *Compiler) expValue(out *BytecodeExp, in *string,
751825 }
752826 return nil
753827 }
828+ eqne2 := func(f func(not bool) error) error {
829+ not, err := c.kyuushiki(in)
830+ if err != nil {
831+ return err
832+ }
833+ if err := f(not); err != nil {
834+ return err
835+ }
836+ return nil
837+ }
754838 var be1, be2, be3 BytecodeExp
755839 var bv1, bv2, bv3 BytecodeValue
756840 var n int32
@@ -889,21 +973,13 @@ func (c *Compiler) expValue(out *BytecodeExp, in *string,
889973 return bvNone(), err
890974 }
891975 case "var":
892- if err := _var(false, false); err != nil {
893- return bvNone(), err
894- }
976+ return bvNone(), _var(false, false)
895977 case "fvar":
896- if err := _var(false, true); err != nil {
897- return bvNone(), err
898- }
978+ return bvNone(), _var(false, true)
899979 case "sysvar":
900- if err := _var(true, false); err != nil {
901- return bvNone(), err
902- }
980+ return bvNone(), _var(true, false)
903981 case "sysfvar":
904- if err := _var(true, true); err != nil {
905- return bvNone(), err
906- }
982+ return bvNone(), _var(true, true)
907983 case "ifelse", "cond":
908984 cond := c.token == "cond"
909985 if err := c.kakkohiraku(in); err != nil {
@@ -971,10 +1047,12 @@ func (c *Compiler) expValue(out *BytecodeExp, in *string,
9711047 bv = bv3
9721048 }
9731049 }
974- case "time":
1050+ case "time", "statetime":
9751051 out.append(OC_time)
9761052 case "alive":
9771053 out.append(OC_alive)
1054+ case "ctrl":
1055+ out.append(OC_ctrl)
9781056 case "random":
9791057 out.append(OC_random)
9801058 case "roundstate":
@@ -1005,8 +1083,10 @@ func (c *Compiler) expValue(out *BytecodeExp, in *string,
10051083 case "animtime":
10061084 out.append(OC_animtime)
10071085 case "animelem":
1008- if _, err = c.kyuushiki(in); err != nil {
1086+ if not, err := c.kyuushiki(in); err != nil {
10091087 return bvNone(), err
1088+ } else if not && !sys.ignoreMostErrors {
1089+ return bvNone(), Error("animelemに != は使えません")
10101090 }
10111091 if c.token == "-" {
10121092 return bvNone(), Error("マイナスが付くとエラーです")
@@ -1161,6 +1241,14 @@ func (c *Compiler) expValue(out *BytecodeExp, in *string,
11611241 out.append(OC_bottomedge)
11621242 case "power":
11631243 out.append(OC_power)
1244+ case "roundsexisted":
1245+ out.append(OC_roundsexisted)
1246+ case "gametime":
1247+ out.append(OC_gametime)
1248+ case "hitfall":
1249+ out.append(OC_hitfall)
1250+ case "win":
1251+ out.append(OC_ex_, OC_ex_win)
11641252 case "ishelper":
11651253 if _, err := c.oneArg(out, in, rd, true, BytecodeInt(-1)); err != nil {
11661254 return bvNone(), err
@@ -1171,10 +1259,11 @@ func (c *Compiler) expValue(out *BytecodeExp, in *string,
11711259 return bvNone(), err
11721260 }
11731261 out.append(OC_numhelper)
1174- case "roundsexisted":
1175- out.append(OC_roundsexisted)
11761262 case "teammode":
11771263 if err := eqne(func() error {
1264+ if len(c.token) == 0 {
1265+ return Error("teammodeの値が指定されていません")
1266+ }
11781267 var tm TeamMode
11791268 switch c.token {
11801269 case "single":
@@ -1191,10 +1280,90 @@ func (c *Compiler) expValue(out *BytecodeExp, in *string,
11911280 }); err != nil {
11921281 return bvNone(), err
11931282 }
1194- case "win":
1195- out.append(OC_ex_, OC_ex_win)
1196- case "ctrl":
1197- out.append(OC_ctrl)
1283+ case "statetype", "p2statetype":
1284+ trname := c.token
1285+ if err := eqne2(func(not bool) error {
1286+ if len(c.token) == 0 {
1287+ return Error(trname + "の値が指定されていません")
1288+ }
1289+ var st StateType
1290+ switch c.token[0] {
1291+ case 's':
1292+ st = ST_S
1293+ case 'c':
1294+ st = ST_C
1295+ case 'a':
1296+ st = ST_A
1297+ case 'l':
1298+ st = ST_L
1299+ default:
1300+ return Error(c.token + "が無効な値です")
1301+ }
1302+ if trname == "p2statetype" {
1303+ out.appendI32Op(OC_p2, 2+Btoi(not))
1304+ }
1305+ out.append(OC_statetype, OpCode(st))
1306+ if not {
1307+ out.append(OC_blnot)
1308+ }
1309+ return nil
1310+ }); err != nil {
1311+ return bvNone(), err
1312+ }
1313+ case "movetype", "p2movetype":
1314+ trname := c.token
1315+ if err := eqne2(func(not bool) error {
1316+ if len(c.token) == 0 {
1317+ return Error(trname + "の値が指定されていません")
1318+ }
1319+ var mt MoveType
1320+ switch c.token[0] {
1321+ case 'i':
1322+ mt = MT_I
1323+ case 'a':
1324+ mt = MT_A
1325+ case 'h':
1326+ mt = MT_H
1327+ default:
1328+ return Error(c.token + "が無効な値です")
1329+ }
1330+ if trname == "p2movetype" {
1331+ out.appendI32Op(OC_p2, 2+Btoi(not))
1332+ }
1333+ out.append(OC_movetype, OpCode(mt))
1334+ if not {
1335+ out.append(OC_blnot)
1336+ }
1337+ return nil
1338+ }); err != nil {
1339+ return bvNone(), err
1340+ }
1341+ case "hitdefattr":
1342+ hda := func() error {
1343+ if attr, err := c.trgAttr(in); err != nil {
1344+ return err
1345+ } else {
1346+ out.appendI32Op(OC_hitdefattr, attr)
1347+ }
1348+ return nil
1349+ }
1350+ if sys.cgi[c.playerNo].ver[0] == 1 {
1351+ if err := eqne(hda); err != nil {
1352+ return bvNone(), err
1353+ }
1354+ } else {
1355+ if not, err := c.kyuushiki(in); err != nil {
1356+ if sys.ignoreMostErrors {
1357+ out.appendValue(BytecodeBool(false))
1358+ } else {
1359+ return bvNone(), err
1360+ }
1361+ } else if err := hda(); err != nil {
1362+ return bvNone(), err
1363+ } else if not && !sys.ignoreMostErrors {
1364+ return bvNone(), Error("旧バージョンのためhitdefattrに != は使えません")
1365+ }
1366+ }
11981367 case "abs":
11991368 if bv, err = c.mathFunc(out, in, rd, OC_abs, out.abs); err != nil {
12001369 return bvNone(), err
@@ -1356,6 +1525,48 @@ func (c *Compiler) expValue(out *BytecodeExp, in *string,
13561525 if err := c.kakkotojiru(in); err != nil {
13571526 return bvNone(), err
13581527 }
1528+ case "const240p":
1529+ if bv, err = c.oneArg(&be1, in, false, false); err != nil {
1530+ return bvNone(), err
1531+ }
1532+ if bv.IsNone() {
1533+ if rd {
1534+ out.append(OC_rdreset)
1535+ }
1536+ out.append(be1...)
1537+ out.appendValue(BytecodeFloat(1))
1538+ out.append(OC_mul)
1539+ } else {
1540+ out.mul(&bv, BytecodeFloat(1))
1541+ }
1542+ case "const480p":
1543+ if bv, err = c.oneArg(&be1, in, false, false); err != nil {
1544+ return bvNone(), err
1545+ }
1546+ if bv.IsNone() {
1547+ if rd {
1548+ out.append(OC_rdreset)
1549+ }
1550+ out.append(be1...)
1551+ out.appendValue(BytecodeFloat(0.5))
1552+ out.append(OC_mul)
1553+ } else {
1554+ out.mul(&bv, BytecodeFloat(0.5))
1555+ }
1556+ case "const720p":
1557+ if bv, err = c.oneArg(&be1, in, false, false); err != nil {
1558+ return bvNone(), err
1559+ }
1560+ if bv.IsNone() {
1561+ if rd {
1562+ out.append(OC_rdreset)
1563+ }
1564+ out.append(be1...)
1565+ out.appendValue(BytecodeFloat(0.25))
1566+ out.append(OC_mul)
1567+ } else {
1568+ out.mul(&bv, BytecodeFloat(0.25))
1569+ }
13591570 case "const":
13601571 if err := c.kakkohiraku(in); err != nil {
13611572 return bvNone(), err
@@ -1580,19 +1791,21 @@ func (c *Compiler) expPostNot(out *BytecodeExp, in *string) (BytecodeValue,
15801791 if err != nil {
15811792 return bvNone(), err
15821793 }
1583- for c.token == "!" {
1584- c.usiroOp = true
1585- if bv.IsNone() {
1586- out.append(OC_blnot)
1587- } else {
1588- out.blnot(&bv)
1794+ if sys.ignoreMostErrors {
1795+ for c.token == "!" {
1796+ c.usiroOp = true
1797+ if bv.IsNone() {
1798+ out.append(OC_blnot)
1799+ } else {
1800+ out.blnot(&bv)
1801+ }
1802+ c.token = c.tokenizer(in)
15891803 }
1590- c.token = c.tokenizer(in)
15911804 }
15921805 if len(c.maeOp) == 0 {
15931806 opp := c.isOperator(c.token)
15941807 if opp == 0 {
1595- if !c.usiroOp && c.token == "(" {
1808+ if !sys.ignoreMostErrors || !c.usiroOp && c.token == "(" {
15961809 return bvNone(), Error("演算子がありません")
15971810 }
15981811 oldtoken, oldin := c.token, *in
@@ -4842,6 +5055,60 @@ func (c *Compiler) envColor(is IniSection, sc *StateControllerBase,
48425055 })
48435056 return *ret, err
48445057 }
5058+func (c *Compiler) displayToClipboardSub(is IniSection,
5059+ sc *StateControllerBase) error {
5060+ if err := c.stateParam(is, "params", func(data string) error {
5061+ bes, err := c.exprs(data, VT_SFalse, 100000)
5062+ if err != nil {
5063+ return err
5064+ }
5065+ sc.add(displayToClipboard_params, bes)
5066+ return nil
5067+ }); err != nil {
5068+ return err
5069+ }
5070+ b := false
5071+ if err := c.stateParam(is, "text", func(data string) error {
5072+ b = true
5073+ _else := false
5074+ if len(data) >= 2 && data[0] == '"' {
5075+ data = data[1:]
5076+ if i := strings.Index(data, "\""); i >= 0 {
5077+ data = data[:i]
5078+ } else {
5079+ _else = true
5080+ }
5081+ } else {
5082+ _else = true
5083+ }
5084+ if _else {
5085+ return Error("\"で囲まれていません")
5086+ }
5087+ sc.add(displayToClipboard_text,
5088+ sc.iToExp(int32(sys.stringPool[c.playerNo].Add(data))))
5089+ return nil
5090+ }); err != nil {
5091+ return err
5092+ }
5093+ if !b {
5094+ return Error("textが指定されていません")
5095+ }
5096+ return nil
5097+}
5098+func (c *Compiler) displayToClipboard(is IniSection, sc *StateControllerBase,
5099+ _ int8) (StateController, error) {
5100+ ret, err := (*displayToClipboard)(sc), c.stateSec(is, func() error {
5101+ return c.displayToClipboardSub(is, sc)
5102+ })
5103+ return *ret, err
5104+}
5105+func (c *Compiler) appendToClipboard(is IniSection, sc *StateControllerBase,
5106+ _ int8) (StateController, error) {
5107+ ret, err := (*appendToClipboard)(sc), c.stateSec(is, func() error {
5108+ return c.displayToClipboardSub(is, sc)
5109+ })
5110+ return *ret, err
5111+}
48455112 func (c *Compiler) stateCompile(bc *Bytecode, filename, def string) error {
48465113 var str string
48475114 fnz := filename
@@ -5133,16 +5400,19 @@ func (c *Compiler) readString(line *string) (string, error) {
51335400 *line = (*line)[i+1:]
51345401 return s, nil
51355402 }
5136-func (c *Compiler) readSentenceLine(line *string) (s string, err error) {
5403+func (c *Compiler) readSentenceLine(line *string) (s string, assign bool,
5404+ err error) {
51375405 c.token = ""
51385406 offset := 0
51395407 for {
51405408 i := strings.IndexAny((*line)[offset:], ";#\"{}")
51415409 if i < 0 {
5410+ assign = assign || strings.Index((*line)[offset:], ":=") >= 0
51425411 s, *line = *line, ""
51435412 return
51445413 }
51455414 i += offset
5415+ assign = assign || strings.Index((*line)[offset:i], ":=") >= 0
51465416 switch (*line)[i] {
51475417 case ';', '{', '}':
51485418 c.token = (*line)[i : i+1]
@@ -5152,7 +5422,7 @@ func (c *Compiler) readSentenceLine(line *string) (s string, err error) {
51525422 case '"':
51535423 tmp := (*line)[i+1:]
51545424 if _, err := c.readString(&tmp); err != nil {
5155- return "", err
5425+ return "", false, err
51565426 }
51575427 offset = len(*line) - len(tmp)
51585428 continue
@@ -5161,10 +5431,10 @@ func (c *Compiler) readSentenceLine(line *string) (s string, err error) {
51615431 }
51625432 return
51635433 }
5164-func (c *Compiler) readSentence(line *string) (s string, err error) {
5165- sen, err := c.readSentenceLine(line)
5166- if err != nil {
5167- return "", err
5434+func (c *Compiler) readSentence(line *string) (s string, a bool, err error) {
5435+
5436+ if s, a, err = c.readSentenceLine(line); err != nil {
5437+ return
51685438 }
51695439 for c.token == "" {
51705440 var ok bool
@@ -5172,13 +5442,14 @@ func (c *Compiler) readSentence(line *string) (s string, err error) {
51725442 if !ok {
51735443 break
51745444 }
5175- s, err := c.readSentenceLine(line)
5176- if err != nil {
5177- return "", err
5445+ if sen, ass, err := c.readSentenceLine(line); err != nil {
5446+ return "", false, err
5447+ } else {
5448+ s += "\n" + sen
5449+ a = a || ass
51785450 }
5179- sen += "\n" + s
51805451 }
5181- return strings.TrimSpace(sen), nil
5452+ return strings.TrimSpace(s), a, nil
51825453 }
51835454 func (c *Compiler) statementEnd(line *string) error {
51845455 c.token = c.tokenizer(line)
@@ -5201,7 +5472,7 @@ func (c *Compiler) readKeyValue(is IniSection, end string,
52015472 if err := c.needToken(":"); err != nil {
52025473 return err
52035474 }
5204- data, err := c.readSentence(line)
5475+ data, _, err := c.readSentence(line)
52055476 if err != nil {
52065477 return err
52075478 }
@@ -5214,7 +5485,7 @@ func (c *Compiler) subBlock(line *string,
52145485 switch c.token {
52155486 case "{":
52165487 case "if":
5217- expr, err := c.readSentence(line)
5488+ expr, _, err := c.readSentence(line)
52185489 if err != nil {
52195490 return nil, err
52205491 }
@@ -5326,7 +5597,35 @@ func (c *Compiler) stateBlock(line *string, bl *StateBlock, root bool) error {
53265597 }
53275598 c.scan(line)
53285599 continue
5600+ } else {
5601+ otk := c.token
5602+ expr, assign, err := c.readSentence(line)
5603+ if err != nil {
5604+ return err
5605+ }
5606+ expr = otk + " " + expr
5607+ otk = c.token
5608+ if stex, err := c.fullExpression(&expr, VT_SFalse); err != nil {
5609+ return err
5610+ } else {
5611+ bl.ctrls = append(bl.ctrls, StateExpr(stex))
5612+ }
5613+ c.token = otk
5614+ if err := c.needToken(";"); err != nil {
5615+ return err
5616+ }
5617+ if !assign {
5618+ return Error("値が利用されない式")
5619+ }
5620+ if root {
5621+ if err := c.statementEnd(line); err != nil {
5622+ return err
5623+ }
5624+ }
5625+ c.scan(line)
5626+ continue
53295627 }
5628+ case "varset", "varadd":
53305629 }
53315630 break
53325631 }
--- a/src/script.go
+++ b/src/script.go
@@ -139,7 +139,7 @@ func scriptCommonInit(l *lua.LState) {
139139 return 0
140140 })
141141 luaRegister(l, "setHomeTeam", func(l *lua.LState) int {
142- tn := int32(numArg(l, 1))
142+ tn := int(numArg(l, 1))
143143 if tn < 1 || tn > 2 {
144144 l.RaiseError("チーム番号(%v)が不正です。", tn)
145145 }
--- a/src/system.go
+++ b/src/system.go
@@ -1,6 +1,7 @@
11 package main
22
33 import (
4+ "fmt"
45 "github.com/go-gl/gl/v2.1/gl"
56 "github.com/go-gl/glfw/v3.2/glfw"
67 "github.com/timshannon/go-openal/openal"
@@ -82,7 +83,8 @@ type System struct {
8283 keyConfig []*KeyConfig
8384 com [MaxSimul * 2]int32
8485 autolevel bool
85- home int32
86+ home int
87+ gameTime int32
8688 match int32
8789 inputRemap [MaxSimul * 2]int
8890 listenPort string
@@ -133,6 +135,7 @@ type System struct {
133135 envcol [3]int32
134136 envcol_time int32
135137 envcol_under bool
138+ clipboardText [MaxSimul * 2][]string
136139 }
137140
138141 func (s *System) init(w, h int32) *lua.LState {
@@ -240,6 +243,13 @@ func (s *System) setSF(gsf GlobalSpecialFlag) {
240243 func (s *System) unsetSF(gsf GlobalSpecialFlag) {
241244 s.specialFlag &^= gsf
242245 }
246+func (s *System) appendToClipboard(pn, sn int, a ...interface{}) {
247+ spl := s.stringPool[pn].List
248+ if sn >= 0 && sn < len(spl) {
249+ s.clipboardText[pn] = append(s.clipboardText[pn],
250+ strings.Split(fmt.Sprintf(spl[sn], a...), "\n")...)
251+ }
252+}
243253
244254 type SelectChar struct {
245255 def, name string
@@ -488,7 +498,8 @@ func (l *Loader) loadChar(pn int) int {
488498 sys.cgi[pn].palno = pal
489499 }
490500 if sys.cgi[pn].sff == nil {
491- if l.code[pn], l.err = newCompiler().Compile(p.playerNo, cdef); l.err != nil {
501+ if l.code[pn], l.err =
502+ newCompiler().Compile(p.playerNo, cdef); l.err != nil {
492503 sys.chars[pn] = nil
493504 return -1
494505 }