1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-01 04:39:44 +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);
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())
{
ESM::RefId primaryFactionId = ptr.getClass().getPrimaryFaction(ptr);
if (value <= 0 || factionId != primaryFactionId)
return;
if (factionId != primaryFactionId)
throw std::runtime_error("Only players can modify ranks in non-primary factions");
}
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.joinFaction(factionId);
npcStats.setFactionRank(factionId, std::min(value - 1, ranksCount - 1));
npcStats.setFactionRank(factionId, targetRank);
};
npc["modifyFactionRank"] = [](Object& actor, std::string_view faction, int value) {
@ -175,35 +178,62 @@ namespace MWLua
{
int currentRank = npcStats.getFactionRank(factionId);
if (currentRank >= 0)
{
npcStats.setFactionRank(factionId, currentRank + value);
}
else if (value > 0)
{
npcStats.joinFaction(factionId);
npcStats.setFactionRank(factionId, std::min(value - 1, ranksCount - 1));
}
npcStats.setFactionRank(factionId, std::clamp(currentRank + value, 0, ranksCount - 1));
else
throw std::runtime_error("Target actor is not a member of faction " + factionId.toDebugString());
return;
}
ESM::RefId primaryFactionId = ptr.getClass().getPrimaryFaction(ptr);
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.
// Otherwise take rank from base NPC record, adjust it and put it to NPC data.
int currentRank = npcStats.getFactionRank(factionId);
if (currentRank < 0)
{
int rank = ptr.getClass().getPrimaryFactionRank(ptr);
currentRank = ptr.getClass().getPrimaryFactionRank(ptr);
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;
}
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) {

View file

@ -744,12 +744,8 @@
---
-- Set rank of given NPC in given faction.
-- Throws an exception if there is no such faction.
-- For NPCs faction 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.
-- 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 also should be an NPC's primary faction.
-- @function [parent=#NPC] setFactionRank
-- @param openmw.core#GameObject actor NPC object
-- @param #string faction Faction ID
@ -759,12 +755,12 @@
---
-- 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.
-- Throws an exception if there is no such faction or actor is not a member of given faction.
-- For NPCs faction also should be an NPC's primary faction.
-- 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 given value if rank is valid (name is not empty), and to the highest valid rank otherwise.
-- * If rank should become <= 0 after modification, function set rank to lowest available rank.
-- * 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
-- @param openmw.core#GameObject actor NPC object
-- @param #string faction Faction ID
@ -772,6 +768,27 @@
-- @usage local NPC = require('openmw.types').NPC;
-- 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.
-- Throws an exception if there is no such faction.