1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-01 07:09:41 +00:00

Split setFactionRank to separate functions

This commit is contained in:
Andrei Kortunov 2023-09-12 11:48:59 +04:00
parent 6ee86dea82
commit 02dcf1fb31
2 changed files with 76 additions and 29 deletions

View file

@ -136,20 +136,23 @@ namespace MWLua
= MWBase::Environment::get().getESMStore()->get<ESM::Faction>().find(factionId); = MWBase::Environment::get().getESMStore()->get<ESM::Faction>().find(factionId);
auto ranksCount = static_cast<int>(getValidRanksCount(factionPtr)); auto ranksCount = static_cast<int>(getValidRanksCount(factionPtr));
if (value <= 0 || value > ranksCount)
throw std::runtime_error("Requested rank does not exist");
auto targetRank = std::clamp(value, 1, ranksCount) - 1;
if (ptr != MWBase::Environment::get().getWorld()->getPlayerPtr()) if (ptr != MWBase::Environment::get().getWorld()->getPlayerPtr())
{ {
ESM::RefId primaryFactionId = ptr.getClass().getPrimaryFaction(ptr); ESM::RefId primaryFactionId = ptr.getClass().getPrimaryFaction(ptr);
if (value <= 0 || factionId != primaryFactionId) if (factionId != primaryFactionId)
return; throw std::runtime_error("Only players can modify ranks in non-primary factions");
} }
MWMechanics::NpcStats& npcStats = ptr.getClass().getNpcStats(ptr); MWMechanics::NpcStats& npcStats = ptr.getClass().getNpcStats(ptr);
if (!npcStats.isInFaction(factionId))
throw std::runtime_error("Target actor is not a member of faction " + factionId.toDebugString());
if (!npcStats.isInFaction(factionId) && value > 0) npcStats.setFactionRank(factionId, targetRank);
npcStats.joinFaction(factionId);
npcStats.setFactionRank(factionId, std::min(value - 1, ranksCount - 1));
}; };
npc["modifyFactionRank"] = [](Object& actor, std::string_view faction, int value) { npc["modifyFactionRank"] = [](Object& actor, std::string_view faction, int value) {
@ -175,35 +178,62 @@ namespace MWLua
{ {
int currentRank = npcStats.getFactionRank(factionId); int currentRank = npcStats.getFactionRank(factionId);
if (currentRank >= 0) if (currentRank >= 0)
{ npcStats.setFactionRank(factionId, std::clamp(currentRank + value, 0, ranksCount - 1));
npcStats.setFactionRank(factionId, currentRank + value); else
} throw std::runtime_error("Target actor is not a member of faction " + factionId.toDebugString());
else if (value > 0)
{
npcStats.joinFaction(factionId);
npcStats.setFactionRank(factionId, std::min(value - 1, ranksCount - 1));
}
return; return;
} }
ESM::RefId primaryFactionId = ptr.getClass().getPrimaryFaction(ptr); ESM::RefId primaryFactionId = ptr.getClass().getPrimaryFaction(ptr);
if (factionId != primaryFactionId) if (factionId != primaryFactionId)
return; throw std::runtime_error("Only players can modify ranks in non-primary factions");
// If we already changed rank for this NPC, modify current rank in the NPC stats. // If we already changed rank for this NPC, modify current rank in the NPC stats.
// Otherwise take rank from base NPC record, adjust it and put it to NPC data. // Otherwise take rank from base NPC record, adjust it and put it to NPC data.
int currentRank = npcStats.getFactionRank(factionId); int currentRank = npcStats.getFactionRank(factionId);
if (currentRank < 0) if (currentRank < 0)
{ {
int rank = ptr.getClass().getPrimaryFactionRank(ptr); currentRank = ptr.getClass().getPrimaryFactionRank(ptr);
npcStats.joinFaction(factionId); npcStats.joinFaction(factionId);
npcStats.setFactionRank(factionId, std::clamp(0, rank + value, ranksCount - 1)); }
npcStats.setFactionRank(factionId, std::clamp(currentRank + value, 0, ranksCount - 1));
};
npc["joinFaction"] = [](Object& actor, std::string_view faction) {
if (dynamic_cast<LObject*>(&actor) && !dynamic_cast<SelfObject*>(&actor))
throw std::runtime_error("Local scripts can modify only self");
const MWWorld::Ptr ptr = actor.ptr();
ESM::RefId factionId = parseFactionId(faction);
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
{
MWMechanics::NpcStats& npcStats = ptr.getClass().getNpcStats(ptr);
int currentRank = npcStats.getFactionRank(factionId);
if (currentRank < 0)
npcStats.joinFaction(factionId);
return; return;
} }
else
npcStats.setFactionRank(factionId, std::clamp(0, currentRank + value, ranksCount - 1)); throw std::runtime_error("Only player can join factions");
};
npc["leaveFaction"] = [](Object& actor, std::string_view faction) {
if (dynamic_cast<LObject*>(&actor) && !dynamic_cast<SelfObject*>(&actor))
throw std::runtime_error("Local scripts can modify only self");
const MWWorld::Ptr ptr = actor.ptr();
ESM::RefId factionId = parseFactionId(faction);
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
{
ptr.getClass().getNpcStats(ptr).setFactionRank(factionId, -1);
return;
}
throw std::runtime_error("Only player can leave factions");
}; };
npc["getFactionReputation"] = [](const Object& actor, std::string_view faction) { npc["getFactionReputation"] = [](const Object& actor, std::string_view faction) {

View file

@ -744,12 +744,8 @@
--- ---
-- Set rank of given NPC in given faction. -- Set rank of given NPC in given faction.
-- Throws an exception if there is no such faction. -- Throws an exception if there is no such faction, target rank does not exist or actor is not a member of given faction.
-- For NPCs faction should be an NPC's primary faction. -- For NPCs faction also should be an NPC's primary faction.
-- Notes:
--
-- * "value" <= 0 does nothing for NPCs and make the player character to leave the faction (purge his rank and reputation in faction).
-- * "value" > 0 set rank to given value if rank is valid (name is not empty), and to the highest valid rank otherwise.
-- @function [parent=#NPC] setFactionRank -- @function [parent=#NPC] setFactionRank
-- @param openmw.core#GameObject actor NPC object -- @param openmw.core#GameObject actor NPC object
-- @param #string faction Faction ID -- @param #string faction Faction ID
@ -759,12 +755,12 @@
--- ---
-- Adjust rank of given NPC in given faction. -- Adjust rank of given NPC in given faction.
-- For NPCs faction should be an NPC's primary faction. -- Throws an exception if there is no such faction or actor is not a member of given faction.
-- Throws an exception if there is no such faction. -- For NPCs faction also should be an NPC's primary faction.
-- Notes: -- Notes:
-- --
-- * If rank should become <= 0 after modification, function does nothing for NPCs and makes the player character to leave the faction (purge his rank and reputation in faction). -- * If rank should become <= 0 after modification, function set rank to lowest available rank.
-- * If rank should become > 0 after modification, function set rank to given value if rank is valid (name is not empty), and to the highest valid rank otherwise. -- * If rank should become > 0 after modification, but target rank does not exist, function set rank to the highest valid rank.
-- @function [parent=#NPC] modifyFactionRank -- @function [parent=#NPC] modifyFactionRank
-- @param openmw.core#GameObject actor NPC object -- @param openmw.core#GameObject actor NPC object
-- @param #string faction Faction ID -- @param #string faction Faction ID
@ -772,6 +768,27 @@
-- @usage local NPC = require('openmw.types').NPC; -- @usage local NPC = require('openmw.types').NPC;
-- NPC.modifyFactionRank(player, "mages guild", 1); -- NPC.modifyFactionRank(player, "mages guild", 1);
---
-- Add given actor to given faction.
-- Throws an exception if there is no such faction or target actor is not player.
-- Function does nothing if valid target actor is already a member of target faction.
-- @function [parent=#NPC] joinFaction
-- @param openmw.core#GameObject actor NPC object
-- @param #string faction Faction ID
-- @usage local NPC = require('openmw.types').NPC;
-- NPC.joinFaction(player, "mages guild");
---
-- Remove given actor from given faction.
-- Function removes rank data and expelling state, but keeps a reputation in target faction.
-- Throws an exception if there is no such faction or target actor is not player.
-- Function does nothing if valid target actor is already not member of target faction.
-- @function [parent=#NPC] leaveFaction
-- @param openmw.core#GameObject actor NPC object
-- @param #string faction Faction ID
-- @usage local NPC = require('openmw.types').NPC;
-- NPC.leaveFaction(player, "mages guild");
--- ---
-- Get reputation of given actor in given faction. -- Get reputation of given actor in given faction.
-- Throws an exception if there is no such faction. -- Throws an exception if there is no such faction.