忍者ブログ

蘭太郎ゲームズ

蘭太郎が制作したゲームに関する紹介ブログです。
MENU

スクリプトメモ:支援の処理

戦闘力計算時の処理で
支援スキル」と
周囲○マス内にいるユニットを探して補正
どっちが負荷が大きいんだろう?

周囲3マス以内にいるユニットに補正するカスタムスキルも
数が多いと処理に負荷が掛かりそうだけど
支援スキルもかなり重そうな処理みたいだしなぁ……。

AIのスコア計算では支援を考慮しないようになっているのは
処理負荷の軽減とスコア計算中は未だユニットの攻撃位置が確定してないからなんだろうな。

以下、自分なりに読み解いてみたSupportCalculatorクラスの処理。
誤解してる部分もあると思うので指摘してもらえたら嬉しいです。


SupportCalculatorクラスの処理
var SupportCalculator = {
    //支援の各数値を算出する時に呼び出す関数
    createTotalStatus: function(unit) {
        var i, x, y, index, targetUnit, indexArray, count;
        //変数totalStatusに攻撃、防御、命中、回避、クリティカル、クリティカル回避の支援値を保存
        var totalStatus = {};

        //初期値として0を代入

        totalStatus.powerTotal = 0;
        totalStatus.defenseTotal = 0;
        totalStatus.hitTotal = 0;
        totalStatus.avoidTotal = 0;
        totalStatus.criticalTotal = 0;
        totalStatus.criticalAvoidTotal = 0;

        if (this._isStatusDisabled()) {//拠点では支援を算出しない
            return totalStatus;
        }
         //インデックスを配列で保存(ユニットを起点に1-3(データ設定の支援範囲)マス分mapを検索)
         //indexArrayクラスはsingleton-system.jsにある
        indexArray = IndexArray.getBestIndexArray(
            unit.getMapX(), unit.getMapY(), 1, this._getSupportRange());

        count = indexArray.length;

         // unit(支援を受ける側)の一定範囲(既定3マス)にいるtargetUnit(支援を与える側)を探す
        for (i = 0; i < count; i++) {
            index = indexArray[i];
            x = CurrentMap.getX(index);
            y = CurrentMap.getY(index);
            targetUnit = PosChecker.getUnitFromPos(x, y);
            if (targetUnit !== null) {
                // targetUnitが見つかった場合は、支援データをtotalStatusに加算
                //ユニットの支援データで設定されている支援関係
                this._collectStatus(unit, targetUnit, totalStatus);
           }
        }

        this._collectSkillStatus(unit, totalStatus);//支援スキル

        return totalStatus;
    },

    //totalStatusを基に各数値を取得する
    //~getCriticalAvoidまで同じ
    getPower: function(totalStatus) {
        if (totalStatus === null) {
            return 0;
        }
        return totalStatus.powerTotal;
    },

    //ユニット→詳細情報→支援データで設定されている支援関係
    _collectStatus: function(unit, targetUnit, totalStatus) {
        var i, data;
        var count = targetUnit.getSupportDataCount();

        for (i = 0; i < count; i++) {
            data = targetUnit.getSupportData(i);
            if (unit === data.getUnit() && data.isGlobalSwitchOn() && data.isVariableOn()) {
                this._addStatus(totalStatus, data.getSupportStatus());
                break;
            }
        }
    },

    //支援スキルを調べる
    _collectSkillStatus: function(unit, totalStatus) {
        var i, j, list, count, targetUnit;

        //ユニットの所属に応じてリストを取得

        //自軍=自軍の出撃者リスト。
        //getSortieList=「出撃」かつ「生存」かつ「フュージョンされていない」
        //敵/同盟=生存者リスト。getAliveList=「生存」かつ「フュージョンされていない」
        var listArray = this._getListArray(unit);
        var listCount = listArray.length;//基本的には所属軍のリスト1つ

        for (i = 0; i < listCount; i++) {
            list = listArray[i];
            count = list.getCount();
            //リストのindex0から順にすべて検索 敵100体だと100体分
            for (j = 0; j < count; j++) {
                targetUnit = list.getData(j);
                if (unit === targetUnit) {
                    continue;
                }
                //スキルの範囲を確認する。targetUnitがスキル所持者になる
                this._checkSkillStatus(targetUnit, unit, false, totalStatus);
            }
        }

         // ユニット自身が「単体」のスキルを持つ場合は、自分自身に加算
         this._checkSkillStatus(unit, null, true, totalStatus);
    },


    //スキルの範囲と一致した場合、支援データを加算する
    _checkSkillStatus: function(unit, targetUnit, isSelf, totalStatus) {
        var i, skill, isSet, indexArray;
        //「支援」効果を持つスキルの配列
        var arr = SkillControl.getDirectSkillArray(unit, SkillType.SUPPORT, '');
        var count = arr.length;

        for (i = 0; i < count; i++) {
            skill = arr[i].skill;//配列のi番を変数skillに保存して範囲を確認して行く
            isSet = false;

            if (isSelf) {
                if (skill.getRangeType() === SelectionRangeType.SELFONLY) {//スキルの範囲が「単体」
                    isSet = true;//支援データを取得する許可を変数に保存
                }
            }
           else {
               if (skill.getRangeType() === SelectionRangeType.ALL) {//スキルの範囲が「全域」
               // 「全域」の場合は、常に支援が有効
                   isSet = true;
               }
             else if (skill.getRangeType() === SelectionRangeType.MULTI) {//スキル範囲が「指定範囲」
                  //_collectSkillStatusで検索中のtargetUnitが、引数unit(座標の基準点)になっている
                  //範囲3のスキルの場合24マス検索
                  //リストのユニット全員に支援を持たせていたら……
                  indexArray = IndexArray.getBestIndexArray(
                      unit.getMapX(), unit.getMapY(), 1, skill.getRangeValue());

                  // 「指定範囲」の場合は、indexArray内の位置にunitが存在しているか調べる
                  //ここでのtargetUnitは_collectSkillStatusの引数unit(=支援をもらう側)

                  isSet = IndexArray.findUnit(indexArray, targetUnit);
               }
            }


        //スキルの「範囲」と「有効相手」が一致していれば支援値を加算する

        if (isSet && this._isSupportable(unit, targetUnit, skill)) {
                this._addStatus(totalStatus, skill.getSupportStatus());
            }
        }
    },

    //支援データの各数値を加算する
    _addStatus: function(totalStatus, supportStatus) {
        totalStatus.powerTotal += supportStatus.getPower();
        totalStatus.defenseTotal += supportStatus.getDefense();
        totalStatus.hitTotal += supportStatus.getHit();
        totalStatus.avoidTotal += supportStatus.getAvoid();
        totalStatus.criticalTotal += supportStatus.getCritical();
        totalStatus.criticalAvoidTotal += supportStatus.getCriticalAvoid();
    },

    //スキルの「有効相手」を確認する
    _isSupportable: function(unit, targetUnit, skill) {
        if (targetUnit === null) {
            targetUnit = unit;
        }
        return skill.getTargetAggregation().isCondition(targetUnit);
    },

    //データ設定→コンフィグ2の支援範囲
    _getSupportRange: function() {
        return DataConfig.getSupportRange();
    },

    //拠点では支援データを算出しない
    _isStatusDisabled: function() {
        return root.getBaseScene() === SceneType.REST;
    },

    //支援スキルの検索対象リストを取得する
    _getListArray: function(unit) {
        var filter = 0;
        var unitType = unit.getUnitType();

        if (unitType === UnitType.PLAYER) {
            filter = UnitFilterFlag.PLAYER;
        }
        else if (unitType === UnitType.ENEMY) {
            filter = UnitFilterFlag.ENEMY;
        }
        else {
            filter = UnitFilterFlag.ALLY;
            // 有効相手に同盟軍を含んだ支援スキルを自軍が持つような場合
            // filter = UnitFilterFlag.PLAYER | UnitFilterFlag.ALLY;
        }
        return FilterControl.getListArray(filter);//singleton-unitlist.jsにある
    }
};

拍手

PR

Comment

久しぶりに

  • まながつお
  • 2020-06-12 02:39
  • edit
 ひさしぶりにお邪魔しましたが
見るだけで頭から煙の出そうな事に
取り掛かられていますね、プラグインの
製作が簡単な物ではない事を理解させられます。

まながつお様

  • 蘭太郎 〔管理人〕
  • 2020-06-12 22:36
コメントありがとうございます。

Sスタを触り始めた当初は、カスパラの記述でつまづいたりしてましたね。
(カンマで区切ったり、セミコロンや括弧の閉じ方といった部分が第一関門)

5年近くゲーム制作を続けている内に
なんとなく推測できる箇所が少しずつ増えてきたという按配ですが
それでも理解が及ばない処理が多くて
たくさんの機能を追加してくださっているスクリプト職人さん達には頭が下がります。
お名前
タイトル
E-MAIL
コメント
パスワード

× CLOSE

カレンダー

03 2024/04 05
S M T W T F S
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

ブログ内検索

× CLOSE

Copyright © 蘭太郎ゲームズ : All rights reserved

TemplateDesign by KARMA7

忍者ブログ [PR]