landsandboat/scripts/tests/systems/elements.lua
2026-02-20 18:42:33 -07:00

119 lines
4.2 KiB
Lua

local crystalToElement =
{
[xi.item.FIRE_CRYSTAL] = xi.element.FIRE,
[xi.item.EARTH_CRYSTAL] = xi.element.EARTH,
[xi.item.WATER_CRYSTAL] = xi.element.WATER,
[xi.item.WIND_CRYSTAL] = xi.element.WIND,
[xi.item.ICE_CRYSTAL] = xi.element.ICE,
[xi.item.LIGHTNING_CRYSTAL] = xi.element.THUNDER,
[xi.item.LIGHT_CRYSTAL] = xi.element.LIGHT,
[xi.item.DARK_CRYSTAL] = xi.element.DARK,
}
describe('Crystals', function()
local player
before_each(function()
player = xi.test.world:spawnPlayer({ zone = xi.zone.EAST_SARUTABARUTA })
player:addStatusEffect(xi.effect.SIGNET, { origin = player })
end)
it('of matching element drop when monster killed', function()
local checkTable =
{
[xi.region.ELSHIMO_UPLANDS] =
{
[xi.zone.TEMPLE_OF_UGGALEPIH] =
{
['Iron_Maiden'] = xi.item.ICE_CRYSTAL,
['Tonberry_Cutter'] = xi.item.LIGHT_CRYSTAL,
},
},
[xi.region.SARUTABARUTA] =
{
[xi.zone.EAST_SARUTABARUTA] =
{
['Carrion_Crow'] = xi.item.FIRE_CRYSTAL,
['Mandragora'] = xi.item.EARTH_CRYSTAL,
['Yagudo_Acolyte'] = xi.item.WIND_CRYSTAL,
['Pug_Pugil'] = xi.item.WATER_CRYSTAL,
['Goblin_Fisher'] = xi.item.LIGHTNING_CRYSTAL,
['Mad_Fox'] = xi.item.DARK_CRYSTAL,
},
},
}
for region, zones in pairs(checkTable) do
-- Someone must control the region for crystals to drop.
xi.test.world:setRegionOwner(region, xi.nation.WINDURST)
for zone, mobs in pairs(zones) do
player:gotoZone(zone)
for mobName, crystal in pairs(mobs) do
local mob = player.entities:moveTo(mobName)
-- Ensure the mob has the correct element
assert(crystalToElement[crystal] == mob:getCrystalElement())
local gotCrystal = false
for _ = 1, 100 do
player:delContainerItems(xi.inv.INVENTORY)
player:setLevel(1)
-- Should have only one item in inventory
assert(1 == #player:getItems())
mob:spawn()
mob.assert:isAlive()
-- Need to be within range to count for crystal drops
player:setPos(mob:getXPos(), mob:getYPos(), mob:getZPos())
player:claimAndKillMob(mob, { waitForDespawn = true })
for _, item in ipairs(player:getItems()) do
if item:getID() == crystal then
gotCrystal = true
break
end
-- Mob dropped an unexpected crystal. Ignore other items
assert(crystalToElement[item:getID()] == nil)
end
if gotCrystal then
break
end
end
-- Did not get a crystal in 100 kills
assert(gotCrystal)
end
end
end
end)
end)
describe('Elementals', function()
local player
local thunderEle, earthEle
before_each(function()
player = xi.test.world:spawnPlayer({ zone = xi.zone.KONSCHTAT_HIGHLANDS })
thunderEle = player.entities:get('Thunder_Elemental')
earthEle = player.entities:get('Earth_Elemental')
end)
it('do not spawn with no matching weather', function()
player:setWeather(xi.weather.NONE)
-- Wait for despawn to process
local ticks = 0
while (thunderEle:isSpawned() or earthEle:isSpawned()) and ticks < 20 do
xi.test.world:skipTime(5)
xi.test.world:tick()
ticks = ticks + 1
end
thunderEle.assert.no:isAlive()
earthEle.assert.no:isAlive()
end)
end)