Skip to content

Commit

Permalink
Merge pull request LandSandBoat#4363 from LandSandBoat/optic-fiber-im…
Browse files Browse the repository at this point in the history
…provements

Correct Automaton maneuver tracking with optic fiber and negative mods
  • Loading branch information
claywar authored Aug 26, 2023
2 parents 1785ecc + 26e6b22 commit 7ab446f
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 16 deletions.
50 changes: 41 additions & 9 deletions scripts/globals/automaton.lua
Original file line number Diff line number Diff line change
Expand Up @@ -187,16 +187,31 @@ local function getRefreshModValue(pet, attachmentName, numManeuvers)
return regenRefreshFormulas[attachmentName][1][numManeuvers + 1] + petMaxMP * (regenRefreshFormulas[attachmentName][2][numManeuvers + 1] / 100)
end

-- TODO: This may still be necessary with future updates
--[[
local function isOpticFiber(attachmentName)
if string.find(attachmentName, 'optic_fiber') ~= nil then
return true
end

return false
end
]]--

-- Due to load order, we can't expect to determine Optic Fiber enhancements on change.
-- For maneuvers, calculate this based on the number of light maneuvers that are active.
local function calculatePerformanceBoost(pet, numManeuvers)
local master = pet:getMaster()
local performanceBoost = 0

local numLightManeuvers = master and master:countEffect(xi.effect.LIGHT_MANEUVER) or 0
for _, attachmentObj in ipairs(pet:getAttachments()) do
local attachmentName = attachmentObj:getName()

if isOpticFiber(attachmentName) then
performanceBoost = performanceBoost + attachmentModifiers[attachmentName][1][2][numLightManeuvers + 1]
end
end

return performanceBoost
end

-- Global functions to handle attachment equip, unequip, maneuver and performance changes
-- NOTE: Core is 0-indexed for maneuvers, yet the table above is 1-indexed, and Maneuvers
Expand Down Expand Up @@ -225,12 +240,19 @@ end

xi.automaton.updateAttachmentModifier = function(pet, attachment, maneuvers)
local attachmentName = attachment:getName()
local modTable = attachmentModifiers[attachmentName]
local modTable = attachmentModifiers[attachmentName]

for k, modList in ipairs(modTable) do
local previousMod = pet:getLocalVar(attachmentName .. k)
for attachmentModPos, modList in ipairs(modTable) do
local previousMod = pet:getLocalVar(attachmentName .. attachmentModPos)
local modValue = 0

-- Local Vars are uint. In all cases, a negative modifier carries
-- for all number of maneuvers, so if the last entry is negative,
-- restore this as a negative value.
if modList[2][4] and modList[2][4] < 0 then
previousMod = previousMod * -1
end

-- Get base modifier value
if modList[1] == xi.mod.REGEN then
modValue = getRegenModValue(pet, attachmentName, maneuvers)
Expand All @@ -240,9 +262,9 @@ xi.automaton.updateAttachmentModifier = function(pet, attachment, maneuvers)
modValue = modList[2][maneuvers + 1]
end

-- Apply Automaton Performance Boost if applicable
-- Apply Automaton Performance Boost if applicable.
if modList[3] then
modValue = math.floor(modValue * (1 + pet:getMod(xi.mod.AUTO_PERFORMANCE_BOOST) / 100))
modValue = math.floor(modValue * (1 + calculatePerformanceBoost(pet, maneuvers) / 100))
end

if modValue ~= previousMod then
Expand All @@ -258,7 +280,17 @@ xi.automaton.updateAttachmentModifier = function(pet, attachment, maneuvers)
pet:addMod(modList[1], modValue)
end

pet:setLocalVar(attachmentName .. k, modValue)
pet:setLocalVar(attachmentName .. attachmentModPos, math.abs(modValue))

-- If this is an Optic Fiber, there may be other maneuvers and attachments that need to be
-- updated.
local master = pet:getMaster()
if
master and
isOpticFiber(attachmentName)
then
master:updateAttachments()
end
end
end
end
Expand Down
57 changes: 57 additions & 0 deletions src/map/lua/lua_baseentity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14523,6 +14523,61 @@ void CLuaBaseEntity::removeAllManeuvers()
PEntity->StatusEffectContainer->RemoveAllManeuvers();
}

/************************************************************************
* Function: getAttachment(slotId)
* Purpose : Gets the attachment of an automaton in the slot specified
* Example : pet:getAttachment(1)
************************************************************************/

std::optional<CLuaItem> CLuaBaseEntity::getAttachment(uint8 slotId)
{
auto* PAutomaton = dynamic_cast<CAutomatonEntity*>(m_PBaseEntity);

if (PAutomaton == nullptr)
{
ShowWarning("Invalid Entity accessing function.");
return std::nullopt;
}

uint8 slotItem = PAutomaton->getAttachment(slotId);
if (slotItem != 0)
{
return CLuaItem(itemutils::GetItemPointer(0x2100 + slotItem)); // TODO: Stop storing by offset
}

return std::nullopt;
}

/************************************************************************
* Function: getAttachments()
* Purpose : Returns a table of attachment items equipped by an Automaton
* Example : pet:getAttachments()
************************************************************************/

sol::table CLuaBaseEntity::getAttachments()
{
auto* PAutomaton = dynamic_cast<CAutomatonEntity*>(m_PBaseEntity);

if (PAutomaton == nullptr)
{
ShowWarning("Invalid Entity accessing function.");
return sol::lua_nil;
}

auto attachmentTable = lua.create_table();
for (uint8 attachmentSlot = 0; attachmentSlot < 12; ++attachmentSlot)
{
uint8 attachmentItemId = PAutomaton->getAttachment(attachmentSlot);

if (attachmentItemId != 0)
{
attachmentTable[attachmentSlot] = CLuaItem(itemutils::GetItemPointer(0x2100 + attachmentItemId));
}
}

return attachmentTable;
}

/************************************************************************
* Function: updateAttachments()
* Purpose : Updates all of the attachments
Expand Down Expand Up @@ -17407,6 +17462,8 @@ void CLuaBaseEntity::Register()
SOL_REGISTER("getActiveManeuverCount", CLuaBaseEntity::getActiveManeuverCount);
SOL_REGISTER("removeOldestManeuver", CLuaBaseEntity::removeOldestManeuver);
SOL_REGISTER("removeAllManeuvers", CLuaBaseEntity::removeAllManeuvers);
SOL_REGISTER("getAttachment", CLuaBaseEntity::getAttachment);
SOL_REGISTER("getAttachments", CLuaBaseEntity::getAttachments);
SOL_REGISTER("updateAttachments", CLuaBaseEntity::updateAttachments);
SOL_REGISTER("reduceBurden", CLuaBaseEntity::reduceBurden);

Expand Down
2 changes: 2 additions & 0 deletions src/map/lua/lua_baseentity.h
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,8 @@ class CLuaBaseEntity
uint8 getActiveManeuverCount();
void removeOldestManeuver();
void removeAllManeuvers();
auto getAttachment(uint8 slotId) -> std::optional<CLuaItem>;
auto getAttachments() -> sol::table;
void updateAttachments();
void reduceBurden(float percentReduction, sol::object const& intReductionObj);
bool isExceedingElementalCapacity();
Expand Down
9 changes: 5 additions & 4 deletions src/map/status_effect_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,10 +626,6 @@ void CStatusEffectContainer::RemoveStatusEffect(CStatusEffect* PStatusEffect, bo
{
if (!PStatusEffect->deleted)
{
if (PStatusEffect->GetStatusID() >= EFFECT_FIRE_MANEUVER && PStatusEffect->GetStatusID() <= EFFECT_DARK_MANEUVER && m_POwner->objtype == TYPE_PC)
{
puppetutils::CheckAttachmentsForManeuver((CCharEntity*)m_POwner, PStatusEffect->GetStatusID(), false);
}
PStatusEffect->deleted = true;
luautils::OnEffectLose(m_POwner, PStatusEffect);
m_POwner->PAI->EventHandler.triggerListener("EFFECT_LOSE", CLuaBaseEntity(m_POwner), CLuaStatusEffect(PStatusEffect));
Expand All @@ -646,6 +642,11 @@ void CStatusEffectContainer::RemoveStatusEffect(CStatusEffect* PStatusEffect, bo
PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, PStatusEffect->GetIcon(), 0, 206));
}
}

if (PStatusEffect->GetStatusID() >= EFFECT_FIRE_MANEUVER && PStatusEffect->GetStatusID() <= EFFECT_DARK_MANEUVER)
{
puppetutils::CheckAttachmentsForManeuver((CCharEntity*)m_POwner, PStatusEffect->GetStatusID(), false);
}
}
else
{
Expand Down
7 changes: 4 additions & 3 deletions src/map/utils/puppetutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ namespace puppetutils
}
}

// After the Automaton has all attachments set, make sure we update for Optic Fiber
puppetutils::UpdateAttachments(PChar);

// Set burden based on JP
PChar->PAutomaton->setAllBurden(30 - PChar->PJobPoints->GetJobPointValue(JP_ACTIVATE_EFFECT));

Expand Down Expand Up @@ -714,9 +717,7 @@ namespace puppetutils
}
else
{
// Note: This is called before the new maneuver count is known. Send GetStatusEffectsCount - 1 to reflect
// the new value.
luautils::OnManeuverLose(PAutomaton, PAttachment, PChar->StatusEffectContainer->GetEffectsCount(maneuver) - 1);
luautils::OnManeuverLose(PAutomaton, PAttachment, PChar->StatusEffectContainer->GetEffectsCount(maneuver));
}
}
}
Expand Down

0 comments on commit 7ab446f

Please sign in to comment.