【FF14】魔獣使い・闘獣練で便利なSplatoonレイアウトまとめ

更新履歴


第三盤に「魔眼の義眼」、特二盤に「消失の魔刃・衝波」のスクリプトを追加しました。

特二盤のレイアウトを更新し、「消失の魔刃」のスクリプトを追加しました。

第一盤を表示
JSON / Splatoon Layout
~Lv2~{"Name":"1戦目_デススパイラル","Group":"闘獣錬:第一盤","ZoneLockH":[1339],"ElementsL":[{"Name":"AoE","type":1,"radius":4.2,"Donut":30.0,"fillIntensity":0.5,"refActorNPCID":14532,"refActorRequireCast":true,"refActorCastId":[46868],"refActorComparisonType":4}]}
~Lv2~{"Name":"1戦目_テュムラス","Group":"闘獣錬:第一盤","ZoneLockH":[1339],"ElementsL":[{"Name":"AoE","type":1,"radius":6.0,"refActorNPCID":14531,"refActorRequireCast":true,"refActorCastId":[46866],"refActorComparisonType":4}]}
~Lv2~{"Name":"1戦目_フロントガード","Group":"闘獣錬:第一盤","ZoneLockH":[1339],"ElementsL":[{"Name":"テキスト","type":1,"offZ":2.0,"radius":6.0,"Filled":false,"fillIntensity":0.5,"overlayFScale":2.0,"thicc":0.0,"overlayText":"前方無敵","refActorNPCID":14531,"refActorRequireBuff":true,"refActorBuffId":[680],"refActorComparisonType":4}]}
~Lv2~{"Enabled":false,"Name":"1戦目_ブラックエラプション_1発目","Group":"闘獣錬:第一盤","ZoneLockH":[1339],"UseTriggers":true,"FreezeDisplayDelay":1.0000001,"Triggers":[{"Type":2,"Duration":1.9,"Match":"xxxxxx"}],"ElementsL":[{"Name":"AoE_前","type":1,"offY":3.0,"radius":5.0,"fillIntensity":0.216,"refActorNPCID":14532,"refActorComparisonType":4,"includeRotation":true,"onlyTargetable":true},{"Name":"AoE_後","type":1,"offY":-3.0,"radius":5.0,"fillIntensity":0.216,"refActorNPCID":14532,"refActorComparisonType":4,"includeRotation":true,"onlyTargetable":true},{"Name":"AoE_右","type":1,"offX":3.0,"radius":5.0,"fillIntensity":0.216,"refActorNPCID":14532,"refActorComparisonType":4,"includeRotation":true,"onlyTargetable":true},{"Name":"AoE_左","type":1,"offX":-3.0,"radius":5.0,"fillIntensity":0.216,"refActorNPCID":14532,"refActorComparisonType":4,"includeRotation":true,"onlyTargetable":true}]}
~Lv2~{"Enabled":false,"Name":"1戦目_ブラックエラプション_2発目","Group":"闘獣錬:第一盤","ZoneLockH":[1339],"FreezeDisplayDelay":5.0,"ElementsL":[{"Name":"AoE_前","type":1,"offY":6.0,"radius":5.0,"fillIntensity":0.216,"refActorNPCID":14532,"refActorComparisonType":4,"includeRotation":true,"onlyTargetable":true},{"Name":"AoE_後","type":1,"offY":-6.0,"radius":5.0,"fillIntensity":0.216,"refActorNPCID":14532,"refActorComparisonType":4,"includeRotation":true,"onlyTargetable":true},{"Name":"AoE_右","type":1,"offX":6.0,"radius":5.0,"fillIntensity":0.216,"refActorNPCID":14532,"refActorComparisonType":4,"includeRotation":true,"onlyTargetable":true},{"Name":"AoE_左","type":1,"offX":-6.0,"radius":5.0,"fillIntensity":0.216,"refActorNPCID":14532,"refActorComparisonType":4,"includeRotation":true,"onlyTargetable":true}]}
~Lv2~{"Name":"2戦目左_アビサルトランスフィクション","Group":"闘獣錬:第一盤","ZoneLockH":[1339],"ElementsL":[{"Name":"AoE_1発目","type":1,"radius":6.0,"fillIntensity":0.5,"refActorNPCNameID":14533,"refActorRequireCast":true,"refActorCastId":[46882],"refActorComparisonType":6},{"Name":"AoE_2~4発目","type":1,"radius":3.0,"fillIntensity":0.5,"refActorNPCNameID":14533,"refActorRequireCast":true,"refActorCastId":[46884],"refActorComparisonType":6}]}
~Lv2~{"Name":"2戦目左_アビサルスイング","Group":"闘獣錬:第一盤","ZoneLockH":[1339],"ElementsL":[{"Name":"AoE","type":4,"radius":40.0,"coneAngleMin":-90,"coneAngleMax":90,"refActorNPCID":14533,"refActorRequireCast":true,"refActorCastId":[46886],"refActorComparisonType":4,"includeRotation":true}]}
~Lv2~{"Name":"4戦目_バーニングスマイト","Group":"闘獣錬:第一盤","ZoneLockH":[1339],"ElementsL":[{"Name":"AoE_その場","type":4,"radius":40.0,"coneAngleMin":-60,"coneAngleMax":60,"refActorNPCNameID":14538,"refActorRequireCast":true,"refActorCastId":[46912],"refActorComparisonType":6,"includeRotation":true},{"Name":"AoE_移動","type":4,"radius":40.0,"coneAngleMin":-60,"coneAngleMax":60,"refActorNPCNameID":14538,"refActorRequireCast":true,"refActorCastId":[49688],"refActorComparisonType":6,"includeRotation":true}]}
~Lv2~{"Name":"5戦目_ブラッドレイン","Group":"闘獣錬:第一盤","ZoneLockH":[1339],"ElementsL":[{"Name":"AoE_円","type":1,"radius":8.0,"refActorNPCID":14541,"refActorRequireCast":true,"refActorCastId":[46925],"refActorComparisonType":4},{"Name":"AoE_ドーナツ","type":1,"radius":8.0,"Donut":40.0,"fillIntensity":0.5,"refActorNPCID":14541,"refActorRequireCast":true,"refActorCastId":[46923],"refActorComparisonType":4}]}
~Lv2~{"Name":"5戦目_ヴォイド・エアロラ","Group":"闘獣錬:第一盤","ZoneLockH":[1339],"ElementsL":[{"Name":"AoE","type":3,"refY":40.0,"radius":3.0,"fillIntensity":0.5,"refActorNPCID":14541,"refActorRequireCast":true,"refActorCastId":[46932],"refActorComparisonType":4,"includeRotation":true}]}
第二盤を表示
JSON / Splatoon Layout
~Lv2~{"Name":"1戦目_アームハンマー","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"AoE_右","type":4,"radius":40.0,"coneAngleMax":180,"refActorNPCID":14545,"refActorRequireCast":true,"refActorCastId":[48122],"refActorComparisonType":4,"includeRotation":true},{"Name":"AoE_左","type":4,"radius":40.0,"coneAngleMin":-180,"refActorNPCID":14545,"refActorRequireCast":true,"refActorCastId":[48124],"refActorComparisonType":4,"includeRotation":true}]}
~Lv2~{"Name":"1戦目_ハンマーリープ","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"AoE","type":1,"radius":30.0,"refActorNPCID":14545,"refActorRequireCast":true,"refActorCastId":[48137],"refActorComparisonType":4}]}
~Lv2~{"Name":"1戦目_クロウ・アンド・テイル","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"AoE_クロウ","type":4,"radius":40.0,"coneAngleMin":-90,"coneAngleMax":90,"fillIntensity":0.5,"refActorNPCID":14545,"refActorRequireCast":true,"refActorCastId":[48139],"refActorCastTimeMin":3.0,"refActorCastTimeMax":6.0,"refActorComparisonType":4,"includeRotation":true},{"Name":"AoE_テイル","type":4,"radius":40.0,"coneAngleMin":90,"coneAngleMax":270,"refActorNPCID":14545,"refActorRequireCast":true,"refActorCastId":[48141],"refActorComparisonType":4,"includeRotation":true}]}
~Lv2~{"Name":"1戦目_テイル・アンド・クロウ","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"AoE_テイル","type":4,"radius":40.0,"coneAngleMin":90,"coneAngleMax":270,"refActorNPCID":14545,"refActorRequireCast":true,"refActorCastId":[50411],"refActorComparisonType":4,"includeRotation":true},{"Name":"AoE_クロウ","type":4,"radius":40.0,"coneAngleMin":-90,"coneAngleMax":90,"fillIntensity":0.5,"refActorNPCID":14545,"refActorRequireCast":true,"refActorCastId":[50413],"refActorCastTimeMin":3.0,"refActorCastTimeMax":6.0,"refActorComparisonType":4,"includeRotation":true}]}
~Lv2~{"Name":"1戦目_チャージ・アンド・ハンマー","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"突進詠唱?","type":1,"Enabled":false,"refActorNPCID":14545,"refActorRequireBuff":true,"refActorBuffId":[2193],"refActorComparisonType":4,"includeRotation":true},{"Name":"AoE_右","type":4,"radius":40.0,"coneAngleMax":180,"refActorNPCID":14545,"refActorRequireCast":true,"refActorCastId":[48132],"refActorComparisonType":4,"includeRotation":true},{"Name":"AoE_左","type":4,"radius":40.0,"coneAngleMin":-180,"refActorNPCID":14545,"refActorRequireCast":true,"refActorCastId":[48134],"refActorComparisonType":4,"includeRotation":true}]}
~Lv2~{"Name":"2戦目右_ブレイジングトレイル","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"AoE","type":3,"refY":40.0,"radius":20.0,"fillIntensity":0.5,"refActorNPCID":14549,"refActorRequireCast":true,"refActorCastId":[48175],"refActorComparisonType":4,"includeRotation":true}]}
~Lv2~{"Name":"2戦目右_ストームトレイル","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"AoE","type":4,"radius":40.0,"coneAngleMin":-30,"coneAngleMax":30,"refActorNPCID":14549,"refActorRequireCast":true,"refActorCastId":[48178],"refActorComparisonType":4,"includeRotation":true}]}
~Lv2~{"Name":"2戦目左_ルイナスローカス","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"AoE","type":1,"radius":8.0,"refActorNPCID":14546,"refActorRequireCast":true,"refActorCastId":[48155],"refActorComparisonType":4}]}
~Lv2~{"Name":"2戦目左_ルイナスリング","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"AoE","type":1,"radius":8.0,"Donut":40.0,"fillIntensity":0.5,"refActorNPCID":14546,"refActorRequireCast":true,"refActorCastId":[48157],"refActorComparisonType":4}]}
~Lv2~{"Name":"2戦目左_ダークレイ","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"最大爆発範囲","type":1,"radius":18.0,"color":3355508480,"fillIntensity":0.1,"refActorNPCID":14547,"refActorComparisonType":4},{"Name":"条件","type":1,"overlayVOffset":1.0,"overlayFScale":2.0,"overlayText":"端捨て","refActorNPCID":14546,"refActorRequireCast":true,"refActorCastId":[48144],"refActorComparisonType":4,"Conditional":true,"Nodraw":true},{"Name":"テキスト","type":1,"radius":0.0,"Filled":false,"fillIntensity":0.5,"overlayTextColor":3355443455,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"端捨て","refActorType":1}]}
~Lv2~{"Name":"2戦目左_エーテル波","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"AoE","type":3,"refY":40.0,"radius":5.0,"fillIntensity":0.5,"refActorNPCID":14546,"refActorRequireCast":true,"refActorCastId":[48150],"refActorUseCastTime":true,"refActorCastTimeMin":3.0,"refActorCastTimeMax":6.0,"refActorUseOvercast":true,"refActorComparisonType":4,"includeRotation":true}]}
~Lv2~{"Name":"3戦目_ダークオーブ","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"AoE","type":1,"radius":18.0,"refActorNPCID":14552,"refActorRequireCast":true,"refActorCastId":[48185],"refActorComparisonType":4,"includeRotation":true}]}
~Lv2~{"Name":"3戦目_瘴気","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"爆発範囲","type":1,"radius":8.0,"color":3355508480,"fillIntensity":0.1,"refActorNPCID":14554,"refActorComparisonType":4}]}
~Lv2~{"Name":"4戦目_1000トンズ・スワイプ","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"AoE_エルダー_先","type":3,"refY":30.0,"radius":40.0,"fillIntensity":0.5,"refActorNPCID":14555,"refActorRequireCast":true,"refActorCastId":[48190],"refActorUseCastTime":true,"refActorCastTimeMax":6.7,"refActorUseOvercast":true,"refActorComparisonType":4,"includeRotation":true},{"Name":"AoE_エルダー_後","type":3,"refY":30.0,"radius":40.0,"fillIntensity":0.5,"refActorNPCID":14555,"refActorRequireCast":true,"refActorCastId":[48192],"refActorUseCastTime":true,"refActorCastTimeMin":6.7,"refActorCastTimeMax":9.7,"refActorUseOvercast":true,"refActorComparisonType":4,"includeRotation":true},{"Name":"AoE_ヤンガー_先","type":3,"refY":30.0,"radius":40.0,"fillIntensity":0.5,"refActorNPCID":14556,"refActorRequireCast":true,"refActorCastId":[48190],"refActorUseCastTime":true,"refActorCastTimeMax":6.7,"refActorUseOvercast":true,"refActorComparisonType":4,"includeRotation":true},{"Name":"AoE_ヤンガー_後","type":3,"refY":30.0,"radius":40.0,"fillIntensity":0.5,"refActorNPCID":14556,"refActorRequireCast":true,"refActorCastId":[48192],"refActorUseCastTime":true,"refActorCastTimeMin":6.7,"refActorCastTimeMax":9.7,"refActorUseOvercast":true,"refActorComparisonType":4,"includeRotation":true}]}
~Lv2~{"Name":"4戦目_1111トンズ・スイング","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"AoE_エルダー_先","type":1,"radius":23.0,"fillIntensity":0.5,"refActorNPCID":14555,"refActorRequireCast":true,"refActorCastId":[48193],"refActorUseCastTime":true,"refActorCastTimeMax":7.7,"refActorComparisonType":4,"includeRotation":true},{"Name":"AoE_エルダー_後","type":1,"radius":23.0,"fillIntensity":0.5,"refActorNPCID":14555,"refActorRequireCast":true,"refActorCastId":[48195],"refActorUseCastTime":true,"refActorCastTimeMin":7.7,"refActorCastTimeMax":13.7,"refActorUseOvercast":true,"refActorComparisonType":4,"includeRotation":true},{"Name":"AoE_ヤンガー_先","type":1,"radius":23.0,"fillIntensity":0.5,"refActorNPCID":14556,"refActorRequireCast":true,"refActorCastId":[48193],"refActorUseCastTime":true,"refActorCastTimeMax":7.7,"refActorUseOvercast":true,"refActorComparisonType":4,"includeRotation":true},{"Name":"AoE_ヤンガー_後","type":1,"radius":23.0,"fillIntensity":0.5,"refActorNPCID":14556,"refActorRequireCast":true,"refActorCastId":[48195],"refActorUseCastTime":true,"refActorCastTimeMin":7.7,"refActorCastTimeMax":13.7,"refActorUseOvercast":true,"refActorComparisonType":4,"includeRotation":true}]}
~Lv2~{"Name":"6戦目_サンドブレス","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"AoE","type":4,"radius":50.0,"coneAngleMin":-45,"coneAngleMax":45,"refActorNPCID":14562,"refActorRequireCast":true,"refActorCastId":[48227],"refActorComparisonType":4,"includeRotation":true},{"Name":"線","type":1,"radius":0.0,"color":3372154880,"fillIntensity":0.5,"thicc":10.0,"refActorNPCID":14562,"refActorRequireCast":true,"refActorCastId":[48227],"refActorComparisonType":4,"includeRotation":true,"tether":true}]}
~Lv2~{"Name":"6戦目_ゴブ流回転剣","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"AoE_ドーナツ","type":1,"radius":4.0,"Donut":40.0,"fillIntensity":0.5,"refActorNPCID":14561,"refActorRequireCast":true,"refActorCastId":[48231],"refActorComparisonType":4},{"Name":"AoE_円","type":1,"radius":8.0,"fillIntensity":0.5,"refActorNPCID":14561,"refActorRequireCast":true,"refActorCastId":[48229],"refActorComparisonType":4}]}
~Lv2~{"Name":"6戦目_ゴブゴブ爆弾","Group":"闘獣練:第二盤","ZoneLockH":[1340],"ElementsL":[{"Name":"爆発範囲_円","type":1,"radius":12.0,"color":3355508480,"fillIntensity":0.1,"refActorDataID":19561,"refActorComparisonType":3,"onlyTargetable":true},{"Name":"爆発範囲_十字1","type":3,"refY":-4.0,"offY":4.0,"radius":20.0,"color":3355508480,"fillIntensity":0.1,"refActorDataID":19559,"refActorComparisonType":3,"includeRotation":true,"onlyTargetable":true},{"Name":"爆発範囲_十字2","type":3,"refY":-20.0,"offY":20.0,"radius":4.0,"color":3355508480,"fillIntensity":0.1,"refActorDataID":19559,"refActorComparisonType":3,"includeRotation":true,"onlyTargetable":true}]}
第三盤を表示
JSON / Splatoon Layout
~Lv2~{"Name":"キャバリアー・ピース_スチールリッパ―","Group":"闘獣練:第三盤","ZoneLockH":[1341],"ElementsL":[{"Name":"扇","type":4,"radius":50.0,"coneAngleMin":-65,"coneAngleMax":65,"refActorNPCNameID":14564,"refActorRequireCast":true,"refActorCastId":[48472],"refActorComparisonType":6,"includeRotation":true}]}
~Lv2~{"Name":"キャバリアー・ピース_ギャザラーズメナス","Group":"闘獣練:第三盤","ZoneLockH":[1341],"ElementsL":[{"Name":"サークル","type":1,"radius":20.0,"refActorNPCNameID":14565,"refActorRequireCast":true,"refActorCastId":[48463],"refActorComparisonType":6}]}
~Lv2~{"Name":"カトブレパス・ピース_魔眼","Group":"闘獣練:第三盤","ZoneLockH":[1341],"ElementsL":[{"Name":"ドーナツ","type":1,"radius":5.0,"Donut":5.0,"refActorNPCNameID":14579,"refActorCastTimeMax":2.0,"refActorComparisonType":6}]}
~Lv2~{"Name":"ラハム・ピース_地滑り","Group":"闘獣練:第三盤","ZoneLockH":[1341],"ElementsL":[{"Name":"直線","type":3,"offX":-45.0,"radius":5.0,"color":3372158464,"fillIntensity":0.345,"refActorNPCNameID":14581,"refActorRequireCast":true,"refActorCastId":[48555],"refActorComparisonType":6,"includeRotation":true,"AdditionalRotation":1.5707964}]}
~Lv2~{"Name":"ラハム・ピース_砂球","Group":"闘獣練:第三盤","ZoneLockH":[1341],"ElementsL":[{"Name":"サークル","type":1,"radius":12.0,"refActorNameIntl":{"Jp":"砂球"}}]}
~Lv2~{"Name":"キャバリアー・ピース_混乱の歌","Group":"闘獣練:第三盤","ZoneLockH":[1341],"DCond":5,"UseTriggers":true,"Triggers":[{"Type":2,"Duration":6.5,"Match":"セイレーン・ピースの「混乱の歌」","FireOnce":true}],"ElementsL":[{"Name":"混乱の歌","type":4,"radius":30.0,"coneAngleMin":-45,"coneAngleMax":45,"refActorNPCNameID":14583,"refActorComparisonType":6,"includeRotation":true,"onlyVisible":true}]}
~Lv2~{"Name":"キャバリアー・ピース_急襲","Group":"闘獣練:第三盤","ZoneLockH":[1341],"ElementsL":[{"Name":"急襲","type":3,"offX":50.0,"radius":8.0,"refActorNPCNameID":14583,"refActorRequireCast":true,"refActorCastId":[48569],"refActorComparisonType":6,"includeRotation":true,"AdditionalRotation":4.712389}]}
~Lv2~{"Name":"キャバリアー・ピース_亡者の歌","Group":"闘獣練:第三盤","ZoneLockH":[1341],"DCond":5,"ElementsL":[{"Name":"円","type":1,"radius":12.0,"refActorNPCNameID":14583,"refActorRequireCast":true,"refActorCastId":[48572],"refActorComparisonType":6,"onlyVisible":true},{"Name":"ドーナツ","type":1,"radius":3.0,"Donut":30.0,"fillIntensity":0.5,"refActorNPCNameID":14583,"refActorRequireCast":true,"refActorCastId":[48575,48574],"refActorComparisonType":6,"onlyVisible":true}]}
~Lv2~{"Name":"キャバリアー・ピース_遠音","Group":"闘獣練:第三盤","ZoneLockH":[1341],"ElementsL":[{"Name":"AoE","type":1,"radius":9.0,"refActorNPCID":14584,"refActorObjectLife":true,"refActorLifetimeMin":3.0,"refActorLifetimeMax":6.0,"refActorComparisonType":4}]}
~Lv2~{"Name":"貪食のガトラー_ミールストリーム","Group":"闘獣練:第三盤","ZoneLockH":[1341],"ElementsL":[{"Name":"ノックバック","type":1,"radius":0.0,"color":3355508490,"fillIntensity":0.5,"overlayVOffset":3.0,"overlayFScale":3.0,"thicc":4.0,"overlayText":"ノックバック","refActorNPCNameID":14592,"refActorRequireCast":true,"refActorCastId":[48606],"refActorComparisonType":6,"tether":true,"ExtraTetherLength":20.0,"LineEndB":1}]}
~Lv2~{"Name":"貪食のガトラー_爆導の魔刃","Group":"闘獣練:第三盤","ZoneLockH":[1341],"ElementsL":[{"Name":"サークル","type":1,"Enabled":false,"radius":8.0,"refActorNPCNameID":14593,"refActorComparisonType":6},{"Name":"サークル","type":1,"radius":8.0,"color":3355508480,"fillIntensity":0.1,"castAnimation":3,"animationColor":3355508480,"refActorNPCNameID":14593,"refActorRequireCast":true,"refActorCastId":[48597],"refActorComparisonType":6}]}
~Lv2~{"Name":"貪食のガトラー_グラトナス・ガッティング","Group":"闘獣練:第三盤","ZoneLockH":[1341],"ElementsL":[{"Name":"直線","type":3,"offX":50.0,"radius":20.0,"refActorNPCNameID":14592,"refActorRequireCast":true,"refActorCastId":[48600],"refActorComparisonType":6,"includeRotation":true,"AdditionalRotation":4.712389,"Conditional":true},{"Name":"テキスト","type":1,"radius":0.0,"fillIntensity":0.5,"overlayTextColor":3355443455,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"近づく","refActorType":1}]}
~Lv2~{"Name":"貪食のガトラー_グラトナス・クランチ","Group":"闘獣練:第三盤","ZoneLockH":[1341],"ElementsL":[{"Name":"円","type":1,"radius":40.0,"refActorNPCNameID":14592,"refActorRequireCast":true,"refActorCastId":[48603],"refActorComparisonType":6,"includeRotation":true,"AdditionalRotation":4.712389,"Conditional":true},{"Name":"テキスト","type":1,"radius":0.0,"fillIntensity":0.5,"overlayTextColor":3355443455,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"離れる","refActorType":1}]}
~Lv2~{"Name":"貪食のガトラー_バーチカルドライブ","Group":"闘獣練:第三盤","ZoneLockH":[1341],"ElementsL":[{"Name":"直線","type":3,"refX":-30.0,"offX":30.0,"radius":10.0,"fillIntensity":0.5,"refActorNPCNameID":14592,"refActorRequireCast":true,"refActorCastId":[48604,48605],"refActorComparisonType":6,"includeRotation":true,"onlyVisible":true,"AdditionalRotation":1.5707964}]}
~Lv2~{"Name":"貪食のガトラー_支配の魔刃","Group":"闘獣練:第三盤","ZoneLockH":[1341],"ElementsL":[{"Name":"直線","type":1,"radius":0.0,"fillIntensity":0.5,"overlayVOffset":1.0,"overlayFScale":3.0,"thicc":4.0,"overlayText":"左右の鎧に当てない","refActorNPCNameID":14592,"refActorRequireCast":true,"refActorCastId":[48614,48612],"refActorComparisonType":6,"onlyVisible":true,"tether":true,"ExtraTetherLength":20.0,"AdditionalRotation":4.712389}]}
~Lv2~{"Name":"貪食のガトラー_魔刃結界","Group":"闘獣練:第三盤","ZoneLockH":[1341],"ElementsL":[{"Name":"AoE_1","type":3,"refY":-15.0,"offY":15.0,"radius":5.0,"fillIntensity":0.5,"refActorNPCID":2015427,"refActorComparisonType":4},{"Name":"AoE_2","type":3,"refY":-5.0,"offY":5.0,"radius":15.0,"fillIntensity":0.5,"refActorNPCID":2015427,"refActorComparisonType":4}]}
魔眼の義眼を表示
C# / Splatoon Script
using ECommons.DalamudServices;
using Splatoon.SplatoonScripting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;

namespace SplatoonScriptsOfficial.Duties;

/// <summary>
/// 闘獣練第三盤 - カトブレパス・ピース「魔眼」安全地帯 v1.5
///
/// v1.5:
/// ・v1.4のSAFE誘導ロジックを維持
/// ・Action #48509「魔眼移植」を検出したフェーズでは、輪状爆発に視線攻撃が付くものとして扱う
/// ・視線付き輪状では、SAFEとは別に「視線」方向マーカーを表示
/// ・方向マーカーは輪状魔眼から離れる向きを示す
/// ・デバッグ用PluginLog出力をすべて削除
/// ・外周へ向かう円状(R>=13.5)を輪状誘導より優先して回避
/// ・輪状中央が迫る円状25m内なら中央へ誘導せず、輪状内側安全円内で円状範囲外を探索
/// ・輪状ターゲットはロックし、Action #48507 輪状爆発を検出した瞬間だけ次へ切替
/// ・輪状中央5m以内が円状で完全に埋まる場合は、円状25m外への退避を最優先
/// ・円状回避後は再び輪状中央へ誘導
/// ・輪状SAFEは原則として魔眼中央へ固定
/// ・円状が中央を覆う時だけ、輪状の内側5m安全円内で円状範囲外を探索
/// ・輪状の移動開始順を単調増加番号で保持し、消滅による順番重複を防止
/// ・SAFEマーカー半径を2.5mへ拡大
/// ・輪状爆発(19613): 出現後に「動き出した順」を記録し、その順番を優先
/// ・円状爆発(19612): 一度中心側へ入った後、再び外周側(R>=19m)へ出た個体を爆発直前として優先
/// ・円状と輪状を別ルールで管理し、次に危険な魔眼を選んでSAFEを計算
///
/// ログ観察値:
/// ・円状魔眼は中心付近を通過後、R=13.6 -> 17.0 -> 19.6付近で爆発
/// ・輪状魔眼は移動開始順に爆発する傾向
/// </summary>
internal class CatoblepasPieceEyeSafeSpotV152 : SplatoonScript
{
    public override Metadata Metadata => new(
        15,
        "ハイネ",
        "闘獣練第三盤 - カトブレパス・ピース「魔眼」安全地帯 v1.5.2"
    );

    public override HashSet<uint>? ValidTerritories => [1341];

    private const uint CircleEyeDataId = 19612;
    private const uint DonutEyeDataId = 19613;
    private const uint DonutExplosionActionId = 48507;
    
    private const float CircleRadius = 25.0f;
    private const float DonutInnerRadius = 5.0f;
    private const float DonutOuterRadius = 25.0f;

    private static readonly Vector2 ArenaCenter = new(120.0f, -420.0f);

    private const float SearchRadius = 20.0f;
    private const float SafetyMargin = 0.5f;
    private const float GridStep = 0.5f;

    // 円状魔眼:
    // 一度この距離より内側へ入ったら「中心側を通過した」とみなす。
    private const float CircleInnerPassRadius = 12.0f;

    // 中心側を通過した円状魔眼が、再びこの距離まで外へ出たら爆発直前扱い。
    // ログでは最終個体が R=19.6 付近で爆発。
    private const float CircleTriggerRadius = 19.0f;

    // 円状魔眼を少し早めに予告対象へ入れる距離。
    private const float CirclePreTriggerRadius = 13.5f;

    // 輪状魔眼が「動き出した」と判定する移動量。
    private const float DonutMoveStartDistance = 0.8f;

    // 爆発直前の円状と次の輪状を同時に見る場合の最大数。
    private const int MaxActiveEyes = 2;

    private readonly Dictionary<uint, EyeTrack> tracks = new();
    private readonly List<uint> donutMoveOrder = new();
    private int nextDonutMoveOrder = 0;
    // v1.4: 輪状ターゲットを固定する。
    // 切替は現在ターゲットの輪状爆発(48507)を検出した時だけ行う。
    private uint? lockedDonutEntityId;
    private readonly HashSet<uint> completedDonuts = new();
    private bool advanceDonutRequested;


    private Vector2? previousSafeSpot;
    private bool gazePhaseActive;

    public override void OnSetup()
    {
        Controller.TryRegisterElement("RecommendedSafeSpot", new(0)
        {
            Enabled = false,
            thicc = 6,
            tether = true,
            radius = 2.5f,
            Filled = true,
            fillIntensity = 0.35f,
            overlayText = "SAFE",
            overlayFScale = 2.0f,
            color = 0xFF00FF00,
        });

        Controller.TryRegisterElement("LookAwayDirection", new(0)
        {
            Enabled = false,
            thicc = 5,
            tether = true,
            radius = 1.0f,
            Filled = true,
            fillIntensity = 0.25f,
            overlayText = "視線",
            overlayFScale = 1.5f,
        });
    }

    public override void OnReset()
    {
        tracks.Clear();
        donutMoveOrder.Clear();
        nextDonutMoveOrder = 0;
        lockedDonutEntityId = null;
        completedDonuts.Clear();
        advanceDonutRequested = false;
        previousSafeSpot = null;
        gazePhaseActive = false;

        HideMarker();
        HideLookAwayMarker();
    }

    public override void OnMessage(string Message)
    {
        // 輪状爆発48507のActionメッセージだけで現在の輪状を完了扱いにする。
        if (Message.Contains("Action #48507") &&
            Message.Contains("輪状爆発") &&
            Message.Contains("19613/魔眼"))
        {
            advanceDonutRequested = true;
        }

        // 「魔眼移植」48509が発生するフェーズでは、
        // 実測ログ上、輪状爆発48507と同時に悪魔の義眼48510が発生する。
        // そのため以後の輪状を視線付きとして方向案内する。
        if (Message.Contains("Action #48509") &&
            Message.Contains("魔眼移植") &&
            Message.Contains("19611/カトブレパス・ピース"))
        {
            gazePhaseActive = true;
        }
    }

    public override void OnUpdate()
    {
        var player = BasePlayer;
        if (player == null)
        {
            HideMarker();
            HideLookAwayMarker();
            return;
        }

        var objects = Svc.Objects
            .Where(x => x != null &&
                       (x.DataId == CircleEyeDataId ||
                        x.DataId == DonutEyeDataId))
            .ToList();

        if (objects.Count == 0)
        {
            tracks.Clear();
            donutMoveOrder.Clear();
            nextDonutMoveOrder = 0;
            lockedDonutEntityId = null;
            completedDonuts.Clear();
            advanceDonutRequested = false;
            previousSafeSpot = null;
            gazePhaseActive = false;
            HideMarker();
            HideLookAwayMarker();
            return;
        }

        var nowIds = objects.Select(x => x.EntityId).ToHashSet();

        // 消滅した魔眼を追跡対象から除外。
        foreach (var id in tracks.Keys.Where(id => !nowIds.Contains(id)).ToList())
            tracks.Remove(id);

        donutMoveOrder.RemoveAll(id => !nowIds.Contains(id));

        // 現在位置から追跡情報を更新。
        foreach (var obj in objects)
        {
            var pos = new Vector2(obj.Position.X, obj.Position.Z);
            float r = Vector2.Distance(pos, ArenaCenter);
            var kind = obj.DataId == CircleEyeDataId ? EyeKind.Circle : EyeKind.Donut;

            if (!tracks.TryGetValue(obj.EntityId, out var track))
            {
                track = new EyeTrack
                {
                    EntityId = obj.EntityId,
                    DataId = obj.DataId,
                    Kind = kind,
                    SpawnPosition = pos,
                    PreviousPosition = pos,
                    Position = pos,
                    PreviousRadius = r,
                    Radius = r,
                    MinRadius = r,
                };

                tracks[obj.EntityId] = track;
            }
            else
            {
                track.PreviousPosition = track.Position;
                track.PreviousRadius = track.Radius;
                track.Position = pos;
                track.Radius = r;
                track.MinRadius = MathF.Min(track.MinRadius, r);
            }

            if (kind == EyeKind.Circle)
            {
                // 開始直後の外周位置では発動直前と誤判定しない。
                // 一度内側へ入った事実を必須にする。
                if (r <= CircleInnerPassRadius)
                    track.CirclePassedInside = true;

                // 内側通過後に半径が増えている = 反対側の外周へ向かっている。
                if (track.CirclePassedInside &&
                    r >= track.MinRadius + 1.0f)
                {
                    track.CircleMovingOutward = true;
                }
            }
            else
            {
                // 輪状は「出現位置から実際に動いた瞬間」を順番として記録。
                if (!track.DonutMoveStarted &&
                    Vector2.Distance(pos, track.SpawnPosition) >= DonutMoveStartDistance)
                {
                    track.DonutMoveStarted = true;
                    track.DonutMoveOrder = nextDonutMoveOrder++;
                    donutMoveOrder.Add(track.EntityId);
                }
            }
        }

        var allEyes = tracks.Values.ToList();

        // v1.4:
        // 現在ロック中の輪状が48507を発動した時だけ完了扱いにし、
        // 次の移動開始順の輪状へ進める。
        if (advanceDonutRequested)
        {
            if (lockedDonutEntityId.HasValue)
                completedDonuts.Add(lockedDonutEntityId.Value);

            lockedDonutEntityId = null;
            advanceDonutRequested = false;
        }

        UpdateDonutLock(allEyes);

        var activeEyes = SelectNextDangerEyes(allEyes);

        if (activeEyes.Count == 0)
        {
            HideMarker();
            HideLookAwayMarker();
            return;
        }

        var playerPosition = new Vector2(player.Position.X, player.Position.Z);
        Vector2? safeSpot;

        // v1.4:
        // 輪状爆発が次の候補にある場合は、原則として「輪状魔眼そのものの中心」をSAFEにする。
        // これによりプレイヤー位置を基準にしたグリッド探索で外周側へ引っ張られたり、
        // 魔眼移動中にSAFEがプルプルする問題を防ぐ。
        var nextDonut = SelectGuidanceDonut(allEyes, activeEyes);

        if (nextDonut != null)
        {
            var donutCenter = nextDonut.Position;

            // 爆発直前の円状が輪状中心を覆う場合だけ例外。
            // その場合も輪状の安全円(中心から5m未満)の中から、
            // 円状25m範囲外となる地点を探す。
            var blockingCircles = allEyes
                .Where(x =>
                    x.Kind == EyeKind.Circle &&
                    x.CirclePassedInside &&
                    x.CircleMovingOutward &&
                    x.Radius >= CirclePreTriggerRadius &&
                    Vector2.Distance(x.Position, donutCenter)
                        <= CircleRadius + SafetyMargin)
                .ToList();

            if (blockingCircles.Count == 0)
            {
                safeSpot = donutCenter;
            }
            else
            {
                // 第1優先:
                // 輪状中央5m以内に残れるなら、その中で円状25m外を探す。
                safeSpot = FindSafeInsideDonut(
                    playerPosition,
                    nextDonut,
                    blockingCircles
                );

                // 第2優先:
                // 輪状中央5m以内が円状で完全に埋まる場合は、
                // 輪状中央への誘導を一旦諦め、円状25m外へ退避する。
                // 円状回避後は blockingCircles が外れるため、
                // 次の更新で再び輪状中央へSAFEが戻る。
                if (!safeSpot.HasValue)
                {
                    safeSpot = FindCircleEvacuationSpot(
                        playerPosition,
                        blockingCircles,
                        nextDonut
                    );
                }
            }
        }
        else
        {
            // 円状だけが次候補の場合は従来の探索。
            safeSpot = FindRecommendedSafeSpot(playerPosition, activeEyes);
        }

        if (!Controller.TryGetElementByName("RecommendedSafeSpot", out var marker))
            return;

        if (!safeSpot.HasValue)
        {
            marker.Enabled = false;
            HideLookAwayMarker();
            return;
        }

        previousSafeSpot = safeSpot.Value;

        marker.refX = safeSpot.Value.X;
        marker.refY = safeSpot.Value.Y;
        marker.Enabled = true;

        UpdateLookAwayMarker(safeSpot.Value, nextDonut);
    }

    private EyeTrack? SelectGuidanceDonut(
        List<EyeTrack> allEyes,
        List<EyeTrack> activeEyes)
    {
        if (!lockedDonutEntityId.HasValue)
            return null;

        return allEyes.FirstOrDefault(x =>
            x.Kind == EyeKind.Donut &&
            x.EntityId == lockedDonutEntityId.Value);
    }

    private void UpdateDonutLock(List<EyeTrack> allEyes)
    {
        // 既にロック済みで、その個体がまだ存在するなら絶対に変更しない。
        if (lockedDonutEntityId.HasValue &&
            allEyes.Any(x =>
                x.Kind == EyeKind.Donut &&
                x.EntityId == lockedDonutEntityId.Value))
        {
            return;
        }

        // 消滅だけで勝手に「次へ完了」とはしない。
        // ただし48507後にロック解除済みなら、次の未完了個体を選ぶ。
        lockedDonutEntityId = null;

        var next = allEyes
            .Where(x =>
                x.Kind == EyeKind.Donut &&
                x.DonutMoveStarted &&
                !completedDonuts.Contains(x.EntityId))
            .OrderBy(x => x.DonutMoveOrder)
            .FirstOrDefault();

        if (next != null)
        {
            lockedDonutEntityId = next.EntityId;
        }
    }

    private List<EyeTrack> SelectNextDangerEyes(List<EyeTrack> allEyes)
    {
        var result = new List<EyeTrack>();

        // ------------------------------------------------------------
        // 1. 円状爆発
        // ------------------------------------------------------------
        // 一度中心側を通過し、反対側へ向かっている円状だけを見る。
        // R>=19 を最優先。まだ19未満でも R>=16 なら予告対象。
        var circles = allEyes
            .Where(x => x.Kind == EyeKind.Circle &&
                        x.CirclePassedInside &&
                        x.CircleMovingOutward)
            .OrderByDescending(x => x.Radius)
            .ToList();

        var imminentCircle = circles
            .FirstOrDefault(x => x.Radius >= CircleTriggerRadius);

        if (imminentCircle != null)
        {
            result.Add(imminentCircle);
        }
        else
        {
            var preCircle = circles
                .FirstOrDefault(x => x.Radius >= CirclePreTriggerRadius);

            if (preCircle != null)
                result.Add(preCircle);
        }

        // ------------------------------------------------------------
        // 2. 輪状爆発
        // ------------------------------------------------------------
        // 「動き出した順」で、まだ存在している最古の輪状を次発候補とする。
        var nextDonut = lockedDonutEntityId.HasValue
            ? allEyes.FirstOrDefault(x =>
                x.Kind == EyeKind.Donut &&
                x.EntityId == lockedDonutEntityId.Value)
            : null;

        if (nextDonut != null && result.Count < MaxActiveEyes)
            result.Add(nextDonut);

        // ------------------------------------------------------------
        // v1.4では未始動輪状への暫定誘導を廃止。
        // 最初の輪状が実際に動き始めるまでSAFEを輪状間で飛ばさない。

        return result;
    }

    private Vector2? FindCircleEvacuationSpot(
        Vector2 playerPosition,
        List<EyeTrack> blockingCircles,
        EyeTrack nextDonut)
    {
        Vector2? bestPoint = null;
        float bestScore = float.MaxValue;

        for (float x = ArenaCenter.X - SearchRadius;
             x <= ArenaCenter.X + SearchRadius;
             x += GridStep)
        {
            for (float z = ArenaCenter.Y - SearchRadius;
                 z <= ArenaCenter.Y + SearchRadius;
                 z += GridStep)
            {
                var point = new Vector2(x, z);

                if (Vector2.Distance(point, ArenaCenter) > SearchRadius)
                    continue;

                // 円状25m + 安全マージンの外側を必須条件とする。
                bool circleSafe = true;
                foreach (var circle in blockingCircles)
                {
                    if (Vector2.Distance(point, circle.Position)
                        <= CircleRadius + SafetyMargin)
                    {
                        circleSafe = false;
                        break;
                    }
                }

                if (!circleSafe)
                    continue;

                // 円状回避を最優先。
                // そのうえで、円状爆発後に輪状中央へ戻りやすい地点を選ぶ。
                float donutScore =
                    Vector2.DistanceSquared(point, nextDonut.Position);

                float playerScore =
                    Vector2.DistanceSquared(point, playerPosition) * 0.15f;

                float score = donutScore + playerScore;

                if (previousSafeSpot.HasValue)
                {
                    score += Vector2.DistanceSquared(
                        point,
                        previousSafeSpot.Value
                    ) * 0.05f;
                }

                if (score < bestScore)
                {
                    bestScore = score;
                    bestPoint = point;
                }
            }
        }

        return bestPoint;
    }

    private Vector2? FindSafeInsideDonut(
        Vector2 playerPosition,
        EyeTrack donut,
        List<EyeTrack> blockingCircles)
    {
        Vector2? bestPoint = null;
        float bestScore = float.MaxValue;

        // 輪状爆発の内側5mより少し余裕を持たせる。
        float maxInnerRadius = MathF.Max(
            0.5f,
            DonutInnerRadius - SafetyMargin
        );

        for (float dx = -maxInnerRadius;
             dx <= maxInnerRadius;
             dx += GridStep)
        {
            for (float dz = -maxInnerRadius;
                 dz <= maxInnerRadius;
                 dz += GridStep)
            {
                var point = donut.Position + new Vector2(dx, dz);

                // 必ず輪状爆発の中央安全円内に収める。
                if (Vector2.Distance(point, donut.Position) >= maxInnerRadius)
                    continue;

                if (Vector2.Distance(point, ArenaCenter) > SearchRadius)
                    continue;

                bool circleSafe = true;

                foreach (var circle in blockingCircles)
                {
                    if (Vector2.Distance(point, circle.Position)
                        <= CircleRadius + SafetyMargin)
                    {
                        circleSafe = false;
                        break;
                    }
                }

                if (!circleSafe)
                    continue;

                // まず輪状中心に近いことを最優先。
                // 同程度ならプレイヤーから近い方を選ぶ。
                float centerScore =
                    Vector2.DistanceSquared(point, donut.Position) * 100.0f;

                float playerScore =
                    Vector2.DistanceSquared(point, playerPosition) * 0.05f;

                float score = centerScore + playerScore;

                if (score < bestScore)
                {
                    bestScore = score;
                    bestPoint = point;
                }
            }
        }

        return bestPoint;
    }

    private Vector2? FindRecommendedSafeSpot(
        Vector2 playerPosition,
        List<EyeTrack> activeEyes)
    {
        Vector2? bestPoint = null;
        float bestScore = float.MaxValue;

        for (float x = ArenaCenter.X - SearchRadius;
             x <= ArenaCenter.X + SearchRadius;
             x += GridStep)
        {
            for (float z = ArenaCenter.Y - SearchRadius;
                 z <= ArenaCenter.Y + SearchRadius;
                 z += GridStep)
            {
                var point = new Vector2(x, z);

                if (Vector2.Distance(point, ArenaCenter) > SearchRadius)
                    continue;

                if (!IsSafe(point, activeEyes))
                    continue;

                float score = Vector2.DistanceSquared(point, playerPosition);

                if (previousSafeSpot.HasValue)
                {
                    score += Vector2.DistanceSquared(
                        point,
                        previousSafeSpot.Value
                    ) * 0.10f;
                }

                score -= ClearanceBonus(point, activeEyes);

                if (score < bestScore)
                {
                    bestScore = score;
                    bestPoint = point;
                }
            }
        }

        return bestPoint;
    }

    private static bool IsSafe(Vector2 point, List<EyeTrack> eyes)
    {
        foreach (var eye in eyes)
        {
            float distance = Vector2.Distance(point, eye.Position);

            if (eye.Kind == EyeKind.Circle)
            {
                if (distance <= CircleRadius + SafetyMargin)
                    return false;
            }
            else
            {
                float inner = MathF.Max(
                    0.0f,
                    DonutInnerRadius - SafetyMargin
                );

                float outer = DonutOuterRadius + SafetyMargin;

                if (distance >= inner && distance <= outer)
                    return false;
            }
        }

        return true;
    }

    private static float ClearanceBonus(
        Vector2 point,
        List<EyeTrack> eyes)
    {
        float bonus = 0.0f;

        foreach (var eye in eyes)
        {
            float d = Vector2.Distance(point, eye.Position);

            if (eye.Kind == EyeKind.Circle)
            {
                float clearance = d - CircleRadius;
                if (clearance > 0)
                    bonus += MathF.Min(clearance, 3.0f) * 0.25f;
            }
            else
            {
                if (d < DonutInnerRadius)
                {
                    float clearance = DonutInnerRadius - d;
                    bonus += MathF.Min(clearance, 2.0f) * 0.25f;
                }
                else if (d > DonutOuterRadius)
                {
                    float clearance = d - DonutOuterRadius;
                    bonus += MathF.Min(clearance, 3.0f) * 0.25f;
                }
            }
        }

        return bonus;
    }

    private void UpdateLookAwayMarker(Vector2 safeSpot, EyeTrack? nextDonut)
    {
        if (!gazePhaseActive || nextDonut == null)
        {
            HideLookAwayMarker();
            return;
        }

        if (!Controller.TryGetElementByName("LookAwayDirection", out var marker))
            return;

        // 視線誘導は「輪状魔眼の中心 → 現在のプレイヤー位置」の方向を使う。
        // つまりプレイヤーを基準に、対象の輪状魔眼とは正反対側へ誘導線を伸ばす。
        var player = BasePlayer;
        if (player == null)
        {
            HideLookAwayMarker();
            return;
        }

        var playerPosition = new Vector2(player.Position.X, player.Position.Z);
        var away = playerPosition - nextDonut.Position;

        if (away.LengthSquared() < 0.01f)
        {
            // プレイヤーと魔眼中心がほぼ同一点の場合のみ、
            // SAFE位置を補助方向として使用する。
            away = playerPosition - ArenaCenter;
            if (away.LengthSquared() < 0.01f)
                away = new Vector2(0.0f, -1.0f);
        }

        away = Vector2.Normalize(away);

        // 誘導線は必ず「現在のプレイヤー位置」から反対側へ伸ばす。
        var lookPoint = playerPosition + away * 4.0f;

        marker.refX = lookPoint.X;
        marker.refY = lookPoint.Y;
        marker.Enabled = true;
    }

    private void HideLookAwayMarker()
    {
        if (Controller.TryGetElementByName("LookAwayDirection", out var marker))
            marker.Enabled = false;
    }

    private void HideMarker()
    {
        if (Controller.TryGetElementByName("RecommendedSafeSpot", out var marker))
            marker.Enabled = false;
    }

    private sealed class EyeTrack
    {
        public uint EntityId;
        public uint DataId;
        public EyeKind Kind;

        public Vector2 SpawnPosition;
        public Vector2 PreviousPosition;
        public Vector2 Position;

        public float PreviousRadius;
        public float Radius;
        public float MinRadius;

        public bool CirclePassedInside;
        public bool CircleMovingOutward;

        public bool DonutMoveStarted;
        public int DonutMoveOrder = int.MaxValue;
    }

    private enum EyeKind
    {
        Circle,
        Donut
    }
}
特一盤を表示
JSON / Splatoon Layout
~Lv2~{"Name":"1戦目_クエイガの書","Group":"闘獣練:特一盤","ZoneLockH":[1342],"ElementsL":[{"Name":"条件","type":1,"refActorNPCID":14596,"refActorRequireCast":true,"refActorCastId":[48657],"refActorComparisonType":4,"Conditional":true,"Nodraw":true},{"Name":"テキスト","type":1,"radius":0.0,"fillIntensity":0.5,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"レビテト","refActorType":1},{"Name":"線","Enabled":false}]}
~Lv2~{"Name":"1戦目_ウォタガの書","Group":"闘獣練:特一盤","ZoneLockH":[1342],"ElementsL":[{"Name":"条件","type":1,"refActorNPCID":14596,"refActorRequireCast":true,"refActorCastId":[48658],"refActorComparisonType":4,"Conditional":true,"Nodraw":true},{"Name":"テキスト","type":1,"radius":0.0,"fillIntensity":0.5,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"カッパ","refActorType":1}]}
~Lv2~{"Name":"1戦目_マジックハンマーの書","Group":"闘獣練:特一盤","ZoneLockH":[1342],"ElementsL":[{"Name":"条件","type":1,"refActorNPCID":14596,"refActorRequireCast":true,"refActorCastId":[48659],"refActorComparisonType":4,"Conditional":true,"Nodraw":true},{"Name":"テキスト","type":1,"radius":0.0,"fillIntensity":0.5,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"プリン","refActorType":1}]}
~Lv2~{"Name":"1戦目_魔力爆散","Group":"闘獣練:特一盤","ZoneLockH":[1342],"ElementsL":[{"Name":"AoE","type":1,"radius":15.0,"refActorNPCNameID":14597,"refActorRequireCast":true,"refActorCastId":[48665],"refActorUseCastTime":true,"refActorCastTimeMin":2.7,"refActorCastTimeMax":6.7,"refActorComparisonType":6}]}
~Lv2~{"Name":"4戦目_円輪連斬","Group":"闘獣練:特一盤","ZoneLockH":[1342],"ElementsL":[{"Name":"AoE_円","type":1,"radius":13.0,"refActorNPCID":14608,"refActorRequireCast":true,"refActorCastId":[48720],"refActorUseCastTime":true,"refActorCastTimeMax":5.7,"refActorComparisonType":4},{"Name":"AoE_輪","type":1,"radius":13.0,"Donut":30.0,"fillIntensity":0.5,"refActorNPCID":14608,"refActorRequireCast":true,"refActorCastId":[48721],"refActorUseCastTime":true,"refActorCastTimeMin":5.7,"refActorCastTimeMax":7.7,"refActorComparisonType":4}]}
~Lv2~{"Name":"4戦目_突進連斬","Group":"闘獣練:特一盤","ZoneLockH":[1342],"DCond":5,"UseTriggers":true,"Triggers":[{"Type":2,"Duration":5.0,"Match":"(14608>48717)","MatchDelay":8.6}],"ElementsL":[{"Name":"AoE","type":4,"radius":40.0,"coneAngleMin":-90,"coneAngleMax":90,"refActorNPCID":14608,"refActorUseCastTime":true,"refActorCastTimeMax":5.7,"refActorComparisonType":4,"includeRotation":true,"onlyTargetable":true}]}
~Lv2~{"Name":"4戦目_衝波五連斬","Group":"闘獣練:特一盤","ZoneLockH":[1342],"DCond":5,"UseTriggers":true,"Triggers":[{"Type":2,"Duration":13.0,"Match":"(14608>50695)"}],"ElementsL":[{"Name":"テキスト","type":1,"radius":0.0,"fillIntensity":0.5,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"最後ノックバック","refActorType":1}]}
~Lv2~{"Name":"6戦目右_ラスリングブリーズ","Group":"闘獣練:特一盤","ZoneLockH":[1342],"ElementsL":[{"Name":"AoE_前","type":4,"radius":40.0,"coneAngleMin":-45,"coneAngleMax":45,"refActorNPCID":14618,"refActorRequireCast":true,"refActorCastId":[48778],"refActorComparisonType":4,"includeRotation":true},{"Name":"AoE_左","type":4,"radius":40.0,"coneAngleMin":-165,"coneAngleMax":-15,"refActorNPCID":14618,"refActorRequireCast":true,"refActorCastId":[48779],"refActorComparisonType":4,"includeRotation":true},{"Name":"AoE_右","type":4,"radius":40.0,"coneAngleMin":15,"coneAngleMax":165,"refActorNPCID":14618,"refActorRequireCast":true,"refActorCastId":[48780],"refActorComparisonType":4,"includeRotation":true}]}
~Lv2~{"Name":"6戦目右_アーボリアルストーム","Group":"闘獣練:特一盤","ZoneLockH":[1342],"ElementsL":[{"Name":"AoE_1","type":1,"radius":12.0,"refActorNPCID":14618,"refActorRequireCast":true,"refActorCastId":[48771],"refActorUseCastTime":true,"refActorCastTimeMax":4.7,"refActorComparisonType":4,"includeRotation":true},{"Name":"AoE_2","type":1,"radius":12.0,"Donut":6.0,"refActorNPCID":14618,"refActorRequireCast":true,"refActorCastId":[48772],"refActorUseCastTime":true,"refActorCastTimeMin":4.7,"refActorCastTimeMax":6.7,"refActorComparisonType":4,"includeRotation":true},{"Name":"AoE_3","type":1,"radius":18.0,"Donut":6.0,"refActorNPCID":14618,"refActorRequireCast":true,"refActorCastId":[48773],"refActorUseCastTime":true,"refActorCastTimeMin":6.7,"refActorCastTimeMax":8.7,"refActorComparisonType":4,"includeRotation":true}]}
~Lv2~{"Name":"8戦目_トキシックブレス","Group":"闘獣練:特一盤","ZoneLockH":[1342],"ElementsL":[{"Name":"AoE","type":4,"radius":40.0,"coneAngleMin":-60,"coneAngleMax":60,"fillIntensity":0.5,"refActorNPCID":14628,"refActorRequireCast":true,"refActorCastId":[48807],"refActorUseCastTime":true,"refActorCastTimeMax":11.7,"refActorUseOvercast":true,"refActorComparisonType":4,"includeRotation":true,"onlyTargetable":true}]}
~Lv2~{"Name":"8戦目_トキシックヴォミット","Group":"闘獣練:特一盤","ZoneLockH":[1342],"ElementsL":[{"Name":"条件","type":1,"refActorNPCID":14628,"refActorRequireCast":true,"refActorCastId":[48809],"refActorComparisonType":4,"Conditional":true,"Nodraw":true},{"Name":"テキスト","type":1,"radius":0.0,"fillIntensity":0.5,"overlayTextColor":3355508480,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"4連沼捨て","refActorType":1}]}
~Lv2~{"Name":"8戦目_リグルフレム","Group":"闘獣練:特一盤","ZoneLockH":[1342],"ElementsL":[{"Name":"条件","type":1,"refActorNPCID":14628,"refActorRequireCast":true,"refActorCastId":[48817],"refActorComparisonType":4,"Conditional":true,"Nodraw":true},{"Name":"テキスト","type":1,"radius":0.0,"fillIntensity":0.5,"overlayTextColor":3355443455,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"沼から離れる","refActorType":1}]}
~Lv2~{"Name":"8戦目_カータライズ","Group":"闘獣練:特一盤","ZoneLockH":[1342],"ElementsL":[{"Name":"AoE","type":3,"offY":40.0,"radius":10.0,"refActorNPCID":14628,"refActorRequireCast":true,"refActorCastId":[48814],"refActorComparisonType":4,"includeRotation":true}]}
特二盤を表示
JSON / Splatoon Layout
~Lv2~{"Name":"フラウロス・ピース_チャージドライトリング","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"AoE","type":3,"offY":40.0,"radius":20.0,"refActorNPCID":14631,"refActorRequireCast":true,"refActorCastId":[49193],"refActorComparisonType":4,"includeRotation":true}]}
~Lv2~{"Name":"フラウロス・ピース_エレクトロショック","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"AoE","type":1,"radius":16.0,"refActorNPCNameID":14631,"refActorRequireCast":true,"refActorCastId":[49191],"refActorComparisonType":6}]}
~Lv2~{"Name":"ドレイク・ピース_バーニングサイクロン","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"AoE","type":4,"radius":40.0,"coneAngleMin":-60,"coneAngleMax":60,"refActorNPCNameID":14651,"refActorRequireCast":true,"refActorCastId":[49256],"refActorComparisonType":6,"includeRotation":true}]}
~Lv2~{"Name":"ドレイク・ピース_火球","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"爆発範囲","type":1,"radius":4.0,"color":3355508480,"fillIntensity":0.1,"refActorNPCID":14652,"refActorComparisonType":4}]}
~Lv2~{"Name":"ドレイク・ピース_火炎旋風","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"AoE","type":1,"radius":3.5,"Donut":40.0,"refActorNPCNameID":14654,"refActorRequireCast":true,"refActorCastId":[49259],"refActorComparisonType":6}]}
~Lv2~{"Name":"マインドフレア・ピース_ヴォイド・サンダガ","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"AoE_1","type":3,"refY":-40.0,"offY":40.0,"radius":5.0,"fillIntensity":0.5,"refActorNPCNameID":14633,"refActorRequireCast":true,"refActorCastId":[49207],"refActorComparisonType":6,"includeRotation":true},{"Name":"AoE_2","type":3,"refY":-5.0,"offY":5.0,"radius":40.0,"fillIntensity":0.5,"refActorNPCNameID":14633,"refActorRequireCast":true,"refActorCastId":[49207],"refActorComparisonType":6,"includeRotation":true}]}
~Lv2~{"Name":"マインドフレア・ピース_ダークストリーム","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"AoE_細","type":3,"refY":-40.0,"offY":40.0,"radius":2.0,"fillIntensity":0.5,"refActorNPCNameID":14637,"refActorRequireCast":true,"refActorCastId":[49203],"refActorComparisonType":6,"includeRotation":true},{"Name":"AoE_太","type":3,"refY":-40.0,"offY":40.0,"radius":5.0,"fillIntensity":0.5,"refActorNPCNameID":14637,"refActorRequireCast":true,"refActorCastId":[49204],"refActorComparisonType":6,"includeRotation":true}]}
~Lv2~{"Name":"マインドフレア・ピース_飛散","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"円","type":1,"radius":6.0,"refActorNPCNameID":14634,"refActorRequireCast":true,"refActorCastId":[49196],"refActorComparisonType":6}]}
~Lv2~{"Name":"マインドフレア・ピース_菌床","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"円","type":1,"radius":6.0,"refActorNPCID":14635,"refActorComparisonType":4}]}
~Lv2~{"Name":"ドゥルガー・ピース_電気放出","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"AoE_大","type":1,"radius":20.0,"refActorNPCNameID":14657,"refActorRequireCast":true,"refActorCastId":[49265],"refActorComparisonType":6},{"Name":"AoE_小","type":1,"radius":6.0,"refActorNPCNameID":14657,"refActorRequireCast":true,"refActorCastId":[49266],"refActorComparisonType":6}]}
~Lv2~{"Name":"ドゥルガー・ピース_気化爆弾","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"条件","type":1,"refActorNPCNameID":14657,"refActorRequireCast":true,"refActorCastId":[49273],"refActorComparisonType":6,"Conditional":true,"Nodraw":true},{"Name":"テキスト","type":1,"radius":0.0,"fillIntensity":0.5,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"大ノックバック設置","refActorType":1}]}
~Lv2~{"Name":"ドゥルガー・ピース_ディフュージョンレイ","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"AoE","type":4,"radius":40.0,"coneAngleMin":-60,"coneAngleMax":60,"refActorNPCNameID":14657,"refActorRequireCast":true,"refActorCastId":[49276],"refActorComparisonType":6,"includeRotation":true}]}
~Lv2~{"Name":"メデューサ・ピース_視線","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"トリガー","type":1,"radius":0.0,"refActorTargetingYou":2,"refActorComparisonType":7,"includeRotation":true,"refActorVFXPath":"vfx/channeling/eff/chn_dark001f.avfx","refActorVFXMax":5800,"Conditional":true,"ConditionalReset":true},{"Name":"扇","type":4,"radius":20.0,"coneAngleMin":-23,"coneAngleMax":23,"refActorNPCNameID":14660,"refActorComparisonType":6,"includeRotation":true,"onlyVisible":true}]}
~Lv2~{"Name":"メデューサ・ピース_輪円連斬","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"ドーナツ","type":1,"radius":5.0,"Donut":10.0,"castAnimation":3,"refActorNPCNameID":14660,"refActorRequireCast":true,"refActorCastId":[49292],"refActorComparisonType":6},{"Name":"円","type":1,"radius":6.0,"castAnimation":3,"refActorNameIntl":{"Jp":"メデューサ・ピース"},"refActorRequireCast":true,"refActorCastId":[49292],"refActorUseCastTime":true,"refActorCastTimeMin":6.0,"refActorCastTimeMax":8.0,"refActorUseOvercast":true}]}
~Lv2~{"Name":"メデューサ・ピース_円輪連斬","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"円","type":1,"radius":6.0,"fillIntensity":0.172,"castAnimation":3,"refActorNPCNameID":14660,"refActorRequireCast":true,"refActorCastId":[49288],"refActorComparisonType":6},{"Name":"サークル","type":1,"radius":5.0,"Donut":10.0,"castAnimation":3,"refActorNPCNameID":14660,"refActorRequireCast":true,"refActorCastId":[49288],"refActorUseCastTime":true,"refActorCastTimeMin":6.0,"refActorCastTimeMax":8.0,"refActorUseOvercast":true,"refActorComparisonType":6}]}
~Lv2~{"Name":"メデューサ・ピース_衝撃波","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"衝撃波","type":4,"radius":6.0,"coneAngleMax":45,"color":3372169728,"fillIntensity":0.112,"castAnimation":3,"animationColor":3355508223,"refActorNPCNameID":14660,"refActorRequireCast":true,"refActorCastId":[49296],"refActorComparisonType":6,"includeRotation":true,"AdditionalRotation":1.1780972}]}
~Lv2~{"Name":"メデューサ・ピース_グラワー","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"直線","type":3,"refX":40.0,"radius":1.5,"refActorNPCNameID":14662,"refActorRequireCast":true,"refActorCastId":[49370],"refActorComparisonType":6,"includeRotation":true,"AdditionalRotation":4.712389}]}
~Lv2~{"Name":"スフィンクス・ピース_バニシュ","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"AoE_左","type":4,"radius":40.0,"coneAngleMin":-180,"refActorNPCNameID":14665,"refActorRequireCast":true,"refActorCastId":[49339],"refActorComparisonType":6,"includeRotation":true},{"Name":"AoE_右","type":4,"radius":40.0,"coneAngleMax":180,"refActorNPCNameID":14665,"refActorRequireCast":true,"refActorCastId":[49341],"refActorComparisonType":6,"includeRotation":true},{"Name":"AoE_円","type":1,"radius":18.0,"refActorNPCNameID":14665,"refActorRequireCast":true,"refActorCastId":[49337],"refActorComparisonType":6,"includeRotation":true},{"Name":"AoE_ドーナツ","type":1,"radius":10.0,"Donut":40.0,"fillIntensity":0.5,"refActorNPCNameID":14665,"refActorRequireCast":true,"refActorCastId":[49335],"refActorComparisonType":6,"includeRotation":true}]}
~Lv2~{"Name":"スフィンクス・ピース_数の謎かけ","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"テキスト_3の倍数","type":1,"radius":0.0,"fillIntensity":0.5,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"3, 6, 9","refActorRequireBuff":true,"refActorBuffId":[5151],"refActorType":1},{"Name":"テキスト_偶数","type":1,"radius":0.0,"fillIntensity":0.5,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"2, 4, 6, 8","refActorRequireBuff":true,"refActorBuffId":[5148],"refActorType":1},{"Name":"テキスト_素数","type":1,"radius":0.0,"fillIntensity":0.5,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"2, 3, 5, 7","refActorRequireBuff":true,"refActorBuffId":[5150],"refActorType":1}]}
~Lv2~{"Name":"スフィンクス・ピース_記憶の謎かけ","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"テキスト_プギル","type":1,"radius":0.0,"fillIntensity":0.5,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"水棲綱","refActorNPCID":14667,"refActorComparisonType":4},{"Name":"テキスト_オポオポ","type":1,"radius":0.0,"fillIntensity":0.5,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"百獣綱","refActorNPCNameID":14668,"refActorComparisonType":6},{"Name":"テキスト_プーク","type":1,"radius":0.0,"fillIntensity":0.5,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"甲鱗綱","refActorNPCNameID":14669,"refActorComparisonType":6},{"Name":"テキスト_ドードー","type":1,"radius":0.0,"fillIntensity":0.5,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"有翼綱","refActorNPCNameID":14666,"refActorComparisonType":6}]}
~Lv2~{"Name":"キマイラ・ピース_雷電の大咆哮","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"サークル","type":1,"radius":8.0,"Donut":10.0,"refActorNPCNameID":14663,"refActorRequireCast":true,"refActorCastId":[49313,49316,49314],"refActorComparisonType":6}]}
~Lv2~{"Name":"キマイラ・ピース_氷結の大咆哮","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"円","type":1,"radius":12.0,"fillIntensity":0.172,"refActorNPCNameID":14663,"refActorRequireCast":true,"refActorCastId":[49310,49315],"refActorComparisonType":6}]}
~Lv2~{"Name":"キマイラ・ピース_フレイムブレス","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"扇","type":4,"radius":25.0,"coneAngleMax":240,"fillIntensity":0.172,"refActorNPCNameID":14663,"refActorRequireCast":true,"refActorCastId":[49304,49331],"refActorComparisonType":6,"includeRotation":true,"AdditionalRotation":4.1887903}]}
~Lv2~{"Name":"キマイラ・ピース_サンダーブレス","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"扇","type":4,"radius":25.0,"coneAngleMax":240,"fillIntensity":0.171,"refActorNPCNameID":14663,"refActorRequireCast":true,"refActorCastId":[49302],"refActorComparisonType":6,"includeRotation":true,"AdditionalRotation":2.0943952}]}
~Lv2~{"Name":"キマイラ・ピース_コールドブレス","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"扇","type":4,"radius":25.0,"coneAngleMax":240,"fillIntensity":0.172,"refActorNPCNameID":14663,"refActorRequireCast":true,"refActorCastId":[49326,49327,49300],"refActorComparisonType":6,"includeRotation":true}]}
~Lv2~{"Name":"キマイラ・ピース_アサルトブレストリガー―","Group":"闘獣練:特二盤","ZoneLockH":[1343],"DCond":5,"UseTriggers":true,"Triggers":[{"Type":2,"Duration":10.0,"Match":"キマイラ・ピースは「アサルトブレス」の構え。"}],"ElementsL":[{"Name":"トリガー氷","type":1,"refActorComparisonType":7,"refActorVFXPath":"vfx/common/eff/m0053_cast_frz_c0j2.avfx","refActorVFXMax":9000,"Conditional":true,"ConditionalReset":true,"Nodraw":true},{"Name":"コールドブレス","type":4,"radius":25.0,"coneAngleMax":240,"refActorNPCNameID":14663,"refActorComparisonType":6,"includeRotation":true,"onlyVisible":true},{"Name":"トリガー炎","type":1,"refActorComparisonType":7,"refActorVFXPath":"vfx/common/eff/m0053_cast_fla_c0j2.avfx","refActorVFXMax":9000,"Conditional":true,"ConditionalReset":true,"Nodraw":true},{"Name":"フレイムブレス","type":4,"radius":25.0,"coneAngleMax":240,"fillIntensity":0.172,"refActorNPCNameID":14663,"refActorComparisonType":6,"includeRotation":true,"onlyVisible":true,"AdditionalRotation":4.1887903},{"Name":"トリガー雷","type":1,"refActorComparisonType":7,"refActorVFXPath":"vfx/common/eff/m0053_cast_thd_c0j2.avfx","refActorVFXMax":9000,"Conditional":true,"ConditionalReset":true,"Nodraw":true},{"Name":"サンダーブレス","type":4,"radius":25.0,"coneAngleMax":240,"fillIntensity":0.172,"refActorNPCNameID":14663,"refActorComparisonType":6,"includeRotation":true,"onlyVisible":true,"AdditionalRotation":2.0943952}]}
~Lv2~{"Name":"キマイラ・ピース_アサルトブレステキスト","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"テキスト","type":1,"radius":0.0,"overlayVOffset":2.0,"overlayFScale":3.0,"overlayText":"離れる","refActorNPCNameID":14663,"refActorRequireCast":true,"refActorCastId":[49323,49325,49324],"TargetAlteration":1100,"refActorComparisonType":6}]}
~Lv2~{"Name":"ギガンティス・ピース_ギガンティックレイジ","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"AoE_前","type":4,"radius":30.0,"coneAngleMin":-90,"coneAngleMax":90,"refActorNPCNameID":14670,"refActorRequireCast":true,"refActorCastId":[49361],"refActorComparisonType":6,"includeRotation":true},{"Name":"AoE_後","type":4,"radius":30.0,"coneAngleMin":90,"coneAngleMax":270,"refActorNPCNameID":14670,"refActorRequireCast":true,"refActorCastId":[49363],"refActorComparisonType":6,"includeRotation":true},{"Name":"AoE_円","type":1,"radius":15.0,"refActorNPCNameID":14670,"refActorRequireCast":true,"refActorCastId":[49359],"refActorComparisonType":6,"includeRotation":true},{"Name":"条件_追炎","type":4,"radius":30.0,"coneAngleMin":90,"coneAngleMax":270,"refActorNPCNameID":14670,"refActorRequireCast":true,"refActorCastId":[49366],"refActorComparisonType":6,"includeRotation":true,"Conditional":true,"ConditionalReset":true,"Nodraw":true},{"Name":"テキスト","type":1,"Enabled":false,"radius":0.0,"fillIntensity":0.5,"overlayTextColor":3355443455,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"タケノコ離れる","refActorType":1},{"Name":"タケノコ","type":1,"radius":6.0,"refActorNPCID":14670,"refActorRequireCast":true,"refActorCastId":[49366],"refActorComparisonType":4},{"Name":"条件_追雷","type":4,"radius":30.0,"coneAngleMin":90,"coneAngleMax":270,"refActorNPCNameID":14670,"refActorRequireCast":true,"refActorCastId":[49364],"refActorComparisonType":6,"includeRotation":true,"Conditional":true,"ConditionalReset":true,"Nodraw":true},{"Name":"塔","type":1,"radius":2.0,"color":3372154880,"fillIntensity":0.5,"overlayTextColor":3355443455,"overlayVOffset":1.0,"overlayFScale":2.0,"overlayText":"塔踏む","refActorNPCNameID":14670,"refActorRequireCast":true,"refActorCastId":[49364],"refActorComparisonType":6}]}
~Lv2~{"Name":"魔斧のラウダ_バーチカルドライブ","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"AoE","type":3,"refY":-30.0,"offY":30.0,"radius":10.0,"refActorNPCNameID":14693,"refActorRequireCast":true,"refActorCastId":[49451],"refActorComparisonType":6,"includeRotation":true},{"Name":"","type":1,"Enabled":false,"fillIntensity":0.5,"refActorNPCID":14696,"refActorRequireCast":true,"refActorComparisonType":4}]}
~Lv2~{"Name":"魔斧のラウダ_支配の魔刃_3本","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"条件","type":1,"refActorNPCNameID":14693,"refActorRequireCast":true,"refActorCastId":[50846],"refActorComparisonType":6,"Conditional":true,"Nodraw":true},{"Name":"捨て場所_1","type":1,"offY":-17.5,"radius":2.5,"color":3372154880,"fillIntensity":0.5,"refActorNameIntl":{"Jp":"魔斧のラウダ"},"onlyTargetable":true},{"Name":"線_1","type":1,"offY":-17.5,"radius":0.0,"color":3372154880,"fillIntensity":0.5,"thicc":4.0,"refActorNameIntl":{"Jp":"魔斧のラウダ"},"onlyTargetable":true,"tether":true},{"Name":"捨て場所_2","type":1,"offY":17.5,"radius":2.5,"color":3372154880,"fillIntensity":0.5,"refActorNameIntl":{"Jp":"魔斧のラウダ"},"onlyTargetable":true},{"Name":"線_2","type":1,"offY":17.5,"radius":0.0,"color":3372154880,"fillIntensity":0.5,"thicc":4.0,"refActorNameIntl":{"Jp":"魔斧のラウダ"},"onlyTargetable":true,"tether":true},{"Name":"テキスト","type":1,"radius":0.0,"fillIntensity":0.5,"overlayTextColor":3372154880,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"青で捨てる","refActorType":1}]}
~Lv2~{"Enabled":false,"Name":"魔斧のラウダ_支配の魔刃_2本","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"条件","type":1,"refActorNPCNameID":14693,"refActorRequireCast":true,"refActorCastId":[50846],"refActorComparisonType":6,"Conditional":true,"Nodraw":true}]}
~Lv2~{"Name":"魔斧のラウダ_魔刃結界_赤","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"AoE","type":1,"radius":12.0,"fillIntensity":0.5,"refActorNPCID":2015453,"refActorComparisonType":4}]}
~Lv2~{"Name":"魔斧のラウダ_魔刃結界_緑","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"AoE_1","type":3,"refY":-15.0,"offY":15.0,"radius":5.0,"refActorNPCID":2015428,"refActorComparisonType":4,"includeRotation":true},{"Name":"AoE_2","type":3,"refY":-5.0,"offY":5.0,"radius":15.0,"refActorNPCID":2015428,"refActorComparisonType":4,"includeRotation":true}]}
~Lv2~{"Name":"魔斧のラウダ_魔刃の爆炎","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"距離減衰","type":1,"radius":15.0,"castAnimation":1,"refActorNPCNameID":14695,"refActorRequireCast":true,"refActorCastId":[49469],"refActorComparisonType":6}]}
~Lv2~{"Enabled":false,"Name":"魔斧のラウダ_消失の魔刃・衝波","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"線","type":3,"refY":40.0,"radius":0.1,"color":3372154880,"fillIntensity":0.5,"overlayVOffset":1.0,"overlayFScale":2.0,"thicc":0.0,"overlayText":"前に大ノックバック","refActorRequireBuff":true,"refActorBuffId":[5341],"refActorType":1,"includeRotation":true,"ExtraTetherLength":5.11}]}
~Lv2~{"Name":"魔斧のラウダ_グラトナス・クランチ","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"AoE","type":1,"radius":40.0,"refActorNPCNameID":14693,"refActorRequireCast":true,"refActorCastId":[49449],"refActorComparisonType":6,"Conditional":true},{"Name":"テキスト","type":1,"overlayTextColor":3355443455,"overlayVOffset":1.0,"overlayFScale":2.0,"overlayText":"近づく+ノックバック","refActorType":1}]}
~Lv2~{"Name":"魔斧のラウダ_グラトナス・ガッティング","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"AoE","type":3,"refY":45.0,"radius":15.0,"fillIntensity":0.5,"refActorNPCNameID":14693,"refActorRequireCast":true,"refActorCastId":[49446],"refActorComparisonType":6,"includeRotation":true,"Conditional":true},{"Name":"テキスト","type":1,"overlayTextColor":3355443455,"overlayVOffset":1.0,"overlayFScale":2.0,"overlayText":"離れる+ノックバック","refActorType":1}]}
~Lv2~{"Name":"魔斧のラウダ_爆導の魔刃","Group":"闘獣練:特二盤","ZoneLockH":[1343],"ElementsL":[{"Name":"AoE","type":1,"radius":8.0,"color":3355508480,"fillIntensity":0.1,"castAnimation":3,"animationColor":3355508480,"refActorNPCNameID":14694,"refActorRequireCast":true,"refActorCastId":[49443],"refActorComparisonType":6}]}
消失の魔刃を表示
C# / Splatoon Script
using Dalamud.Bindings.ImGui;
using Dalamud.Game.ClientState.Objects.Types;
using ECommons.Configuration;
using ECommons.DalamudServices;
using ECommons.Hooks.ActionEffectTypes;
using ECommons.ImGuiMethods;
using Splatoon;
using Splatoon.SplatoonScripting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;

namespace UserScripts.Beastmaster;

public class BST_Tokuni_ShissouNoMajin_V1_1 : SplatoonScript
{
    public override HashSet<uint>? ValidTerritories => [1343];
    public override Metadata Metadata => new(18, "5ch+ハイネ");

    private const uint CastVanish = 49481;
    private const uint CastCloneDash = 49482;

    // Actual log:
    // 隠蔽の魔刃 = base/data 19745
    private const uint BladeBaseId = 19745;

    // ActorControl seen when a group becomes active/appears.
    private const uint ActorControlCommand = 407;
    private const uint ActorControlAppear = 4562;

    private const float LineLength = 50f;
    private const float LineWidth = 2.5f;
    private const int MaxLines = 8;
    private const int AheadCount = 2;

    private readonly List<Wave> _waves = [];
    private readonly Dictionary<uint, int> _entityToWave = [];
    private readonly HashSet<uint> _seenEntities = [];

    private bool _active;
    private int _currentWave;
    private long _lastRegisterTick;

    private Config C => Controller.GetConfig<Config>();

    public override void OnSetup()
    {
        for (var i = 0; i < MaxLines; i++)
        {
            Controller.RegisterElementFromCode(
                $"line{i}",
                "{\"Name\":\"line\",\"type\":2,\"radius\":2.5,\"color\":3355508503,\"fillIntensity\":0.35,\"thicc\":2}");
        }
    }

    public override void OnStartingCast(uint source, uint castId)
    {
        if (castId != CastVanish) return;
        StartMechanic();
    }

    public override void OnActorControl(
        uint sourceId,
        uint command,
        uint p1,
        uint p2,
        uint p3,
        uint p4,
        uint p5,
        uint p6,
        uint p7,
        uint p8,
        ulong targetId,
        byte replaying)
    {
        if (!_active) return;
        if (command != ActorControlCommand || p1 != ActorControlAppear) return;

        // The log shows command=407 / p1=4562 on each 隠蔽の魔刃.
        // Use the source EntityId as the authoritative appearance event.
        RegisterBlade(sourceId);
    }

    public override void OnActionEffectEvent(ActionEffectSet set)
    {
        var actionId = set.Action?.RowId ?? 0;

        if (actionId == CastVanish)
        {
            if (!_active)
                StartMechanic();
            return;
        }

        if (!_active || actionId != CastCloneDash)
            return;

        var sourceId = set.Source?.EntityId ?? 0;
        if (sourceId == 0)
            return;

        // Normally ActorControl has already registered this entity.
        // If not, try to recover it directly from the object table.
        if (!_entityToWave.TryGetValue(sourceId, out var waveIndex))
        {
            RegisterBlade(sourceId);
            if (!_entityToWave.TryGetValue(sourceId, out waveIndex))
                return;
        }

        ResolveWave(waveIndex);
    }

    public override void OnUpdate()
    {
        if (!_active)
        {
            HideLines();
            return;
        }

        // ActorControl is the primary detector.
        // This only refreshes positions/rotations for already registered entities.
        RefreshPoses();
        DrawCurrentWaves();
    }

    public override void OnReset()
    {
        StopMechanic();
    }

    public override void OnSettingsDraw()
    {
        ImGui.TextWrapped(
            "V1.1: 隠蔽の魔刃の ActorControl command=407 / p1=4562 を出現トリガーとして使用します。"
            + "49482はSource Entity IDから所属セットを判定します。");

        ImGui.InputInt("同時出現とみなす間隔(ms)", ref C.AppearGapMs);
        ImGui.Checkbox("向きを反転", ref C.FlipDirection);

        ImGuiEx.Text($"稼働中: {_active}");
        ImGuiEx.Text($"記録セット数: {_waves.Count}");
        ImGuiEx.Text($"現在セット: {(_active ? (_currentWave + 1).ToString() : "-")}");

        for (var i = 0; i < _waves.Count; i++)
        {
            var w = _waves[i];
            ImGuiEx.Text(
                $"  SET {i + 1}: {w.Poses.Count} objects / resolved={w.Resolved}");
        }
    }

    private void StartMechanic()
    {
        HideLines();

        _active = true;
        _currentWave = 0;
        _lastRegisterTick = 0;

        _waves.Clear();
        _entityToWave.Clear();
        _seenEntities.Clear();
    }

    private void StopMechanic()
    {
        _active = false;
        _currentWave = 0;
        _lastRegisterTick = 0;

        _waves.Clear();
        _entityToWave.Clear();
        _seenEntities.Clear();

        HideLines();
    }

    private void RegisterBlade(uint entityId)
    {
        if (entityId == 0 || !_seenEntities.Add(entityId))
            return;

        // Resolve the actual object from ActorControl's source EntityId.
        var obj = Svc.Objects.FirstOrDefault(o => o.EntityId == entityId);
        if (obj is not IBattleNpc npc)
        {
            // Do not permanently consume it if the object table has not caught up yet.
            _seenEntities.Remove(entityId);
            return;
        }

        // The log identifies 隠蔽の魔刃 by base/data ID 19745.
        // DataId is used here instead of the old NameId=14696 assumption.
        if (npc.DataId != BladeBaseId)
        {
            _seenEntities.Remove(entityId);
            return;
        }

        var now = Environment.TickCount64;
        var gap = Math.Max(100, C.AppearGapMs);

        int waveIndex;

        if (_waves.Count == 0 || now - _lastRegisterTick > gap)
        {
            waveIndex = _waves.Count;
            _waves.Add(new Wave());
        }
        else
        {
            waveIndex = _waves.Count - 1;
        }

        _lastRegisterTick = now;

        _waves[waveIndex].Poses.Add(
            new Pose(entityId, npc.Position, npc.Rotation));

        _entityToWave[entityId] = waveIndex;
    }

    private void RefreshPoses()
    {
        foreach (var obj in Svc.Objects)
        {
            if (obj is not IBattleNpc npc)
                continue;

            if (!_entityToWave.TryGetValue(npc.EntityId, out var waveIndex))
                continue;

            if (waveIndex < 0 || waveIndex >= _waves.Count)
                continue;

            var wave = _waves[waveIndex];
            var poseIndex = wave.Poses.FindIndex(x => x.Id == npc.EntityId);
            if (poseIndex < 0)
                continue;

            wave.Poses[poseIndex] =
                new Pose(npc.EntityId, npc.Position, npc.Rotation);
        }
    }

    private void ResolveWave(int waveIndex)
    {
        if (waveIndex < 0 || waveIndex >= _waves.Count)
            return;

        var wave = _waves[waveIndex];

        // Every blade in the same set may emit 49482.
        // Only the first one resolves that set.
        if (wave.Resolved)
            return;

        wave.Resolved = true;

        while (_currentWave < _waves.Count && _waves[_currentWave].Resolved)
            _currentWave++;

        // Disable old lines immediately; OnUpdate redraws only unresolved 2-ahead sets.
        HideLines();

        // Four logical attack sets are expected.
        if (_currentWave >= 4)
            StopMechanic();
    }

    private void DrawCurrentWaves()
    {
        var draw = new List<Pose>();
        var shownWaves = 0;

        for (var i = _currentWave; i < _waves.Count && shownWaves < AheadCount; i++)
        {
            if (_waves[i].Resolved)
                continue;

            draw.AddRange(_waves[i].Poses);
            shownWaves++;
        }

        for (var i = 0; i < MaxLines; i++)
        {
            if (!Controller.TryGetElementByName($"line{i}", out var e) || e == null)
                continue;

            if (i >= draw.Count)
            {
                e.Enabled = false;
                continue;
            }

            var p = draw[i];
            var rot = C.FlipDirection ? p.Rot + MathF.PI : p.Rot;
            var dx = MathF.Sin(rot) * LineLength;
            var dz = MathF.Cos(rot) * LineLength;

            e.Enabled = true;
            e.radius = LineWidth;

            e.refX = p.Pos.X;
            e.refY = p.Pos.Z;
            e.refZ = p.Pos.Y;

            e.offX = p.Pos.X + dx;
            e.offY = p.Pos.Z + dz;
            e.offZ = p.Pos.Y;
        }
    }

    private void HideLines()
    {
        for (var i = 0; i < MaxLines; i++)
        {
            if (Controller.TryGetElementByName($"line{i}", out var e) && e != null)
                e.Enabled = false;
        }
    }

    private sealed class Wave
    {
        public readonly List<Pose> Poses = [];
        public bool Resolved;
    }

    private readonly record struct Pose(uint Id, Vector3 Pos, float Rot);

    public class Config : IEzConfig
    {
        public int AppearGapMs = 800;
        public bool FlipDirection = false;
    }
}
消失の魔刃・衝波を表示
C# / Splatoon Script
using Dalamud.Game.ClientState.Objects.Types;
using ECommons.DalamudServices;
using ECommons.Hooks.ActionEffectTypes;
using Splatoon.SplatoonScripting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;

namespace SplatoonScriptsOfficial.Duties
{
    public class Rauda_Knockback_v014 : SplatoonScript
    {
        // 闘獣練特二盤 / 魔斧のラウダ / 消失の魔刃・衝波
        // Final v0.1.4

        public override HashSet<uint>? ValidTerritories => new() { 1343 };

        public override Metadata Metadata =>
            new(5, "ハイネ", "魔斧のラウダ 消失の魔刃・衝波 v0.1.4");

        private const uint StartAction = 49484;
        private const uint HitAction = 49487;
        private const uint WaveAction = 49489;
        private const uint RaudaCloneDataId = 9020;
        private const float KnockbackDistance = 40.0f;

        private bool mechanicActive = false;
        private bool directionLocked = false;
        private bool knockbackForward = false;
        private string displayText = "";

        public override void OnSetup()
        {
            Controller.RegisterElementFromCode(
                "KB_Destination",
                """
                {
                    "Name":"KB Destination",
                    "type":0,
                    "Enabled":false,
                    "refX":100.0,
                    "refY":100.0,
                    "refZ":0.0,
                    "radius":1.0,
                    "color":2868838655,
                    "Filled":true,
                    "fillIntensity":0.25,
                    "thicc":6.0,
                    "tether":true,
                    "LineEndA":0,
                    "LineEndB":0
                }
                """
            );

            Controller.RegisterElementFromCode(
                "KB_Text",
                """
                {
                    "Name":"KB Text",
                    "type":1,
                    "Enabled":false,
                    "refActorType":1,
                    "radius":0.01,
                    "color":0,
                    "overlayBGColor":2147483648,
                    "overlayTextColor":4294967295,
                    "overlayVOffset":3.0,
                    "overlayFScale":2.0,
                    "overlayText":""
                }
                """
            );

            HideAll();
        }

        public override void OnStartingCast(uint source, uint castId)
        {
            if (castId != StartAction)
                return;

            mechanicActive = true;
            directionLocked = false;
            knockbackForward = false;
            displayText = "";
            HideAll();
        }

        public override void OnActionEffectEvent(ActionEffectSet set)
        {
            if (!mechanicActive)
                return;

            uint actionId = set.Action?.RowId ?? 0;

            if (actionId == HitAction)
            {
                uint sourceId = set.Source?.EntityId ?? 0;
                TryDetermineDirection(sourceId);
                return;
            }

            if (actionId == WaveAction)
                ResetMechanic();
        }

        private void TryDetermineDirection(uint sourceId)
        {
            var player = BasePlayer;
            if (player == null)
                return;

            IGameObject? clone = null;

            if (sourceId != 0)
            {
                clone = Svc.Objects.FirstOrDefault(x =>
                    x != null && x.EntityId == sourceId);
            }

            if (clone == null)
            {
                clone = Svc.Objects.FirstOrDefault(x =>
                    x != null && x.DataId == RaudaCloneDataId);
            }

            if (clone == null)
                return;

            float rotation = player.Rotation;

            Vector2 forward = new Vector2(
                MathF.Sin(rotation),
                MathF.Cos(rotation)
            );

            Vector2 toClone = new Vector2(
                clone.Position.X - player.Position.X,
                clone.Position.Z - player.Position.Z
            );

            if (toClone.LengthSquared() < 0.000001f)
                return;

            toClone = Vector2.Normalize(toClone);

            float dot = Vector2.Dot(forward, toClone);
            bool cloneInFront = dot >= 0.0f;

            if (cloneInFront)
            {
                knockbackForward = false;
                displayText = "後方へ吹き飛ばし";
            }
            else
            {
                knockbackForward = true;
                displayText = "前方へ吹き飛ばし";
            }

            directionLocked = true;

            if (Controller.TryGetElementByName("KB_Text", out var textElement))
            {
                textElement.overlayText = displayText;
                textElement.Enabled = true;
            }

            UpdateDestination();
        }

        private void UpdateDestination()
        {
            if (!directionLocked)
                return;

            var player = BasePlayer;
            if (player == null)
                return;

            float currentRotation = player.Rotation;

            Vector2 currentForward = new Vector2(
                MathF.Sin(currentRotation),
                MathF.Cos(currentRotation)
            );

            Vector2 currentDirection =
                knockbackForward ? currentForward : -currentForward;

            float destinationX =
                player.Position.X + currentDirection.X * KnockbackDistance;

            float destinationZ =
                player.Position.Z + currentDirection.Y * KnockbackDistance;

            float destinationY = player.Position.Y;

            if (Controller.TryGetElementByName("KB_Destination", out var element))
            {
                element.refX = destinationX;
                element.refY = destinationZ;
                element.refZ = destinationY;
                element.Enabled = true;
            }
        }

        public override void OnUpdate()
        {
            if (!mechanicActive || !directionLocked)
                return;

            UpdateDestination();
        }

        private void HideAll()
        {
            if (Controller.TryGetElementByName("KB_Destination", out var destinationElement))
                destinationElement.Enabled = false;

            if (Controller.TryGetElementByName("KB_Text", out var textElement))
                textElement.Enabled = false;
        }

        private void ResetMechanic()
        {
            mechanicActive = false;
            directionLocked = false;
            knockbackForward = false;
            displayText = "";
            HideAll();
        }

        public override void OnReset()
        {
            ResetMechanic();
        }
    }
}

転載元

  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次