@@ -121,12 +121,12 @@ DEFINE_HOOK(0x43FB23, BuildingClass_AI_Radiation, 0x5)
121
121
if (pBuilding->Type ->ImmuneToRadiation || pBuilding->InLimbo || pBuilding->BeingWarpedOut || pBuilding->TemporalTargetingMe )
122
122
return 0 ;
123
123
124
- int radDelay = RulesExt::Global ()->RadApplicationDelay_Building ;
125
-
126
- if (RulesExt::Global ()->UseGlobalRadApplicationDelay &&
127
- (radDelay == 0 || Unsorted::CurrentFrame % radDelay != 0 ))
124
+ if (RulesExt::Global ()->UseGlobalRadApplicationDelay )
128
125
{
129
- return 0 ;
126
+ const int delay = RulesExt::Global ()->RadApplicationDelay_Building ;
127
+
128
+ if (delay == 0 || Unsorted::CurrentFrame % delay)
129
+ return 0 ;
130
130
}
131
131
132
132
const auto buildingCoords = pBuilding->GetMapCoords ();
@@ -141,39 +141,65 @@ DEFINE_HOOK(0x43FB23, BuildingClass_AI_Radiation, 0x5)
141
141
continue ;
142
142
143
143
const auto pCellExt = CellExt::ExtMap.Find (pCell);
144
+ std::vector<std::pair<RadTypeClass*, std::vector<std::pair<RadSiteClass*, int >>>> typeMap;
145
+ typeMap.reserve (RadTypeClass::Array.size ());
144
146
145
147
for (const auto & [pRadSite, radLevel] : pCellExt->RadLevels )
146
148
{
147
149
if (radLevel <= 0 )
148
150
continue ;
149
151
150
152
const auto pRadExt = RadSiteExt::ExtMap.Find (pRadSite);
151
- RadTypeClass* pType = pRadExt->Type ;
152
- int maxDamageCount = pType ->GetBuildingDamageMaxCount ();
153
+ const auto pRadType = pRadExt->Type ;
154
+ int maxDamageCount = pRadType ->GetBuildingDamageMaxCount ();
153
155
154
156
if (maxDamageCount > 0 && damageCounts[pRadSite] >= maxDamageCount)
155
157
continue ;
156
158
157
- if (!pType ->GetWarhead ())
159
+ if (!pRadType ->GetWarhead ())
158
160
continue ;
159
161
160
162
if (!RulesExt::Global ()->UseGlobalRadApplicationDelay )
161
163
{
162
- int delay = pType ->GetBuildingApplicationDelay ();
164
+ const int delay = pRadType ->GetBuildingApplicationDelay ();
163
165
164
- if (( delay == 0 ) || ( Unsorted::CurrentFrame % delay != 0 ) )
166
+ if (delay == 0 || Unsorted::CurrentFrame % delay)
165
167
continue ;
166
168
}
167
169
168
- if (pBuilding->IsAlive ) // simple fix for previous issues
170
+ const auto it = std::ranges::find_if (typeMap, [pRadType](std::pair<RadTypeClass*, std::vector<std::pair<RadSiteClass*, int >>> const & item) { return item.first == pRadType; });
171
+
172
+ if (it != typeMap.cend ())
173
+ {
174
+ it->second .emplace_back (pRadSite, radLevel);
175
+ }
176
+ else
177
+ {
178
+ std::vector<std::pair<RadSiteClass*, int >> sites { std::make_pair (pRadSite, radLevel) };
179
+ typeMap.emplace_back (pRadType, std::move (sites));
180
+ }
181
+ }
182
+
183
+ for (auto & [_, sites] : typeMap)
184
+ std::ranges::stable_sort (sites, [](std::pair<RadSiteClass*, int > const & left, std::pair<RadSiteClass*, int > const & right) { return left.second > right.second ; });
185
+
186
+ for (const auto & [pRadType, sites] : typeMap)
187
+ {
188
+ const int radLevelMax = pRadType->GetLevelMax ();
189
+ int radLevelSum = 0 ;
190
+
191
+ for (const auto & [pRadSite, radLevel] : sites)
169
192
{
170
- int damage = Game::F2I (radLevel * pType->GetLevelFactor ());
193
+ const int remain = radLevelMax - radLevelSum;
194
+ int damage = static_cast <int >(std::min (radLevel, remain) * pRadType->GetLevelFactor ());
171
195
172
- if (maxDamageCount > 0 )
173
- damageCounts[pRadSite]++ ;
196
+ if (pBuilding-> IsAlive && !RadSiteExt::ExtMap. Find (pRadSite)-> ApplyRadiationDamage (pBuilding, damage) )
197
+ return 0 ;
174
198
175
- if (!pRadExt-> ApplyRadiationDamage (pBuilding, damage) )
199
+ if (radLevel >= remain )
176
200
break ;
201
+
202
+ radLevelSum += radLevel;
177
203
}
178
204
}
179
205
}
@@ -196,32 +222,61 @@ DEFINE_HOOK(0x4DA59F, FootClass_AI_Radiation, 0x5)
196
222
{
197
223
const auto pCell = pFoot->GetCell ();
198
224
const auto pCellExt = CellExt::ExtMap.Find (pCell);
225
+ std::vector<std::pair<RadTypeClass*, std::vector<std::pair<RadSiteClass*, int >>>> typeMap;
226
+ typeMap.reserve (RadTypeClass::Array.size ());
199
227
200
228
for (const auto & [pRadSite, radLevel] : pCellExt->RadLevels )
201
229
{
202
230
if (radLevel <= 0 )
203
231
continue ;
204
232
205
233
const auto pRadExt = RadSiteExt::ExtMap.Find (pRadSite);
206
- RadTypeClass* pType = pRadExt->Type ;
234
+ const auto pRadType = pRadExt->Type ;
207
235
208
- if (!pType ->GetWarhead ())
236
+ if (!pRadType ->GetWarhead ())
209
237
continue ;
210
238
211
239
if (!RulesExt::Global ()->UseGlobalRadApplicationDelay )
212
240
{
213
- int delay = pType ->GetApplicationDelay ();
241
+ const int delay = pRadType ->GetApplicationDelay ();
214
242
215
- if (( delay == 0 ) || ( Unsorted::CurrentFrame % delay != 0 ) )
243
+ if (delay == 0 || Unsorted::CurrentFrame % delay)
216
244
continue ;
217
245
}
218
246
219
- if (pFoot->IsAlive || !pFoot->IsSinking )
247
+ const auto it = std::ranges::find_if (typeMap, [pRadType](std::pair<RadTypeClass*, std::vector<std::pair<RadSiteClass*, int >>> const & item) { return item.first == pRadType; });
248
+
249
+ if (it != typeMap.cend ())
250
+ {
251
+ it->second .emplace_back (pRadSite, radLevel);
252
+ }
253
+ else
254
+ {
255
+ std::vector<std::pair<RadSiteClass*, int >> sites { std::make_pair (pRadSite, radLevel) };
256
+ typeMap.emplace_back (pRadType, std::move (sites));
257
+ }
258
+ }
259
+
260
+ for (auto & [_, sites] : typeMap)
261
+ std::ranges::stable_sort (sites, [](std::pair<RadSiteClass*, int > const & left, std::pair<RadSiteClass*, int > const & right) { return left.second > right.second ; });
262
+
263
+ for (const auto & [pRadType, sites] : typeMap)
264
+ {
265
+ const int radLevelMax = pRadType->GetLevelMax ();
266
+ int radLevelSum = 0 ;
267
+
268
+ for (const auto & [pRadSite, radLevel] : sites)
220
269
{
221
- int damage = Game::F2I (radLevel * pType->GetLevelFactor ());
270
+ const int remain = radLevelMax - radLevelSum;
271
+ int damage = static_cast <int >(std::min (radLevel, remain) * pRadType->GetLevelFactor ());
272
+
273
+ if ((pFoot->IsAlive || !pFoot->IsSinking ) && !RadSiteExt::ExtMap.Find (pRadSite)->ApplyRadiationDamage (pFoot, damage))
274
+ return ReturnFromFunction;
222
275
223
- if (!pRadExt-> ApplyRadiationDamage (pFoot, damage) )
276
+ if (radLevel >= remain )
224
277
break ;
278
+
279
+ radLevelSum += radLevel;
225
280
}
226
281
}
227
282
}
0 commit comments