Boblen Опубликовано 24 августа, 2005 Жалоба Поделиться Опубликовано 24 августа, 2005 (изменено) Приступим, пожалуй. Думаю все скриптеры знают, что язык ТЕС3 далек от совершенства и таит в себе множество подводных камней. И чтобы не споткнуться о них - я решил создать эту тему. 1. Количество переменных. Ну их может быть очень много, однако подвох есть и здесь. Это 34 переменная одного типа (short, float, long - неважно). Она зачастую принимает неверные и странные значения, так что если ваш скрипт использует много переменных - не используйте 34 по счету. По объяснению cdcooley на оф.форуме это происходит из-за того, что ASCII код 34 символа - кавычка и именно она часто записывается в переменную вместо нужного значения. 2. Очередность исполнения скриптов. Все скрипты ставятся в очередь по мере их появления, однако если в скрипте используется команда Startscript, чтобы запустить новый глобальный скрипт, то вся очередь сбрасывается на начало и прогоняется еще раз. Подробнее об этом можно почитать на оф.форуме в этом постеЗдесь приведу краткий перевод:Имеем:1 локальный объект A со скриптом1 самозавершающийся глоб.скрипт B1 самозавершающийся глоб.скрипт C1 всегда работающий глоб.скрипт D Что должно быть:1. A работает и стартует скрипт B2. D работает3. B работает и стартует скрипт C4. C работает Что, я думаю, происходит на самом деле:1. A работает и запускает скрипт B2. D работает3. B работает и запускает скрипт C4. D работает5. C работает или что-то в этом роде. Я предполагаю, что использование startscript заставляет Морроувинд заново проработать список глоб.скриптов, включая те, что уже работали ранее. Graphite posted, 07/16/04 03:25 AM Я думал, совпадают ли виденные мной результаты с тем, как ты предполагаешь это работает и решил провести тест. Я создал 2 глоб.переменных с названиями test_global и test_local. Затем написал следующие 4 скрипта: begin script_A short state set test_local to test_local + 1 if ( state == 1 ) startScript "script_B" set state to 0 endif end begin script_B stopScript "script_B" startScript "script_C" end begin script_C stopScript "script_C" end begin script_D short temp set test_global to test_global + 1 set temp to test_global - test_local MessageBox "counter-difference: %g " temp end Script D был добавлен в стартовые скрипты. Script A был приаттачен к контейнеру и помещен в игру. Теперь получалось, что script A увеличивает "local" счетчик, а script D увеличивает "global" счетчик перед тем, как показать разницу между ними.Теперь, если мое предположение верно, разница останется постоянной, т.к. script A работает также часто, как script D. Если верно мое наблюдение, то это значение будет меняться каждый раз, как я меняю значение переменной state на 1, потому что script D будет работать чаще, чем script A. Я вошел в игру и получил: counter-difference: 0counter-difference: 0counter-difference: 0 Кажется все нормально... оба скрипта заработали водно и то же время. Я открыл консоль, выбрал ящик и ввел "set state to 1". counter-difference: 2counter-difference: 2counter-difference: 2 Сделал это еще раз: counter-difference: 4counter-difference: 4counter-difference: 4 Это указывает на то, что script D работает дважды всякий раз, как я меняю state на 1. Еще раз, я считаю, что порядок работы такой A, D, B, D, C, D, а после снова A, D, A, D, A, ... 3. О работе команд if-endif и if-elseif-endif.В скриптах часто приходится использовать, так называемые переменные состояния, дабы обеспечить правильную работу скрипта. Обычно такой переменной дается имя state и она постепенно меняется в ходе его работы. И такую проверку организуют либо через группу последовательных if-endif, либо более длинным блоком if-elseif-endif. И из-за этого могут возникнуть проблемы, т.к. во втором случае, если наша контрольная переменная меняется ВНУТРИ блока, то обнаружится ее изменение только в следующем фрейме, т.е. при следующем прогоне скрипта, а не немедленно, что, в некоторых случаях, желательно, а в некоторых, наоборот, может привести к ошибкам. К данному посту приложен файл с плагом, в нем всего 2 скрипта, показывающих данный принцип. Подключите его, в консоли наберите Startscript, Script_A для запуска 2 варианта (if-elseif-endif) - и вы увидите, что счетчик фреимов будет разным для каждого состояния переменной state. Begin Script_A short state short framecount set framecount to ( framecount + 1 ) if ( state == 0 ) MessageBox "State - %.0f, Frame - %.0f", state, framecount set state to 1 elseif ( state == 1 ) MessageBox "State - %.0f, Frame - %.0f", state, framecount set state to 2 elseif (state == 2 ) MessageBox "State - %.0f, Frame - %.0f", state, framecount set state to 0 StopScript, Script_A endif end Запустите аналогично Script_B и вы увидите, что он исполняется за один фрейм, проходя все стадии переменной state.Begin Script_B short state short framecount set framecount to ( framecount + 1 ) if ( state == 0 ) MessageBox "State - %.0f, Frame - %.0f", state, framecount set state to 1 endif if ( state == 1 ) MessageBox "State - %.0f, Frame - %.0f", state, framecount set state to 2 endif if (state == 2 ) MessageBox "State - %.0f, Frame - %.0f", state, framecount set state to 0 StopScript, Script_B endif end -----------------------------------------Пожалуй все на сегодня. Если Вы также знаете какой-то секрет или возможность скриптов ТЕС3 - поделитесь своими знаниями или предположениями в данной теме. Изменено 25 августа, 2005 пользователем Boblen Ссылка на комментарий Поделиться на другие сайты Поделиться
lost81 Опубликовано 30 августа, 2005 Жалоба Поделиться Опубликовано 30 августа, 2005 (изменено) Цитата MSFD: - "Локальные переменные уникальны в пределах данного экземпляра скрипта. То есть одинаковые локальные переменные на разных объектах не влияют друг на друга". Чушь! Еще как влияют друг на друга! Но, надо сказать, что влияют они не всегда, а только если один объект со скриптом в непосредственной близости от другого объекта с другим скриптом, но с теми же переменными! (distance ~ 50-100) Выяснил я это абсолютно случайно, дело было так:№1 на активаторе висит скрипт телепортации. При OnActivate == 1 переменной состояния - "status" присваивается значение = 1, дальше MessageBox, с проверкой GetButtonPressed при нажатии кнопки, отличной от последней, отправляет игрока в различные локации (Экстерьеры). №2 Есть кольцо телепортации в интерьер. При OnPCEquip == 1 переменной состояния тоже "status" также как и в первом скрипте присваивается значение (обратите внимание!) = 1. Как же я был удивлен, когда, отказавшись (предварительно активировав (при отказе status сбрасывался в 0)) от путешествия в экстерьер и, решив отправиться в интерьер, меня перекинуло в ЭКСТЕРЬЕР, причем по счету соответствовавший первой кнопке первого скрипта! (Кольцо также с MessageBox и 2-мя кнопками: "Да" "Нет"), При отказе телепортации в интерьер, я отнюдь не оставался на месте, как хотел того, а перемещался в то место экстерьера, которое соответствовало 2-й кнопке 1-го скрипта! Я решил поэкспериментировать, и обнаружил, что в движке в скриптах главного меню (Сохранить, Выйти, Загрузить и тд), меню закрепления быстрых кнопок для смены оружия, магии и тп, также присутствует переменная, имя которой либо "status" либо "button"!!!Причем в последнем меню, меня телепортировало по всем локациям, при выборе кнопки меню, по счету совпадавшей с 1-м скриптом! Лечилось это 2-мя методами: изменением имен переменных... Хм, удивительно не помогло (возможно, не те переменные менял...) и введением условия "do-once"(сработало отлично!) подобные казусы были обнаружены и с другими скриптами, но поведал я об этом, тк он был первый, и довольно яркий, на мой взгляд. Небольшая поправка: Дистанция роли не играет! Во внимание принимается только активность ячейки и значение одинаковых переменных в разных локальных скриптах! Изменено 2 сентября, 2005 пользователем lost81 Ссылка на комментарий Поделиться на другие сайты Поделиться
Boblen Опубликовано 30 августа, 2005 Автор Жалоба Поделиться Опубликовано 30 августа, 2005 DinkumThinkum1. Если скрипт генерирует более, чем одно текстовое сообщение в одном фрейме, то возможен CTD. Это относится не только к тексту, генерируемому командой 'MessageBox', но также и к сообщениям 'Ваш журнал обновлен, ненерируемых командой 'Journal'. Вот почему мой StartUpScript(из плагина Unarmored Corrector) делает задержку в один фрейм между сообщением '...активирован' и командой 'Journal': у меня несколько раз прохоисходил CTD при загрузке, огда оба текста демонстрировались в одной фрейме. Я не тестировал этого, но возможно, что CTD также могут вызываться другими игровыми сообщениями, расположенными близко. 2. Если цель нацеленного глобального скрипта не помещена в мир через Construction Set, скрипт будет терять ее каждый раз при перезагрузке игры. Например 'Player' ID реально не расположен в игровом мире, он помещается туда после начала новой игры. Для того, чтобы мой Mainscript был нацелен на игрока, StartUpScript останавливает его и перезапускает, правильно нацеливая на 'Player', каждый раз при перезагрузке. /Речь ведется о плагине Unarmored Corrector/ 3. Если игрок ведет кулачный бой (Hand-to-Hand) и его руки готовы (т.е. кулаки перед лицом), то одевание или удаление части брони или одежды заставит персонаж на мгновение "дернуться": он возвращается в обычную позицию, руки по бокам, а затем снова в позицию H-to-H. Обычно это незаметно. Однако мой скрипт периодически надевает невидимые шлемы, так что мне пришлось добавить несколько улучшающих таймеров и удостоверится в том, что это будет незаметно. Заметьте, чтоNote #3 это не графический глюк: значение, возвращаемое 'GetWeaponDrawn' становится равным нулю каждый раз, как это происходит.Это выдержка из редми к плагину Unarmorred_Corrector (сейчас лежит на Саммите, скоро и у нас в базе). Ссылка на комментарий Поделиться на другие сайты Поделиться
Boblen Опубликовано 15 сентября, 2005 Автор Жалоба Поделиться Опубликовано 15 сентября, 2005 GetStat, ModStat and SetStat: A concerned modder’s guide.Throughout the term “base stat” means the value of the stat when yellow – i.e. unmodified by any in game bonus / penalty apart from fortification abilities. GetStat:Always returns the current stat – including any bonus / penalty. No nasty side effects as far as I’m aware, so GetStating should always be safe. There is (sadly) no GetBaseStat function. MWSE has these I think, but they don't include e.g. racial fortification abilities in the base (I think), and usually you'd want them included.Note that all stats are stored as floats, even though they should nearly always be integers. Usually this makes no difference. Most of the problems of ModStat and SetStat explained below are only really important for the player (and companions I guess). These functions won’t do anything worse than screwing up the stats they operate on, so for normal NPCs, there’s not much point worrying about all this. I’ve only tested the following on the player, but I presume the same is true for NPCs. As with pretty much anything in Morrowind modding, if you have a choice to use scripting or something else, then use something else. For ModStat / SetStat, the “something else” will usually be fortify/drain stat spell effects or curses. For most purposes, standard effects will work as well as ModStat and SetStat, and will be much less buggy. ModStat:Usually increases (or decreases) the stat concerned by the amount given (local variables are accepted). Both the current stat and the base stat are affected. Usually preserves the amount of fortification or damage on the stat. E.g. for a player with strength 50(base) + 10(fortification) = 60(current)Player->ModStrength 10 will give 60(b.) + 10(f.) = 70(c.), just as you’d expect. Limitations: ModStat can never decrease a stat below zero. It also cannot increase a base stat to a value over 100. Trying to Modstat below zero or above 100 can cause trouble in the following ways: Strength = 30(b.) + 0(f.) = 30(c.)ModStrength, -50 givesStrength = 0(b.) + 0(f.) = 0(c.)ModStrength 50 [hoping to undo the first modstrength]Strength = 50(b.) + 0(f.) = 50(c.) – and the player has a permanent bonus. You can try to avoid this by instead checking that you don’t reduce the stat by more than the current value, but that won’t always work. For example:Strength = 40(b.) + 10(f.) = 50(c.)ModStrength -50Strength = 0(b.) + 0(f.) = 0(c.)ModStrength 50Strength = 50(b.) + 0(f.) = 50(c.) – and the player’s base strength is increased.If he then removes the fortification, his strength will show up as damaged. Restoring and replacing the forification will leave him with:Strength = 50(b.) + 10(f.) = 60(c.) It’s never safe to ModStat down by more than the player’s base stat. Given that there’s no failsafe method to determine the player’s base stat, this is annoying [the only ways I know to determine the player’s base stat are the method which I use in GCD – complicated, and doesn’t work correctly when the player’s stat is damaged -, using MWSE, which I think doesn’t include permanent abilities in the base (for most purposes you’d want permanent abilities to count towards the base). Even systematically removing every conceivable bonus / penalty – which is a drag anyway – won’t always work with other scripted mods]. Going over 100 has similar problems. The following is fine:Strength = 70(b.) + 20(f.) = 90(c.)ModStrength, 20 givesStrength = 90(b.) + 20(f.) = 110(c.)ModStrength -20 givesStrength = 70(b.) + 20(f.) = 90(c.) – all fine. However, this also happens for some reason:Strength = 70(b.) + 20(f.) = 90(c.)ModStrength, 50 givesStrength = 100(b.) + 40(f.) = 140(c.) – already screwed up.ModStrength -50 givesStrength = 50(b.) + 40(f.) = 90(c.) – further screwed up. This problem arises because if a stat is fortified or damaged, and the base is not 100, ModStat always increases the current stat by the value you give it, even if the base stops at 100. If the base is 100, ModStating won't have any effect. If the stat is equal to its base value, ModStat will behave normally. So this is fine (so long as you don’t ModStat -50 afterwards):Strength = 70(b.) + 0(f.) = 70(c.)ModStrength, 50 givesStrength = 100(b.) + 0(f.) = 100(c.) And this is fine:Strength = 100(b.) + 20(f.) = 120(c.)ModStrength, 50 givesStrength = 100(b.) + 20(f.) = 120(c.) But this isn’t:Strength = 99(b.) + 20(f.) = 119(c.)ModStrength, 50 givesStrength = 100(b.) + 69(f.) = 169(c.) – oh dear. Of course as a modder you won’t know in general what the Base + Fortification is before you use the ModStat function, so you have no way to compensate for errors even once you know what can go wrong. Joy! Ok, so as long as you never try to ModStat the current stat over 100, everything should be fine, right?Sadly not:Strength = 95(b.) - 10(damage) = 85(c.)ModStrength, 15 givesStrength = 100(b.) + 0(f.) = 100(c.) – OK so farModStrength, -15 givesStrength = 85(b.) + 0(f.) = 85(c.) – Permanent strength damage. So under what circumstances will ModStating up or down give reliably predictable results?Only when you know the base value of the stat. Can you reliably work out the base value of the stat?No – only in some situations is it possible (the process is explained below, and implemented in my Gals_Sk_Acrobatics script in GCD). Even then it’s not easy. (it’s worth checking script extenders for updates though) SetStat:Sets both the base and the current value to the value you give it (also accepts local variables). This will pretty much always cause problems if the player’s current stat is not equal to their base stat. If their stat is fortified, and you SetStat it, it’ll turn yellow at the value you give it. Removing the fortification, then restoring will give the player a permanent bonus.If their stat is damaged, SetStating it will again turn it yellow, but this time at a lower value than you (probably) intended. They will instantly have their base knocked down to the value you set. Using SetStat is therefore never even slightly safe unless you know the player’s base stat, and compensate accordingly. While you can’t guarantee that ModStat won’t cause trouble, you can almost guarantee that SetStat will.Using SetStat is therefore almost always a bad decision – if you’re ever not sure whether it’s a bad decision, then it is. Then are these functions useless!?Not always. You can use them on NPCs without worrying too much. Using them on companions could occasionally not have the effect you want, but it’s unlikely the player would notice. Using ModStat on the player can be safe, so long as you’re careful – e.g. to increase strength by (up to) 10 points temporarily, you could:Give the player a very strong restore strength curse for a frame or two. (you can then be sure his strength isn’t damaged)ModStrength by MIN{ 10, 100-current }…ModStrength down by the same amount when you want the effect to finish. You can never be sure that giving a temporary penalty won’t cause trouble, but if you only reduce the stat by at most 30, then it’ll usually be fine since most players start with all stats that high. Restoring the stat after you’ve reduced it like this could cause trouble if the player has since gained base stat points, and his stat started close to 100. Some "cunning" tricks with SetStat / ModStat:WARNING – using the following tricks might cause even more trouble than using the functions normally. Use with care. Conflicts are likely. Finding the base of a stat:You can find the base of a stat using the (mis)behaviour of ModStat, as follows:(1)Make sure that the player’s stat isn’t damaged [You have been tracking increases in the natural values of the stat since the beginning of the game, haven’t you? If you haven’t, then you have no way of knowing if it’s damaged – you could check the base value on installation of your mod, so long as you ask the player to install when stats aren’t damaged / fortified].(2)If it is damaged, give up. (you might want to check script extenders)(3)If it isn’t:(4)Store the current value of the stat.(5)Mod the stat up to 100 if it isn’t already 100 or more.(6)ModStat, 1 as many times as you can while the stat still increases.(7)The fortified part of the stat is the value it reached minus 100.(8)The base part of the stat is the current value minus the fortified part.(9)Return the stat to its current value (DON’T use SetStat, use ModStat). Armed with the base value, you can now use ModStat and SetStat wisely and safely, so long as you’re very careful. Damaging a stat:To set a stat to e.g. 50 damaged from 70, you can do the following:Player->SetStat, -20 [base and current are now both -20]Player->ModStat, 0 [Necessary: sets the base to 0]Player->ModStat, 70 [base = 70, current = 50 (red)] This level of precision is not possible in general using e.g. damage stat curse effects, but it’s not usually necessary either. The above can also be done within one frame, whereas a curse effect might take a second to kick in. Again, the speed can be useful, but is usually unnecessary. Fortifying a stat:To set a stat to e.g. 120 fortified from 90, you can do the following:Player->SetStat 130 [base and current are now both 130]Player->ModStat, 0 [Necessary: sets the base to 100]Player->ModStat, -10 [base = 90, current = 120 (white)] Right, I hope that made some sense. Now you know pretty much everything about the Get/Set/ModStat functions. Just remember not to use them wink.gif. Оригинал здесьАвтор Galsiah Ссылка на комментарий Поделиться на другие сайты Поделиться
Boblen Опубликовано 22 сентября, 2005 Автор Жалоба Поделиться Опубликовано 22 сентября, 2005 I thought it would helpful to make this information public knowledge. The ToggleMenus function can be useful to to force the game engine out of Menu Mode, but some scripters (myself included) have had real issues with using it. Remember that a second ToggleMenus call is always necessary. Without this, menus do not "have permission" to display at all. Attempting to force menus to open by script, while the general Menus state is toggled "off", will often cause freezing/CTD. As others have found, however, using a double ToggleMenus call has the nasty side effect of completely disabling the HUD. Once disabled, the HUD will not reappear until it is reinitialized. There are only two events, that I know of, that will force the game engine to reinitialize the HUD without the player's intervention. There may be others, but these are the ones I have tested and which I know work:- Cell Load Any new cell load (interior or exterior) forces the game engine to reinitialize the game interface completely, including the HUD. e.g. Begin nigedo_hidemove If ( OnActivate ) ToggleMenus Player->COE 0 0 ToggleMenus Endif End This means that it is entirely safe to use ToggleMenus to hide the cell load progress bar in the case of scripts that teleport the player by means of multiple cell loads. Delaying the second ToggleMenus call until the same frame that the player arrives in their destination cell will hide the transportation and still reinitialize the HUD. ForceGreeting This is the other, and more useful, means of reinitializing the HUD. 1. If you use ToggleMenus to immediately exit dialogue, you should add follow on code to initiate a ForceGreeting from the same NPC and then call ToggleMenus twice, to restart the HUD and safely leave Menu Mode respectively. e.g. Call this script from a StartScript in the required dialogue Results field:- Begin nigedo_exit_dialogue Short step If ( step == 0 ) ToggleMenus ToggleMenus Set step to 1 Elseif ( step == 1 ) ForceGreeting ToggleMenus Set step to 2 Elseif ( step == 2 ) ToggleMenus MenuTest StopScript nigedo_exit_dialogue Endif End Notes: * The functions must be called in separate frames in this order to work successfully. * Calling ForceGreeting in the same frame as the first of the second set of ToggleMenus calls (step 1), allows the HUD to remain active despite menus state being toggled "off". I believe this is because the ForceGreeting is already in the process of reinitializing the HUD as the ToggleMenus call processes. The ToggleMenus call catches the dialogue window, but not the HUD. * The MenuTest call (step 2) eliminates an inventory view Menu Mode state that appears to underlie dialogue Menu Mode states. 2. If you want to use this method to safely exit Menu Mode states other than dialogue, you will need to create a custom NPC that you can use to initiate a ForceGreeting call, as required. To do this: * Create a new race with default attributes - call it "race_invisible" * Create a new NPC using the race "race_invisible" and call him "npc_HUD_reset" * Create a new dialogue entry towards the start of the "Greetings 0" section. Filter it by ID = "npc_HUD_reset" and enter the text "." (this isn't strictly necessary, but it's cleaner) Then add this script to "npc_HUD_reset":- Begin nigedo_reset_HUD Short step If ( GetDisabled ) SetDelete 1 Return Endif If ( step == 0 ) ForceGreeting ToggleMenus Set step to 1 Elseif ( step == 1 ) ToggleMenus MenuTest Disable Set step to 0 Endif End Now, whenever you create a script that uses ToggleMenus calls to exit Menu Mode, add a follow on section that places an instance of "npc_HUD_reset" at the player. e.g. This example exits the inventory share Menu Mode state, when activating a container:- Begin nigedo_container_shutDown Short step If ( step == 0 ) If ( OnActivate ) Activate Set step to 1 Endif Elseif ( step == 1 ) MenuTest ToggleMenus ToggleMenus Set step to 2 Elseif ( step == 2 ) If ( MenuMode ) Return Endif PlaceAtPC npc_HUD_reset 1 0 0 Set step to 0 Endif End Note that, in this case, a MenuTest call is necessary at step 1, in order to exit an underlying inventory view Menu Mode state. This is not always necessary and MenuTest can cause problems if called unnecessarily. Experiment with your specific needs and determine whether you may need additional MenuTest calls to assist the process. smile.gif Оригинал здесь Ссылка на комментарий Поделиться на другие сайты Поделиться
Boblen Опубликовано 26 сентября, 2005 Автор Жалоба Поделиться Опубликовано 26 сентября, 2005 Подборка основных багов в скриптах.реклама на форуме запрещена, читай правилаwww.uesp.net/wiki/index.php?title=T...ipting_Pitfalls Ссылка на комментарий Поделиться на другие сайты Поделиться
Ордмайер Опубликовано 15 марта, 2006 Жалоба Поделиться Опубликовано 15 марта, 2006 Ребят подскажите пожалуйста, что за команда в скрипте лифта "move z"?И еще, что это за команда "doonce"? Ссылка на комментарий Поделиться на другие сайты Поделиться
Boblen Опубликовано 15 марта, 2006 Автор Жалоба Поделиться Опубликовано 15 марта, 2006 Ты MSFD читал? Move двигает по относительным координатам, а doonce вообще не команда, а переменная, которую часто используют моддеры для того, чтобы структурировать скрипт... ЗЫ: Это не та тема, где нужно задавать эти вопросы. Ссылка на комментарий Поделиться на другие сайты Поделиться
LofZ Опубликовано 21 июня, 2006 Жалоба Поделиться Опубликовано 21 июня, 2006 Мне не встречалось в руководстве упоминание о таком нюансе, но я сама так пару раз попадала: Кажется вроде бы удобно писать новый скрипт на базе уже существующего, вызвав его сразу через окно параметров объекта вместо того, чтобы копаться в списке скриптов. Однако, по неизвестной причине, даже если у нового скрипта совершенно другое имя, после нажатия на save новый скрипт перепишет существующий, и тот пропадет безвозвратно, даже если скрипт был стандартный, типа nolore. Тоже самое произойдет при попытке и просто писать новый скрипт в окне существующего. :1anim_am: Это исправить можно только выйдя из редактора без сохранения, либо удалить новый скрипт в tesame, что в любом случае означает - работа кагути под хвост :1anim_ac: Ссылка на комментарий Поделиться на другие сайты Поделиться
Эндер Виггин Опубликовано 13 октября, 2007 Жалоба Поделиться Опубликовано 13 октября, 2007 Функция PlaceItem работает коряво. Она всегда ставит ПОДБИРАЕМУЮ версию предмета. Если это была одежда или оружие или что-то что можна подобрать - то всё ОК. Но если плейсить статики, активаторы, непереносимые светильники - всё то, что нельзя подобрать - то появляются глюки. При наведении прицела на призванный объект появляется его ИДшник (исключение - активатор с заданным именем) и при активации он попадет в инвентарь. При попытке просмотра инвентаря Морра зависнет, ибо такие характеристики как вес, цена, иконка итд. не то чтобы не заданы - их вообще НЕТ. Единственное исключение - если разместить PlaceItem`ом активатор со скриптом, который отлавливает активацию, то таких глюков не будет - он активируется, как положено. Тоже должно сработать и для не переносного светильника со скриптом, однако имени у него нет и отобразится ИД... Ссылка на комментарий Поделиться на другие сайты Поделиться
Boeny Опубликовано 27 мая, 2008 Жалоба Поделиться Опубликовано 27 мая, 2008 1) Что такое "the HUD"?это все дополнительные элементы на экране, полоски здоровья, иконки заклинаний, крестик прицела 2) Функция setscale, добавляемая Трибуналом, не воспринимает значения меньше 0.01.3) if...else...endif могут быть вложены друг в друга не более 10 раз. Ссылка на комментарий Поделиться на другие сайты Поделиться
Эндер Виггин Опубликовано 27 мая, 2008 Жалоба Поделиться Опубликовано 27 мая, 2008 1) HUD - Heads Up Display - То что видит геймер играя в игру. Типа Полоска здоровья, прицел итд. 2) Она также не воспринимает значения больше 10 (это есть в МСФД).... хотя.... там нижняя граница 0, а не 0.01... впрочем, врядли это так страшно... 3) интересно.... в МСФД только про максимальное количество и расстояние между блоками, а по вложенность нет Ссылка на комментарий Поделиться на другие сайты Поделиться
Boeny Опубликовано 28 мая, 2008 Жалоба Поделиться Опубликовано 28 мая, 2008 (изменено) 1) HUD - Heads Up Display - То что видит геймер играя в игру. Типа Полоска здоровья, прицел итд. 2) Она также не воспринимает значения больше 10 (это есть в МСФД).... хотя.... там нижняя граница 0, а не 0.01... впрочем, врядли это так страшно... 3) интересно.... в МСФД только про максимальное количество и расстояние между блоками, а по вложенность нет 1) Здорово, спс 2) По крайней мере 0.009 и меньше - это то же самое, что и 0.01. Я пытался в 1000 раз уменьшить кантон в Вивеке, чтобы поместить его на мини-карту... а он максимум стал высотой с Игрока. Или даже двух 3) Компилер так и говорит:"Script ...Max nesting of 10 exceded on line ..." Пришлось применить отрицание ("И" переделывает в "ИЛИ"!) и вместо else ставить return'ы. 4) Если команду SetScale "size" ставить после вызова/применения заклинания, то обычно она не срабатывает. Я думаю, это потому, что применение/снятие эффекта занимает много времени - и скрипт сбрасывается (виснет и начинается сначала), поэтому я либо ставлю ее ДО, либо изменяю локальную переменную status и работаю с ней в следующем фрейме. 5) И последнее (это меня убило). Оказывается команда StopScript "CurrentScript" не прекращает выполнение текущего скрипта, как можно подумать, а ПО-МОЕМУ только активизирует флаг о его завершении. И когда исполнение дойдет до строчки "end", скрипт выгружается из памяти. Пример из "Необходимостей Морровинда" (глобальный скрипт):Begin BINN_start_message short DaysLeft if ( BINN_message == 1 ) StopScript "BINN_start_message"; я-то думал, здесь конец set BINN_message to 0; ан нет return; идем вканец endif ... end; и вот здесь завершаем выполнение НО! Если ПОСЛЕ StopScript "CurrentScript" написать StartScript "SomeScript", то скрипт SomeScript не запустится! StartScript надо писать ПЕРЕД завершением текущего скрипта! Шо за бред??? КАК ЭТО РАБОТАЕТ??? 6) ВНИМАНИЕ! ОПАСНОСТЬ! Компилер не проверяет (по крайней мере, у меня; версия Трибунал), объявлены ли локальные переменные, используемые в скрипте, поэтому при операции над необъявленной переменной скрипт перестает работать! Если переменных много, за этим надо строго следить. Изменено 29 мая, 2008 пользователем boeny Ссылка на комментарий Поделиться на другие сайты Поделиться
Ллирик Опубликовано 25 апреля, 2010 Жалоба Поделиться Опубликовано 25 апреля, 2010 (изменено) Я выяснил две вещи. Я, конечно, уже писал об этом на этом форуме, но боюсь меня не правильно поняли, поэтому повторюсь1) скрипт с xAITravel должен выглядеть примерно так: begin kKirStartNPCKiss short kislongshort kirtravelscrpfloat Player_Xfloat Player_Yfloat Player_Z if ( kirtravelscrp == 0)if ( kirtravelscrp == 0)set kirtravelscrp to 1set Player_X to Player -> GetPos, Xset Player_Y to Player -> GetPos, Yset Player_Z to Player -> GetPos, Zxaitravel Player_X Player_Y Player_Zset kislong to 1set kislong to 2startscript Kir_Romance_Kisselseif ( kislong < kislong )if ( kislong == 9)set kislong to 1endifendifendifend Я и сам не понимаю зачем эту лишнюю чушь писать, но без неё непись застывает на месте. Можете сами проверить. Вместо чуши могут быть подставлены другие значения, но сокращать скрипт нельзя 2) баг PositionCell, описанный в Morrowind_Scripting_for_Dummies_8.0_RusЦитата:А также: если вы пытаетесь телепортировать NPC из ячейки, где игрок никогда не был (соответственно ни разу не видел этого NPC), туда, где игрок находится в данный момент, то при попытке поговорить с этим NPC Морр вылетит. (Прим. Gwathlobal)Решение: В MWEdit в разделе NPC выбираете какого-нибудь непися и делаете "Create copy". в поле "new id" пишите другой ид и сохраняете. в TES Construction Set эту копию помещаете в какую-нибудь ячейку и всё! Можно использовать PositionCell или xPositionCell с этой копией! игра не вылетит! Изменено 25 апреля, 2010 пользователем Ллирик Ссылка на комментарий Поделиться на другие сайты Поделиться
Охотник за Смертью Опубликовано 11 ноября, 2013 Жалоба Поделиться Опубликовано 11 ноября, 2013 (изменено) Итак, после многих лет игнорирования сией темы я таки решил испытать скрипты. И вот что у меня не получается:есть вот такая конструкцияSet PC_Personal to ( Player->GetPersonality )PC_Personal это shortДалее в ходе скрита мы делаем такSet PC_Personal to ( PC_Personal - 35 )и это не работает - значение PC_Personal остается неизменнымоднако вот это:Set fuckBuff to PC_Personal Set fuckBuff to ( fuckBuff - 35 )работает как надо. В чем может быть бок? Изменено 11 ноября, 2013 пользователем Охотник за Смертью Ссылка на комментарий Поделиться на другие сайты Поделиться
aL☢ Опубликовано 11 ноября, 2013 Жалоба Поделиться Опубликовано 11 ноября, 2013 Может привлекательность была меньше 35? Ну, там 30 например, а short не ест отрицательные значения вроде? а на fuckbuff какой числовой тип висит? Или он вообще не прописан? Ссылка на комментарий Поделиться на другие сайты Поделиться
Охотник за Смертью Опубликовано 11 ноября, 2013 Жалоба Поделиться Опубликовано 11 ноября, 2013 (изменено) Может привлекательность была меньше 35? Ну, там 30 например, а short не ест отрицательные значения вроде? а на fuckbuff какой числовой тип висит? Или он вообще не прописан?тоже шорты там.Отрицательность щас проверю, мне казалось, что она должна кушать отрицательность апдШорты кушают отрицательные значения Изменено 11 ноября, 2013 пользователем Охотник за Смертью Ссылка на комментарий Поделиться на другие сайты Поделиться
Daedroth_CH Опубликовано 11 ноября, 2013 Жалоба Поделиться Опубликовано 11 ноября, 2013 Попробуй сделать переменную, отслеживающую последовательность повышения переменных и заставляющую скрипт ее соблюдать. Ссылка на комментарий Поделиться на другие сайты Поделиться
aL☢ Опубликовано 11 ноября, 2013 Жалоба Поделиться Опубликовано 11 ноября, 2013 А не пробовал у PC_Personal убрать нижний слеш и оставить PCPerconal? Ссылка на комментарий Поделиться на другие сайты Поделиться
Охотник за Смертью Опубликовано 13 ноября, 2013 Жалоба Поделиться Опубликовано 13 ноября, 2013 А не пробовал у PC_Personal убрать нижний слеш и оставить PCPerconal?пробовал. Проблема вообще не понятно в чем, но с костылем работает отлично Новый вопрос к вам, мои любители скриптописания. В МСФД есть такая фраза: Более того, недавно я осознал, что подобный синтаксис работает и для глобальных скриптов: set Global_script_name.variable to 1 Это полезно, чтобы избежать большого количества глобальных переменных или для отладки глобальных скриптов в консоли.кто-то это тестил? а то у меня и не падает, но и не взлетает И еще один вопрос Значения глобальных переменных сохраняются при сохранении/загрузке? Ссылка на комментарий Поделиться на другие сайты Поделиться
Daedroth_CH Опубликовано 14 ноября, 2013 Жалоба Поделиться Опубликовано 14 ноября, 2013 Да, сохраняются. Ссылка на комментарий Поделиться на другие сайты Поделиться
Охотник за Смертью Опубликовано 15 ноября, 2013 Жалоба Поделиться Опубликовано 15 ноября, 2013 Да, сохраняются.Просто я смотрю, что, например у вас в СХ есть глобус PC_Class, который не сохраняется... Хотя я, возможно, просто не нашел, что он где-то сбрасывается Ссылка на комментарий Поделиться на другие сайты Поделиться
Daedroth_CH Опубликовано 15 ноября, 2013 Жалоба Поделиться Опубликовано 15 ноября, 2013 Хм, странно. Впочем, я задал вопрос по этому поводу на нашем форуме. Но если и так, то 90% схшных квестов не будут работать при перезагрузке, ибо переменные, тем паче глобалы, там изобилуют. Ссылка на комментарий Поделиться на другие сайты Поделиться
aL☢ Опубликовано 15 ноября, 2013 Жалоба Поделиться Опубликовано 15 ноября, 2013 А вот кстати, пол ГГ как легче всего определить скриптом? Ссылка на комментарий Поделиться на другие сайты Поделиться
Макс Кауфман Опубликовано 15 ноября, 2013 Жалоба Поделиться Опубликовано 15 ноября, 2013 (изменено) Скриптом его нормально не определишь, в диалогах есть функции.Далее в ходе скрита мы делаем такSet PC_Personal to ( PC_Personal - 35 )и это не работает - значение PC_Personal остается неизменнымоднако вот это:Set fuckBuff to PC_Personal Set fuckBuff to ( fuckBuff - 35 )работает как надо. В чем может быть бок? Ты из скриптов копировал? Просто поэкспериментируй с пробелами.Новый вопрос к вам, мои любители скриптописания. В МСФД есть такая фраза: кто-то это тестил? а то у меня и не падает, но и не взлетает И еще один вопрос Значения глобальных переменных сохраняются при сохранении/загрузке?1 скорее всего у тебя глобальный скрипт не запущен, добавь его в старт скрипт 2Как уже ответили - сохраняются, как и локальные. Только локальные действуют на 1 объект, а глобальные - как связующие нити между скриптами. Изменено 15 ноября, 2013 пользователем Макс Кауфман Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Пожалуйста, войдите, чтобы комментировать
Вы сможете оставить комментарий после входа в
Войти