Перейти к содержанию

Pretorius

Граждане
  • Постов

    55
  • Зарегистрирован

  • Посещение

Весь контент Pretorius

  1. Переменная trigger - всего лишь устанавливала ОДНОКРАТНОСТЬ обнуления магии: как только GetDetected = 1, и если trigger и combatOnce равны нулям - то оба устанавливаются в 1 - поскольку trigger дальше не изменяется, то этим обеспечивается однократность обнуления. Проблема оказалась в том, что блоки if-endif на условие таймера должны идти сразу после запуска таймера (timer + GetSecondsPassed) - после такого исправления все стало работать (хотя странно, почему ошибка оказалась в этом: в скриптах, управляющих стихийными бедствиями, я использовал сходные конструкции, и они почти никогда не дают сбоев). Насчет загрузки Магнуса при условии GetJournalIndex - это обычный способ заставить NPC, активатор и т. п. появляться при появлении некоторой записи в журнале - такая конструкция есть в Wizards Islands, и с ней никогда не было ошибок. Эта конструкция весьма стабильна: если есть искомая запись в журнале, то даже установив Магнусу Disable через консоль, он тут же появится снова. Начало битвы с Магнусом - действительно начинается из диалога, когда наивный игрок спешит проинформировать его о своей победе в битве с правителем Аэдра Монотеархом Анурром. Может ли игрок спастись бегством, а затем атаковать ослабленного Магнуса - нет, потому что Мантия Вечности дает ее владельцу постоянную 100-кратную левитацию; и если Магнус игрока и не испепелит на расстоянии (достаточно 2 секунды, даже если здоровье игрока равно 10000), то одного удара его посоха достаточно для уничтожения не то что игрока, но кого бы то ни было (вот почему нужно обнуление магии - чтобы игрок не успел сбежать). Магнус в моем плагине, будучи самым умным и коварным из всех Аэдра, предает Анурра, направляя к нему воскресшего Падомая (понятно в чьем теле...), а под конец решает расправиться и с ним. Поэтому ModFlee нужно - было бы странно, если бы коварный и осторожный Магнус был бы безрассудно храбрым. begin MagnusScript float timer short combatOnce short NoFlee short NoIdle short NoIntruder short noLore short NoThief short trigger if ( MenuMode == 1 ) return endif If ( GetJournalIndex "1_1_1_1" >= 10 ) enable else disable endif if ( combatOnce == 1 ) set timer to ( timer + GetSecondsPassed ) if ( timer >= 10 ) ModFlee 50 SetIntelligence 0 set combatOnce to 0 set timer to 0 endif endif if ( GetTarget, Player == 1 ) if ( combatOnce == 0 ) if ( trigger == 0 ) set combatOnce to 1 set trigger to 1 endif endif endif if ( onDeath == 1 ) PlaySoundVP "endboom2" 1.0, 0.5 StreamMusic "Explore\WIexplore11 - WindPrayer.mp3" endif end MagnusScript
  2. Ниже приведен скрипт, управляющий действиями Аэдра Магнуса: после того, как игрок вступает с ним в бой, Магнус пытается сначала поразить игрока с помощью заклинаний; затем, по истечении 10 секунд, если игрок все еще жив, Магнус должен применить более действенные средства для его уничтожения, для чего его интеллект (и, следовательно, магия) обнуляется. Необходимость такого управления его действиями - обусловлена тем, что у Магнуса есть "Мантия Вечности", которая, помимо всего прочего, увеличивает его интеллект на 9000 и восстанавливает магию 100 (эффект постоянный) - понятно, что умнейший из Аэдра не должен тупо обстреливать заклинаниями игрока, если видит, что это бесполезно. Ошибка заключается в том, что таймер принимает какое-то фиксированное значение до 1 (часто - 0,2000 или 0,9400), и дальше не растет (проверял через sv), так что команды на таймере равном 10 не выполняются (хотя, если приравнять таймер 10 с помощью консоли, все выполняется). В сходном скрипте, управляющем другими Аэдра, также имеется обнуление магии, но там оно вызывается при условии драки с игроком и если один из Аэдра уже уничтожен (GetTarget и GetDeadCount), и там оно работает (хотя те Аэдра имеют сходные мантии) - значит, ошибка связана с таймером. begin MagnusScript float timer short combatOnce short Easing short noLore short trigger if ( MenuMode == 1 ); ошибка вызывается не этим (таймер глючит и при отсутствии этих строк) return endif If ( GetJournalIndex "1_1_1_1" >= 10 ); загрузка после заданного события enable else disable endif if ( timer >= 10 ) if ( Easing == 0 ) ModFlee 50; устрашение живучестью игрока SetIntelligence 0; обнуление магии set Easing to 1 set timer to 0 endif endif if ( combatOnce == 1 ) if ( timer < 10 ); ошибка не вызывается этим (есть и при отсутствии этого условия) set combatOnce to 0 set timer to ( timer + GetSecondsPassed ) endif endif if ( GetTarget, Player == 1 ) if ( combatOnce == 0 ) if ( trigger == 0 ) set combatOnce to 1; запуск ослабления set trigger to 1; однократность ослабления endif endif endif if ( onDeath == 1 ) PlaySoundVP "endboom2" 1.0, 0.5 StreamMusic "Explore\WIexplore11 - WindPrayer.mp3" endif end MagnusScript
  3. Wizard's Islands содержит интересную группу моделей стихийных бедствий (Z_Fire_Rain_Creature, Z_IceFlurry_Creature, Z_Inferno_Creature, Z_LightningStorm_Cr, Z_SonicWave_Creature, Z_Tornado_Creature), которые так и не были использованы в оригинальной игре. Ниже приведен скрипт, загружающий эти модели в игру при MornAssault == 1 (при атаке на Морнхолд Рыцарей Тьмы, посылаемых Священным Советом после уничтожения тирана Хелсета). При приближении игрока к creature, оно должно загружаться, атаковать некоторое время игрока и исчезать до повторного к нему приближения. Проблема заключается в том, что иногда скрипт почему-то работает нестабильно, останавливаясь на исполнении команд DisablePlayerControls и Enable. begin DestructionMournholdScript short Blast short doOnce short Sitisit float timer float damage if ( MenuMode == 1 ) return endif if ( Player->GetHealth <= 0 ) return endif if ( doOnce == 1 ) set doOnce to 0 return endif SetHealth 10000 if ( GetAttacked == 1 ) if ( doOnce == 0 ) SetFight 0 StopCombat Player set doOnce to 1 endif endif if ( MornAssault == 0 ) if ( GetDisabled == 0 ) Disable return elseif ( GetDisabled == 1 ) return endif endif if ( MornAssault == 1 ) if ( CellChanged == 0 ) if ( GetSoundPlaying "DarkFire" == 0 ) PlayLoopSound3DVP "DarkFire" 1.0, 1.0 endif endif endif if ( MornAssault == 1 ) if ( GetDistance Player < 500 ) if ( Blast == 0 ) if ( GetDisabled == 1 ) Enable set Sitisit to 1 elseif ( GetDisabled == 0 ) set Sitisit to 1 endif elseif ( Blast == 1 ) Disable return endif elseif ( GetDistance Player >= 500 ) if ( GetDisabled == 0 ) Disable set Sitisit to 0 set Blast to 0 return elseif ( GetDisabled == 1 ) set Sitisit to 0 set Blast to 0 return endif endif endif if ( Sitisit == 1 ) if ( timer >= 10 ) if ( Blast == 0 ) EnablePlayerControls set Blast to 1 set timer to 0 endif endif endif if ( Sitisit == 1 ) if ( timer < 10 ) if ( Blast == 0 ) DisablePlayerControls set timer to ( timer + GetSecondsPassed ) set damage to -500 set damage to ( damage * GetSecondsPassed ) Player->ModCurrentHealth, damage PlayGroup, Idle endif endif endif end DestructionMournholdScript
  4. Удаление GetDetected действительно помогло, хотя, к сожалению, несколько нарушило план моего квеста (теперь Кагренак обращается к игроку, хотя тот еще не наткнулся на него в лабиринте). Вторая же проблема оказалась связана всего лишь с тем, что функция OnPCHitMe принимает только два значения (1 \ 0); установив поэтапную модификацию countHits на + 1 всякий раз, когда OnPCHitMe принимала значение 1, скрипт моделирования процессов Сердца Лорхана все-таки удалось привести в работоспособное состояние, и теперь он работает как часы!! begin KagrenakField short Compression short countHits short doOnce short keeningHit short Release short sunderHit if ( MenuMode == 1 ) return endif if ( GetDistance Player < 1000 ) if ( doOnce == 0 ) ForceGreeting set doOnce to 1 endif endif if ( CellChanged == 0 ) if ( Release < 5 ) if ( GetSoundPlaying "Jarktlom" == 0 ) PlayLoopSound3DVP "Jarktlom", 1.0, 1.0 endif elseif ( Release == 5 ) if ( GetSoundPlaying "Jarktlom" == 1 ) StopSound "Jarktlom" endif endif endif if ( Release < 5 ) if ( GetHealth < 65535 ) SetHealth 65535 endif endif ;Сердце Лорхана изолирует Кагренака от Плеромона. set sunderHit to HitOnMe "Sunder" set keeningHit to HitOnMe "Keening" if ( sunderHit == 1 ) if ( Release == 0 ) set Release to 1 set sunderHit to 0 elseif ( Release > 0 ) set sunderHit to 0 endif endif ;Разделитель фокусирует Щит Сердца. if ( keeningHit == 1 ) set countHits to ( countHits + 1 ) set keeningHit to 0 endif ;Разрубатель сжимает Щит Сердца. if ( Compression == 1 ) set Compression to 0 set Release to ( Release + 1 ) return endif if ( countHits == 0 ) if ( GetSpell "dagoth_ur_shield_01" == 0 ) AddSpell "dagoth_ur_shield_01" endif endif ;Физическое проявление действия Сердца. if ( countHits == 1 ) if ( Release == 1 ) if ( GetSpell "dagoth_ur_shield_01" == 1 ) PlaySound3DVP "hearthit1" 1.0, 1.0 RemoveSpell "dagoth_ur_shield_01" AddSpell "dagoth_ur_shield_02" set Compression to 1 endif endif endif if ( countHits == 2 ) if ( Release == 2 ) if ( GetSpell "dagoth_ur_shield_02" == 1 ) PlaySound3DVP "hearthit2" 1.0, 1.0 RemoveSpell "dagoth_ur_shield_02" AddSpell "dagoth_ur_shield_03" set Compression to 1 endif endif endif if ( countHits == 3 ) if ( Release == 3 ) if ( GetSpell "dagoth_ur_shield_03" == 1 ) PlaySound3DVP "hearthit3" 1.0, 1.0 RemoveSpell "dagoth_ur_shield_03" AddSpell "dagoth_ur_shield_04" set Compression to 1 endif endif endif if ( countHits == 4 ) if ( Release == 4 ) if ( GetSpell "dagoth_ur_shield_04" == 1 ) PlaySound3DVP "hearthit4" 1.0, 1.0 RemoveSpell "dagoth_ur_shield_04" set Compression to 1 endif endif endif ;Возможность освобождения - после полной компактификации Щита Сердца. if ( OnDeath == 1 ) PlaySoundVP "endboom2" 1.0, 0.5 StreamMusic "Special\MW_Triumph.mp3" endif end KagrenakField
  5. Привожу полный текст проблемного скрипта, который, по идее, должен имитировать на созданном creature "Кагренак" (модель пепельного вампира, голоса – от лича) процессы, идентичные процессам с Сердцем Лорхана: begin KagrenakField short sunderHit short keeningHit short doOnce short Release if ( MenuMode == 1 ) return endif if ( GetDistance Player < 1000 ) if ( GetDetected, Player == 1 ) if ( doOnce == 0 ) ForceGreeting set doOnce to 1 endif endif endif if ( CellChanged == 0 ) if ( Release < 5 ) if ( GetSoundPlaying "Jarktlom" == 0 ) PlayLoopSound3DVP "Jarktlom", 1.0, 1.0 endif elseif ( Release == 5 ) if ( GetSoundPlaying "Jarktlom" == 1 ) StopSound "Jarktlom" endif endif endif if ( Release < 5 ) if ( GetHealth < 65535 ) SetHealth 65535 endif endif ;Сердце Лорхана изолирует Кагренака от Плеромона. set sunderHit to HitOnMe Sunder if ( sunderHit == 1 ) if ( Release == 0 ) set Release to 1 set sunderHit to 0 elseif ( Release > 0 ) set sunderHit to 0 endif endif if ( Release > 0 ) set keeningHit to HitOnMe Keening endif ;Разделитель позволяет освободить Кагренака. if ( keeningHit == 0 ) if ( GetSpell "dagoth_ur_shield_01" == 0 ) AddSpell "dagoth_ur_shield_01" endif endif ;Физическое проявление действия Сердца. if ( keeningHit == 1 ) if ( Release == 1 ) if ( GetSpell "dagoth_ur_shield_01" == 1 ) PlaySound3DVP "hearthit1" 1.0, 1.0 RemoveSpell "dagoth_ur_shield_01" AddSpell "dagoth_ur_shield_02" set Release to 2 endif endif endif if ( keeningHit == 2 ) if ( Release == 2 ) if ( GetSpell "dagoth_ur_shield_02" == 1 ) PlaySound3DVP "hearthit2" 1.0, 1.0 RemoveSpell "dagoth_ur_shield_02" AddSpell "dagoth_ur_shield_03" set Release to 3 endif endif endif if ( keeningHit == 3 ) if ( Release == 3 ) if ( GetSpell "dagoth_ur_shield_03" == 1 ) PlaySound3DVP "hearthit3" 1.0, 1.0 RemoveSpell "dagoth_ur_shield_03" AddSpell "dagoth_ur_shield_04" set Release to 4 endif endif endif if ( keeningHit == 4 ) if ( Release == 4 ) if ( GetSpell "dagoth_ur_shield_04" == 1 ) PlaySound3DVP "hearthit4" 1.0, 1.0 RemoveSpell "dagoth_ur_shield_04" set Release to 5 endif endif endif ;Возможность освобождения - после полной компактификации Щита Сердца. if ( keeningHit > 4 ) if ( Release == 5 ) set keeningHit to 4 endif endif if ( OnDeath == 1 ) PlaySoundVP "endboom2" 1.0, 0.5 StreamMusic "Special\MW_Triumph.mp3" endif end KagrenakField Исследование реализации в игре этого скрипта (TGM и последовательные удары Разделителем и Разрубателем с проверкой переменных через sv) дало следующие результаты: В исходном состоянии Кагренака: sunderHit == 0, keeningHit == 0, doOnce == 0, Release == 0. Звук "Jarktlom" проигрывается, огненный щит имеется, здоровье действительно принудительно равно 65535. Однако, команда ForceGreeting не выполняется; даже если игрок заговорит с Кагренаком сам, переменная doOnce по-прежнему == 0. После первого удара Разделителем: sunderHit == 0, keeningHit == 0, doOnce == 0, Release == 1. То есть здесь все в порядке. После второго удара Разделителем: sunderHit == 0, keeningHit == 0, doOnce == 0, Release == 1. То есть здесь все в порядке. После первого удара Разрубателем: sunderHit == 0, keeningHit == 0, doOnce == 0, Release == 2. ПРОБЛЕМЫ С ИМИТАЦИЕЙ ПРОЦЕССА СЕРДЦА ЛОРХАНА НАЧИНАЮТСЯ ЗДЕСЬ. Ледяной щит все-таки появляется, но и огненный не исчезает, и звук "hearthit1" не проигрывается. После второго удара Разрубателем: sunderHit == 0, keeningHit == 0, doOnce == 0, Release == 2. У Кагренака по-прежнему остаются огненный и ледяной щиты, т.е. на дальнейшие удары Разрубателем он вообще никак не реагирует. (Примечание: если через консоль ввести Кагренаку SetHealth 0, то условия на OnDeath == 1 все же выполняются).
×
×
  • Создать...