• Уважаемые гости и новички, приветствуем Вас на нашем форуме
    Здесь вы можете найти ответы практически на все свои вопросы о серии игр «Готика» (в том числе различных модах на нее), «Ведьмак», «Ризен», «Древние свитки», «Эра дракона» и о многих других играх. Можете также узнать свежие новости о разработке новых проектов, восхититься творчеством наших форумчан, либо самим показать, что вы умеете. Ну и наконец, можете обсудить общие увлечения или просто весело пообщаться с посетителями «Таверны».

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!

Возвращение 1: Гильдии (на базе Rebalance 2.1) - Предложения и отзывы

Диккен

Участник форума
Регистрация
12 Июн 2004
Сообщения
469
Благодарности
127
Баллы
210
Гильдии 0.2 - вместо превью... by xterm 15.09.2012, 16:07

МОДИФИКАЦИИ
Bump:
значительное упрощение игры, в частности касаемо затрат выносливости
Я поступил по другому, просто улучшил реген стамины под себя, 150 сек реала на восполнение с нуля.
Код:
	if((ATR_STAMINA < (ATR_STAMINA_MAX * 10)) && (POISONED == 0) && Npc_IsInFightMode(hero,FMODE_NONE) && (C_BodyStateContains(hero,BS_STAND) || C_BodyStateContains(hero,BS_SIT)))
	{
		if(VATRAS_TEACHREGENSTAM == TRUE)
		{
			ATR_STAMINA = ATR_STAMINA + ATR_STAMINA_MAX / 5;
			RELOADSTAM = 0;
		}
		else if((RELOADSTAM == 2) && (VATRAS_TEACHREGENSTAM == FALSE))
		{
			ATR_STAMINA = ATR_STAMINA + ATR_STAMINA_MAX / 5;
			RELOADSTAM = 0;
		}
		else
		{
			RELOADSTAM += 1;
		};
		if(ATR_STAMINA > (ATR_STAMINA_MAX * 10))
		{
			ATR_STAMINA = ATR_STAMINA_MAX * 10;
		};
		print_percent_bar_learn(ATR_STAMINA,ATR_STAMINA_MAX * 10,"Выносливость",42,97);
	};

Мне надоело ловить случайные бонусы для навыка перезагрузками и сделал себе так:
Код:
			if(WAFFENTALENTNAHKAMPF[2] > EXP_LAST_LEVEL[2])
			{
				if(hero.aivar[REAL_TALENT_1H] < 100)
				{
					concatText = ConcatStrings(concatText,"\nОдноручное + 1 EXP ");
					concatText = ConcatStrings(concatText,IntToString(EXP_LAST_LEVEL[2]));
					PrintScreen("Одноручное + 1",-1,YPOS_XPGained - 10,FONT_Screen,2);
					B_RaiseFightTalent(hero,NPC_TALENT_1H,1);
				};
				if(BONUSHW == 2)
				{
					concatText = ConcatStrings(concatText,"\nСила + 1");
					concatText = ConcatStrings(concatText,"\n----------");
					Log_AddEntry(TOPICCOUNT,concatText);
					B_RaiseAttribute(hero,ATR_STRENGTH,1);
				}
				else
				{
					concatText = ConcatStrings(concatText,"\nЛовкость + 1");
					concatText = ConcatStrings(concatText,"\n----------");
					Log_AddEntry(TOPICCOUNT,concatText);
					B_RaiseAttribute(hero,ATR_DEXTERITY,1);
				};
				WAFFENTALENTNAHKAMPF[2] -= EXP_LAST_LEVEL[2];
				EXP_LAST_LEVEL[2] = EXP_LAST_LEVEL[2] + 20;
			};

Молитва на статы, моя идея с хитрым рандомом для манчкинов:
Код:
func void PC_PrayShrine_Pray_Info()
{
	var int karmainnos;
	var string concatText;
	concatText = "Пожертвовать 50 золотых.";
//	concatText = ConcatStrings(concatText,IntToString(50 * Kapitel));
//	concatText = ConcatStrings(concatText," золотых.");
	karmainnos = INNOSPRAYCOUNT - INNOSCRIMECOUNT;
	if(ShrineIsObsessed == TRUE)
	{
		SC_IsObsessed = TRUE;
		PrintScreen(PRINT_SCIsObsessed,-1,-1,FONT_Screen,2);
		Snd_Play("DEM_Die");
	}
	else
	{
		Info_ClearChoices(PC_PrayShrine_Pray);
		Info_AddChoice(PC_PrayShrine_Pray,Dialog_Back,PC_PrayShrine_Pray_Back);
		Info_AddChoice(PC_PrayShrine_Pray,"Просто помолиться.",PC_PrayShrine_Pray_NoPay);
		if((Npc_HasItems(hero,ItMi_Gold) >= 50) && (PRAYDAY_BONUS != Wld_GetDay()) && (PRAYDAY_CH1 <= (10 * Kapitel)))
		{
			Info_AddChoice(PC_PrayShrine_Pray,concatText,PC_PrayShrine_Pray_SmallPay);
		};
/*		if(Npc_HasItems(hero,ItMi_Gold) >= 200)
		{
			Info_AddChoice(PC_PrayShrine_Pray,"Пожертвовать 200 золотых.",PC_PrayShrine_Pray_MediumPay);
		};
		if(Npc_HasItems(hero,ItMi_Gold) >= 500)
		{
			Info_AddChoice(PC_PrayShrine_Pray,"Пожертвовать 500 золотых.",PC_PrayShrine_Pray_BigPay);
		};*/
	};
};

func void PC_PrayShrine_Pray_SmallPay()
{
	var int zufall;
	var int zufallday;
	var int karmainnos;
	var int blessinnos;
	karmainnos = INNOSPRAYCOUNT - INNOSCRIMECOUNT;
	blessinnos = Hlp_Random(100 + karmainnos);
	B_Say(self,self,"$SACR_INNOS");
	zufallday = Wld_GetDay() + 1;
	Npc_RemoveInvItems(hero,ItMi_Gold,50);
	zufall = Hlp_Random(zufallday) + Hlp_Random(zufallday) + Hlp_Random(zufallday) + Hlp_Random(zufallday) + Hlp_Random(zufallday);
	if(hero.guild != GIL_KDM)
	{
		if(PrayDay != Wld_GetDay())
		{
			INNOSPRAYCOUNT = INNOSPRAYCOUNT + 1;
			hero.attribute[ATR_HITPOINTS] = hero.attribute[ATR_HITPOINTS_MAX];
			PrintScreen(PRINT_FullyHealed,-1,YPOS_LevelUp,FONT_Screen,2);
		};
		PrintScreen(Print_BlessNone,-1,-1,FONT_Screen,2);
		print_percent_bar_karma_innos(ATR_STAMINA,ATR_STAMINA_MAX * 10,"Выносливость",51,80);
		if(PRAYDAY_BONUS != Wld_GetDay())
		{
			if(karmainnos > blessinnos)
			{
				Wld_PlayEffect("spellFX_LIGHTSTAR_BLUE",hero,hero,0,0,0,FALSE);
				Snd_Play("SFX_HealObsession");
//				if(zufall > (zufallday * 5 * 8 / 10)) || (zufall < (zufallday* 5 * 2 / 10))
				if(zufall >= (zufallday * 4)) || (zufall <= zufallday)
				{
					B_BlessAttribute(hero,ATR_STRENGTH,1);
				}
//				else if(zufall > (zufallday * 5 * 7 / 10)) || (zufall < (zufallday * 5 * 3 / 10))
				else if(zufall >= (zufallday * 7 / 2)) || (zufall <= (zufallday * 3 / 2))
				{
					B_BlessAttribute(hero,ATR_DEXTERITY,1);
				}
//				else if(zufall > (zufallday * 5 * 6 / 10)) || (zufall < (zufallday * 5 * 4 / 10))
				else if(zufall >= (zufallday * 3)) || (zufall <= (zufallday * 2))
				{
					B_BlessAttribute(hero,ATR_MANA_MAX,3);
					Npc_ChangeAttribute(self,ATR_MANA,ATR_MANA_MAX);
				}
				else
				{
					B_BlessAttribute(hero,ATR_HITPOINTS_MAX,5);
					Npc_ChangeAttribute(self,ATR_HITPOINTS,ATR_HITPOINTS_MAX);
				};
				if(Kapitel >= 1)
				{
					PRAYDAY_CH1 += 1;
				};
				if(karmainnos > Hlp_Random(200))
				{
					PRAYDAY_BONUS = 0;
				}
				else
				{
					PRAYDAY_BONUS = Wld_GetDay();
				};
				BONUSCOUNT += 1;
			};
		};
	}
	else
	{
		PrintScreen(PRINT_BLESSNONEKDM,-1,-1,FONT_Screen,2);
	};
	PrayDay = Wld_GetDay();
	Info_ClearChoices(PC_PrayShrine_Pray);
};

Мои эксперименты над модификацией кода воровства, рабочий вариант. Теперь своровать с 1й попытки ключ у Хагена архисложно даже имея 100+ ловкости. ;)
B_Beklauen.d
Код:
var int pickitem;

func int C_Beklauen(var int pickInstance,var int TheftGold)
{
	if((Npc_GetTalentSkill(other,NPC_TALENT_PICKPOCKET) == TRUE) && (self.aivar[AIV_PlayerHasPickedMyPocket] == FALSE) && (NpcObsessedByDMT == FALSE))
	{
		PICKITEM = pickInstance;
		if(Npc_IsInState(self,ZS_Talk))
		{
			if(pickInstance == ItMi_Gold)
			{
				TheftGoldGlob = 25 + Hlp_Random(TheftGold);
				return TRUE;
			};
			if(pickInstance == ItRw_Arrow)
			{
				TheftGoldGlob = 1 + Hlp_Random(TheftGold);
				return TRUE;
			};
			if((Npc_HasItems(self,pickInstance) >= 1) || (TheftGold < 0))
			{
				TheftGoldGlob = 1;
				return TRUE;
			};
			return FALSE;
		};
	};
	return FALSE;
};

func void B_Beklauen()
{
	var int TheftDex;
	var int CheckDex;
/*	if(Hlp_IsItem(ItMi_Gold,PICKITEM) || Hlp_IsItem(ITKE_HAGEN_SECRETKEY,PICKITEM) || Hlp_IsItem(ITKE_OC_STORE2,PICKITEM) || Hlp_IsItem(ItKe_KlosterSchatz,PICKITEM) || Hlp_IsItem(ItKe_Salandril,PICKITEM) || Hlp_IsItem(ItKe_Richter,PICKITEM) || Hlp_IsItem(ITKE_Greg_ADDON_MIS,PICKITEM))
	{
		TheftDex = other.attribute[ATR_DEXTERITY];
	}
	else
	{
		TheftDex = Hlp_Random(other.attribute[ATR_DEXTERITY]);
	};
	if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(Pedro))
	{
		CheckDex = 45;
	};
	if((Hlp_GetInstanceID(self) == Hlp_GetInstanceID(LordHagen)) || (Hlp_GetInstanceID(self) == Hlp_GetInstanceID(Parcival)))
	{
		CheckDex = 100;
	}*/
	TheftDex = other.attribute[ATR_DEXTERITY];
	TheftDex += TheftDex * ThiefLevel / 20;
	CheckDex = Hlp_Random(self.attribute[ATR_DEXTERITY]);
	if(BELIARCURSEYOU == FALSE)
	{
		if(TheftDex >= CheckDex)
		{
			if(Npc_IsPlayer(other))
			{
				INNOSCRIMECOUNT = INNOSCRIMECOUNT + 1;
				if((self.guild == GIL_PAL) || (self.guild == GIL_KDF) || (self.guild == GIL_NOV))
				{
					INNOSCRIMECOUNT = INNOSCRIMECOUNT + 1;
				};
				if((other.guild == GIL_PAL) || (other.guild == GIL_KDF))
				{
					INNOSCRIMECOUNT = INNOSCRIMECOUNT + 1;
				};
				if(PICKITEM == Hlp_GetInstanceID(ItMi_Gold))
				{
					B_GiveInvItems(self,other,ItMi_Gold,TheftGoldGlob);
					Snd_Play("Geldbeutel");
				}
				else
				{
//					CreateInvItems(self,PICKITEM,TheftGoldGlob);
					B_GiveInvItems(self,other,PICKITEM,TheftGoldGlob);
				};
				self.aivar[AIV_PlayerHasPickedMyPocket] = TRUE;
				B_GiveThiefXP();
			};
		}
		else
		{
			if((other.guild == GIL_PAL) || (other.guild == GIL_KDF))
			{
				INNOSCRIMECOUNT = INNOSCRIMECOUNT + 1;
			};
			THIEFCATCHER = Hlp_GetNpc(self);
			HERO_CANESCAPEFROMGOTCHA = TRUE;
			B_ResetThiefLevel();
			AI_StopProcessInfos(self);
		};
	}
	else
	{
		if((other.guild == GIL_PAL) || (other.guild == GIL_KDF))
		{
			INNOSCRIMECOUNT = INNOSCRIMECOUNT + 1;
		};
		THIEFCATCHER = Hlp_GetNpc(self);
		HERO_CANESCAPEFROMGOTCHA = TRUE;
		B_ResetThiefLevel();
		AI_StopProcessInfos(self);
	};
	print_percent_bar_karma_innos(ATR_STAMINA,ATR_STAMINA_MAX * 10,"Выносливость",42,97);
};

if((Npc_HasItems(self,pickInstance) >= 1) || (TheftGold < 0)) - это условие проверки на наличие реального предмета в кармане ИЛИ фантомного, к. не существует, но можно украсть.

Пришлось изменить автозаменой примерно 300+ строк к виду:
- для золота (стрел)
Код:
instance DIA_Bodo_PICKPOCKET(C_Info)
{
	npc = Bau_903_Bodo;
	nr = 900;
	condition = DIA_Bodo_PICKPOCKET_Condition;
	information = DIA_Bodo_PICKPOCKET_Info;
	permanent = TRUE;
	description = PICKPOCKET_COMM;
};


func int DIA_Bodo_PICKPOCKET_Condition()
{
	[B]return C_Beklauen(ItMi_Gold,60);[/B]
};

func void DIA_Bodo_PICKPOCKET_DoIt()
{
	B_Beklauen();
	Info_ClearChoices(DIA_Bodo_PICKPOCKET);
};

-для фантомных вещей
Код:
instance DIA_Gorax_PICKPOCKET(C_Info)
{
	npc = KDF_508_Gorax;
	nr = 888;
	condition = DIA_Gorax_PICKPOCKET_Condition;
	information = DIA_Gorax_PICKPOCKET_Info;
	permanent = TRUE;
	description = "(Попытаться украсть его ключ)";
};


func int DIA_Gorax_PICKPOCKET_Condition()
{
	[B]return C_Beklauen(ItKe_KlosterSchatz,-1);[/B]
};

func void DIA_Gorax_PICKPOCKET_DoIt()
{
	B_Beklauen();
	Info_ClearChoices(DIA_Gorax_PICKPOCKET);
};

Пришлось в исключения занести проверку аргумента функции, иначе ошибка при сборке:
\GothicSourcer\GothicSourcer\System\RedefinedFunc.dsc
int C_Beklauen(int#,int)

Bump:
darv1n написал(а):
Всем привет, недавно сного установил готику и возникла следующая проблема. В конце драке когда нпц должен падать в нокаут он почему то умирает, хотя никаких добивающих ударов не делаю. Из за этого не могу даже пройти квест с Мо, тк в порту начинают орать что я убийца и тд.
Вы будете решать проблему смертельно-колящего оружия в моде? Мне удалось вычислить комплексную формулу урона, теперь моя шпага не убивает нпц.

Код:
instance ItMw_Addon_BanditTrader(C_Item)
{
	name = "Шпага бандита";
	mainflag = ITEM_KAT_NF;
	flags = ITEM_SWD;
	material = MAT_METAL;
	value = Value_BanditTrader;
	damageTotal = Damage_VLKSchwert;
	damagetype = DAM_EDGE | DAM_POINT;
	damage[DAM_INDEX_EDGE] = 0;
	damage[DAM_INDEX_POINT] = 40;
	range = Range_VLKSchwert;
	cond_atr[2] = ATR_DEXTERITY;
	cond_value[2] = Condition_VLKSchwert;
	visual = "ItMw_018_1h_SwordCane_01.3ds";
	on_equip = equip_1h_light_d;
	on_unequip = unequip_1h_light;
	description = name;
	text[0] = "На эфесе выгравирована буква 'Ф.'";
	text[1] = NAME_Damage;
	count[1] = damageTotal;
	text[2] = NAME_Dex_needed;
	count[2] = cond_value[2];
	text[3] = NAME_RADIUS;
	count[3] = range;
	text[4] = NAME_ONEHANDED_PIERCE;
	text[5] = NAME_Value;
	count[5] = value;
};


Формула прямого попадания для оружия ББ со свойствами: damagetype = DAM_EDGE | DAM_POINT


GS = GS(EDGE) + GS(POINT) = (WS[DAM_EDGE] + STR - RS[PROT_EDGE]) + (WS[DAM_POINT] + DEX / 2 + 15 - RS[PROT_POINT]) , GS >= 10


GS = причиненный совокупный ущерб
WS = повреждение оружия
STR/DEX = сила/ловкость (бонус повреждения)
RS = защита вооружения противника


Таким образом формула для шпаги бандита, к. не убивает противника и наносит полный колющий урон, будет выглядеть так:

GS(POINT) = WS[DAM_POINT] + DEX - RS[PROT_POINT]
, где DEX = DEX / 2 + 15 + delta_DEX, отсюда delta_DEX = DEX / 2 - 15

Тогда WS[DAM_POINT] = 30 + DEX / 2 + DEX / 2 - 15 = 15 + DEX

на языке скриптов

otherweap.damage[DAM_INDEX_POINT] = 15 + oth.attribute[ATR_DEXTERITY];


Примечание:
1. Минимальный урон от шпаги повышается до 10.
2. В примере используется делитель SBMODE = 2, он зависит от сложности игры.


Проверка:

1. При типе урона только колющий от "Шпага бандита" для тестового героя с параметрами: ToHit 100%, STR 0, DEX 60, урон по противнику с нулевой защитой от колющего составляет:

GSdex = WS[DAM_POINT] + DEX = (30 + 60 / 2) + 60 = 120 ед.

2. При сочетании двух типов урона, суммарный урон от данной шпаги для тестового героя с ToHit 100%, STR 0, DEX 60, по противнику с нулевой защитой от колющего составляет:

GSstr + GSdex = 5 + (30 + 60 / 2) + (60 / 2 + 15) = 5 + 105 ед.

3. Тогда полный колющий урон составит при условии, что
otherweap.damage[DAM_INDEX_POINT] = 15 + oth.attribute[ATR_DEXTERITY];

GSstr + GSdex = 5 + (15 + 60) + (60 / 2 + 15)) = 5 + 120 ед.


ОШИБКИ ИГРЫ

1. Когда одеваешь вещь "бонус для оружейного навыка", то после снятия остается в навыке 100 - бонус, что приводит к забавной ситуации, при снятии кольца Моргана и ЭльБастарда, когда текущий навык 90% сбрасывается от 100 до 82.

Вот правильный алгоритм снятия
Код:
func void B_AddFightSkill(var C_Npc slf,var int talent,var int percent)
{
	if(talent == NPC_TALENT_1H)
	{
		slf.HitChance[NPC_TALENT_1H] = slf.HitChance[NPC_TALENT_1H] + percent;
		if(slf.HitChance[NPC_TALENT_1H] >= 100)
		{
			slf.HitChance[NPC_TALENT_1H] = 100;
		}
		else if(slf.aivar[REAL_TALENT_1H] > slf.HitChance[NPC_TALENT_1H])
		{
			slf.HitChance[NPC_TALENT_1H] = slf.aivar[REAL_TALENT_1H];
		};
		if(slf.HitChance[NPC_TALENT_1H] >= 60)
		{
			Npc_SetTalentSkill(slf,NPC_TALENT_1H,2);
			Mdl_ApplyOverlayMds(self,"humans_1hST2.mds");
		}
		else if(slf.HitChance[NPC_TALENT_1H] >= 30)
		{
			Npc_SetTalentSkill(slf,NPC_TALENT_1H,1);
			Mdl_ApplyOverlayMds(self,"humans_1hST1.mds");
		}
		else if(slf.HitChance[NPC_TALENT_1H] >= 0)
		{
			Npc_SetTalentSkill(slf,NPC_TALENT_1H,0);
		};
	};

2. Ошибка при активации заклинания "Ловец Души" на монстра, к. слабее героя и старается убежать от него и которого убивает другой персонаж. В таком случае при обыске трупика монстра мы не получаем камень души и не можем кастовать повторно, поскольку не сбросился флаг STONEFIRST = 1.

Ввести дополнительную проверку в скрипты:
spell_waterwall.d - ввести внешнюю переменную VAR, к. просвоить текущий номер монстра, и сделать проверку при касте в виде: if((other.aivar[89] == FALSE) && (STONEFIRST == 0)) || Npc_IsDead(VAR);

B_GiveDeathInv.d - выдать камень души, при self.aivar[89] = TRUE && STONEFIRST = 1.

func void ZS_Dead() - убрать проверку if(Npc_IsPlayer(other)
Код:
    if((self.aivar[89] == TRUE) && (Hlp_GetInstanceID(self) != Hlp_GetInstanceID(soul_ghost)) && (Hlp_GetInstanceID(self) != Hlp_GetInstanceID(ghost_senyak_demon)) && (Hlp_GetInstanceID(self) != Hlp_GetInstanceID(senyak_demon))) 
       { 
        CreateInvItems(self,itmi_stonesoul,1); 
        STONEFIRST = 0;

3. Когда Ищущий призывает монстра, он становится безобидным как овечка, т.к. бросается с кулаками на бойца с 200+ броней.

4. Монстры с атакующей магией, такие как Гарпия, Болотный голем и прочие начинают биться друг с другом, если один из них заденет магией товарища.

5. Багоюз скрижалей
- если не умеешь читать бонусные скрижали, то при непрерывном клике на них, они будут размножаться. Старые таблички для Ватраса так не размножить, на экране возникает рисунок. Если также подправить скрипт для бонусных, то этой ошибки можно будет избежать.

6. На приготовление 30 спец. напитков я затратил всего одну мензурку.

7. Если украсть амулет у Франко, то ему снижают жизнь до 196 ед.
 

sophus

Участник форума
Регистрация
20 Ноя 2010
Сообщения
74
Благодарности
2
Баллы
155
я думал что гильдии будут разрабатыватся на возврвщение 2.0, а не на ребаланс версии 2.1?
 

Ян75

Почетный форумчанин
Регистрация
14 Янв 2009
Сообщения
7.927
Благодарности
2.860
Баллы
735
sophus, как можно разрабатывать мод на основе еще не сделанной версии игры? А Ребаланс2.1 уже готов. Ну и читать надо внимательно - все это указано в описании Гильдий.
Вот выйдет Возвращение2.0 - там и посмотрим. К тому же ряд идей из Гильдий войдут в В2.0.
 
Сверху Снизу