-
Notifications
You must be signed in to change notification settings - Fork 0
/
NRP_CountTimeTurnBattle.js
701 lines (627 loc) · 21.9 KB
/
NRP_CountTimeTurnBattle.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
//=============================================================================
// NRP_CountTimeTurnBattle.js
//=============================================================================
/*:
* @target MZ
* @plugindesc v1.051 A dream battle system that forcefully blends turn-based and CTB.
* @author Takeshi Sunagawa (http://newrpg.seesaa.net/)
* @base NRP_VisualTurn
* @orderBefore NRP_VisualTurn
* @url http://newrpg.seesaa.net/article/472839675.html
*
* @help Multiple characters act together like a typical turn-based system.
* However, a character with high agility will get more turns
* in proportion to that number.
* Conversely, slower characters can have their turns skipped.
*
* For more information, please see below.
* http://newrpg.seesaa.net/article/472839675.html
*
* This plugin does not display order by itself.
* Please use it in combination with NRP_VisualTurn.js.
* http://newrpg.seesaa.net/article/472840225.html
*
* [Terms]
* There are no restrictions.
* Modification, redistribution freedom, commercial availability,
* and rights indication are also optional.
* The author is not responsible,
* but we will respond to defects as far as possible.
*
* @param <Basic>
*
* @param number
* @parent <Basic>
* @type number
* @default 9
* @desc The number of battler to calculate the turn order.
* This is the number of battler to be displayed. default 9.
*
* @param <Battle Start>
*
* @param actorStartRandomWt
* @parent <Battle Start>
* @type number
* @default 0
* @desc Distribute the actors' initial wait time by the numerical %.
* Example: 20 distributes 90-110%. 0 if not specified.
*
* @param enemyStartRandomWt
* @parent <Battle Start>
* @type number
* @default 20
* @desc Distribute the enemys' initial wait time by the numerical %.
* Example: 20 distributes 90-110%. 0 if not specified.
*
* @param preemptiveAdvantage
* @parent <Battle Start>
* @type number
* @default 50
* @desc Advantage to actors during a preemptive attack.
* Speed up their turn by the % of the specified number.
*
* @param surpriseAdvantage
* @parent <Battle Start>
* @type number
* @default 50
* @desc Advantage to enemys during a surprise attack.
* Speed up their turn by the % of the specified number.
*
* @param startTurn
* @parent <Battle Start>
* @type select
* @option 0
* @option 1
* @default 1
* @desc Sets the number of turns at the start of battle.
* It is used to determine the enemy's action. default 1. MV's default 0.
*/
/*:ja
* @target MZ
* @plugindesc v1.051 ターン制とCTBを無理やり融合させた夢の戦闘システムを実現します。
* @author 砂川赳(http://newrpg.seesaa.net/)
* @base NRP_VisualTurn
* @orderBefore NRP_VisualTurn
* @url http://newrpg.seesaa.net/article/472839675.html
*
* @help 一般的なターン制のように複数のキャラがまとまって行動します。
* ただし、敏捷性が高いキャラはその数値に比例して多くターンが回ってきます。
* 逆に言うと、遅いキャラは出番が飛ばされることがあります。
*
* 詳細は以下をご覧ください。
* http://newrpg.seesaa.net/article/472839675.html
*
* このプラグイン単体では順序の表示を行いません。
* NRP_VisualTurn.jsと組み合わせて使用してください。
* http://newrpg.seesaa.net/article/472840225.html
*
* ■利用規約
* 特に制約はありません。
* 改変、再配布自由、商用可、権利表示も任意です。
* 作者は責任を負いませんが、不具合については可能な範囲で対応します。
*
* @param <Basic>
* @text <基本設定>
* @desc 見出しです。
*
* @param number
* @text 計算人数(表示人数)
* @parent <Basic>
* @type number
* @default 9
* @desc ターン順序の計算を行う人数。これが表示される人数になります。
* 指定なしなら9。
*
* @param <Battle Start>
* @text <戦闘開始関連>
* @desc 見出しです。
*
* @param actorStartRandomWt
* @text 味方の始動時間バラツキ
* @parent <Battle Start>
* @type number
* @default 0
* @desc 味方の初期待ち時間を数値%分だけ分散させます。
* 例:20ならば、90~110%に分散。指定なしは0。
*
* @param enemyStartRandomWt
* @text 敵の始動時間バラツキ
* @parent <Battle Start>
* @type number
* @default 20
* @desc 敵の初期待ち時間を数値%分だけ分散させます。
* 例:20ならば、90~110%に分散。指定なしは20。
*
* @param preemptiveAdvantage
* @text 先制時の始動時間ボーナス
* @parent <Battle Start>
* @type number
* @default 50
* @desc 先制攻撃時の特典。
* 指定した数値の%分だけ仲間のターンを早めます。
*
* @param surpriseAdvantage
* @text 奇襲時の始動時間ボーナス
* @parent <Battle Start>
* @type number
* @default 50
* @desc 奇襲時の敵特典。
* 指定した数値の%分だけ敵のターンを早めます。
*
* @param startTurn
* @text 初期ターン数
* @parent <Battle Start>
* @type select
* @option 0
* @option 1
* @default 1
* @desc 戦闘開始時のターン数(敵の行動判定用)を設定します。
* 初期値は1。MVのデフォルトの仕様だと0です。
*/
(function() {
"use strict";
function toNumber(str, def) {
return isNaN(str) ? def : +(str || def);
}
var parameters = PluginManager.parameters("NRP_CountTimeTurnBattle");
var paramNumber = toNumber(parameters["number"], 9);
var paramActorStartRandomWt = toNumber(parameters["actorStartRandomWt"], 0);
var paramEnemyStartRandomWt = toNumber(parameters["enemyStartRandomWt"], 20);
var paramPreemptiveAdvantage = toNumber(parameters["preemptiveAdvantage"], 50);
var paramSurpriseAdvantage = toNumber(parameters["surpriseAdvantage"], 50);
var paramStartTurn = toNumber(parameters["startTurn"], 1);
/*------------------------------------------------------
* BattleManager
------------------------------------------------------*/
/*
* ●初期化処理
*/
var _BattleManager_initMembers = BattleManager.initMembers;
BattleManager.initMembers = function() {
_BattleManager_initMembers.call(this);
// CTTB判定フラグ
this._isCttb = true;
// コマンド入力順のアクター
this._commandActors = [];
// コマンド入力アクターのindex(追加)
this._commandActorsIndex = -1;
// CTTBターン内の行動のべ人数(追加)
this._cttbCount = -1;
};
/**
* ●戦闘開始時
* ※バトラー変数の初期化
*/
var _Game_Battler_onBattleStart = Game_Battler.prototype.onBattleStart;
Game_Battler.prototype.onBattleStart = function() {
// 元処理実行
_Game_Battler_onBattleStart.call(this);
this._wt = 0;
// 初期ターンの設定
this._turnCount = paramStartTurn - 1;
// ターンに参加しているか?
this._isTurnEntry = false;
};
/**
* ● コマンド入力中のアクターを取得
*/
BattleManager.actor = function() { // MZ対応
return this._commandActorsIndex >= 0 ? this._commandActors[this._commandActorsIndex] : null;
//return this._actorIndex >= 0 ? $gameParty.members()[this._actorIndex] : null;
};
/**
* ● アクターの変更
* また、newActorIndex = -1で初期化を行う。
*/
BattleManager.changeActor = function(newActorIndex, lastActorActionState) {
var lastActor = this.actor();
this._commandActorsIndex = newActorIndex; // 追加
var newActor = this.actor();
if (lastActor) {
lastActor.setActionState(lastActorActionState);
}
if (newActor) {
// アクターが取得できるなら、そのインデックスを設定
this._actorIndex = newActor.index();
newActor.setActionState('inputting');
} else {
// それ以外はそのままセット(-1の初期化を想定)
this._actorIndex = newActorIndex;
}
// MZ対応
if (Utils.RPGMAKER_NAME != "MV") {
this._currentActor = newActor;
}
};
/**
* ●戦闘開始
*/
var _BattleManager_startBattle = BattleManager.startBattle;
BattleManager.startBattle = function() {
_BattleManager_startBattle.apply(this, arguments); // 再定義した旧処理
// 戦闘開始時の初期WTを設定
this.setStartWt();
};
/**
* 【独自実装】●戦闘開始時のWT(待ち時間)設定
* ※先制攻撃、奇襲を考慮
*/
BattleManager.setStartWt = function() {
// ループ内でthis参照はできないので一旦移す
var surprise = this._surprise;
var preemptive = this._preemptive;
// 敵味方全員の初期WTを計算する。
this.allBattleMembers().forEach(function(battler) {
// 基本WTを設定する。
battler.makeBaseWt();
// WTの初期値として基本WTを設定する。
var wt = battler._baseWt;
var startRandomWt = 0;
// 味方
if (battler.isActor()) {
startRandomWt = paramActorStartRandomWt;
// 先制攻撃の場合はWT減算
if (preemptive) {
// - WT * 先制攻撃特典% / 100
wt -= parseInt(wt * paramPreemptiveAdvantage / 100);
}
// 敵の場合はWT分散
} else {
startRandomWt = paramEnemyStartRandomWt;
// 不意打ちの場合はWT半減
if (surprise) {
// - WT * 奇襲特典% / 100
wt -= parseInt(wt * paramSurpriseAdvantage / 100);
}
}
// 初期WTを分散値に従って設定する。
// 例:分散値が20の場合
// 100 - (20 / 2) + [0~20未満の乱数] → 90~110未満の乱数を作成
var r = 100 - (startRandomWt / 2) + Math.random() * startRandomWt;
wt = parseInt(wt * r / 100);
battler._wt = wt;
});
};
/**
* ●コマンド入力開始
*/
var _BattleManager_startInput = BattleManager.startInput;
BattleManager.startInput = function() {
this._phase = 'input';
// 行動順序計算
this.makeActionOrders();
// 時間経過
this.timeGoesBy();
// 各自の個別ターン加算
this._entryBattlers.forEach(function(battler) {
battler._turnCount++;
});
this._commandActorsIndex = -1;
// 元処理実行
_BattleManager_startInput.call(this);
}
/**
* ● 次のコマンド入力へ
*/
BattleManager.selectNextCommand = function() {
do {
/*
* 以下のいずれかの場合は次へ
* アクターが取得できない。
* アクターのコマンドは全て入力済み。(複数行動の場合)
*/
if (!this.actor() || !this.actor().selectNextCommand()) {
this.changeActor(this._commandActorsIndex + 1, 'waiting');
// 全員入力完了ならターン開始
if (this._commandActorsIndex >= this._commandActors.length) {
this.startTurn();
break;
}
}
} while (!this.actor().canInput());
};
/**
* ● 前のコマンド入力へ
*/
BattleManager.selectPreviousCommand = function() {
do {
if (!this.actor() || !this.actor().selectPreviousCommand()) {
this.changeActor(this._commandActorsIndex - 1, 'undecided');
if (this._commandActorsIndex < 0) {
return;
}
}
} while (!this.actor() || !this.actor().canInput());
};
/**
* ●行動順序の作成
*/
BattleManager.makeActionOrders = function() {
// WTとバトラーの組のリスト
var wt_battlers = [];
// 一時バトラーリスト
var battlers = [];
/*
* 敵味方全員の生存者リストを作成し、基本WTを計算する。
*/
this.allBattleMembers().forEach(function(battler) {
// 生存者のみに絞る
if (battler.isAlive()) {
battlers.push(battler);
}
/*
* ついでにバトラー別の初期化処理
*/
// ターン参加フラグを初期化
battler._isTurnEntry = false;
});
battlers.forEach(function(battler) {
// 基本WTを設定する。(speedではなく、agiが参照される。)
battler.makeBaseWt();
});
/*
* CTB用のリストを作成していく。
*/
battlers.forEach(function(battler) {
for (var i = 0; i < paramNumber; i++) {
// 現在のWTに、次の行動までのWTを加算する。
var tmpWt = battler._wt + (battler._baseWt * i);
/*
* 以下の条件を満たす場合は、割り込めない。
* 1.現在の行動順リストが埋まっている。
* 2.かつ、末尾のバトラーよりもWTが大きい場合。
*/
if (wt_battlers.length >= paramNumber
&& tmpWt >= wt_battlers[paramNumber - 1][0]) {
// forループを終了して、次のバトラーへ
break;
}
// 行動順リストの末尾にWTとバトラーの組を追加
wt_battlers.push([tmpWt, battler]);
// WT降順でソート実行
wt_battlers.sort(function(a, b) {
return a[0] - b[0];
});
// 押し出された要素(最後の要素)を削除
if (wt_battlers.length > paramNumber) {
wt_battlers.pop();
}
}
});
/*
* WTを除いたリストを再作成
*/
battlers = wt_battlers.map(function(wtBattler) {
return wtBattler[1];
});
/*
* CTTB用戦闘人数を算出
*/
var entryBattlers = []; // 参加リスト
var noEntryBattlers = []; // 不参加リスト
// CTTBターン内の行動のべ人数(追加)
this._cttbCount = paramNumber; // 最大表示人数を初期値に
// 参加締め切りフラグ
var cttbCountFlg = false;
var count = 0;
// 配列をターン参加と不参加に分割する。
battlers.forEach(function(battler) {
// 参加締め切り後なら
if (cttbCountFlg) {
// 不参加リストに追加
noEntryBattlers.push(battler);
} else {
// 対象のバトラーが二回目の登場なら参加締め切り
// その直前をターンの終了点に
if (entryBattlers.includes(battler)) {
this._cttbCount = count;
cttbCountFlg = true;
// 不参加リストに追加
noEntryBattlers.push(battler);
} else {
// ターン参加フラグを立てる
battler._isTurnEntry = true;
// ターン参加リストに追加
entryBattlers.push(battler);
}
}
count++;
}, this);
// ターン開始後、最速始動技が選択されているなら優先。
if (this._phase == "turn") {
entryBattlers.sort(function(a, b) {
if (isFastTrick(a)) {
return -1;
} else if (isFastTrick(b)) {
return 1;
}
return 0;
});
}
// 参加者のみのリスト
this._entryBattlers = entryBattlers;
// 参加者、非参加者の順で結合
this._actionBattlers = entryBattlers.concat(noEntryBattlers);
// コマンド入力対象(アクター)に絞ったリストを作成
this._commandActors = entryBattlers.filter(function(battler) {
return battler.isActor();
});
};
/**
* ●最速始動かどうか?
*/
function isFastTrick(battler) {
if (battler.numActions() > 0) {
// ターン参加かつ最速始動ならば最優先
var fastTrick = battler._actions.some(function(action) {
return battler._isTurnEntry && action.item() && action.item().meta.FastTrick;
});
if (fastTrick) {
return true;
}
}
}
/**
* ●時間経過処理
*/
BattleManager.timeGoesBy = function() {
var topWt = this._actionBattlers[0]._wt;
if (topWt > 0) {
// 先頭行動者のWTが0になるように、全バトラーのWTを減算。
this.allBattleMembers().forEach(function(battler) {
// 生存者のみに絞る
if (battler.isAlive()) {
battler._wt -= topWt;
}
});
}
}
/**
* ●行動開始
*/
var _BattleManager_startAction = BattleManager.startAction;
BattleManager.startAction = function() {
// 元処理実行
_BattleManager_startAction.apply(this);
// 実行した行動の速度を計算する。
this._subject.makeSpeed();
};
/**
* ● 次の行動主体の取得
* 行動順序リストの次に来るバトラーを取得する。
* 現在パーティにいないアクターを取得した場合(index が nil, バトルイベ
* ントでの離脱直後などに発生)は、それをスキップする。
*/
BattleManager.getNextSubject = function() {
for (;;) {
// そのターンの行動人数を超えていたら終了
if (this._cttbCount <= 0) {
return null;
}
this._cttbCount -= 1;
var battler = this._actionBattlers.shift();
if (!battler) {
return null;
}
if (battler.isBattleMember() && battler.isAlive()) {
return battler;
}
}
};
/**
* ●パラメータの追加
*/
Object.defineProperties(Game_BattlerBase.prototype, {
// WT(待ち時間)
wt: { get: function() { return this._wt; }, configurable: true },
});
/**
* ●個別ターン数の取得
*/
Game_BattlerBase.prototype.turnCount = function() {
return this._turnCount;
};
/**
* ●基本WTを計算する。
*/
Game_Battler.prototype.makeBaseWt = function() {
// 敏捷性が0以下ならNumber型の最大値(たぶん9007199254740991)を設定
if (this.agi <= 0) {
this._baseWt = Number.MAX_SAFE_INTEGER;
return;
}
// 100000 / 敏捷性
this._baseWt = parseInt(100000 / this.agi);
};
/**
* ●速度補正つき加算WTを取得する。
*/
Game_Battler.prototype.getAddWt = function() {
var addWt = 100000;
// speedが有効ならspeed値を使用する。
if (this._speed > 0) {
addWt = parseInt(100000 / this._speed);
// なければagiを参照する。
} else {
// 敏捷性が0以下ならNumber型の最大値(たぶん9007199254740991)を設定
if (this.agi <= 0) {
return Number.MAX_SAFE_INTEGER;
}
addWt = parseInt(100000 / this.agi);
}
return addWt;
};
/**
* ●個別のターン終了処理
*/
var _Game_Battler_prototype_onTurnEnd = Game_Battler.prototype.onTurnEnd;
Game_Battler.prototype.onTurnEnd = function() {
// ターンに参加していないバトラーは終了処理をしない。
if (!this._isTurnEntry) {
return;
}
// 行動者の現在WTに加算WTを加算する。
this._wt += this.getAddWt();
// 元の処理を呼び出し。
_Game_Battler_prototype_onTurnEnd.apply(this, arguments);
};
/**
* ●行動速度の計算
* 速度補正を%化
*/
Game_Action.prototype.speed = function() {
var agi = this.subject().agi;
// バラつきをなくす
var speed = agi;
// var speed = agi + Math.randomInt(Math.floor(5 + agi / 4));
// 速度補正を%化
if (this.item()) {
// 速度補正MAX(2000)の場合は速度無限に(時間経過がなくなる)
if (this.item().speed >= 2000) {
return Infinity;
}
speed += parseInt(speed * this.item().speed / 100);
// speed += this.item().speed;
}
if (this.isAttack()) {
// 速度補正MAX(2000)の場合は速度無限に(時間経過がなくなる)
if (this.subject().attackSpeed() >= 2000) {
return Infinity;
}
speed += parseInt(speed * this.subject().attackSpeed() / 100);
// speed += this.subject().attackSpeed();
}
return speed;
};
/**
* ●敵の行動条件合致判定[ターン数]
*/
Game_Enemy.prototype.meetsTurnCondition = function(param1, param2) {
// グループのターンではなく、行動者の個別ターンを参照する。
var n = this.turnCount();
// var n = $gameTroop.turnCount();
if (param2 === 0) {
return n === param1;
} else {
return n > 0 && n >= param1 && n % param2 === param1 % param2;
}
};
/**
* ●ステート追加(WT変動の実装)
*/
var _Game_BattlerBase_prototype_addNewState = Game_BattlerBase.prototype.addNewState;
Game_BattlerBase.prototype.addNewState = function(stateId) {
/*
* WT設定値を元にWTを変化
*/
// <SetWt:number>があれば、その値(%)を設定
if ($dataStates[stateId].meta.SetWt) {
this._wt = this._baseWt * $dataStates[stateId].meta.SetWt / 100;
// <AddWt:number>があれば、その値(%)を加算
} else if ($dataStates[stateId].meta.AddWt) {
this._wt += this._baseWt * $dataStates[stateId].meta.AddWt / 100;
}
// 元の処理
_Game_BattlerBase_prototype_addNewState.apply(this, arguments);
};
})();