Город Мастеров
IPB

Здравствуйте, гость ( Вход | Регистрация )

 Правила этого форума ПРАВИЛА РАЗДЕЛА
3 страниц V   1 2 3 >  
Ответить в эту темуОткрыть новую тему
> Крафт в Neverwinter Nights - а это вообще возможно?, Герой-робинзон, "адын на льдине" купить-продать невозможно, вс
Chiffa
сообщение Nov 5 2017, 04:09
Сообщение #1


Level 6
**

Класс: Волшебник
Характер: Chaotic Good
Раса: Человек



Собственно, началась тема на WRG, откуда я скачал замечательную систему крафта от PaiNtа. Поставил за нее десятку, и до сих пор считаю, что поступил правильно. Несмотря на все грабли, на которые наступил. Переношу сюда два последних поста с WRG, потому что в них, собственно, суть. (Продолжать обсужденние в теме на WRG, думаю, неправильно, это превращать тему "файлы" в форум.
Итак, собственно грабли:

Цитата
Записал дословно сообщение сисемы. Вот это:
"Скрипт pt_axcrf_activ OID ffffffff, Tag:, ОШИБКА СЛИШКОМ МНОГО ИНСТРУКЦИЙ
Скрипт x2_mod_def_act, OID 80000000, Tag:, ОШИБКА СЛИШКОМ МНОГО ИНСТРУКЦИЙ"
В очередной раз это произошло сразу после входа в игру. Расстроился. Дело в том, что герой как раз присел отдохнуть перед крафтом. Что ж это, прощай атмосферность? А я то разгубастился и на рискованный отдых, и на систему от Авадона с ковриками-кострами, эх!
Ладно, заменил скрипт отдыха на "родной". Снова зашел. То же самое. И тоже прям сразу.
Подумал, может проблема в хаке? Но вот хак то - курам на смех, всего то заменил четыре из бесчисленных и доставших донельзя дефолтных флагов на мокрую водичку 1х1 и 4х4 (это где герой в затопленной палубе фрегата задыхается.)
Ладно, убрал хак. Короче, все настройки - родные. Поиграл полчаса. Собщение системы то же самое.
А компилятор от обоих скриптов в восторге. Прямо тащатся от удовольствия, какие они правильные, белые и пушистые.
И еще. Если в переменной "pt_CRAFT_PROCESS_PC_CUSTOM_SCRIPT" действительно сдуру поставить какой-нибудь скрипт (даже самый простенький, с анимацией присесть когда что-то мастеришь или "говорить убедительно", когда ветку от дерева отламываешь или руду "киркой" долбишь, то скрипт запустится, но никакого крафта уже не будет.
Ставить в переменных скилы и прочие навыки не стал. Страшно...


И ответ уважаемого Aiwanа на этот пост:

Цитата
Чаще всего такое происходит, когда какой-то скрипт не отключается и постоянно выдает какие-то задания. Чаще всего это забытый новичком скрипт на хертбите НПС или модуля или триггероах. Или неккоректно сделана проверка в скрипте и он постоянно циклично работает


Aiwan, при всем уважении, нет там у меня никаких неписей, герой "адын на льдине". Для теста даже монстров не ставил. Примерно половина (минимум треть) модуля задумана как исключительно робинзонада, нет магазинов, никто ничо не подарит, все сам, все ручками, от кремневого ножа до лохмотьев и простейших зелий. Настройки модуля, как и писал, все вернул "родные", от PaiNtа. Триггер единственный, это "REST_ZONA". и сильно сомневаюсь, что он будет выдавать цикличные инструкции.

Остаются скрипты? Первый, на который жалуется система и которым восхищается компилятор, это скрипт настроек модуля "x2_mod_def_act", стоит на OnActivateltem. Вот он, целиком, совсем короткий:

Neverwinter Script
//::///////////////////////////////////////////////
//:: Example XP2 OnActivate Script Script
//:: x2_mod_def_act
//:: © 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Put into: OnItemActivate Event

*/

//:://////////////////////////////////////////////
//:: Created By: Georg Zoeller
//:: Created On: 2003-07-16
//:://////////////////////////////////////////////

#include "x2_inc_switches"
void main()
{
    object oItem = GetItemActivated();

    // * Generic Item Script Execution Code
    // * If MODULE_SWITCH_EXECUTE_TAGBASED_SCRIPTS is set to TRUE on the module,
    // * it will execute a script that has the same name as the item's tag
    // * inside this script you can manage scripts for all events by checking against
    // * GetUserDefinedItemEventNumber(). See x2_it_example.nss
    if (GetModuleSwitchValue(MODULE_SWITCH_ENABLE_TAGBASE
D_SCRIPTS) == TRUE)
    {
        SetUserDefinedItemEventNumber(X2_ITEM_EVENT_ACTIVA
TE);
        int nRet =  ExecuteScriptAndReturnInt(GetUserDefinedItemEventS
criptName(oItem),OBJECT_SELF);
        if (nRet == X2_EXECUTE_SCRIPT_END)
        {
          return;
        }

    }



//Execute PaiNt activate craft-tool script
if(GetStringLeft(GetTag(oItem), 14)=="pt_craft_tool_")
    {
    object oActivator=GetItemActivator();

    SetLocalObject(oActivator, "pt_ActTool", oItem);
    SetLocalObject(oActivator, "pt_ActTarget", GetItemActivatedTarget());


    ExecuteScript("pt_axcrf_activ", oActivator);
    };
}


Смотрю на него, как известное рунное животное на известный новый плейстейбл и в упор не понимаю, чему тут зацикливаться...

Второй скрипт "pt_axcrf_activ" куда серьезней. Даже не уверен, поместится ли, но рискну таки. Вот он:

Neverwinter Script
//Óíèâåðñàëüíûé ñêðèïò àêòèâàöèè èíñòðóìåíòà

#include "pt_frame000"
#include "x3_inc_string"
#include "pt_axcrf_md_cons"






void pCreateObjectInLocal(object oTarget, string sName, int nObjectType, string sTemplate, location lLocation, int bUseAppearAnimation=FALSE, string sNewTag="")
{
SetLocalObject(oTarget, sName, CreateObject(nObjectType, sTemplate, lLocation, bUseAppearAnimation, sNewTag));
}



void main()
{
object oModule=GetModule();
object oActivator=OBJECT_SELF;
if(GetLocalInt(oActivator, "pt_curCraftProcess_Mode")) return;
object oTool=GetLocalObject(oActivator, "pt_ActTool");DeleteLocalObject(oActivator, "pt_ActTool");
object oTarget=GetLocalObject(oActivator, "pt_ActTarget");DeleteLocalObject(oActivator, "pt_ActTarget");
object oParentRawTarget;






//Î÷èñòêà äèàëîãîâûõ ïåðåìåííûõ
SetLocalInt(oActivator, "pt_craft_dialNodeArray_Length", 0);
SetLocalInt(oActivator, "pt_craft_dialTok"+IntToString(pt_CUSTTOK_NODE_ONE)+"_Index", -1);
SetLocalInt(oActivator, "pt_craft_dialTok"+IntToString(pt_CUSTTOK_NODE_TWO)+"_Index", -1);
SetLocalInt(oActivator, "pt_craft_dialTok"+IntToString(pt_CUSTTOK_NODE_THREE)+"_Index", -1);
SetLocalInt(oActivator, "pt_craft_dialTok"+IntToString(pt_CUSTTOK_NODE_FOUR)+"_Index", -1);
SetLocalInt(oActivator, "pt_craft_dialTok"+IntToString(pt_CUSTTOK_NODE_FIVE)+"_Index", -1);
SetCustomToken(pt_CUSTTOK_NODE_ONE, "");
SetCustomToken(pt_CUSTTOK_NODE_TWO, "");
SetCustomToken(pt_CUSTTOK_NODE_THREE, "");
SetCustomToken(pt_CUSTTOK_NODE_FOUR, "");
SetCustomToken(pt_CUSTTOK_NODE_FIVE, "");
SetLocalInt(oActivator, "pt_craft_dialMinI", 0);
SetLocalInt(oActivator, "pt_craft_dialMaxI", 0);
int iNumDialogNodes=-1;

//Î÷èñòêà ïåðåìåííûõ ñëóæåáíûõ ïðåäìåòîâ
SetLocalInt(oActivator, "pt_craft_dialToolIsBook", FALSE);
SetLocalInt(oActivator, "pt_craft_dialToolIsSkillStick", FALSE);
SetLocalInt(oActivator, "pt_craft_dialToolIsToolTool", FALSE);

SetLocalInt(oActivator, "pt_craft_dialToolIsRawCreateSp", FALSE);
SetLocalInt(oActivator, "pt_craft_dialToolIsRawSeeRawSp", FALSE);
SetLocalInt(oActivator, "pt_craft_dialToolIsRawSeeToolSp", FALSE);
SetLocalInt(oActivator, "pt_craft_dialToolIsRawSeeSkillSp", FALSE);
SetLocalInt(oActivator, "pt_craft_dialToolIsRawCreateSkillSt", FALSE);




//Èìÿ èíñòðóìåíòà,êîòîðûé âûçâàë ñêðèïò äëÿ äèàëîãà
SetLocalString(oActivator, "pt_craft_dialTool", GetName(oTool));

//Òàã èíñòðóìåíòà, êîòîðûé âûçâàë ñêðèïò
string sToolTag=GetTag(oTool);



/////////////////////////////////////////////
//Ñëóæåáíûå ïðåäìåòû äëÿ óïðàâëåíèÿ ñèñòåìîé

//Áîëüøàÿ êíèãà êðàôòà
if(sToolTag=="pt_craft_tool_DMbook")
    {
    SetLocalInt(oActivator, "pt_craft_dialToolIsBook", TRUE);
    }


//Áîëüøàÿ ïàëêà íàâûêîâ
    else if(sToolTag=="pt_craft_tool_DMs00")
    {
    if(GetObjectType(oTarget)!=OBJECT_TYPE_CREATURE) {FloatingTextStringOnCreature("Íå ïîäõîäÿùèé ïðåäìåò.", oActivator, FALSE); return;};

    SetLocalInt(oActivator, "pt_craft_dialToolIsSkillStick", TRUE);
    SetLocalObject(oActivator, "pt_craft_dialToolIsSkillStickTarget", oTarget);
    }


//Áîëüøàÿ ïàëêà Èíñòðóìåíòîâ
    else if(sToolTag=="pt_craft_tool_DMs10")
    {
    if(GetObjectType(oTarget)!=OBJECT_TYPE_ITEM && GetObjectType(oTarget)!=OBJECT_TYPE_PLACEABLE && GetObjectType(oTarget)!=OBJECT_TYPE_CREATURE) {FloatingTextStringOnCreature("Íå ïîäõîäÿùèé ïðåäìåò.", oActivator, FALSE); return;};

    SetLocalInt(oActivator, "pt_craft_dialToolIsToolTool", TRUE);
    SetLocalObject(oActivator, "pt_craft_dialToolIsToolToolTarget", oTarget);

    AssignCommand(oActivator, ActionStartConversation(oActivator, "pt_axcrf_main", TRUE, FALSE));
    return;
    }


/////////////////////////////////////////////////////
//Ñëóæåáíûå ïðåäìåòû äëÿ ââîäà â ñèñòåìó èíãðèäèåíòîâ

//Áîëüøàÿ côåðà òðàíñôîðìàöèè
    else if(sToolTag=="pt_craft_tool_DMs01")
    {
    if(GetObjectType(oTarget)!=OBJECT_TYPE_ITEM) {DeleteLocalObject(oActivator, "pt_craft_dialToolIsRawCreateTarget"); FloatingTextStringOnCreature("Íå ïîäõîäÿùèé ïðåäìåò.", oActivator, FALSE); return;};

    SetLocalInt(oActivator, "pt_craft_dialToolIsRawCreateSp", TRUE);
    SetLocalObject(oActivator, "pt_craft_dialToolIsRawCreateTarget", oTarget);


    //Çàäàíèå ïåðåìåííûõ äëÿ äèàëîãà
    string sRawsString=GetLocalString(oTarget, "pt_CRAFT_RAW"), sToolsString=GetLocalString(oTarget, "pt_CRAFT_TOOL"), sSkillsString=GetLocalString(oTarget, "pt_CRAFT_SKILL_ID"), sRTtempstring, sNumDialogNodes;
    int x, iRawLen=pArrayLength(sRawsString), iToolLen=pArrayLength(sToolsString), iSkillLen=pArrayLength(sSkillsString);

    iNumDialogNodes=-1;
    for(x=0; x<iRawLen; x++)
        {
        sRTtempstring=pArray(sRawsString, x);
        if(sRTtempstring=="") continue;

        iNumDialogNodes++;
        sNumDialogNodes=IntToString(iNumDialogNodes);

        SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_ItemRawTag", sRTtempstring);
        };
    iNumDialogNodes=-1;
    for(x=0; x<iToolLen; x++)
        {
        sRTtempstring=pArray(sToolsString, x);
        if(sRTtempstring=="") continue;

        iNumDialogNodes++;
        sNumDialogNodes=IntToString(iNumDialogNodes);

        SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_ItemToolTag", sRTtempstring);
        };
    iNumDialogNodes=-1;
    for(x=0; x<iSkillLen; x++)
        {
        sRTtempstring=pArray(sSkillsString, x);
        if(sRTtempstring=="") continue;

        iNumDialogNodes++;
        sNumDialogNodes=IntToString(iNumDialogNodes);

        SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_ItemSkillId", sRTtempstring);
        };

    //Çàäàíèå äëèííû ìàññèâà
    SetLocalInt(oActivator, "pt_craft_dialNodeArray_Length", iRawLen+((iRawLen<iToolLen)?abs(iRawLen-iToolLen):0));
    //debug
    //SendMessageToPC(GetFirstPC(), "'"+GetName(oCrftItem)+"' Çàïèñü äàííûõ â ïåðåìåííûå");



    AssignCommand(oActivator, ActionStartConversation(oActivator, "pt_axcrf_main", TRUE, FALSE));
    return;
    }


//Ìàëàÿ ïàëêà ñûðüÿ
    else if(sToolTag=="pt_craft_tool_DMs02")
    {
    oParentRawTarget=GetLocalObject(oActivator, "pt_craft_dialToolIsRawCreateTarget");
    if(!GetIsObjectValid(oParentRawTarget)) {FloatingTextStringOnCreature("Âû íå âûáðàëè ïðåäìåò äëÿ ðåäàêòèðîâàíèÿ ñ ïîìîùüþ ñôåðû òðàíñôîðìàöèè.", oActivator, FALSE); return;};

    if(GetIsObjectValid(oTarget) && GetObjectType(oTarget)==OBJECT_TYPE_ITEM)
        {
        FloatingTextStringOnCreature("Ïðåäìåò äîáàâëåí â êà÷åñòâå ñûðüÿ ê '"+GetName(oParentRawTarget)+"'" , oActivator, FALSE);
        }
        else
        {
        FloatingTextStringOnCreature("Íå ïîäõîäÿùèé ïðåäìåò.", oActivator, FALSE);
        SetLocalInt(oActivator, "pt_craft_dialToolIsRawSeeRawSp", TRUE);
        AssignCommand(oActivator, ActionStartConversation(oActivator, "pt_axcrf_main", TRUE, FALSE));
        return;
        };

    //Çàäàíèå ïåðåìåííûõ äëÿ äèàëîãà
    string sRawsString=GetLocalString(oParentRawTarget, "pt_CRAFT_RAW");
    int iRawLen=pArrayLength(sRawsString);

    iNumDialogNodes=iRawLen;
    iNumDialogNodes++;
    string sNumDialogNodes=IntToString(iNumDialogNodes);

    SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_ItemRawTag", GetTag(oTarget));
    if(sRawsString!="") {sRawsString+=","+GetTag(oTarget);} else{sRawsString=GetTag(oTarget);};
    SetLocalString(oParentRawTarget, "pt_CRAFT_RAW", sRawsString);

    //Çàäàíèå äëèííû ìàññèâà
    SetLocalInt(oActivator, "pt_craft_dialNodeArray_Length", iNumDialogNodes);
    //debug
    //SendMessageToPC(GetFirstPC(), "'"+GetName(oCrftItem)+"' Çàïèñü äàííûõ â ïåðåìåííûå");

    SetLocalInt(oActivator, "pt_craft_dialToolIsRawSeeRawSp", TRUE);
    AssignCommand(oActivator, ActionStartConversation(oActivator, "pt_axcrf_main", TRUE, FALSE));

    return;
    }


//Ìàëàÿ ïàëêà èíñòðóìåíòîâ
    else if(sToolTag=="pt_craft_tool_DMs04")
    {
    oParentRawTarget=GetLocalObject(oActivator, "pt_craft_dialToolIsRawCreateTarget");
    if(!GetIsObjectValid(oParentRawTarget)){FloatingText
StringOnCreature("Âû íå âûáðàëè ïðåäìåò äëÿ ðåäàêòèðîâàíèÿ ñ ïîìîùüþ ñôåðû òðàíñôîðìàöèè.", oActivator, FALSE);return;};

    if(GetIsObjectValid(oTarget))
        {
        FloatingTextStringOnCreature("Ïðåäìåò äîáàâëåí â êà÷åñòâå èíñòðóìåíòà ê '"+GetName(oParentRawTarget)+"'" , oActivator, FALSE);
        }
        else
        {
        FloatingTextStringOnCreature("Íå ïîäõîäÿùèé ïðåäìåò.", oActivator, FALSE);
        SetLocalInt(oActivator, "pt_craft_dialToolIsRawSeeToolSp", TRUE);
        AssignCommand(oActivator, ActionStartConversation(oActivator, "pt_axcrf_main", TRUE, FALSE));
        return;
        };
    //Çàäàíèå ïåðåìåííûõ äëÿ äèàëîãà
    string sToolsString=GetLocalString(oParentRawTarget, "pt_CRAFT_TOOL");
    int iToolLen=pArrayLength(sToolsString);

    iNumDialogNodes=iToolLen;
    iNumDialogNodes++;
    string sNumDialogNodes=IntToString(iNumDialogNodes);

    SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_ItemToolTag", GetTag(oTarget));
    if(sToolsString!="") {sToolsString+=","+GetTag(oTarget);} else{sToolsString=GetTag(oTarget);};
    SetLocalString(oParentRawTarget, "pt_CRAFT_TOOL", sToolsString);

    //Çàäàíèå äëèííû ìàññèâà
    SetLocalInt(oActivator, "pt_craft_dialNodeArray_Length", iNumDialogNodes);
    //debug
    //SendMessageToPC(GetFirstPC(), "'"+GetName(oCrftItem)+"' Çàïèñü äàííûõ â ïåðåìåííûå");

    SetLocalInt(oActivator, "pt_craft_dialToolIsRawSeeToolSp", TRUE);
    AssignCommand(oActivator, ActionStartConversation(oActivator, "pt_axcrf_main", TRUE, FALSE));

    return;
    }


//Ìàëàÿ ïàëêà íàâûêîâ
    else if(sToolTag=="pt_craft_tool_DMs06")
    {
    oParentRawTarget=GetLocalObject(oActivator, "pt_craft_dialToolIsRawCreateTarget");
    if(!GetIsObjectValid(oParentRawTarget)){FloatingText
StringOnCreature("Âû íå âûáðàëè ïðåäìåò äëÿ ðåäàêòèðîâàíèÿ ñ ïîìîùüþ ñôåðû òðàíñôîðìàöèè.", oActivator, FALSE);return;};

    FloatingTextStringOnCreature("Ïðîèçíåñèòå èäåíòèôèêàòîð íàâûêà", oActivator, FALSE);

    SetLocalInt(oActivator, "pt_craft_dialToolIsRawCreateSkillSt", TRUE);

    return;
    }



//Ìàëàÿ ñôåðà ïðîñìîòðà ñûðüÿ
    else if(sToolTag=="pt_craft_tool_DMs03")
    {
    oParentRawTarget=GetLocalObject(oActivator, "pt_craft_dialToolIsRawCreateTarget");
    if(!GetIsObjectValid(oParentRawTarget)) {FloatingTextStringOnCreature("Âû íå âûáðàëè ïðåäìåò äëÿ ðåäàêòèðîâàíèÿ ñ ïîìîùüþ ñôåðû òðàíñôîðìàöèè.", oActivator, FALSE); return;};

    SetLocalInt(oActivator, "pt_craft_dialToolIsRawSeeRawSp", TRUE);

    AssignCommand(oActivator, ActionStartConversation(oActivator, "pt_axcrf_main", TRUE, FALSE));
    return;
    }


//Ìàëàÿ ñôåðà ïðîñìîòðà èíñòðóìåíòîâ
    else if(sToolTag=="pt_craft_tool_DMs05")
    {
    oParentRawTarget=GetLocalObject(oActivator, "pt_craft_dialToolIsRawCreateTarget");
    if(!GetIsObjectValid(oParentRawTarget)) {FloatingTextStringOnCreature("Âû íå âûáðàëè ïðåäìåò äëÿ ðåäàêòèðîâàíèÿ ñ ïîìîùüþ ñôåðû òðàíñôîðìàöèè.", oActivator, FALSE); return;};

    SetLocalInt(oActivator, "pt_craft_dialToolIsRawSeeToolSp", TRUE);

    AssignCommand(oActivator, ActionStartConversation(oActivator, "pt_axcrf_main", TRUE, FALSE));
    return;
    }


//Ìàëàÿ ñôåðà ïðîñìîòðà íàâûêîâ
    else if(sToolTag=="pt_craft_tool_DMs07")
    {
    oParentRawTarget=GetLocalObject(oActivator, "pt_craft_dialToolIsRawCreateTarget");
    if(!GetIsObjectValid(oParentRawTarget)) {FloatingTextStringOnCreature("Âû íå âûáðàëè ïðåäìåò äëÿ ðåäàêòèðîâàíèÿ ñ ïîìîùüþ ñôåðû òðàíñôîðìàöèè.", oActivator, FALSE); return;};

    SetLocalInt(oActivator, "pt_craft_dialToolIsRawSeeSkillSp", TRUE);

    AssignCommand(oActivator, ActionStartConversation(oActivator, "pt_axcrf_main", TRUE, FALSE));
    return;
    };
////////////////////////////////////////////////////
////////////////////////////////////////////////////





//////////////////////////
//Èíñòðóìåíò èçíàøèâàåòñÿ
int iMaxUses=GetLocalInt(oTool, "pt_CRAFT_PROCESS_NUMUSE");
int iCurUses=GetLocalInt(oTool, "pt_curCraftProcess_uses");
iCurUses++;
SetLocalInt(oTool, "pt_curCraftProcess_uses", iCurUses);
if(iCurUses>iMaxUses && iMaxUses>0)
    {
    //debug
    FloatingTextStringOnCreature("Ïðîöåññ íåâîçìîæåí. Ðåñóðñ èíñòðóìåíòà èñ÷åðïàí.", oActivator, FALSE);

    int iToolObjectType=GetObjectType(oTool);
    float fRespTime=GetLocalFloat(oTool, "pt_CRAFT_PROCESS_RESPTIME");
    if(fRespTime>0.0 && iToolObjectType!=OBJECT_TYPE_ITEM && iToolObjectType!=OBJECT_TYPE_TRIGGER)
        {
        string sToolResRef=GetResRef(oTool);
        object oBuoy=CreateObject(OBJECT_TYPE_PLACEABLE, "plc_invisobj", GetLocation(oTool));
        float fCurRespTime=fRespTime+IntToFloat(Random(FloatToIn
t(fRespTime)/2));

        AssignCommand(oBuoy, DelayCommand(fCurRespTime, pCreateObjectInLocal(oBuoy, "pt_curCraftProcess_buoytool", iToolObjectType, sToolResRef, GetLocation(oBuoy))));

        AssignCommand(oBuoy, DelayCommand(fCurRespTime+0.1, SetLocalInt(GetLocalObject(oBuoy, "pt_curCraftProcess_buoytool"), "pt_CRAFT_PROCESS_NUMUSE", iMaxUses)));
        AssignCommand(oBuoy, DelayCommand(fCurRespTime+0.1, SetLocalFloat(GetLocalObject(oBuoy, "pt_curCraftProcess_buoytool"), "pt_CRAFT_PROCESS_RESPTIME", fRespTime)));

        AssignCommand(oBuoy, DelayCommand(fCurRespTime+0.1, DestroyObject(oBuoy)));
        };

    DeleteLocalInt(oActivator, "pt_curCraftProcess_Mode");
    DeleteLocalInt(oActivator, "pt_curCraftProcess_ScriptMode");
    DeleteLocalLocation(oActivator, "pt_craft_PClocation");
    DestroyObject(oTool);

    return;
    };









//Øêóðà àêòèâàòîðà
object oSkin=GetItemInSlot(INVENTORY_SLOT_CARMOUR, oActivator);

//Ïîñëåäíèé èñïîëüçóåìûé èíñòðóìåíò, ìîæåò èñïîëüçîâàòüñÿ â ñêðèïòàõ ïðîöåññà.
SetLocalObject(oActivator, "pt_craft_lastUsedTool", oTool);







//////////////////////////////////////////////
///Íà÷àëî öèêëà ïîñòðîåíèÿ âîçìîæíûõ ïðîöåññîâ
//////////////////////////////////////////////
int i, k, l, m;
int iMaxIItem=GetLocalInt(oModule, "pt_CraftItemBoxArray_Length");
for(i=0; i<iMaxIItem; i++)
    {
    string sI=IntToString(i);
    DeleteLocalObject(oActivator, "pt_craft_dialNodeArray"+sI+"_Object");
    DeleteLocalString(oActivator, "pt_craft_dialNodeArray"+sI+"_ItemName");
    ///////////////////////////////////////////////////////////////////////
    object oCrftItem=GetLocalObject(oModule, "pt_CraftItemBoxArray"+sI);

    if(!GetIsObjectValid(oCrftItem)) continue;


    //Áîëüøàÿ êíèãà êðàôòà
    if(GetTag(oTool)=="pt_craft_tool_DMbook")
        {
        iNumDialogNodes++;
        string sNumDialogNodes=IntToString(iNumDialogNodes);

        SetLocalObject(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_Object", oCrftItem);
        SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_ItemName", GetName(oCrftItem));

        SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_Skills", GetLocalString(oCrftItem, "pt_CRAFT_SKILL_ID"));
        SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_SkillsVal", GetLocalString(oCrftItem, "pt_CRAFT_SKILL_VALUE"));
        SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_RawNames", GetLocalString(oCrftItem, "pt_CRAFT_RAW"));
        SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_RawCost", GetLocalString(oCrftItem, "pt_CRAFT_RAW_COST"));

        SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_ToolNames", GetLocalString(oCrftItem, "pt_CRAFT_TOOL"));

        //debug
        //SendMessageToPC(GetFirstPC(), "'"+GetName(oCrftItem)+"' Çàïèñü äàííûõ â ïåðåìåííûå");

        continue;
        };



















///////////////////
////Ïðîâåðêà íàâûêà
    string sProcSkill=GetLocalString(oCrftItem, "pt_CRAFT_SKILL_ID");
    string sProcSkillVal=GetLocalString(oCrftItem, "pt_CRAFT_SKILL_VALUE");
    int iSkillLen=pArrayLength(sProcSkill);
    int iSkillValLen=pArrayLength(sProcSkillVal);
    int bClosedSkill=FALSE;
    for(k=0; k<iSkillLen; k++)
        {
        int iValK=(k<=(iSkillValLen-1)?k:iSkillValLen-1);

        string sSkillID=pArray(sProcSkill, k);
        sSkillID=GetStringLeft(sSkillID, 35);

        //Áîëüøàÿ ïàëêà íàâûêîâ
        if(GetTag(oTool)=="pt_craft_tool_DMs00")
            {
            int z, bHasThatSkill;
            bHasThatSkill=FALSE;
            for(z=0; z<=iNumDialogNodes+1; z++)
                {
                if(GetLocalString(oActivator, "pt_craft_dialNodeArray"+IntToString(z)+"_ItemName")==sSkillID) {bHasThatSkill=TRUE; break;};
                };
            if(!bHasThatSkill)
                {
                iNumDialogNodes++;
                string sNumDialogNodes=IntToString(iNumDialogNodes);

                SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_ItemName", sSkillID);
                };

            //debug
            //SendMessageToPC(GetFirstPC(), "'"+GetName(oCrftItem)+"' Çàïèñü äàííûõ â ïåðåìåííûå");

            continue;
            }
            else
            {
            float fActivatorSkill=GetLocalFloat(oSkin, "pt_craft_skill_"+sSkillID+"_value");

            if(fActivatorSkill<0.0 || GetLocalInt(oSkin, "pt_craft_skill_"+sSkillID+"_DMblock")) {bClosedSkill=TRUE; break;};
            };
        };
    if(bClosedSkill) continue;
    //debug
    //SendMessageToPC(GetFirstPC(), "'"+GetName(oCrftItem)+"' Ïðîâåðêà ñêèëà óñïåøíà.");


    //Áîëüøàÿ ïàëêà íàâûêîâ
    if(GetTag(oTool)=="pt_craft_tool_DMs00")
        {
        continue;
        };























////////////////////////////////////
////Ïðîâåðêà âûçûâàþùåãî èíñòðóìåíòà
    string sProcTool=GetLocalString(oCrftItem, "pt_CRAFT_TOOL");
    string sProcToolNames=sProcTool;
    int iToolLen=pArrayLength(sProcTool);

    string sCurToolTag=sToolTag;
    int iCurToolIndex=-1;
    for(k=0; k<iToolLen; k++)
        {
        string sToolTemp=pArray(sProcTool, k);
        if(sCurToolTag==sToolTemp || ((sProcTool=="" || sProcTool=="pt_craft_tool_") && sCurToolTag=="pt_craft_tool_")) {sProcToolNames=pArray(sProcToolNames, k, GetName(oTool)); iCurToolIndex=k; break;};
        };
    if(iCurToolIndex<0) continue;
    //debug
    //SendMessageToPC(GetFirstPC(), "'"+GetName(oCrftItem)+"' âûäåëèëè èíñòðóìåíò âûçîâà. ("+pArray(sProcTool, iCurToolIndex)+")");















/////////////////////////
////Ïðîâåðêà èíñòðóìåíòîâ
    int bNotHasAllTool=FALSE;
    for(k=0; k<iToolLen; k++)
        {
        int bHasTool=FALSE;

        if(iCurToolIndex==k) continue;

        string sToolTag=pArray(sProcTool, k);


        object oPlaTool=GetNearestObjectByTag(sToolTag, oActivator); //Scan near activator
        if(GetIsObjectValid(oPlaTool) && GetObjectType(oPlaTool)!=OBJECT_TYPE_ITEM && GetDistanceBetween(oPlaTool, oActivator)<=3.0) {sProcToolNames=pArray(sProcToolNames, k, GetName(oPlaTool)); bHasTool=TRUE;};
        if(!bHasTool)
            {
            int iCurItemSlot=0;
            object oActItem=GetItemInSlot(iCurItemSlot, oActivator);
            while(!bHasTool && iCurItemSlot<=17) //Scan in equipeble slots
                {
                if(GetTag(oActItem)==sToolTag) {sProcToolNames=pArray(sProcToolNames, k, GetName(oActItem)); bHasTool=TRUE; break;};

                iCurItemSlot++; oActItem=GetItemInSlot(iCurItemSlot, oActivator);
                };
            if(!bHasTool)
                {
                oActItem=GetFirstItemInInventory(oActivator);
                while(!bHasTool && GetIsObjectValid(oActItem)) //Scan in inventory
                    {
                    if(GetTag(oActItem)==sToolTag) {sProcToolNames=pArray(sProcToolNames, k, GetName(oActItem)); bHasTool=TRUE; break;};

                    oActItem=GetNextItemInInventory(oActivator);
                    };
                };
            };

        if(!bHasTool) {bNotHasAllTool=TRUE; break;};
        };
    if(bNotHasAllTool) continue;
    //debug
    //SendMessageToPC(GetFirstPC(), "'"+GetName(oCrftItem)+"' Ïðîâåðêà îñòàëüíûõ èíñòðóìåíòîâ óñïåøíà");




































//////////////////////////////
////Ïðîâåðêà íèìåíîâàíèé ñûðüÿ
    string sProcRaw=GetLocalString(oCrftItem, "pt_CRAFT_RAW");
    string sProcRawNames=GetLocalString(oCrftItem, "pt_CRAFT_RAW");
    string sProcRawCost=GetLocalString(oCrftItem, "pt_CRAFT_RAW_COST");
    string sProcActivatorRawValue="0";

    int iRawLen=pArrayLength(sProcRaw);
    int iRawCostLen=pArrayLength(sProcRawCost);

    int bNotHasAllRaw=FALSE;
    for(k=0; k<iRawLen; k++)
        {
        string sRawTag=pArray(sProcRaw, k);

        int bHasRaw=TRUE;
        object oActItem=GetFirstItemInInventory(oActivator);
        while(GetIsObjectValid(oActItem))
            {
            if(GetTag(oActItem)==sRawTag)
                {
                sProcRawNames=pArray(sProcRawNames, k, GetName(oActItem));

                int iActRawVal=StringToInt(pArray(sProcActivatorRawVal
ue, k));
                iActRawVal+=GetItemStackSize(oActItem);
                sProcActivatorRawValue=pArray(sProcActivatorRawVal
ue, k, IntToString(iActRawVal));
                bHasRaw=TRUE;
                };

            oActItem=GetNextItemInInventory(oActivator);
            };
        if(!bHasRaw) {bNotHasAllRaw=TRUE; break;};
        };
    if(bNotHasAllRaw) continue;
    //debug
    //SendMessageToPC(GetFirstPC(), "'"+GetName(oCrftItem)+"' Ôîðìèðîâàíèå ìàññèâà íàëè÷èÿ ñûðüÿ óñïåøíî.");















/////////////////////////////
////Ïðîâåðêà êîëè÷åñòâà ñûðüÿ

    //debug
    //SendMessageToPC(GetFirstPC(), "'"+GetName(oCrftItem)+"' Òðåáîâàíèå ñûðüÿ: "+sProcRawCost);
    //debug
    //SendMessageToPC(GetFirstPC(), "'"+GetName(oCrftItem)+"' Íàëè÷èå ñûðüÿ: "+sProcActivatorRawValue);
    int bNotHasAllRawQuant=FALSE;
    for(k=0; k<iRawLen; k++)
        {
        int iCostK=(k<=(iRawCostLen-1)?k:iRawCostLen-1);

        int iCurRawCost=StringToInt(pArray(sProcRawCost, iCostK));
        int iCurRawHave=StringToInt(pArray(sProcActivatorRawVa
lue, iCostK));

        if(iCurRawCost<0) iCurRawCost=1;

        if(iCurRawHave<iCurRawCost) {bNotHasAllRawQuant=TRUE; break;};
        };
    if(bNotHasAllRawQuant) continue;
    //debug
    //SendMessageToPC(GetFirstPC(), "'"+GetName(oCrftItem)+"' Ïðîâåðêà êîëè÷åñòâà ñûðüÿ ó èãðîêà óñïåøíà.");



















/////////////////////////////////////////////////////////////////////
////Çàäàíèå ïåðåìåííûõ åñëè âñå ïðîâåðêè óñïåøíû äëÿ äàííîãî ïðîöåññà
    iNumDialogNodes++;
    string sNumDialogNodes=IntToString(iNumDialogNodes);

    SetLocalObject(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_Object", oCrftItem);
    SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_ItemName", GetName(oCrftItem));

    SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_Skills", sProcSkill);
    SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_SkillsVal", sProcSkillVal);
    SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_RawNames", sProcRawNames);
    SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_RawCost", sProcRawCost);

    SetLocalString(oActivator, "pt_craft_dialNodeArray"+sNumDialogNodes+"_ToolNames", sProcToolNames);

    //debug
    //SendMessageToPC(GetFirstPC(), "'"+GetName(oCrftItem)+"' Çàïèñü äàííûõ â ïåðåìåííûå");



    };
/////////////////////////////////////////////
//Çàäàíèå äëèííû ìàññèâà ïîëó÷åííûõ ïðîöåññîâ
SetLocalInt(oActivator, "pt_craft_dialNodeArray_Length", iNumDialogNodes+1);




/////////////////////////
//Çàïóñê äèàëîãîâîãî ìåíþ
if(iNumDialogNodes>=0) AssignCommand(oActivator, ActionStartConversation(oActivator, "pt_axcrf_main", TRUE, FALSE));
}


Собственно, это и есть универсальный скрипт активации инструмента. Думаю, уважаемый PaiNt оставил пробелы, чтобы юзер мог дописать что-то нужное конкретно ему. Но тут я понять что-то и не пытаюсь, не мой уровень. Может, кто-то из мастеров поймет?
А если нет, или просто лениво вникать, то господь с ней, с системой PaiNt_craft. Потому что тема не только и не столько о ней. Но об этом позже, и так пост раздулся, лопнет еще...

Пока писал, подумал (я уже говорил, со мной такое случается (IMG:style_emoticons/kolobok_light/rolleyes.gif) ).
Обратил внимание на строчку " ExecuteScript("pt_axcrf_activ", oActivator);" скрипта настроек модуля "x2_mod_def_act". Она же запускает главный скрипт инструмента! Тот самый, который второй и такой большой...
Может она это постоянно делать, поскольку в настройках модуля прописана? Если так, то понятно. Такого ни один грузчик не выдержит, не то что мой маленький модуль.
Однако, надо полагать, уважаемый PaiNt не просто так ее вписал... И не мог не предусмотреть какую-то "страховку" от зацикливания команды?
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
denis0k
сообщение Nov 5 2017, 12:54
Сообщение #2


Level 19
Иконки Групп

Класс: Воин
Характер: Lawful Good
Раса: Человек
NWN: Скриптинг [PW]
Gem of the North
Край Лесов



На этапе компиляции в скрипт подцепляются все инклуды, поэтому ошибка может быть как в самом скрипте, так и в его "вложениях". Слишком много инструкций - это в 99% случаев цикл с большим количеством итераций. Под большим имеется в виду реальное большое число, скорее всего это тысячи итераций (зависит от количества кода в цикле).

В нвскрипте есть защита от зацикливания. Инструкции - это базовый набор команд, на которых скриптовая машина работает - присвоение, арифметические операции, вызов функций и т.п. Лимит на количество инструкций - 131к. Это с виду много, но одним хорошим циклом его легко выработать.

Для серверов есть nwnx и там есть плагин для увеличения лимита. Но я бы сильно не обольщался - нвскрипт тормозной, он перестанет выдавать ошибки, но может нарастить лаги.


Что касается конкретно этого скрипта - я в нём не разбирался, это долго и бессмысленно, т.к. без нвн его всё равно не проверить (IMG:style_emoticons/kolobok_light/smile.gif) Но там есть циклы for, смотри в первую очередь туда. Возможно, условие окончания цикла слишком далеко - там считывается какая-то переменная, поставь её гораздо меньше. Или она вообще у тебя отсутствует, скрипт считает её за 0 и бажит.


Что касается крафта в нвн в принципе. Я писал довольно сложные. Всё, что нужно, в нвн есть - создание итемов, навешивание на них свойств. Сложность только с изменением внешнего вида сложных итемов (это можно, но гемор), но тут можно пойти по пути других игр и просто сделать в палитре несколько разных болванок и играть с ними.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Chiffa
сообщение Nov 5 2017, 15:33
Сообщение #3


Level 6
**

Класс: Волшебник
Характер: Chaotic Good
Раса: Человек



Уважаемый denis0k, спасибо что откликнулись. Вряд ли я способен разобраться с такими скриптами. С годами - может быть. Но тратить годы, как верно подмечено:
Цитата(denis0k @ Nov 5 2017, 12:54) *
это долго и бессмысленно

Так что и правда, господь с ней, с системой PaiNt_craft. По крайней мере, пока. Поговорить хотелось о другом.
Цитата(denis0k @ Nov 5 2017, 12:54) *
Что касается крафта в нвн в принципе. Я писал довольно сложные. Всё, что нужно, в нвн есть - создание итемов, навешивание на них свойств. Сложность только с изменением внешнего вида сложных итемов

Тут позволю себе не согласиться. Крафт, ПМСМ, начинается все-таки не с этого. А с добычи. А это не только и не столько монстры ради шкурок-костей и т.п. Это активные плейсы. Я в "робинзонаде" пока поставил только четыре вида. Это "выход горной породы" (добывать кремень для ножиков-топоров), это "пласт песчанника" (точильные камни и стройматериал), это "годный куст" (волокно для тканей-веревок), ну и "годное дерево" - понятно для чего.
И произошло следующее. Герой стал дергаться, как эпилептик. Постоянно поворачивается куда угодно, только не туда, куда его посылаешь мышкой. Его атакует "морская тыдра" (ну не называть же эту тварь на "вы" - выдрой (IMG:style_emoticons/kolobok_light/biggrin.gif) ), а он куда-то опять поворачивается. У него захлопывается инвентарь сразу после открывания. Он не может подобрать дроп без нажатого пробела - все схлопывается.
Много еще он чего не так делает, но если в двух словах, то ПС стал практически неуправляем.
Да, сначала добыча у меня начиналась через диалог типа "Ага, вот деревце, а где мой топор?" и т. п. Но у меня таки хватило ума ставить скрипт, включающий эти диалоги, на "OnUsed" плейсов, а не на "OnClick" или куда похуже. Расстояние - 2 метра. Так он за километры пытается побеседовать "по душам" с плейсом, вместо того, что от него требуется.
Очень дорожу атмосферностью, но при таких делах отключил диалоги вовсе. Не помогло... Плейс "поговорить" не хочет и уже не может, а герой все одно дергается.
Убрал все породы и песчанники под землю, в пещеру к крысам. Кустики-деревца перенес на соседний островок. Не помогло.
Как говорил прапорщик Наливайко "или я дурак или одно из двух".
Понимаю, что не имея нвн и не видя моего мода, сходу не сообразишь, в чем беда. Но, уважаемые мастера, у вас нет нвн, зато есть опыт. И вы можете хотя бы предположить, в чем проблема? В моей, миль пардон, рукожопости или все-таки, упаси бог, в движке авроры?
Спасибо.
З.Ы.Да, насчет сложности крафта я не сильно парюсь. (За исключением этой чертовой добычи!) Взял систему из ПЛ, которую, если я правильно понял, сочинял DBColl. А этот гений (пишу без кавычек, заметьте!) нагородил огород из секретных плейсов, ящиков, специальных полезных таблиц 2ДА и много еще чего, но у него, как у ТруЪ-индуса непонятно почему, но все работает. И я почему-то не сомневаюсь, что даже когда 2ДА-табличка раздуется до размеров "Войны и мира", все равно будет все работать.


Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
denis0k
сообщение Nov 5 2017, 23:58
Сообщение #4


Level 19
Иконки Групп

Класс: Воин
Характер: Lawful Good
Раса: Человек
NWN: Скриптинг [PW]
Gem of the North
Край Лесов



Вообще не представляю, в чём проблема (IMG:style_emoticons/kolobok_light/smile.gif) Я могу только сказать, что я на двух шардах работал и ещё несколько модулей пилил, нигде персонажи эпилепсией не страдали (IMG:style_emoticons/kolobok_light/smile.gif) Но я обычно не брал цельные чужие наработки, всё больше писал сам с нуля. Или разбирался досконально и всё равно писал с нуля скелет, втыкая в него готовые авторские модули функций/скриптов.

Индусского кода действительно очень много, в любых языках программирования. Тут сложно что-то посоветовать, кроме как двух вариантов: либо разобраться в программировании самому, либо найти другую систему, которая таки заработает. Поковыряй волт.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Chiffa
сообщение Nov 6 2017, 04:28
Сообщение #5


Level 6
**

Класс: Волшебник
Характер: Chaotic Good
Раса: Человек



Цитата(denis0k @ Nov 5 2017, 23:58) *
Вообще не представляю, в чём проблема (IMG:style_emoticons/kolobok_light/smile.gif)

Разобрался сам. Но с твоей помощью, спасибо. Понимаешь, столь уверенное заявление мастера, что "такого не может быть, потому что не может быть никогда" подсказало мне идею провести жестокий эксперимент. Над собой, любимым, прежде всего.
Посидел ночку, нарисовал нечто подобное моей робинзонаде, только в "Шадоу". Скопипастил туда скрипты и диалоги блокнотиком (экспорт-импорт невозможен по понятным причинам). И специально нарисовал этих пресловутых активных плейсов побольше, побольше, побольше... (IMG:style_emoticons/kolobok_light/biggrin.gif)
И что? Да, герой чуть дергается, но играть это не мешает. А когда свел количество плейсов к оптимальному, так и это дерганье прекратилось.
Скопировал что получилось в "лошадки". Там - опять эпилепсия у героя, да еще какая!
И биовари, кстати, тоже в этот раз не виноваты. Мне досталась какая-то локализация с локализации версии НВН. И чего там еще накосячено - сам Бейн не разберется.
Просто к слову, типа примера:
Этот неизвестный , извините за выражение, локализатор налепил в папку "portraits":
1. Агроном, сын Агронома - 8 штук,
2. Гиви, сын Реваза - 3 штуки,
3 эльф Логоваз - 7 штук
4 Пендальф - поленился считать, но много.
Всегда с настороженностью относился к толкиенутым...
Фотографии безобразные. Полдня сидел в инете, подыскивая морды поприличнее и еще два дня сидел за фотошопом, приводя папку "portraits" в более менее приличный вид.
И вот почему я сразу, еще тогда, не подумал, что не надо ждать от этой толкиенутой версии "лошадок" ничего хорошего!!!
Дважды наступил ведь на эти грабли! Вывод: мне просто надо найти нормальную локализацию. И не "лошадок" даже, а все-таки "Хордесов".
Как резюме: тему можно закрывать, толком не открыв (IMG:style_emoticons/kolobok_light/swoon.gif) . Крафт в НВН возможен. Причем именно такой, ради которого я и затеял эту тему. То есть крафт полного цикла, от добычи самого простого сырья до изготовления самых сложных вещей.
Только просьба к уважаемым модераторам пока ее не закрывать. У меня еще немало вопросов по робинзонаде. Хотелось бы получить пусть не ответы, то хотя бы подсказки.
З.Ы.
Цитата(denis0k @ Nov 5 2017, 23:58) *
сложно что-то посоветовать, кроме как двух вариантов: либо разобраться в программировании самому, либо найти другую систему, которая таки заработает. Поковыряй волт.

Увы, поздно. Я, честно говоря, староват даже для того, чтобы просто учить английский, не говоря уже о программировании. Потому и был так рад тому, что форум ГМ еще жив.
И важное уточнение. denis0k, извини, если моя манера изложения навела тебя на ложные мысли. Я не "катил бочку" на систему крафта от DBColl, а совсем наоборот. Работает она как часики, несмотря на ее странности. Впрочем, может и "странности" эти таковыми кажутся только мне, а для специалиста - норма.


З.Ы.Ы.
Вероятно, в нормальной НВН и система PaiNtа будет работать без "зацикливаний". Просто у DBColl, как я понял, очень важную роль играет именно 2ДА-табличка, а уж до нее наш "локализатор" не имел никакой возможности добраться. Найду нормальный невер - проверю обязательно.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Aiwan
сообщение Nov 6 2017, 06:59
Сообщение #6


Миловидный Бегрюссунг
Иконки Групп

Класс: Воин
Характер: Chaotic Good
Раса: Человек
NWN: Модмейкер
Проклятие Левора
Порядок Времени



Chiffa, дружище, первое правило начинающего горнолыжника - не есть желтый снег. Первое правило модульмейкера - никаких кастрированных НВН. Только оригинал пропатченый до нужной версии. По поводу лагов. У нас в ПЛ был случай, хеньчша Каэтан в моем модуле жестко тупила вплоть до ухода в дауни, нвн лагал. Она никакая на команды не реагировала, перезагрузка не помогала. Ее я импортировал из ДБа модуля. Так вот, решил я ее сделать с нуля новую, без импорта. Импорт хотел сделал только диалог, позже. И о чудо, она зашавелилась, забегала, глюки пропали. Я ее везде проверил, решил все, импорт диалога и тут бац! Она опять объелась твиксов, так что весь нвн тупить стал. Посоветовались мы и решили ее утопить (IMG:style_emoticons/kolobok_light/smile.gif) Но потом я решил все же (а я упертый) все диалоги перенести текстом на созданный заново персонаж. Ну и что? Все заработало. Так вот, косячил просто диалог без скриптов который я импортировал. Как, почему, какого хрена? ХЗ. Вот такие косяки бывали у нас.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
denis0k
сообщение Nov 6 2017, 07:51
Сообщение #7


Level 19
Иконки Групп

Класс: Воин
Характер: Lawful Good
Раса: Человек
NWN: Скриптинг [PW]
Gem of the North
Край Лесов



Да, с НПС беда конечно. Я когда ИИ боссам писал, отхлебнул (IMG:style_emoticons/kolobok_light/smile.gif) В результате босса-кастера, способного биться несколько минут, так и не сделал - каст через некоторое время просто зависает, в каждой попытке через разное количество времени. Возможно, этот баг никто не заметил, т.к. ~200-300 хитов выбиваются за пару раундов в обычных условиях (до зависания), но при 5000+ хп с закосом под фазированные бои ММО злой маг просто выключается в бою, т.к. перестают работать ActionCastSpell*.

Но вот с крафтом проблем не было (IMG:style_emoticons/kolobok_light/smile.gif)
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Chiffa
сообщение Nov 6 2017, 09:33
Сообщение #8


Level 6
**

Класс: Волшебник
Характер: Chaotic Good
Раса: Человек



Цитата(Aiwan @ Nov 6 2017, 06:59) *
первое правило начинающего горнолыжника

Не-е, я на пост Президента РФ не претендую. (IMG:style_emoticons/kolobok_light/biggrin.gif)
Больше нравится система воспитания детишек у чукчей. Всего два правила. Первое: "Нельзя есть желтый снег!". Второе: "Желтый снег есть нельзя!" Оба правила знал назубок - и вот так вляпался...
Цитата(Aiwan @ Nov 6 2017, 06:59) *
...никаких кастрированных НВН.

Ладно бы кастрированная. Так наоборот, с лишними э-э-э ... органами.
Цитата(Aiwan @ Nov 6 2017, 06:59) *
...а я упертый...

Я тоже. Потому и угробил ночь, сев за комп просто в омерзительном настроении, ибо не имел понятия, какой получу результат и получу ли его вообще. Теперь, правда, выходит, что не так уж и угробил. Хотя мог бы давно сообразить: человек, напрочь лишенный вкуса, ничего путного не сделает. Ведь и фильм хороший (особенно гоблинский вариант (IMG:style_emoticons/kolobok_light/biggrin.gif) ) и артисты там обаятельные. И такие отвратные рожи с так криворуко сделанных скринов. "Локализация" могла быть только соответствующая.
Но заканчиваю флуд, попробую насмешить народ немного более иначе. У меня в робинзонаде снова получился чит, и опять невольный. А дело вот в чем. Все больше и больше я усложняю жизнь своему робинзону. Приучаю к дисциплине и аккуратности. Чтобы породу долбил строго киркой, дерево рубил топором, кусты, соответственно, серпом. Но тут ничего сложного: бьешь киркой породу - флаг сюжета снимается, бьешь чем-то другим - вешается взад. Впрочем, прошу прощения: кому я это объясняю... (IMG:style_emoticons/kolobok_light/bb.gif)
В общем, все проверки работают безупречно, а дальше получается смех. Вот, собственно:
Neverwinter Script
void main()
{
int HIT = GetLocalInt(OBJECT_SELF,"HIT");
int HP = GetLocalInt(OBJECT_SELF,"HP");
int CHP = GetCurrentHitPoints(OBJECT_SELF);
if (HP==0)
  {
  HP=GetMaxHitPoints();
  }
HIT = HIT + HP-CHP;
SetLocalInt(OBJECT_SELF,"HP",CHP);
if (HIT >=30)
  {
  HIT = HIT - 100;
  if (GetIsPC(GetLastDamager()))
        CreateItemOnObject("itm_peschan",GetLastDamager(),1);

  SendMessageToPC(GetLastDamager(),"Вы откололи кусок песчанника");
  }
SetLocalInt(OBJECT_SELF,"HIT",HIT);

{

string ref="";
switch(Random(30))

  {

  case 0: ref = "itm_ametist"; break; // Дополнительная награда за усердие, малодрагоценные камни. Драгоценные будут падать из руд металлов
  case 1: ref = "itm_awantyr"; break;
  case 2: ref = "itm_fire_agat"; break;
  case 3: ref = "itm_kvarcz"; break;
  case 4: ref = "itm_apatit"; break;
  case 5: ref = "itm_flourit"; break;
  }
if (ref!="")
  {

  object oItem = CreateItemOnObject(ref,GetLastDamager(),1);
  SetDroppableFlag(oItem,TRUE);
  }
}
}


Aiwan, что-то знакомое, так? Он самый, слегка измененный и чуть дописанный скрипт прокладки туннелей, куда безжалостный Lex загонял ПС-штрафников. Работает, ясен пень, тоже безупречно. А смех вот в чем. Я был уверен, что все эти аметисты-апатиты тоже привязаны к урону. То есть снес булыге 100 ХП - получи кусок печанника (ну, или кремня) + махонький рандомный камушек (не всегда).
Оказалось - нет. Если взять вместо кирки меч поострее, то никаких песчанников-кремней ты не отколешь, булыгу защитит флаг. А вот дополнительная награда будет сыпаться. Под аккомпанемент дефолтных визгов: "Оружие неэффективно!" "Вы не можете нанести повреждение текущим оружием!" (IMG:style_emoticons/kolobok_light/biggrin.gif)
И чем острее оружие тестера, тем больше будет этих камушков!
Почему, собственно? Ведь скрипт строит на OnDamaged булыжника. И просто по определению должен быть привязан к нанесенному плейсу демагу. Или нет?
Как прекратить это безобразие? Я пытался вставить проверку на хиты и урон еще раз, перед камушками. На все мои попытки компилятор ругался тупо и косноязычно, как малолетний гопник.
Надеюсь, повеселил. Спасибо.
З.Ы. Пока не нашел нормальную НВН, переселяю робинзона в "Шадоу" насовсем. Редактор скрипта моих кастрированных лошадок час назад выделил строку "object oPC = GetPCSpeaker();" и написал "Непонятное условие компилятора."
Занавес...
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
denis0k
сообщение Nov 6 2017, 17:32
Сообщение #9


Level 19
Иконки Групп

Класс: Воин
Характер: Lawful Good
Раса: Человек
NWN: Скриптинг [PW]
Gem of the North
Край Лесов



Так и не понял, что хотел сделать автор арифметической магией в начале скрипта, но могу сказать, что скрипт работает с любым оружием, т.к. проверки на него нет (IMG:style_emoticons/kolobok_light/smile.gif) В нвскрипте есть функция на получение итема в слоте рук(и), можно просто проверить по тэгу - если не кирка, то return.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Chiffa
сообщение Nov 7 2017, 02:40
Сообщение #10


Level 6
**

Класс: Волшебник
Характер: Chaotic Good
Раса: Человек



Цитата(denis0k @ Nov 6 2017, 17:32) *
могу сказать, что скрипт работает с любым оружием, т.к. проверки на него нет (IMG:style_emoticons/kolobok_light/smile.gif)


Совершенно верно. Скрипт проверки стоит не на демаге (OnDamaged), а на физической атаке (OnPhysicalAttacked) булыжника. То есть герой только начинает атаковать, а ему:
Neverwinter Script
if(GetTag(oWeap)!="itm_kam_kirka" && (GetTag(oWeap)!="itm_krem_kirka")) // Не каменная и не кремневая кирка
SetPlotFlag(OBJECT_SELF,TRUE);
SendMessageToPC(GetLastDamager(),"Камни надо долбить киркой");

Ну, а если "инструмент" какой надо, тогда:
Neverwinter Script
if(GetTag(oWeap)=="itm_kam_kirka" || (GetTag(oWeap)=="itm_krem_kirka")) // Они, родимые, та или другая
SetPlotFlag(OBJECT_SELF,FALSE); // Убираем галку "сюжет" и демаж хоть до потери пульса


Хочешь сказать, что я ошибся и скрипты стоит слепить в один? Но куда его ставить, на демаг или на атаку?
Да и вряд ли это поможет, потому что смех совсем в другом. Скрипт проверки нормально работает, уж сколько раз проверял. Когда в руке меч хоть на +100500 (IMG:style_emoticons/kolobok_light/biggrin.gif) , все равно нет и не может быть никакого демага. Это со всей ответственностью подтверждают дефолтные визги "Оружие неэффективно!".
А скрипт, стоящий как раз на этом демаге сыплет тебе аметисты-аппатиты (основной добычи нет, тут все "честно").
Получилась этакая вечная читерская булыга. Долби ее чем угодно, кроме кирок, и всякие аметисты-агаты будут сыпаться бесконечно...
Вот я и спросил, как это безобразие прекратить?
Основная добыча (кремень, песчанник) привязана к хит-пойнтам булыги. Снял 100 ХП - получи кусок кремня. Снял еще сотню - еще один и так, пока все не раздолбишь. А дополнительная, получается, нет. Как привязать и ее тоже? Или что-то более другое надо сделать?

З.Ы. denis0k, извини, забыл поблагодарить за ссылку. Про волт я знал, но тем не менее спасибо. И вопрос. Помню, на этих волтах была огромная библиотека хаков. Причем русская. Она жива? Если да, то где, не в курсе, случайно? Старые ссылки показывают 404...


Цитата(denis0k @ Nov 6 2017, 17:32) *
Так и не понял, что хотел сделать автор арифметической магией в начале скрипта

denis0k, ты уникум! Мастер с заглавной буквы "М", у тебя даже подколки идут на пользу делу. (IMG:style_emoticons/kolobok_light/biggrin.gif)
Короче, проблема решена. Я также задумался, зачем эта арифметическая магия понадобилась? Не будет же Lex просто так заниматься арифметическим словоблудием (цифроблудием, точнее). И понял (скорее на интуитивном уровне): да это же он хиты горемычной булыги подсчитывает! Сколько их имеется, сколько осталось, сколько ПС снес. Ну и потом что ему за этот демаг выдать.
Конечный скрипт стал даже короче:
Neverwinter Script
void main()
{
int HIT = GetLocalInt(OBJECT_SELF,"HIT");
int HP = GetLocalInt(OBJECT_SELF,"HP");
int CHP = GetCurrentHitPoints(OBJECT_SELF);
if (HP==0)
{
string ref="";
if (ref!="")
switch(Random(30))

  {
  case 0: ref = "itm_ametist"; break;
  case 1: ref = "itm_awantyr"; break;
  case 2: ref = "itm_fire_agat"; break;
  case 3: ref = "itm_kvarcz"; break;
  case 4: ref = "itm_apatit"; break;
  case 5: ref = "itm_flourit"; break;

  {
  HP=GetMaxHitPoints();
  }
HIT = HIT + HP-CHP;
SetLocalInt(OBJECT_SELF,"HP",CHP);
if (HIT >=30)
  {
  HIT = HIT - 100;
  if (GetIsPC(GetLastDamager()))
    CreateItemOnObject("ITM_KREM",GetLastDamager(),1);
  SendMessageToPC(GetLastDamager(),"Âû îòêîëîëè êóñîê êðåìíÿ");

    object oItem = CreateItemOnObject(ref,GetLastDamager(),1);
    SetDroppableFlag(oItem,TRUE);
    }

    SetLocalInt(OBJECT_SELF,"HIT",HIT);
    }
  }
}

И работает именно так, как я хотел. Выдает полудрагоценный камешек примерно после каждого второго добытого куска кремня или чуть реже. Я специально поставил тестового перса долбить эту булыгу хорошими мечами и ушел курить. Вернулся - он все долбит, но фиг ему что в инвентарь упало. Взял "кирку" и все пошло, как и было задумано.
Спасибо, уважаемые мастера! Прежде всего за моральную поддержку, дельные советы (желтого снега больше в рот не возьму! (IMG:style_emoticons/kolobok_light/biggrin.gif) ) и за к месту сказанные подколки. (IMG:style_emoticons/kolobok_light/biggrin.gif)


З.Ы.Ы. Вообще-то выше два разных поста, написаны с перерывом больше часа. Слепились в один почему-то. Хотел это объяснить, а также еще сказать о том, что проблема была для меня ну оч-чень важна. Не век же мой робинзон будет кремний долбить, в задумках и руды металлов, причем далеко не одного вида. И призовые камешки из этих руд будут сыпаться уже гораздо более другие. Вечные читерские рудные залежи стали бы кошмаром...
Спасибо!
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
denis0k
сообщение Nov 7 2017, 07:44
Сообщение #11


Level 19
Иконки Групп

Класс: Воин
Характер: Lawful Good
Раса: Человек
NWN: Скриптинг [PW]
Gem of the North
Край Лесов



Очевидно, что OnDamaged всё равно запускается, даже если урон нулевой. К слову, на неписях он запускается от любого урона, попробуй скалу атаковать спеллом после атаки киркой - так плот-флага не будет (после кирки), а урон пройдёт (IMG:style_emoticons/kolobok_light/smile.gif)
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Melisse
сообщение Nov 7 2017, 15:08
Сообщение #12


Level 11
Иконки Групп

Класс: Волшебник
Характер: Neutral Good
Раса: Фея
NWN: Скриптинг [PW]
Край Лесов



Если стоит ПлотФлаг событие не работает

Сообщение отредактировал Melisse - Nov 7 2017, 15:09
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
denis0k
сообщение Nov 7 2017, 17:55
Сообщение #13


Level 19
Иконки Групп

Класс: Воин
Характер: Lawful Good
Раса: Человек
NWN: Скриптинг [PW]
Gem of the North
Край Лесов



Событие не работает, а итемы создаются xD Мб у автора не 1.69, а ранее баги были просто.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Chiffa
сообщение Nov 8 2017, 00:29
Сообщение #14


Level 6
**

Класс: Волшебник
Характер: Chaotic Good
Раса: Человек



Цитата(denis0k @ Nov 7 2017, 07:44) *
Очевидно, что OnDamaged всё равно запускается, даже если урон нулевой. К слову, на неписях он запускается от любого урона, попробуй скалу атаковать спеллом после атаки киркой - так плот-флага не будет (после кирки), а урон пройдёт (IMG:style_emoticons/kolobok_light/smile.gif)

Даже проверять не буду, не сомневаюсь, что ты прав. Собственно, уже проверено. За подсказку про спеллы спасибо. Сейчас это не актуально, вряд ли кастер 1-4 уровня будет тратить на булыгу свой невеликий запас спеллов и каждый раз бегать в зону отдыха. Но когда дело дойдет до руд металлов, придется и эту тему вспомнить. (IMG:style_emoticons/kolobok_light/rolleyes.gif)
Цитата(Melisse @ Nov 7 2017, 15:08) *
Если стоит ПлотФлаг событие не работает

Разумеется. Вот только я и есть тот самый специальный полезный парень на котором удобно проверять все мыслимые и немыслимые исключения из всех правил. Если есть грабли - наступлю обязательно. Это называется "карма". (IMG:style_emoticons/kolobok_light/biggrin.gif) Одна только галка "ландшафт" чего стоила...

Цитата(denis0k @ Nov 7 2017, 17:55) *
Событие не работает, а итемы создаются xD Мб у автора не 1.69, а ранее баги были просто.

Конечно, баги. Только они и в "лошадках" и в 1.69, в старой, надежной как лом "Шадоу" (Держу, собственно, ради ПЛ). Говорю же, если грабли существуют в принципе - наступлю обязательно (см. выше).
Вот еще пример на тему просто похохотать. Как выяснилось, скрипт, второй, которому я радовался, вообще не работает. От слова "совсем". Когда он стоит, ничего из булыги не вышибешь. Ни ТруЪ-киркой, ни мечом на плюс стопитьсот, ни ядреной бомбой.
А произошло следующее. Тестер долбил мечами, пока я курил, одну булыгу. Потом я вернулся, дал ему кирку и кинул атаковать ... другую булыгу. Просто по запарке, рядом она стояла. И оказалась единственной, на которой я забыл старый скрипт. Вот у него и посыпались все, что надо и типа "как надо". (IMG:style_emoticons/kolobok_light/vava.gif) (IMG:style_emoticons/kolobok_light/biggrin.gif)
Говорю же, карма...
Сроду не признался бы в таком позорище, но, во-первых, должен поблагодарить мастеров за поддержку и участие, а лучший способ - улыбнуть. Во-вторых, я таки решил проблему. Понял, что все попытки запрячь в одну упряжку коня надежных и проверенных скриптов на рандом от Aiwanа и трепетную лань Lexовой "арифметической магии" (с) denis0k - и есть ошибка. Проще надо быть. (IMG:style_emoticons/kolobok_light/this.gif)
И решение оказалось действительно простым до смешного. Теперь, когда ПС снял 100 ХП с горемычной булыги, включается локалка. Тут же проверяется, если адын - начинают сыпаться всякие апатиты-флоуриты. Скрипт на OnDeath булыги и скрипты проверки оружия сбрасывают локалку на ноль. Profit!
Надеюсь, повеселил. Есть еще несколько проблем, но задам вопросы и/или попрошу подсказки попозже. Побьюсь пока сам, вдруг справлюсь.
Спасибо.

З.Ы. Еще раз хочу спросить насчет волтов. Там была огромная библиотека хаков. И все названия, пояснения, комменты в ней были на русском языке, ИЧСХ, слева направо. Вопрос купца Елисеева анекдота: кому она помешала?
Или она таки жива? Может, кто-то знает ссылку (старые не работают)?
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Aiwan
сообщение Nov 8 2017, 09:08
Сообщение #15


Миловидный Бегрюссунг
Иконки Групп

Класс: Воин
Характер: Chaotic Good
Раса: Человек
NWN: Модмейкер
Проклятие Левора
Порядок Времени



Волат помер, ща какая-то новая версия сайта. https://neverwintervault.org/
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Chiffa
сообщение Nov 9 2017, 06:04
Сообщение #16


Level 6
**

Класс: Волшебник
Характер: Chaotic Good
Раса: Человек



Цитата(Aiwan @ Nov 8 2017, 09:08) *
Волат помер, ща какая-то новая версия сайта. https://neverwintervault.org/

А вот это на самом деле неприятно. Ждал от проклятых буржуинов любой гадости, но вот что они применят против нас ТАКИЕ санкции! Все-таки всему должны быть какие-то рамки! (IMG:style_emoticons/kolobok_light/sad.gif)
Прошу прощения, что так неуклюже шучу, это от злости. За ссылку спасибо, только зная я ее, да и denis0k на днях дал ее же. То есть, похоже, других серьезных ресурсов больше не осталось. Только там все на поросячьей латыни (так римляне называли языки англосаксов, а римляне дураками не были). А я как старый цирковой пес, который уже не может научиться новым фокусам. Да и не хочет, если уж честно.
Просто прикинул, КАКОВО будет искать где-то и впихивать в хак эти каменные топоры, пальмовые юбки дикарок (не век же робинзонить!) и прочие шаманские бубны. И все это через гугл-переводчик... дурно делается.
Ладно, прекращаю нытье.
Уважаемые мастера, подскажите, есть ли способ уничтожать в инвентаре героя несколько предметов с одинаковым тегом? Точнее, не просто несколько, а совершенно определенное количество. Вот простой пример, робинзон делает ткань из местного травяного волокна:
Neverwinter Script
#include "lm_tsurl_lib"// Как я понял, инклюда, которую Lex сочинил специально для того, чтобы выдавать алкашу Вагису пиво строго по одной бутылочке.
void main()
{
object oVol = FindItem("trav_volokno",GetFirstPC()); // Травяное волокно в инвентаре ПС.
int Number = GetItemStackSize(oVol);
if (Number==1)
    DestroyObject(oVol);  //"Арифметическая магия", в которой я не разобрался...
else

SetItemStackSize(oVol,Number-4); // По идее, должен вычесть 4 куска волокна. Но только по идее, увы...

{
DelayCommand(0.5,AssignCommand(GetFirstPC(),ActionPlayAnimation(AN
IMATION_LOOPING_MEDITATE ,1.0f,5.0f))); //Ну с анимацией я еще покопаюсь, а пока фиг с ней, не до нее.
DelayCommand(2.5,AssignCommand(GetFirstPC(),ActionPlayAnimation(AN
IMATION_PLACEABLE_OPEN ,1.0f,5.0f)));
DelayCommand(4.5,AssignCommand(GetFirstPC(),ActionPlayAnimation(AN
IMATION_PLACEABLE_DEACTIVATE ,1.0f,5.0f)));
CreateItemOnObject("itm_rogozha", GetFirstPC(),1); // Получите, сеньор робинзон кусок ткани, который вы "лично сплели" из 4-х кусков волокна.
}
}


Скрип вполне себе рабочий. И волокно забирает, и ткань выдает. Только забирает не 4 куска волокна, а только один. В общем, что бы ни точил русский токарь, все-равно получается АКМ. Чтобы ни мудрил Chiffa, все равно получается читерство. (IMG:style_emoticons/kolobok_light/biggrin.gif)
ИЧСХ, скрипт проверки (основан на том же принципе) вполне себе корректный. Если волокон в инвентаре меньше четырех, строка диалога "займусь тканью" не открывается.
Понятно, обходные пути есть. Так, веревку сплести и ткань соткать - это я могу вписать в 2ДА табличку имени DBCollа. Но как быть с плейсами, под них эта табличка вовсе не "заточена". Вот герою надо "сколотить" сундук. С палитры я этот ящик вызову, но как сделать, чтобы на его "изготовление" ушло именно 4 доски (а не одна и не восемь) + 20 дубовых гвоздей и 2 веревки?
Прописать в табличку итем-"пустышку", а в конце диалога вместо его выдачи ставить сундук с палитры? Тоже ничего себе способ... Но, во-первых, все-таки не хочется раздувать табличку до размеров "Войны и мира". Во-вторых, хочется разнообразить диалоги, а у крафта он практически один на все случаи.
Может, все-таки существует способ проще? Подскажите, что делать, где искать...
Спасибо.

Все-таки упертым быть, тяжело, но иногда полезно. Не верите, спросите у Aiwanа...
Изгалялся над скриптом до утра. Сначала просто тупо повторил строчку "SetItemStackSize(oVol,Number-1);" четыре раза. Ничего не изменилось. Потом написал "SetItemStackSize(oVol,Number-1-1-1-1);" . Тоже не помогло. Потом повыше вместо "if (Number==+1)" написал "if (Number==1+1+1+1)". Так получился чит еще круче: ткань выдает, но волокно не берет.
В общем, долго я издевался над этой "арифметической магией", чего только не перепробовал. Странно, но компилятор на все эти дикости почти не ругался. Но вот под утро "зоркий сокол" таки заметил забавное слово "Stac" в обоих командах.
Так, какие предметы у меня в стек складываются? Пока только "прочные деревянные гвозди" (обычные арбалетные болты). В результате утреннего "выноса мозга" и вообще досады на собственную тупость родилась новая ветка диалога (Г - герой, И - инструмент):

Г: - А забью-ка я себе в задницу десяток гвоздей!
И: - Почему нет? Гвозди прочые, из мореного дуба.
Г: -Заколачиваю!

Срабатывает скрипт, есссно, с другими рефами и строкой "SetItemStackSize(oVol,Number-10);".
Понятно, все получилось. Герой потратил ровно 10 гвоздей и получил с палитры итем "Утыканная гвоздями задница".

В общем, все ясно. Скрипт очень даже корректный, просто для стековых итемов. Потому вопрос формулирую несколько более иначе:

Существует ли способ уничтожать в инвентаре ПС точно количество итемов с одинаковым тегом, если эти итемы - НЕ стековые? Если да, то где копать?

З.Ы. Сначала я попробовал тупо убрать слово "Stac" из переменной. Результат немного предсказуем: потеря анализатора. Потом чисто от безысходности написал "SetItemNoStackSize". Ясен пень, снова потеря анализатора переменной...

З.Ы.Ы. Два поста написаны опять с перерывом, теперь уже часов в шесть, но, скорее всего, опять слипнутся в один. Потому прошу прощения за многабукаф. Спасибо.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
denis0k
сообщение Nov 9 2017, 13:33
Сообщение #17


Level 19
Иконки Групп

Класс: Воин
Характер: Lawful Good
Раса: Человек
NWN: Скриптинг [PW]
Gem of the North
Край Лесов



https://nwnlexicon.com/index.php?title=TakeNumItems
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Aiwan
сообщение Nov 9 2017, 14:51
Сообщение #18


Миловидный Бегрюссунг
Иконки Групп

Класс: Воин
Характер: Chaotic Good
Раса: Человек
NWN: Модмейкер
Проклятие Левора
Порядок Времени



Chiffa, полистай мои скрипты в монетке, там много чего я делал и все описал кратко. Найдешь кучу интересного и нужного.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Chiffa
сообщение Nov 10 2017, 03:14
Сообщение #19


Level 6
**

Класс: Волшебник
Характер: Chaotic Good
Раса: Человек



Цитата(Aiwan @ Nov 9 2017, 14:51) *
Chiffa, полистай мои скрипты в монетке, там много чего я делал и все описал кратко. Найдешь кучу интересного и нужного.

Aiwan, мне даже неловко малость. И так львиную долю скриптов натаскал именно у тебя. И монетку, кстати, ковыряю уже давно, так что рад, что получил теперь на это официальное разрешение. (IMG:style_emoticons/kolobok_light/rolleyes.gif)
Там и правда очень много полезного. А самое полезное - высокая культура оформления. Спасибо.
Досадно одно: пока я там не нашел ничего похожего на мой случай. Надеюсь, пока не нашел...
denis0k, спасибо за ссылку, она выводит именно на итемы. Понять бы еще, чего там буржуины понаписали на своем тарабарском языке... (IMG:style_emoticons/kolobok_light/sad.gif)
Впрочем, кое-что с помощью гугла-переводчика даже я кое-что понял. Например, что oTarget - это (цитирую дословно): "объект для удаления нескольких элементов". И что есть специальная полезная переменная nNumItems, которая обозначает (тоже дословно): "Максимальное количество элементов, найденных в инвентаре объектов, для удаления."
Казалось бы, куда уж яснее...
Пишу скрипт:
Neverwinter Script
void main()
{
object oTarget = GetItemPossessedBy(GetFirstPC(), "trav_volokno"); // Определяем, что там для удаления
int Number = 4; // Удалить надо 4 штуки
DestroyObject(oTarget); Number; //Удаляем. По идее, 4 штуки, только фиг!
CreateItemOnObject("itm_rogozha", GetFirstPC(),1); //Выдаем с палитры рогожу, которую ПС из этих четырех волокон типа скрафтил.
}

Компилятор вынес вердикт "составлено верно". А движок все равно убивает только один итем. Пытался писать через запятую "DestroyObject(oTarget, Number;" и "Number++" и менять циферку после этого Numberа. И подключал инклюду "nw_i0_plot". Что с ней, что без нее - все бесполезно... С первым выражением компилятор меня просто послал, все остальные принимал, но это ничего не меняло.
В конце-концов, написав "int Number = 0;" я понял, что движок эту переменную просто не видит...
Что я сделал не так? Чего не хватает? Или что лишнее (хотя уж чему тут быть лишнем!)
Спасибо.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Aiwan
сообщение Nov 10 2017, 07:04
Сообщение #20


Миловидный Бегрюссунг
Иконки Групп

Класс: Воин
Характер: Chaotic Good
Раса: Человек
NWN: Модмейкер
Проклятие Левора
Порядок Времени



Цитата(Chiffa @ Nov 10 2017, 06:14) *
Aiwan, мне даже неловко малость. И так львиную долю скриптов натаскал именно у тебя. И монетку, кстати, ковыряю уже давно, так что рад, что получил теперь на это официальное разрешение. rolleyes.gif
Там и правда очень много полезного. А самое полезное - высокая культура оформления. Спасибо.
Досадно одно: пока я там не нашел ничего похожего на мой случай. Надеюсь, пока не нашел...


Именно для этого я и писал комментарии и описания в скриптах. Для таких как ты, тем кому интересно и нужны пометки что и как. Жаль, что ты можно сказать единственный кому они пригодились. Но культура написания скриптов у меня была, тут согласен, вплоть до образцов с шапками. Люблю порядок. (IMG:style_emoticons/kolobok_light/wink3.gif)

В ПЛ в моем модуле, есть квест, где надо принести несколько бутылок с зельем. Там в одном скрипте их проверяют, сколько в слоте у РС, а в другом уничтожают заданное количество. Я точно не помню, но где-то на пристане НПС ему типа нужны зелья какие-то. (IMG:style_emoticons/kolobok_light/this.gif)
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
denis0k
сообщение Nov 10 2017, 07:44
Сообщение #21


Level 19
Иконки Групп

Класс: Воин
Характер: Lawful Good
Раса: Человек
NWN: Скриптинг [PW]
Gem of the North
Край Лесов



Neverwinter Script
#include "nw_i0_plot"

void main() {

...

TakeNumItems(GetFirstPC(), "trav_volokno", 4);

...

}
Причины изменения: Перевел в nss
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Aiwan
сообщение Nov 10 2017, 09:09
Сообщение #22


Миловидный Бегрюссунг
Иконки Групп

Класс: Воин
Характер: Chaotic Good
Раса: Человек
NWN: Модмейкер
Проклятие Левора
Порядок Времени



Точно (IMG:style_emoticons/kolobok_light/smile.gif)
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Chiffa
сообщение Nov 10 2017, 09:43
Сообщение #23


Level 6
**

Класс: Волшебник
Характер: Chaotic Good
Раса: Человек



Aiwan. denis0k, ребята, СПА-СИ-БО!!!
Уже проверил скрипт на "Полигоне" (это у меня специальный полезный мод для издевательств над ПС). Все работает как часики! Блин, всего одна строчка, а все в корне меняется и уже на жизнь смотришь по-другому. (IMG:style_emoticons/kolobok_light/biggrin.gif) (IMG:style_emoticons/kolobok_light/biggrin.gif) (IMG:style_emoticons/kolobok_light/biggrin.gif)
denis0k, тебе подошел бы титул Лаконичный Мастер. Твой подарок действительно трудно переоценить, настолько он для меня важен. Спасибо еще раз!
Правда что ли за инглиш взяться? Как там у Маяковского "Да будь я негром преклонных годов"? Я, увы, не негр. И хотя годов вполне преклонных, но уже не думаю, что понять английский страшнее, чем плавать в Тамбовском море в ноябре месяце (именно плавать, т. е. подолгу, а не "моржевать"). Но это так, к слову.
Aiwan, а с твоего Андра-Дуна я практически начинал свою "Долбанутую сказку". Правда, не с вина, а с ковыряния твоих ... ох, прости! - пиратских, конечно, ушей. (IMG:style_emoticons/kolobok_light/biggrin.gif) Там герой убивал нехороших ребят и приносил с них особый трофей (опозновательное колечко) хорошим гномам. Менял колечки на мифрил, его, ясен пень, только у этих шахтеров и можно было достать. И только таким способом. Скрипт занял, как ты уже понял, у секретаря сэра Генри.
И сценку с вином найду и посмотрю обязательно. Хотя вино и складывается в стек, а насчет стеков я уже вроде что-то стал понимать. Но наверняка найду что-то для себя новое и полезное.
Спасибо!

З.Ы. И еще в моей сказке герой много плавает. На корабле. Откуда дровишки, в смысле скриптики, объяснять не надо, думаю? Разница только в том, что фамилия у капитана другая. Не Огнев...
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Chiffa
сообщение Nov 16 2017, 16:33
Сообщение #24


Level 6
**

Класс: Волшебник
Характер: Chaotic Good
Раса: Человек



Уважаемые мастера, надеюсь, я не слишком вас достал. Пишу только потому, что сам не смог добиться толку за трое суток. Проблема наверняка из серии "галка на ландшафте" или "демаг, которого не может быть, но он есть". Но она превращает мою робинзонаду в клоунаду. (IMG:style_emoticons/kolobok_light/vava.gif)
Вот, взгляните, в чем "провинился" этот несложный скрипт. Надеюсь, увидите ошибку:
Neverwinter Script
#include "nw_i0_plot"
#include "lm_tsurl_lib" //для работы со стеками
void main()
{
object oPC = GetPCSpeaker();
object oGvo = FindItem("itm_der_gvozd",GetPCSpeaker());
int Number = GetItemStackSize(oGvo);
if (Number==1)
    DestroyObject(oGvo);
else
    SetItemStackSize(oGvo,Number-10); // Это гвозди, которые уничтожаются ровно по 10 штук, все корректно...
TakeNumItems(oPC, "itm_dosk_kor", 4); // Тут тоже ок, спасибо, denis0k!
location oLoc = GetLocation(GetNearestObjectByTag("PLACE_CHEST")); // Невидимый объект, статик
DelayCommand(0.0,ActionPauseConversation()); // А вот отсюда начинается какая-то хрень!
DelayCommand(0.5,AssignCommand(oPC,ActionForceMoveToObject(GetObje
ctByTag("PLASE_CHEST")))); // НИКОГДА не идет, зараза!
DelayCommand(1.5,AssignCommand(oPC,ActionPlayAnimation(ANIMATION_L
OOPING_GET_LOW ,1.0f,3.0f))); //Иногда корячится, но чаще стоит столбом
DelayCommand(2.5,AssignCommand(oPC,ActionPlayAnimation(ANIMATION_L
OOPING_SIT_CROSS ,1.0f,5.0f))); // То же самое
DelayCommand(3.5,AssignCommand(oPC,ActionPlayAnimation(ANIMATION_L
OOPING_TALK_FORCEFUL ,1.0f,3.0f))); // То же самое
DelayCommand(5.0,AssignCommand (oPC, SpeakString("Уф... упарился, аж в глазах потемнело."))); // Чаще молчит, гад
DelayCommand(7.5, ActionCreate(OBJECT_TYPE_PLACEABLE, "SAMOD_CHEST",oLoc)); //Вызывается. Иногда. Есть любопытная закономерность
DelayCommand(8.5,ActionResumeConversation());
}


Как вы поняли, это мой "робонзон" сколачивает ящик, накопил барахлишка, инвентарь не резиновый. Скрипт стоит на диалоге с невидимым монстром. Монстр вызывается, когда юзаешь молоток. Тут полная аналогия с маршрутизаторами ПЛ и "Саги". Монстра я импортировал, естественно, поменяв теги, рефы и вызываемые диалоги.
Но монстр вряд ли в чем виноват. Потому что есть еще монстры, например, мультитул, к нему никаких претензий.
Скажу сразу: дело не в моих глюканутых "лошадках". Проверял и в старой, надежной "Шадоу", и в недавно установленной 1.69 - везде одинаково. (Кстати, "лошадок" я пока не стер. Возможно, проблема даже не в них, а в 64-разрядной винде).
Так вот, что происходит.
1. Если скрипт стоит на "совершены действия" ПС, то герой стоит столбом и вообще ничего не делает. Ящик с палитры не вызывается. Никогда.
2. Если переставить на "совершены действия" непися (монстра), герой изображает "танцы с бубном", а также вполне спикает и стрингает, но к плейсу не идет и ящик не вызывается.
3. Если поставить на "совершены действия" обычного непися (специально рисовал для проверки) - тогда и танцы с бубном, и спики-стринги, - все ок, и ящик вызывается. Всегда. За километр от героя, точно на плейсе. Казалось бы, куда уж яснее: "ActionForceMoveToObject(GetObjectByTag("PLASE_CHEST"))));" - так не двигается! Говорю, не робинзонада, а клоунада...
Конечно, я пробовал и несколько более иначе. Без "DelayCommand", а просто "AssignCommand", естественно, через ActionWait(1.5f); или побольше. Как и учил нас, нубов, уважаемый Aiwan. Получилось еще смешнее. Тут даже герой к плейсу пошел, и все танцы исполнил. Вот только ящик плевать хотел на эту вашу "ActionWait". Появляется с палитры сразу, без малейшей задержки. И герой "сколачивает" уже готовый ящик.
Может, проблема в том, что монстр-мультитул работает исключительно с предметами, потому к нему и нет претензий. А к плейстейблам нужен какой другой подход?
В общем, печалька...
Ведь робинзону предстоит еще по такой же схеме делать и ткацкую раму, и печку для плавки, и много еще чего в задумках. А тут такая фигня...
Спасибо.

З.Ы. Проделал еще один опыт, такой же дурачий, как и сама ситуация. У всех невидимых монстров слоты чистые, кроме двух, на "OnHeartbeat" (коротенький скрипт, заставляет уничтожаться после использования) и на "OnSpawn" - скрипт вызова.
Так вот, я взял и тупо поставил все дефолтные скрипты на эти чистые слоты. И получилось все, как в разговоре со специально подрисованным неписем.
Ну вот что за фигня, на самом деле?!
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Aiwan
сообщение Nov 16 2017, 18:51
Сообщение #25


Миловидный Бегрюссунг
Иконки Групп

Класс: Воин
Характер: Chaotic Good
Раса: Человек
NWN: Модмейкер
Проклятие Левора
Порядок Времени



Основная твоя ошибка ты понятия не имеешь зачем все эти DelayCommand, AssignCommand и бла бла бла. Читал мануал по тулсету давно и невнимательно.
Первое. Что бы построить цепочку действий с двумя или тремя объектами, нужен диспетчер. Тот, кто будет следить за исполнением команды. Ни РС ни НПС на это слабо подходят. Либо им забивать стэки команд и делать их глухими для всего, либо через диспетчера. Что бы все шло по рельсам, нужно, например надовать действий игроку и пусть он выполняет их по очереди. Для этого нужно правильно уметь раздавать команды и понимать какая команда кем выполняется. В твоем скрипте все действия разданы хаотично и большинство из них исполняет тот на ком скрипт по умолчания OBJECT_SELF. Вот и вся петрушка. Кратко:

Neverwinter Script
#include "nw_i0_plot"
#include "lm_tsurl_lib" //для работы со стеками
void main()
{
object oPC = GetPCSpeaker();
object oGvo = FindItem("itm_der_gvozd",GetPCSpeaker());
int Number = GetItemStackSize(oGvo);
if (Number==1)
    DestroyObject(oGvo);
else
    SetItemStackSize(oGvo,Number-10); // Это гвозди, которые уничтожаются ровно по 10 штук, все корректно...
TakeNumItems(oPC, "itm_dosk_kor", 4); // Тут тоже ок, спасибо, denis0k!
location oLoc = GetLocation(GetNearestObjectByTag("PLACE_CHEST")); // Невидимый объект, статик
DelayCommand(0.0,ActionPauseConversation()); // Задержку 0.0 никогда не делай.
DelayCommand(0.5,AssignCommand(oPC,ActionForceMoveToObject(GetObje
ctByTag("PLASE_CHEST")))); // Игрок получает команду выполнить и...
DelayCommand(1.5,AssignCommand(oPC,ActionPlayAnimation(ANIMATION_L
OOPING_GET_LOW ,1.0f,3.0f))); // ... через 1 секунду его сбивает эта команда выполнения движения.
DelayCommand(2.5,AssignCommand(oPC,ActionPlayAnimation(ANIMATION_L
OOPING_SIT_CROSS ,1.0f,5.0f))); // потом эта
DelayCommand(3.5,AssignCommand(oPC,ActionPlayAnimation(ANIMATION_L
OOPING_TALK_FORCEFUL ,1.0f,3.0f))); // и эта
DelayCommand(5.0,AssignCommand (oPC, SpeakString("Уф... упарился, аж в глазах потемнело."))); // Эта команда не идет в стек и срабатывает иногда
DelayCommand(7.5, ActionCreate(OBJECT_TYPE_PLACEABLE, "SAMOD_CHEST",oLoc)); //
DelayCommand(8.5,ActionResumeConversation()); // Если скрипт на РС то он продолжит, если нет... сам понимаешь.
/*игрока можно отправлять в катсцену и в конце всех актионов снимать ее
ActionDoCommand(SetCutsceneMode(oPC,TRUE)) - ставим
ActionDoCommand(SetCutsceneMode(oPC,FALSE)) - снимаем
*/


}


Action можно игроку или НПС выдавать по очереди и он их будет выполнять пока они не кончатся или его не собьет с действия какой либо скрипт в слотах или округи.
В общем у тебя полная жопа с понятием основ. Я конечно могу исправить скрипт, посижу часик, но не думаю, что это поможет. Возьми для начала и перечитай мою тему построения скриптовых сцен. Там четко написано кто и почему делает так как в скриптах. В катсценах участвуют куча НПС и РС и все до долей секунд исполняют написанный сценарий. Помешь как оно работает, поймешь свои ошибки.


Тебе сюда: Построение скриптовых сцен
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения

3 страниц V   1 2 3 >
Ответить в эту темуОткрыть новую тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



Текстовая версия Сейчас: 28th March 2024 - 11:27