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

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

Gothic ½ Конструктор заклинаний | zSpells

Saturas


Модостроитель
Регистрация
11 Фев 2009
Сообщения
2.512
Благодарности
1.334
Баллы
315
Так крч, обновил плагин, теперь коллизии заклинаний работают как надо, впереди обновление до г1(МОЖЕТ БЫТЬ)
Свежая версия в ресурс менеджере
 

Saturas


Модостроитель
Регистрация
11 Фев 2009
Сообщения
2.512
Благодарности
1.334
Баллы
315
Прилетела еще одна обнова, суть в том что спеллы выше индекса 100 не определялись как Projectile и в следствии этого шли без коллизии, скоро зальем в менеджер
 

Saturas


Модостроитель
Регистрация
11 Фев 2009
Сообщения
2.512
Благодарности
1.334
Баллы
315
Новое обновление:
Теперь старые заклинания совсем отделены от новых и работают согласно стандартной логики движка игры
Новые заклинания теперь имеют дополнительные параметры для определения типа спела
Выбор типа заклинания по области ( как волна смерти) так и выбор типа с осколками ( как малая огненая буря)
Добавлена переменная определяющая типа заклинания
EffectType SPL_AREA or SPL_SPREAD




Daedalus:
//---------------------------------------
// 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;
};



Daedalus:
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;
};
 
Последнее редактирование:

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.001
Благодарности
971
Баллы
295
попробовал огненный дождь. в Spell_Collide_515 зашёл один и тот же НПС.
Daedalus:
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;
};

1670126141167.png
 
Последнее редактирование:

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.001
Благодарности
971
Баллы
295
spellAniName из G2NotR
  • "STM"
  • "WHI"
  • "MSD"
  • "SLE"
  • "HEA"
  • "FBT"
  • "FIB"
  • "SUM"
  • "TRF"
  • "FEA"
  • "FRZ"

Daedalus:
   "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
Пост автоматически объединён:

значения return из G2NotR для функции Spell_Collide_***

C_CanNpcCollideWithSpell определяет, как будет реагировать конкретный npc, когда в него попадет конкретное заклинание.

COLL_DONOTHING - заклинание не подействует. Например, нельзя поджечь плывущего NPC.
COLL_DOEVERYTHING - полноценный обычный эффект. Полный урон, заморозка, горение и т.д.
COLL_APPLYDAMAGE - заклинание нанесет урон, но не будет вызван обработчик PERC_ASSESSMAGIC, т.е. не будет сопутствующих эффектов. Каменного голема нельзя заморозить или поджечь, охранник не взлетит в смерче.
COLL_APPLYHALVEDAMAGE - то же, плюс будет нанесена только половина урона (огненный шар на огненного голема).
COLL_APPLYDOUBLEDAMAGE - то же, но урон удвоенный (огонь против льда).
COLL_APPLYVICTIMSTATE - предположу, что как COLL_APPLYDAMAGE, но npc запомнит, что на него напали с магией (иначе реагирует как на обычное повреждение). Не используется, может и не работает.
COLL_DONTKILL - в результате действия заклинания npc не умирает, а падает без сознания (кулак ветра, воды, молния)
 
Последнее редактирование:

Slavemaster


Модостроитель
Регистрация
10 Июн 2019
Сообщения
1.082
Благодарности
1.901
Баллы
320
COLL_APPLYVICTIMSTATE - предположу, что как COLL_APPLYDAMAGE, но npc запомнит, что на него напали с магией (иначе реагирует как на обычное повреждение). Не используется, может и не работает.
Флаг позволяет наложить дополнительный визуальный эффект на цель, заданный как emFXCollDynPerc_S (магическое горение, например).
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.001
Благодарности
971
Баллы
295
var int cost; //Cost for rune
что то не понял на что это влияет :) это проверка на то может ли нпс экипировать руну?
Пост автоматически объединён:

а можно добавить Spell_Collide_666 информацию о том какого уровня было заклинание ? Gratt это реализовал в рамках OnDamage_Hit
 
Последнее редактирование:

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.001
Благодарности
971
Баллы
295
пример нового телепорт сделанного с помощью zSpells.
Daedalus:
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" );
};
про переключения уровня смотри тут https://worldofplayers.ru/threads/42298/post-1163067
 

WoOliN

Участник форума
Регистрация
13 Окт 2012
Сообщения
347
Благодарности
196
Баллы
210
SPL_COST_TELEPORT - это константа, которая определяет количество требуемой на активацию маны (в данном случае ее, раз energyType = ATR_MANA),
величина задана в оригинальных скриптах, там же можно и поменять.

time_per_mana - благополучно не упоминается в гайдах, но, так как величина, отличная от 0 в этой строке встречается только в заряжаемых заклинаниях (типа Большого огненного шара или Кулака ветра), то, вероятно, отвечает за скорость расхода маны при зарядке каждой стадии; и это вряд ли секунды.
В заклинаниях без зарядки, таких как телепорт - ставь там 0.
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.001
Благодарности
971
Баллы
295
мой комментарий "ХЗ что" касался не SPL_COST_TELEPORT, а cost из C_SPELL_DATA. собственно 31 сообщение именного про него. Думаю Saturas когда нибудь расскажет где это значение используется, может при экипировки руны / свитка.

time_per_mana - благополучно не упоминается в гайдах, но, так как величина, отличная от 0 в этой строке встречается только в заряжаемых заклинаниях (типа Большого огненного шара или Кулака ветра), то, вероятно, отвечает за скорость расхода маны при зарядке каждой стадии; и это вряд ли секунды.
time_per_mana встречается почти во всех заклинаниях Готики 1 и отвечает за скорость инвестирования маны. то есть сколько миллисекунд уйдёт на инвестирование 1 единицы маны.
Daedalus:
PROTOTYPE C_Spell_Proto(C_Spell) {
    time_per_mana        =    500;            // Zeit pro investierten Manapunkt (ms)

В заклинаниях без зарядки, таких как телепорт - ставь там 0.
в приведенном мною Spell_Logic ману отнимает движок. делает он это с определённой "скоростью", за эту "скорость" отвечает time_per_mana. что бы мана отнималась синхронно с анимацией каста я установил time_per_mana = 300. Можно поставить меньше. Можно поставить больше. Ставить 0 это халтура.
 
Последнее редактирование:

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.001
Благодарности
971
Баллы
295
это на какое количество маны: 5, 10? сколько там анимация каста длится?
300 мс на 1 ману. 3000 мс на 10 маны. анимация подготовки к телепорту длинная: 2 с лишнем секунды.
 

WoOliN

Участник форума
Регистрация
13 Окт 2012
Сообщения
347
Благодарности
196
Баллы
210
Ну, такое себе решение с практической точки зрения: подгонять скорость расхода под каждую анимацию и конкретные требования свитка/руны (а они могут разниться), еще и учитывая, что требования по мане сами по себе слишком мизерные и постепенный расход просто не будет заметен при общем запасе маны от 100 и выше.
Но познавательно, спасибо.
 

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.001
Благодарности
971
Баллы
295
Ну, такое себе решение с практической точки зрения
что значит "такое себе решение"? это оригинальная механика. хочешь делай халтурно и используй как ты и рекомендуешь time_per_mana = 0. в таком случае вся мана инвестируется мгновенно, а потом герой с уже потраченной манной будет делать вид что он якобы её тратит. хочешь разбирайся и определяй сколько времени требуется для того или иного заклинание на инвестирование единицы маны.

Я сделал ряд заклинаний с использованием zSpells, а тут выложил Телепорт для примера. Телепорт написал таким каким он должен быть: без отнимание маны скриптами с равномерным инвестированием маны. Это пример. Считаешь что "правильно" делать time_per_mana = 0 и отнимать ману скриптами, потому что это быстрее и т.д. - пожалуйста:) Делай как считаешь нужным. Но это не повод наводить тень на плетень на оригинальные механики.
 

WoOliN

Участник форума
Регистрация
13 Окт 2012
Сообщения
347
Благодарности
196
Баллы
210
Пара причин "такого себе решения" с практической точки зрения указана выше.
С практической точки зрения, на мой взгляд, смысла в том, чтобы вручную корпеть над тем, сколько длится анимация каждого конкретного заклинания такого типа и подстраивать инвестирование маны под него - нет.
Речи о механиках не было вообще.

Ситуация (а):
У ГГ 400 маны, а свиток телепорта требует 5 - я замечу правильный расход маны на каст?

Ситуация (б):
Свиток телепорта требует 5 маны, руна телепорта требует 50 маны - ситуация учтена в заклинании?

Ситуация (в):
Если в процессе инвестирования ГГ потеряет часть маны из-за внешних факторов (какие-нибудь проклятия или выжигания маны) - каст прервется? И насколько корректно прервется?
 
Последнее редактирование:

MW 7


Модостроитель
Регистрация
26 Мар 2004
Сообщения
2.001
Благодарности
971
Баллы
295
С практической точки зрения, на мой взгляд, смысла в том, чтобы вручную корпеть над тем, сколько длится анимация каждого конкретного заклинания такого типа и подстраивать инвестирование маны под него - нет.
твоё право как автора делать модификацию такой какой тебе хочется. хочется тебе сделать 100 заклинаний за 10 минут - пожалуйста. и у такого принципа найдутся поклонники и сторонники. Мне лично нравится решение ElderGamer где увеличивается скорость инвестирования маны для свитков трансформации требующих много маны. и мне вообще нравится скрипты ElderGamer как раз потому что он вручную прорабатывает различные аспекты и ситуации, тратя на это колоссальное кол-во времени и сил. Я считаю что доработка логики с сохранением принципа это правильный путь. То есть когда есть общее понимание что заклинание не произносится мгновенно, а НПС инвестирует ману в него. и когда баланс меняет кол-венные показатели маны, увеличивая требования маны, можно увеличить и скорость инвестирования маны. И вот как раз для "сложных" свитков трансформации ElderGamer это и сделал. Что-то подобное я писал и для заклинания "контроль", изменяя скорость инвестирования маны в зависимости от того какой уровень у жертвы. Но это всё подразумевает "вручную корпеть", а в этом ты не видишь практического смысла :-D

У ГГ 400 маны, а свиток телепорта требует 5 - я замечу правильный расход маны на каст?
понятия не имею. заметишь ли ты или нет. я думаю ты можешь придумать и реализовать такую ситуацию, при которой что то будет не заметно, а что то наоборот крайне заметно.

Свиток телепорта требует 5 маны, руна телепорта требует 50 маны - ситуация учтена в заклинании?
если ты про мой пример, то он сделан под руну телепорта и проверка в коде на то используется ли свиток отсутствует, ровно как и отсутствует инстанция свитка. таким образом отвечая на твой вопрос: да, эта ситуация учтена, в примере свиток телепорта отсутствует, отсутствует он осознанно.

Если в процессе инвестирования ГГ потеряет часть маны из-за внешних факторов (какие-нибудь проклятия или выжигания маны) - каст прервется? И насколько корректно прервется?
если в процессе инвестирования герой не сделает каст, то заклинание не состоится, при этом некоторое кол-во маны будет потрачено. "прервёт" заклинание движок и сделает это корректно, то есть мана не станет отрицательной и/или герой не зависит. если отнимать ману скриптами без доп проверок мана может стать отрицательной.

Речи о механиках не было вообще.
скорость инвестирования маны это не про механику магии ? а что это тогда? ненужная хрень из готики 1?
 
Последнее редактирование:
Сверху Снизу