Skip to content

Commit

Permalink
Save state and load initial
Browse files Browse the repository at this point in the history
  • Loading branch information
ZikkeyLS committed Jun 9, 2024
1 parent 4c463f4 commit b43ac9a
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 9 deletions.
4 changes: 2 additions & 2 deletions skymp5-server/cpp/server_guest_lib/Faction.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

struct Faction
{
uint32_t formID;
uint32_t formId;
int8_t rank;

friend bool operator==(const Faction& r, const Faction& l)
{
return r.formID == l.formID;
return r.formId == l.formId;
}

friend bool operator!=(const Faction& r, const Faction& l)
Expand Down
44 changes: 43 additions & 1 deletion skymp5-server/cpp/server_guest_lib/MpChangeForms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ std::vector<std::string> ToStringArray(const std::vector<FormDesc>& formDescs)
[](const FormDesc& v) { return v.ToString(); });
return res;
}

std::vector<FormDesc> ToFormDescsArray(const std::vector<std::string>& strings)
{
std::vector<FormDesc> res(strings.size());
Expand Down Expand Up @@ -96,6 +97,20 @@ nlohmann::json MpChangeForm::ToJson(const MpChangeForm& changeForm)
res["displayName"] = *changeForm.displayName;
}

if (changeForm.factions.has_value() &&
!changeForm.factions.value().empty()) {
auto factionsJson = nlohmann::json::array();
for (int i = 0; i < static_cast<int>(changeForm.factions.value().size());
++i) {
nlohmann::json obj = {
{ "formId", changeForm.factions.value()[i].formId },
{ "rank", (uint32_t)changeForm.factions.value()[i].rank }
};
factionsJson.push_back(obj);
}
res["factions"] = { { "entries", factionsJson } };
}

return res;
}

Expand All @@ -118,7 +133,7 @@ MpChangeForm MpChangeForm::JsonToChangeForm(simdjson::dom::element& element)
spawnDelay("spawnDelay"), effects("effects"),
templateChain("templateChain"), lastAnimation("lastAnimation"),
setNodeTextureSet("setNodeTextureSet"), setNodeScale("setNodeScale"),
displayName("displayName");
displayName("displayName"), factions("factions");

MpChangeForm res;
ReadEx(element, recType, &res.recType);
Expand Down Expand Up @@ -281,6 +296,33 @@ MpChangeForm MpChangeForm::JsonToChangeForm(simdjson::dom::element& element)
res.displayName = tmp;
}

if (element.at_pointer(factions.GetData()).error() ==
simdjson::error_code::SUCCESS) {
ReadEx(element, factions, &jTmp);
static const JsonPointer entries("entries");

std::vector<simdjson::dom::element> parsedEntries;
ReadVector(jTmp, entries, &parsedEntries);

std::vector<Faction> factions = std::vector<Faction>(parsedEntries.size());

for (size_t i = 0; i != parsedEntries.size(); ++i) {
auto& jEntry = parsedEntries[i];

static JsonPointer formId("formId"), rank("rank");
Faction fact = Faction();
ReadEx(jEntry, formId, &fact.formId);

uint32_t rankTemp = 0;
ReadEx(jEntry, rank, &rankTemp);
fact.rank = rankTemp;

factions[i] = fact;
}

res.factions = factions;
}

return res;
}

Expand Down
6 changes: 3 additions & 3 deletions skymp5-server/cpp/server_guest_lib/MpObjectReference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,7 @@ void MpObjectReference::AddToFaction(Faction faction)
changeForm.factions.value().push_back(faction);
} else {
for (const auto& fact : changeForm.factions.value()) {
if (faction.formID == fact.formID) {
if (faction.formId == fact.formId) {
return;
}
}
Expand All @@ -934,7 +934,7 @@ bool MpObjectReference::IsInFaction(uint32_t factionFormID)
}

for (const auto& faction : factions.value()) {
if (faction.formID == factionFormID) {
if (faction.formId == factionFormID) {
return true;
}
}
Expand All @@ -950,7 +950,7 @@ void MpObjectReference::RemoveFromFaction(uint32_t factionFormID)

for (auto it = changeForm.factions.value().begin();
it != changeForm.factions.value().end(); ++it) {
if (it->formID == factionFormID) {
if (it->formId == factionFormID) {
changeForm.factions.value().erase(it);
return;
}
Expand Down
18 changes: 17 additions & 1 deletion skymp5-server/cpp/server_guest_lib/WorldState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -581,15 +581,31 @@ bool WorldState::AttachEspmRecord(const espm::CombineBrowser& br,
LocationalDataUtils::GetRot(locationalData),
FormDesc::FromFormId(worldOrCell, espmFiles)
};

MpChangeFormREFR* changeForm = nullptr;
if (!isNpc) {
form.reset(new MpObjectReference(formLocationalData,
formCallbacksFactory(), baseId,
typeStr.data(), primitiveBoundsDiv2));
} else {
form.reset(
new MpActor(formLocationalData, formCallbacksFactory(), baseId));

if (isNpc) {
changeForm->factions = std::vector<Faction>();

auto npcData =
reinterpret_cast<const espm::NPC_*>(base.rec)->GetData(cache);

for (auto npcFaction : npcData.factions) {
Faction faction = Faction();
faction.formId = npcFaction.formId;
faction.rank = npcFaction.rank;
changeForm->factions.value().push_back(faction);
}
}
}
AddForm(std::move(form), formId, true);
AddForm(std::move(form), formId, true, changeForm);

// Do not TriggerFormInitEvent here, doing it later after changeForm apply

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ VarValue PapyrusActor::AddToFaction(VarValue self,
WorldState* worldState = compatibilityPolicy->GetWorldState();

Faction resultFaction = Faction();
resultFaction.formID = factionRec.rec->GetId();
resultFaction.formId = factionRec.rec->GetId();
resultFaction.rank = 0;

actor->AddToFaction(resultFaction);
Expand Down Expand Up @@ -383,7 +383,7 @@ VarValue PapyrusActor::GetFactions(VarValue self,
for (const auto& faction : factions.value()) {
if (faction.rank >= minFactionRank && faction.rank <= maxFactionRank) {
result.pArray->push_back(VarValue(std::make_shared<EspmGameObject>(
worldState->GetEspm().GetBrowser().LookupById(faction.formID))));
worldState->GetEspm().GetBrowser().LookupById(faction.formId))));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once
#include "IPapyrusClass.h"
#include "WorldState.h"
#include "script_objects/EspmGameObject.h"

class PapyrusSkymp final : public IPapyrusClass<PapyrusSkymp>
Expand Down

0 comments on commit b43ac9a

Please sign in to comment.