Skip to content

Commit

Permalink
Merge pull request #4520 from LandSandBoat/magian/dayweather
Browse files Browse the repository at this point in the history
[magian] Add support for day/weather condition to trials
  • Loading branch information
claywar authored Sep 19, 2023
2 parents 411b1ee + fe43f00 commit 9d62a75
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 14 deletions.
1 change: 1 addition & 0 deletions scripts/enum/item.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5785,6 +5785,7 @@ xi.item =
PUGILISTS = 19327,
SIMIAN_FISTS = 19328,
MANTIS = 19329,
CATS_CLAWS = 19331,
PEELER = 19332,
RENEGADE = 19333,
KARTIKA = 19334,
Expand Down
19 changes: 19 additions & 0 deletions scripts/enum/magian_element.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
xi = xi or {}

-- NOTE: These values align with the optParam in the event update for a trial, and are the
-- only groupings supported by the message. These enum is to be used in the dayWeather
-- condition for trial data.
xi.magianElement =
{
FIRE = 0,
ICE = 1,
WIND = 2,
EARTH = 3,
THUNDER = 4,
WATER = 5,
LIGHT = 6,
DARK = 7,
ANY_LIGHT = 8,
ANY_DARK = 9,
ANY = 10,
}
112 changes: 105 additions & 7 deletions scripts/globals/magian.lua
Original file line number Diff line number Diff line change
Expand Up @@ -444,10 +444,15 @@ xi.magian.magianEventUpdate = function(player, csid, option, npc)
local requiredElement = trialData.requiredElement and trialData.requiredElement or 0
local optParam = 0

-- NOTE: optParam value is required for certain messages, and even though
-- this system can support more complex combinations, it may not display correctly
-- if customizing.
if trialData.tradeItem then
optParam = getRequiredTradeItem(trialId)
elseif trialData.minDamage then
optParam = trialData.minDamage
elseif trialData.dayWeather then
optParam = trialData.dayWeather
end

player:updateEvent(trialData.numRequired, 0, progress, 0, 0, optParam, requiredElement)
Expand Down Expand Up @@ -768,8 +773,88 @@ xi.magian.deliveryCrateOnEventFinish = function(player, csid, option)
end
end

-- [elementId] = { validDay, { weatherEffect1, weatherEffect2 } },
local dayWeatherElement =
{
[xi.element.FIRE ] = { xi.day.FIRESDAY, { xi.weather.HOT_SPELL, xi.weather.HEAT_WAVE } },
[xi.element.ICE ] = { xi.day.ICEDAY, { xi.weather.SNOW, xi.weather.BLIZZARDS } },
[xi.element.WIND ] = { xi.day.WINDSDAY, { xi.weather.WIND, xi.weather.GALES } },
[xi.element.EARTH ] = { xi.day.EARTHSDAY, { xi.weather.DUST_STORM, xi.weather.SAND_STORM } },
[xi.element.THUNDER] = { xi.day.LIGHTNINGDAY, { xi.weather.THUNDER, xi.weather.THUNDERSTORMS } },
[xi.element.WATER ] = { xi.day.WATERSDAY, { xi.weather.RAIN, xi.weather.SQUALL } },
[xi.element.LIGHT ] = { xi.day.LIGHTSDAY, { xi.weather.AURORAS, xi.weather.STELLAR_GLARE } },
[xi.element.DARK ] = { xi.day.DARKSDAY, { xi.weather.GLOOM, xi.weather.DARKNESS } },
}

local elementData =
{
[xi.magianElement.FIRE ] = { xi.element.FIRE },
[xi.magianElement.ICE ] = { xi.element.ICE },
[xi.magianElement.WIND ] = { xi.element.WIND },
[xi.magianElement.EARTH ] = { xi.element.EARTH },
[xi.magianElement.THUNDER ] = { xi.element.THUNDER },
[xi.magianElement.WATER ] = { xi.element.WATER },
[xi.magianElement.LIGHT ] = { xi.element.LIGHT },
[xi.magianElement.DARK ] = { xi.element.DARK },
[xi.magianElement.ANY_LIGHT] =
{
xi.element.FIRE,
xi.element.WIND,
xi.element.THUNDER,
xi.element.LIGHT,
},

[xi.magianElement.ANY_DARK] =
{
xi.element.ICE,
xi.element.EARTH,
xi.element.WATER,
xi.element.DARK,
},

[xi.magianElement.ANY] =
{
xi.element.FIRE,
xi.element.ICE,
xi.element.WIND,
xi.element.EARTH,
xi.element.THUNDER,
xi.element.WATER,
xi.element.LIGHT,
xi.element.DARK,
},
}

local trialConditions =
{
-- NOTE: This condition is a bit of an outlier, as it is both a condition and
-- can have a higher reward value as opposed to a credit of 1. Light and Dark are special exceptions
-- that should be handled in magian trial data, if it is the case where multiple elements are allowed.
['dayWeather'] = function(trialData, player, mob, paramTable)
if trialData.dayWeather then
local dayWeatherResult = 0
local dayWeatherTable = elementData[trialData.dayWeather]

local currentWeather = player:getWeather(true)
for _, elementId in ipairs(dayWeatherTable) do
if dayWeatherElement[elementId][1] == VanadielDayOfTheWeek() then
dayWeatherResult = dayWeatherResult + 1
end

for _, weatherType in ipairs(dayWeatherElement[elementId][2]) do
if weatherType == currentWeather then
dayWeatherResult = dayWeatherResult and dayWeatherResult + 5
break
end
end
end

return dayWeatherResult > 0 and dayWeatherResult or false
end

return true
end,

['minDamage'] = function(trialData, player, mob, paramTable)
return not trialData.minDamage or paramTable.weaponskillDamage >= trialData.minDamage
end,
Expand All @@ -782,6 +867,10 @@ local trialConditions =
return not trialData.mobFamily or trialData.mobFamily[mob:getFamily()]
end,

['mobSuperFamily'] = function(trialData, player, mob, paramTable)
return not trialData.mobSuperFamily or trialData.mobSuperFamily[mob:getSuperFamily()]
end,

['useWeaponskill'] = function(trialData, player, mob, paramTable)
local weaponskillTable = type(trialData.useWeaponskill) == 'table' and trialData.useWeaponskill or set{ trialData.useWeaponskill }

Expand All @@ -794,13 +883,19 @@ local trialConditions =
}

local function checkConditions(trialData, player, mob, paramTable)
local creditReward = 1

for conditionName, conditionFunc in pairs(trialConditions) do
if not conditionFunc(trialData, player, mob, paramTable) then
local conditionResult = conditionFunc(trialData, player, mob, paramTable)

if not conditionResult then
return false
elseif type(conditionResult) == 'number' then
creditReward = conditionResult
end
end

return true
return creditReward
end

-----------------------------------
Expand Down Expand Up @@ -829,7 +924,6 @@ xi.magian.onItemEquip = function(player, itemObj)
-- require the player to both be alive and the mob be experience-granting (NMs are handled separately)

-- TODO:
-- Weather Type / Day (Weather = 5, Day = 1, Additive) Special exception for Light/Dark
-- Elemental Damage (Anyone counts!)
-- Pet kill
-- Avatar Kill (Summon must be out, but another of the same type can cause credit)
Expand All @@ -839,17 +933,21 @@ xi.magian.onItemEquip = function(player, itemObj)
if trialData.defeatMob then
player:addListener('DEFEATED_MOB', 'TRIAL_' .. itemTrialId, function(mobObj, playerObj, optParams)
if not playerObj:isDead() and playerObj:checkKillCredit(mobObj) then
if checkConditions(trialData, playerObj, mobObj, optParams) then
progressPlayerTrial(playerObj, itemTrialId, 1)
local conditionResult = checkConditions(trialData, playerObj, mobObj, optParams)

if conditionResult then
progressPlayerTrial(playerObj, itemTrialId, conditionResult)
end
end
end)

elseif trialData.useWeaponskill then
player:addListener('WEAPONSKILL_USE', 'TRIAL_' .. itemTrialId, function(playerObj, mobObj, weaponskillId, tpSpent, action, damage)
if not playerObj:isDead() and playerObj:checkKillCredit(mobObj) then
if checkConditions(trialData, playerObj, mobObj, { weaponskillUsed = weaponskillId, weaponskillDamage = damage }) then
progressPlayerTrial(playerObj, itemTrialId, 1)
local conditionResult = checkConditions(trialData, playerObj, mobObj, { weaponskillUsed = weaponskillId, weaponskillDamage = damage })

if conditionResult then
progressPlayerTrial(playerObj, itemTrialId, conditionResult)
end
end
end)
Expand Down
20 changes: 20 additions & 0 deletions scripts/globals/magian_data.lua
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,26 @@ xi.magian.trials =
},
},

[82] =
{
previousTrial = 0,
requiredItem =
{
itemId = xi.item.PUGILISTS,
},

textOffset = 99,
dayWeather = xi.magianElement.ANY,
defeatMob = true,
mobSuperFamily = set{ 56 },
numRequired = 50,

rewardItem =
{
itemId = xi.item.CATS_CLAWS,
},
},

[150] = -- Serpopard Ishtar x3
{
previousTrial = 0,
Expand Down
5 changes: 3 additions & 2 deletions src/map/lua/lua_baseentity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2204,13 +2204,14 @@ void CLuaBaseEntity::updateNPCHideTime(sol::object const& seconds)
* Example : if player:getWeather() == xi.weather.WIND then
************************************************************************/

uint8 CLuaBaseEntity::getWeather()
uint8 CLuaBaseEntity::getWeather(sol::object const& ignoreScholar)
{
WEATHER weather = WEATHER_NONE;

if (m_PBaseEntity->objtype & TYPE_PC || m_PBaseEntity->objtype & TYPE_MOB)
{
weather = battleutils::GetWeather(static_cast<CBattleEntity*>(m_PBaseEntity), false);
bool ignoreScholarWeather = ignoreScholar.is<bool>() ? ignoreScholar.as<bool>() : false;
weather = battleutils::GetWeather(static_cast<CBattleEntity*>(m_PBaseEntity), ignoreScholarWeather);
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/map/lua/lua_baseentity.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class CLuaBaseEntity
void hideNPC(sol::object const& seconds); // hide an NPC
void updateNPCHideTime(sol::object const& seconds); // Updates the length of time a NPC remains hidden, if shorter than the original hide time.

uint8 getWeather();
uint8 getWeather(sol::object const& ignoreScholar);
void setWeather(uint8 weatherType); // Set Weather condition (GM COMMAND)

// PC Instructions
Expand Down
4 changes: 0 additions & 4 deletions tools/ci/lua.sh
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,6 @@ global_objects=(
TPMOD_ATTACK
TPMOD_DURATION
INT_BASED
CHR_BASED
MND_BASED
ForceCrash
BuildString
Expand Down

0 comments on commit 9d62a75

Please sign in to comment.