SMG-Decomp
A decompilation of Super Mario Galaxy 1
Loading...
Searching...
No Matches
TalkNodeCtrl.cpp
1#include "Game/NPC/TalkNodeCtrl.hpp"
2#include "Game/System/MessageHolder.hpp"
3#include "Game/Util.hpp"
4#include <cstdio>
5
6void TalkMessageHistory::entry(u16 msgID) {
7 mHistory[mCount++] = msgID;
8}
9
10bool TalkMessageHistory::search(u16 msgID) const {
11 for (s32 i = 0; i < mCount; i++) {
12 if (mHistory[i] == msgID) {
13 return true;
14 }
15 }
16
17 return false;
18}
19
20TalkNodeCtrl::TalkNodeCtrl() : _0(0), mCurrentNodeIdx(-1), mMessageInfo() {
21 mHistory.mCount = 0;
22 _38 = nullptr;
23 mCurrentNode = nullptr;
24 mNodeData = -1;
25}
26
27void TalkNodeCtrl::resetFlowNode() {
28 if (mCurrentNode != _38) {
29 mCurrentNode = _38;
30 mFlowNode = _38;
31 updateMessage();
32 }
33}
34
35void TalkNodeCtrl::resetTempFlowNode() {
36 if (mCurrentNode != mFlowNode) {
37 mCurrentNode = mFlowNode;
38 updateMessage();
39 }
40}
41
42void TalkNodeCtrl::recordTempFlowNode() {
43 mFlowNode = mCurrentNode;
44}
45
46void TalkNodeCtrl::forwardFlowNode() {
47 TalkNode* node = mCurrentNode;
48
49 if (node == nullptr) {
50 return;
51 }
52
53 if (node->mNodeType == 1) {
54 u16 idx = node->mNextIdx;
55 MessageData* msg = MessageSystem::getSceneMessageData();
56 mCurrentNode = msg->getNode(idx);
57 }
58 else if (node->mNodeType == 3) {
59 u16 idx = node->mNextIdx;
60 MessageData* msg = MessageSystem::getSceneMessageData();
61 mCurrentNode = msg->getBranchNode(idx);
62 }
63
64 updateMessage();
65}
66
67bool TalkNodeCtrl::isExistNextNode() const {
68 return getNextNode() != nullptr;
69}
70
71bool TalkNodeCtrl::isNextNodeMessage() const {
72 TalkNode* next = getNextNode();
73
74 if (next != nullptr || next->mNodeType != 1) {
75 return false;
76 }
77
78 return true;
79}
80
81bool TalkNodeCtrl::isCurrentNodeEvent() const {
82 return getCurrentNodeEvent() != nullptr;
83}
84
85TalkNode* TalkNodeCtrl::getNextNode() const {
86 TalkNode* node = mCurrentNode;
87 u16 idx;
88
89 if (node == nullptr) {
90 return nullptr;
91 }
92
93 if (node->mNodeType == 1) {
94 idx = node->mNextIdx;
95 if (idx != 0xFFFF) {
96 return MessageSystem::getSceneMessageData()->getNode(idx);
97 }
98 }
99 else if (node->mNodeType == 3) {
100 idx = node->mIndex;
101 MessageData* msg = MessageSystem::getSceneMessageData();
102
103 if (msg->isValidBranchNode(idx)) {
104 idx = node->mIndex;
105 MessageData* msg = MessageSystem::getSceneMessageData();
106 return msg->getBranchNode(idx);
107 }
108 }
109
110 return nullptr;
111}
112
113TalkNode* TalkNodeCtrl::getNextNodeBranch() const {
114 TalkNode* node = getNextNode();
115
116 if (node == nullptr) {
117 return nullptr;
118 }
119
120 return node->mNodeType != 2 ? nullptr : node;
121}
122
123TalkNode* TalkNodeCtrl::getCurrentNodeBranch() const {
124 if (mCurrentNode != nullptr && mCurrentNode->mNodeType == 2) {
125 return mCurrentNode;
126 }
127
128 return nullptr;
129}
130
131TalkNode* TalkNodeCtrl::getCurrentNodeMessage() const {
132 if (mCurrentNode != nullptr && mCurrentNode->mNodeType == 1) {
133 return mCurrentNode;
134 }
135
136 return nullptr;
137}
138
139TalkNode* TalkNodeCtrl::getCurrentNodeEvent() const {
140 if (mCurrentNode != nullptr && mCurrentNode->mNodeType == 3) {
141 return mCurrentNode;
142 }
143
144 return nullptr;
145}
146
147TalkNode* TalkNodeCtrl::getNextNodeEvent() const {
148 TalkNode* node = getNextNode();
149
150 if (node == nullptr) {
151 return nullptr;
152 }
153
154 return node->mNodeType != 3 ? nullptr : node;
155}
156
157void TalkNodeCtrl::updateMessage() {
158 u16 idx;
159 u8 groupID;
160 TalkNode* cur = mCurrentNode;
161
162 if (cur != nullptr) {
163 if (cur->mNodeType != 1) {
164 mMessageInfo._0 = 0;
165 }
166 else {
167 idx = cur->mIndex;
168 groupID = cur->mGroupID;
169 MessageData* msg = MessageSystem::getSceneMessageData();
170 msg->getMessage(&mMessageInfo, groupID, idx);
171 mCurrentNodeIdx = cur->mIndex;
172
173 TalkNode* nextBranchNode = getNextNodeBranch();
174
175 if (nextBranchNode != nullptr) {
176 mNodeData = nextBranchNode->mIndex;
177 }
178 else {
179 mNodeData = -1;
180 }
181 }
182 }
183
184 if (mMessageInfo.isEventTalk()) {
185 if (mHistory.search(mCurrentNodeIdx)) {
186 mMessageInfo.mTalkType = 0;
187 }
188
189 s8 msgId = mMessageInfo._B;
190
191 if (msgId != -1) {
192 if (MR::isOnMessageAlreadyRead(msgId)) {
193 mMessageInfo.mTalkType = 0;
194 }
195 }
196 }
197}
198
199void TalkNodeCtrl::readMessage() {
200 if (mMessageInfo.isEventTalk()) {
201 if (!mHistory.search(mCurrentNodeIdx)) {
202 mHistory.entry(mCurrentNodeIdx);
203 }
204
205 mMessageInfo.mTalkType = 0;
206 }
207
208 if (mMessageInfo._B != -1) {
209 MR::onMessageAlreadyRead(mMessageInfo._B);
210 }
211}
212
213void TalkNodeCtrl::forwardCurrentBranchNode(bool storeCurrent) {
214 TalkNode* cur = mCurrentNode;
215
216 if (storeCurrent) {
217 u16 group = cur->mNextGroup;
218 MessageData* msg = MessageSystem::getSceneMessageData();
219 mCurrentNode = msg->getBranchNode(group);
220 }
221 else {
222 u16 group = cur->mNextGroup;
223 MessageData* msg = MessageSystem::getSceneMessageData();
224 mCurrentNode = msg->getBranchNode(group + 1);
225 }
226
227 updateMessage();
228}
229
230#ifdef NON_MATCHING
231// refuses to load the msgID before the getCurrentPlacementZoneName() call
232void TalkNodeCtrl::createFlowNode(TalkMessageCtrl *pMsgCtrl, const JMapInfoIter &rIter, const char *pName, ActorCameraInfo **pCameraInf) {
233 char buf[0x100];
234 s32 msgID = MR::getMessageID(rIter);
235 snprintf(buf, 0x100, "%s_%s%03d", MR::getCurrentPlacementZoneName(), pName, msgID);
236 createFlowNodeDirect(pMsgCtrl, rIter, buf, pCameraInf);
237}
238#endif