1#include "Enemy/Togezo2D.h"
2
3#include "Library/Item/ItemUtil.h"
4#include "Library/Joint/JointControllerKeeper.h"
5#include "Library/LiveActor/ActorActionFunction.h"
6#include "Library/LiveActor/ActorClippingFunction.h"
7#include "Library/LiveActor/ActorCollisionFunction.h"
8#include "Library/LiveActor/ActorFlagFunction.h"
9#include "Library/LiveActor/ActorInitUtil.h"
10#include "Library/LiveActor/ActorModelFunction.h"
11#include "Library/LiveActor/ActorMovementFunction.h"
12#include "Library/LiveActor/ActorPoseUtil.h"
13#include "Library/LiveActor/ActorSensorUtil.h"
14#include "Library/Nerve/NerveSetupUtil.h"
15#include "Library/Nerve/NerveUtil.h"
16
17#include "Util/ActorDimensionKeeper.h"
18#include "Util/ItemUtil.h"
19#include "Util/SensorMsgFunction.h"
20
21namespace {
22NERVE_IMPL(Togezo2D, Walk)
23NERVE_IMPL(Togezo2D, Damage)
24NERVE_IMPL(Togezo2D, HideWait)
25
26NERVES_MAKE_STRUCT(Togezo2D, Walk, Damage, HideWait)
27} // namespace
28
29Togezo2D::Togezo2D(const char* name) : al::LiveActor(name) {}
30
31void Togezo2D::init(const al::ActorInitInfo& info) {
32 al::initActor(actor: this, initInfo: info);
33 al::initNerve(actor: this, nerve: &NrvTogezo2D.Walk, maxStates: 0);
34 rs::createAndSetFilter2DOnly(actor: this);
35 mDimensionKeeper = rs::createDimensionKeeper(actor: this);
36 rs::updateDimensionKeeper(keeper: mDimensionKeeper);
37 if (!rs::isIn2DArea(dimension: this)) {
38 makeActorDead();
39 return;
40 }
41 rs::snap2DGravity(actor: this, dimension: this, unk_distance: 500.0f);
42 makeActorAlive();
43 mLocalZRotator = 0.0f;
44 al::initJointControllerKeeper(this, 1);
45 al::initJointLocalZRotator(this, &mLocalZRotator, "Center");
46 mInitTrans = al::getTrans(actor: this);
47 mInitFront = al::getFront(actor: this);
48}
49
50void Togezo2D::checkFacingTarget(al::HitSensor* target) {
51 if (al::isFaceToTargetDegreeH(actor: this, target: al::getSensorPos(target), face: al::getFront(actor: this), degH: 5.0f)) {
52 al::turnFront(actor: this, deg: 180.0f);
53 al::setVelocityToFront(actor: this, speed: mVelocityFront);
54 al::addVelocityToGravity(actor: this, force: 0.65f);
55 updateCollider();
56 }
57}
58
59bool Togezo2D::receiveMsg(const al::SensorMsg* message, al::HitSensor* other, al::HitSensor* self) {
60 if (al::isNerve(user: this, nerve: &NrvTogezo2D.Damage))
61 return false;
62 if (rs::isMsgPlayerDisregardHomingAttack(message) ||
63 rs::isMsgPlayerDisregardTargetMarker(message) || al::isMsgPlayerDisregard(msg: message))
64 return true;
65 if (rs::isMsgPush2D(message) && al::isNerve(user: this, nerve: &NrvTogezo2D.Walk)) {
66 checkFacingTarget(target: other);
67 return true;
68 }
69 if (rs::isMsgBlockUpperPunch2D(message)) {
70 al::setNerve(user: this, nerve: &NrvTogezo2D.Damage);
71 rs::setAppearItemFactorAndOffsetByMsg(actor: this, msg: message, sensor: other);
72 al::appearItem(actor: this);
73 return true;
74 }
75 if (rs::isMsgKouraAttack2D(message)) {
76 al::setNerve(user: this, nerve: &NrvTogezo2D.Damage);
77 rs::requestHitReactionToAttacker(message, self, other);
78 rs::setAppearItemFactorAndOffsetByMsg(actor: this, msg: message, sensor: other);
79 al::appearItem(actor: this);
80 return true;
81 }
82 return false;
83}
84
85void Togezo2D::attackSensor(al::HitSensor* self, al::HitSensor* other) {
86 if (al::isSensorEnemyBody(self) && al::isSensorEnemyBody(other) &&
87 rs::sendMsgPush2D(source: other, target: self))
88 checkFacingTarget(target: other);
89 if (al::isSensorPlayer(other) && al::isSensorEnemyAttack(self))
90 rs::sendMsgEnemyAttack2D(source: other, target: self);
91}
92
93void Togezo2D::startMove() {
94 al::onCollide(actor: this);
95 al::setNerve(user: this, nerve: &NrvTogezo2D.Walk);
96}
97
98void Togezo2D::control() {
99 rs::updateDimensionKeeper(keeper: mDimensionKeeper);
100 if (al::isNerve(user: this, nerve: &NrvTogezo2D.HideWait))
101 return;
102 al::addVelocityToGravity(actor: this, force: 0.65f);
103 al::scaleVelocityDirection(actor: this, direction: al::getGravity(actor: this), factor: 0.98f);
104 if (al::isCollidedWall(this)) {
105 al::turnFront(actor: this, deg: 150.0f);
106 if (al::isOnGround(this, 0)) {
107 al::setVelocityToFront(actor: this, speed: mVelocityFront);
108 al::addVelocityToGravity(actor: this, force: 0.65f);
109 } else {
110 al::addVelocityToFront(actor: this, force: 2 * mVelocityFront);
111 }
112 updateCollider();
113 }
114 if (al::isNerve(user: this, nerve: &NrvTogezo2D.Damage))
115 return;
116 if (!rs::isIn2DArea(dimension: this)) {
117 al::setNerve(user: this, nerve: &NrvTogezo2D.HideWait);
118 return;
119 }
120 if (al::isOnGround(this, 0)) {
121 al::setVelocityToFront(actor: this, speed: mVelocityFront);
122 al::addVelocityToGravity(actor: this, force: 0.65f);
123 }
124 rs::snap2DGravity(actor: this, dimension: this, unk_distance: 500.0f);
125}
126
127void Togezo2D::exeWalk() {
128 if (al::isFirstStep(user: this)) {
129 al::validateClipping(actor: this);
130 al::showModelIfHide(actor: this);
131 al::onCollide(actor: this);
132 al::validateHitSensors(this);
133 mVelocityFront = 2.5f;
134 al::setVelocityToFront(actor: this, speed: mVelocityFront);
135 al::addVelocityToGravity(actor: this, force: 0.65f);
136 al::startAction(actor: this, actionName: "Move");
137 }
138 if (al::isOnGround(this, 0)) {
139 al::setVelocityToFront(actor: this, speed: mVelocityFront);
140 al::addVelocityToGravity(actor: this, force: 0.65f);
141 }
142}
143
144void Togezo2D::exeDamage() {
145 if (al::isFirstStep(user: this)) {
146 al::offCollide(actor: this);
147 al::invalidateHitSensors(this);
148 al::turnFront(actor: this, deg: 180.0f);
149 mVelocityFront = 2.5f;
150 mLocalZRotator = 180.0f;
151 al::setVelocityToFront(actor: this, speed: mVelocityFront);
152 al::addVelocity(actor: this, vel: al::getGravity(actor: this) * -20.0f);
153 }
154 if (al::isGreaterStep(user: this, step: 90))
155 al::setNerve(user: this, nerve: &NrvTogezo2D.HideWait);
156}
157
158void Togezo2D::exeHideWait() {
159 if (al::isFirstStep(user: this)) {
160 al::invalidateClipping(actor: this);
161 al::offCollide(actor: this);
162 al::hideModelIfShow(actor: this);
163 al::invalidateHitSensors(this);
164 al::setVelocityZero(this);
165 al::setTrans(actor: this, trans: mInitTrans);
166 al::setFront(actor: this, front: mInitFront);
167 if (mIsAlwaysFalse)
168 mIsAlwaysFalse = false;
169 al::resetPosition(actor: this);
170 }
171}
172