| 544 | |
| 545 | |
| 546 | void CustomFunctionLibrary::OnApplyStatus(esv::StatusMachine__ApplyStatus wrappedApply, esv::StatusMachine * self, esv::Status * status) |
| 547 | { |
| 548 | // Don't throw events for inactive status machines, as those will get swallowed |
| 549 | // by Osiris during loading anyway. |
| 550 | if (!self->IsStatusMachineActive) { |
| 551 | wrappedApply(self, status); |
| 552 | return; |
| 553 | } |
| 554 | |
| 555 | char const * targetGuid{ nullptr }; |
| 556 | auto target = FindGameObjectByHandle(self->OwnerObjectHandle); |
| 557 | if (target != nullptr) { |
| 558 | targetGuid = target->GetGuid()->Str; |
| 559 | } else { |
| 560 | OsiError("Can't throw ApplyStatus event - target handle could not be resolved."); |
| 561 | } |
| 562 | |
| 563 | bool eventThrown{ false }; |
| 564 | if (targetGuid != nullptr) { |
| 565 | char const * sourceGuid = "NULL_00000000-0000-0000-0000-000000000000"; |
| 566 | if (status->StatusSourceHandle) { |
| 567 | auto source = FindGameObjectByHandle(status->StatusSourceHandle); |
| 568 | if (source != nullptr) { |
| 569 | sourceGuid = source->GetGuid()->Str; |
| 570 | } |
| 571 | } |
| 572 | |
| 573 | auto eventArgs = OsiArgumentDesc::Create(OsiArgumentValue{ ValueType::GuidString, targetGuid }); |
| 574 | eventArgs->Add(OsiArgumentValue{ ValueType::String, status->StatusId.Str }); |
| 575 | eventArgs->Add(OsiArgumentValue{ (int64_t)status->StatusHandle }); |
| 576 | eventArgs->Add(OsiArgumentValue{ ValueType::GuidString, sourceGuid }); |
| 577 | |
| 578 | gPendingStatuses.Add(status); |
| 579 | eventThrown = true; |
| 580 | gOsirisProxy->GetCustomFunctionInjector().ThrowEvent(StatusAttemptEventHandle, eventArgs); |
| 581 | |
| 582 | delete eventArgs; |
| 583 | } |
| 584 | |
| 585 | bool previousPreventApplyState = self->PreventStatusApply; |
| 586 | if (eventThrown) { |
| 587 | ObjectHandle targetHandle; |
| 588 | target->GetObjectHandle(&targetHandle); |
| 589 | |
| 590 | auto pendingStatus = gPendingStatuses.Find(targetHandle, status->StatusHandle); |
| 591 | if (pendingStatus != nullptr) { |
| 592 | self->PreventStatusApply = pendingStatus->PreventApply; |
| 593 | } else { |
| 594 | OsiError("Status not found in pending status list during ApplyStatus ?!"); |
| 595 | } |
| 596 | } |
| 597 | |
| 598 | wrappedApply(self, status); |
| 599 | |
| 600 | self->PreventStatusApply = previousPreventApplyState; |
| 601 | |
| 602 | if (eventThrown) { |
| 603 | gPendingStatuses.Remove(status); |
nothing calls this directly
no test coverage detected