Closed Kor-Angar closed 3 years ago
В общем, есть идеи всё это дело переделать глобально. Мне уже подгоняли готовую систему, которая должна исправить все подобные ошибки и сделать разработку проще в будущем. Пора пустить её в дело.
Мне уже подгоняли готовую систему
Ту систему можно сильнее обобщить. Суть в том, что для любого изменения таланта должен указываться источник (Talent Source). Например:
ChangeTalent(NPC_TALENT_2H, 5, TS_Training);
Для каждого источника необходимо хранить значение отдельно.
Результирующее значение для таланта, которое нужно использовать в игре, всегда будет равно сумме значений из всех источников, при необходимости урезанной в диапазон [0-100].
Как-то так должно выглядеть: https://gist.github.com/UnresolvedExternal/b840e020da8878e9bf002b7762ff875f
@UnresolvedExternal Тестировала первый вариант. При любом повышении навыка герою назначается оверлей мастера. Всё из-за этой строки:
newSkill = GetMin(hero.HitChance[NPC_TALENT_x] / 3, 2);
Здесь всегда возвращается 2, а значит что в UpdateHeroOverlay пойдет newSkill равный 2 и каждый раз будет выполняться назначение оверлея mds2:
} else if (newSkill == 2)
{
Mdl_ApplyOverlayMds(hero, mds2);
};
Во втором варианте, похоже, всё так же. Мне непонятна логика с GetMin. Хотя, может, я неправильно инициализирую ГГ при старте новой игры. Если что, делаю это в диалоге с Ксардасом, потому что на этапе проигрывания ролика ГГ ещё не существует.
Минимально возможный hero.HitChance при старте игры - 10. Максимальный - 100. Деление любого из чисел этого промежутка даст число, большее 2.
На 30 над делить, а не на 3.
const int TAL_MinValue[TAL_Max];
Значение не устанавливается. Что тут должно быть?
Значение не устанавливается. Что тут должно быть?
Нули
Поправь как нужно, пожалуйста. А точно можно использовать конструкции такого вида?
= { 0, 100, 100, 100, 100 }
Нигде в скриптах такого нет.
А точно можно использовать конструкции такого вида?
Я не пробовал компилировать свой код. https://github.com/dosinabox/g2nr_unofficial_update/blob/develop/PrjGOTHIC/_Intern/Constants.d Найди spellFxInstanceNames
Исправил ошибки компиляции
Обновил код. Функция B_GetLearnCostTalent изменится так.
func int B_GetLearnCostTalent(var C_Npc oth,var int talent,var int skill)
{
var int kosten;
kosten = 0;
if (B_IsTalentSupported(oth, talent))
{
kosten = B_GetTalentChangeCost(talent, skill);
return kosten;
};
функция B_TeachFightTalentPercent
func int B_TeachFightTalentPercent(var C_Npc slf,var C_Npc oth,var int talent,var int percent,var int teacherMAX)
{
var string concatText;
var int kosten;
var int realHitChance;
kosten = B_GetLearnCostTalent(oth,talent,1) * percent;
if((talent != NPC_TALENT_1H) && (talent != NPC_TALENT_2H) && (talent != NPC_TALENT_BOW) && (talent != NPC_TALENT_CROSSBOW))
{
Print("*** ОШИБКА: Неправильный параметр ***");
return FALSE;
};
if (B_IsTalentSupported(oth, talent))
{
kosten = B_GetTalentChangeCost(talent, percent);
realHitChance = B_GetInTrainingTalent(talent);
if (realHitChance + percent > B_GetTalentMax(talent))
{
PrintScreen(PRINT_NoLearnOverMAX,-1,-1,FONT_Screen,2);
B_Say(slf,oth,"$NOLEARNYOUREBETTER");
return FALSE;
};
if (realHitChance + percent > teacherMAX)
{
concatText = ConcatStrings(PRINT_NoLearnOverPersonalMAX,IntToString(teacherMAX));
PrintScreen(concatText,-1,-1,FONT_Screen,2);
B_Say(slf,oth,"$YOULEARNEDSOMETHING");
return FALSE;
};
if (oth.lp < kosten)
{
PrintScreen(PRINT_NotEnoughLP,-1,-1,FONT_Screen,2);
B_Say(slf,oth,"$NOLEARNNOPOINTS");
return FALSE;
};
B_ChangeTalent(talent, percent, TS_Training);
oth.lp -= kosten;
return TRUE;
};
Остаётся:
https://gist.github.com/UnresolvedExternal/b840e020da8878e9bf002b7762ff875f
Спасибо! Будем тестировать. Вопросы:
Что-то мне эта функция не нравится, можешь её объяснить?
if (talent == NPC_TALENT_1H)
{
return CoerceInRange(
TAL_Training[NPC_TALENT_1H] + TAL_TempBonus[NPC_TALENT_1H] + TAL_PermBonus[NPC_TALENT_1H],
TAL_MinValue[NPC_TALENT_1H],
TAL_MaxValue[NPC_TALENT_1H]
);
}
TAL_Training[NPC_TALENT_1H] это (обучение за LP +10)? TAL_TempBonus[NPC_TALENT_1H] это бонусы/штрафы от кольца и оружия? TAL_PermBonus[NPC_TALENT_1H] скрижали, книга?
а бонус Вульфгара относится к TAL_Training[NPC_TALENT_1H] или к TAL_PermBonus[NPC_TALENT_1H] ?
а бонус Вульфгара относится к TAL_Training[NPC_TALENT_1H] или к TAL_PermBonus[NPC_TALENT_1H] ?
Нужно будет относить к TAL_PermBonus.
Нужно будет относить к TAL_PermBonus.
не факт :-)
TAL_Training[NPC_TALENT_1H] это (обучение за LP +10)? TAL_TempBonus[NPC_TALENT_1H] это бонусы/штрафы от кольца и оружия? TAL_PermBonus[NPC_TALENT_1H] скрижали, книга?
Да.
а бонус Вульфгара относится к TAL_Training[NPC_TALENT_1H] или к TAL_PermBonus[NPC_TALENT_1H] ?
Лучше к TAL_PermBonus, думаю. С точки зрения реализма, это тренировка, но с позиции игры этот бонус имеет все те же нюансы что и бонусы от скрижалей. Например, игрок может отсрочивать получение этого бонуса, чтобы стоимость тренировок не увеличилась раньше времени.
Что-то мне эта функция не нравится, можешь её объяснить?
Попроще сейчас ее перепишу, убрав последний аргумент.
С точки зрения реализма, это тренировка
а можно его получить если навык 1р =80, при том что Вульфгар тренирует только до 75? это вопрос конечно же риторический :-)
а можно его получить если навык 1р =80, при том что Вульфгар тренирует только до 75?
в Готики 1 Горацио не давал бонус +5 к силе, если у героя было больше 100 силы и становилось понятно что это по сути обучение у учителя за 0 LP. или нет?
// ************************************************************
// Will Ricelord kцpfen
// ************************************************************
func void DIA_Horatio_HelpSTR_LEARN_NOW()
{
if (other.attribute[ATR_STRENGTH]<=(100-5))
{
other.attribute[ATR_STRENGTH] = other.attribute[ATR_STRENGTH] + 5;
PrintScreen ("Stдrke + 5", -1,-1,"FONT_OLD_20_WHITE.TGA",2);
}
else
{
other.attribute[ATR_STRENGTH] = 100;
PrintScreen ("Stдrke: 100", -1,-1,"FONT_OLD_20_WHITE.TGA",2);
};
AI_Output (self, other,"DIA_Horatio_HelpSTR_LEARN_NOW_09_00"); //Wenn du stark zuschlagen willst, kommt es auf die richtige Technik an. Das ist das Erste, was du beim Schmieden lernst.
AI_Output (self, other,"DIA_Horatio_HelpSTR_LEARN_NOW_09_01"); //Lerne jeden Teil deines Arms, von der Schulter bis zum Handgelenk, gleichzeitig nach vorne schnellen zu lassen.
AI_Output (self, other,"DIA_Horatio_HelpSTR_LEARN_NOW_09_02"); //Je besser die Technik, umso hдrter der Schlag. Du wirst es schnell raushaben.
};
если у героя было к примеру 97 силы, то он поднимал на 3 то есть до 100?
следует ли из этого что Эрол должен давать бонус если у Героя < 200 силы?
Если упростить неправильно считает: или я туплю или сурсер. Короче, имея одноручное 28, хотим узнать, сколько будет стоить поднять навык на 5: f(28, 5, 0) = f(29, 4, 1) = f(30, 3, 2) = f(31, 2, 4) = f(32, 1, 6) = f(33, 0, 8) => return 8 Последним параметром накапливается результат, который в конце концов возвращается.
Короче, имея одноручное 28, хотим узнать, сколько будет стоить поднять навык на 5: f(28, 5, 0) = f(29, 4, 1) = f(30, 3, 2) = f(31, 2, 4) = f(32, 1, 6) = f(33, 0, 8) => return 8
2х1+3х2=6+2=8 считает всё верно
это как раз то что хотела D36
В идеале нужно делать точный расчет очков при обучении с такими значениями и переключатель у помощника ("честный расчет стоимости обучения"). Слишком привычная механика, не стоит её ломать для всех.
https://github.com/dosinabox/g2nr_unofficial_update/issues/215
Учесть влияние одноручного на двуручное и наоборот
Это вот это https://github.com/dosinabox/g2nr_unofficial_update/issues/206 имеется ввиду?
Обучился сначала одноручному до 75, затем двуручному до 75. Потратил 190 очков обучения. Обучался одновременно одноручному и двуручному - потратил 250 очков обучения. Это так и задумано, или это баг?
Обучился сначала одноручному до 75, затем двуручному до 75. Потратил 190 очков обучения. Обучался одновременно одноручному и двуручному - потратил 250 очков обучения. Это так и задумано, или это баг?
В НВ так было задумано:-(
В НВ так было задумано:-(
Ага. Или просто тот же баг присутствует и там.
//С чего мне лучше начать? С одноручного или двуручного оружия?
//Выбирай сам.
//Но даже если ты и специализируешься только в одном типе оружия, со временем ты начнешь автоматически изучать и другой тип.
//Если, например, ты хорошо сражаешься одноручным оружием, но все еще новичок в использовании двуручного...
//... твой навык владения двуручным оружием повышается каждый раз, когда ты тренируешься с одноручным...
//Правда, в этом случае обучение изматывает сильнее, чем когда ты тренируешься с различным типом оружия по очереди.
//Тебе нужно просто начать - и ты сам поймешь, о чем я говорю.
Этот диалог из Готики 2 классик. Там была другая логика прокачки. В НВ 2 авторы логику поменяли, а диалог остался тот же.
Можно попытаться восстановить логику Готику 2 классик, но тогда обучение обоим навыкам станет дороже чем сейчас.
Можно попытаться восстановить логику Готику 2 классик, но тогда обучение обоим навыкам станет дороже чем сейчас.
Мне ближайший аналог видится как 10лп в пользу игрока:
Пример:
Пример: Качаем одноручное до 40% по 1лп. Получаем навыки 40%/10%. Качаем одноручное до 60% по 2лп. Получаем навыки 60%/30%. Качаем одноручное до 90% по 3лп. Получаем навыки 90%/60%. Качаем одноручное до 100% по 4лп. Получаем навыки 100%/70%.
сейчас 10-30 = 20 ЛП 30-60 = 60 ЛП итого 80 ЛП
у тебя 10-40 = 30 ЛП 40-60 = 20 ЛП + 20 ЛП итого 70 ЛП если при этом поднять 2р за бонусы вовремя получится всего 50 ЛП
и вот это отставание на 30 в НВ прописано с потолка. так как проверка шла в Готике 2 Классик по Боец / Мастер.
//Если, например, ты хорошо сражаешься одноручным оружием, но все еще новичок в использовании двуручного...
Так же и Корд проверяет не по тому какой % навыка у героя, а как герой держит меч. Собственно в игровом мире НПС могут понять какой навык у героя только визуально оценив как он держит оружие. Ну и игрок тоже не угадает никак какой процент у Диего. Понятно что он мастер 1р, а сколько именно процентов понять нереально :-)
можно попытаться объединить логику Готику 2 Классик и цены Готики 2 НВ. Но как это сделать с учётом тех бонусов что появились в НВ? если перманентные бонусы учителя не будут замечать тогда система прокачки станет значительно дороже, если учителя будут учитывать бонусы, то это на баланс не повлияет.
если же пытаться настроить что вот тут учителя бонусы не замечают, а тут замечают, получится Шизофрения. а Готика это не TES, тут Шеогората нет:-))
Корд проверяет не по тому какой % навыка, а как герой держит меч
Корд до тренировки проверяет. Во время тренировки становится ясно, какой реальный навык имеет ГГ.
Корд до тренировки проверяет. Во время тренировки становится ясно, какой реальный навык имеет ГГ.
Я про квест Корда.
func void DIA_Cord_WannaJoin_Info()
{
AI_Output(other,self,"DIA_Cord_WannaJoin_15_00"); //Я хочу стать наемником!
if(Cord_SchonmalGefragt == FALSE)
{
if(MIS_Addon_Lares_ComeToRangerMeeting != LOG_SUCCESS)
{
AI_Output(self,other,"DIA_Cord_WannaJoin_14_01"); //Ты больше похож на того, кто был рожден работать на поле, парень.
};
AI_Output(self,other,"DIA_Cord_WannaJoin_14_02"); //Ты умеешь обращаться с оружием?
Cord_SchonmalGefragt = TRUE;
}
else
{
AI_Output(self,other,"DIA_Cord_WannaJoin_14_03"); //Ты повысил свои навыки?
};
AI_Output(self,other,"DIA_Cord_WannaJoin_14_04"); //Итак, как насчет одноручного оружия?
if(Npc_GetTalentSkill(other,NPC_TALENT_1H) > 0)
{
AI_Output(other,self,"DIA_Cord_WannaJoin_15_05"); //Я не так уж плох в этом.
}
else
{
AI_Output(other,self,"DIA_Cord_WannaJoin_15_06"); //Что-о-ожж...
};
AI_Output(self,other,"DIA_Cord_WannaJoin_14_07"); //А что насчет двуручного оружия?
if(Npc_GetTalentSkill(other,NPC_TALENT_2H) > 0)
{
AI_Output(other,self,"DIA_Cord_WannaJoin_15_08"); //Я умею обращаться с ним.
}
else
{
AI_Output(other,self,"DIA_Cord_WannaJoin_15_09"); //И скоро я стану еще лучше!
};
if((Npc_GetTalentSkill(other,NPC_TALENT_1H) > 0) || (Npc_GetTalentSkill(other,NPC_TALENT_2H) > 0))
{
AI_Output(self,other,"DIA_Cord_WannaJoin_14_10"); //Ну, по крайней мере, ты не зеленый новичок. Хорошо. Я проголосую за тебя.
AI_Output(self,other,"DIA_Cord_WannaJoin_14_11"); //Если тебе еще что-то нужно знать, ты можешь спросить у меня.
Cord_Voted = TRUE;
B_GivePlayerXP(XP_Cord_Voted);
if(Torlof_GenugStimmen == FALSE)
{
Log_CreateTopic(TOPIC_SLDRespekt,LOG_MISSION);
Log_SetTopicStatus(TOPIC_SLDRespekt,LOG_Running);
};
B_LogEntry(TOPIC_SLDRespekt,"Голос Корда у меня в кармане.");
}
else
{
AI_Output(self,other,"DIA_Cord_WannaJoin_14_12"); //Другими словами: ты зеленый новичок!
AI_Output(self,other,"DIA_Cord_WannaJoin_14_13"); //Мы, наемники, должны быть уверены, что можем всецело положиться на наших товарищей. От этого зависит наша жизнь.
SCKnowsSLDVotes = TRUE;
B_Cord_BeBetter();
if(DIA_Cord_WannaJoin_Once == FALSE)
{
Log_CreateTopic(TOPIC_CordProve,LOG_MISSION);
Log_SetTopicStatus(TOPIC_CordProve,LOG_Running);
B_LogEntry(TOPIC_CordProve,"Корд проголосует за меня, когда я научусь сражаться лучше.");
DIA_Cord_WannaJoin_Once = TRUE;
};
};
};
В Готике 2 Классик вот так было
1р | 1р | 2р | 2р |
---|---|---|---|
10 -->20 | Новичок | 10 | Новичок |
20 -->30 | Новичок --> Боец | 10 | Новичок |
30 -->40 | Боец | 10-->20 | Новичок |
40 -->50 | Боец | 20 -->30 | Новичок --> Боец |
50 -->60 | Боец--> Мастер | 30 | Боец |
60 -->70 | Мастер | 30 -->40 | Боец |
70 -->80 | Мастер | 40 -->50 | Боец |
80 -->90 | Мастер | 50 -->60 | Боец--> Мастер |
90 -->100 | Мастер | 60 | Мастер |
то есть между "50-60" и "90-100" 1р прокачивался без 2р
а дельта 30 в НВ это видимо разница выраженная в цифрах между Боец и Мастер. 60(Мастер)-30(Боец)=30. Ну это только мне так кажется. как видели это авторы я не знаю.
Что точно можно убрать, это когда имея 59% одноручного и 30% двуручного, качаешь одноручное на 5%, а двуручное при этом не качается.
Что точно можно убрать, это когда имея 59% одноручного и 30% двуручного, качаешь одноручное на 5%, а двуручное при этом не качается.
посмотри если не сложно своим опытным взглядом https://github.com/dosinabox/g2nr_unofficial_update/issues/206
Да это переделано будет. Как насчёт убрать эти строки из проекта?
const string PRINT_Learn1H = "Улучшено: Сражение одноручным оружием";
const string PRINT_Learn1H_and_2H = "Улучшено: Сражение одноручным и двуручным оружием";
const string PRINT_Learn2H = "Улучшено: Сражение двуручным оружием";
const string PRINT_Learn2H_and_1H = "Улучшено: Сражение двуручным и одноручным оружием";
const string PRINT_LearnBow = "Улучшено: Меткость стрельбы из лука";
const string PRINT_LearnBow_and_Crossbow = "Улучшено: Меткость стрельбы из лука и арбалета";
const string PRINT_LearnCrossbow = "Улучшено: Меткость стрельбы из арбалета";
const string PRINT_LearnCrossbow_and_Bow = "Улучшено: Меткость стрельбы из арбалета и лука";```
Да это переделано будет.
а при проверка разницы между 1р и 2р учителя будут учитывать или игнорировать бонусы/штрафы от оружия и колец?
к примеру если у меня 1р =30 и я одел меч +10 (1р=30+10=40), а 2р = 10, при прокачке 1р поднимется ли 2р?
Как насчёт убрать эти строки из проекта?
Почему?
это как раз то что хотела D36
С одной стороны - это очень хорошо и правильно. С другой - слишком непривычно и радикально.
а можно его получить если навык 1р =80, при том что Вульфгар тренирует только до 75?
Да, и так должно остаться. При сомнениях ориентируемся на оригинал, смотрим как там и делаем так же.
Почему?
Потому что проще конкретное значение вывести Одноручное оружие + 2
.
а при проверка разницы между 1р и 2р учителя будут учитывать или игнорировать бонусы/штрафы от оружия и колец?
Можно оба варианта реализовать. Либо кольца влияют на цены, либо нет.
Да, и так должно остаться. При сомнениях ориентируемся на оригинал, смотрим как там и делаем так же.
в оригинале он и Наёмнику бонус даёт +2%, а в следующем диалоге говорит что он тренирует Наёмника.
AI_Output(self,other,"DIA_Wulfgar_Bonus_04_00");//Ранняя пташка? Я обычно один в это время дня. Но раз уж ты здесь, то можно потренироваться.
AI_Output(self,other,"DIA_Wulfgar_Bonus_04_01");//Будь внимательным. Ты можешь обмануть некоторых противников, если уклонишься от удара, а затем атакуешь в правильный момент.
AI_Output(self,other,"DIA_Wulfgar_Bonus_04_02");//Помни об этом в своем следующем бою!
AI_Output(other,self,"DIA_Wulfgar_Teach_15_00");//Начнем обучение.
AI_Output(self,other,"DIA_Wulfgar_Add_04_00"); //Я не обучаю наемников!
я выше писал как в Готике 1 был реализован бонус от Горацио.
в оригинале он и Наёмнику бонус даёт +2%, а в следующем диалоге говорит что он тренирует Наёмника.
Это всё лирика и индивидуальные случаи применения новой общей системы. Эту систему сначала нужно осознать, продумать, внедрить, протестировать и довести до совершенства.
Потому что проще конкретное значение вывести
Когда старые строки перестанут использоваться, то я их сразу уберу.
Когда старые строки перестанут использоваться, то я их сразу уберу.
Да ладно, приспособил уже. Просто сначала думал, что функция повышения таланта сразу будет выводить сообщение, основываясь на источнике. Но не стал так делать, для большей гибкости.
А это чё за условие?
func void UnEquip_1H_01()
{
if(Npc_IsPlayer(self) && (MELEEWEAPONCHANGEDHERO || (SCRIPTPATCHWEAPONCHANGE == FALSE)))
Если у ГГ 98% владения и он использует табличку на +6, что должно произойти? Если после этого он экипирует дубинку на -10, что должно произойти? Не очень понятно, когда учитель должен говорить, что дальше учиться невозможно (>100) А так, вроде, работает. https://gist.github.com/UnresolvedExternal/b840e020da8878e9bf002b7762ff875f
Если у ГГ 98% владения и он использует табличку на +6, что должно произойти?
наверное если 98% без бонуса от оружия и без бонуса от кольца, то 98+6=100 :-)
Если после этого он экипирует дубинку на -10, что должно произойти?
100-10 = 90. дубинку можно использовать для прокачки навыка, если навык уже 100%, то и качаться дальше не надо. а для иных целей она в игре не используется.
Не очень понятно, когда учитель должен говорить, что дальше учиться невозможно (>100)
это зависит от того какой у него порог обучения и как он навык оценивает. В оригинальной игре это было та цифра которая выводится на экране, В неофициальном обновление сейчас это зависит от настроек, D36 прийдет расскажет :-)
Я правильно понимаю, что эта строчка заставляет вернуться табличку в инвентарь?
Mdl_ApplyOverlayMdsTimed(self,"HUMANS_STONEPLATE.MDS",500);
И если она не выполнится, то табличка исчезнет?
Сделал так:
func void B_RaiseTalentByStonePlate(var C_NPC npc, var int talent, var int value)
{
if (B_IsTalentSupported(npc, talent))
{
value = B_ChangeTalent(talent, value, TS_PermBonus);
}
else
{
B_RaiseAttribute(npc, talent, value);
};
if (value == 0)
{
PrintScreen(PRINT_NoLearnOverMAX,-1,-1,FONT_Screen,2);
Mdl_ApplyOverlayMdsTimed(self,"HUMANS_STONEPLATE.MDS",500);
B_Say(self,self,"$PickBroke");
AI_Waitms(self,500);
return;
};
// далее эффекты и вывод реального увеличения таланта
Игрок с именем "Я" качается по продвинутой схеме. Все остальные - по примитивной, без обрезаний талантов (на цены и пороги учителей для них влияю все бонусы). Основные изменения тут: https://gist.github.com/UnresolvedExternal/8751584893caaaf06e5a610b4e0d334a
Проверить работоспособность системы можно с этим файлом (переделано обучение, оружие ближнего боя, кольцо Моргана, таблички и бонус Вульфгара): Gothic.dat.zip
Кстати когда носишь кольцо к 1р и оружие к 1р, после того как что то снимаешь, а потом одеваешь некорректно считается бонус приходится ещё раз все снять, а потом одеть.
_Originally posted by @Kor-Angar in https://github.com/dosinabox/g2nr_unofficial_update/issues/187#issuecomment-594368384_
https://github.com/dosinabox/g2nr_unofficial_update/issues/187