|
4 | 4 | #include "MiscUtils.h"
|
5 | 5 | #include "modules/Military.h"
|
6 | 6 | #include "modules/Translation.h"
|
| 7 | +#include "modules/Units.h" |
7 | 8 | #include "df/building.h"
|
8 | 9 | #include "df/building_civzonest.h"
|
| 10 | +#include "df/histfig_entity_link_former_positionst.h" |
| 11 | +#include "df/histfig_entity_link_former_squadst.h" |
| 12 | +#include "df/histfig_entity_link_positionst.h" |
| 13 | +#include "df/histfig_entity_link_squadst.h" |
9 | 14 | #include "df/historical_figure.h"
|
10 | 15 | #include "df/historical_entity.h"
|
11 | 16 | #include "df/entity_position.h"
|
|
16 | 21 | #include "df/squad_schedule_order.h"
|
17 | 22 | #include "df/squad_order.h"
|
18 | 23 | #include "df/squad_order_trainst.h"
|
| 24 | +#include "df/unit.h" |
19 | 25 | #include "df/world.h"
|
20 | 26 |
|
21 | 27 | using namespace DFHack;
|
@@ -289,3 +295,125 @@ void Military::updateRoomAssignments(int32_t squad_id, int32_t civzone_id, df::s
|
289 | 295 | }
|
290 | 296 | }
|
291 | 297 | }
|
| 298 | + |
| 299 | +static void remove_soldier_entity_link(df::historical_figure* hf, df::squad* squad) |
| 300 | +{ |
| 301 | + int32_t start_year = -1; |
| 302 | + for (size_t i = 0; i < hf->entity_links.size(); i++) |
| 303 | + { |
| 304 | + df::histfig_entity_link* link = hf->entity_links[i]; |
| 305 | + if (link->getType() != df::enums::histfig_entity_link_type::SQUAD) |
| 306 | + continue; |
| 307 | + |
| 308 | + auto squad_link = strict_virtual_cast<df::histfig_entity_link_squadst>(link); |
| 309 | + if (squad_link == nullptr || squad_link->squad_id != squad->id) |
| 310 | + continue; |
| 311 | + |
| 312 | + hf->entity_links.erase(hf->entity_links.begin() + i); |
| 313 | + start_year = squad_link->start_year; |
| 314 | + |
| 315 | + delete squad_link; |
| 316 | + break; |
| 317 | + } |
| 318 | + |
| 319 | + if (start_year == -1) |
| 320 | + return; |
| 321 | + |
| 322 | + auto former_squad = df::allocate<df::histfig_entity_link_former_squadst>(); |
| 323 | + former_squad->squad_id = squad->id; |
| 324 | + former_squad->entity_id = squad->entity_id; |
| 325 | + former_squad->start_year = start_year; |
| 326 | + former_squad->end_year = *df::global::cur_year; |
| 327 | + former_squad->link_strength = 100; |
| 328 | + |
| 329 | + hf->entity_links.push_back(former_squad); |
| 330 | +} |
| 331 | + |
| 332 | +static void remove_officer_entity_link(df::historical_figure* hf, df::squad* squad) |
| 333 | +{ |
| 334 | + std::vector<Units::NoblePosition> nps; |
| 335 | + if (!Units::getNoblePositions(&nps, hf)) |
| 336 | + return; |
| 337 | + |
| 338 | + int32_t assignment_id = -1; |
| 339 | + for (auto& np : nps) |
| 340 | + { |
| 341 | + if (np.entity->id != squad->entity_id || np.assignment->squad_id != squad->id) |
| 342 | + continue; |
| 343 | + |
| 344 | + np.assignment->histfig = -1; |
| 345 | + np.assignment->histfig2 = -1; |
| 346 | + |
| 347 | + assignment_id = np.assignment->id; |
| 348 | + break; |
| 349 | + } |
| 350 | + |
| 351 | + if (assignment_id == -1) |
| 352 | + return; |
| 353 | + |
| 354 | + int32_t start_year = -1; |
| 355 | + for (size_t i = 0; i < hf->entity_links.size(); i++) |
| 356 | + { |
| 357 | + df::histfig_entity_link* link = hf->entity_links[i]; |
| 358 | + if (link->getType() != df::enums::histfig_entity_link_type::POSITION) |
| 359 | + continue; |
| 360 | + |
| 361 | + auto pos_link = strict_virtual_cast<df::histfig_entity_link_positionst>(link); |
| 362 | + if (pos_link == nullptr) |
| 363 | + continue; |
| 364 | + if (pos_link->assignment_id != assignment_id && pos_link->entity_id != squad->entity_id) |
| 365 | + continue; |
| 366 | + |
| 367 | + hf->entity_links.erase(hf->entity_links.begin() + i); |
| 368 | + start_year = pos_link->start_year; |
| 369 | + |
| 370 | + delete pos_link; |
| 371 | + break; |
| 372 | + } |
| 373 | + |
| 374 | + if (start_year == -1) |
| 375 | + return; |
| 376 | + |
| 377 | + auto former_pos = df::allocate<df::histfig_entity_link_former_positionst>(); |
| 378 | + former_pos->assignment_id = assignment_id; |
| 379 | + former_pos->entity_id = squad->entity_id; |
| 380 | + former_pos->start_year = start_year; |
| 381 | + former_pos->end_year = *df::global::cur_year; |
| 382 | + former_pos->link_strength = 100; |
| 383 | + |
| 384 | + hf->entity_links.push_back(former_pos); |
| 385 | +} |
| 386 | + |
| 387 | +bool Military::removeFromSquad(int32_t unit_id) |
| 388 | +{ |
| 389 | + df::unit *unit = df::unit::find(unit_id); |
| 390 | + if (unit == nullptr || unit->military.squad_id == -1 || unit->military.squad_position == -1) |
| 391 | + return false; |
| 392 | + |
| 393 | + int32_t squad_id = unit->military.squad_id; |
| 394 | + df::squad* squad = df::squad::find(squad_id); |
| 395 | + if (squad == nullptr) |
| 396 | + return false; |
| 397 | + |
| 398 | + int32_t squad_pos = unit->military.squad_position; |
| 399 | + df::squad_position* pos = vector_get(squad->positions, squad_pos); |
| 400 | + if (pos == nullptr) |
| 401 | + return false; |
| 402 | + |
| 403 | + df::historical_figure* hf = df::historical_figure::find(unit->hist_figure_id); |
| 404 | + if (hf == nullptr) |
| 405 | + return false; |
| 406 | + |
| 407 | + // remove from squad information |
| 408 | + pos->occupant = -1; |
| 409 | + // remove from unit information |
| 410 | + unit->military.squad_id = -1; |
| 411 | + unit->military.squad_position = -1; |
| 412 | + |
| 413 | + if (squad_pos == 0) // is unit a commander? |
| 414 | + remove_officer_entity_link(hf, squad); |
| 415 | + else |
| 416 | + remove_soldier_entity_link(hf, squad); |
| 417 | + |
| 418 | + return true; |
| 419 | +} |
0 commit comments