| 1 | #include "Layout/CounterLifeCtrl.h" |
| 2 | |
| 3 | #include "Library/Camera/CameraUtil.h" |
| 4 | #include "Library/Draw/SubCameraRenderer.h" |
| 5 | #include "Library/Layout/LayoutActionFunction.h" |
| 6 | #include "Library/Layout/LayoutActorUtil.h" |
| 7 | #include "Library/Math/MathUtil.h" |
| 8 | #include "Library/Nerve/NerveSetupUtil.h" |
| 9 | #include "Library/Nerve/NerveUtil.h" |
| 10 | #include "Library/Player/PlayerUtil.h" |
| 11 | #include "Library/Screen/ScreenFunction.h" |
| 12 | #include "Library/Se/SeFunction.h" |
| 13 | |
| 14 | #include "Layout/CounterLife.h" |
| 15 | #include "System/GameDataFunction.h" |
| 16 | #include "System/GameDataUtil.h" |
| 17 | #include "Util/PlayerUtil.h" |
| 18 | |
| 19 | namespace { |
| 20 | NERVE_IMPL(CounterLifeCtrl, Dead); |
| 21 | NERVE_IMPL(CounterLifeCtrl, CountStartFadeIn); |
| 22 | NERVE_IMPL(CounterLifeCtrl, DemoLifeMaxUpStartFadeIn); |
| 23 | NERVE_IMPL(CounterLifeCtrl, Appear); |
| 24 | NERVE_IMPL(CounterLifeCtrl, Wait); |
| 25 | NERVE_IMPL(CounterLifeCtrl, End); |
| 26 | NERVE_IMPL(CounterLifeCtrl, Count); |
| 27 | NERVE_IMPL(CounterLifeCtrl, CountEnd); |
| 28 | NERVE_IMPL(CounterLifeCtrl, DemoLifeMaxUpAddLife); |
| 29 | NERVE_IMPL(CounterLifeCtrl, DemoLifeMaxUpWaitForMove); |
| 30 | NERVE_IMPL(CounterLifeCtrl, DemoLifeMaxUpMove); |
| 31 | NERVE_IMPL(CounterLifeCtrl, DemoLifeMaxUpUnite); |
| 32 | NERVE_IMPL(CounterLifeCtrl, CountStartFadeOut); |
| 33 | |
| 34 | NERVES_MAKE_NOSTRUCT(CounterLifeCtrl, Dead, CountStartFadeIn, End, DemoLifeMaxUpWaitForMove); |
| 35 | NERVES_MAKE_STRUCT(CounterLifeCtrl, DemoLifeMaxUpStartFadeIn, Appear, Wait, Count, CountEnd, |
| 36 | DemoLifeMaxUpAddLife, DemoLifeMaxUpMove, DemoLifeMaxUpUnite, CountStartFadeOut); |
| 37 | } // namespace |
| 38 | |
| 39 | CounterLifeCtrl::CounterLifeCtrl(const al::LayoutInitInfo& info, |
| 40 | const al::PlayerHolder* player_holder, |
| 41 | const al::SubCameraRenderer* sub_camera_renderer) |
| 42 | : al::NerveExecutor("ライフカウンタ更新" ), mPlayerHolder(player_holder), |
| 43 | mSubCameraRenderer(sub_camera_renderer) { |
| 44 | mCounterLife = new CounterLife("[ライフ]ライフカウンタ" , "CounterLife" , info); |
| 45 | mCounterLife->kill(); |
| 46 | mCounterLifeKids = new CounterLife("[ライフ]キッズ用ライフカウンタ" , "CounterLifeKids" , info); |
| 47 | mCounterLifeKids->kill(); |
| 48 | mCounterLifeUp = new CounterLife("[ライフ]最大ライフカウンタ" , "CounterLifeUp" , info); |
| 49 | mCounterLifeUp->kill(); |
| 50 | initNerve(nerve: &Dead, stateCount: 0); |
| 51 | setCount(GameDataFunction::getPlayerHitPoint(accessor: mCounterLife)); |
| 52 | mCounterLifeInitTrans = al::getPaneLocalTrans(mCounterLife, "All" ); |
| 53 | mCounterLifeKidsInitTrans = al::getPaneLocalTrans(mCounterLifeKids, "All" ); |
| 54 | } |
| 55 | |
| 56 | static bool isDemoLifeMaxUp(CounterLifeCtrl* ctrl) { |
| 57 | return al::isNerve(user: ctrl, nerve: &NrvCounterLifeCtrl.DemoLifeMaxUpStartFadeIn) || |
| 58 | al::isNerve(user: ctrl, nerve: &NrvCounterLifeCtrl.DemoLifeMaxUpAddLife) || |
| 59 | al::isNerve(user: ctrl, nerve: &NrvCounterLifeCtrl.DemoLifeMaxUpMove) || |
| 60 | al::isNerve(user: ctrl, nerve: &NrvCounterLifeCtrl.DemoLifeMaxUpUnite); |
| 61 | } |
| 62 | |
| 63 | static s32 calcLifeUpCount(const al::IUseSceneObjHolder* game_data_holder, s32 count) { |
| 64 | return sead::Mathi::clampMin( |
| 65 | val: count - GameDataFunction::getPlayerHitPointMaxNormal(accessor: game_data_holder), min_: 0); |
| 66 | } |
| 67 | |
| 68 | static f32 calcGaugeFrame(CounterLife* counter, s32 count, s32 max) { |
| 69 | f32 max_frame = al::getActionFrameMax(layout: counter, actionName: "Gauge" , paneName: "Gauge" ); |
| 70 | return max_frame - max_frame * (static_cast<f32>(count) / static_cast<f32>(max)); |
| 71 | } |
| 72 | |
| 73 | static void setGaugeCount(CounterLife* counter, s32 count, s32 max) { |
| 74 | counter->setCount(calcGaugeFrame(counter, count, max)); |
| 75 | } |
| 76 | |
| 77 | void CounterLifeCtrl::setCount(s32 count) { |
| 78 | mCount = count; |
| 79 | mTargetCount = count; |
| 80 | |
| 81 | setGaugeCount(counter: mCounterLife, count: mCount, max: GameDataFunction::getPlayerHitPointMaxNormal(accessor: mCounterLife)); |
| 82 | setGaugeCount(counter: mCounterLifeUp, count: calcLifeUpCount(game_data_holder: mCounterLifeUp, count: mCount), max: 3); |
| 83 | setGaugeCount(counter: mCounterLifeKids, count: sead::Mathi::clamp(value: mCount, low: 0, high: 6), |
| 84 | max: GameDataFunction::getPlayerHitPointMaxNormal(accessor: mCounterLifeKids)); |
| 85 | |
| 86 | if (!isDemoLifeMaxUp(ctrl: this)) { |
| 87 | al::setPaneStringFormat(mCounterLife, "TxtLife" , al::StringTmp<32>("%d" , count).cstr()); |
| 88 | al::setPaneStringFormat(mCounterLifeUp, "TxtLife" , al::StringTmp<32>("%d" , count).cstr()); |
| 89 | al::setPaneStringFormat(mCounterLifeKids, "TxtLife" , al::StringTmp<32>("%d" , count).cstr()); |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | bool CounterLifeCtrl::tryUpdateCount(s32 count) { |
| 94 | if (count == mTargetCount) |
| 95 | return false; |
| 96 | setCount(mTargetCount); |
| 97 | mTargetCount = count; |
| 98 | al::setNerve(user: this, nerve: &CountStartFadeIn); |
| 99 | return true; |
| 100 | } |
| 101 | |
| 102 | bool CounterLifeCtrl::tryStartDemoLifeUp(bool is_hack_koopa) { |
| 103 | if (!GameDataFunction::isPlayerHitPointMaxWithItem(accessor: mCounterLife) || |
| 104 | mTargetCount == GameDataFunction::getPlayerHitPointMaxCurrent(accessor: mCounterLife)) |
| 105 | return false; |
| 106 | mTargetCount = GameDataFunction::getPlayerHitPointMaxCurrent(accessor: mCounterLife); |
| 107 | mIsHackKoopa = is_hack_koopa; |
| 108 | if (is_hack_koopa) { |
| 109 | s32 count = GameDataFunction::getPlayerHitPointMaxNormal(accessor: mCounterLife); |
| 110 | mCount = count; |
| 111 | setCount(count); |
| 112 | } |
| 113 | al::setNerve(user: this, nerve: &NrvCounterLifeCtrl.DemoLifeMaxUpStartFadeIn); |
| 114 | return true; |
| 115 | } |
| 116 | |
| 117 | void CounterLifeCtrl::appear() { |
| 118 | if (al::isNerve(user: this, nerve: &NrvCounterLifeCtrl.Appear) || |
| 119 | al::isNerve(user: this, nerve: &NrvCounterLifeCtrl.Wait)) |
| 120 | return; |
| 121 | al::setPaneLocalAlpha(mCounterLife, "Life" , 255); |
| 122 | al::setPaneLocalAlpha(mCounterLifeKids, "Life" , 255); |
| 123 | al::setNerve(user: this, nerve: &NrvCounterLifeCtrl.Appear); |
| 124 | } |
| 125 | |
| 126 | void CounterLifeCtrl::end() { |
| 127 | al::setNerve(user: this, nerve: &End); |
| 128 | } |
| 129 | |
| 130 | void CounterLifeCtrl::kill() { |
| 131 | killAllLayout(); |
| 132 | al::setNerve(user: this, nerve: &Dead); |
| 133 | } |
| 134 | |
| 135 | void CounterLifeCtrl::killAllLayout() { |
| 136 | al::killLayoutIfActive(mCounterLife); |
| 137 | al::killLayoutIfActive(mCounterLifeUp); |
| 138 | al::killLayoutIfActive(mCounterLifeKids); |
| 139 | } |
| 140 | |
| 141 | bool CounterLifeCtrl::isEndLifeDemo() const { |
| 142 | return al::isNerve(user: this, nerve: &NrvCounterLifeCtrl.Wait); |
| 143 | } |
| 144 | |
| 145 | void CounterLifeCtrl::exeAppear() { |
| 146 | if (al::isFirstStep(user: this)) { |
| 147 | setTransAllLayout(getInitTrans()); |
| 148 | appearAllLayout(); |
| 149 | startAllLayout(); |
| 150 | setCount(GameDataFunction::getPlayerHitPoint(accessor: mCounterLife)); |
| 151 | } |
| 152 | if (getCurrentLayout()->isWait()) |
| 153 | al::setNerve(user: this, nerve: &NrvCounterLifeCtrl.Wait); |
| 154 | } |
| 155 | |
| 156 | void CounterLifeCtrl::setTransAllLayout(const sead::Vector3f& trans) { |
| 157 | al::setPaneLocalTrans(mCounterLife, "All" , trans); |
| 158 | al::setPaneLocalTrans(mCounterLifeUp, "All" , trans); |
| 159 | al::setPaneLocalTrans(mCounterLifeKids, "All" , trans); |
| 160 | } |
| 161 | |
| 162 | const sead::Vector3f& CounterLifeCtrl::getInitTrans() const { |
| 163 | return rs::isKidsMode(layout: mCounterLife) ? mCounterLifeKidsInitTrans : mCounterLifeInitTrans; |
| 164 | } |
| 165 | |
| 166 | static bool isActiveCounterLifeUp(const al::IUseSceneObjHolder* game_data_holder) { |
| 167 | return GameDataFunction::getPlayerHitPoint(accessor: game_data_holder) > |
| 168 | GameDataFunction::getPlayerHitPointMaxNormal(accessor: game_data_holder); |
| 169 | } |
| 170 | |
| 171 | void CounterLifeCtrl::appearAllLayout() { |
| 172 | if (rs::isKidsMode(layout: mCounterLifeKids)) |
| 173 | mCounterLifeKids->appear(); |
| 174 | else |
| 175 | mCounterLife->appear(); |
| 176 | if (isActiveCounterLifeUp(game_data_holder: mCounterLifeUp)) |
| 177 | mCounterLifeUp->appear(); |
| 178 | } |
| 179 | |
| 180 | void CounterLifeCtrl::startAllLayout() { |
| 181 | if (rs::isKidsMode(layout: mCounterLifeKids)) |
| 182 | mCounterLifeKids->start(); |
| 183 | else |
| 184 | mCounterLife->start(); |
| 185 | if (isActiveCounterLifeUp(game_data_holder: mCounterLifeUp)) |
| 186 | mCounterLifeUp->start(); |
| 187 | } |
| 188 | |
| 189 | CounterLife* CounterLifeCtrl::getCurrentLayout() const { |
| 190 | return rs::isKidsMode(layout: mCounterLife) ? mCounterLifeKids : mCounterLife; |
| 191 | } |
| 192 | |
| 193 | void CounterLifeCtrl::exeWait() { |
| 194 | if (al::isFirstStep(user: this)) |
| 195 | waitAllLayout(); |
| 196 | if (rs::isEmptyPlayerOxygen(al::getPlayerActor(mPlayerHolder, 0))) |
| 197 | updateTransAllLayout(); |
| 198 | else |
| 199 | setTransAllLayout(getInitTrans()); |
| 200 | if (rs::isPlayerCameraSubjective(al::getPlayerActor(mPlayerHolder, 0))) |
| 201 | mSubjectiveCameraWaitTime = 5; |
| 202 | else |
| 203 | mSubjectiveCameraWaitTime = sead::Mathi::clampMin(val: mSubjectiveCameraWaitTime - 1, min_: 0); |
| 204 | tryChangeCount(); |
| 205 | } |
| 206 | |
| 207 | void CounterLifeCtrl::waitAllLayout() { |
| 208 | if (rs::isKidsMode(layout: mCounterLifeKids)) |
| 209 | mCounterLifeKids->wait(); |
| 210 | else |
| 211 | mCounterLife->wait(); |
| 212 | if (isActiveCounterLifeUp(game_data_holder: mCounterLifeUp)) |
| 213 | mCounterLifeUp->wait(); |
| 214 | else if (al::isActive(mCounterLifeUp) && !al::isActionPlaying(layout: mCounterLifeUp, actionName: "Break" , paneName: "Life" )) |
| 215 | al::startAction(layout: mCounterLifeUp, actionName: "Break" , paneName: "Life" ); |
| 216 | setCount(GameDataFunction::getPlayerHitPoint(accessor: mCounterLife)); |
| 217 | } |
| 218 | |
| 219 | void CounterLifeCtrl::updateTransAllLayout() { |
| 220 | updateTrans(layout: mCounterLife); |
| 221 | updateTrans(layout: mCounterLifeUp); |
| 222 | updateTrans(layout: mCounterLifeKids); |
| 223 | } |
| 224 | |
| 225 | bool CounterLifeCtrl::tryChangeCount() { |
| 226 | if (GameDataFunction::getPlayerHitPoint(accessor: mCounterLife) == mTargetCount) |
| 227 | return false; |
| 228 | mTargetCount = GameDataFunction::getPlayerHitPoint(accessor: mCounterLife); |
| 229 | if (rs::isEmptyPlayerOxygen(al::getPlayerActor(mPlayerHolder, 0))) |
| 230 | al::setNerve(user: this, nerve: &NrvCounterLifeCtrl.Count); |
| 231 | else |
| 232 | al::setNerve(user: this, nerve: &NrvCounterLifeCtrl.CountStartFadeOut); |
| 233 | return true; |
| 234 | } |
| 235 | |
| 236 | void CounterLifeCtrl::exeEnd() { |
| 237 | if (al::isFirstStep(user: this)) { |
| 238 | mCounterLife->end(); |
| 239 | mCounterLifeKids->end(); |
| 240 | mCounterLifeUp->end(); |
| 241 | } |
| 242 | if (al::isDead(getCurrentLayout())) |
| 243 | al::setNerve(user: this, nerve: &Dead); |
| 244 | } |
| 245 | |
| 246 | void CounterLifeCtrl::exeDead() { |
| 247 | if (al::isFirstStep(user: this)) |
| 248 | killAllLayout(); |
| 249 | } |
| 250 | |
| 251 | void CounterLifeCtrl::exeCountStartFadeOut() { |
| 252 | if (al::isFirstStep(user: this)) { |
| 253 | appearAllLayout(); |
| 254 | startActionAllLayout(action_name: "FadeOut" , pane_name: nullptr); |
| 255 | } |
| 256 | if (al::isActionEnd(layout: getCurrentLayout(), paneName: nullptr)) |
| 257 | al::setNerve(user: this, nerve: &CountStartFadeIn); |
| 258 | } |
| 259 | |
| 260 | void CounterLifeCtrl::exeCountStartFadeIn() { |
| 261 | updateTransAllLayout(); |
| 262 | if (al::isFirstStep(user: this)) { |
| 263 | al::startAction(layout: mCounterLife, actionName: "FadeIn" , paneName: nullptr); |
| 264 | al::startAction(layout: mCounterLifeKids, actionName: "FadeIn" , paneName: nullptr); |
| 265 | al::startAction(layout: mCounterLifeUp, actionName: "FadeIn" , paneName: nullptr); |
| 266 | appearAllLayout(); |
| 267 | } |
| 268 | if (al::isActionEnd(layout: getCurrentLayout(), paneName: nullptr)) |
| 269 | al::setNerve(user: this, nerve: &NrvCounterLifeCtrl.Count); |
| 270 | } |
| 271 | |
| 272 | void CounterLifeCtrl::exeCount() { |
| 273 | if (al::isFirstStep(user: this)) |
| 274 | startCountAnim(target: mTargetCount); |
| 275 | if (mTargetCount == mCount) { |
| 276 | if (mTargetCount != GameDataFunction::getPlayerHitPoint(accessor: mCounterLife)) { |
| 277 | mTargetCount = GameDataFunction::getPlayerHitPoint(accessor: mCounterLife); |
| 278 | al::setNerve(user: this, nerve: &NrvCounterLifeCtrl.Count); |
| 279 | return; |
| 280 | } |
| 281 | getCurrentLayout(); |
| 282 | if (al::isGreaterEqualStep(user: this, step: 80)) { |
| 283 | if (rs::isEmptyPlayerOxygen(al::getPlayerActor(mPlayerHolder, 0))) |
| 284 | al::setNerve(user: this, nerve: &NrvCounterLifeCtrl.Wait); |
| 285 | else |
| 286 | al::setNerve(user: this, nerve: &NrvCounterLifeCtrl.CountEnd); |
| 287 | } |
| 288 | return; |
| 289 | } |
| 290 | if (al::isGreaterEqualStep(user: this, step: 12)) |
| 291 | al::setNerve(user: this, nerve: &NrvCounterLifeCtrl.Count); |
| 292 | } |
| 293 | |
| 294 | static void startGaugeAnim(CounterLifeCtrl* ctrl, CounterLife* counter, s32 count, s32 max) { |
| 295 | f32 frame = calcGaugeFrame(counter, count, max); |
| 296 | if (isDemoLifeMaxUp(ctrl)) |
| 297 | counter->startGaugeWithFrame(goalFrame: frame, frames: al::getActionFrameMax(layout: counter, actionName: "AddMax" , paneName: "Life" )); |
| 298 | else |
| 299 | counter->startGauge(goalFrame: frame); |
| 300 | } |
| 301 | |
| 302 | void CounterLifeCtrl::startCountAnim(s32 target) { |
| 303 | s32 count = mCount; |
| 304 | if (count == target) { |
| 305 | startGaugeAnim(ctrl: this, counter: mCounterLife, count: mCount, |
| 306 | max: GameDataFunction::getPlayerHitPointMaxNormal(accessor: mCounterLife)); |
| 307 | startGaugeAnim(ctrl: this, counter: mCounterLifeUp, count: calcLifeUpCount(game_data_holder: mCounterLifeUp, count: mCount), max: 3); |
| 308 | startGaugeAnim(ctrl: this, counter: mCounterLifeKids, count: sead::Mathi::clamp(value: mCount, low: 0, high: 6), |
| 309 | max: GameDataFunction::getPlayerHitPointMaxNormal(accessor: mCounterLifeKids)); |
| 310 | return; |
| 311 | } |
| 312 | |
| 313 | mCount += target < mCount ? -1 : 1; |
| 314 | s32 new_count = mCount; |
| 315 | startGaugeAnim(ctrl: this, counter: mCounterLife, count: new_count, |
| 316 | max: GameDataFunction::getPlayerHitPointMaxNormal(accessor: mCounterLife)); |
| 317 | startGaugeAnim(ctrl: this, counter: mCounterLifeUp, count: calcLifeUpCount(game_data_holder: mCounterLifeUp, count: new_count), max: 3); |
| 318 | startGaugeAnim(ctrl: this, counter: mCounterLifeKids, count: sead::Mathi::clamp(value: new_count, low: 0, high: 6), |
| 319 | max: GameDataFunction::getPlayerHitPointMaxNormal(accessor: mCounterLifeKids)); |
| 320 | |
| 321 | bool is_add_max = al::isNerve(user: this, nerve: &NrvCounterLifeCtrl.DemoLifeMaxUpAddLife); |
| 322 | if (count > target) { |
| 323 | if ((mCount == 3 && !rs::isKidsMode(layout: mCounterLife)) || mCount == 6) { |
| 324 | al::startAction(layout: mCounterLifeUp, actionName: "Break" , paneName: "Life" ); |
| 325 | } else if (mCount >= GameDataFunction::getPlayerHitPointMaxNormal(accessor: mCounterLife)) { |
| 326 | al::startAction(layout: mCounterLifeUp, actionName: "Damage" , paneName: "Life" ); |
| 327 | } else { |
| 328 | al::startAction(layout: getCurrentLayout(), actionName: "Damage" , paneName: "Life" ); |
| 329 | if (mCount == 1) { |
| 330 | CounterLife* counter = |
| 331 | rs::isKidsMode(layout: mCounterLifeKids) ? mCounterLifeKids : mCounterLife; |
| 332 | al::startHitReaction(counter, "ライフ1警告" , nullptr); |
| 333 | } |
| 334 | } |
| 335 | } else { |
| 336 | const char* action = "Add" ; |
| 337 | if (is_add_max && !mIsHackKoopa) |
| 338 | action = "AddMax" ; |
| 339 | if (mCount > GameDataFunction::getPlayerHitPointMaxNormal(accessor: mCounterLife)) { |
| 340 | al::startAction(layout: mCounterLifeUp, actionName: action, paneName: "Life" ); |
| 341 | } else { |
| 342 | al::startAction(layout: mCounterLife, actionName: action, paneName: "Life" ); |
| 343 | al::startAction(layout: mCounterLifeKids, actionName: action, paneName: "Life" ); |
| 344 | } |
| 345 | al::tryStopSe(mCounterLife, "LifeAlert" , -1, nullptr); |
| 346 | } |
| 347 | |
| 348 | if (isDemoLifeMaxUp(ctrl: this)) { |
| 349 | al::setPaneStringFormat( |
| 350 | mCounterLife, "TxtLife" , |
| 351 | al::StringTmp<32>( |
| 352 | "%d" , sead::Mathi::min(a: mCount, |
| 353 | b: GameDataFunction::getPlayerHitPointMaxNormal(accessor: mCounterLife))) |
| 354 | .cstr()); |
| 355 | al::setPaneStringFormat( |
| 356 | mCounterLifeKids, "TxtLife" , |
| 357 | al::StringTmp<32>( |
| 358 | "%d" , sead::Mathi::min(a: mCount, |
| 359 | b: GameDataFunction::getPlayerHitPointMaxNormal(accessor: mCounterLife))) |
| 360 | .cstr()); |
| 361 | al::setPaneStringFormat( |
| 362 | mCounterLifeUp, "TxtLife" , |
| 363 | al::StringTmp<32>( |
| 364 | "%d" , sead::Mathi::clampMin( |
| 365 | val: mCount - GameDataFunction::getPlayerHitPointMaxNormal(accessor: mCounterLife), min_: 0)) |
| 366 | .cstr()); |
| 367 | } else { |
| 368 | al::setPaneStringFormat(mCounterLife, "TxtLife" , al::StringTmp<32>("%d" , mCount).cstr()); |
| 369 | al::setPaneStringFormat(mCounterLifeUp, "TxtLife" , al::StringTmp<32>("%d" , mCount).cstr()); |
| 370 | al::setPaneStringFormat(mCounterLifeKids, "TxtLife" , |
| 371 | al::StringTmp<32>("%d" , mCount).cstr()); |
| 372 | } |
| 373 | |
| 374 | if (GameDataFunction::getPlayerHitPoint(accessor: mCounterLife) > 1) { |
| 375 | al::startFreezeAction(layout: mCounterLife, actionName: "Loop" , frame: 0, paneName: "Loop" ); |
| 376 | al::startFreezeAction(layout: mCounterLifeKids, actionName: "Loop" , frame: 0, paneName: "Loop" ); |
| 377 | } |
| 378 | } |
| 379 | |
| 380 | void CounterLifeCtrl::exeCountEnd() { |
| 381 | if (al::isFirstStep(user: this)) |
| 382 | mCountEndTrans = al::getPaneLocalTrans(mCounterLife, "All" ); |
| 383 | sead::Vector3f pos = sead::Vector3f::zero; |
| 384 | al::lerpVec(&pos, mCountEndTrans, getInitTrans(), al::calcNerveEaseInRate(user: this, max: 27)); |
| 385 | setTransAllLayout(pos); |
| 386 | if (al::isGreaterEqualStep(user: this, step: 27)) { |
| 387 | setTransAllLayout(getInitTrans()); |
| 388 | al::setNerve(user: this, nerve: &NrvCounterLifeCtrl.Wait); |
| 389 | } |
| 390 | } |
| 391 | |
| 392 | void CounterLifeCtrl::exeDemoLifeMaxUpStartFadeIn() { |
| 393 | CounterLife* counter = mCounterLifeUp; |
| 394 | if (al::isFirstStep(user: this)) { |
| 395 | appearAllLayout(); |
| 396 | getCurrentLayout()->start(); |
| 397 | al::setPaneLocalTrans(getCurrentLayout(), "All" , mCounterLifeInitTrans); |
| 398 | counter->setEmpty(); |
| 399 | al::startAction(layout: counter, actionName: "FadeIn" , paneName: nullptr); |
| 400 | startGaugeAnim(ctrl: this, counter, count: 0, max: 3); |
| 401 | updateTrans(layout: counter); |
| 402 | al::setPaneStringFormat(mCounterLifeUp, "TxtLife" , al::StringTmp<32>("3" ).cstr()); |
| 403 | } |
| 404 | if (al::isActionEnd(layout: counter, paneName: nullptr)) |
| 405 | al::setNerve(user: this, nerve: &NrvCounterLifeCtrl.DemoLifeMaxUpAddLife); |
| 406 | } |
| 407 | |
| 408 | void CounterLifeCtrl::updateTrans(al::LayoutActor* layout) { |
| 409 | sead::Vector3f pos = sead::Vector3f::zero; |
| 410 | calcLayoutTransByPlayer(out: &pos); |
| 411 | sead::Vector2f pos2 = {pos.x, pos.y}; |
| 412 | al::setPaneLocalTrans(layout, "All" , pos2); |
| 413 | } |
| 414 | |
| 415 | void CounterLifeCtrl::exeDemoLifeMaxUpAddLife() { |
| 416 | if (al::isFirstStep(user: this)) |
| 417 | mTargetCount = GameDataFunction::getPlayerHitPointMaxCurrent(accessor: mCounterLife); |
| 418 | if (al::isIntervalStep(user: this, interval: 12, offset: 0)) |
| 419 | startCountAnim(target: mTargetCount); |
| 420 | if (mTargetCount == mCount) |
| 421 | al::setNerve(user: this, nerve: &DemoLifeMaxUpWaitForMove); |
| 422 | } |
| 423 | |
| 424 | void CounterLifeCtrl::exeDemoLifeMaxUpWaitForMove() { |
| 425 | if (al::isGreaterEqualStep(user: this, step: 30)) |
| 426 | al::setNerve(user: this, nerve: &NrvCounterLifeCtrl.DemoLifeMaxUpMove); |
| 427 | } |
| 428 | |
| 429 | void CounterLifeCtrl::exeDemoLifeMaxUpMove() { |
| 430 | sead::Vector3f pos = sead::Vector3f::zero; |
| 431 | calcLayoutTransByPlayer(out: &pos); |
| 432 | al::lerpVec(&pos, pos, getInitTrans(), al::calcNerveEaseInRate(user: this, max: 27)); |
| 433 | al::setPaneLocalTrans(mCounterLifeUp, "All" , pos); |
| 434 | if (al::isGreaterEqualStep(user: this, step: 27)) |
| 435 | al::setNerve(user: this, nerve: &NrvCounterLifeCtrl.DemoLifeMaxUpUnite); |
| 436 | } |
| 437 | |
| 438 | void CounterLifeCtrl::calcLayoutTransByPlayer(sead::Vector3f* out) { |
| 439 | al::LiveActor* player = al::getPlayerActor(mPlayerHolder, 0); |
| 440 | if (rs::isPlayerCameraSubjective(player) || mSubjectiveCameraWaitTime > 0) { |
| 441 | out->set(getInitTrans()); |
| 442 | return; |
| 443 | } |
| 444 | sead::Vector3f pos = sead::Vector3f::zero; |
| 445 | rs::calcPlayerFollowLayoutWorldPos(&pos, player); |
| 446 | if (rs::isPlayer2D(player) && al::isValidView(info: al::getSceneCameraInfo(user: player), viewIdx: 1)) |
| 447 | mSubCameraRenderer->calcOnScreenPos(&pos, pos); |
| 448 | sead::Vector3f side = {0, 0, 0}; |
| 449 | al::calcCameraSideDir(sideDir: &side, user: player, viewIdx: 0); |
| 450 | sead::Vector3f up = {0, 0, 0}; |
| 451 | al::calcCameraUpDir(upDir: &up, user: player, viewIdx: 0); |
| 452 | sead::Vector2f layout_pos = {0, 0}; |
| 453 | al::calcLayoutPosFromWorldPos(output: &layout_pos, player, pos + side * 30 + up * 25); |
| 454 | sead::Vector2f layout_offset = {0, 24}; |
| 455 | out->x = layout_pos.x + layout_offset.x; |
| 456 | out->y = layout_pos.y + layout_offset.y; |
| 457 | f32 min_x = -0.5f * al::getLayoutDisplayWidth() + 100; |
| 458 | f32 max_x = 0.5f * al::getLayoutDisplayWidth() - 100; |
| 459 | out->x = sead::Mathf::clamp(value: out->x, low: min_x, high: max_x); |
| 460 | f32 min_y = -0.5f * al::getLayoutDisplayHeight() + 100; |
| 461 | f32 max_y = 0.5f * al::getLayoutDisplayHeight() - 100; |
| 462 | out->y = sead::Mathf::clamp(value: out->y, low: min_y, high: max_y); |
| 463 | out->z = getInitTrans().z; |
| 464 | } |
| 465 | |
| 466 | void CounterLifeCtrl::exeDemoLifeMaxUpUnite() { |
| 467 | if (al::isFirstStep(user: this)) { |
| 468 | al::startAction(layout: mCounterLifeUp, actionName: "Unite" , paneName: "Life" ); |
| 469 | al::startAction(layout: mCounterLife, actionName: "Unite" , paneName: "Life" ); |
| 470 | al::startAction(layout: mCounterLifeKids, actionName: "Unite" , paneName: "Life" ); |
| 471 | al::setPaneStringFormat( |
| 472 | mCounterLifeUp, "TxtLife" , |
| 473 | al::StringTmp<32>("%d" , GameDataFunction::getPlayerHitPointMaxCurrent(accessor: mCounterLife)) |
| 474 | .cstr()); |
| 475 | if (mIsHackKoopa) |
| 476 | al::startHitReaction(getCurrentLayout(), "合体[クッパ]" , nullptr); |
| 477 | else |
| 478 | al::startHitReaction(getCurrentLayout(), "合体[通常]" , nullptr); |
| 479 | return; |
| 480 | } |
| 481 | if (al::isActionEnd(layout: mCounterLifeUp, paneName: nullptr)) |
| 482 | al::setNerve(user: this, nerve: &NrvCounterLifeCtrl.Wait); |
| 483 | } |
| 484 | |
| 485 | void CounterLifeCtrl::startActionAllLayout(const char* action_name, const char* pane_name) { |
| 486 | al::startAction(layout: mCounterLife, actionName: action_name, paneName: pane_name); |
| 487 | al::startAction(layout: mCounterLifeUp, actionName: action_name, paneName: pane_name); |
| 488 | al::startAction(layout: mCounterLifeKids, actionName: action_name, paneName: pane_name); |
| 489 | } |
| 490 | |