-------------------------------- ----- Written by Darryl123 ----- -------------------------------- -------------------------- ----- Initialisation ----- -------------------------- -- Delays interaction until the player is loaded. -- This may look pointless, but it prevents articles unlocking "off-screen". local interaction_delay = nil local interaction_enabled = nil function detect_intereaction(typ, obj, name) -- smarts / anomalies / mutants / characters / chraracters_dead / factions / items / artefacts / levels / if name then create_interaction(typ, name) elseif obj then create_interaction(typ, obj:section()) if IsArtefact(obj) then create_interaction("artefacts", obj:section()) elseif IsWeapon(obj) or IsGrenade(obj) then create_interaction("weapons", obj:section()) elseif IsStalker(obj) then detect_intereaction("factions", nil, character_community(obj)) elseif IsMonster(obj) then detect_intereaction("mutants", nil, clsid_monster_to_string(obj)) end end end function create_interaction(key, section) local guide = ui_pda_encyclopedia_tab.get_ui() local interactivity = guide.interactivity or {} if (interaction_enabled and key and section and interactivity[key] and interactivity[key][section]) then for k, v in pairs(interactivity[key][section]) do unlock_article(v) end end end ------------------------------- -- Callbacks ------------------------------- local function actor_on_leave_dialog(id) local character = level.object_by_id(id) detect_intereaction("characters", character) end local function actor_on_item_take(obj) detect_intereaction("items", obj) end local cache_anomaly = {} local anomaly_match = { "zone_field_psychic", "zone_field_radioactive", "zone_burning_fuzz", "zone_field_thermal", "zone_mine_thermal", "zone_zharka_static", "zone_buzz", "zone_mine_chemical", "zone_mine_electric", "zone_witches_galantine", "zone_field_acidic", "zone_mine_acidic", "zone_mine_gravitational_big", "zone_mine_gravitational_strong", "zone_mine_gravitational_average", "zone_mine_gravitational_weak", "fireball_acidic_zone", "fireball_zone", "fireball_electric_zone", "zone_teleport", "lim_space_restrictor_0016" } local function actor_on_feeling_anomaly(obj, flags) if (cache_anomaly[obj:section()]) then return false end -- Article detection cache_anomaly[obj:section()] = true for i=1,#anomaly_match do if string.find(obj:section(),anomaly_match[i]) then detect_intereaction("anomalies", nil, anomaly_match[i]) end end end function actor_on_first_update() interaction_delay = interaction_delay or time_global() + 7500 end -- Checks whether or not interaction can be enabled. local function actor_on_update() if (interaction_delay and interaction_delay <= time_global()) then -- Talking-to or looting a character. RegisterScriptCallback("actor_on_leave_dialog", actor_on_leave_dialog) -- Taking, using or equipping items. RegisterScriptCallback("actor_on_item_take", actor_on_item_take) -- Anomaly articles. RegisterScriptCallback("actor_on_feeling_anomaly", actor_on_feeling_anomaly) -- We don't need these callbacks anymore. UnregisterScriptCallback("actor_on_first_update", actor_on_first_update) -- Enable guide interactivity. interaction_enabled = true -- Unlock articles the player's faction and the current level. local faction = character_community(db.actor):sub(7) detect_intereaction("factions", nil, faction) detect_intereaction("levels", nil, level.name()) db.actor:iterate_inventory( function(temp, obj) detect_intereaction("items", obj) end) interaction_delay = nil end end -- Initialises callbacks for interactivity plugin. function on_game_start() RegisterScriptCallback("actor_on_interaction",detect_intereaction) RegisterScriptCallback("actor_on_first_update", actor_on_first_update) RegisterScriptCallback("actor_on_update", actor_on_update) end ---------------------- ----- Statistics ----- ---------------------- -- Counts how many articles currently exist. function get_articles_count() local guide = ui_pda_encyclopedia_tab.get_ui() return guide.articles_count end -- Counts how many articles are locked. function get_articles_locked_count() local guide = ui_pda_encyclopedia_tab.get_ui() return guide.articles_locked_count end -- Counts how many articles are unlocked. function get_articles_unlocked_count() local guide = ui_pda_encyclopedia_tab.get_ui() return guide.articles_unlocked_count end -------------------------------- ----- Article Manipulation ----- -------------------------------- -- Jumps straight to a specific article. -- Also returns the category and article indices. function set_article(section) -- Instance of the guide object. local guide = ui_pda_encyclopedia_tab.get_ui() -- Return if no section exists. if not (section) then return end -- Discover the category of the article. local article = nil local category = nil for index_c = 1, #guide.categories do category = guide.categories[index_c] -- Determine if the article is in this category. if (category) then for index_a = 1, #category.articles do article = category.articles[index_a] -- Set the category and article if correct. if (article and article == section) then guide:SelectCategory(index_c) guide:SelectArticle(index_a) return index_a, index_c end end end end end -- Unlocks an article for the player. -- A random one will be chosen if none is specified. function unlock_article(section) -- Instance of the guide object. local guide = ui_pda_encyclopedia_tab.get_ui() -- Instance of the locked and unlocked article tables. local locked_articles = guide.locked_articles local unlocked_articles = xr_statistic.actor_articles -- Return if all articles have been unlocked. if (get_articles_locked_count() == 0) then return end -- Return if the specified article is already unlocked or doesn't exist. if (section) then if (unlocked_articles[section]) then return elseif (not locked_articles[section]) then return end -- Should no article be specified select one at random to unlock. else -- Determine the lowest tier of articles to make available. local lowest_tier = guide.highest_tier for k, v in pairs(locked_articles) do lowest_tier = (v > 0 and v < lowest_tier) and v or lowest_tier end -- Sort available articles into tiered and valid tables. local tiered_articles = {} local valid_articles = {} for k, v in pairs(locked_articles) do if (v <= lowest_tier) then if (v > 0) then table.insert(tiered_articles, k) end table.insert(valid_articles, k) end end -- 50% chance of selecting from exclusively tiered articles if available. -- Their information is more useful and important, so is given priority. if (#tiered_articles > 0 and math.random(100) > 50) then section = tiered_articles[math.random(#tiered_articles)] else section = valid_articles[math.random(#valid_articles)] end end -- Update the required tables. locked_articles[section] = nil unlocked_articles[section] = true -- Update the required counters. guide.articles_locked_count = guide.articles_locked_count - 1 guide.articles_unlocked_count = guide.articles_unlocked_count + 1 --xr_statistic.increment_statistic("articles") -- Set the article and retrieve the indices. local index_a, index_c = set_article(section) if not (index_a and index_c) then return end -- Send a message about unlocking the article. if (axr_main.config:r_value("pda_encyclopedia", "display_messages", 1, true)) then -- Article and category texts. local message = game.translate_string("pda_encyclopedia_notify") local text_c = game.translate_string(guide.categories[index_c].section) local text_a = game.translate_string(guide.categories[index_c].articles[index_a]) -- Other information. local header = game.translate_string("st_tip") local texture = news_manager.tips_icons["guide_unlock"] or "ui_inGame2_Poslednie_razrabotki" local sound_obj_tip = sound_object([[device\pda\pda_tip]]) db.actor:give_game_news(header, strformat(message, text_c, text_a), texture, 0, 5000, 0) sound_obj_tip:play(db.actor,0,sound_object.s2d) -- sound_object("device\\pda\\pda_tip"):play(db.actor,0,sound_object.s2d) end end