Перейти к контенту

Скриптование


Svoboда

Рекомендуемые сообщения

(изменено)

Возникла задача: как сделать ограничение на количество появлений какого-либо диалога? Чтоб диалог появился, например, 8 раз, а на девятый - не появился? На форуме нашел пару вопросов по этому поводу, но ответов не нашел. Поэтому решил придумать сам. Решение движковое, на поршнях, нетпакет не используется.

Сначала общий код (описано на базе Народной Солянки):

 

В dialogs.script ставим это:

-- счетчик количества вызовов диалога. Возвращает count раз true, затем false. 
-- должны быть прописаны поршни: "portion1, portion2...portion|Count|)" 
function dialog_count(portion, count)
    local pname = ""
    for i=1,count do
        pname = portion..tostring(i)
        if not has_alife_info(pname) then 
            db.actor:give_info_portion(pname)
            return true
        end
    end
    return false
end
-- проверка лимита. возвращает true если все поршни выданы.
function dialog_is_enough(portion, count)
    local pname = ""
    for i=1,count do
        pname = portion..tostring(i)
        if not has_alife_info(pname) then
            return false
        end
    end
    return true
end

В любой stable ставим это:

<string id="dialog_is_enough">
  <text>К сожалению, больше я тебе ничем помочь не могу.</text>
</string>

Эта фраза будет выдаваться вместо всех ограниченных диалогов, когда они будет выданы нужное число раз.

 

Далее привязка к конкретному персу. Например, сделаем так, чтобы диалог обмена у Ворона появился только 8 раз. Для этого добавляем в указанные файлы следующее:

 

info_wawka_way:

    <info_portion id="trade_voron_enough1"></info_portion>
    <info_portion id="trade_voron_enough2"></info_portion>
    <info_portion id="trade_voron_enough3"></info_portion>
    <info_portion id="trade_voron_enough4"></info_portion>
    <info_portion id="trade_voron_enough5"></info_portion>
    <info_portion id="trade_voron_enough6"></info_portion>
    <info_portion id="trade_voron_enough7"></info_portion>
    <info_portion id="trade_voron_enough8"></info_portion>

wawka_dialog:

function trade_voron_not_enough()
    return not dialogs.dialog_is_enough("trade_voron_enough",8)
end
function trade_voron_enough()
    return dialogs.dialog_is_enough("trade_voron_enough",8)
end
function trade_voron_count()
    return dialogs.dialog_count("trade_voron_enough",8)
end

dialogs_wawka, изменяем диалог следующим образом:

<dialog id="trade_dialog_voron"> 
        <phrase_list>
<!-- лимит диалогов. добавлена фраза 1000 и прекондишины на вызов dialog_is_(not)_enough во фразе 1 и 1000. торговля сработает 8 раз -->
            <phrase id="0">
                <text>trade_dialog_voron_0</text>
                <next>1</next>
                <next>1000</next>
            </phrase>
            <phrase id="1">
                <precondition>wawka_dialog.trade_voron_not_enough</precondition>
                <text>trade_dialog_voron_1</text>
                <give_info>price_voron</give_info>
                <next>2</next>
                <next>3</next>
            </phrase>
            <phrase id="1000">
                <precondition>wawka_dialog.trade_voron_enough</precondition>
                <text>dialog_is_enough</text>
            </phrase>

Далее, во все фразы, которые, по нашей задумке, влияют на количесво появлений диалога, в конце фразы вставляем сделующий код:

<action>wawka_dialog.trade_voron_count</action>

Т.е. должно получиться примерно следующее:

            <phrase id="221">
            <precondition>wawka_dialog.psevdo_tails_have</precondition>
                <text>trade_dialog_voron_221</text>
                <action>wawka_dialog.give_psevdo_tails</action>
                <action>wawka_dialog.add_ammo_12x70_buck</action>
                <action>wawka_dialog.trade_voron_count</action>
            </phrase>
            <phrase id="2211">
            <precondition>wawka_dialog.psevdo_tails_have</precondition>
                <text>trade_dialog_voron_2211</text>
                <action>wawka_dialog.give_psevdo_tails</action>
                <action>wawka_dialog.add_ammo_12x76_zhekan</action>
                <action>wawka_dialog.trade_voron_count</action>
            </phrase>
            <phrase id="2212">
            <precondition>wawka_dialog.psevdo_tails_have</precondition>
                <text>trade_dialog_voron_2212</text>
                <action>wawka_dialog.give_psevdo_tails</action>
                <action>wawka_dialog.add_ammo_12x76_dart</action>
                <action>wawka_dialog.trade_voron_count</action>
            </phrase>

Эта команда вызывает счетчик. При этом, вызов счетчика можно включать не в каждую фразу, таким образом получая, что не все обмены становятся ограниченными. Например, можно включить счетчик только в обмен патронов, а в обмен оружия и канистр не включать. Тогда канистры и оружие будут меняться неограниченное количество раз, а патроны - только 8 раз. Если нужно изменить количество - меняем количество поршней и цифру 8 на нужную нам, и все. :grin2:

 

Кстати, таким способом (через поршни) можно считать что угодно, не нагружая нетпакет.

 

Пользуйтесь на здоровье :rolleyes: rolleyes:

Изменено пользователем proper70

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Здравствуйте! Не знаю, куда лучше написать, поэтому написал сюда. Понадобилась Ваша помощь, т.к. сам не смог разобраться)

Ковыряю Народную Солянку в попытке сделать ОП-2. Впервые спавню скриптом квестовика. Он стоит в Баре, где Долговязый и Доцент.

Конфиг в character_desc_sniper.xml

    <specific_character id="kotobegemot" team_default = "1">
        <name>Котобегемот</name>
        <icon>ui_npc_snp_kotobegemot</icon>
        <bio>esc_wolf_bio</bio>

        <class>kotobegemot</class>
        <community>stalker</community> <terrain_sect>stalker_terrain</terrain_sect>
        
        <rank>434</rank>
        <reputation>5</reputation>
        <money min="600" max="2000" infinitive="0"/>
        
        <snd_config>characters_voice\human_01\stalker\</snd_config>
        <crouch_type>-1</crouch_type>

        <visual>snp\kotobegemot</visual>
        <supplies>
            [spawn] \n
            wpn_fn2000_paratrooper \n
            ammo_9x39_sp5 \n
        </supplies>

#include "gameplay\character_criticals_4.xml"

        <actor_dialog>snp_kotobegemot1</actor_dialog>   
        <actor_dialog>snp_kotobegemot2</actor_dialog>   
#include "gameplay\character_dialogs.xml"
        
    </specific_character>

Профиль в npc_new.xml

    <character id="kotobegemot">
        <class>kotobegemot</class>
    </character>
    <character id="kotobegemot_bar">
        <class>kotobegemot</class>
    </character>

Секция для спавна в spawn_sections.ltx

[kotobegemot]:stalker
$spawn                 = "respawn\kotobegemot"
character_profile    = kotobegemot
spec_rank = master
community = stalker
custom_data = scripts\snp\kotobegemot_bar.ltx

Ему прописана логика, как у Долговязого, сделаны точки way и look, добавлены в файл way_l05_bar.ltx и запакованы в алспаун. Вот его логика:

[logic]
active = walker

[walker]
path_walk = kotobegemot_bar_walk
path_look = kotobegemot_bar_look
meet = meet
danger = danger_ignore

[danger_ignore]
ignore_distance = 0

[meet]
use = true
use_wpn = true
meet_talk_enabled = true
;meet_state = 10|ward@doktor_hello|2|ward
;meet_state_wpn = 10|ward@doktor_hello|2|ward

Вобщем, все слизано с Долговязого.

Перс спавнится, говорит, отыгрывает все анимации, стоит на месте, никуда не уходит, вобщем, все работает как надо.

Но, когда я ухожу далеко, на свалку или ДТ, чтобы игра полностью забыла про бар и про него, а затем возвращаюсь, то перса нет на месте. Я путем экспериментов понял, что он просто не респавнится, когда движок очищает память, когда уходишь далеко и потом возвращаешься. Если уйти на ДТ, но недалеко и потом вернуться, то он на месте. Я все перпробовал: и диалоги отключал и уборщик отключал и визуал менял - все одно и то же - не респавнится.

Я заметил такой момент, что пока в логе не появляются вот эти строки:

sv reject. id_parent [1372][kotobegemot:kotobegemot1372] id_entity [23939][ammo_m209:ammo_m20923939] [112401]

sv reject. id_parent [1372][kotobegemot:kotobegemot1372] id_entity [15366][bandage:bandage15366] [112401]

sv reject. id_parent [1372][kotobegemot:kotobegemot1372] id_entity [15540][yad:yad15540] [112401]

sv reject. id_parent [1372][kotobegemot:kotobegemot1372] id_entity [6668][bolt:bolt] [112401]

sv reject. id_parent [1372][kotobegemot:kotobegemot1372] id_entity [1375][wpn_fn2000_paratrooper:wpn_fn2000_paratrooper1375] [112401]

sv reject. id_parent [1372][kotobegemot:kotobegemot1372] id_entity [1374][ammo_9x39_sp5:ammo_9x39_sp51374] [112401]

sv reject. id_parent [1372][kotobegemot:kotobegemot1372] id_entity [1373][device_pda:device_pda1373] [112401]

- то перс стоит на месте даже если уйти на другую локу, но недалеко, чтобы он еще оставался в памяти. А если эти строки появились в логе - то его на месте не будет. И еще я заметил один момент:

По моему персу идет такой лог:

 

sv reject. id_parent [1372][kotobegemot:kotobegemot1372] id_entity [23939][ammo_m209:ammo_m20923939] [112401]

 

тогда как по всем остальным персам Бара идет вот такой лог:

 

sv reject. id_parent [13994][stalker_sakharov:dolgovazyi] id_entity [6167][bolt:bolt] [112337]

sv reject. id_parent [13165][stalker:bar_bar_drunk_dolg] id_entity [6291][bolt:bolt] [112401]

sv reject. id_parent [13537][stalker_trader:bar_dolg_petrenko] id_entity [15585][yad:yad15585] [112401]

 

т.е. везде стоит базовый класс непися, тогда как у меня стоит просто класс, как в конфиге, хотя в spawn_sections.ltx я присовил ему класс stalker, как это сделано по аналогии с другими персами. Поэтому я подозреваю, что я его не так прописал, из-за этого и проблема.

Подскажите мне, что я сделал не так? Я искал чисто скриптовый спавн неписей в скриптах НС, но не нашел, т.к. они практически все вынесены в алспаун. Можно ли корректно сделать чисто скриптовый спавн непися? Уж очень не хочется в алспаун лезть, чтобы при каждой правке НИ начинать)

 

_Призрак_, спасибо, все заработало)

Изменено пользователем proper70

Поделиться этим сообщением


Ссылка на сообщение

Еще раз привет! В алспауне есть параметр direction. Как я понял, он разворачивает объект относительно сетки координат при спавне. А можно ли как-то задавать этот параметр через нетпакет при скриптовом спавне? Мне нужно разворачивать рюкзаки-тайники в пространстве. Для актора есть функция set_actor_direction, а для объектов, так понимаю, нету...

 

ЗЫ: Пример задавания story_id при скриптовом спавне я нашел в НС:

local obj = alife():create("mil_trader_gavr",vector():set(25.325489,-8.35158157,-17.512226425),330707,1587)
local params=amk.read_stalker_params(obj)
params.sid=9623
amk.write_stalker_params(params,obj)

а вот direction - не нашел...

Поделиться этим сообщением


Ссылка на сообщение

Господа, подскажите. Хочу заспавнить труп непися вне аи сетки (в подвале - там нет аи сетки)

Я прочитал про назначения флажков, нашел этот: flUsedAI_Locations (8-й бит) и написал так:

    local obj = alife():create("forest_nebo_veteran",vector():set(-180.48532104492,5.3024110794067,-317.11584472656),50507,3365)
    local tbl = amk.read_stalker_params(obj)
        tbl.oflags = tbl.oflags-128 -- сброс восьмого бита - flUsedAI_Locations
        tbl.health = 0
        tbl.updhealth = 0
    amk.write_stalker_params(tbl, obj)

Флаг сбрасывается, я проверял. Приходит -65 (=1110111111) а записывается -193 (=1100111111). Как видно, восьмой бит сброшен. Но непись все равно спавнится на полу, где идет аи сетка. Я менял координату Y выше, ниже - все равно непись спавнится на аи сетке.

 

Что я сделал не так? И как мне правильно заспавнить труп непися вне аи сетки?

 

 

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Господа! Может не в тему, но вот я иногда заглядываю в эту тему и просто восторгаюсь терпению Артоса и иже с ним. Можно я скажу тем кто не может разобраться со спикерами, передачей предметов и прочими я бы сказал, очевидными вещами: вы просто скачайте последнюю солянку а лучше оп1, перенесите в отдельную папку папку config и scripts, поставьте себе notepad++ и используйте поиск фразы по файлам. И смотрите, как ваши пожелания сделаны у пысов или в солянке.

Проблемы со спикерами? Поиск по файлам фразы first_speaker ответит на все ваши вопросы. Просто скопируйте уже рабочий код и поправьте на свои значения. Не перекладывается предмет из гг к неписю или в нычку - поиск по фразе transfer_item решит ее.

А если не знаете с чего начать поиск - вспомните, где в игре есть подобное, найдите этот код по любой фразе, по диалогу например, или по описанию и дальше по цепочке поиском по ключевым словам.

А если вы хотите научиться азам ООП на сталкере, просто ковыряя файлы - то у вас ничего не выйдет - вы начали с конца. Настоятельно рекомендую купить книгу основы ООП или похожую и внимательно изучить ее. Без этих знаний вы простоянно будете блудить в очевидных вещах, так ничему и не научитесь, и только зафлуживаете тему.

Чтобы научиться читать - нужно как минимум выучить алфавит. Чтобы научиться считать - нужно как минимум выучить цифры. Чтобы научиться программировать в сталкере - нужно как минимум понять что такое объект, класс, наследование и чем конфиги отличаются от скриптов, а также чем серверный объект отличается от клиентского. Иначе у вас ничего не выйдет и для вас только один вариант - тупое копирование уже рабочих скриптов.

Я не хочу хвастаться, но я 99% всех своих проблем решил простым поиском по скриптам и конфигам. Конечно, я знаком с основами ООП и это очень сильно мне помогало в пониманиии скриптов. Это поможет и вам)

Изменено пользователем proper70
  • Нравится 2

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Кстати, по звукам и по скорости загрузки игры.

По звукам:

Очень странно, что у ПЫСов нет обьекта звук, который можно создать через alife():create(). Как с рестрикторами и прочими вспомогательными фичами. А ведь как было бы просто: сделал alife():create("sound_object") с его логикой, как у рестриктора, указанием пути к файлу и когда играть, а когда замолчать - и все))

Я тут просто в .ОП-2 делал сюжет по поиску тайников по звуку и реально пришлось изобретать велосипед, реализуя запуск и отключение звуков по сюжету) Но копаясь в скриптах, я понял, что ПЫСам это просто было не нужно - нет у них таких квестов - вот они и не сделали)

А насчет быстродействя: Buusty сегодня наконец-то вычистил алспаун от дублирующих путей (их просто невероятное количестово было) и он пишет, что ОП1 стал грузиться чуть ли не быстрее чем оригинал ТЧ. А у меня оригинал ТЧ вообще грузится 10-15 секунд. Так что вот так, уважаемые Господа)

 

А классы... они только ПОВЫШАЮТ производительность, и никак не понижают - это основы ООП)

Изменено пользователем proper70

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Господа, вопрос: можно ли в ТЧ скриптово сделать ГГ неуязвимым к хитам на короткое время? Если да, то как? Как вариант, сделать конфиг арта со 100% защитами от всего, и вешать его на пояс. Но как скриптово повешать арт на пояс? Может, есть еще какие варианты? С броником такой вариант не проходит, т.к. броник в ТЧ защищает только сам себя...

Изменено пользователем proper70

Поделиться этим сообщением


Ссылка на сообщение

malandrinus, с костями фишка не работает) Похоже, эти кости только на неписей влияют. На гг они никакого эффекта не оказали. Зависимость его иммунитетов я заметил только при правке защит в actor.ltx.

Но: если сделать вот такой конфиг арта:

 

[af_invul]:af_blood

inv_weight = 0

inv_grid_width = 0

inv_grid_height = 0

cost = 0

belt = true

default_to_ruck = false

 

;скорости увеличения (уменьшения)

health_restore_speed = 0.0

radiation_restore_speed = 0.0

satiety_restore_speed = 0.0

power_restore_speed = 0.0

bleeding_restore_speed = 0.0

hit_absorbation_sect = af_invul_absorbation

 

[af_invul_absorbation]

burn_immunity = 0.0 ;коэффициенты иммунитета

strike_immunity = 0.0

shock_immunity = 0.0

wound_immunity = 0.0

radiation_immunity = 0.0

telepatic_immunity = 0.0

chemical_burn_immunity = 0.0

explosion_immunity = 0.0

fire_wound_immunity = 0.0

То он спавнится сразу на поясе при наличии свободного места. И ГГ бессмертен) Заспавнил арт - бессмертен. Удалил - все как обычно)

Поделиться этим сообщением


Ссылка на сообщение
что курили пысовцы, когда делали эту систему?

Я за время изготовления ОП-2 такого в скриптах начитался, что уже ничему не удивляюсь)) В любом случае, спасибо за помощь!

Поделиться этим сообщением


Ссылка на сообщение

Господа, подскажите, можно ли как-то проверить, что ГГ убил непися именно хедшотом? Т.е. смертельный выстрел попал в кость головы (bip01_head)? В мотиваторе в hit_callback передается кость, по которой прошел хит, а в death_callback - нет. Можно ли как-то решить эту задачу?

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Artos, попробовал. Да, так работает, только у неписей bone_index при любом хите всегда = 0. Похоже в ТЧ этот параметр просто не обрабатывается. И я не нашел ни одного использования этого параметра в чистом ТЧ и в Солянке. Этот параметр просто передается из функции в функцию, гуляя по логике и калбекам, но нигде не проверяется на значение...

Изменено пользователем proper70

Поделиться этим сообщением


Ссылка на сообщение

Господа! Всё, что вы написали выше, про умное выпадение и прочее - это всё относится к монстрам. А я спрашивал про неписей. То, что для монстров кость передается, я даже проверять не буду - по скриптам видно, что она обрабатывается и работает. А вот для неписей - она всегда = 0. Убедиться в этом очень просто:  в мотиваторе в самом начале hit_callback напишите вот это:

 

get_console():execute("load ~~~ npc: "..self.object:name().." bone_index:"..bone_index)

 

и постреляйте по неписям по разным частям их тела. Сами всё увидите) Вот вырезка из моего лога, когда я воевал с бандитами на АТП:

 

 

! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129339 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_125265 bone_index:0
! Cannot find saved game ~~~ npc: agr_bandit_respawn_138926 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_232020 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129318 bone_index:0
! Cannot find saved game ~~~ npc: val_bandit_respawn_438920 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_330071 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129339 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_125265 bone_index:0
! Cannot find saved game ~~~ npc: agr_bandit_respawn_138926 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_232020 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129318 bone_index:0
! Cannot find saved game ~~~ npc: val_bandit_respawn_438920 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_330071 bone_index:0
! Cannot find saved game ~ spawn now [respawn30856] -> [ghoul_strong24093]
! Cannot find saved game ~ spawn now [respawn30856] -> [m_poltergeist_strong_flame24198]
! Cannot find saved game ~ spawn now [respawn30856] -> [ghoul_strong24200]
sv reject. id_parent [0][actor:single_player] id_entity [4278][ammo_9x39_sp5:ammo_9x39_sp54278] [9134]
sv destroy object [4278][ammo_9x39_sp5:ammo_9x39_sp54278] [9134]
cl setDestroy [4278][9135]
sv destroy object [24130][separator:separator24130] [9136]
sv reject. id_parent [0][actor:single_player] id_entity [24130][separator:separator24130] [9136]
cl setDestroy [24130][9136]
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129339 bone_index:0
! Cannot find saved game ~~~ npc: val_bandit_respawn_438920 bone_index:0
! Cannot find saved game ~~~ npc: agr_bandit_respawn_138926 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_330071 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_232020 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129318 bone_index:0
! Cannot find saved game ~~~ npc: agr_bandit_respawn_138926 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129339 bone_index:0
! Cannot find saved game ~~~ npc: val_bandit_respawn_438920 bone_index:0
! Cannot find saved game ~~~ npc: agr_bandit_respawn_138926 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_330071 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_232020 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129318 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129339 bone_index:0
! Cannot find saved game ~~~ npc: val_bandit_respawn_438920 bone_index:0
! Cannot find saved game ~~~ npc: agr_bandit_respawn_138926 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_330071 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_232020 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129318 bone_index:0
! Cannot find saved game ~~~ npc: agr_bandit_respawn_138926 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129339 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_125265 bone_index:0
! Cannot find saved game ~~~ npc: val_bandit_respawn_438920 bone_index:0
! Cannot find saved game ~~~ npc: agr_bandit_respawn_138926 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_330071 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_232020 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129318 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129339 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_125265 bone_index:0
! Cannot find saved game ~~~ npc: val_bandit_respawn_438920 bone_index:0
! Cannot find saved game ~~~ npc: agr_bandit_respawn_138926 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_330071 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_232020 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129318 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129339 bone_index:0
! Cannot find saved game ~~~ npc: val_bandit_respawn_438920 bone_index:0
! Cannot find saved game ~~~ npc: agr_bandit_respawn_138926 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_330071 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_232020 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129318 bone_index:0
sv reject. id_parent [29318][atp_fabrika_bandit_respawn_1:atp_fabrika_bandit_respawn_129318] id_entity [13492][ammo_5.45x39_ap:ammo_5.45x39_ap] [9219]
sv destroy object [13492][ammo_5.45x39_ap:ammo_5.45x39_ap] [9219]
cl setDestroy [13492][9220]
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129339 bone_index:0
! Cannot find saved game ~~~ npc: val_bandit_respawn_438920 bone_index:0
! Cannot find saved game ~~~ npc: agr_bandit_respawn_138926 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_330071 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_232020 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129318 bone_index:0
! Cannot find saved game ~~~ npc: val_bandit_respawn_438920 bone_index:0
! Cannot find saved game ~~~ npc: val_bandit_respawn_438920 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129339 bone_index:0
! Cannot find saved game ~~~ npc: val_bandit_respawn_438920 bone_index:0
! Cannot find saved game ~~~ npc: agr_bandit_respawn_138926 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_330071 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_232020 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129318 bone_index:0
sv destroy object [9506][grenade_rgd5:grenade_rgd59506] [9230]
sv reject. id_parent [38920][val_bandit_respawn_4:val_bandit_respawn_438920] id_entity [9506][grenade_rgd5:grenade_rgd59506] [9230]
sv destroy object [14883][grenade_f1:grenade_f114883] [9230]
sv reject. id_parent [38920][val_bandit_respawn_4:val_bandit_respawn_438920] id_entity [14883][grenade_f1:grenade_f114883] [9230]
sv destroy object [9366][yad:yad9366] [9230]
sv reject. id_parent [38920][val_bandit_respawn_4:val_bandit_respawn_438920] id_entity [9366][yad:yad9366] [9230]
sv destroy object [9323][bandage:bandage9323] [9230]
sv reject. id_parent [38920][val_bandit_respawn_4:val_bandit_respawn_438920] id_entity [9323][bandage:bandage9323] [9230]
sv destroy object [9396][medkit:medkit9396] [9230]
sv reject. id_parent [38920][val_bandit_respawn_4:val_bandit_respawn_438920] id_entity [9396][medkit:medkit9396] [9230]
sv destroy object [38915][device_pda:device_pda38915] [9230]
sv reject. id_parent [38920][val_bandit_respawn_4:val_bandit_respawn_438920] id_entity [38915][device_pda:device_pda38915] [9230]
sv destroy object [38923][ammo_5.56x45_ap:ammo_5.56x45_ap38923] [9230]
sv reject. id_parent [38920][val_bandit_respawn_4:val_bandit_respawn_438920] id_entity [38923][ammo_5.56x45_ap:ammo_5.56x45_ap38923] [9230]
sv destroy object [38947][device_torch:device_torch38947] [9230]
sv reject. id_parent [38920][val_bandit_respawn_4:val_bandit_respawn_438920] id_entity [38947][device_torch:device_torch38947] [9230]
sv destroy object [38923][NOTFOUND] [9230]
!SV:ge_destroy: [38923] not found on server
cl setDestroy [9506][9231]
cl setDestroy [14883][9231]
cl setDestroy [9366][9231]
cl setDestroy [9323][9231]
cl setDestroy [9396][9231]
cl setDestroy [38915][9231]
cl setDestroy [38923][9231]
cl setDestroy [38947][9231]
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129339 bone_index:0
! Cannot find saved game ~~~ npc: agr_bandit_respawn_138926 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_330071 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_232020 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129318 bone_index:0
sv reject. id_parent [38920][val_bandit_respawn_4:val_bandit_respawn_438920] id_entity [38948][wpn_l85:wpn_l8538948] [9232]
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129339 bone_index:0
! Cannot find saved game ~~~ npc: agr_bandit_respawn_138926 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_330071 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_232020 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129318 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129339 bone_index:0
! Cannot find saved game ~~~ npc: agr_bandit_respawn_138926 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_330071 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_232020 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129318 bone_index:0
sv reject. id_parent [29339][atp_fabrika_bandit_respawn_1:atp_fabrika_bandit_respawn_129339] id_entity [21405][ammo_5.45x39_fmj:ammo_5.45x39_fmj] [9305]
sv destroy object [21405][ammo_5.45x39_fmj:ammo_5.45x39_fmj] [9305]
cl setDestroy [21405][9306]
sv reject. id_parent [29339][atp_fabrika_bandit_respawn_1:atp_fabrika_bandit_respawn_129339] id_entity [24462][grenade_rgd5_test:grenade_rgd5_test24462] [9439]
sv reject. id_parent [29339][atp_fabrika_bandit_respawn_1:atp_fabrika_bandit_respawn_129339] id_entity [24463][grenade_rgd5_test:grenade_rgd5_test24463] [9439]
! Cannot find saved game ~~~ npc: agr_bandit_respawn_138926 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129339 bone_index:0
! Cannot find saved game ~~~ npc: agr_bandit_respawn_138926 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_330071 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_232020 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129318 bone_index:0
sv destroy object [9372][yad:yad9372] [9456]
sv reject. id_parent [38926][agr_bandit_respawn_1:agr_bandit_respawn_138926] id_entity [9372][yad:yad9372] [9456]
sv destroy object [9400][medkit:medkit9400] [9456]
sv reject. id_parent [38926][agr_bandit_respawn_1:agr_bandit_respawn_138926] id_entity [9400][medkit:medkit9400] [9456]
sv destroy object [9401][bandage:bandage9401] [9456]
sv reject. id_parent [38926][agr_bandit_respawn_1:agr_bandit_respawn_138926] id_entity [9401][bandage:bandage9401] [9456]
sv destroy object [38927][device_pda:device_pda38927] [9456]
sv reject. id_parent [38926][agr_bandit_respawn_1:agr_bandit_respawn_138926] id_entity [38927][device_pda:device_pda38927] [9456]
sv destroy object [38959][ammo_12x70_buck:ammo_12x70_buck38959] [9456]
sv reject. id_parent [38926][agr_bandit_respawn_1:agr_bandit_respawn_138926] id_entity [38959][ammo_12x70_buck:ammo_12x70_buck38959] [9456]
sv destroy object [38961][device_torch:device_torch38961] [9456]
sv reject. id_parent [38926][agr_bandit_respawn_1:agr_bandit_respawn_138926] id_entity [38961][device_torch:device_torch38961] [9456]
sv destroy object [38962][guitar_a:guitar_a38962] [9456]
sv reject. id_parent [38926][agr_bandit_respawn_1:agr_bandit_respawn_138926] id_entity [38962][guitar_a:guitar_a38962] [9456]
sv destroy object [38959][NOTFOUND] [9456]
!SV:ge_destroy: [38959] not found on server
cl setDestroy [9372][9457]
cl setDestroy [9400][9457]
cl setDestroy [9401][9457]
cl setDestroy [38927][9457]
cl setDestroy [38959][9457]
cl setDestroy [38961][9457]
cl setDestroy [38962][9457]
sv reject. id_parent [38926][agr_bandit_respawn_1:agr_bandit_respawn_138926] id_entity [38964][wpn_bm16:wpn_bm1638964] [9458]
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129339 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_330071 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_232020 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129318 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129339 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_330071 bone_index:0
! Cannot find saved game ~~~ npc: atp_fabrika_bandit_respawn_129318 bone_index:0

Как видно из лога - кость не работает. Я стрелял по разным частям тела, рукам, ногам, туловищу, взрывал неписей гранатами - результат один)

Ну да ладно) я могу обойтись без этого, просто хотел кое-что сделать по неписям, но обойдусь без него))

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Artos, последний вопрос: как может быть хит "пустой" (amount=0), если непись погиб от одного-единственного выстрела в голову? Из ствола актора. При этом он стоял на абсолютно ровной открытой местности, т.е. ни за что не цеплялся, и погиб именно от пули актора? А у меня во вчерашнем, более полном тесте, также, как и у тебя, amount практически везде = 0, и это при том, что я зачистил весь АТП - более 15 бандитов? Они все что, погибли, споткнувшись об ветки?) Или я все ещё чего-то не понимаю, а в ТЧ хит калбек работает правильно, и amount=0 в момент, когда непись погибает - это именно так и должно быть?

Изменено пользователем proper70

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Наконец-то победил причину автозавершения квестов на защиту барьера и им подобным после сейв/лоада) Найдена и вырвана с корнем глубоко сидевшая в скриптах ошибка еще от ПЫСов, что в сейве не сохранялся ИД смарта, от которого надо защищать другой смарт) Этот ИД задавался при выдаче таска, но при сейв/лоаде он терялся, и после лоада это ИД было = nil. Но ее легко было бы выловить, если бы при запросе состояния несуществующего гулага возвращалось заведомо несуществующее значение, например -1. Но xr_gulag.getGulagState() при несуществующем гулаге возвращает 0, или состояние неактивного, пустого гулага. Вот проверка и срабатывала, что гулаг зачищен, и задание выполнялось)) Это, конечно, досадная оплошность со стороны того, кто делал скрипты гулагов, и, если бы не она, то это все было бы выявлено и поправлено еще в далеком 2007 году) а так эта проблема дожила аж до 2014 года)) И, наконец, она вылечена))

Правка этой ошибки в общем случае требует НИ, так как в нетпакет пишется новое значение и меняется его размер. Но можно использовать технологию двухэтапного подключения этой и подобных ей правок, без начала НИ. Для этого нужно в методе save выдать поршень, и в методе load его проверять при чтении нетпакета. Тогда на старых сейвах до правки будет читаться старый нетпакет, а на новых - новый)

Вот правка автозавершения на task_manager от Народной Солянки на версии 1.0006:

 

 



-- Будем записывать не id задания а его хеш - семикратная экономия.
function CRandomTask:save(p)
  printf("^^^ SAVE")
  -- Отметка того, что это новая версия формата.
  p:w_u8(255)
  --' Считаем количество записей
  local i = 0
  for k,v in pairs(self.task_info) do
    i = i + 1
  end
  p:w_u8(i)
  for k,v in pairs(self.task_info) do
    if not id_to_hash[k] then
      abort("Cannot find hash for id %s!",k)
    end
    p:w_u16(id_to_hash[k]) 
    p:w_bool(v.enabled) 
    p:w_bool(v.enabled_props)
    if not status_to_num[v.status] then
      abort("Wrong status '%s' for task %s!",v.status,k)
    end
    p:w_u8(status_to_num[v.status])
    p:w_u32(v.selected_target or -1)
    p:w_u32(v.defend_target or -1)	-- Фикс автозавершения квестов
    utils.w_CTime(p, v.last_task_time)
  end

  --' Та же самая процедура с активными тасками
  i = 0
  for k,v in pairs(self.active_task_by_type) do
    i = i + 1
  end
  p:w_u8(i)
  for k,v in pairs(self.active_task_by_type) do
    if not ct_to_hash[k] then
      abort("Cannot find hash for complex type %s!",k)
    end
    p:w_u16(ct_to_hash[k]) 
    if not id_to_hash[v] then
      abort("Cannot find hash for task id %s!",v)
    end
    p:w_u16(id_to_hash[v])
  end

  -- Фикс автозавершения квестов
  db.actor:give_info_portion("fix_task_manager")
end

--' Загрузка
function CRandomTask:load(p)
  printf("^^^ LOAD")
  --' Считаем количество записей
  local rt0=p:r_tell()
  local i = p:r_u8()
  amk.mylog("tasks "..i)
  if i~=255 then
    for k = 1,i do
      local id = p:r_stringZ()
      if id ~= nil and self.task_info[id] ~= nil then
            self.task_info[id].enabled = p:r_bool()
            self.task_info[id].enabled_props = p:r_bool()
            self.task_info[id].status = p:r_stringZ()

            local selected_target = p:r_u32()
            if selected_target ~= -1 then
              self.task_info[id].selected_target = selected_target
            end

			-- Фикс автозавершения квестов
			if has_alife_info("fix_task_manager") then
				local defend_target = p:r_u32()
				if defend_target ~= -1 then
				  self.task_info[id].defend_target = defend_target
				end
			end
            self.task_info[id].last_task_time = utils.r_CTime(p)
      end
    end
    --' Та же самая процедура с активными тасками
    local i = p:r_u8()  
    amk.mylog("active "..i)
    for k = 1,i do
      local id = p:r_stringZ()
      self.active_task_by_type[id] = p:r_stringZ()  
    end
  else
    i=p:r_u8()
    for k = 1,i do
      local hash = p:r_u16() 
      local id=hash_to_id[hash]
      if not id then
        abort("Cannot find id for hash %d!",hash)
      end
      self.task_info[id].enabled = p:r_bool()
      self.task_info[id].enabled_props = p:r_bool()
      self.task_info[id].status = num_to_status[p:r_u8()]

      local selected_target = p:r_u32()
      if selected_target ~= -1 then
        self.task_info[id].selected_target = selected_target
      end
	  
	  -- Фикс автозавершения квестов
	  if has_alife_info("fix_task_manager") then
		local defend_target = p:r_u32()
		if defend_target ~= -1 then
		  self.task_info[id].defend_target = defend_target
		end
	  end
      self.task_info[id].last_task_time = utils.r_CTime(p)
    end
    --' Та же самая процедура с активными тасками
    i = p:r_u8()  
    amk.mylog("active "..i)
    for k = 1,i do
      local cthash = p:r_u16()
      local id=hash_to_ct[cthash]
      if not id then
        abort("Cannot find complex type for hash %d!",cthash)
      end
      local hash=p:r_u16()
      self.active_task_by_type[id] = hash_to_id[hash]
      if not self.active_task_by_type[id] then
        abort("Cannot find task id for hash %d!",hash)
      end
    end
    amk.mylog("Feel the difference.")
  end
  amk.mylog("size "..p:r_tell()-rt0)
end

Если адаптация к старым сейвам не нужна, то можно выкинуть поршень fix_task_manager и все его проверки.

 

 

Изменено пользователем proper70
  • Нравится 2

Поделиться этим сообщением


Ссылка на сообщение
(изменено)

Совершенно случайно нашел истинную причину, почему бьются сейвы в Лиманске, если сохраниться рядом зомби и изломами, бились сейвы в ОП-1 в Путепроводе, бьются сейвы если не зачистить территорию после взятия некоторых тайников Кости, когда спавнятся зомбированные сталкеры и зомби одновременно. Вот цитата со stalkerwiki:

 

 

В оригинале ОГСМ и основанных на нём модах часто встречались проблемы с сохранениями на Радаре. Эту проблему долго не удавалось победить, пока наконец благодаря помощи Маландринуса не удалось выявить её первопричину. Как выяснилось, она очень проста - гражданские зомби в моде (монстры) имели в конфиге ту же пропись вида (параметр конфига species), что и монолитовцы и зомбированные (неписи). И там и тут было проставлено "zombie", и так оно было ещё с оригинала. Как оказалось, так делать категорически нельзя. Дело в том, что у неписей есть такой функционал, как хитовая память - в ней какое-то время хранятся ссылки на атакующие объекты. У монстров тоже есть остатки этого функционала, но он неработоспособен, и использовать его нельзя. В случае же когда монстры и неписи попадают в один вид, в ситуации когда они находятся рядом в бою, хитовая память монстров автоматически получает от неписей того же вида распространяемую внутри вида информацию об атакующих - а хранить её монстрам нельзя. Если после создания такой ситуации сохраниться - сейв будет вызывать вылет при загрузке. То есть проще говоря, если в бою с монолитовцами рядом оказывались гражданские зомби - и игрок сохранял игру - сейв этот не загружался. Чтобы предотвратить эти проблемы, вполне достаточно создать для гражданских зомби свой отдельный вид, добавив его прописи в конфиг game_relations.

 

 

так и сделал) оставил у всех сталкеров 

species                            = zombie

а всем зомби и изломам поставил

species                    = zombi

завел эту новую группу в game_relations.ltx и поставил ей такие же параметры друг-враг, как и у zombie

 

загрузил имевшийся у меня сейв  в Лиманске, и сохранился у фонтана, где бегали и неписи и моснтры зомби, и загрузил этот сейв. И - о чудо - сейв загрузился!!! То есть бились сейвы, где зомби-неписи и зомби-монстры были рядом. Подобное есть по тайникам Кости, где идет спавн при взятии тайника - там была такая же проблема) теперь и она решена))

 

По этой же причине в солянке не работали изломы в x-16 и Архара был вынужден их убрать оттуда из спавна - потому что там терлись неписи/зомби, и они вместе приходили в онлайн. На Янтаре нет битья сейвов потому, что там нет монстров зомби и изломов, а иначе была бы та же проблема))

 

Здорово, 697e7bf03714a0175ceff55cef81032b.gif только вот пост не совсем в тему...

ColR_iT

Изменено пользователем ColR_iT
  • Спасибо 1
  • Полезно 1

Поделиться этим сообщением


Ссылка на сообщение
  • Недавно просматривали   0 пользователей

    Ни один зарегистрированный пользователь не просматривает эту страницу.

AMK-Team.ru

×
×
  • Создать...