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

[SoC] Ковыряемся в файлах

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

Daniar299, как это не изменилось, т.е везде стоит last_day? а лог

Expression    : no_assert
Function      : CIni_IdToIndex<1,struct COMMUNITY_DATA,class shared_str,int,class CHARACTER_COMMUNITY>::GetById
File          : e:\stalker\patch_1_0004\xr_3da\xrgame\ini_id_loader.h
Line          : 134
Description   : item not found, id
Arguments     : last day

и неплохо бы, чтобы ты под спойлером выложил все что делал.

Изменено пользователем Вампир35
Ссылка на комментарий

Вампир35, Да лог тот же вот что я делал::

[game_relations]
;реальное разделение на группы репутаций на шкалы
rating            = novice, 300, experienced, 600, veteran, 900, master
monster_rating    = weak, 400, normal, 800, strong
reputation        = terrible, -1000, very_bad, -150, bad, -50, neutral, 50, good, 150, very_good, 1000, excellent

;шкалы для вывода названий вместо чисел 
;рейтингов, репутаций и благосклонности в интерфейсе
rating_names        = novice, 300, experienced, 600, veteran, 900, master
reputation_names    = terrible, -1000, very_bad, -150, bad, -50, neutral, 50, good, 150, very_good, 1000, excellent
goodwill_names      = enemy, -150, indifferent, 400, friendly

;пороговые значения для отношения персонажей
attitude_neutal_threshold =  -150    ;когда attitude меньше значения, то выставляется ALife::eRelationEnemy
attitude_friend_threshold =   400    ;когда attitude меньше значения, то выставляется ALife::eRelationNeutral, иначе ALife::eRelationFriend

;константы, которые присвоят скриптовые функции set_relation для personal goodwill
goodwill_enemy  = -1000
goodwill_neutal =    0 
goodwill_friend =  1000

;названия группировок
communities        = actor, 0, actor_dolg, 1, actor_freedom, 2, stalker, 5, monolith, 6, military, 7, killer, 8, ecolog, 9, dolg, 10, freedom, 11, bandit, 12, zombied, 13, stranger, 14, trader, 15, arena_enemy, 16, Last_Day, 18, actor_Last_Day, 19,


;    отношение персонажа к актеру (или другому NPC) вычисляется по формуле
;    attitude = personal_goodwill +     //личное отношение персонажа к актеру (если раньше не встречались, то 0)
;              community_goodwill +   //отношение группировки персонажа лично к актеру (если раньше контактов не было, то 0)
;          community_to_community +   //отношение группировки персонажа к группировке актера из [communities_relations]
;                reputation_goodwill +     //отношение репутации персонажа к репутации актера из [reputation_relations]
;                   rank_goodwill     //отношение ранга персонажа к рангу актера из [rank_relations]

[communities_relations]
;                  |actor  |act_dol|act_fre|stalker|monolit|militar|killer |ecolog |dolg   |freedom|bandit |zombied|strange|trader |arena_enemy| Last_Day | actor_Last_Day| 
;===============================================================================
==================================================
actor        =           0,       0,       0,      50,  -1000,   -750,  -1250,      0,       0,       0,   -350,  -2000,       0,      0,  -1250




actor_dolg    =           0,       0,       0,      0,  -2000,   -650,  -1200,    500,    250,  -1250,  -1000,  -2000,       0,      0,  -1250




actor_freedom =                   0,       0,       0,     -80,  -1500,  -1500,   -750,   -100,  -1250,    150,    -150,  -2000,       0,      0,  -1250




stalker        =          50,       0,     -80,      40,  -1000,  -1250,  -1500,      0,       0,       0,   -250,  -2000,       0,      0,  -1250




monolith    =           -1000,  -2000,  -1500,  -1000,    400,  -2000,   -500,   -750,  -2000,  -1500,  -1250,    150,  -1250,      0,  -1250




military    =            -750,   -650,  -1500,  -1250,  -2000,    700,  -1250,     40,   -650,  -1500,  -2000,  -2000,     -100,      0,  -1250




killer        =           -1250,  -1250,   -650,  -1500,   -500,  -1250,    150,  -1250,  -1500,   -650,   -500,  -2000,  -1250,      0,  -1250




ecolog        =           0,    500,   -100,      0,   -650,     40,  -1500,   1250,    500,   -100,  -1000,  -2000,       0,      0,      0




dolg        =           0,    250,  -1250,      0,  -2000,   -650,  -1500,    500,    650,  -1500,  -1250,  -2000,       0,      0,      0




freedom        =           0,  -1250,     150,       0,  -1500,  -1500,   -650,   -100,  -1250,    150,    -150,  -2000,       0,      0,      0




bandit        =            -350,  -1000,    -150,   -250,  -1250,  -2000,   -500,  -1000,  -1250,    -150,      40,  -2000,  -1250,      0,  -1250




zombied        =           -2000,  -2000,  -2000,  -2000,    150,  -2000,  -2000,  -2000,  -2000,  -2000,  -2000,    250,  -1250,      0,  -1250




stranger    =           0,       0,       0,      0,   -250,   -100,   -650,      0,       0,       0,   -150,  -1250,       0,      0,      0




trader        =           0,       0,     -40,       0,       0,        0,       0,       0,       0,       0,       0,       0,      0,      0,      0




arena_enemy =                   -1000,  -1250,  -1250,  -1000,  -1250,  -1250,  -1250,      0,   -650,  -1250,  -1250,      0,      0,      0,      0



Last_Day = 0,       0,       0,       0,  -5000,  -5000,  -5000,      0,       0,       0,  -5000,  -5000,       0,      0,  -5000, 0

actor_Last_Day = 0, 0, 0, 0, -5000, -5000, -5000, 0, 0, 0, -5000, -5000, 0, 0, -5000, 0, 600, 600

[rank_relations]
;                  novice, experienced, veteran, master
;================================================================
novice            =    70,     20,        0,      0
experienced        =    20,     70,       20,        0
veteran            =     0,     20,       70,       20
master            =     0,      0,       20,       70



[reputation_relations]
;               terrible, very_bad, bad, neutral, good, very_good, excellent
;================================================================
terrible        =    -250,   -100,    -50,  -20,      0,      0,     0
very_bad        =    -100,    -50,    -20,    0,      0,      0,     0
bad             =     -50,    -20,    0,    0,      0,      0,     0
neutral            =     -20,    0,    0,    0,      0,      0,        50
good            =    0,    0,    0,    0,      0,     50,       100
very_good        =    0,    0,    0,    0,     50,    100,       200
excellent        =    0,    0,    0,   50,    100,    200,       350


;
; очки рейтинга и репутации начисляемые за определенные действия
;

;коэффициенты "сочувствия" группировок
;после воздействия на одного из членов группировки
;goodwill его распространится на остальных членов группировки
;с определенным коэффициентом
[communities_sympathy]
actor        =        0.0
actor_dolg    =        0.0
actor_freedom =                0.0
stalker        =        0.0
monolith    =        0.2
military    =        0.2
killer        =        0.2
ecolog        =        0.4
dolg        =        0.2
freedom        =        0.2
bandit        =        0.1
zombied        =        0.0
trader        =        0.2
stranger    =        0.0
arena_enemy =    0.0
Last_Day        =         0.0

actor_Last_Day = 0.0

;
;очки рейтинга, получаемые за убийство персонажа
;с определенным статусом
[rank_kill_points]
novice            =        0
experienced        =        0    
veteran            =        0
master            =        0

  --[[------------------------------------------------------------------------------------------------------------------
Respawner. Схема обновления популяции всего всего всего в симуляции.
by Stohe (Диденко Руслан)
--------------------------------------------------------------------------------------------------------------------]]

--function printf()
--end

local section_name = "respawn"
local i,k,v = 0,0,0

-- Таблица ограничений на спаун: всего в симуляции не должно быть больше, чем указано.
local simMaxCount = {
  stalker_novice = 26, stalker_regular = 24, stalker_veteran = 22, stalker_master = 10,
  monolith_novice = 2, monolith_regular = 15, monolith_veteran = 17, monolith_master = 15,
  military_novice = 2, military_regular = 16, military_veteran = 11, military_master = 2,
  killer_novice = 2, killer_regular = 15, killer_veteran = 13, killer_master = 10,
  ecolog_novice = 1, ecolog_regular = 1, ecolog_veteran = 1, ecolog_master = 1,
  dolg_novice = 2, dolg_regular = 17, dolg_veteran = 18, dolg_master = 8,
  freedom_novice = 25, freedom_regular = 10, freedom_veteran = 13, freedom_master = 10,
  bandit_novice = 15, bandit_regular = 20, bandit_veteran = 9, bandit_master = 5,
  zombied_novice = 10, zombied_regular = 7, zombied_veteran = 5, zombied_master = 5,
  Last_Day_novice = 20, Last_Day_regular = 20, Last_Day_veteran = 20, Last_Day_master = 6,

local killCountProps = {
    neutral_novice = 1,     neutral_experienced = 2,     neutral_veteran = 3,     neutral_master = 4,
    monolith_novice = 1,     monolith_experienced = 2,     monolith_veteran = 3,     monolith_master = 4,
    military_novice = 1,     military_experienced = 2,     military_veteran = 3,     military_master = 4,
    killer_novice = 1,     killer_experienced = 2,     killer_veteran = 3,     killer_master = 4,
    ecolog_novice = 1,     ecolog_experienced = 2,     ecolog_veteran = 3,     ecolog_master = 4,
    dolg_novice = 1,     dolg_experienced = 2,         dolg_veteran = 3,     dolg_master = 4,
    freedom_novice = 1,     freedom_experienced = 2,     freedom_veteran = 3,     freedom_master = 4,
    bandit_novice = 1,     bandit_experienced = 2,     bandit_veteran = 3,     bandit_master = 4,
    zombied_novice = 1,     zombied_experienced = 2,     zombied_veteran = 3,     zombied_master = 4,
        Last_Day_novice = 1,    Last_Day_experienced = 2,       Last_Day_veteran = 3,   Last_Day_master = 4,
    
    tushkano_weak = 1,
    flesh_weak = 1,     flesh_normal = 2,     flesh_strong = 3,
    boar_weak = 1,         boar_normal = 2,     boar_strong = 3,
    cat_weak = 1,
    burer_weak = 1, burer_normal = 2, burer_strong = 3,
    fracture_weak = 1, fracture_normal = 2, fracture_strong = 3,
    chimera_weak = 1, chimera_normal = 2, chimera_strong = 3,
    zombie_weak = 1, zombie_normal = 2, zombie_strong = 3,
    dog_weak = 1,         dog_normal = 2,     dog_strong = 3,
    pseudodog_weak = 1,     pseudodog_normal = 2,     pseudodog_strong = 3,
    psy_dog_weak = 1,     psy_dog_normal = 2,     psy_dog_strong = 3,
    snork_weak = 2,     snork_normal = 3,     snork_strong = 4,
    poltergeist_weak = 2,
    pseudo_gigant_weak = 4,
    controller_weak = 4,
    bloodsucker_weak = 1,     bloodsucker_normal = 2, bloodsucker_strong = 3
}

local sect_alias = {    
    tushkano_normal = "tushkano_weak",
    tushkano_strong = "tushkano_weak",
    burer_normal = "burer_weak",
    burer_strong = "burer_weak",
    fracture_normal = "fracture_weak",
    fracture_strong = "fracture_weak",
    cat_normal = "cat_weak",
    cat_strong = "cat_weak",
    chimera_normal = "fracture_weak",
    chimera_strong = "fracture_weak",
    poltergeist_normal = "poltergeist_weak",
    poltergeist_strong = "poltergeist_weak",
    pseudo_gigant_normal = "pseudo_gigant_weak",
    pseudo_gigant_strong = "pseudo_gigant_weak",
    controller_normal = "controller_weak",
    controller_strong = "controller_weak",
    --[[ -- алиасы не нужны
    psy_dog_weak = "psy_dog",
    psy_dog_normal = "psy_dog",
    psy_dog_strong = "psy_dog", ]]
    zombie_trup = "zombie_weak",
    zombie_trup2 = "zombie_weak"
}

monster_classes = {
            [clsid.tushkano_s    ] = "tushkano",
            [clsid.flesh_s       ] = "flesh",
            [clsid.boar_s        ] = "boar",
            [clsid.cat_s         ] = "cat",
            [clsid.zombie_s      ] = "zombie",
            [clsid.burer_s       ] = "burer",
            [clsid.fracture_s    ] = "fracture",
            [clsid.chimera_s     ] = "chimera",
            [clsid.dog_s         ] = "dog",
            [clsid.pseudodog_s   ] = "pseudodog",
            [clsid.psy_dog_s     ] = "psy_dog",
            [clsid.psy_dog_phantom_s] = "psy_dog_phantom",
            [clsid.snork_s       ] = "snork",
            [clsid.poltergeist_s ] = "poltergeist",
            [clsid.gigant_s      ] = "pseudo_gigant",
            [clsid.controller_s  ] = "controller",
            [clsid.bloodsucker_s ] = "bloodsucker"
        }        


function addKillCount(npc)
if(npc) then
    local props, sect = getNpcType(npc)
    if (props == nil or sect == nil) then
        return
    end

    local sect_name
    if sect_alias[sect] ~= nil then
        sect_name = sect_alias[sect]
    else
        sect_name = sect
    end

    if killCountProps[sect_name] == nil then
        print_table(sect_alias)
        abort("Statistic ERROR: required section [%s] not present, based [%s]", tostring(sect_name), tostring(sect))
    end
    actor_stats.add_points(props, sect_name, 1, killCountProps[sect_name])
    db.actor:set_character_rank(db.actor:character_rank() + killCountProps[sect_name])
end
end


function getNpcType(npc)
    if npc == nil then
        return nil
    end
    if IsStalker(npc) then
        local community = "neutral"
        if     npc:character_community() == "monolith" then    community = "monolith"
        elseif npc:character_community() == "military" then     community = "military"
        elseif npc:character_community() == "killer" then     community = "killer"
        elseif npc:character_community() == "ecolog" then     community = "ecolog"
        elseif npc:character_community() == "dolg" then     community = "dolg"
        elseif npc:character_community() == "freedom" then     community = "freedom"
        elseif npc:character_community() == "bandit" then     community = "bandit"
        elseif npc:character_community() == "zombied" then     community = "zombied"
                elseif npc:character_community() == "Last_Day" then     community = "Last_Day"
        end

function init_drop_settings()
    local community_list = { "stalker", "dolg", "freedom", "bandit", "military", "zombied", "ecolog", "killer", "monolith", "arena_enemy", "actor_dolg", "Last_Day", "actor_Last_Day" }

 

 <string id="Last_Day">
    <text>"Последний день"</text>
  </string>

 

Ссылка на комментарий
Daniar299, во-первых зачем тебе группировка actor_last_day? При вступлении просто давай гг группировку last_day, раз лог тот же, посмотри, кому ты прописывал эту группировку, правильно ли там написано? Изменено пользователем Вампир35
Ссылка на комментарий

Morder07, Это не скрипт а логика. gamedata\config\scripts\gar_dm_bandit1.ltx, gar_dm_bandit2.ltx, gar_dm_bandit3.ltx, gar_dm_novice.ltx.

---

Подскажите можно ли заспавнить свет или лампочку и как? Просто есть помещение которое необходимо осветить (типа люстры на потолке).

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

ЯДиск папка с крутым схроном!

Ссылка на комментарий

Вампир35, исправил название группировки у НПС которому её дал появилось так:

Expression    : no_assert
Function      : CIni_IdToIndex<1,struct COMMUNITY_DATA,class shared_str,int,class CHARACTER_COMMUNITY>::GetById
File          : e:\stalker\patch_1_0004\xr_3da\xrgame\ini_id_loader.h
Line          : 134
Description   : item not found, id
Arguments     : last_day

 

Добавлено через 5 мин.:

Как я понел он не может найти ид группировки, но как его прописать???

Ссылка на комментарий
[game_relations]
;реальное разделение на группы репутаций на шкалы
rating            = novice, 300, experienced, 600, veteran, 900, master
monster_rating    = weak, 400, normal, 800, strong
reputation        = terrible, -1000, very_bad, -150, bad, -50, neutral, 50, good, 150, very_good, 1000, excellent

;шкалы для вывода названий вместо чисел 
;рейтингов, репутаций и благосклонности в интерфейсе
rating_names        = novice, 300, experienced, 600, veteran, 900, master
reputation_names    = terrible, -1000, very_bad, -150, bad, -50, neutral, 50, good, 150, very_good, 1000, excellent
goodwill_names      = enemy, -400, indifferent, 500, friendly

;пороговые значения для отношения персонажей
attitude_neutal_threshold = -400;когда attitude меньше значения, то выставляется ALife::eRelationEnemy
attitude_friend_threshold =  500;когда attitude меньше значения, то выставляется ALife::eRelationNeutral, иначе ALife::eRelationFriend

;константы, которые присвоят скриптовые функции set_relation для personal goodwill
goodwill_enemy  = -1000
goodwill_neutal = 0 
goodwill_friend = 1000

;названия группировок
communities        = actor, 0, actor_dolg, 1, actor_freedom, 2, stalker, 5, monolith, 6, military, 7, killer, 8, ecolog, 9, dolg, 10, freedom, 11, bandit, 12, zombied, 13, stranger, 14, trader, 15, arena_enemy, 16, last_day, 17



;    отношение персонажа к актеру (или другому NPC) вычисляется по формуле
;    attitude = personal_goodwill +                //личное отношение персонажа к актеру (если раньше не встречались, то 0)
;               community_goodwill +                //отношение группировки персонажа лично к актеру (если раньше контактов не было, то 0)
;               community_to_community +            //отношение группировки персонажа к группировке актера из [communities_relations]
;              reputation_goodwill +            //отношение репутации персонажа к репутации актера из [reputation_relations]
;               rank_goodwill                    //отношение ранга персонажа к рангу актера из [rank_relations]

[communities_relations]
;                |actor  |act_dol|act_fre|stalker|monolit|militar|killer |ecolog |dolg   |freedom|bandit |zombied|strange|trader |arena_enemy|last_day|
;===============================================================================
==================================================
actor        =           0,       0,       0,       0,  -5000,  -5000,  -5000,      0,       0,       0,  -5000,  -5000,       0,      0,  -5000,0
actor_dolg    =           0,       0,       0,      0,  -5000,   -500,  -5000,   5000,    600,  -5000,  -5000,  -5000,       0,      0,  -5000,0
actor_freedom =           0,       0,       0,       0,  -5000,  -5000,  -5000,  -1500,  -5000,   5000,       0,  -5000,       0,      0,  -5000,0

stalker        =           0,       0,       0,       0,  -5000,  -5000,  -5000,      0,       0,       0,  -5000,  -5000,       0,      0,  -5000,0
monolith    =       -5000,  -5000,  -5000,  -5000,   5000,  -5000,  -5000,  -5000,  -5000,  -5000,   5000,   5000,  -5000,      0,  -5000,0
military    =       -5000,  -5000,  -5000,  -5000,  -5000,   5000,  -5000,      0,  -5000,  -5000,  -5000,  -5000,        0,      0,  -5000
killer        =       -5000,  -5000,      0,  -5000,  -5000,  -5000,   5000,  -5000,  -5000,  -5000,       0,  -5000,  -5000,      0,  -5000,0
ecolog        =           0,     600,  -5000,      0,  -5000,   1000,  -5000,   5000,    500,  -5000,   -500,  -5000,       0,      0,      0,0
dolg        =           0,    600,  -5000,      0,  -5000,   -500,  -5000,   5000,   5000,  -5000,  -5000,  -5000,       0,      0,      0,0
freedom        =           0,  -5000,     600,       0,  -5000,  -5000,  -5000,  -1500,  -5000,   5000,       0,  -5000,       0,      0,      0,0
bandit        =       -5000,  -5000,       0,  -5000,  -5000,   -500,      0,  -5000,  -5000,       0,       0,  -5000,  -5000,      0,  -5000,0
zombied        =       -5000,  -5000,  -5000,  -5000,   5000,  -5000,  -5000,  -5000,  -5000,  -5000,  -5000,   5000,  -5000,      0,  -5000,0
stranger    =           0,       0,       0,      0,  -5000,  -5000,  -5000,      0,       0,       0,   -500,  -5000,       0,      0,      0,0
trader        =           0,       0,       0,       0,       0,        0,       0,       0,       0,       0,       0,       0,      0,      0,      0,0
arena_enemy =       -5000,  -5000,  -5000,  -5000,  -5000,  -5000,      0,      0,      0,  -5000,  -5000,      0,      0,      0,      0,0
last_day    =       -5000,  -5000,  -5000,  -5000,   5000,  -5000,  -5000,  -5000,  -5000,  -5000,   5000,   5000,  -5000,      0,  -5000,0

[rank_relations]
;                  novice, experienced, veteran, master
;================================================================
novice            =    0,        0,        0,        0
experienced        =   0,        0,        0,        0
veteran            =   0,      0,        0,        0
master            =   0,      0,        0,        0



[reputation_relations]
;               terrible, very_bad, bad, neutral, good, very_good, excellent
;================================================================
terrible        =    0,        0,        0,        0,      0,      0,     0
very_bad        =    0,        0,        0,        0,      0,      0,     0
bad                =    0,        0,        0,        0,      0,      0,     0
neutral            =    0,        0,        0,        0,      0,      0,     0
good            =    0,        0,        0,        0,      0,      0,     0
very_good        =    0,        0,        0,        0,      0,      0,     0
excellent        =    0,        0,        0,        0,      0,      0,     0


;
; очки рейтинга и репутации начисляемые за определенные действия
;

;коэффициенты "сочувствия" группировок
;после воздействия на одного из членов группировки
;goodwill его распространится на остальных членов группировки
;с определенным коэффициентом
[communities_sympathy]
actor        =        0.0
actor_dolg    =        0.0
actor_freedom =        0.0
stalker        =        0.0
monolith    =        0.0
military    =        0.0
killer        =        0.0
ecolog        =        0.0
dolg        =        0.1
freedom        =        0.1
bandit        =        0.0
zombied        =        0.0
trader        =        0.0
stranger    =        0.0
arena_enemy =        0.0
last_day =        0.0

;
;очки рейтинга, получаемые за убийство персонажа
;с определенным статусом
[rank_kill_points]
novice            =        0
experienced        =         0    
veteran            =        0
master            =        0

;очки рейтинга, репутации и доброжелательности начисляемые
;в зависимости от совершенного действия
[action_points]
personal_goodwill_limits            = -1000, 1000
community_goodwill_limits            = -3000, 1000 
;-------------------------------------------------------
free_friend_attack_goodwill            = -2500
free_neutral_attack_goodwill        = -1000
free_enemy_attack_goodwill            = 0

danger_friend_attack_goodwill        = -200
danger_neutral_attack_goodwill        = -200
danger_enemy_attack_goodwill        = 0

free_friend_attack_reputation        = -20
free_neutral_attack_reputation        = -10
free_enemy_attack_reputation        = 0

danger_friend_attack_reputation        = 0
danger_neutral_attack_reputation    = 0
danger_enemy_attack_reputation        = 0
;--------------------------------------------------
;(с) мин. время через которое снова будет зарегистрировано 
;сообщение об атаке на персонажа, и соответственно вычтеся attack_goodwill и attack_reputation
;(работает аналогично и при помощи другим персонажам в бою)
min_attack_delta_time = 3        

friend_kill_goodwill            = -1000
neutral_kill_goodwill            = -1000
enemy_kill_goodwill                = 0
community_member_kill_goodwill  = -1000

;убийство члена группировки отражается на отношении
;группировки (умножается на communities_sympathy)

friend_kill_reputation            = -40
neutral_kill_reputation            = -15
enemy_kill_reputation            = 0

;
; помощь актера персонажу во время боя
;
fight_remember_time = 10;(c) время которое про драку будет помнить реестр

friend_fight_help_goodwill   = 200
neutral_fight_help_goodwill     = 200 
enemy_fight_help_goodwill    = 0

friend_fight_help_reputation  = 10
neutral_fight_help_reputation = 10
enemy_fight_help_reputation      = 0

;свойства, которые изменяются у сталкеров в 
;зависимости от их ранга 
;коэффициенты линейно интерполируются для рангов от 0 (novice) до 100 (experienced)




[ranks_properties]
immunities_novice_k            = 1.0
immunities_experienced_k    = 1.0

visibility_novice_k            = 1
visibility_experienced_k    = 1

dispersion_novice_k            = 1.0
dispersion_experienced_k    = 0.1


; диапазон изменения рангов при регистрации в новом смарт террейне
[smart_terrain_rank_change]
min = 1
max = 30

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; for monsters
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

[monster_communities]
;номера team которые присваиваются соответствующим видам
;255 - команда не задается   
communities = actor, 255, human, 255, arena_monstr, 39, boar, 40, bloodsucker, 41, flesh, 42,  dog, 43, pseudodog, 44, cat, 45, chimera, 46, giant, 47, zombie, 48,  burer, 49, controller, 50, poltergeist, 51, snork, 52, fracture, 53, bird, 54, rat, 55, tushkano, 56

[monster_relations]
; [1] друг, [0] нейтрал, [-1] враг, [-2] злейший враг
;                actor,human,arena_monstr, boar, bloodsucker, flesh,  dog, pseudodog, cat, chimera, giant, zombie,  burer, controller, poltergeist, snork, fracture, bird,   rat, tushkano
;===============================================================================
================================================================================
=
==========
actor        =     1,         1,       -2,        -1,        -1,            -1,        -1,        -1,        -1,        -1,        -1,        -1,        -1,        -1,            -1,            -1,        -1,        0,         0,        -1
human        =      0          1,        0,        -1,        -1,            -1,        -1,        -1,        -1,        -1,        -1,        -1,        -1,        -1,            -1,            -1,        -1,        0,         0,        -1
arena_monstr=    -2,         0,        0,         0,         0,             0,         0,         0,         0,         0,         0,         0,         0,         0,             0,             0,         0,        0,         0,         0
boar        =    -2,        -2,        0,         1,        -1,             0,        -1,        -1,         0,         0,        -1,         0,         0,        -1,            -1,             0,         0,        0,         0,         0
bloodsucker    =    -2,        -2,        0,        -1,         1,            -1,         0,         0,         0,         0,         0,         0,         0,         0,             0,             0,         0,        0,         0,         0
flesh        =    -2,        -1,        0,         0,        -1,             1,        -1,        -1,         0,         0,        -1,         0,         0,        -1,            -1,             0,         0,        0,         0,         0
dog            =    -2,        -1,        0,        -1,         0,            -1,         1,         0,         0,         0,        -1,         0,        -1,        -1,            -1,             0,         0,        0,         0,         0
pseudodog    =    -2,        -1,        0,        -1,         0,            -1,         0,         1,         0,         0,        -1,         0,        -1,         0,            -1,             0,         0,        0,         0,         0
cat            =    -2,        -1,        0,         0,         0,             0,         0,         0,      1,         0,         0,         0,         0,         0,             0,             0,         0,        0,         0,         0
chimera        =    -2,        -1,        0,         0,         0,             0,         0,         0,         0,      1,         0,         0,         0,         0,             0,             0,         0,        0,         0,         0
giant        =    -2,        -1,        0,        -1,         0,            -1,        -1,        -1,         0,         0,         1,         0,         0,         0,             0,             0,         0,        0,         0,         0
zombie        =    -2,        -1,        0,         0,         0,             0,         0,         0,         0,         0,         0,         1,         0,         0,             0,             0,         0,        0,         0,         0
burer        =    -2,        -2,        0,         0,         0,            -1,        -1,        -1,         0,         0,         0,         0,         1,         0,             0,             0,         0,        0,         0,         0
controller    =    -2,        -2,        0,        -1,         0,            -1,        -1,         0,         0,         0,         0,         0,         0,         1,             0,            -1,         0,        0,         0,         0
poltergeist    =    -2,        -1,        0,        -1,         0,            -1,        -1,        -1,         0,         0,         0,         0,         0,         0,             1,             0,         0,        0,         0,         0
snork        =    -2,        -1,        0,         0,         0,             0,         0,         0,         0,         0,         0,         0,         0,        -1,             0,             1,         0,        0,         0,         0
fracture    =    -2,        -1,        0,         0,         0,             0,         0,         0,         0,         0,         0,         0,         0,         0,             0,             0,         1,        0,         0,         0
bird        =     0,         0,        0,         0,         0,             0,         0,         0,         0,         0,         0,         0,         0,         0,             0,             0,         0,        1,         0,         0
rat            =    -2,        -1,        0,         0,         0,             0,         0,         0,         0,         0,         0,         0,         0,         0,             0,             0,         0,     0,         1,         0
tushkano    =    -2,        -1,        0,         0,         0,             0,         0,         0,         0,         0,         0,         0,         0,         0,             0,             0,         0,        0,         0,         1

[stalker];Указывается вероятность заспаунить или нет
;Артефакты
af_medusa                = 0.015
af_cristall_flower        = 0.01
af_night_star            = 0.005
af_vyvert                = 0.015
af_gravi                = 0.01
af_gold_fish            = 0.005
af_blood                = 0.015
af_mincer_meat            = 0.01
af_soul                    = 0.005
af_electra_sparkler        = 0.015
af_electra_flash        = 0.01
af_electra_moonlight    = 0.005
af_rusty_thorn            = 0.015
af_rusty_kristall        = 0.01
af_rusty_sea-urchin        = 0.005
af_ameba_slime            = 0.015
af_ameba_slug            = 0.01
af_ameba_mica            = 0.005
af_drops                = 0.015
af_fireball                = 0.01
af_cristall                = 0.005
af_dummy_glassbeads        = 0.005
af_dummy_pellicle        = 0.005
af_dummy_battery        = 0.005
af_dummy_dummy            = 0.005
af_dummy_spring            = 0.005
af_fuzz_kolobok            = 0.005

;Аммуниция
ammo_9x18_fmj            = 1
ammo_9x18_pmm            = 1
ammo_9x19_pbp            = 1
ammo_9x19_fmj            = 1
ammo_11.43x23_hydro        = 1
ammo_11.43x23_fmj        = 1
ammo_12x70_buck            = 1
ammo_12x76_dart            = 1
ammo_12x76_zhekan        = 1
ammo_5.45x39_ap            = 1
ammo_5.45x39_fmj        = 1
ammo_9x39_sp5            = 1
ammo_9x39_ap            = 1
ammo_9x39_pab9            = 1
ammo_5.56x45_ss190        = 1
ammo_5.56x45_ap            = 1
ammo_7.62x54_7h14        = 1
ammo_7.62x54_7h1        = 1
ammo_7.62x54_ap            = 1
ammo_gauss                = 1
ammo_og-7b                = 1
ammo_vog-25p            = 0.1
ammo_vog-25                = 0.1
grenade_f1                = 0.1
grenade_rgd5            = 0.1
ammo_m209                = 0.1

;Медикаменты
bandage                    = 0.4
medkit                    = 0.2
medkit_army                = 0
medkit_scientic            = 0.05
antirad                    = 0.2

;Еда
bread                    = 0.2
kolbasa                    = 0.2
conserva                = 0.1
vodka                    = 0.1
energy_drink            = 0.1


[bandit]:stalker

[killer]:stalker
;Еда
bread                    = 0
kolbasa                    = 0
vodka                    = 0
energy_drink            = 0.3

[ecolog]:stalker
;Еда
bread                    = 0
kolbasa                    = 0
conserva                = 0
vodka                    = 0
energy_drink            = 0

medkit                    = 0
medkit_scientic            = 0.2
antirad                    = 0.3

[military]:stalker
af_medusa                = 0
af_cristall_flower        = 0
af_night_star            = 0
af_vyvert                = 0
af_gravi                = 0
af_gold_fish            = 0
af_blood                = 0
af_mincer_meat            = 0
af_soul                    = 0
af_electra_sparkler        = 0
af_electra_flash        = 0
af_electra_moonlight    = 0
af_rusty_thorn            = 0
af_rusty_kristall        = 0
af_rusty_sea-urchin        = 0
af_ameba_slime            = 0
af_ameba_slug            = 0
af_ameba_mica            = 0
af_drops                = 0
af_fireball                = 0
af_cristall                = 0
af_dummy_glassbeads        = 0
af_dummy_pellicle        = 0
af_dummy_battery        = 0
af_dummy_dummy            = 0
af_dummy_spring            = 0
af_fuzz_kolobok            = 0

;Медикаменты
bandage                    = 0.4
antirad                    = 0.3
medkit                    = 0
medkit_scientic            = 0
medkit_army                = 0.2

;Еда
bread                    = 0.2
kolbasa                    = 0
conserva                = 0.3
vodka                    = 0
energy_drink            = 0


[dolg]:stalker
;Медикаменты
medkit_army                = 0.2
medkit_scientic            = 0.2

[freedom]:stalker
;Еда
vodka                    = 0.5

[zombied]:stalker
af_medusa                = 0
af_cristall_flower        = 0
af_night_star            = 0
af_vyvert                = 0
af_gravi                = 0
af_gold_fish            = 0
af_blood                = 0
af_mincer_meat            = 0
af_soul                    = 0
af_electra_sparkler        = 0
af_electra_flash        = 0
af_electra_moonlight    = 0
af_rusty_thorn            = 0
af_rusty_kristall        = 0
af_rusty_sea-urchin        = 0
af_ameba_slime            = 0
af_ameba_slug            = 0
af_ameba_mica            = 0
af_drops                = 0
af_fireball                = 0
af_cristall                = 0
af_dummy_glassbeads        = 0
af_dummy_pellicle        = 0
af_dummy_battery        = 0
af_dummy_dummy            = 0
af_dummy_spring            = 0
af_fuzz_kolobok            = 0

;Еда
bread                    = 0
kolbasa                    = 0
conserva                = 0
vodka                    = 0
energy_drink            = 0

[monolith]:stalker
;Артефакты
af_medusa                = 0
af_cristall_flower        = 0
af_night_star            = 0
af_vyvert                = 0
af_gravi                = 0
af_gold_fish            = 0
af_blood                = 0
af_mincer_meat            = 0
af_soul                    = 0
af_electra_sparkler        = 0
af_electra_flash        = 0
af_electra_moonlight    = 0
af_rusty_thorn            = 0
af_rusty_kristall        = 0
af_rusty_sea-urchin        = 0
af_ameba_slime            = 0
af_ameba_slug            = 0
af_ameba_mica            = 0
af_drops                = 0
af_fireball                = 0
af_cristall                = 0
af_dummy_glassbeads        = 0
af_dummy_pellicle        = 0
af_dummy_battery        = 0
af_dummy_dummy            = 0
af_dummy_spring            = 0
af_fuzz_kolobok            = 0

;Еда
vodka                    = 0


[arena_enemy]


[actor_dolg]

[last_day]:stalker
;Артефакты
af_medusa                = 0.016
af_dummy_glassbeads        = 0.004

--[[------------------------------------------------------------------------------------------------------------------
Respawner. Схема обновления популяции всего всего всего в симуляции.
by Stohe (Диденко Руслан)
--------------------------------------------------------------------------------------------------------------------]]

--function printf()
--end

local section_name = "respawn"
local i,k,v = 0,0,0

-- Таблица ограничений на спаун: всего в симуляции не должно быть больше, чем указано.
local simMaxCount = {
    stalker_novice = 43, stalker_regular = 48, stalker_veteran = 43, stalker_master = 20,
    monolith_novice = 0, monolith_regular = 30, monolith_veteran = 35, monolith_master = 30,
    military_novice = 0, military_regular = 32, military_veteran = 22, military_master = 5,
    killer_novice = 0, killer_regular = 18, killer_veteran = 17, killer_master = 10,
    ecolog_novice = 1, ecolog_regular = 1, ecolog_veteran = 1, ecolog_master = 1,
    dolg_novice = 0, dolg_regular = 33, dolg_veteran = 36, dolg_master = 17,
    freedom_novice = 50, freedom_regular = 20, freedom_veteran = 26, freedom_master = 21,
    bandit_novice = 40, bandit_regular = 50, bandit_veteran = 18, bandit_master = 10,
    zombied_novice = 20, zombied_regular = 15, zombied_veteran = 10, zombied_master = 10,
    last_day_novice = 20, last_day_regular = 15, last_day_veteran = 10, last_day_master = 10,
    
    rat_weak = 0,    
    tushkano_weak = 150,
    flesh_weak = 14, flesh_normal = 38, flesh_strong = 22,
    boar_weak = 52, boar_normal = 38, boar_strong = 27,
    dog_weak = 53, dog_normal = 126, dog_strong = 130,
    pseudodog_weak = 59, pseudodog_normal = 80, pseudodog_strong = 60,
    psy_dog_weak = 15, psy_dog_normal = 15, psy_dog_strong = 15,
    zombie_weak = 61, zombie_normal = 50, zombie_strong = 35,
    snork_weak = 50, snork_normal = 61, snork_strong = 15,
    poltergeist_weak = 10,
    pseudo_gigant_weak = 23,
    controller_weak = 18,
    burer_weak = 20,
    bloodsucker_weak = 7, bloodsucker_normal = 40, bloodsucker_strong = 15    
}

local idle_spawn_preset = {
    seldom = 60*60,
    medium = 60*60,
    often = 60*60
}

-- Список респавнеров, для сбора статистики
local respawners = {}
local respawners_by_parent = {}
----------------------------------------------------------------------------------------------------------------------
-- Разные полезные функции
----------------------------------------------------------------------------------------------------------------------
function r_bool( spawn_ini, section, line, default )
    if spawn_ini:line_exist( section, line ) then
        return spawn_ini:r_bool( section, line )
    else
        return default
    end
end

function r_str( spawn_ini, section, line, default )
    if spawn_ini:line_exist( section, line ) then
        return spawn_ini:r_string( section, line )
    else
        return default
    end
end

function r_num( spawn_ini, section, line, default )
    if spawn_ini:line_exist( section, line ) then
        return spawn_ini:r_float( section, line )
    else
        return default
    end
end

function r_2nums( spawn_ini, section, line, def1, def2 )
    if spawn_ini:line_exist( section, line ) then
        -- если default-ов больше, чем значений в ini, то забить недостающие последним значением из ini
        local t = parse_names( spawn_ini:r_string( section, line ) )
        local n = table.getn( t )

        if n == 0 then
            return def1, def2
        elseif n == 1 then
            return t[1], def2
        else
            return t[1], t[2]
        end
    else
        return def1, def2
    end
end

function parse_names( s )
    local t = {}
    for name in string.gfind( s, "([%w_%-.\\]+)%p*" ) do
        table.insert( t, name )
    end
    return t
end

function r_spawns( spawn_ini, section, line, sectSpawnProps)
    if spawn_ini:line_exist( section, line ) then
        --' если default-ов больше, чем значений в ini, то забить недостающие последним значением из ini
        local t = parse_names( spawn_ini:r_string( section, line ) )
        local n = table.getn( t )
        
        local ret_table = {}
        local k = 1
        while k <= n do
            local spawn = {}
            spawn.section = t[k]
            -- Проверяем что это не последняя запись
            if t[k+1] ~= nil then
                local p = tonumber(t[k+1])
                -- проверяем что вторым числом задана вероятность, а не другая секция спавну
                if p then
                    -- забиваем число
                    spawn.prob = p
                    k = k + 2
                else
                    -- забиваем дефолт 1
                    spawn.prob = 1
                    k = k + 1
                end
            else
                spawn.prob = 1
                k = k + 1
            end
            table.insert(ret_table, spawn)
    
            -- Вычитываем настройки секций респавна и кешируем их.
            if sectSpawnProps[spawn.section] == nil then
                local respawn_ini = system_ini()

                local community = r_str(respawn_ini, spawn.section, "community", "nil")
                local rank = r_str(respawn_ini, spawn.section, "spec_rank", "nil")
                local check = true
                local custom_data = r_str(respawn_ini, spawn.section, "custom_data")
                if custom_data ~= nil then
                    local custom_data_ltx = ini_file(custom_data)
                    if custom_data_ltx:section_exist("smart_terrains") then
                        if custom_data_ltx:line_exist("smart_terrains", "none") then
                            if r_str(custom_data_ltx, "smart_terrains", "none") == "true" then
                                check = false
                            end    
                        end
                        if custom_data_ltx:line_exist("smart_terrains", "respawn_check") then
                            if r_str(custom_data_ltx, "smart_terrains", "respawn_check") == "false" then
                                check = false
                            end
                        end                        
                    end
                end
                
                sectSpawnProps[spawn.section] = {community = community, rank = rank, check = check}
            end
                        
        end
        return ret_table
    end
    return nil
end
----------------------------------------------------------------------------------------------------------------------
-- Серверный объект спавнера
----------------------------------------------------------------------------------------------------------------------
class "se_respawn" ( cse_alife_smart_zone )
function se_respawn:__init( section ) super( section )
    self.spawned_obj = {}
    -- Таблица для кеширования свойств секций респавна.
    self.sectSpawnProps = {}

    self.proxy_initialized = false
end
-- сохранение
function se_respawn:STATE_Write( packet )
    cse_alife_smart_zone.STATE_Write( self, packet )

    local table_size = table.getn(self.spawned_obj)
--    printf("SPAWNER SAVE table_size[%d]", table_size)
--    print_table(self.spawned_obj)
    
    packet:w_u8(table_size)
    for i=1,table_size do
        packet:w_u16(self.spawned_obj[i])
    end
end
-- восстановление
function se_respawn:STATE_Read( packet, size )
    cse_alife_smart_zone.STATE_Read( self, packet, size )
    
    if editor() then
        return
    end

    local table_size = packet:r_u8()
    for i=1,table_size do
        table.insert(self.spawned_obj, packet:r_u16())
    end

--    printf("SPAWNER READ table_size[%d]", table_size)
--    print_table(self.spawned_obj)    
end
-- инициализация объекта.
-- вызывается симулятором.
function se_respawn:on_register()
    cse_alife_smart_zone.on_register( self )
    --printf("RESPAWN: [%s] se_respawn on_register", tostring(self:name()))

    -- Вычитываем настройки спауна
    local ini = self:spawn_ini()
    if not ini:section_exist(section_name) then
        return    
    end
    
    self.respawn_section = r_spawns(ini, section_name, "respawn_section", self.sectSpawnProps)    
    if self.respawn_section == nil then
        abort("RESPAWN: [%s] field 'respawn_section' doesn't exist.", self:name())
    end

    self.min_count = r_num(ini, section_name, "min_count", 0)
    self.max_count = r_num(ini, section_name, "max_count", -1)
    if self.min_count > self.max_count and
       self.max_count ~= -1 
    then
        abort("RESPAWN: [%s] min_count > max_count", self:name())
    end
    --' FOR DEBUG ONLY, please don't forget to delete
    --'if self.max_count > 0 then
    --'    self.min_count = self.max_count
    --'end
    
    self.max_spawn = r_num(ini, section_name, "max_spawn", 1)
    self.idle_spawn_min, self.idle_spawn_max = r_2nums(ini, section_name, "idle_spawn")
    if self.idle_spawn_min == nil then
        abort("RESPAWN: [%s] field 'idle_spawn' doesn't exist.", self:name())
    end
    if self.idle_spawn_max == nil then
        self.idle_spawn_max = self.idle_spawn_min
    end

    --' Вычитка пресетов
    if idle_spawn_preset[self.idle_spawn_min] ~= nil then
        self.idle_spawn_min = idle_spawn_preset[self.idle_spawn_min]
    else
        self.idle_spawn_min = tonumber(self.idle_spawn_min)
    end
    if idle_spawn_preset[self.idle_spawn_max] ~= nil then
        self.idle_spawn_max = idle_spawn_preset[self.idle_spawn_max]
    else
        self.idle_spawn_max = tonumber(self.idle_spawn_max)
    end

    self.str_conditions = r_str(ini, section_name, "conditions", 100) 
    self.conditions = xr_logic.parse_condlist(self, section_name, "conditions", self.str_conditions)
    self.respawn_radius = r_num(ini, section_name, "respawn_radius", -1)

    --' Спешкейс, чтобы сохранить совместимость сейвов.
    if self:name() == "mil_freedom_barier_respawn_1" then
        self.respawn_radius = -1
    end

    self.parent    = r_num(ini, section_name, "parent", nil)
    self.item_spawn    = r_bool(ini, section_name, "item_spawn", false)
    
    -- производим первичную инициализацию
    self.respawn_time = game.CTime()
    
    -- Для сбора статистики сохраняем указатель на респавнер
    respawners[self:name()] = self
    if self.parent ~= nil then
        respawners_by_parent[self.parent] = self
    end

    --' Отметка респавнера мапспотом (для статистики)
    sim_statistic.register_respawn(self)
end
-- Создаем объект
function se_respawn:create(prob)
    if tostring(prob) == "nil" then        
        print_table(self.conditions)
        abort("RESPAWN[%s]spawn probability doesn't set", tostring(self:name()))
        prob = 0
    end
    
    if math.random(100) <= tonumber(prob) then
        local spawn_section = ""
        local sum = 0
        -- Производим рандомную взвешенную выборку
        -- с учетом уже заспавленного количества человек.
        for k,v in pairs(self.respawn_section) do
--'            local tt = self.sectSpawnProps[v.section]
--'            local community_rank = tt.community.."_"..tt.rank
--'            local s_count = simMaxCount[community_rank]
--'            if s_count == nil then
--'                s_count = 0
--'            end
--'            if tt.check == false or
--'               self.item_spawn == true or
--'               sim_statistic.simNpcCount(tt.community, tt.rank) < s_count
--'            then    
                sum = sum + v.prob
--'            end
        end
        sum = math.random(0, sum)
        for k,v in pairs(self.respawn_section) do
--'            local tt = self.sectSpawnProps[v.section]
--'            local community_rank = tt.community.."_"..tt.rank
--'            local s_count = simMaxCount[community_rank]
--'            if s_count == nil then
--'                s_count = 0
--'            end            
--'            if tt.check == false or
--'               self.item_spawn == true or
--'               sim_statistic.simNpcCount(tt.community, tt.rank) < s_count 
--'            then    
                sum = sum - v.prob            
                if sum <= 0 then
                    spawn_section = v.section
                    break
                end
--'            end
        end
        
        if spawn_section == "" then
--            printf("SPAWNING [%s], CANT SPAWN, SIMULATION POPULATION EXCEED", tostring(self:name()))
            return false
        end
        
        local parent_id = nil
        if self.parent ~= nil then
            local s_obj = alife():story_object(self.parent)
            if s_obj == nil then
                abort("SPAWNING [%s], cant find parent with SID [%s]", self:name(), self.parent)
                return
            end
            parent_id = s_obj.id
        end
        
        local obj
        if parent_id == nil then
            obj = alife():create(spawn_section,    
                        self.position,
                        self.m_level_vertex_id,    
                        self.m_game_vertex_id)
        else
            obj = alife():create(spawn_section,    
                        self.position,
                        self.m_level_vertex_id,    
                        self.m_game_vertex_id,
                        parent_id)
        end

        local tt = self.sectSpawnProps[spawn_section]

--        printf("SPAWN [%s] -> [%s]", tostring(self:name()), obj:name())

        if self.item_spawn == false then                
            if tt.check == true then
                obj:brain():update()
                local smart_terrain_id = obj:smart_terrain_id()
    --            printf("SPAWN [%s] move_offline [%s], interactive [%s], smart_terrain_id [%s]", tostring(self:name()), tostring(self:move_offline()), tostring(self:interactive()), smart_terrain_id)
                if smart_terrain_id ~= 65535 then        
                    table.insert(self.spawned_obj ,obj.id)
                    local pos = obj.position
--                    printf("SPAWNING [%s] -> [%s], position [%s][%s][%s]", tostring(self:name()), spawn_section, pos.x, pos.y, pos.z)
                    local sm_obj = alife():object(smart_terrain_id)
                    printf("SPAWNING for SMART [%s] : [%s] -> [%s]", self:name(), obj:name(), sm_obj:name())

                    return true
                else
                    alife():release(obj, true)
--                    printf("SPAWNING [%s] -> [%s], CANT SPAWN. NO SMART_TERRAIN AVAILABLE!!!", tostring(self:name()), spawn_section)
                    return false
                end
            end
        end
        table.insert(self.spawned_obj ,obj.id)
        return true
    end
end
-- Попытка спаунить объекты. Анализируется сколько уже заспавнено и выбирается один из механизмов - либо 
-- мы доспавниваем до минимального количества, либо спавним с заданной вероятностью
function se_respawn:spawn()
--    printf("RESPAWN: [%s] spawn execute", tostring(self:name()))
    
    -- Пробегаемся по списку уже заспавненных объектов и удаляем из них мертвые либо уничтоженные.
    for k,v in pairs(self.spawned_obj) do
        local obj = level.object_by_id(v)
        if obj == nil then
            obj = alife():object(v)
        end
        
        if obj ~= nil then
            if (IsStalker(obj) or IsMonster(obj)) and obj:alive() ~= true then
                table.remove(self.spawned_obj, k)
            end
        else
            table.remove(self.spawned_obj, k)
        end
    end    

    if xr_logic.pick_section_from_condlist(db.actor_proxy, self, self.conditions) == "0" then
--        printf("SPAWNING [%s], CANT SPAWN. PROBABILITY ZERO!!!", tostring(self:name()))
        sim_statistic.respawn_enabled(self, false)
        return
    end
    sim_statistic.respawn_enabled(self, true)
    
    -- экстренный спаун минимального количества объектов
    if table.getn(self.spawned_obj) < self.min_count then    
        while table.getn(self.spawned_obj) < self.min_count do
            if self:create(100) == false then
                return
            end
        end
        return
    end
    
    -- делаем несколько попыток заспаунить объект.
    for i=1,self.max_spawn do        
        if self.max_count ~= -1 and table.getn(self.spawned_obj) >= self.max_count then
--            printf("SPAWNING [%s], CANT SPAWN. MAX COUNT REACHED!!!", tostring(self:name()))
            return
        end        
        if self:create(xr_logic.pick_section_from_condlist(db.actor_proxy, self, self.conditions)) == false then
            return
        end
    end        
end
--' Удаляем уже заспавненный объект из списка заспавненных
--' Используется только  для ящиком со шмотками в смарттеррейнах
function se_respawn:remove_spawned(id)
    for k,v in pairs(self.spawned_obj) do
        if id == v then
            table.remove(self.spawned_obj, k)
        end                
    end    
end
-- Обновление респавнера. В зависимости от настроек обновляется либо только в офлайне, либо и там и там.
function se_respawn:execute()
--    printf("RESPAWN: [%s] se_respawn execute", tostring(self:name()))
    
    --' Выходим, если у нас установлен событийный спавн.
    if self.idle_spawn_min == -1 then
        return
    end
    
    if self.respawn_time < game.get_game_time() then
--        if not self.proxy_initialized then
--            db.actor_proxy:init()
--            self.proxy_initialized = true
--        end

        local idle_time = game.CTime()
        idle_time:setHMSms( 0, 0, 0, math.random(self.idle_spawn_min, self.idle_spawn_max)*1000)
        self.respawn_time = game.get_game_time() + idle_time
        -- Производим попытку заспаунить объекты        
        self:spawn()
        
--        printf("spawn_count = %s", table.getn(self.spawned_obj))
    end
end
-- Обновление в офлайне
function se_respawn:update()
    cse_alife_smart_zone.update( self )
    --'printf("RESPAWN: [%s] se_respawn update_offline", tostring(self:name()))
    self:execute()
end
-- Обновление в онлайне
function se_respawn:update_online()
    --'cse_alife_smart_zone.update( self )
    --'printf("RESPAWN: [%s] se_respawn update_online", tostring(self:name()))
    if self.respawn_radius == -1 then
        sim_statistic.respawn_enabled(self, false)
        return
    end
    if db.actor:position():distance_to (self.position) >= self.respawn_radius then
        self:execute()
    else
        sim_statistic.respawn_enabled(self, false)
    end
end

function spawn(name)
    local spawner = respawners[name]
    if spawner == nil then
        return
    end
    
    for i=1,spawner.max_spawn do
        if spawner.max_count ~= -1 and table.getn(spawner.spawned_obj) >= spawner.max_count then
--            printf("SPAWNING [%s], CANT SPAWN. MAX COUNT REACHED!!!", tostring(spawner:name()))
            return
        end        
        if spawner:create(xr_logic.pick_section_from_condlist(db.actor_proxy, spawner, spawner.conditions)) == false then
            return
        end
    end        
end

function get_respawner_by_parent(parent_id)
    return respawners_by_parent[parent_id]
end

-- Сбор статистики
function stats()
    local total_spawned = 0
    local total_avail = 0
    local total = 0
    printf("***************** RESPAWN STATISTIC *********************")
    for k,v in pairs(respawners) do
        local s = xr_logic.pick_section_from_condlist(db.actor_proxy, v, v.conditions)
        local pops = "DISABLE"
        if s ~= "nil" and s ~= "0" then
            pops = table.getn(v.spawned_obj)
        end
        local str_pops
        if v.max_count == pops then
            str_pops = "FULL "..tostring(pops)
        else
            str_pops = tostring(pops)
        end
        printf("[%s] spawns [%s] object", tostring(v:name()), str_pops)
        print_table(v.respawn_section)
        -- Увеличиваем общие счетчики
        total = total + v.max_count
        if pops ~= "DISABLE" then
            total_avail = total_avail + v.max_count
            total_spawned = total_spawned + pops
        end
    end
    printf("*** SUMMARY ***")
    printf("    total = %s", total)
    printf("    total_avail = %s", total_avail)
    printf("    total_spawned = %s", total_spawned)
    printf("***************")
end



-- Сбор продвинутой статистики статистики по лимитам
function lstats()
    local can_spawn = {}
    printf("***************** LIMITS STATISTIC *********************")
    for k,v in pairs(respawners) do
        -- Запоминаем максимальное количество весов для данного респавнера
        local wage = 0
        for kk,vv in pairs(v.respawn_section) do
            wage = wage + vv.prob
        end
        
        -- Заносим максимальное количество всех типов чуваков, которые данный респавнер может наспаунить.
        for kk,vv in pairs(v.respawn_section) do
            local tt = v.sectSpawnProps[vv.section]
            local community_rank = tt.community.."_"..tt.rank
            if can_spawn[community_rank] == nil then
                can_spawn[community_rank] = {community = tt.community, rank = tt.rank}
            end
        end
    end    
    -- Выводим все это в общей статистике
    local total_max, total_prob, total_current, total_limit = 0,0,0,0
    for k,v in pairs(can_spawn) do
        local cs = sim_statistic.simNpcCount(v.community, v.rank)
        local gl = simMaxCount[k]
        if gl == nil then gl = 0 end

        total_current = total_current + cs
        total_limit = total_limit + gl
        
        printf("%s current=%s limit=%s", k, cs, gl)
    end
    printf("TOTAL: current=%s limit=%s", total_current, total_limit)
end


-- Сбор статистики по ненастроенным объектам
function estats()
    printf("***************** SPAWN ERROR STATISTIC *********************")
    for k,v in pairs(respawners) do
        -- Заносим максимальное количество всех типов чуваков, которые данный респавнер может наспаунить.
        for kk,vv in pairs(v.respawn_section) do
            local tt = v.sectSpawnProps[vv.section]
            if tt.community == "nil" or tt.rank == "nil" then
                printf("respawner [%s]", tostring(v:name()))
                printf("Section [%s] community[%s] rank [%s]", vv.section, tt.community, tt.rank)
            end
        end
    end    
end



function create_ammo(section, position, lvi, gvi, pid, num)
    local ini = system_ini()

    local num_in_box = ini:r_u32(section, "box_size")

    while num > num_in_box do
        alife():create_ammo(section, position, lvi,    gvi, pid, num_in_box)
        num = num - num_in_box
    end
    alife():create_ammo(section, position, lvi,    gvi, pid, num)
end

--' Ключем является группировка персонажа. Значением является таблица, содержашая имена секций предметов.
local item_by_community = {}

--' Зависимости в спауне предметов. Предмет спауниться только если есть хотя бы один из зависимых.
local item_dependence = {}

--' Множители и минимаксы для выпадения вещей в зависимости от уровня
local mul_by_level = {}
local count_by_level = {}

--' Предметы, которые нельзя удалять (квестовые например)
local always_keep_item = {}

--' Предметы, относящиеся к патронам. Их надо спаунить другим методом.
local ammo_sections = {}

local death_ini = ini_file("misc\\death_generic.ltx")


function init_drop_settings()
  local community_list = { "stalker", "dolg", "freedom", "bandit", "military", "zombied", "ecolog", "killer", "monolith", "arena_enemy", "actor_dolg" , "last_day" } 

    for k,v in pairs(community_list) do
        --' Необходимо заполнить таблицу
        item_by_community[v] = {}
        if death_ini:section_exist(v) then
        local n = death_ini:line_count(v)
        local id, value = "", ""
        for i=0,n-1 do
          result, id, value = death_ini:r_line(v,i,"","")
                item_by_community[v][id] = 100*tonumber(value)
        end
        end
    end

    --' Заполняем таблицу зависимостей
  local n = death_ini:line_count("item_dependence")
  local id, value = "", ""
  for i=0,n-1 do
    result, id, value = death_ini:r_line("item_dependence",i,"","")
    item_dependence[id] = {}
    local vvv = parse_names(value)
    for k,v in pairs(vvv) do
      item_dependence[id][v] = true
    end
  end

  --' Множители и минимаксы для выпадения вещей в зависимости от уровня
    local level_name = level.name()
  
  if not death_ini:section_exist(level_name) then
    level_name = "default"
  end

    local n = death_ini:line_count(level_name)
  local id, value = "", ""
  for i=0,n-1 do
    result, id, value = death_ini:r_line(level_name,i,"","")
        mul_by_level[id] = tonumber(value)
  end        

    local item_count_section = "item_count_" .. level.get_game_difficulty()
    local n = death_ini:line_count(item_count_section)
  for i=0,n-1 do
    result, id, value = death_ini:r_line(item_count_section,i,"","")
        --' Нужно распарсить value в два значения
        local t = parse_nums(value)
    if t[1] == nil then
            abort("Error on [death_ini] declaration. Section [%s], line [%s]", item_count_section, tostring(id))
        end
        local min = t[1]
        local max = t[2]
        if max == nil then
            max = min
        end
        
        if mul_by_level[id] == nil then
            mul_by_level[id] = 0
        end

        min = tonumber(min) * mul_by_level[id]
        max = tonumber(max) * mul_by_level[id]

        count_by_level[id] = {min = min, max = max}
  end        

  --' Предметы, которые нельзя удалять (квестовые например)
    local n = death_ini:line_count("keep_items")
  for i=0,n-1 do
    result, id, value = death_ini:r_line("keep_items",i,"","")
        if value == "true" then
            always_keep_item[id] = true
        end
    end

  --' Предметы, относящиеся к патронам. Их надо спаунить другим методом.
    ammo_sections = {}
    local n = death_ini:line_count("ammo_sections")
  local id, value = "", ""
  for i=0,n-1 do
    result, id, value = death_ini:r_line("ammo_sections",i,"","")
        ammo_sections[id] = true
  end        
end



class "drop_manager"
function drop_manager:__init(npc)
  self.npc = npc
end
function drop_manager:create_release_item()
  --' Спрашиваем у серверного объекта генерились ли предметы
  local se_obj = alife():object(self.npc:id())
  if se_obj.death_droped == true then
    return
  end
  se_obj.death_droped = true

    --' Запускаем итератор на удаление предметов
    self.npc:iterate_inventory(keep_item, self.npc)

    --' Проверка на отсутствие спауна лута
    local ini = self.npc:spawn_ini()

    if ini and ini:section_exist("dont_spawn_loot") then
        return
    end

    --' Доспавниваем необходимое количество итемов:
    --' Необходимо составить список объектов которые могут быть заспавнены для персонажа

    local spawn_items = item_by_community[self.npc:character_community()]    
    for k,v in pairs(spawn_items) do
        --' По каждому объекту необходимо получить зависимости    
        if check_item_dependence(self.npc, k) == true then
            --' По каждому объекту необходимо получить количество
            local number = math.ceil(math.random(count_by_level[k].min, count_by_level[k].max))
            --' Необходимо заспавнить нужное количество.
            create_items(self.npc, k, number, v)
        end
    end
end

--' Функция вызывается для каждого предмета, если вернет false то предмет удалится.
function keep_item(npc, item)
    local section = item:section()

    if section == "bolt" then
        return false
    end

    if always_keep_item[section] == true then
        return true
    end

    local item_id = item:id()
    local item_in_slot = npc:item_in_slot(1)
    if item_in_slot ~= nil and
       item_in_slot:id() == item_id
    then
        item:unload_magazine()
    --' Тут надо уменьшить кондишн оружия
        item:set_condition((math.random(15)+75)/100)
        return true
    end
    item_in_slot = npc:item_in_slot(2)
    if item_in_slot ~= nil and
       item_in_slot:id() == item_id
    then
        item:unload_magazine()
    --' Тут надо уменьшить кондишн оружия
        item:set_condition((math.random(15)+75)/100)
        return true
    end
    alife():release(alife():object(item:id()), true)
end

--' Функция спавнит необходимое число предметов
function create_items(npc, section, number, rnd)
    --'printf("create %s of %s", tostring(number), tostring(section))
    if ammo_sections[section] == true then
        if number > 0 then
            se_respawn.create_ammo(section, 
            npc:position(),
            npc:level_vertex_id(),  
            npc:game_vertex_id(),
            npc:id(),
                    number)
        end
    else
        for i=1,number do
      --' Проверяем вероятность появить каждый объект в отдельности
            if math.random(100) <=  rnd then
            alife():create(section, 
            npc:position(),
            npc:level_vertex_id(),  
            npc:game_vertex_id(),
            npc:id())
            end
        end
    end    
end


--' Функция проверяет есть ли хоть один из зависимых объектов у персонажа
function check_item_dependence(npc, section)
  if item_dependence[section] == nil then
    return true
  end

    local d_flag = true
    for k,v in pairs(item_dependence[section]) do
        local obj = npc:object(k)
        if obj ~= nil and npc:marked_dropped(obj) ~= true then
            return true
        end
        d_flag = false
    end

    return d_flag
end

 

Все заменил, потому как у тебя слишком странное расстояние между строками в файле game_relations

Изменено пользователем Вампир35
Ссылка на комментарий

Вампир35, раньше был вылет при начале новой игры, теперь при запуске, появился такой:

Expression    : fatal error
Function      : CScriptEngine::lua_error
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp
Line          : 73
Description   : <no expression>
Arguments     : LUA error: ...shadow of chernobyl2\gamedata\scripts\amk_mod.script:1731: attempt to call field 'reinit_spawner_params' (a nil value)

Пытаюсь в этом файле пытаюсь разобраться, но немогу понять в чём смысл??

Ссылка на комментарий

Starter, конечно можно.

[7]

; cse_abstract properties
section_name = lights_hanging_lamp
name = ds_lights_hanging_lamp
position = 114.868431091309,-3.05655956268311,-30.8430423736572
direction = 0.0329925864934921,3.14159250259399,3.14159250259399
version = 118
script_version = 6

; cse_alife_object properties
game_vertex_id = 2909
distance = 0
level_vertex_id = 1268
object_flags = 0xffffffba

; cse_visual properties
visual_name = physics\light\new_light\light_galogen_1_glass

; cse_ph_skeleton properties

; cse_alife_object_hanging_lamp properties
main_color = 0xffffffff
main_brightness = 1
main_range = 10
light_flags = 0x1f
lamp_fixed_bones = link
health = 100
main_virtual_size = 0.100000001490116
ambient_radius = 10
ambient_power = 0.100000001490116
main_bone = bone_lamp
main_cone_angle = 2.09439516067505
glow_radius = 0.699999988079071

Объясняю

 

Кость, которая зафиксирована, чтоб лампа не упала при выстреле

lamp_fixed_bones = link

 

Кость от которой идет свет

main_bone = bone_lamp

 

Визуал лампы

visual_name = physics\light\new_light\light_galogen_1_glass

 

Координаты и прочее вставишь сам

 

 

 

 

Добавлено через 1 мин.:

Daniar299, это уже с оригиналом несвязано, к сожалению помочь не могу, скорее всего в затронутых мною скриптах было что-то от амк мода, так что перенеси все что я менял в скриптах в амкашные скрипты.

Изменено пользователем Вампир35
Ссылка на комментарий

Перенёс, вроде всё работает всё хорошо! Спс!

 

Добавлено через 10 мин.:

Ещё такой вопрос, как в энциклопедию ПДА добавить информацию про новую группировку?

Ссылка на комментарий

Daniar299,

<article id="social_last_day" name="Army" group="Social">
        <texture x="768" y="128" width="128" height="128">ui\ui_icons_npc</texture>
        <text>enc_social_military_army</text>
</article>

<texture x="768" y="128" width="128" height="128">
здесь указана иконка, по каким она координатам и ее размар.

 

<string id="enc_social_military_army">
        <text>Последний день-это........</text>
</string>

<info_portion id="vidaem_o_last_day">
  <article>social_last_day</article>
</info_portion>

потом выдай в диалоге, или еще где инфопоршень

vidaem_o_last_day

 

 

Ссылка на комментарий
Daniar299, делаешь нужный скрин. Открываешь с помощью программы(я для этих целей использую paint.net) любой файл с иконками нпс, перетаскиваешь скрин туда, подрезаешь, подгоняешь размер, обводишь его инструментом прямоугольное выделение, внизу будут координаты иконки, которые надо перенести в конфиг(справедливо не только для иконок НПС).
Ссылка на комментарий
плащ, ну так в чём проблема?

1. Убери все диалоги и задания. Чтобы убрать задание "Убить стрелка" в файле bind_stalker.script найди и закоментируй вот этот код:

if not has_alife_info("storyline_actor_start") and (level.name() == "l01_escape") then
    self.object:give_info_portion("storyline_actor_start")
    _G.g_start_avi = true
    printf("*AVI* RUN START AVI")            
end

 

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

вставил получилось что-то типо этого


-- if not has_alife_info("storyline_actor_start") and
(level.name() == "l01_escape")
then
self.object:give_info_portion("storyline_actor_start")
_G.g_start_avi = true
printf("*AVI* RUN START AVI")
end

<action>start_soobshenie.ваш текст</action>

 

не работает

Пытаюсь создать глобальный мод с новым сюжетом,буду рад любой оказанной помощи

Ссылка на комментарий

плащ, надо не так, надо так

--[[if not has_alife_info("storyline_actor_start") and (level.name() == "l01_escape") then
    self.object:give_info_portion("storyline_actor_start")
    _G.g_start_avi = true
    printf("*AVI* RUN START AVI")            
end]]
news_manager.send_tip(db.actor, "твой текст сообщения")

Ссылка на комментарий

Вампир35, спасибо но у меня еще вопрос

как вывести его на экран?

Пытаюсь создать глобальный мод с новым сюжетом,буду рад любой оказанной помощи

Ссылка на комментарий
плащ, оно и так выведется, если есть только звук, а тектса нету(только в кпк в истории), такой глюк бывает, пока не нашел как править.
Ссылка на комментарий

Вампир35, хорошо как тогда

привязать к тексту звук (голосовую запись) и поменять картинку (ну типа кто шлет его?)

Пытаюсь создать глобальный мод с новым сюжетом,буду рад любой оказанной помощи

Ссылка на комментарий

Привяать звук+иконку сменить

--[[if not has_alife_info("storyline_actor_start") and (level.name() == "l01_escape") then
    self.object:give_info_portion("storyline_actor_start")
    _G.g_start_avi = true
    printf("*AVI* RUN START AVI")            
end]]
news_manager.send_tip(db.actor, "Твой текст", nil, "pda_icon")
snd_obj = sound_object([[actor\gazmask_idle]])
snd_obj:play(db.actor,0,sound_object.s2d)

pda_icon
список иконок посмотри в news_manager.script, можно добавить свои по аналогии
Ссылка на комментарий

Вампир35, спс, помогло сделал!

 

Добавлено через 6 мин.:

Вот только в энциклопедию закинуть не смог, не робит, ты мог бы написать так же как с группировкой? А что я не понимаю!

Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

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

AMK-Team.ru

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