HeroistВообще, там своеобразная логика есть. Например, сначала идут основные скиллы. Потом 1-уровень перки, затем расовые, затем остальные уровни-перки.
Что интересно, расовые перки идут практически всегда в таком же порядке, что и в skeelwheele, но против часовой стрелки. Только в конце может немного перепутаться. (Я только так и пытался оренинтироваться).
Единственная сильная ошибка, допущенная при создании id, так это, на мой взгляд, глупое распределение на "расовые перки". ИМХО - бред. Намного удобней было-бы просто писать перк, в скобках указывая, кто его может получить (ведь может быть несколько). Я мозг взорвал, решив, что это - 99. Но увы =)
Кто мешает создать собственный "класс", который будет работать с перками так, как тебе удобнее (в котором будут функции, определяющие, кому перк может принадлежать)? Порядок обхода ID не имеет никакого значения, если использовать именнованные константы вроде WIZARD_FEAT_SUPRESS_DARK вместо "магических" цифр (99). Просто вместо циклов for через копипаст работаешь с перками вручную, указывая для каждого ID информацию о том, кому он может принадлежать. Плюс там же (в этом "классе") можно переопределить любые названия ID, например написав SUPRESS_DARK = WIZARD_FEAT_SUPRESS_DARK. И, подключив файл, содержащий этот "класс" через doFile, можно обращаться к перку как к SUPRESS_DARK.
Пример из области городских построек (функция push определена в другом подключаемом "классе" - она добавляет элемент в конец списка, константы YES и NO также определены в другом "классе"):
-- Коэффициент перевода ID здания в его внутренний код
BUILDING_ID_TO_CODE_COEF = 10
BUILDING_LEVEL_1 = 1
BUILDING_LEVEL_2 = 2
BUILDING_LEVEL_3 = 3
BUILDING_LEVEL_4 = 4
BUILDING_LEVEL_5 = 5
-- Получить код здания по его ID и уровню
function getBuildingCode(buildingID, buildingLevel)
local buildingCode = BUILDING_ID_TO_CODE_COEF * buildingID + buildingLevel
return buildingCode
end
-- Получить ID здания по его коду
function getBuildingID(buildingCode)
local buildingID = intg(buildingCode / BUILDING_ID_TO_CODE_COEF)
return buildingID
end
-- Получить уровень здание по его коду
function getBuildingLevel(buildingCode)
local buildingLevel = mod(buildingCode, BUILDING_ID_TO_CODE_COEF)
return buildingLevel
end
-- Коды базовых общих зданий
TOWN_HALL_1 = getBuildingCode(TOWN_BUILDING_TOWN_HALL, BUILDING_LEVEL_1)
FORT_1 = getBuildingCode(TOWN_BUILDING_FORT, BUILDING_LEVEL_1)
MARKETPLACE_1 = getBuildingCode(TOWN_BUILDING_MARKETPLACE, BUILDING_LEVEL_1)
SHIPYARD_1 = getBuildingCode(TOWN_BUILDING_SHIPYARD, BUILDING_LEVEL_1)
TAVERN_1 = getBuildingCode(TOWN_BUILDING_TAVERN, BUILDING_LEVEL_1)
BLACKSMITH_1 = getBuildingCode(TOWN_BUILDING_BLACKSMITH, BUILDING_LEVEL_1)
MAGIC_GUILD_1 = getBuildingCode(TOWN_BUILDING_MAGIC_GUILD, BUILDING_LEVEL_1)
DWELLING_1_1 = getBuildingCode(TOWN_BUILDING_DWELLING_1, BUILDING_LEVEL_1)
DWELLING_2_1 = getBuildingCode(TOWN_BUILDING_DWELLING_2, BUILDING_LEVEL_1)
DWELLING_3_1 = getBuildingCode(TOWN_BUILDING_DWELLING_3, BUILDING_LEVEL_1)
DWELLING_4_1 = getBuildingCode(TOWN_BUILDING_DWELLING_4, BUILDING_LEVEL_1)
DWELLING_5_1 = getBuildingCode(TOWN_BUILDING_DWELLING_5, BUILDING_LEVEL_1)
DWELLING_6_1 = getBuildingCode(TOWN_BUILDING_DWELLING_6, BUILDING_LEVEL_1)
DWELLING_7_1 = getBuildingCode(TOWN_BUILDING_DWELLING_7, BUILDING_LEVEL_1)
GRAIL_1 = getBuildingCode(TOWN_BUILDING_GRAIL, BUILDING_LEVEL_1)
-- Коды улучшенных общих зданий
TOWN_HALL_2 = getBuildingCode(TOWN_BUILDING_TOWN_HALL, BUILDING_LEVEL_2)
TOWN_HALL_3 = getBuildingCode(TOWN_BUILDING_TOWN_HALL, BUILDING_LEVEL_3)
TOWN_HALL_4 = getBuildingCode(TOWN_BUILDING_TOWN_HALL, BUILDING_LEVEL_4)
FORT_2 = getBuildingCode(TOWN_BUILDING_FORT, BUILDING_LEVEL_2)
FORT_3 = getBuildingCode(TOWN_BUILDING_FORT, BUILDING_LEVEL_3)
MARKETPLACE_2 = getBuildingCode(TOWN_BUILDING_MARKETPLACE, BUILDING_LEVEL_2)
MAGIC_GUILD_2 = getBuildingCode(TOWN_BUILDING_MAGIC_GUILD, BUILDING_LEVEL_2)
MAGIC_GUILD_3 = getBuildingCode(TOWN_BUILDING_MAGIC_GUILD, BUILDING_LEVEL_3)
MAGIC_GUILD_4 = getBuildingCode(TOWN_BUILDING_MAGIC_GUILD, BUILDING_LEVEL_4)
MAGIC_GUILD_5 = getBuildingCode(TOWN_BUILDING_MAGIC_GUILD, BUILDING_LEVEL_5)
DWELLING_1_2 = getBuildingCode(TOWN_BUILDING_DWELLING_1, BUILDING_LEVEL_2)
DWELLING_2_2 = getBuildingCode(TOWN_BUILDING_DWELLING_2, BUILDING_LEVEL_2)
DWELLING_3_2 = getBuildingCode(TOWN_BUILDING_DWELLING_3, BUILDING_LEVEL_2)
DWELLING_4_2 = getBuildingCode(TOWN_BUILDING_DWELLING_4, BUILDING_LEVEL_2)
DWELLING_5_2 = getBuildingCode(TOWN_BUILDING_DWELLING_5, BUILDING_LEVEL_2)
DWELLING_6_2 = getBuildingCode(TOWN_BUILDING_DWELLING_6, BUILDING_LEVEL_2)
DWELLING_7_2 = getBuildingCode(TOWN_BUILDING_DWELLING_7, BUILDING_LEVEL_2)
-- Коды базовых расовых зданий
CASTLE_TRAINING_GROUNDS_1 = getBuildingCode(TOWN_BUILDING_HAVEN_TRAINING_GROUNDS, BUILDING_LEVEL_1)
CASTLE_MONUMENT_TO_FALLEN_HEROES_1 = getBuildingCode(TOWN_BUILDING_HAVEN_MONUMENT_TO_FALLEN_HEROES, BUILDING_LEVEL_1)
CASTLE_STABLE_1 = getBuildingCode(TOWN_BUILDING_HAVEN_STABLE, BUILDING_LEVEL_1)
CASTLE_FARMS_1 = getBuildingCode(TOWN_BUILDING_HAVEN_FARMS, BUILDING_LEVEL_1)
INFERNO_INFERNAL_LOOM_1 = getBuildingCode(TOWN_BUILDING_INFERNO_INFERNAL_LOOM, BUILDING_LEVEL_1)
INFERNO_ORDER_OF_FIRE_1 = getBuildingCode(TOWN_BUILDING_INFERNO_ORDER_OF_FIRE, BUILDING_LEVEL_1)
INFERNO_HALLS_OF_HORROR_1 = getBuildingCode(TOWN_BUILDING_INFERNO_HALLS_OF_HORROR, BUILDING_LEVEL_1)
INFERNO_SACRIFICIAL_PIT_1 = getBuildingCode(TOWN_BUILDING_INFERNO_SACRIFICIAL_PIT, BUILDING_LEVEL_1)
DUNGEON_ALTAR_OF_ELEMENTS_1 = getBuildingCode(TOWN_BUILDING_DUNGEON_ALTAR_OF_ELEMENTS, BUILDING_LEVEL_1)
DUNGEON_RITUAL_PIT_1 = getBuildingCode(TOWN_BUILDING_DUNGEON_RITUAL_PIT, BUILDING_LEVEL_1)
DUNGEON_TRADE_GUILD_1 = getBuildingCode(TOWN_BUILDING_DUNGEON_TRADE_GUILD, BUILDING_LEVEL_1)
DUNGEON_HALL_OF_INTRIGUE_1 = getBuildingCode(TOWN_BUILDING_DUNGEON_HALL_OF_INTRIGUE, BUILDING_LEVEL_1)
ACADEMY_LIBRARY_1 = getBuildingCode(TOWN_BUILDING_ACADEMY_LIBRARY, BUILDING_LEVEL_1)
ACADEMY_ARCANE_FORGE_1 = getBuildingCode(TOWN_BUILDING_ACADEMY_ARCANE_FORGE, BUILDING_LEVEL_1)
ACADEMY_ARTIFACT_MERCHANT_1 = getBuildingCode(TOWN_BUILDING_ACADEMY_ARTIFACT_MERCHANT, BUILDING_LEVEL_1)
ACADEMY_TREASURE_CAVE_1 = getBuildingCode(TOWN_BUILDING_ACADEMY_TREASURE_CAVE, BUILDING_LEVEL_1)
RAMPART_AVENGERS_BROTHERHOOD_1 = getBuildingCode(TOWN_BUILDING_PRESERVE_AVENGERS_BROTHERHOOD, BUILDING_LEVEL_1)
RAMPART_MYSTIC_POND_1 = getBuildingCode(TOWN_BUILDING_PRESERVE_MYSTIC_POND, BUILDING_LEVEL_1)
RAMPART_BLOOMING_GROVE_1 = getBuildingCode(TOWN_BUILDING_PRESERVE_BLOOMING_GROVE, BUILDING_LEVEL_1)
RAMPART_TREANT_SAMPLING_1 = getBuildingCode(TOWN_BUILDING_PRESERVE_TREANT_SAMPLING, BUILDING_LEVEL_1)
NECROPOLIS_AMPLIFIER_1 = getBuildingCode(TOWN_BUILDING_NECROMANCY_AMPLIFIER, BUILDING_LEVEL_1)
NECROPOLIS_UNHOLY_TEMPLE_1 = getBuildingCode(TOWN_BUILDING_NECROMANCY_UNHOLY_TEMPLE, BUILDING_LEVEL_1)
NECROPOLIS_UNEARHED_GRAVES_1 = getBuildingCode(TOWN_BUILDING_NECROMANCY_UNEARHED_GRAVES, BUILDING_LEVEL_1)
NECROPOLIS_DRAGON_TOMBSTONE_1 = getBuildingCode(TOWN_BUILDING_NECROMANCY_DRAGON_TOMBSTONE, BUILDING_LEVEL_1)
FORTRESS_RUNIC_SHRINE_1 = getBuildingCode(TOWN_BUILDING_FORTRESS_RUNIC_SHRINE, BUILDING_LEVEL_1)
FORTRESS_ARENA_1 = getBuildingCode(TOWN_BUILDING_FORTRESS_ARENA, BUILDING_LEVEL_1)
FORTRESS_GUARDPOST_1 = getBuildingCode(TOWN_BUILDING_FORTRESS_GUARDPOST, BUILDING_LEVEL_1)
FORTRESS_RUNIC_STONEWORKS_1 = getBuildingCode(TOWN_BUILDING_FORTRESS_RUNIC_STONEWORKS, BUILDING_LEVEL_1)
FORTRESS_RUNIC_ACADEMY_1 = getBuildingCode(TOWN_BUILDING_FORTRESS_RUNIC_ACADEMY, BUILDING_LEVEL_1)
STRONGHOLD_HALL_OF_TRIAL_1 = getBuildingCode(TOWN_BUILDING_STRONGHOLD_HALL_OF_TRIAL, BUILDING_LEVEL_1)
STRONGHOLD_GARBAGE_PILE_1 = getBuildingCode(TOWN_BUILDING_STRONGHOLD_GARBAGE_PILE, BUILDING_LEVEL_1)
STRONGHOLD_TRAVELLERS_SHELTER_1 = getBuildingCode(TOWN_BUILDING_STRONGHOLD_TRAVELLERS_SHELTER, BUILDING_LEVEL_1)
STRONGHOLD_PILE_OF_OUR_FOES_1 = getBuildingCode(TOWN_BUILDING_STRONGHOLD_PILE_OF_OUR_FOES, BUILDING_LEVEL_1)
STRONGHOLD_SLAVE_MARKET_1 = getBuildingCode(TOWN_BUILDING_STRONGHOLD_SLAVE_MARKET, BUILDING_LEVEL_1)
-- Коды улучшенных расовых зданий
DUNGEON_ALTAR_OF_ELEMENTS_2 = getBuildingCode(TOWN_BUILDING_DUNGEON_ALTAR_OF_ELEMENTS, BUILDING_LEVEL_2)
RAMPART_AVENGERS_BROTHERHOOD_2 = getBuildingCode(TOWN_BUILDING_PRESERVE_AVENGERS_BROTHERHOOD, BUILDING_LEVEL_2)
RAMPART_MYSTIC_POND_2 = getBuildingCode(TOWN_BUILDING_PRESERVE_MYSTIC_POND, BUILDING_LEVEL_2)
FORTRESS_RUNIC_SHRINE_2 = getBuildingCode(TOWN_BUILDING_FORTRESS_RUNIC_SHRINE, BUILDING_LEVEL_2)
FORTRESS_RUNIC_SHRINE_3 = getBuildingCode(TOWN_BUILDING_FORTRESS_RUNIC_SHRINE, BUILDING_LEVEL_3)
STRONGHOLD_HALL_OF_TRIAL_2 = getBuildingCode(TOWN_BUILDING_STRONGHOLD_HALL_OF_TRIAL, BUILDING_LEVEL_2)
STRONGHOLD_HALL_OF_TRIAL_3 = getBuildingCode(TOWN_BUILDING_STRONGHOLD_HALL_OF_TRIAL, BUILDING_LEVEL_3)
-- Добавление всех уровней указанного здания в список
function addAllBuildingLevels(townType, codeBuildingList, buildingID)
push(codeBuildingList, getBuildingCode(buildingID, BUILDING_LEVEL_1))
if (buildingID == TOWN_BUILDING_TOWN_HALL) then
push(codeBuildingList, TOWN_HALL_2)
push(codeBuildingList, TOWN_HALL_3)
push(codeBuildingList, TOWN_HALL_4)
elseif (buildingID == TOWN_BUILDING_FORT) then
push(codeBuildingList, FORT_2)
push(codeBuildingList, FORT_3)
elseif (buildingID == TOWN_BUILDING_MARKETPLACE) then
push(codeBuildingList, MARKETPLACE_2)
elseif (buildingID == TOWN_BUILDING_MAGIC_GUILD) then
push(codeBuildingList, MAGIC_GUILD_2)
push(codeBuildingList, MAGIC_GUILD_3)
push(codeBuildingList, MAGIC_GUILD_4)
push(codeBuildingList, MAGIC_GUILD_5)
elseif (buildingID == TOWN_BUILDING_DWELLING_1) then
push(codeBuildingList, DWELLING_1_2)
elseif (buildingID == TOWN_BUILDING_DWELLING_2) then
push(codeBuildingList, DWELLING_2_2)
elseif (buildingID == TOWN_BUILDING_DWELLING_3) then
push(codeBuildingList, DWELLING_3_2)
elseif (buildingID == TOWN_BUILDING_DWELLING_4) then
push(codeBuildingList, DWELLING_4_2)
elseif (buildingID == TOWN_BUILDING_DWELLING_5) then
push(codeBuildingList, DWELLING_5_2)
elseif (buildingID == TOWN_BUILDING_DWELLING_6) then
push(codeBuildingList, DWELLING_6_2)
elseif (buildingID == TOWN_BUILDING_DWELLING_7) then
push(codeBuildingList, DWELLING_7_2)
elseif (buildingID == TOWN_BUILDING_DUNGEON_ALTAR_OF_ELEMENTS)
and (townType == TOWN_DUNGEON)
then
push(codeBuildingList, DUNGEON_ALTAR_OF_ELEMENTS_2)
elseif (buildingID == TOWN_BUILDING_PRESERVE_AVENGERS_BROTHERHOOD)
and (townType == TOWN_PRESERVE)
then
push(codeBuildingList, RAMPART_AVENGERS_BROTHERHOOD_2)
elseif (buildingID == TOWN_BUILDING_PRESERVE_MYSTIC_POND)
and (townType == TOWN_PRESERVE)
then
push(codeBuildingList, RAMPART_MYSTIC_POND_2)
elseif (buildingID == TOWN_BUILDING_FORTRESS_RUNIC_SHRINE)
and (townType == TOWN_FORTRESS)
then
push(codeBuildingList, FORTRESS_RUNIC_SHRINE_2)
push(codeBuildingList, FORTRESS_RUNIC_SHRINE_3)
elseif (buildingID == TOWN_BUILDING_STRONGHOLD_HALL_OF_TRIAL)
and (townType == TOWN_STRONGHOLD)
then
push(codeBuildingList, STRONGHOLD_HALL_OF_TRIAL_2)
push(codeBuildingList, STRONGHOLD_HALL_OF_TRIAL_3)
end
end
-- Получение списка кодов зданий по типу города и списку их ID
function getBuildingCodeList(townType, townBuildingList)
local codeBuildingList = {}
for i, buildingID in townBuildingList do
addAllBuildingLevels(townType, codeBuildingList, buildingID)
end
return codeBuildingList
end
-- Проверка, построено ли в городе указанное здание
function hasTownThisBuildingCode(town, buildingCode)
local hasBuildingCode = NO
local buildingID = getBuildingID(buildingCode)
local targetLevel = getBuildingLevel(buildingCode)
if (GetTownBuildingLevel(town, buildingID) >= targetLevel) then
hasBuildingCode = YES
end
return hasBuildingCode
end
-- Получение списка построенных зданий в городе
function getTownBuildingCodeList(town)
local currentTownBuildingCodeList = {}
local townType = GetTownRace(town)
local townBuildingList = getTownTypeBuildingList(townType)
local fullTownBuildingCodeList = getBuildingCodeList(townType, townBuildingList)
for i, buildingCode in fullTownBuildingCodeList do
if (hasTownThisBuildingCode(town, buildingCode) == YES) then
push(currentTownBuildingCodeList, buildingCode)
end
end
return currentTownBuildingCodeList
end