//---------------------------------------
// CONSTANTS
//---------------------------------------
const int SPL_TRANSFORM = 3;
const string SPL_DAMAGE_TEXT = "Урон: ";
const string SPL_DAMAGEPL_TEXT = "Урон за уровень: ";
const string SPL_COST_TEXT = "Стоимость: ";
const string SPL_COSTPL_TEXT = "Стоимость за уровень: ";
const string SPL_ENERGYTYPE = "Энергия: ";
const string SPL_HP = "Здоровье";
const string SPL_MP = "Мана";
const int SPL_DEFAULT = 0; //is DEFAULT spell
const int SPL_AREA = 1; //is area spell
const int SPL_SPREAD = 2; //is spread spell
//---------------------------------------
// CLASSES
//---------------------------------------
class C_SPELL_DATA
{
var string instName; //oCSpell objectname UNIQUE!
var int spellID; //unique spell ID > 500!
var string spellName; //Display name
var string spellAniName; //Cast animation
var string visualFxName; //VisualFX
var int damage; //Spell damage
var int cost; //Cost for rune
var int energyType; //Energy type
var int EffectType; //area/spread
};
//---------------------------------------
// PROTOTYPES
//---------------------------------------
PROTOTYPE C_SPL_DATA(C_SPELL_DATA)
{
instName = "Light";
spellID = 0;
spellName = "SPL_XXX";
spellAniName = "FBT";
visualFxName = "Light";
damage = 0;
cost = 0;
energyType = ATR_MANA;
EffectType = SPL_DEFAULT;
};
prototype NEW_Rune(C_Item)
{
name = "Руна";
mainflag = ITEM_KAT_RUNE;
flags = 0;
material = MAT_GLAS;
wear = WEAR_EFFECT;
effect = "";
text[1] = NAME_Manakosten;
text[5] = NAME_Value;
COUNT[5] = value;
};
const int SPL_FireRainN = 515;
const int SPL_Cost_Firerain = 15;
const int SPL_Damage_FireRain = 5;
//---------------------------------------
// Spell data instance
//---------------------------------------
instance Spell_FireRain_data (C_SPL_DATA)
{
instName = "Firerain";
spellID = SPL_FireRainN;
spellName = "Огненый дошть";
spellAniName = "HEA";
visualFxName = "FireRain";
damage = 10;
cost = SPL_Cost_Firerain;
energyType = ATR_MANA;
EffectType = SPL_AREA;
};
//---------------------------------------
// Spell Item
//---------------------------------------
instance ItRu_FireRain(C_Item)
{
name = NAME_Rune;
mainflag = ITEM_KAT_RUNE;
flags = 0;
value = 0;
visual = "ItRu_FireRain.3DS";
material = MAT_STONE;
spell = SPL_FireRainN;
wear = WEAR_EFFECT;
effect = "SPELLFX_WEAKGLIMMER_YELLOW";
description = "FireRain";
};
instance Spell_FireRain(C_Spell_Proto)
{
time_per_mana = 0;
damage_per_level = SPL_Damage_FireRain;
damagetype = DAM_MAGIC;
targetCollectAlgo = TARGET_COLLECT_ALL;
targetCollectRange = 100000;
isMultiEffect = TRUE;
};
func int Spell_Logic_Firerain(var int manaInvested)
{
if(Npc_GetActiveSpellIsScroll(self) && (self.attribute[ATR_MANA] >= SPL_Cost_Scroll))
{
return SPL_SENDCAST;
}
else if(self.attribute[ATR_MANA] >= SPL_Cost_Firerain)
{
return SPL_SENDCAST;
}
else
{
return SPL_SENDSTOP;
};
};
func void Spell_Cast_Firerain()
{
if(Npc_GetActiveSpellIsScroll(self))
{
self.attribute[ATR_MANA] = self.attribute[ATR_MANA] - SPL_Cost_Scroll;
}
else
{
self.attribute[ATR_MANA] = self.attribute[ATR_MANA] - SPL_Cost_Firerain;
};
self.aivar[AIV_SelectSpell] += 1;
};
func int Spell_Collide_515()
{
if(self.guild < GIL_SEPERATOR_HUM)
{
var string msg;
msg = Str_Format("%s[%i] Spell_Collide_515", self.name, self.id);
Hlp_PrintConsole(msg);
};
return COLL_DOEVERYTHING;
};
"STM" // SPL_Thunderstorm
"WHI" // SPL_Whirlwind
"MSD" // SPL_MassDeath
"SLE" // SPL_Light
"SLE" // SPL_Sleep
"SLE" // SPL_Shrink
"SLE" // SPL_Inflate
"HEA" // SPL_TeleportXardas
"HEA" // SPL_FullHeal
"FBT" // SPL_PalHolyBolt
"FBT" // SPL_Firebolt
"FBT" // SPL_Icebolt
"FBT" // SPL_Zap
"FBT" // SPL_IceLance
"FBT" // SPL_Plague
"FBT" // SPL_Swarm
"FIB" // SPL_DestroyUndead
"FIB" // SPL_ChargeFireball
"FIB" // SPL_ChargeZap
"FIB" // SPL_BreathOfDeath
"FIB" // SPL_Charm
"FIB" // SPL_MasterOfDisaster
"SUM" // SPL_SummonGoblinSkeleton
"SUM" // SPL_SummonDemon
"SUM" // SPL_ArmyOfDarkness
"TRF" // SPL_TrfSheep
"TRF" // SPL_TrfDragonSnapper
"WND" // SPL_WindFist
"WND" // SPL_LightningFlash
"WND" // SPL_SuckEnergy
"WND" // SPL_Skull
"WND" // SPL_Geyser
"FEA" // SPL_IceWave
"FEA" // SPL_Firerain
"FEA" // SPL_Waterwall
"FEA" // SPL_Fear
"FEA" // SPL_Earthquake
"FRZ" // SPL_IceCube
"FRZ" // SPL_GreenTentacle
C_CanNpcCollideWithSpell определяет, как будет реагировать конкретный npc, когда в него попадет конкретное заклинание.
COLL_DONOTHING - заклинание не подействует. Например, нельзя поджечь плывущего NPC.
COLL_DOEVERYTHING - полноценный обычный эффект. Полный урон, заморозка, горение и т.д.
COLL_APPLYDAMAGE - заклинание нанесет урон, но не будет вызван обработчик PERC_ASSESSMAGIC, т.е. не будет сопутствующих эффектов. Каменного голема нельзя заморозить или поджечь, охранник не взлетит в смерче.
COLL_APPLYHALVEDAMAGE - то же, плюс будет нанесена только половина урона (огненный шар на огненного голема).
COLL_APPLYDOUBLEDAMAGE - то же, но урон удвоенный (огонь против льда).
COLL_APPLYVICTIMSTATE - предположу, что как COLL_APPLYDAMAGE, но npc запомнит, что на него напали с магией (иначе реагирует как на обычное повреждение). Не используется, может и не работает.
COLL_DONTKILL - в результате действия заклинания npc не умирает, а падает без сознания (кулак ветра, воды, молния)
Флаг позволяет наложить дополнительный визуальный эффект на цель, заданный как emFXCollDynPerc_S (магическое горение, например).COLL_APPLYVICTIMSTATE - предположу, что как COLL_APPLYDAMAGE, но npc запомнит, что на него напали с магией (иначе реагирует как на обычное повреждение). Не используется, может и не работает.
попробовал огненный дождь. в Spell_Collide_515 зашёл один и тот же НПС.
что то не понял на что это влияет это проверка на то может ли нпс экипировать руну?var int cost; //Cost for rune
const int spellID_TeleportADWENTRANC = 666; // должно быть более 500
instance ItRu_TeleportADWENTRANCE (C_Item)
{
ItRu_PalTeleportSecret();
visual = "ItAr_Rune_40.3ds";
spell = spellID_TeleportADWENTRANC;
};
instance Spell_Teleport_data(C_SPELL_DATA)
{
instName = "zTeleportADWENTRANCE"; // инстанция Spell_zTeleportADWENTRANCE
spellID = spellID_TeleportADWENTRANC; // ID. должно быть больше 500
spellName = NAME_SPL_PalTeleportSecret; // отображается на экране при переключение заклинаний
spellAniName = "HEA"; // "STM" "WHI" "MSD" "SLE" "HEA" "FBT" "FIB" "SUM" "TRF" "FEA" "FRZ"
visualFxName = "Teleport"; // spellFX_Teleport из файла VisualFxInst.d
damage = 0; // !!! урон !!!
cost = SPL_COST_TELEPORT; // хз что
energyType = ATR_MANA; // требует ману. может требовать жизни и хз что ещё
EffectType = zSPL_DEFAULT; // zSPL_DEFAULT или zSPL_AREA или zSPL_SPREAD или zSPL_TRANSFORM
};
// ------ Instanz fьr alle Teleport-Spells ------
INSTANCE Spell_zTeleportADWENTRANCE(C_Spell_Proto)
{
Spell_Teleport();
time_per_mana = 300; // Время в мс, требуемое для инвестирования 1 единицы маны?
};
func int Spell_Logic_zTeleportADWENTRANCE(var int manaInvested)
{
//if (manaInvested ==0 ) { return SPL_NEXTLEVEL; }; // "классичесий" вариант.
if (manaInvested == 0) { Spl_InvestNext(self); }; // "новый" вариант 1
//Spl_SetLevel(self,1); // "новый" вариант 2. для телепорта плохо
if (manaInvested > SPL_Cost_Teleport)
{
return SPL_SENDCAST;
};
return SPL_RECEIVEINVEST;
};
func void Spell_Cast_zTeleportADWENTRANCE()
{
if (CurrentLevel == ADDONWORLD_ZEN)
{
AI_Teleport (self, "ADW_ENTRANCE");
}
else if (CurrentLevel != DRAGONISLAND_ZEN)
{
Wld_ChangeLevel ("ADDON\ADDONWORLD.zen","ADW_ENTRANCE");
}
else
{
PrintScreen (PRINT_TeleportTooFarAway ,-1,YPOS_LevelUp,FONT_ScreenSmall,2);
};
AI_PlayAni (self, "T_HEASHOOT_2_STAND" );
};
time_per_mana встречается почти во всех заклинаниях Готики 1 и отвечает за скорость инвестирования маны. то есть сколько миллисекунд уйдёт на инвестирование 1 единицы маны.time_per_mana - благополучно не упоминается в гайдах, но, так как величина, отличная от 0 в этой строке встречается только в заряжаемых заклинаниях (типа Большого огненного шара или Кулака ветра), то, вероятно, отвечает за скорость расхода маны при зарядке каждой стадии; и это вряд ли секунды.
PROTOTYPE C_Spell_Proto(C_Spell) {
time_per_mana = 500; // Zeit pro investierten Manapunkt (ms)
в приведенном мною Spell_Logic ману отнимает движок. делает он это с определённой "скоростью", за эту "скорость" отвечает time_per_mana. что бы мана отнималась синхронно с анимацией каста я установил time_per_mana = 300. Можно поставить меньше. Можно поставить больше. Ставить 0 это халтура.В заклинаниях без зарядки, таких как телепорт - ставь там 0.
это на какое количество маны: 5, 10? сколько там анимация каста длится?я установил time_per_mana = 300
300 мс на 1 ману. 3000 мс на 10 маны. анимация подготовки к телепорту длинная: 2 с лишнем секунды.это на какое количество маны: 5, 10? сколько там анимация каста длится?
что значит "такое себе решение"? это оригинальная механика. хочешь делай халтурно и используй как ты и рекомендуешь time_per_mana = 0. в таком случае вся мана инвестируется мгновенно, а потом герой с уже потраченной манной будет делать вид что он якобы её тратит. хочешь разбирайся и определяй сколько времени требуется для того или иного заклинание на инвестирование единицы маны.Ну, такое себе решение с практической точки зрения
твоё право как автора делать модификацию такой какой тебе хочется. хочется тебе сделать 100 заклинаний за 10 минут - пожалуйста. и у такого принципа найдутся поклонники и сторонники. Мне лично нравится решение ElderGamer где увеличивается скорость инвестирования маны для свитков трансформации требующих много маны. и мне вообще нравится скрипты ElderGamer как раз потому что он вручную прорабатывает различные аспекты и ситуации, тратя на это колоссальное кол-во времени и сил. Я считаю что доработка логики с сохранением принципа это правильный путь. То есть когда есть общее понимание что заклинание не произносится мгновенно, а НПС инвестирует ману в него. и когда баланс меняет кол-венные показатели маны, увеличивая требования маны, можно увеличить и скорость инвестирования маны. И вот как раз для "сложных" свитков трансформации ElderGamer это и сделал. Что-то подобное я писал и для заклинания "контроль", изменяя скорость инвестирования маны в зависимости от того какой уровень у жертвы. Но это всё подразумевает "вручную корпеть", а в этом ты не видишь практического смысла :-DС практической точки зрения, на мой взгляд, смысла в том, чтобы вручную корпеть над тем, сколько длится анимация каждого конкретного заклинания такого типа и подстраивать инвестирование маны под него - нет.
понятия не имею. заметишь ли ты или нет. я думаю ты можешь придумать и реализовать такую ситуацию, при которой что то будет не заметно, а что то наоборот крайне заметно.У ГГ 400 маны, а свиток телепорта требует 5 - я замечу правильный расход маны на каст?
если ты про мой пример, то он сделан под руну телепорта и проверка в коде на то используется ли свиток отсутствует, ровно как и отсутствует инстанция свитка. таким образом отвечая на твой вопрос: да, эта ситуация учтена, в примере свиток телепорта отсутствует, отсутствует он осознанно.Свиток телепорта требует 5 маны, руна телепорта требует 50 маны - ситуация учтена в заклинании?
если в процессе инвестирования герой не сделает каст, то заклинание не состоится, при этом некоторое кол-во маны будет потрачено. "прервёт" заклинание движок и сделает это корректно, то есть мана не станет отрицательной и/или герой не зависит. если отнимать ману скриптами без доп проверок мана может стать отрицательной.Если в процессе инвестирования ГГ потеряет часть маны из-за внешних факторов (какие-нибудь проклятия или выжигания маны) - каст прервется? И насколько корректно прервется?
скорость инвестирования маны это не про механику магии ? а что это тогда? ненужная хрень из готики 1?Речи о механиках не было вообще.