Ну тут сразу вопрос: на сколько это должно быть гибко и надо ли оно вообще (по мне так важнее возможность добавлять новые скилы, а для этого нужен скриптинг)? Вынести цифры в конфиг не проблема.
Половина скилов и так сделаны через бонусы, то есть теоретически можно перенести на них оставшиеся скилы и пробросить целиком в моддинг.
Но тут еще остаются всякие особые случаи. Мудрость/школы магии которые выдаются на определенных уровнях, обдумать что делать с привязкой заклинаний к школам. Если переносить полностью на бонусы - то что делать с такими ситуациями как некромантия, где герой без скила может получить бонус с города или арта. Это то что с ходу вспомнил.
Нужно или нет вообще - останется на совести автора кода, можно сразу прикинуть возможный формат и написать конфиг скилов в нем, не делая поддержки новых скилов. Такая схема работала везде до появления модов, сейчас осталась в редких местах по типу почв.
Ну разговор то как раз про те умения, которые через бонусы, а еще конкретнее про
void CGHeroInstance::updateSkill
. Там считаются значения бонусов на основе уровня умения. Но там не только цифры разные там еще и формулы разные. Можно или выкинуть формулы и внести в конфиг константы для каждого уровня или все таки добавить поддержку произвольных формул (а это уже почти скиптинг).
Хмм… Чтот казалось что там только часть умений а не все/почти все. В таком случае логичнее сделать через константы - уровней всего 3 и их количество фактически фиксировано.
Мне кажется, делать жесткие блоки “basic”,“advanced”,“expert” некруто. А если со временем понадобится сделать 5 уровней навыка, как в HMM4? Я предлагаю сделать массив текстовых идентификаторов уровней (“skillLevels”:“basic”,“advanced”,“expert”]), и их отдельно в похожем как у тебя формате расписать.
И надо не забыть пути к файлам иконок.
{
“skillName”:
{
“name”:“Demonology”,
“description”:“Gives hero a spell to rise demons from corpses of hero troops after battle.”,
“skillLevels”:“basic”,“advanced”,“expert”],
"levels":
"basic":
{
// optional, number
// most of sec skills use SECONDARY_SKILL_PREMY bonus with skillName subtype
// this is value for such case
"premyValue":50,
"description": "Basic demonology rises demon from each 50 HP of dead troops.",
//optional object, allows overriding by name
"bonuses":
{
"firstBonus":{[bonus format]},
"secondBonus":{[bonus format]}
}
},
"advanced":
{
"name":"Advanced",
"premyValue": 30,
"description": "Advanced demonology rises demon from each 30 HP of dead troops.",
возможно стоит отписаться в английской часть форума. Не знаю все ли следят за списком изменений на вики.
не уверен нужно ли поле “premyValue”. Возможно проще добавить его как бонус. Сейчас он вносит зависимость от id навыков, которые жестко зашиты, тем самым делает его бессмысленным для навыков с модов.
Macron1,
Лучше оставить как есть. Разве что обернуть это в отдельную структуру:
“levels” : { “basic” : { < бонусы > }, “advanced” : { < бонусы > }, “expert” : { < бонусы > } }
Доп. уровни или даже перки с 5ки проще организовать в таком формате. Тогда нужно будет добавить одно поле вида “requires” по типу новых зависимостей в зданиях.
В итоге продвинутый уровень будет требовать начальный, какой-то 4й уровень - будет требовать эксперта, а в перках - будет прописан базовый навык.
Сервер упал при создании новой кампании, лог сервера:
15:20:18 INFO global [7ffff7fc2740] - Map loaded!
15:20:18 INFO global [7ffff7fc2740] - Our checksum for the map: 486245561
15:20:18 DEBUG global [7ffff7fc2740] - Initialization:
15:20:18 DEBUG global [7ffff7fc2740] - Creating player entries in gs
15:20:18 DEBUG global [7ffff7fc2740] - Picking grail position
15:20:18 DEBUG global [7ffff7fc2740] - Picking random factions for players
15:20:18 DEBUG global [7ffff7fc2740] - Randomizing objects
15:20:18 ERROR global [7ffff7fc2740] - Failed to find template for 54:194
15:20:18 ERROR global [7ffff7fc2740] - Error: signal 11:
15:20:18 ERROR global [7ffff7fc2740] - /usr/games/vcmiserver(_Z17handleLinuxSignali+0x22) [0x4cba02]
15:20:18 ERROR global [7ffff7fc2740] - /lib/x86_64-linux-gnu/libc.so.6(+0x36ff0) [0x7ffff6013ff0]
15:20:18 ERROR global [7ffff7fc2740] - /usr/lib/x86_64-linux-gnu/vcmi/libvcmi.so(_ZNSt6vectorIS_IhSaIhEESaIS1_EEaSERKS3_+0x1f) [0x7ffff79965df]
15:20:18 ERROR global [7ffff7fc2740] - /usr/lib/x86_64-linux-gnu/vcmi/libvcmi.so(_ZN10CGameState15randomizeObjectEP16CGObjectInstance+0x4d4) [0x7ffff7981d14]
15:20:18 ERROR global [7ffff7fc2740] - /usr/lib/x86_64-linux-gnu/vcmi/libvcmi.so(_ZN10CGameState19randomizeMapObjectsEv+0xa5) [0x7ffff7982f15]
15:20:18 ERROR global [7ffff7fc2740] - /usr/lib/x86_64-linux-gnu/vcmi/libvcmi.so(_ZN10CGameState4initEP9StartInfo+0x450) [0x7ffff79870a0]
15:20:18 ERROR global [7ffff7fc2740] - /usr/games/vcmiserver(_ZN12CGameHandler4initEP9StartInfo+0x8a) [0x46e63a]
15:20:18 ERROR global [7ffff7fc2740] - /usr/games/vcmiserver(_ZN11CVCMIServer27initGhFromHostingConnectionER11CConnection+0x183) [0x4d0c03]
15:20:18 ERROR global [7ffff7fc2740] - /usr/games/vcmiserver(_ZN11CVCMIServer7newGameEv+0x2a) [0x4d0d8a]
15:20:18 ERROR global [7ffff7fc2740] - /usr/games/vcmiserver(_ZN11CVCMIServer5startEv+0x6e8) [0x4d21c8]
15:20:18 ERROR global [7ffff7fc2740] - /usr/games/vcmiserver(main+0x745) [0x465f25]
15:20:18 ERROR global [7ffff7fc2740] - /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5) [0x7ffff5ffede5]
15:20:18 ERROR global [7ffff7fc2740] - /usr/games/vcmiserver() [0x46665a]
Бэктрейс:
Established connection with VCMI 0.94b (server)
Connecting to the server: 0
Will send info to server...
Server opened map properly.
Error: server failed to close correctly or crashed!
Check /home/kroartem/.vcmi/server_log.txt for more info
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >'
what(): read: End of file
Program received signal SIGABRT, Aborted.
[Switching to Thread 0x7fffdd5f6700 (LWP 13904)]
0x00007ffff3fedf77 in __GI_raise (sig=sig@entry=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: Нет такого файла или каталога.
(gdb) bt
#0 0x00007ffff3fedf77 in __GI_raise (sig=sig@entry=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1 0x00007ffff3ff15e8 in __GI_abort () at abort.c:90
#2 0x00007ffff48f96e5 in __gnu_cxx::__verbose_terminate_handler() ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff48f7856 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ffff48f7883 in std::terminate() ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ffff48f7af6 in __cxa_rethrow ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007ffff79d0587 in CConnection::read (this=this@entry=0x7fffcc003120,
data=data@entry=0x7fffdd5f5b1d, size=size@entry=1)
at /build/buildd/vcmi-0.94+svn3406/lib/Connection.cpp:171
#7 0x00000000005cf953 in loadPrimitive<unsigned char> (
data=@0x7fffdd5f5b1d: 127 '\177', this=0x7fffcc003120)
at /build/buildd/vcmi-0.94+svn3406/client/../lib/Connection.h:973
#8 invoke (data=@0x7fffdd5f5b1d: 127 '\177', s=...)
at /build/buildd/vcmi-0.94+svn3406/client/../lib/Connection.h:191
#9 load<unsigned char> (data=@0x7fffdd5f5b1d: 127 '\177', this=0x7fffcc003120)
at /build/buildd/vcmi-0.94+svn3406/client/../lib/Connection.h:960
#10 operator>><unsigned char> (t=@0x7fffdd5f5b1d: 127 '\177',
this=0x7fffcc003120, this@entry=0x0)
at /build/buildd/vcmi-0.94+svn3406/client/../lib/Connection.h:915
---Type <return> to continue, or q <return> to quit---
#11 CISer<CConnection>::loadPointer<StartInfo*> (
this=this@entry=0x7fffcc003120, data=@0x7fffdd5f5ba8: 0x7fffd8556300)
at /build/buildd/vcmi-0.94+svn3406/client/../lib/Connection.h:1005
#12 0x00000000005c4569 in invoke (data=@0x7fffdd5f5ba8: 0x7fffd8556300, s=...)
at /build/buildd/vcmi-0.94+svn3406/client/../lib/Connection.h:207
#13 load<StartInfo*> (data=@0x7fffdd5f5ba8: 0x7fffd8556300,
this=0x7fffcc003120)
at /build/buildd/vcmi-0.94+svn3406/client/../lib/Connection.h:960
#14 operator>><StartInfo*> (t=@0x7fffdd5f5ba8: 0x7fffd8556300,
this=0x7fffcc003120)
at /build/buildd/vcmi-0.94+svn3406/client/../lib/Connection.h:915
#15 CClient::newGame (this=this@entry=0x7fffcc000a90, con=con@entry=0x0,
si=si@entry=0x7fffd8556300)
at /build/buildd/vcmi-0.94+svn3406/client/Client.cpp:335
#16 0x00000000005f7127 in startGame (options=0x7fffd8556300, serv=0x0)
at /build/buildd/vcmi-0.94+svn3406/client/CMT.cpp:941
#17 0x00007ffff6ddd94a in ?? ()
from /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.53.0
#18 0x00007ffff6bbcf6e in start_thread (arg=0x7fffdd5f6700)
at pthread_create.c:311
#19 0x00007ffff40b19cd in clone ()
at ../sysdeps/unix/sysv/linux/x86_64/clone.S:113
Похоже я зря забыл о баге с невидимыми оборотнями
Падает, так как у них не прописана анимация для карты. Исправлю.
Стоп. У них все на месте.
Вопрос - вог ставился из нашего zip архива? Или откуда-то еще?
UPD:
запусти игру и в системной консоли введи
extract data/objects.txt
VCMI извлечет этот файл сюда:
~/.vcmi/extracted/Data/objects.txt
И выложи его тут.
Игра падает в сражении, видимо, какие-то условия соблюдаются\не соблюдаются, потому что уже полмиссии прошел, и это первое падение.
Бэктрейс:
Opening BattleAI
Loaded Battle AI
[New Thread 0x7fffde886700 (LWP 29956)]
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffde886700 (LWP 29956)]
CBattleAI::activeStack (this=0x7fffd842b208, stack=0x0)
at /build/buildd/vcmi-0.94+svn3407~ubuntu13.10.1/AI/BattleAI/BattleAI.cpp:107
107 /build/buildd/vcmi-0.94+svn3407~ubuntu13.10.1/AI/BattleAI/BattleAI.cpp: Нет такого файла или каталога.
(gdb) bt
#0 CBattleAI::activeStack (this=0x7fffd842b208, stack=0x0)
at /build/buildd/vcmi-0.94+svn3407~ubuntu13.10.1/AI/BattleAI/BattleAI.cpp:107
#1 0x0000000000522a7b in operator() (__closure=0x7fffd8377018)
at /build/buildd/vcmi-0.94+svn3407~ubuntu13.10.1/client/battle/CBattleInterface.cpp:2851
#2 boost::detail::thread_data<CBattleInterface::requestAutofightingAIToTakeAction()::__lambda22>::run(void) (this=0x7fffd8376e60)
at /usr/include/boost/thread/detail/thread.hpp:117
#3 0x00007ffff6ddd94a in ?? ()
from /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.53.0
#4 0x00007ffff6bbcf6e in start_thread (arg=0x7fffde886700)
at pthread_create.c:311
#5 0x00007ffff40b19cd in clone ()
at ../sysdeps/unix/sysv/linux/x86_64/clone.S:113
(gdb)
И, кажется, я нашел момент, когда баг воспроизводится. Прикладываю сейв. Жемчужиной надо атаковать рядом стоящего противника, личом я атакую скелета, другим личом - его же, потом противник посылает в меня какое-то заклинание и в этот момент я жму на кнопку ‘автоматическая битва’. Видимо, проблема именно в одновременности происходящих событий (судя по отсылкам на pthread). save.tar (3.44 MB)