mirror of
https://github.com/OTCv8/otclientv8.git
synced 2025-05-06 05:49:20 +02:00
889 lines
22 KiB
Lua
889 lines
22 KiB
Lua
-- Author: Vithrax
|
|
-- contains mostly basic function shortcuts and code shorteners
|
|
|
|
|
|
-- burst damage calculation, for function burstDamageValue()
|
|
local dmgTable = {}
|
|
local lastDmgMessage = now
|
|
onTextMessage(function(mode, text)
|
|
if not text:lower():find("you lose") or not text:lower():find("due to") then return end
|
|
local dmg = string.match(text, "%d+")
|
|
if #dmgTable > 0 then
|
|
for k, v in ipairs(dmgTable) do
|
|
if now - v.t > 3000 then
|
|
table.remove(dmgTable, k)
|
|
end
|
|
end
|
|
end
|
|
lastDmgMessage = now
|
|
table.insert(dmgTable, {d = dmg, t = now})
|
|
schedule(3050, function()
|
|
if now - lastDmgMessage > 3000 then
|
|
dmgTable = {} end
|
|
end)
|
|
end)
|
|
|
|
function whiteInfoMessage(text)
|
|
return modules.game_textmessage.displayGameMessage(text)
|
|
end
|
|
|
|
function burstDamageValue()
|
|
local d = 0
|
|
local time = 0
|
|
if #dmgTable > 1 then
|
|
for i, v in ipairs(dmgTable) do
|
|
if i == 1 then
|
|
time = v.t
|
|
end
|
|
d = d + v.d
|
|
end
|
|
end
|
|
return math.ceil(d/((now-time)/1000))
|
|
end
|
|
|
|
|
|
function scheduleNpcSay(text, delay)
|
|
if not text or not delay then return false end
|
|
|
|
return schedule(delay, function() NPC.say(text) end)
|
|
end
|
|
|
|
function getFirstNumberInText(text)
|
|
local n = 0
|
|
if string.match(text, "%d+") then
|
|
n = tonumber(string.match(text, "%d+"))
|
|
end
|
|
return n
|
|
end
|
|
|
|
function isOnTile(id, p1, p2, p3)
|
|
if not id then return end
|
|
local tile
|
|
if type(p1) == "table" then
|
|
tile = g_map.getTile(p1)
|
|
elseif type(p1) ~= "number" then
|
|
tile = p1
|
|
else
|
|
local p = getPos(p1, p2, p3)
|
|
tile = g_map.getTile(p)
|
|
end
|
|
if not tile then return end
|
|
|
|
local item = false
|
|
if #tile:getItems() ~= 0 then
|
|
for i,v in ipairs(tile:getItems()) do
|
|
if v:getId() == id then
|
|
item = true
|
|
end
|
|
end
|
|
else
|
|
return false
|
|
end
|
|
|
|
return item
|
|
end
|
|
|
|
function getPos(x,y,z)
|
|
if not x or not y or not z then return nil end
|
|
local pos = pos()
|
|
pos.x = x
|
|
pos.y = y
|
|
pos.z = z
|
|
|
|
return pos
|
|
end
|
|
|
|
function openPurse()
|
|
return g_game.use(g_game.getLocalPlayer():getInventoryItem(InventorySlotPurse))
|
|
end
|
|
|
|
function containerIsFull(c)
|
|
if not c then return false end
|
|
|
|
if c:getCapacity() > #c:getItems() then
|
|
return false
|
|
else
|
|
return true
|
|
end
|
|
|
|
end
|
|
|
|
function isBuffed()
|
|
local var = false
|
|
for i=1,4 do
|
|
local premium = (player:getSkillLevel(i) - player:getSkillBaseLevel(i))
|
|
local base = player:getSkillBaseLevel(i)
|
|
if hasPartyBuff() and (premium/100)*305 > base then
|
|
var = true
|
|
end
|
|
end
|
|
return var
|
|
end
|
|
|
|
function reindexTable(t)
|
|
if not t or type(t) ~= "table" then return end
|
|
|
|
local i = 0
|
|
for _, e in pairs(t) do
|
|
i = i + 1
|
|
e.index = i
|
|
end
|
|
end
|
|
|
|
function killsToRs()
|
|
return math.min(g_game.getUnjustifiedPoints().killsDayRemaining, g_game.getUnjustifiedPoints().killsWeekRemaining, g_game.getUnjustifiedPoints().killsMonthRemaining)
|
|
end
|
|
|
|
-- [[ experimental healing cooldown calculation ]] --
|
|
storage.isUsingPotion = false
|
|
onTalk(function(name, level, mode, text, channelId, pos)
|
|
if name ~= player:getName() then return end
|
|
if mode ~= 34 then return end
|
|
|
|
if text == "Aaaah..." then
|
|
storage.isUsingPotion = true
|
|
schedule(950, function()
|
|
storage.isUsingPotion = false
|
|
end)
|
|
end
|
|
end)
|
|
|
|
-- [[ eof ]] --
|
|
|
|
-- [[ canCast and cast functions ]] --
|
|
SpellCastTable = {}
|
|
onTalk(function(name, level, mode, text, channelId, pos)
|
|
if name ~= player:getName() then return end
|
|
|
|
if SpellCastTable[text] then
|
|
SpellCastTable[text].t = now
|
|
end
|
|
end)
|
|
|
|
function cast(text, delay)
|
|
if type(text) ~= "string" then return end
|
|
if not delay or delay < 100 then
|
|
return say(text) -- if not added delay or delay is really low then just treat it like casual say
|
|
end
|
|
if not SpellCastTable[text] or SpellCastTable[text].d ~= delay then
|
|
SpellCastTable[text] = {t=now-delay,d=delay}
|
|
return say(text)
|
|
end
|
|
local lastCast = SpellCastTable[text].t
|
|
local spellDelay = SpellCastTable[text].d
|
|
if now - lastCast > spellDelay then
|
|
return say(text)
|
|
end
|
|
return
|
|
end
|
|
local Spells = modules.gamelib.SpellInfo['Default']
|
|
function canCast(spell, ignoreRL, ignoreCd)
|
|
if type(spell) ~= "string" then return end
|
|
spell = spell:lower()
|
|
if not getSpellData(spell) then
|
|
if SpellCastTable[spell] then
|
|
if now - SpellCastTable[spell].t > SpellCastTable[spell].d then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
if (ignoreCd or not getSpellCoolDown(spell)) and (ignoreRL or level() >= getSpellData(spell).level and mana() >= getSpellData(spell).mana) then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
function getSpellData(spell)
|
|
if not spell then return false end
|
|
spell = spell:lower()
|
|
local t = nil
|
|
for k,v in pairs(Spells) do
|
|
if v.words == spell then
|
|
t = k
|
|
break
|
|
end
|
|
end
|
|
if t then
|
|
return Spells[t]
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
function getSpellCoolDown(text)
|
|
if not text then return false end
|
|
text = text:lower()
|
|
if not getSpellData(text) then return false end
|
|
for i,v in pairs(Spells) do
|
|
if v.words == text then
|
|
return modules.game_cooldown.isCooldownIconActive(v.id)
|
|
end
|
|
end
|
|
end
|
|
|
|
storage.isUsing = false
|
|
|
|
onUse(function(pos, itemId, stackPos, subType)
|
|
if pos.x < 65000 then
|
|
storage.isUsing = true
|
|
end
|
|
schedule(1500, function() if storage.isUsing then storage.isUsing = false end end)
|
|
end)
|
|
|
|
onUseWith(function(pos, itemId, target, subType)
|
|
if itemId ~= 3180 then return end
|
|
if pos.x < 65000 then
|
|
storage.isUsing = true
|
|
end
|
|
schedule(1500, function() if storage.isUsing then storage.isUsing = false end end)
|
|
end)
|
|
|
|
function string.starts(String,Start)
|
|
return string.sub(String,1,string.len(Start))==Start
|
|
end
|
|
|
|
local cachedFriends = {}
|
|
local cachedNeutrals = {}
|
|
local cachedEnemies = {}
|
|
function isFriend(c)
|
|
local name = c
|
|
if type(c) ~= "string" then
|
|
if c == player then return true end
|
|
name = c:getName()
|
|
if name == name() then return true end
|
|
end
|
|
|
|
if table.find(cachedFriends, c) then return true end
|
|
if table.find(cachedNeutrals, c) or table.find(cachedEnemies, c) then return false end
|
|
|
|
if table.find(storage.playerList.friendList, name) then
|
|
table.insert(cachedFriends, c)
|
|
return true
|
|
elseif string.find(storage.serverMembers, name) then
|
|
table.insert(cachedFriends, c)
|
|
return true
|
|
elseif storage.playerList.groupMembers then
|
|
local p = c
|
|
if type(c) == "string" then
|
|
p = getCreatureByName(c, true)
|
|
end
|
|
if p:isLocalPlayer() then return true end
|
|
if p:isPlayer() then
|
|
if ((p:getShield() >= 3 and p:getShield() <= 10) or p:getEmblem() == 2) then
|
|
table.insert(cachedFriends, c)
|
|
table.insert(cachedFriends, p)
|
|
return true
|
|
else
|
|
table.insert(cachedNeutrals, c)
|
|
table.insert(cachedNeutrals, p)
|
|
return false
|
|
end
|
|
end
|
|
else
|
|
table.insert(cachedNeutrals, c)
|
|
table.insert(cachedNeutrals, p)
|
|
return false
|
|
end
|
|
end
|
|
|
|
function isEnemy(name)
|
|
if not name then return false end
|
|
local p = getCreatureByName(name, true)
|
|
if p:isLocalPlayer() then return end
|
|
|
|
if p:isPlayer() and table.find(storage.playerList.enemyList, name) or (storage.playerList.marks and not isFriend(name)) then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
function isAttSpell(expr)
|
|
if string.starts(expr, "exori") or string.starts(expr, "exevo") then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
function getActiveItemId(id)
|
|
if not id then
|
|
return false
|
|
end
|
|
|
|
if id == 3049 then
|
|
return 3086
|
|
elseif id == 3050 then
|
|
return 3087
|
|
elseif id == 3051 then
|
|
return 3088
|
|
elseif id == 3052 then
|
|
return 3089
|
|
elseif id == 3053 then
|
|
return 3090
|
|
elseif id == 3091 then
|
|
return 3094
|
|
elseif id == 3092 then
|
|
return 3095
|
|
elseif id == 3093 then
|
|
return 3096
|
|
elseif id == 3097 then
|
|
return 3099
|
|
elseif id == 3098 then
|
|
return 3100
|
|
elseif id == 16114 then
|
|
return 16264
|
|
elseif id == 23531 then
|
|
return 23532
|
|
elseif id == 23533 then
|
|
return 23534
|
|
elseif id == 23529 then
|
|
return 23530
|
|
else
|
|
return id
|
|
end
|
|
end
|
|
|
|
function getInactiveItemId(id)
|
|
if not id then
|
|
return false
|
|
end
|
|
|
|
if id == 3086 then
|
|
return 3049
|
|
elseif id == 3087 then
|
|
return 3050
|
|
elseif id == 3088 then
|
|
return 3051
|
|
elseif id == 3089 then
|
|
return 3052
|
|
elseif id == 3090 then
|
|
return 3053
|
|
elseif id == 3094 then
|
|
return 3091
|
|
elseif id == 3095 then
|
|
return 3092
|
|
elseif id == 3096 then
|
|
return 3093
|
|
elseif id == 3099 then
|
|
return 3097
|
|
elseif id == 3100 then
|
|
return 3098
|
|
elseif id == 16264 then
|
|
return 16114
|
|
elseif id == 23532 then
|
|
return 23531
|
|
elseif id == 23534 then
|
|
return 23533
|
|
elseif id == 23530 then
|
|
return 23529
|
|
else
|
|
return id
|
|
end
|
|
end
|
|
|
|
function getMonstersInRange(pos, range)
|
|
if not pos or not range then
|
|
return false
|
|
end
|
|
local monsters = 0
|
|
for i, spec in pairs(getSpectators()) do
|
|
if spec:isMonster() and (g_game.getClientVersion() < 960 or spec:getType() < 3) and getDistanceBetween(pos, spec:getPosition()) < range then
|
|
monsters = monsters + 1
|
|
end
|
|
end
|
|
return monsters
|
|
end
|
|
|
|
function distanceFromPlayer(coords)
|
|
if not coords then
|
|
return false
|
|
end
|
|
return getDistanceBetween(pos(), coords)
|
|
end
|
|
|
|
function getMonsters(range, multifloor)
|
|
if not range then
|
|
range = 10
|
|
end
|
|
local mobs = 0;
|
|
for _, spec in pairs(getSpectators(multifloor)) do
|
|
mobs = (g_game.getClientVersion() < 960 or spec:getType() < 3) and spec:isMonster() and distanceFromPlayer(spec:getPosition()) <= range and mobs + 1 or mobs;
|
|
end
|
|
return mobs;
|
|
end
|
|
|
|
function getPlayers(range, multifloor)
|
|
if not range then
|
|
range = 10
|
|
end
|
|
local specs = 0;
|
|
for _, spec in pairs(getSpectators(multifloor)) do
|
|
specs = not spec:isLocalPlayer() and spec:isPlayer() and distanceFromPlayer(spec:getPosition()) <= range and not ((spec:getShield() >= 3 and spec:getShield() <= 10) or spec:getEmblem() == 1) and specs + 1 or specs;
|
|
end
|
|
return specs;
|
|
end
|
|
|
|
function isBlackListedPlayerInRange(range)
|
|
if #storage.playerList.blackList == 0 then return end
|
|
if not range then range = 10 end
|
|
local safe = false
|
|
for _, spec in pairs(getSpectators()) do
|
|
if spec:isPlayer() and distanceFromPlayer(spec:getPosition()) < range then
|
|
if table.find(storage.playerList.blackList, spec:getName()) then
|
|
safe = true
|
|
end
|
|
end
|
|
end
|
|
|
|
return safe
|
|
end
|
|
|
|
function isSafe(range, multifloor, padding)
|
|
local onSame = 0
|
|
local onAnother = 0
|
|
if not multifloor and padding then
|
|
multifloor = false
|
|
padding = false
|
|
end
|
|
|
|
for _, spec in pairs(getSpectators(multifloor)) do
|
|
if spec:isPlayer() and not spec:isLocalPlayer() and not isFriend(spec:getName()) then
|
|
if spec:getPosition().z == posz() and distanceFromPlayer(spec:getPosition()) <= range then
|
|
onSame = onSame + 1
|
|
end
|
|
if multifloor and padding and spec:getPosition().z ~= posz() and distanceFromPlayer(spec:getPosition()) <= (range + padding) then
|
|
onAnother = onAnother + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
if onSame + onAnother > 0 then
|
|
return false
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
|
|
function getAllPlayers(range, multifloor)
|
|
if not range then
|
|
range = 10
|
|
end
|
|
local specs = 0;
|
|
for _, spec in pairs(getSpectators(multifloor)) do
|
|
specs = not spec:isLocalPlayer() and spec:isPlayer() and distanceFromPlayer(spec:getPosition()) <= range and specs + 1 or specs;
|
|
end
|
|
return specs;
|
|
end
|
|
|
|
function getNpcs(range, multifloor)
|
|
if not range then
|
|
range = 10
|
|
end
|
|
local npcs = 0;
|
|
for _, spec in pairs(getSpectators(multifloor)) do
|
|
npcs = spec:isNpc() and distanceFromPlayer(spec:getPosition()) <= range and npcs + 1 or npcs;
|
|
end
|
|
return npcs;
|
|
end
|
|
|
|
function itemAmount(id)
|
|
local totalItemCount = 0
|
|
for _, container in pairs(getContainers()) do
|
|
for _, item in ipairs(container:getItems()) do
|
|
totalItemCount = item:getId() == id and totalItemCount + item:getCount() or totalItemCount
|
|
end
|
|
end
|
|
if getHead() and getHead():getId() == id then
|
|
totalItemCount = totalItemCount + getHead():getCount()
|
|
end
|
|
if getNeck() and getNeck():getId() == id then
|
|
totalItemCount = totalItemCount + getNeck():getCount()
|
|
end
|
|
if getBack() and getBack():getId() == id then
|
|
totalItemCount = totalItemCount + getBack():getCount()
|
|
end
|
|
if getBody() and getBody():getId() == id then
|
|
totalItemCount = totalItemCount + getBody():getCount()
|
|
end
|
|
if getRight() and getRight():getId() == id then
|
|
totalItemCount = totalItemCount + getRight():getCount()
|
|
end
|
|
if getLeft() and getLeft():getId() == id then
|
|
totalItemCount = totalItemCount + getLeft():getCount()
|
|
end
|
|
if getLeg() and getLeg():getId() == id then
|
|
totalItemCount = totalItemCount + getLeg():getCount()
|
|
end
|
|
if getFeet() and getFeet():getId() == id then
|
|
totalItemCount = totalItemCount + getFeet():getCount()
|
|
end
|
|
if getFinger() and getFinger():getId() == id then
|
|
totalItemCount = totalItemCount + getFinger():getCount()
|
|
end
|
|
if getAmmo() and getAmmo():getId() == id then
|
|
totalItemCount = totalItemCount + getAmmo():getCount()
|
|
end
|
|
return totalItemCount
|
|
end
|
|
|
|
function hasSupplies()
|
|
local items = {
|
|
{ID = storage.supplies.item1, minAmount = storage.supplies.item1Min},
|
|
{ID = storage.supplies.item2, minAmount = storage.supplies.item2Min},
|
|
{ID = storage.supplies.item3, minAmount = storage.supplies.item3Min},
|
|
{ID = storage.supplies.item4, minAmount = storage.supplies.item4Min},
|
|
{ID = storage.supplies.item5, minAmount = storage.supplies.item5Min},
|
|
{ID = storage.supplies.item6, minAmount = storage.supplies.item6Min},
|
|
{ID = storage.supplies.item7, minAmount = storage.supplies.item7Min}
|
|
}
|
|
-- false = no supplies
|
|
-- true = supplies available
|
|
|
|
local hasSupplies = true
|
|
|
|
for i, supply in pairs(items) do
|
|
if supply.min and supply.ID then
|
|
if supply.ID > 100 and itemAmount(supply.ID) < supply.min then
|
|
hasSupplies = false
|
|
end
|
|
end
|
|
end
|
|
|
|
return hasSupplies
|
|
end
|
|
|
|
function cordsToPos(x, y, z)
|
|
if not x or not y or not z then
|
|
return false
|
|
end
|
|
local tilePos = pos()
|
|
tilePos.x = x
|
|
tilePos.y = y
|
|
tilePos.z = z
|
|
return tilePos
|
|
end
|
|
|
|
function reachGroundItem(id)
|
|
if not id then return nil end
|
|
local targetTile
|
|
for _, tile in ipairs(g_map.getTiles(posz())) do
|
|
if tile:getTopUseThing():getId() == id then
|
|
targetTile = tile:getPosition()
|
|
end
|
|
end
|
|
if targetTile then
|
|
CaveBot.walkTo(targetTile, 10, {ignoreNonPathable = true, precision=1})
|
|
delay(500*getDistanceBetween(targetTile, pos()))
|
|
return true
|
|
else
|
|
return nil
|
|
end
|
|
end
|
|
|
|
function useGroundItem(id)
|
|
if not id then
|
|
return nil
|
|
end
|
|
local targetTile = nil
|
|
for _, tile in ipairs(g_map.getTiles(posz())) do
|
|
if tile:getTopUseThing():getId() == id then
|
|
targetTile = tile:getPosition()
|
|
end
|
|
end
|
|
if targetTile then
|
|
g_game.use(g_map.getTile(targetTile):getTopUseThing())
|
|
delay(500*getDistanceBetween(targetTile, pos()))
|
|
else
|
|
return nil
|
|
end
|
|
end
|
|
|
|
function target()
|
|
if not g_game.isAttacking() then
|
|
return
|
|
else
|
|
return g_game.getAttackingCreature()
|
|
end
|
|
end
|
|
|
|
function getTarget()
|
|
return target()
|
|
end
|
|
|
|
function targetPos(dist)
|
|
if not g_game.isAttacking() then
|
|
return
|
|
end
|
|
if dist then
|
|
return distanceFromPlayer(target():getPosition())
|
|
else
|
|
return target():getPosition()
|
|
end
|
|
end
|
|
|
|
-- for gunzodus
|
|
function reopenPurse()
|
|
for i, c in pairs(getContainers()) do
|
|
if c:getName():lower() == "loot bag" or c:getName():lower() == "store inbox" then
|
|
g_game.close(c)
|
|
end
|
|
end
|
|
schedule(100, function() g_game.use(g_game.getLocalPlayer():getInventoryItem(InventorySlotPurse)) end)
|
|
schedule(1400, function()
|
|
for i, c in pairs(getContainers()) do
|
|
if c:getName():lower() == "store inbox" then
|
|
for _, i in pairs(c:getItems()) do
|
|
if i:getId() == 23721 then
|
|
g_game.open(i, c)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
return CaveBot.delay(1500)
|
|
end
|
|
|
|
-- getSpectator patterns
|
|
|
|
function getCreaturesInArea(param1, param2, param3)
|
|
-- param1 - pos/creature
|
|
-- param2 - pattern
|
|
-- param3 - type of return
|
|
-- 1 - everyone, 2 - monsters, 3 - players
|
|
local specs = 0
|
|
local monsters = 0
|
|
local players = 0
|
|
for i, spec in pairs(getSpectators(param1, param2)) do
|
|
if spec ~= player then
|
|
specs = specs + 1
|
|
if spec:isMonster() and (g_game.getClientVersion() < 960 or spec:getType() < 3) then
|
|
monsters = monsters + 1
|
|
elseif spec:isPlayer() and not isFriend(spec:getName()) then
|
|
players = players +1
|
|
end
|
|
end
|
|
end
|
|
|
|
if param3 == 1 then
|
|
return specs
|
|
elseif param3 == 2 then
|
|
return monsters
|
|
else
|
|
return players
|
|
end
|
|
end
|
|
|
|
function getBestTileByPatern(pattern, specType, maxDist, safe)
|
|
if not pattern or not specType then return end
|
|
if not maxDist then maxDist = 4 end
|
|
|
|
|
|
local bestTile = nil
|
|
local best = nil
|
|
-- best area tile to use
|
|
for _, tile in pairs(g_map.getTiles(posz())) do
|
|
if distanceFromPlayer(tile:getPosition()) <= maxDist then
|
|
local minimapColor = g_map.getMinimapColor(tile:getPosition())
|
|
local stairs = (minimapColor >= 210 and minimapColor <= 213)
|
|
if tile:canShoot() and tile:isWalkable() and not stairs then
|
|
if getCreaturesInArea(tile:getPosition(), pattern, specType) > 0 then
|
|
if (not safe or getCreaturesInArea(tile:getPosition(), pattern, 3) == 0) then
|
|
local candidate = {pos = tile, count = getCreaturesInArea(tile:getPosition(), pattern, specType)}
|
|
if not best or best.count <= candidate.count then
|
|
best = candidate
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
bestTile = best
|
|
|
|
if bestTile then
|
|
return bestTile
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
function getContainerByName(name)
|
|
if type(name) ~= "string" then return nil end
|
|
|
|
local d = nil
|
|
for i, c in pairs(getContainers()) do
|
|
if c:getName():lower() == name:lower() then
|
|
d = c
|
|
break
|
|
end
|
|
end
|
|
return d
|
|
end
|
|
|
|
function getContainerByItem(id)
|
|
if type(name) ~= "number" then return nil end
|
|
|
|
local d = nil
|
|
for i, c in pairs(getContainers()) do
|
|
if c:getContainerItem():getId() == id then
|
|
d = c
|
|
break
|
|
end
|
|
end
|
|
return d
|
|
end
|
|
|
|
LargeUeArea = [[
|
|
0000001000000
|
|
0000011100000
|
|
0000111110000
|
|
0001111111000
|
|
0011111111100
|
|
0111111111110
|
|
1111111111111
|
|
0111111111110
|
|
0011111111100
|
|
0001111111000
|
|
0000111110000
|
|
0000011100000
|
|
0000001000000
|
|
]]
|
|
|
|
NormalUeAreaMs = [[
|
|
00000100000
|
|
00011111000
|
|
00111111100
|
|
01111111110
|
|
01111111110
|
|
11111111111
|
|
01111111110
|
|
01111111110
|
|
00111111100
|
|
00001110000
|
|
00000100000
|
|
]]
|
|
|
|
NormalUeAreaEd = [[
|
|
00000100000
|
|
00001110000
|
|
00011111000
|
|
00111111100
|
|
01111111110
|
|
11111111111
|
|
01111111110
|
|
00111111100
|
|
00011111000
|
|
00001110000
|
|
00000100000
|
|
]]
|
|
|
|
smallUeArea = [[
|
|
0011100
|
|
0111110
|
|
1111111
|
|
1111111
|
|
1111111
|
|
0111110
|
|
0011100
|
|
]]
|
|
|
|
largeRuneArea = [[
|
|
0011100
|
|
0111110
|
|
1111111
|
|
1111111
|
|
1111111
|
|
0111110
|
|
0011100
|
|
]]
|
|
|
|
adjacentArea = [[
|
|
111
|
|
101
|
|
111
|
|
]]
|
|
|
|
longBeamArea = [[
|
|
0000000N0000000
|
|
0000000N0000000
|
|
0000000N0000000
|
|
0000000N0000000
|
|
0000000N0000000
|
|
0000000N0000000
|
|
0000000N0000000
|
|
WWWWWWW0EEEEEEE
|
|
0000000S0000000
|
|
0000000S0000000
|
|
0000000S0000000
|
|
0000000S0000000
|
|
0000000S0000000
|
|
0000000S0000000
|
|
0000000S0000000
|
|
]]
|
|
|
|
shortBeamArea = [[
|
|
00000100000
|
|
00000100000
|
|
00000100000
|
|
00000100000
|
|
00000100000
|
|
EEEEE0WWWWW
|
|
00000S00000
|
|
00000S00000
|
|
00000S00000
|
|
00000S00000
|
|
00000S00000
|
|
]]
|
|
|
|
newWaveArea = [[
|
|
000NNNNN000
|
|
000NNNNN000
|
|
0000NNN0000
|
|
WW00NNN00EE
|
|
WWWW0N0EEEE
|
|
WWWWW0EEEEE
|
|
WWWW0S0EEEE
|
|
WW00SSS00EE
|
|
0000SSS0000
|
|
000SSSSS000
|
|
000SSSSS000
|
|
]]
|
|
|
|
bigWaveArea = [[
|
|
0000NNN0000
|
|
0000NNN0000
|
|
0000NNN0000
|
|
00000N00000
|
|
WWW00N00EEE
|
|
WWWWW0EEEEE
|
|
WWW00S00EEE
|
|
00000S00000
|
|
0000SSS0000
|
|
0000SSS0000
|
|
0000SSS0000
|
|
]]
|
|
|
|
|
|
smallWaveArea = [[
|
|
00NNN00
|
|
00NNN00
|
|
WW0N0EE
|
|
WWW0EEE
|
|
WW0S0EE
|
|
00SSS00
|
|
00SSS00
|
|
]]
|
|
|
|
diamondArrowArea = [[
|
|
01110
|
|
11111
|
|
11111
|
|
11111
|
|
01110
|
|
]] |