Added New Mods and Profiles Folders

This is a complete rebuild of the modpack, with all new mods and updates for 1.5.3 of Anomaly.
This commit is contained in:
2025-01-14 05:07:53 -05:00
parent 85c665b107
commit 376b4b9689
21217 changed files with 546254 additions and 0 deletions
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="windows-1251"?>
<string_table>
<string id="pda_games_menu_rogue">
<text>Mini Anomaly</text>
</string>
<string id="pda_rogue_level_str">
<text>Level</text>
</string>
<string id="pda_rogue_withdraw">
<text>Finish and withdraw money (10 to 1)</text>
</string>
<string id="pda_rogue_next_level">
<text>To next level</text>
</string>
<string id="pda_rogue_trade_max_health">
<text>Max health:</text>
</string>
<string id="pda_rogue_trade_range_pwr">
<text>Gun power:</text>
</string>
<string id="pda_rogue_trade_evasion">
<text>Evasion:</text>
</string>
<string id="pda_rogue_trade_buy">
<text>Buy</text>
</string>
<string id="pda_rogue_start_over_text">
<text>Start over</text>
</string>
<string id="pda_rogue_help_text">
<text> - W/A/S/D to move and rotate \n
- Q to wait, R to shoot in direction \n
- To complete the level you have to reach the exit \n
- After every 5 levels you will visit trader and can upgrade some of your attributes for money \n
- Money is earned mainly from getting an artefact, small amount is gained from completing level or killing mutants \n
- Each level will contain 1 artefact, 1 medkit (restores 4 health) and 1 ammo (restores 6 ammo) \n
- Every 10 levels the difficulty will increase, maps will become more narrow, more anomalies and stronger mutants will spawn \n
- Bloodsucker mutant is invisible and appears only when near a few cells from player \n
- Chimera mutant can jump at player if no walls/objects on a way \n
- You can shoot through obstacles that aren't wall, such as water for example (chimera can jump over them too)</text>
</string>
</string_table>
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="windows-1251"?>
<string_table>
<string id="pda_games_menu_rogue">
<text>Мини Аномали</text>
</string>
<string id="pda_rogue_level_str">
<text>Уровень</text>
</string>
<string id="pda_rogue_withdraw">
<text>Закончить и вывести деньги (10 к 1)</text>
</string>
<string id="pda_rogue_next_level">
<text>На след. уровень</text>
</string>
<string id="pda_rogue_trade_max_health">
<text>Макс. здоровье:</text>
</string>
<string id="pda_rogue_trade_range_pwr">
<text>Урон оружия:</text>
</string>
<string id="pda_rogue_trade_evasion">
<text>Уклонение:</text>
</string>
<string id="pda_rogue_trade_buy">
<text>Купить</text>
</string>
<string id="pda_rogue_start_over_text">
<text>Начать заново</text>
</string>
<string id="pda_rogue_help_text">
<text> - W/A/S/D для перемещения и разворота \n
- Q для пропуска хода, R для стрельбы в направлении \n
- Чтобы пройти уровень, вам нужно добраться до выхода \n
- После каждых 5 уровней вы будете посещать торговца и сможете улучшить некоторые свои характеристики за деньги \n
- Деньги зарабатываются в основном за нахождение артефакта, небольшое количество можно получить за прохождение уровня или убийство мутантов \n
- На каждом уровне будет 1 артефакт, 1 аптечка (восстанавливает 4 здоровья) и 1 ящик с патронами (восстанавливает 6 боеприпасов) \n
- Каждые 10 уровней сложность будет увеличиваться, карты будут становиться более узкими, будут появляться больше аномалий и более сильные мутанты \n
- Кровосос невидим и появляется только в нескольких клетках от игрока \n
- Химера может прыгнуть на игрока, если на пути нет стен/объектов \n
- Вы можете стрелять сквозь препятствия, которые не являются стенами, например, через воду (химера тоже может перепрыгивать через них)</text>
</string>
</string_table>
@@ -0,0 +1,232 @@
<w>
<file name = "ui\xcvb_pda\pda_rogue">
<texture id="rogue_cell_texture" x="0" y="0" width="50" height="50"/>
<texture id="rogue_cell_blank" x="50" y="0" width="50" height="50"/>
<texture id="rogue_cell_help_btn_h" x="50" y="50" width="50" height="50" /> <!-- hovered -->
<texture id="rogue_cell_help_btn_t" x="50" y="50" width="50" height="50" /> <!-- pressed -->
<texture id="rogue_cell_help_btn_d" x="0" y="50" width="50" height="50" /> <!-- disabled -->
<texture id="rogue_cell_help_btn_e" x="0" y="50" width="50" height="50" /> <!-- normal -->
</file>
<file name = "ui\xcvb_pda\pda_rogue_trader">
<texture id="rogue_trader_background" x="0" y="0" width="300" height="300"/>
</file>
<file name = "ui\xcvb_pda\pda_rogue_characters">
<texture id="rogue_cell_actor_down" x="0" y="0" width="115" height="115"/>
<texture id="rogue_cell_actor_up" x="115" y="0" width="115" height="115"/>
<texture id="rogue_cell_actor_left" x="230" y="0" width="115" height="115"/>
<texture id="rogue_cell_actor_right" x="345" y="0" width="115" height="115"/>
<texture id="rogue_cell_dog_1_right" x="0" y="115" width="50" height="50"/>
<texture id="rogue_cell_dog_1_left" x="50" y="115" width="50" height="50"/>
<texture id="rogue_cell_dog_2_right" x="100" y="115" width="50" height="50"/>
<texture id="rogue_cell_dog_2_left" x="150" y="115" width="50" height="50"/>
<texture id="rogue_cell_dog_3_right" x="200" y="115" width="50" height="50"/>
<texture id="rogue_cell_dog_3_left" x="250" y="115" width="50" height="50"/>
<texture id="rogue_cell_dog_4_right" x="300" y="115" width="50" height="50"/>
<texture id="rogue_cell_dog_4_left" x="350" y="115" width="50" height="50"/>
<texture id="rogue_cell_bloodsucker_1_right" x="0" y="165" width="50" height="50"/>
<texture id="rogue_cell_bloodsucker_1_left" x="50" y="165" width="50" height="50"/>
<texture id="rogue_cell_chimera_1_right" x="100" y="165" width="50" height="50"/>
<texture id="rogue_cell_chimera_1_left" x="150" y="165" width="50" height="50"/>
<texture id="rogue_cell_boar_1_right" x="200" y="165" width="50" height="50"/>
<texture id="rogue_cell_boar_1_left" x="250" y="165" width="50" height="50"/>
<texture id="rogue_cell_body" x="400" y="115" width="30" height="30"/>
</file>
<file name = "ui\xcvb_pda\pda_rogue_items">
<texture id="rogue_cell_artefact_1" x="0" y="0" width="22" height="22"/>
<texture id="rogue_cell_artefact_2" x="22" y="0" width="22" height="22"/>
<texture id="rogue_cell_artefact_3" x="44" y="0" width="22" height="22"/>
<texture id="rogue_cell_artefact_4" x="66" y="0" width="22" height="22"/>
<texture id="rogue_cell_ammo" x="0" y="22" width="30" height="30"/>
<texture id="rogue_cell_medkit" x="30" y="22" width="30" height="30"/>
<texture id="rogue_cell_exit" x="63" y="23" width="28" height="28"/>
</file>
<file name = "ui\xcvb_pda\pda_rogue_tiles">
<texture id="rogue_cell_dirt_1" x="0" y="0" width="50" height="50"/>
<texture id="rogue_cell_dirt_2" x="50" y="0" width="50" height="50"/>
<texture id="rogue_cell_water_1" x="0" y="260" width="50" height="50"/>
<texture id="rogue_cell_water_2" x="50" y="260" width="50" height="50"/>
<texture id="rogue_cell_water_3" x="100" y="260" width="50" height="50"/>
<texture id="rogue_cell_water_4" x="150" y="260" width="50" height="50"/>
<texture id="rogue_cell_water_5" x="100" y="310" width="50" height="50"/>
<texture id="rogue_cell_water_6" x="150" y="310" width="50" height="50"/>
<texture id="rogue_cell_grass_1" x="200" y="0" width="50" height="50"/>
<texture id="rogue_cell_grass_2" x="250" y="0" width="50" height="50"/>
<texture id="rogue_cell_grass_3" x="300" y="0" width="50" height="50"/>
<texture id="rogue_cell_grass_4" x="250" y="0" width="50" height="50"/>
<texture id="rogue_cell_grass_overlay_1" x="400" y="0" width="50" height="50"/>
<texture id="rogue_cell_grass_overlay_2" x="450" y="50" width="50" height="50"/>
<texture id="rogue_cell_grass_overlay_3" x="400" y="50" width="50" height="50"/>
<texture id="rogue_cell_grass_overlay_4" x="450" y="50" width="50" height="50"/>
<texture id="rogue_cell_tree_1" x="250" y="50" width="50" height="50"/>
<texture id="rogue_cell_tree_2" x="300" y="50" width="50" height="50"/>
<texture id="rogue_cell_tree_3" x="350" y="50" width="50" height="50"/>
<texture id="rogue_cell_swamp_tree_1" x="270" y="230" width="50" height="50"/>
<texture id="rogue_cell_swamp_tree_2" x="320" y="230" width="50" height="50"/>
<texture id="rogue_cell_swamp_tree_3" x="370" y="230" width="50" height="50"/>
<texture id="rogue_cell_swamp_tree_4" x="420" y="230" width="50" height="50"/>
<texture id="rogue_cell_swamp_grass_overlay" x="270" y="280" width="50" height="50"/>
<texture id="rogue_cell_swamp_grass_overlay_l" x="270" y="330" width="50" height="50"/>
<texture id="rogue_cell_swamp_grass_overlay_r" x="320" y="330" width="50" height="50"/>
<texture id="rogue_cell_swamp_grass_overlay_u" x="370" y="330" width="50" height="50"/>
<texture id="rogue_cell_swamp_grass_overlay_d" x="420" y="330" width="50" height="50"/>
<texture id="rogue_cell_red_ground_1" x="0" y="410" width="50" height="50"/>
<texture id="rogue_cell_red_grass_overlay_1" x="100" y="360" width="50" height="50"/>
<texture id="rogue_cell_red_grass_overlay_2" x="150" y="360" width="50" height="50"/>
<texture id="rogue_cell_red_grass_overlay_3" x="100" y="410" width="50" height="50"/>
<texture id="rogue_cell_red_grass_overlay_4" x="150" y="410" width="50" height="50"/>
<texture id="rogue_cell_red_tree_1" x="270" y="430" width="50" height="50"/>
<texture id="rogue_cell_red_tree_2" x="320" y="430" width="50" height="50"/>
<texture id="rogue_cell_red_tree_3" x="370" y="430" width="50" height="50"/>
<texture id="rogue_cell_red_tree_4" x="420" y="430" width="50" height="50"/>
<texture id="rogue_cell_rock_1" x="250" y="100" width="61" height="64"/>
<texture id="rogue_cell_rock_2" x="311" y="100" width="61" height="64"/>
<texture id="rogue_cell_rock_3" x="372" y="100" width="61" height="61"/>
<texture id="rogue_cell_rock_4" x="433" y="100" width="61" height="61"/>
<texture id="rogue_cell_rock_5" x="372" y="161" width="61" height="61"/>
<texture id="rogue_cell_rock_6" x="433" y="161" width="61" height="61"/>
<texture id="rogue_cell_ground2_1" x="101" y="1" width="48" height="48"/>
<texture id="rogue_cell_ground2_2" x="151" y="1" width="48" height="48"/>
<texture id="rogue_cell_wall_left_top" x="0" y="51" width="50" height="50"/>
<texture id="rogue_cell_wall_top" x="50" y="51" width="50" height="50"/>
<texture id="rogue_cell_wall_right_top" x="100" y="51" width="50" height="50"/>
<texture id="rogue_cell_wall_right" x="100" y="101" width="50" height="50"/>
<texture id="rogue_cell_wall_right_bot" x="100" y="151" width="50" height="50"/>
<texture id="rogue_cell_wall_bot" x="50" y="151" width="50" height="50"/>
<texture id="rogue_cell_wall_left_bot" x="0" y="151" width="50" height="50"/>
<texture id="rogue_cell_wall_left" x="0" y="101" width="50" height="50"/>
<texture id="rogue_cell_wire_h" x="151" y="51" width="30" height="30"/>
<texture id="rogue_cell_wire_v" x="181" y="51" width="30" height="30"/>
</file>
<file name = "ui\xcvb_pda\pda_rogue_tiles_shores">
<texture id="rogue_cell_shore_l" x="0" y="0" width="50" height="50"/>
<texture id="rogue_cell_shore_u" x="50" y="0" width="50" height="50"/>
<texture id="rogue_cell_shore_r" x="100" y="0" width="50" height="50"/>
<texture id="rogue_cell_shore_d" x="150" y="0" width="50" height="50"/>
<texture id="rogue_cell_shore_ul" x="0" y="50" width="50" height="50"/>
<texture id="rogue_cell_shore_ur" x="50" y="50" width="50" height="50"/>
<texture id="rogue_cell_shore_rd" x="100" y="50" width="50" height="50"/>
<texture id="rogue_cell_shore_ld" x="150" y="50" width="50" height="50"/>
<texture id="rogue_cell_shore_uld" x="0" y="100" width="50" height="50"/>
<texture id="rogue_cell_shore_ulr" x="50" y="100" width="50" height="50"/>
<texture id="rogue_cell_shore_urd" x="100" y="100" width="50" height="50"/>
<texture id="rogue_cell_shore_lrd" x="150" y="100" width="50" height="50"/>
<texture id="rogue_cell_shore_lr" x="0" y="150" width="50" height="50"/>
<texture id="rogue_cell_shore_ud" x="50" y="150" width="50" height="50"/>
<texture id="rogue_cell_shore_ulrd" x="100" y="150" width="50" height="50"/>
</file>
<file name = "ui\xcvb_pda\pda_rogue_hud">
<texture id="rogue_hud_health" x="0" y="0" width="14" height="12"/>
<texture id="rogue_hud_ammo" x="14" y="0" width="7" height="18"/>
<texture id="rogue_hud_money" x="21" y="0" width="18" height="18"/>
<texture id="rogue_hud_max_health" x="58" y="0" width="12" height="12"/>
<texture id="rogue_hud_range_pwr" x="40" y="1" width="16" height="16"/>
<texture id="rogue_hud_evasion" x="71" y="0" width="12" height="12"/>
<texture id="rogue_hud_upgrade_el" x="30" y="30" width="21" height="54"/>
</file>
<file name = "ui\xcvb_pda\pda_rogue_anomalies">
<texture id="rogue_anomaly_fire_1" x="0" y="0" width="27" height="27"/>
<texture id="rogue_anomaly_fire_2" x="27" y="0" width="27" height="27"/>
<texture id="rogue_anomaly_fire_3" x="54" y="0" width="27" height="27"/>
<texture id="rogue_anomaly_fire_4" x="81" y="0" width="27" height="27"/>
<texture id="rogue_anomaly_electra_1" x="0" y="30" width="65" height="64"/>
<texture id="rogue_anomaly_electra_2" x="65" y="30" width="65" height="64"/>
<texture id="rogue_anomaly_electra_3" x="130" y="30" width="65" height="64"/>
<texture id="rogue_anomaly_electra_4" x="195" y="30" width="65" height="64"/>
<texture id="rogue_anomaly_electra_5" x="260" y="30" width="65" height="64"/>
<texture id="rogue_anomaly_acid_1" x="0" y="150" width="50" height="50"/>
<texture id="rogue_anomaly_acid_2" x="50" y="150" width="50" height="50"/>
<texture id="rogue_anomaly_acid_3" x="100" y="150" width="50" height="50"/>
<texture id="rogue_anomaly_acid_4" x="150" y="150" width="50" height="50"/>
<texture id="rogue_anomaly_acid_5" x="200" y="150" width="50" height="50"/>
<texture id="rogue_anomaly_acid_6" x="250" y="150" width="50" height="50"/>
<texture id="rogue_anomaly_gravi_1" x="0" y="200" width="100" height="100"/>
<texture id="rogue_anomaly_gravi_2" x="100" y="200" width="100" height="100"/>
<texture id="rogue_anomaly_gravi_3" x="200" y="200" width="100" height="100"/>
<texture id="rogue_anomaly_gravi_4" x="0" y="300" width="100" height="100"/>
<texture id="rogue_anomaly_gravi_5" x="100" y="300" width="100" height="100"/>
<texture id="rogue_anomaly_gravi_6" x="200" y="300" width="100" height="100"/>
</file>
<file name = "ui\xcvb_pda\pda_rogue_lab">
<texture id="rogue_cell_lab_ground_1" x="0" y="80" width="128" height="128"/>
<texture id="rogue_cell_lab_ground_2" x="128" y="80" width="128" height="128"/>
<texture id="rogue_cell_lab_misc_ground_1" x="260" y="0" width="100" height="100"/>
<texture id="rogue_cell_lab_misc_ground_2" x="360" y="0" width="100" height="100"/>
<texture id="rogue_cell_lab_misc_ground_3" x="260" y="100" width="100" height="100"/>
<texture id="rogue_cell_lab_misc_ground_4" x="360" y="100" width="100" height="100"/>
<texture id="rogue_cell_lab_wall_l" x="0" y="210" width="32" height="32"/>
<texture id="rogue_cell_lab_wall_u" x="32" y="210" width="32" height="32"/>
<texture id="rogue_cell_lab_wall_r" x="64" y="210" width="32" height="32"/>
<texture id="rogue_cell_lab_wall_d" x="96" y="210" width="32" height="32"/>
<texture id="rogue_cell_lab_misc_wall_1" x="260" y="200" width="80" height="80"/>
<texture id="rogue_cell_lab_misc_wall_2" x="340" y="200" width="80" height="80"/>
<texture id="rogue_cell_lab_misc_wall_3" x="420" y="200" width="80" height="80"/>
<texture id="rogue_cell_lab_misc_wall_4" x="260" y="280" width="80" height="80"/>
<texture id="rogue_cell_lab_misc_wall_5" x="340" y="280" width="80" height="80"/>
<texture id="rogue_cell_lab_misc_wall_6" x="420" y="280" width="80" height="80"/>
<texture id="rogue_cell_lab_wall_ul" x="0" y="242" width="32" height="32"/>
<texture id="rogue_cell_lab_wall_ur" x="32" y="242" width="32" height="32"/>
<texture id="rogue_cell_lab_wall_rd" x="96" y="210" width="32" height="32"/> <!-- 64 242 -->
<texture id="rogue_cell_lab_wall_ld" x="96" y="210" width="32" height="32"/> <!-- 96 242 -->
<texture id="rogue_cell_lab_wall_uld" x="96" y="210" width="32" height="32"/> <!-- 0 274 -->
<texture id="rogue_cell_lab_wall_ulr" x="32" y="274" width="32" height="32"/>
<texture id="rogue_cell_lab_wall_urd" x="96" y="210" width="32" height="32"/> <!-- 64 274 -->
<texture id="rogue_cell_lab_wall_lrd" x="96" y="210" width="32" height="32"/> <!-- 96 274 -->
<texture id="rogue_cell_lab_wall_lr" x="0" y="306" width="32" height="32"/>
<texture id="rogue_cell_lab_wall_ud" x="96" y="210" width="32" height="32"/> <!-- 32 306 -->
<texture id="rogue_cell_lab_wall_ulrd" x="96" y="210" width="32" height="32"/> <!-- 64 306 -->
<texture id="rogue_cell_lab_wall_hzr" x="96" y="306" width="32" height="32"/>
<texture id="rogue_cell_lab_wall_hzl" x="128" y="306" width="32" height="32"/>
</file>
</w>
@@ -0,0 +1 @@
#include "ui\ui_xcvb_pda_16.xml"
@@ -0,0 +1,960 @@
<w>
<!-- Background (obviously) -->
<pda_background x="0" y="0" width="1024" height="768" stretch="1">
<texture>ui_inter_pda_bg</texture>
</pda_background>
<!-- ============================================= -->
<!-- --------------------------- Main menu --------------------------- -->
<!-- ============================================= -->
<left_container x="32" y="55" width="162" height="332" stretch="1">
<!-- Buttons -->
<menu_btn_1 x="0" y="20" width="130" height="35" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_main_menu_raid</text>
<texture>ui_inter_pda_btn</texture>
</menu_btn_1>
<menu_btn_2 x="0" y="60" width="130" height="35" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_main_menu_find</text>
<texture>ui_inter_pda_btn</texture>
</menu_btn_2>
<menu_btn_3 x="0" y="100" width="130" height="35" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_main_menu_games</text>
<texture>ui_inter_pda_btn</texture>
</menu_btn_3>
<menu_btn_4 x="0" y="140" width="130" height="35" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_main_menu_trade</text>
<texture>ui_inter_pda_btn</texture>
</menu_btn_4>
<menu_btn_5 x="0" y="180" width="130" height="35" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_main_menu_notes</text>
<texture>ui_inter_pda_btn</texture>
</menu_btn_5>
<menu_btn_6 x="0" y="220" width="130" height="35" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_banter_main_menu</text>
<texture>ui_inter_pda_btn</texture>
</menu_btn_6>
<menu_btn_7 x="0" y="260" width="130" height="35" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_task_main_menu</text>
<texture>ui_inter_pda_btn</texture>
</menu_btn_7>
<!-- Arrows -->
<arrow_r x="130" y="0" width="35" height="35" stretch="1">
<texture>ui_inter_pda_arrow_right_d</texture>
</arrow_r>
</left_container>
<!-- ============================================= -->
<!-- -------------------------- Menu 1 Raid --------------------------- -->
<!-- ============================================= -->
<mid_container_1 x="222" y="75" width="575" height="300" stretch="1">
<!-- Map Header -->
<map_header x="222" y="0" width="131" height="18">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="letterica18" />
</map_header>
<!-- Level List 1 -->
<list_map x="186" y="40" width="203" height="21" stretch="1" list_length="15">
<list_font r="190" g="190" b="190" font="letterica18"/>
<text_color>
<e r="170" g="170" b="170"/>
<d r="70" g="70" b="70"/>
</text_color>
</list_map>
<!-- Map Image -->
<map_img x="128" y="90" width="320" height="160" stretch="1">
<texture></texture>
</map_img>
<!-- Difficulty -->
<raid_diff x="128" y="270" width="131" height="18">
<text complex_mode="1" r="190" g="190" b="190" align="l" vert_align="c" font="letterica18" />
</raid_diff>
</mid_container_1>
<!-- ============================================= -->
<!-- ------------------------- Menu 2 Buy Info ------------------------ -->
<!-- ============================================= -->
<mid_container_2 x="222" y="75" width="575" height="300" stretch="1">
<!-- ----------------------- Small main menu ---------------------------- -->
<left_btn_list x="10" y="0" width="200" height="300" stretch="1">
<!-- Find Buttons -->
<left_btn_1 x="0" y="0" width="150" height="45" check_mode="0">
<text complex_mode="1" vert_align="c" font="letterica18">pda_find_menu_artefact</text>
<texture>ui_inter_pda_btn</texture>
</left_btn_1>
<left_btn_2 x="0" y="50" width="150" height="45" check_mode="0">
<text complex_mode="1" vert_align="c" font="letterica18">pda_find_menu_mutant</text>
<texture>ui_inter_pda_btn</texture>
</left_btn_2>
<left_btn_3 x="0" y="100" width="150" height="45" check_mode="0">
<text complex_mode="1" vert_align="c" font="letterica18">pda_find_menu_stalker</text>
<texture>ui_inter_pda_btn</texture>
</left_btn_3>
<!-- Arrow -->
<arrow_r x="150" y="0" width="45" height="45" stretch="1">
<texture>ui_inter_pda_arrow_right_d</texture>
</arrow_r>
</left_btn_list>
<!-- ------------------------- Small menu 1 ---------------------------- -->
<right_panel_1 x="230" y="0" width="335" height="300" stretch="1">
<!-- List -->
<artefact_list x="0" y="30" width="203" height="21" stretch="1" list_length="15">
<list_font r="190" g="190" b="190" font="letterica18"/>
<text_color>
<e r="170" g="170" b="170"/>
<d r="70" g="70" b="70"/>
</text_color>
</artefact_list>
<!-- Image -->
<artefact_img x="128" y="90" width="200" height="200" stretch="1">
</artefact_img>
</right_panel_1>
<!-- ------------------------- Small menu 2 ---------------------------- -->
<right_panel_2 x="230" y="0" width="335" height="300" stretch="1">
<!-- List -->
<mutant_list x="0" y="30" width="203" height="21" stretch="1" list_length="15">
<list_font r="190" g="190" b="190" font="letterica18"/>
<text_color>
<e r="170" g="170" b="170"/>
<d r="70" g="70" b="70"/>
</text_color>
</mutant_list>
<!-- Image -->
<mutant_img x="128" y="90" width="200" height="200" stretch="1">
</mutant_img>
</right_panel_2>
<!-- ------------------------- Small menu 3 ---------------------------- -->
<right_panel_3 x="230" y="0" width="335" height="300" stretch="1">
<!-- Input box -->
<stalker_input x="0" y="30" width="250" height="25">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="letterica18" />
<texture>ui_inGame2_edit_box_2</texture>
</stalker_input>
<!-- Accept Button -->
<stalker_btn x="0" y="80" width="75" height="35" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_find_menu_stalker_confirm</text>
<texture>ui_inter_pda_btn</texture>
</stalker_btn>
</right_panel_3>
</mid_container_2>
<!-- ============================================= -->
<!-- -------------------------- Menu 3 Games ------------------------- -->
<!-- ============================================= -->
<mid_container_3 x="222" y="75" width="575" height="300" stretch="1">
<!-- <texture r="0" g="0" b="90" a="255">none.dds</texture> -->
<!-- ----------------------------- Games main menu ----------------------------- -->
<games_btn_list x="10" y="0" width="200" height="300" stretch="1">
<!-- Game Buttons -->
<left_btn_1 x="0" y="0" width="150" height="45" check_mode="0">
<text complex_mode="1" vert_align="c" font="letterica18">pda_games_menu_puzzle</text>
<texture>ui_inter_pda_btn</texture>
</left_btn_1>
<left_btn_2 x="0" y="50" width="150" height="45" check_mode="0">
<text complex_mode="1" vert_align="c" font="letterica18">pda_games_menu_slots</text>
<texture>ui_inter_pda_btn</texture>
</left_btn_2>
<left_btn_3 x="0" y="100" width="150" height="45" check_mode="0">
<text complex_mode="1" vert_align="c" font="letterica18">pda_games_menu_snake</text>
<texture>ui_inter_pda_btn</texture>
</left_btn_3>
<left_btn_4 x="0" y="150" width="150" height="45" check_mode="0">
<text complex_mode="1" vert_align="c" font="letterica18">pda_games_menu_blackjack</text>
<texture>ui_inter_pda_btn</texture>
</left_btn_4>
<left_btn_5 x="0" y="200" width="150" height="45" check_mode="0">
<text complex_mode="1" vert_align="c" font="letterica18">pda_games_menu_sudoku</text>
<texture>ui_inter_pda_btn</texture>
</left_btn_5>
<left_btn_6 x="0" y="250" width="150" height="45" check_mode="0">
<text complex_mode="1" vert_align="c" font="letterica18">pda_games_menu_rogue</text>
<texture>ui_inter_pda_btn</texture>
</left_btn_6>
<!-- Arrow -->
<arrow_r x="150" y="0" width="45" height="45" stretch="1">
<texture>ui_inter_pda_arrow_right_d</texture>
</arrow_r>
</games_btn_list>
<!-- ----------------------------- Game menu 1 ----------------------------- -->
<game_pda_1 complex_mode="1" x="300" y="40" width="335" height="300" align="c" vert_align="c" stretch="1">
<texture r="190" g="190" b="190" a="0">none.dds</texture>
<puzzle_btn_1 x="0" y="0" width="50" height="50" check_mode="0"><texture>ui_puzzle_a1</texture></puzzle_btn_1>
<puzzle_btn_2 x="55" y="0" width="50" height="50" check_mode="0"><texture>ui_puzzle_a2</texture></puzzle_btn_2>
<puzzle_btn_3 x="110" y="0" width="50" height="50" check_mode="0"><texture>ui_puzzle_a3</texture></puzzle_btn_3>
<puzzle_btn_4 x="165" y="0" width="50" height="50" check_mode="0"><texture>ui_puzzle_a4</texture></puzzle_btn_4>
<puzzle_btn_5 x="0" y="55" width="50" height="50" check_mode="0"><texture>ui_puzzle_b1</texture></puzzle_btn_5>
<puzzle_btn_6 x="55" y="55" width="50" height="50" check_mode="0"><texture>ui_puzzle_b2</texture></puzzle_btn_6>
<puzzle_btn_7 x="110" y="55" width="50" height="50" check_mode="0"><texture>ui_puzzle_b3</texture></puzzle_btn_7>
<puzzle_btn_8 x="165" y="55" width="50" height="50" check_mode="0"><texture>ui_puzzle_b4</texture></puzzle_btn_8>
<puzzle_btn_9 x="0" y="110" width="50" height="50" check_mode="0"><texture>ui_puzzle_c1</texture></puzzle_btn_9>
<puzzle_btn_10 x="55" y="110" width="50" height="50" check_mode="0"><texture>ui_puzzle_c2</texture></puzzle_btn_10>
<puzzle_btn_11 x="110" y="110" width="50" height="50" check_mode="0"><texture>ui_puzzle_c3</texture></puzzle_btn_11>
<puzzle_btn_12 x="165" y="110" width="50" height="50" check_mode="0"><texture>ui_puzzle_c4</texture></puzzle_btn_12>
<puzzle_btn_13 x="0" y="165" width="50" height="50" check_mode="0"><texture>ui_puzzle_d1</texture></puzzle_btn_13>
<puzzle_btn_14 x="55" y="165" width="50" height="50" check_mode="0"><texture>ui_puzzle_d2</texture></puzzle_btn_14>
<puzzle_btn_15 x="110" y="165" width="50" height="50" check_mode="0"><texture>ui_puzzle_d3</texture></puzzle_btn_15>
<puzzle_btn_16 x="165" y="165" width="50" height="50" check_mode="0"><texture>ui_puzzle_d4</texture></puzzle_btn_16>
<puzzle_winning_text x="45" y="-35" width="150" height="25" check_mode="0">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="graffiti22">pda_blackjack_won</text>
</puzzle_winning_text>
</game_pda_1>
<!-- ----------------------------- Game menu 2 ----------------------------- -->
<game_pda_2 complex_mode="1" x="250" y="90" width="304" height="200" align="c" vert_align="c" stretch="1">
<texture r="0" g="0" b="190" a="0">none.dds</texture>
<!-- Slots -->
<slot_1 x="30" y="40" width="80" height="100" check_mode="0" stretch="1"><texture>ui_slot_machine_main1</texture></slot_1>
<slot_2 x="112" y="40" width="80" height="100" check_mode="0" stretch="1"><texture>ui_slot_machine_main1</texture></slot_2>
<slot_3 x="194" y="40" width="80" height="100" check_mode="0" stretch="1"><texture>ui_slot_machine_main1</texture></slot_3>
<!-- Descr -->
<slot_descr_coin1 x="0" y="-100" width="60" height="30" check_mode="0">
<text x="55" y="5" complex_mode="1" align="r" vert_align="c" font="graffiti22">x5</text>
<texture>ui_slot_machine_coin</texture>
</slot_descr_coin1>
<slot_descr_coin2 x="0" y="-60" width="92" height="30" check_mode="0">
<text x="55" y="5" complex_mode="1" align="r" vert_align="c" font="graffiti22">x20</text>
<texture>ui_slot_machine_coin2</texture>
</slot_descr_coin2>
<slot_descr_seven x="0" y="-20" width="85" height="27" check_mode="0">
<text x="55" y="5" complex_mode="1" align="r" vert_align="c" font="graffiti22">x100</text>
<texture>ui_slot_machine_seven</texture>
</slot_descr_seven>
<!-- Button -->
<slot_launch x="102" y="160" width="100" height="50" check_mode="0">
<text complex_mode="1" vert_align="c" font="letterica18">pda_games_menu_play</text>
<texture>ui_inter_pda_btn</texture>
</slot_launch>
</game_pda_2>
<!-- ----------------------------- Game menu 3 ----------------------------- -->
<game_pda_3 complex_mode="1" x="300" y="-15" width="220" height="320" align="c" vert_align="c" stretch="1">
<snake_grid x="10" y="10" width="200" height="300" check_mode="0"><texture>ui_snake_grid</texture></snake_grid>
<snake_border x="0" y="0" width="220" height="320" check_mode="0"><texture>ui_snake_border</texture></snake_border>
<snake_block x="50" y="50" width="10" height="10" check_mode="0"><texture>ui_snake_block</texture></snake_block>
<snake_food x="50" y="50" width="10" height="10" check_mode="0"><texture>ui_snake_food</texture></snake_food>
<snake_head x="50" y="50" width="10" height="10" check_mode="0"><texture>ui_snake_head</texture></snake_head>
<snake_score x="-50" y="300" width="30" height="30" check_mode="0">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="graffiti22" />
</snake_score>
<snake_launch_btn x="102" y="160" width="100" height="50">
<text complex_mode="1" vert_align="c" align="c" font="letterica18">pda_games_menu_play</text>
<texture>ui_inter_pda_btn</texture>
</snake_launch_btn>
</game_pda_3>
<!-- ----------------------------- Game menu 4 ----------------------------- -->
<game_pda_4 complex_mode="1" x="220" y="-15" width="370" height="320" align="c" vert_align="c" stretch="1">
<!-- Hands -->
<cards_player_1 x="16" y="200" width="41" height="72" check_mode="0" stretch="1"><texture></texture></cards_player_1>
<cards_player_2 x="72" y="200" width="41" height="72" check_mode="0" stretch="1"><texture></texture></cards_player_2>
<cards_player_3 x="128" y="200" width="41" height="72" check_mode="0" stretch="1"><texture></texture></cards_player_3>
<cards_player_4 x="184" y="200" width="41" height="72" check_mode="0" stretch="1"><texture></texture></cards_player_4>
<cards_player_5 x="240" y="200" width="41" height="72" check_mode="0" stretch="1"><texture></texture></cards_player_5>
<cards_player_6 x="296" y="200" width="41" height="72" check_mode="0" stretch="1"><texture></texture></cards_player_6>
<cards_enemy_1 x="16" y="15" width="41" height="72" check_mode="0" stretch="1"><texture></texture></cards_enemy_1>
<cards_enemy_2 x="72" y="15" width="41" height="72" check_mode="0" stretch="1"><texture></texture></cards_enemy_2>
<cards_enemy_3 x="128" y="15" width="41" height="72" check_mode="0" stretch="1"><texture></texture></cards_enemy_3>
<cards_enemy_4 x="184" y="15" width="41" height="72" check_mode="0" stretch="1"><texture></texture></cards_enemy_4>
<cards_enemy_5 x="240" y="15" width="41" height="72" check_mode="0" stretch="1"><texture></texture></cards_enemy_5>
<cards_enemy_6 x="296" y="15" width="41" height="72" check_mode="0" stretch="1"><texture></texture></cards_enemy_6>
<cards_enemy_fake_1 x="16" y="15" width="41" height="72" check_mode="0" stretch="1"><texture>ui_card_fake</texture></cards_enemy_fake_1>
<cards_enemy_fake_2 x="72" y="15" width="41" height="72" check_mode="0" stretch="1"><texture>ui_card_fake</texture></cards_enemy_fake_2>
<cards_enemy_fake_3 x="128" y="15" width="41" height="72" check_mode="0" stretch="1"><texture>ui_card_fake</texture></cards_enemy_fake_3>
<cards_enemy_fake_4 x="184" y="15" width="41" height="72" check_mode="0" stretch="1"><texture>ui_card_fake</texture></cards_enemy_fake_4>
<cards_enemy_fake_5 x="240" y="15" width="41" height="72" check_mode="0" stretch="1"><texture>ui_card_fake</texture></cards_enemy_fake_5>
<cards_enemy_fake_6 x="296" y="15" width="41" height="72" check_mode="0" stretch="1"><texture>ui_card_fake</texture></cards_enemy_fake_6>
<!-- UI stuff -->
<cards_deck_texture x="310" y="115" width="45" height="72" check_mode="0" stretch="1"><texture>ui_card_deck</texture></cards_deck_texture>
<cards_launch_btn x="135" y="230" width="100" height="50">
<text complex_mode="1" vert_align="c" align="c" font="letterica18">pda_games_menu_play</text>
<texture>ui_inter_pda_btn</texture>
</cards_launch_btn>
<cards_bet_text x="150" y="135" width="30" height="30" check_mode="0">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="graffiti22" />
</cards_bet_text>
<cards_bet_less_btn x="110" y="135" width="35" height="35">
<text complex_mode="1" vert_align="c" align="c" font="letterica18"></text>
<texture>ui_inter_pda_btn</texture>
</cards_bet_less_btn>
<cards_bet_more_btn x="190" y="135" width="35" height="35">
<text complex_mode="1" vert_align="c" align="c" font="letterica18"></text>
<texture>ui_inter_pda_btn</texture>
</cards_bet_more_btn>
<cards_player_score_text x="165" y="285" width="40" height="25" check_mode="0">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="graffiti22" />
</cards_player_score_text>
<cards_enemy_score_text x="-50" y="300" width="30" height="30" check_mode="0">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="graffiti22" />
</cards_enemy_score_text>
<cards_take_btn x="190" y="120" width="50" height="50">
<text complex_mode="1" vert_align="c" align="c" font="letterica18">pda_blackjack_take</text>
<texture>ui_inter_pda_btn</texture>
</cards_take_btn>
<cards_stop_btn x="250" y="120" width="50" height="50">
<text complex_mode="1" vert_align="c" align="c" font="letterica18">pda_blackjack_stop</text>
<texture>ui_inter_pda_btn</texture>
</cards_stop_btn>
<cards_result_text x="25" y="100" width="150" height="150" check_mode="0">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="t" font="graffiti22" />
</cards_result_text>
<cards_ok_btn x="10" y="115" width="40" height="40">
<text complex_mode="1" vert_align="c" align="c" font="letterica18">OK</text>
<texture>ui_inter_pda_btn</texture>
</cards_ok_btn>
</game_pda_4>
<!-- ----------------------------- Game menu 5 ----------------------------- -->
<game_pda_5 complex_mode="1" x="270" y="0" width="370" height="320" align="c" vert_align="c" stretch="1">
<sudoku_cell x="0" y="0" width="30" height="30" check_mode="0" stretch="1">
<texture>sudoku_cell_texture</texture>
<text complex_mode="1" vert_align="c" align="c" font="letterica18"></text>
</sudoku_cell>
<sudoku_v x="0" y="0" width="1" height="30" check_mode="0" stretch="1"><texture>sudoku_line_v</texture></sudoku_v>
<sudoku_h x="0" y="0" width="30" height="1" check_mode="0" stretch="1"><texture>sudoku_line_h</texture></sudoku_h>
<sudoku_winning_text x="60" y="-23" width="150" height="25" check_mode="0">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="graffiti22">pda_blackjack_won</text>
</sudoku_winning_text>
</game_pda_5>
<!-- ----------------------------- Game menu 6 ----------------------------- -->
<game_pda_6 complex_mode="1" x="220" y="0" width="370" height="297" align="c" vert_align="c" stretch="1">
<!-- <texture r="0" g="80" b="0" a="255">none.dds</texture> -->
<!-- rogue game -->
<rogue_game_main x="0" y="0" width="222.75" height="297" check_mode="0" stretch="1">
<rogue_cell x="0" y="0" width="20.25" height="27" check_mode="0" stretch="1">
<!-- <texture>rogue_cell_texture</texture> -->
<texture>rogue_cell_blank</texture>
<text complex_mode="1" vert_align="c" align="c" a="90" font="letterica16"></text>
</rogue_cell>
<rogue_cell2 x="0" y="0" width="20.25" height="27" check_mode="0" stretch="1">
<texture>rogue_cell_blank</texture>
<text complex_mode="1" vert_align="c" align="c" a="90" font="letterica16"></text>
</rogue_cell2>
<rogue_item_cell x="0" y="0" width="20.25" height="27" check_mode="0" stretch="1">
<texture>rogue_cell_blank</texture>
<text complex_mode="1" vert_align="c" align="c" font="letterica16"></text>
</rogue_item_cell>
<rogue_body_cell x="0" y="0" width="20.25" height="27" check_mode="0" stretch="1">
<texture>rogue_cell_blank</texture>
<text complex_mode="1" vert_align="c" align="c" font="letterica16"></text>
</rogue_body_cell>
<rogue_obj_cell x="0" y="0" width="20.25" height="27" check_mode="0" stretch="1">
<texture>rogue_cell_blank</texture>
<text complex_mode="1" vert_align="c" align="c" font="letterica16"></text>
</rogue_obj_cell>
</rogue_game_main>
<!-- rogue trader window -->
<rogue_trader_main x="0" y="0" width="222.75" height="297" check_mode="0" stretch="1">
<texture>rogue_trader_background</texture>
<rogue_trader_upg_cont x="12" y="23" width="200" height="50" check_mode="0" stretch="1">
<icon_title x="4" y="3" width="39" height="14" check_mode="0" stretch="1">
<text complex_mode="1" vert_align="c" align="c" a="180" font="arial_14"></text>
</icon_title>
<icon x="14" y="19" width="18" height="24" check_mode="0" stretch="1">
</icon>
<upgrades x="56" y="14" width="90" height="30" check_mode="0" stretch="1">
<el x="0" y="0" width="25" height="30" check_mode="0" stretch="1">
<texture>rogue_hud_upgrade_el</texture>
</el>
</upgrades>
<cost_title x="159" y="3" width="39" height="14" check_mode="0" stretch="1">
<text complex_mode="1" vert_align="c" align="c" a="180" font="arial_14"></text>
</cost_title>
<buy_btn x="161" y="24" width="35" height="20" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica16">pda_rogue_trade_buy</text>
<texture>ui_inGame2_Mp_bigbuttone</texture>
</buy_btn>
</rogue_trader_upg_cont>
<rogue_withdraw_btn x="10" y="231" width="90" height="50" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="arial_14">pda_rogue_withdraw</text>
<texture>ui_inGame2_Mp_bigbuttone</texture>
</rogue_withdraw_btn>
<rogue_next_level_btn x="123" y="231" width="90" height="50" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica16">pda_rogue_next_level</text>
<texture>ui_inGame2_Mp_bigbuttone</texture>
</rogue_next_level_btn>
</rogue_trader_main>
<!-- rogue HUD -->
<rogue_hud_main x="230" y="33" width="140" height="224" check_mode="0" stretch="1">
<!-- <texture r="0" g="80" b="0" a="90">none.dds</texture> -->
<rogue_hud_level x="0" y="0" width="140" height="45" check_mode="0" stretch="1">
<text complex_mode="1" vert_align="c" align="c" font="letterica18"></text>
</rogue_hud_level>
<rogue_hud_health x="0" y="55" width="140" height="45" check_mode="0" stretch="1">
<health x="0" y="15" width="13" height="15" check_mode="0" stretch="1">
<texture>rogue_hud_health</texture>
</health>
</rogue_hud_health>
<rogue_hud_ammo x="0" y="110" width="140" height="45" check_mode="0" stretch="1">
<ammo x="0" y="13.5" width="5" height="18" check_mode="0" stretch="1">
<texture>rogue_hud_ammo</texture>
</ammo>
</rogue_hud_ammo>
<rogue_hud_money x="0" y="165" width="140" height="45" check_mode="0" stretch="1">
<icon x="0" y="10" width="20" height="25" check_mode="0" stretch="1">
<texture>rogue_hud_money</texture>
</icon>
<value x="30" y="10" width="100" height="25" check_mode="0" stretch="1">
<text complex_mode="1" vert_align="c" align="l" font="letterica18"></text>
</value>
</rogue_hud_money>
</rogue_hud_main>
<!-- start over btn -->
<rogue_start_over_btn x="70" y="250" width="80" height="25" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica16">pda_rogue_start_over_text</text>
<texture>ui_inGame2_Mp_bigbuttone</texture>
</rogue_start_over_btn>
<!-- help -->
<rogue_help_window x="0" y="0" width="370" height="235" check_mode="0" stretch="1">
<texture r="40" g="40" b="40" a="200">none.dds</texture>
<text complex_mode="1" vert_align="c" align="l" font="arial_14">pda_rogue_help_text</text>
</rogue_help_window>
<rogue_help_btn x="340" y="265" width="19" height="25" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica16"></text>
<texture>rogue_cell_help_btn</texture>
</rogue_help_btn>
</game_pda_6>
</mid_container_3>
<rogue_test_grid x="664" y="275" width="360" height="480" check_mode="0" stretch="1">
<texture r="50" g="50" b="50" a="255">none.dds</texture>
<text complex_mode="1" vert_align="c" align="c" a="60" font="letterica25"> T E S T </text>
<rogue_test_cell x="0" y="0" width="12" height="16" check_mode="0" stretch="1">
<texture r="70" g="70" b="70" a="90">rogue_cell_texture</texture>
<text complex_mode="1" vert_align="c" align="c" a="200" font="arial_14"></text>
</rogue_test_cell>
</rogue_test_grid>
<!-- ============================================= -->
<!-- -------------------------- Menu 4 Trade -------------------------- -->
<!-- ============================================= -->
<mid_container_4 x="222" y="75" width="575" height="300" stretch="1">
<!-- Category cont -->
<category_cont x="0" y="0" width="110" height="200">
<category_btn x="0" y="0" width="110" height="20" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica16"></text>
<texture>ui_inter_pda_btn</texture>
</category_btn>
</category_cont>
<!-- Scrollbar -->
<trade_scrollbar x="125" y="0" width="313" height="240" right_ident="0" left_ident="0" top_indent="0" bottom_indent="0" vert_interval="0" always_show_scroll="0" stretch="1"/>
<!-- Scroll cont -->
<trade_scroll_cont x="125" y="0" width="303" height="240" stretch="1"></trade_scroll_cont>
<!-- Item -->
<item_main_cont x="0" y="0" width="67" height="90"> <!-- 50 67 -->
<icon x="0" y="0" width="67" height="60" stretch="1"> <!-- 36 36 -->
<texture>none.dds</texture>
</icon>
<name x="1" y="60" width="65" height="16">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="arial_14"></text>
</name>
<btn x="1" y="76" width="65" height="14" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica16">trade_item_buy</text>
<texture>ui_inter_pda_btn</texture>
</btn>
</item_main_cont>
<!-- Choosen item header -->
<choosen_item_header x="447" y="12" width="116" height="18">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="letterica18">trade_choosen_item_header</text>
</choosen_item_header>
<!-- Choosen item -->
<choosen_item x="447" y="26" width="116" height="36">
<text complex_mode="1" r="230" g="230" b="230" align="c" vert_align="c" font="letterica16"></text>
</choosen_item>
<!-- Quantity header -->
<quantity_item_header x="447" y="84" width="116" height="20">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="letterica18">pda_trade_menu_quantity</text>
</quantity_item_header>
<!-- Quantity input box -->
<quantity_item_input x="447" y="110" width="116" height="25">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="letterica18" />
<texture>ui_inGame2_edit_box_2</texture>
</quantity_item_input>
<!-- Level header -->
<level_item_header x="447" y="152" width="116" height="20">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="letterica18">pda_trade_menu_delivery</text>
</level_item_header>
<!-- Level list -->
<level_item_list x="447" y="174" width="116" height="20" stretch="1" list_length="15">
<list_font r="190" g="190" b="190" font="letterica18"/>
<text_color>
<e r="170" g="170" b="170"/>
<d r="70" g="70" b="70"/>
</text_color>
</level_item_list>
<!-- Level image -->
<level_item_img x="447" y="197" width="116" height="70" stretch="1">
<texture></texture>
</level_item_img>
<!-- Logo -->
<trade_logo x="5" y="262" width="122" height="31" stretch="1">
<texture>ui_inter_pda_omazone</texture>
</trade_logo>
<!-- Tooltip -->
<trade_tooltip x="175" y="250" width="235" height="40" stretch="1">
<text complex_mode="1" r="210" g="210" b="210" align="c" vert_align="c" font="letterica18"></text>
<texture>ui_inter_pda_trade_tooltip</texture>
</trade_tooltip>
</mid_container_4>
<!-- ============================================= -->
<!-- -------------------------- Menu 5 Notes -------------------------- -->
<!-- ============================================= -->
<mid_container_5 x="222" y="75" width="575" height="300" stretch="1">
<texture r="190" g="190" b="190" a="0">none.dds</texture>
<!-- Notes scrollbar -->
<notes_scrollbar x="0" y="0" width="575" height="250" right_ident="0" left_ident="0" top_indent="0" bottom_indent="0" vert_interval="0" always_show_scroll="0" stretch="1"/>
<!-- Notes text window -->
<notes_text_wnd x="0" y="0" width="553" height="600">
<text complex_mode="1" r="190" g="190" b="190" vert_align="t" align="l" font="letterica18"></text>
</notes_text_wnd>
<!-- Notes picker Hint -->
<notes_picker_hint x="375" y="255" width="100" height="20">
<text complex_mode="1" r="190" g="190" b="190" vert_align="c" align="r" font="letterica18">pda_notes_picker_hint</text>
</notes_picker_hint>
<!-- Notes picker input -->
<notes_picker_input x="480" y="255" width="40" height="20">
<text complex_mode="1" r="190" g="190" b="190" vert_align="c" align="c" font="letterica18" />
<texture>ui_inGame2_edit_box_2</texture>
</notes_picker_input>
<notes_edit_btn x="523" y="255" width="29" height="20" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica16">pda_notes_edit_btn</text>
<texture>ui_inter_pda_btn</texture>
</notes_edit_btn>
<notes_delete_btn x="555" y="255" width="19" height="20" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" r="190" g="0" b="0" font="letterica16">pda_notes_delete_btn</text>
<texture>ui_inter_pda_btn</texture>
</notes_delete_btn>
<!-- Notes input box -->
<notes_input_box x="0" y="280" width="525" height="20">
<text complex_mode="1" r="190" g="190" b="190" vert_align="t" align="l" font="letterica18" />
<texture>ui_inGame2_edit_box_2</texture>
</notes_input_box>
<notes_confirm_btn x="530" y="280" width="44" height="20" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica16">pda_notes_add_btn</text>
<texture>ui_inter_pda_btn</texture>
</notes_confirm_btn>
<!-- Tab swap button -->
<notes_switch_btn x="250" y="255" width="100" height="20" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica16"></text>
<texture>ui_inter_pda_btn</texture>
</notes_switch_btn>
<notes_task_text_wnd x="0" y="0" width="480" height="25">
<text complex_mode="1" r="190" g="190" b="190" vert_align="c" align="l" font="letterica16"></text>
</notes_task_text_wnd>
<notes_task_cancel_btn x="500" y="0" width="70" height="25" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="graffiti22">X</text>
<texture>ui_inter_pda_btn</texture>
</notes_task_cancel_btn>
</mid_container_5>
<!-- ============================================= -->
<!-- -------------------------- Menu 6 Banter ------------------------- -->
<!-- ============================================= -->
<mid_container_6 x="222" y="75" width="575" height="300" stretch="1">
<!-- Banter SOS -->
<banter_header_sos x="0" y="-20" width="200" height="20">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="letterica18">pda_banter_sos_header</text>
</banter_header_sos>
<banter_btn_sos x="0" y="5" width="200" height="30" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_banter_sos_confirm</text>
<texture>ui_inter_pda_btn</texture>
</banter_btn_sos>
<!-- Banter Surge -->
<banter_header_surge x="0" y="45" width="200" height="20">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="letterica18">pda_banter_surge_header</text>
</banter_header_surge>
<banter_btn_surge x="0" y="70" width="200" height="30" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_banter_surge_confirm</text>
<texture>ui_inter_pda_btn</texture>
</banter_btn_surge>
<!-- Banter Psi Storm -->
<banter_header_psi x="0" y="110" width="200" height="20">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="letterica18">pda_banter_psi_header</text>
</banter_header_psi>
<banter_btn_psi x="0" y="135" width="200" height="30" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_banter_psi_confirm</text>
<texture>ui_inter_pda_btn</texture>
</banter_btn_psi>
<!-- Banter Status -->
<banter_header_status x="0" y="175" width="200" height="20">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="letterica18">pda_banter_status_header</text>
</banter_header_status>
<banter_btn_status x="0" y="200" width="200" height="30" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_banter_status_confirm</text>
<texture>ui_inter_pda_btn</texture>
</banter_btn_status>
</mid_container_6>
<!-- ============================================= -->
<!-- ------------------------- Menu 7 Tasks --------------------------- -->
<!-- ============================================= -->
<mid_container_7 x="222" y="75" width="575" height="300" stretch="1">
<!-- Mutant Hunt -->
<task_btn_1 x="0" y="0" width="200" height="45" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_task_mutant_hunt_btn</text>
<texture>ui_inter_pda_btn</texture>
</task_btn_1>
<!-- Bounty -->
<task_btn_2 x="0" y="50" width="200" height="45" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_task_bounty_btn</text>
<texture>ui_inter_pda_btn</texture>
</task_btn_2>
<!-- Guide -->
<task_btn_3 x="0" y="100" width="200" height="45" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_task_guide_btn</text>
<texture>ui_inter_pda_btn</texture>
</task_btn_3>
<!-- Fetch items -->
<task_btn_4 x="0" y="150" width="200" height="45" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_task_fetch_items_btn</text>
<texture>ui_inter_pda_btn</texture>
</task_btn_4>
<!-- Dangerous Squad -->
<task_btn_5 x="0" y="200" width="200" height="45" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_task_dangerous_squad_btn</text>
<texture>ui_inter_pda_btn</texture>
</task_btn_5>
<!-- Stealth Task -->
<task_btn_6 x="300" y="0" width="200" height="45" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_task_stealth_btn</text>
<texture>ui_inter_pda_btn</texture>
</task_btn_6>
<!-- Guard task -->
<task_btn_7 x="300" y="50" width="200" height="45" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_task_guard_btn</text>
<texture>ui_inter_pda_btn</texture>
</task_btn_7>
<!-- Scout task -->
<task_btn_8 x="300" y="100" width="200" height="45" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_task_scout_btn</text>
<texture>ui_inter_pda_btn</texture>
</task_btn_8>
<!-- Artefact task -->
<task_btn_9 x="300" y="150" width="200" height="45" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_task_artefact_btn</text>
<texture>ui_inter_pda_btn</texture>
</task_btn_9>
<!-- Delivery task -->
<task_btn_10 x="300" y="200" width="200" height="45" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_task_delivery_btn</text>
<texture>ui_inter_pda_btn</texture>
</task_btn_10>
<!-- Arrow -->
<arrow_r x="502" y="0" width="45" height="45" stretch="1">
<texture>ui_inter_pda_arrow_right_d</texture>
</arrow_r>
</mid_container_7>
<!-- ============================================= -->
<!-- -------------------------- Send button ---------------------------- -->
<!-- ============================================= -->
<send_btn x="860" y="180" width="100" height="35" check_mode="0">
<text font="letterica18">pda_main_menu_send</text>
<texture>ui_inter_pda_btn</texture>
</send_btn>
<!-- ============================================= -->
<!-- --------------------------- Money text ---------------------------- -->
<!-- ============================================= -->
<money_text x="810" y="70" width="200" height="25">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="graffiti22" />
</money_text>
<!-- ============================================= -->
<!-- ------------------------ Active message -------------------------- -->
<!-- ============================================= -->
<active_cont x="30" y="395" width="965" height="65" stretch="1">
<!-- Text -->
<active_cont_text x="0" y="25" width="600" height="18">
<text complex_mode="1" r="190" g="190" b="190" align="c" vert_align="c" font="letterica18" />
</active_cont_text>
<!-- Cancel button -->
<cancel_btn x="830" y="15" width="100" height="35" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18">pda_main_menu_cancel</text>
<texture>ui_inter_pda_btn</texture>
</cancel_btn>
</active_cont>
<!-- ============================================= -->
<!-- ------------------------ Close button -------------------------- -->
<!-- ============================================= -->
<close_btn x="972" y="50" width="25" height="20" check_mode="0">
<text font="letterica16">x</text>
<texture>ui_inter_pda_btn</texture>
</close_btn>
<!-- ============================================= -->
<!-- ------------------------- Bottom menu --------------------------- -->
<!-- ============================================= -->
<bot_cont_main x="30" y="465" width="970" height="260" stretch="1">
<!-- ------------------------- container 1 --------------------------- -->
<bot_cont_1 x="5" y="0" width="150" height="260" stretch="1">
<!-- Icon -->
<bot_icon x="0" y="12" width="110" height="110" stretch="1"></bot_icon>
<!-- Descr -->
<bot_descr x="0" y="134" width="130" height="70">
<text x="10" y="0" complex_mode="1" r="190" g="190" b="190" font="letterica16" />
</bot_descr>
<!-- Button -->
<bot_btn x="0" y="207" width="120" height="40" align="c" vert_align="c" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18"></text>
<texture>ui_inter_pda_btn</texture>
</bot_btn>
</bot_cont_1>
<!-- ------------------------- container 2 --------------------------- -->
<bot_cont_2 x="165" y="0" width="150" height="260" stretch="1">
<!-- Icon -->
<bot_icon x="0" y="12" width="110" height="110" stretch="1"></bot_icon>
<!-- Descr -->
<bot_descr x="0" y="134" width="130" height="70">
<text x="10" y="0" complex_mode="1" r="190" g="190" b="190" font="letterica16" />
</bot_descr>
<!-- Button -->
<bot_btn x="0" y="207" width="120" height="40" align="c" vert_align="c" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18"></text>
<texture>ui_inter_pda_btn</texture>
</bot_btn>
</bot_cont_2>
<!-- ------------------------- container 3 --------------------------- -->
<bot_cont_3 x="325" y="0" width="150" height="260" stretch="1">
<!-- Icon -->
<bot_icon x="0" y="12" width="110" height="110" stretch="1"></bot_icon>
<!-- Descr -->
<bot_descr x="0" y="134" width="130" height="70">
<text x="10" y="0" complex_mode="1" r="190" g="190" b="190" font="letterica16" />
</bot_descr>
<!-- Button -->
<bot_btn x="0" y="207" width="120" height="40" align="c" vert_align="c" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18"></text>
<texture>ui_inter_pda_btn</texture>
</bot_btn>
</bot_cont_3>
<!-- ------------------------- container 4 --------------------------- -->
<bot_cont_4 x="485" y="0" width="150" height="260" stretch="1">
<!-- Icon -->
<bot_icon x="0" y="12" width="110" height="110" stretch="1"></bot_icon>
<!-- Descr -->
<bot_descr x="0" y="134" width="130" height="70">
<text x="10" y="0" complex_mode="1" r="190" g="190" b="190" font="letterica16" />
</bot_descr>
<!-- Button -->
<bot_btn x="0" y="207" width="120" height="40" align="c" vert_align="c" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18"></text>
<texture>ui_inter_pda_btn</texture>
</bot_btn>
</bot_cont_4>
<!-- ------------------------- container 5 --------------------------- -->
<bot_cont_5 x="645" y="0" width="150" height="260" stretch="1">
<!-- Icon -->
<bot_icon x="0" y="12" width="110" height="110" stretch="1"></bot_icon>
<!-- Descr -->
<bot_descr x="0" y="134" width="130" height="70">
<text x="10" y="0" complex_mode="1" r="190" g="190" b="190" font="letterica16" />
</bot_descr>
<!-- Button -->
<bot_btn x="0" y="207" width="120" height="40" align="c" vert_align="c" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18"></text>
<texture>ui_inter_pda_btn</texture>
</bot_btn>
</bot_cont_5>
<!-- ------------------------- container 6 --------------------------- -->
<bot_cont_6 x="805" y="0" width="150" height="260" stretch="1">
<!-- Icon -->
<bot_icon x="0" y="12" width="110" height="110" stretch="1"></bot_icon>
<!-- Descr -->
<bot_descr x="0" y="134" width="130" height="70">
<text x="10" y="0" complex_mode="1" r="190" g="190" b="190" font="letterica16" />
</bot_descr>
<!-- Button -->
<bot_btn x="0" y="207" width="120" height="40" align="c" vert_align="c" check_mode="0">
<text complex_mode="1" align="c" vert_align="c" font="letterica18"></text>
<texture>ui_inter_pda_btn</texture>
</bot_btn>
</bot_cont_6>
</bot_cont_main>
</w>
@@ -0,0 +1,484 @@
local gt = game.translate_string
local CustomPDAX = pda_inter_gui.CustomPDAX
local pr = pda_inter_gui.pr
if pda_inter_gui_c_games and pda_inter_gui_c_games.games_amount then
pda_inter_gui_c_games.games_amount = pda_inter_gui_c_games.games_amount + 1
end
pda_rogue_game = {}
function CustomPDAX:BuildGamesUpperChildRogue(xml) -- xd
local xml = self.xml
self.rogue_launched = false
self.rogue_enable_input = true
self.rogue_debug = false
self.rogue_grid = {}
self.rogue_render = {}
local game_path = "mid_container_3:game_pda_6:"
-- trade
self.rogue_upgrades = {
[1] = { name="max_health", cost={300, 700, 1500}, upg=0, add=2 },
[2] = { name="range_pwr", cost={350, 1000, 2000}, upg=0, add=1 },
[3] = { name="evasion", cost={250, 700, 2000}, upg=0, add=10 },
}
self:RogueBuildTradeMenu(xml, game_path)
-----------------------
-- objects
self.cur_level = 1
self.rogue_objects = {}
------------------------
-- for level generation
self.grid_h = 30
self.grid_w = 30
-----------------------
-- game window
self.rogue_game_main = xml:InitStatic(game_path .. "rogue_game_main", self.games_menu[6].child_menu)
-- create 30x30 grid
for row = 1, self.grid_h do
self.rogue_grid[row] = {}
for col = 1, self.grid_w do
self.rogue_grid[row][col] = {}
self.rogue_grid[row][col].terrain = 0 -- 0 cell, 1 wall, 2 edge
self.rogue_grid[row][col].texture = false
self.rogue_grid[row][col].texture2 = false
end
end
-- create 11x11 renderer xd
local x_offset, y_offset = 20.25, 27
for row = 1, 11 do
self.rogue_render[row] = {}
for col = 1, 11 do
self.rogue_render[row][col] = {}
-- static
self.rogue_render[row][col].cell = xml:InitStatic(game_path .. "rogue_game_main:rogue_cell", self.rogue_game_main)
self.rogue_render[row][col].cell:SetWndPos(vector2():set(x_offset*(col-1), y_offset*(row-1)))
self.rogue_render[row][col].cell2 = xml:InitStatic(game_path .. "rogue_game_main:rogue_cell2", self.rogue_game_main)
self.rogue_render[row][col].cell2:SetWndPos(vector2():set(x_offset*(col-1), y_offset*(row-1)))
-- objects
self.rogue_render[row][col].item = xml:InitStatic(game_path .. "rogue_game_main:rogue_item_cell", self.rogue_game_main)
self.rogue_render[row][col].item:SetWndPos(vector2():set(x_offset*(col-1), y_offset*(row-1)))
self.rogue_render[row][col].body = xml:InitStatic(game_path .. "rogue_game_main:rogue_body_cell", self.rogue_game_main)
self.rogue_render[row][col].body:SetWndPos(vector2():set(x_offset*(col-1), y_offset*(row-1)))
self.rogue_render[row][col].obj = xml:InitStatic(game_path .. "rogue_game_main:rogue_obj_cell", self.rogue_game_main)
self.rogue_render[row][col].obj:SetWndPos(vector2():set(x_offset*(col-1), y_offset*(row-1)))
end
end
-- HUD
self:RogueBuildHUD(xml, game_path)
-- start over btn
self.rogue_start_over_btn = xml:Init3tButton(game_path .. "rogue_start_over_btn", self.games_menu[6].child_menu)
self:Register(self.rogue_start_over_btn, "rogue_start_over")
self.rogue_start_over_btn:Show(false)
-- help window
self.rogue_help_window = xml:InitStatic(game_path .. "rogue_help_window", self.games_menu[6].child_menu)
self.rogue_help_window:Show(false)
self.rogue_help_btn = xml:Init3tButton(game_path .. "rogue_help_btn", self.games_menu[6].child_menu)
self:Register(self.rogue_help_btn, "rogue_help")
-- TEST DISPLAY GRID
self:BuildTestDisplayGrid(xml)
----------------------------
-- launch on first open
self:RogueGenerateNewLevel()
end
function CustomPDAX:RogueBuildTradeMenu(xml, game_path)
self.rogue_trader_main = xml:InitStatic(game_path .. "rogue_trader_main", self.games_menu[6].child_menu)
self.rogue_trader_main:Show(false)
self.rogue_trade_ar = {}
for i, t in ipairs(self.rogue_upgrades) do
self.rogue_trade_ar[i] = {}
self.rogue_trade_ar[i].main = xml:InitStatic(game_path .. "rogue_trader_main:rogue_trader_upg_cont", self.rogue_trader_main)
local pos, h = self.rogue_trade_ar[i].main:GetWndPos(), self.rogue_trade_ar[i].main:GetHeight()
local new_pos_y = (i == 1 and pos.y) or ( pos.y + (h + 15) * (i-1) )
self.rogue_trade_ar[i].main:SetWndPos(vector2():set( pos.x, new_pos_y ))
self.rogue_trade_ar[i].icon_title = xml:InitStatic(game_path .. "rogue_trader_main:rogue_trader_upg_cont:icon_title", self.rogue_trade_ar[i].main)
self.rogue_trade_ar[i].icon = xml:InitStatic(game_path .. "rogue_trader_main:rogue_trader_upg_cont:icon", self.rogue_trade_ar[i].main)
self.rogue_trade_ar[i].icon:InitTexture( "rogue_hud_" .. t.name )
self.rogue_trade_ar[i].cost_title = xml:InitStatic(game_path .. "rogue_trader_main:rogue_trader_upg_cont:cost_title", self.rogue_trade_ar[i].main)
self.rogue_trade_ar[i].buy_btn = xml:Init3tButton(game_path .. "rogue_trader_main:rogue_trader_upg_cont:buy_btn", self.rogue_trade_ar[i].main)
self:Register(self.rogue_trade_ar[i].buy_btn, "rogue_buy_" .. t.name)
self.rogue_trade_ar[i].upgrades = xml:InitStatic(game_path .. "rogue_trader_main:rogue_trader_upg_cont:upgrades", self.rogue_trade_ar[i].main)
self.rogue_trade_ar[i].els = {}
for j = 1, #self.rogue_upgrades[i].cost do
self.rogue_trade_ar[i].els[j] = xml:InitStatic(game_path .. "rogue_trader_main:rogue_trader_upg_cont:upgrades:el", self.rogue_trade_ar[i].upgrades)
self.rogue_trade_ar[i].els[j]:SetWndPos(vector2():set( (25+5)*(j-1), 0 ))
end
end
self.rogue_trader_withdraw_btn = xml:Init3tButton(game_path .. "rogue_trader_main:rogue_withdraw_btn", self.rogue_trader_main)
self:Register(self.rogue_trader_withdraw_btn, "rogue_finish_withdraw")
self.rogue_trader_next_level_btn = xml:Init3tButton(game_path .. "rogue_trader_main:rogue_next_level_btn", self.rogue_trader_main)
self:Register(self.rogue_trader_next_level_btn, "rogue_next_level")
end
function CustomPDAX:InitRogueCallbacks()
self:AddCallback("rogue_buy_max_health", ui_events.BUTTON_CLICKED, self.OnClickRogueBuyHealth, self)
self:AddCallback("rogue_buy_range_pwr", ui_events.BUTTON_CLICKED, self.OnClickRogueBuyPower, self)
self:AddCallback("rogue_buy_evasion", ui_events.BUTTON_CLICKED, self.OnClickRogueBuyEvasion, self)
self:AddCallback("rogue_finish_withdraw", ui_events.BUTTON_CLICKED, self.OnClickRogueFinish, self)
self:AddCallback("rogue_next_level", ui_events.BUTTON_CLICKED, self.OnClickRogueNextLevel, self)
self:AddCallback("rogue_start_over", ui_events.BUTTON_CLICKED, self.OnClickRogueStartOver, self)
self:AddCallback("rogue_help", ui_events.BUTTON_CLICKED, self.OnClickRogueHelp, self)
end
function CustomPDAX:RogueBuildHUD(xml, game_path)
self.rogue_hud_main = xml:InitStatic(game_path .. "rogue_hud_main", self.games_menu[6].child_menu)
self.rogue_hud_level = xml:InitStatic(game_path .. "rogue_hud_main:rogue_hud_level", self.rogue_hud_main)
self.rogue_hud_health = xml:InitStatic(game_path .. "rogue_hud_main:rogue_hud_health", self.rogue_hud_main)
self.rogue_hud_health_ar = {}
for i = 1, 10 do
self.rogue_hud_health_ar[i] = xml:InitStatic(game_path .. "rogue_hud_main:rogue_hud_health:health", self.rogue_hud_health)
self.rogue_hud_health_ar[i]:SetWndPos(vector2():set( 13*(i-1), 15 ))
end
self.rogue_hud_ammo = xml:InitStatic(game_path .. "rogue_hud_main:rogue_hud_ammo", self.rogue_hud_main)
self.rogue_hud_ammo_ar = {}
for i = 1, 20 do
self.rogue_hud_ammo_ar[i] = xml:InitStatic(game_path .. "rogue_hud_main:rogue_hud_ammo:ammo", self.rogue_hud_ammo)
self.rogue_hud_ammo_ar[i]:SetWndPos(vector2():set( (5+2)*(i-1), 13.5 ))
end
self.rogue_hud_money = xml:InitStatic(game_path .. "rogue_hud_main:rogue_hud_money", self.rogue_hud_main)
self.rogue_hud_money_icon = xml:InitStatic(game_path .. "rogue_hud_main:rogue_hud_money:icon", self.rogue_hud_money)
self.rogue_hud_money_text = xml:InitStatic(game_path .. "rogue_hud_main:rogue_hud_money:value", self.rogue_hud_money)
end
function CustomPDAX:OnClickRogueStartOver()
self.rogue_start_over_btn:Show(false)
self.rogue_enable_input = true
self:RogueGenerateNewLevel()
end
function CustomPDAX:RogueGenerateNewLevel(win, debug_set_level)
-- reset grid
self:RogueResetGrid()
-- reset upgrades if not win
if not win then
for i, t in ipairs(self.rogue_upgrades) do
t.upg = 0
end
end
-- new level sound
if win then
self:PlaySound("rogue_new_level")
end
-- set level
self.cur_level = (debug_set_level) or (win and self.cur_level + 1) or 1
-- reset and generate level
self:RogueGenerateWorld()
-- reset and generate objects
self:RogueGenerateObjects(win)
-- Grid and Render updates
self:RogueGridUpdate(true)
end
function CustomPDAX:RogueResetGrid()
for row = 1, #self.rogue_grid do
for col = 1, #self.rogue_grid[row] do
self.rogue_grid[row][col].terrain = 0
self.rogue_grid[row][col].texture = false
self.rogue_grid[row][col].texture2 = false
----- test -------
if self.rogue_debug then
self.rogue_grid[row][col].test_cell:InitTexture("rogue_cell_texture")
self.rogue_grid[row][col].test_cell:SetTextureColor( GetARGB(255, 70, 70, 70) )
end
------------------
end
end
end
function CustomPDAX:RogueGridUpdate(start)
-- update mutants
if not start then
self:MutantsUpdate()
self:AnomaliesUpdate()
end
-- update render
self:RenderUpdate()
-- hud update
self:RogueHUDUpdate()
-- still test
self:TESTTerrainDisplay()
-- self:TESTDisplaySpawnRadius("gulag")
self:TESTObjectsDisplay()
------------------
end
function CustomPDAX:RogueHUDUpdate()
self.rogue_hud_level:TextControl():SetText(gt("pda_rogue_level_str") .. ": " .. tostring(self.cur_level) )
for i = 1, 10 do
local show_cond = i <= self:RogueActor().health
self.rogue_hud_health_ar[i]:Show(show_cond)
end
for i = 1, 20 do
local show_cond = i <= self:RogueActor().ammo
self.rogue_hud_ammo_ar[i]:Show(show_cond)
end
self.rogue_hud_money_text:TextControl():SetText(" " .. tostring(self:RogueActor().money) .. " $")
end
function CustomPDAX:RenderUpdate()
-- reset all render cells
for row = 1, #self.rogue_render do
for col = 1, #self.rogue_render[row] do
self.rogue_render[row][col].cell:InitTexture("rogue_cell_blank")
self.rogue_render[row][col].cell2:InitTexture("rogue_cell_blank")
self.rogue_render[row][col].item:InitTexture("rogue_cell_blank")
self.rogue_render[row][col].body:InitTexture("rogue_cell_blank")
self.rogue_render[row][col].obj:InitTexture("rogue_cell_blank")
end
end
-- update render
local cur_grid_row = self:RogueActor().row - (#self.rogue_render - 1) / 2
local cur_grid_col = self:RogueActor().col - (#self.rogue_render - 1) / 2
for row = 1, #self.rogue_render do
cur_grid_col = self:RogueActor().col - (#self.rogue_render - 1) / 2
for col = 1, #self.rogue_render[row] do
if self.rogue_grid[cur_grid_row] and self.rogue_grid[cur_grid_row][cur_grid_col] then
-- draw terrain
local cell_texture = self.rogue_grid[cur_grid_row][cur_grid_col].texture or "rogue_cell_blank"
self.rogue_render[row][col].cell:InitTexture(cell_texture)
local cell_texture2 = self.rogue_grid[cur_grid_row][cur_grid_col].texture2 or "rogue_cell_blank"
self.rogue_render[row][col].cell2:InitTexture(cell_texture2)
-- draw objects
for idx, t in pairs(self.rogue_objects) do
if t.row == cur_grid_row and t.col == cur_grid_col then
-- actor / mutant
if t.typ == "actor" or t.typ == "mutant" then
if t.status == "alive" then
-- bloodsucker special case
if not t.invis then
self.rogue_render[row][col].obj:InitTexture(t.texture .. t.dir)
end
else
self.rogue_render[row][col].body:InitTexture("rogue_cell_body")
end
end
-- exit / items
if t.typ == "exit" or t.status == "world" then
self.rogue_render[row][col].item:InitTexture(t.texture)
end
-- anomalies
if t.typ == "anomaly" then
self.rogue_render[row][col].item:InitTexture(t.texture .. t.anm)
self.rogue_objects[idx].anm = self.rogue_objects[idx].anm + 1
if self.rogue_objects[idx].anm > t.max_anm then
self.rogue_objects[idx].anm = 1
end
end
end
end
end
cur_grid_col = cur_grid_col + 1
end
cur_grid_row = cur_grid_row + 1
end
end
------------------------------------------------------------
-------------------------- Trade ---------------------------
function CustomPDAX:RogueTradeUpdate()
local ac = self:RogueActor()
if not ac then return end
self.rogue_trader_main:Show(true)
self.rogue_game_main:Show(false)
for i, t in ipairs(self.rogue_upgrades) do
local evasion_str = t.name == "evasion" and "%" or ""
self.rogue_trade_ar[i].icon_title:TextControl():SetText( gt("pda_rogue_trade_" .. t.name) .. " " .. ac[t.name] .. evasion_str)
local cost_str = t.cost[t.upg + 1] and (tostring(t.cost[t.upg + 1]) .. " $") or ""
self.rogue_trade_ar[i].cost_title:TextControl():SetText(cost_str)
local btn_cond = t.upg < #t.cost and ac.money >= t.cost[t.upg + 1]
self.rogue_trade_ar[i].buy_btn:Enable(btn_cond)
for j = 1, #t.cost do
local upg_cond = j <= t.upg
self.rogue_trade_ar[i].els[j]:Show(upg_cond)
end
end
end
function CustomPDAX:OnClickRogueBuyHealth()
local ac = self:RogueActor()
for i, t in ipairs(self.rogue_upgrades) do
if t.name == "max_health" then
ac.money = ac.money - t.cost[t.upg + 1]
ac.max_health = ac.max_health + t.add
ac.health = ac.max_health
self.rogue_upgrades[i].upg = self.rogue_upgrades[i].upg + 1
end
end
self:PlaySound("rogue_pda_beep")
self:RogueHUDUpdate()
self:RogueTradeUpdate()
end
function CustomPDAX:OnClickRogueBuyPower()
local ac = self:RogueActor()
for i, t in ipairs(self.rogue_upgrades) do
if t.name == "range_pwr" then
ac.money = ac.money - t.cost[t.upg + 1]
ac.range_pwr = ac.range_pwr + t.add
self.rogue_upgrades[i].upg = self.rogue_upgrades[i].upg + 1
end
end
self:PlaySound("rogue_pda_beep")
self:RogueHUDUpdate()
self:RogueTradeUpdate()
end
function CustomPDAX:OnClickRogueBuyEvasion()
local ac = self:RogueActor()
for i, t in ipairs(self.rogue_upgrades) do
if t.name == "evasion" then
ac.money = ac.money - t.cost[t.upg + 1]
ac.evasion = ac.evasion + t.add
self.rogue_upgrades[i].upg = self.rogue_upgrades[i].upg + 1
end
end
self:PlaySound("rogue_pda_beep")
self:RogueHUDUpdate()
self:RogueTradeUpdate()
end
function CustomPDAX:OnClickRogueFinish()
local money = math.ceil(self:RogueActor().money / 10)
db.actor:give_money(money)
self:UpdMoneyText()
self:PlaySound("rogue_pda_beep")
self.rogue_enable_input = true
self.rogue_trader_main:Show(false)
self.rogue_game_main:Show(true)
self:RogueGenerateNewLevel()
end
function CustomPDAX:OnClickRogueNextLevel()
self.rogue_enable_input = true
self.rogue_trader_main:Show(false)
self.rogue_game_main:Show(true)
self:RogueGenerateNewLevel(true)
end
function CustomPDAX:OnClickRogueHelp()
local help_show_cond = not self.rogue_help_window:IsShown()
self.rogue_help_window:Show(help_show_cond)
end
------------------------------------------------------------
------------------------------------------------------------
function CustomPDAX:ResetGamesRogue()
self.rogue_launched = false
self:AllowMovement(true)
end
function CustomPDAX:RogueActorAction(key)
if not self.rogue_enable_input then
return
end
-- test
if key == DIK_keys.DIK_M then
self:UpdateTestGrid(true)
end
if key == DIK_keys.DIK_W then
self:MoveActor("up")
elseif key == DIK_keys.DIK_S then
self:MoveActor("down")
elseif key == DIK_keys.DIK_A then
self:MoveActor("left")
elseif key == DIK_keys.DIK_D then
self:MoveActor("right")
elseif key == DIK_keys.DIK_Q then
self:WaitActor()
elseif key == DIK_keys.DIK_R then
self:ShootActor()
end
end
function on_option_change()
end
function save_state(m_data)
m_data.pda_rogue_game = pda_rogue_game
end
function load_state(m_data)
pda_rogue_game = m_data.pda_rogue_game or {}
end
function on_game_start()
RegisterScriptCallback("on_option_change", on_option_change)
RegisterScriptCallback("save_state", save_state)
RegisterScriptCallback("load_state", load_state)
end
@@ -0,0 +1,171 @@
--[[
Lua star example - Run with love (https://love2d.org/)
Copyright 2018 Wesley Werner <wesley.werner@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
References:
https://en.wikipedia.org/wiki/A*_search_algorithm
https://www.redblobgames.com/pathfinding/a-star/introduction.html
https://www.raywenderlich.com/4946/introduction-to-a-pathfinding
]]--
--- Provides easy A* path finding.
-- (Internal) Return the distance between two points.
-- This method doesn't bother getting the square root of s, it is faster
-- and it still works for our use.
local function distance(x1, y1, x2, y2)
local dx = x1 - x2
local dy = y1 - y2
local s = dx * dx + dy * dy
return s
end
-- (Internal) Return the score of a node.
-- G is the cost from START to this node.
-- H is a heuristic cost, in this case the distance from this node to the goal.
-- Returns F, the sum of G and H.
local function calculateScore(previous, node, goal)
local G = previous.score + 1
local H = distance(node.x, node.y, goal.x, goal.y)
return G + H, G, H
end
-- (Internal) Returns true if the given list contains the specified item.
local function listContains(list, item)
for _, test in ipairs(list) do
if test.x == item.x and test.y == item.y then
return true
end
end
return false
end
-- (Internal) Returns the item in the given list.
local function listItem(list, item)
for _, test in ipairs(list) do
if test.x == item.x and test.y == item.y then
return test
end
end
end
-- (Internal) Requests adjacent map values around the given node.
local function getAdjacent(width, height, node, positionIsOpenFunc, self, start, goal, idx, victim_idx)
local result = { }
local positions = {
{ x = 0, y = -1 }, -- top
{ x = -1, y = 0 }, -- left
{ x = 0, y = 1 }, -- bottom
{ x = 1, y = 0 }, -- right
}
for _, point in ipairs(positions) do
local px = clamp(node.x + point.x, 1, width)
local py = clamp(node.y + point.y, 1, height)
local value = positionIsOpenFunc( self, px, py, start, goal, idx, victim_idx )
if value then
table.insert( result, { x = px, y = py } )
end
end
return result
end
-- Returns the path from start to goal, or false if no path exists.
function astar_find(width, height, start, goal, positionIsOpenFunc, self, idx, victim_idx)
local success = false
local open = { }
local closed = { }
start.score = 0
start.G = 0
start.H = distance(start.x, start.y, goal.x, goal.y)
start.parent = { x = 0, y = 0 }
table.insert(open, start)
while not success and #open > 0 do
-- sort by score: high to low
table.sort(open, function(a, b) return a.score > b.score end)
local current = table.remove(open)
table.insert(closed, current)
success = listContains(closed, goal)
if not success then
local adjacentList = getAdjacent(width, height, current, positionIsOpenFunc, self, start, goal, idx, victim_idx)
for _, adjacent in ipairs(adjacentList) do
if not listContains(closed, adjacent) then
if not listContains(open, adjacent) then
adjacent.score = calculateScore(current, adjacent, goal)
adjacent.parent = current
table.insert(open, adjacent)
end
end
end
end
end
if not success then
return false
end
-- traverse the parents from the last point to get the path
local node = listItem(closed, closed[#closed])
local path = { }
while node do
table.insert(path, 1, { x = node.x, y = node.y } )
node = listItem(closed, node.parent)
end
-- reverse the closed list to get the solution
return path
end
function AStarCanMove(self, row, col, start, goal, idx, victim_idx)
-- terrain check
local terrain = self.rogue_grid[row] and self.rogue_grid[row][col] and self.rogue_grid[row][col].terrain == 0
if not terrain then
return
end
-- disallow storing cell if theres another alive object and its not victim
for i, t in pairs(self.rogue_objects) do
local alive_not_victim = i ~= victim_idx and t.status == "alive"
local same_pos = row == t.row and col == t.col
if alive_not_victim and same_pos then
return
end
end
return true
end
function AStarCanMoveToExit(self, row, col, start, goal)
-- terrain check only
if self.rogue_grid[row] and self.rogue_grid[row][col] and self.rogue_grid[row][col].terrain == 0 then
return true
end
end
@@ -0,0 +1,590 @@
local CustomPDAX = pda_inter_gui.CustomPDAX
local pr = pda_inter_gui.pr
function CustomPDAX:RogueGenerateWorld()
local lvl = self.cur_level
if lvl >= 1 and lvl <= 10 then
self:RogueGenerateWildWorld(20)
self:RogueSetDarkscapeCellTextures()
elseif lvl >= 11 and lvl <= 20 then
self:RogueGenerateWildWorld(30)
self:RogueSetSwampCellTextures()
elseif lvl >= 21 and lvl <= 30 then
self:RogueGenerateWildWorld(40)
self:RogueSetRedForestCellTextures()
elseif lvl >= 31 then
self:RogueGenerateLabWorld()
self:RogueSetLabCellTextures()
end
end
function CustomPDAX:RogueGenerateWildWorld(wall_percents)
local walls_map = {}
-- repeat wilderness world and flood fill check until cell ratio is more than 70%
repeat
empty_table(walls_map)
walls_map, start_cells = self:LevelWildGenerate(self.grid_w, self.grid_h, wall_percents)
local flood_fill = self:LevelFloodFill(walls_map, start_cells)
until flood_fill > 0.7
-- set main grid, flag < 2 are walls
for row = 1, #walls_map do
for col = 1, #walls_map[row] do
local val = walls_map[row][col]
if val < 2 then
self.rogue_grid[row][col].terrain = 1
end
end
end
end
function CustomPDAX:RogueGenerateLabWorld()
for row = 1, #self.rogue_grid do
for col = 1, #self.rogue_grid[row] do
self.rogue_grid[row][col].terrain = 1
end
end
self:LevelLabGenerate(self.grid_w, self.grid_h, 1)
-- edges just in case
for row = 1, #self.rogue_grid do
for col = 1, #self.rogue_grid[row] do
if row == 1 or col == 1 or row == #self.rogue_grid or col == #self.rogue_grid[row] then
self.rogue_grid[row][col].terrain = 1
end
end
end
end
------------------------------------------------------------------------------------------------------------------------
----------------------------------------------- Level Textures and misc -----------------------------------------------
------------------------------------------------------------------------------------------------------------------------
function CustomPDAX:RogueSetDarkscapeCellTextures()
local txtr = "rogue_cell_"
for row = 1, #self.rogue_grid do
for col = 1, #self.rogue_grid[row] do
local terrain = self.rogue_grid[row][col].terrain
-- ground
if terrain == 0 or terrain == 1 then
self.rogue_grid[row][col].texture = txtr .. "grass_1"
end
-- grass
if terrain == 0 and math.random() > 0.75 then
self.rogue_grid[row][col].texture2 = txtr .. "grass_overlay_" .. math.random(4)
end
-- obstacles
if terrain == 1 then
local pick = math.random() > 0.3 and ("tree_" .. math.random(3)) or ("rock_" .. math.random(6))
self.rogue_grid[row][col].texture2 = txtr .. pick
end
end
end
end
function CustomPDAX:RogueSetSwampCellTextures()
local txtr = "rogue_cell_"
for row = 1, #self.rogue_grid do
for col = 1, #self.rogue_grid[row] do
local terrain = self.rogue_grid[row][col].terrain
-- ground
if terrain == 0 or terrain == 1 then
self.rogue_grid[row][col].texture = txtr .. "dirt_" .. math.random(1, 2)
end
-- water / obstacles
if terrain == 1 then
if math.random() > 0.2 then
self.rogue_grid[row][col].terrain = 2
self.rogue_grid[row][col].texture = txtr .. "water_6"
else
local pick = math.random() > 0.3 and ("rock_" .. math.random(6)) or ("swamp_tree_" .. math.random(4))
self.rogue_grid[row][col].texture2 = txtr .. pick
end
end
end
end
local function try_to_spawn_grass(cl, pos)
if cl.terrain == 0 and math.random() > 0.75 then
local pos_str = pos and "_" .. pos or ""
cl.texture2 = txtr .. "swamp_grass_overlay" .. pos_str
end
end
-- shores / grass overlay
for row = 1, #self.rogue_grid do
for col = 1, #self.rogue_grid[row] do
local cell = self.rogue_grid[row][col]
if cell.terrain == 2 then
local adj_str = ""
-- check adj
for i = row - 1, row + 1 do
for j = col - 1, col + 1 do
local adj_cel = self.rogue_grid[i] and self.rogue_grid[i][j]
if adj_cel and string.find(adj_cel.texture, "dirt") then
-- up
if i == row-1 and j == col then
adj_str = adj_str .. "u"
try_to_spawn_grass(adj_cel, "d")
-- down
elseif i == row+1 and j == col then
adj_str = adj_str .. "d"
try_to_spawn_grass(adj_cel, "u")
-- left
elseif i == row and j == col-1 then
adj_str = adj_str .. "l"
try_to_spawn_grass(adj_cel, "r")
-- right
elseif i == row and j == col+1 then
adj_str = adj_str .. "r"
try_to_spawn_grass(adj_cel, "l")
end
end
end
end
if adj_str ~= "" then
self.rogue_grid[row][col].texture2 = txtr .. "shore_" .. adj_str
end
end
end
end
end
function CustomPDAX:RogueSetRedForestCellTextures()
local txtr = "rogue_cell_"
for row = 1, #self.rogue_grid do
for col = 1, #self.rogue_grid[row] do
local terrain = self.rogue_grid[row][col].terrain
-- ground
if terrain == 0 or terrain == 1 then
self.rogue_grid[row][col].texture = txtr .. "red_ground_1"
end
-- grass
if terrain == 0 and math.random() > 0.5 then
self.rogue_grid[row][col].texture2 = txtr .. "red_grass_overlay_" .. math.random(4)
end
-- obstacles
if terrain == 1 then
local pick = math.random() > 0.2 and ("red_tree_" .. math.random(4)) or ("rock_" .. math.random(6))
self.rogue_grid[row][col].texture2 = txtr .. pick
end
end
end
end
function CustomPDAX:RogueSetLabCellTextures()
local txtr = "rogue_cell_"
for row = 1, #self.rogue_grid do
for col = 1, #self.rogue_grid[row] do
local cell = self.rogue_grid[row][col]
local terrain = cell.terrain
-- empty space first
if terrain == 0 or terrain == 1 then
self.rogue_grid[row][col].texture = txtr .. "blank"
end
-- ground and ground misc
if terrain == 0 then
self.rogue_grid[row][col].texture = txtr .. "lab_ground_1"
if math.random() < 0.03 then
self.rogue_grid[row][col].texture2 = txtr .. "lab_misc_ground_" .. math.random(3)
end
end
-- walls
if terrain == 1 then
local adj_str = ""
-- check adj
for i = row - 1, row + 1 do
for j = col - 1, col + 1 do
local adj_cel = self.rogue_grid[i] and self.rogue_grid[i][j]
if adj_cel and adj_cel.terrain == 0 then
-- up
if i == row-1 and j == col then
adj_str = adj_str .. "u"
-- down
elseif i == row+1 and j == col then
adj_str = adj_str .. "d"
-- left
elseif i == row and j == col-1 then
adj_str = adj_str .. "l"
-- right
elseif i == row and j == col+1 then
adj_str = adj_str .. "r"
end
end
end
end
-- set texture
if adj_str ~= "" then
self.rogue_grid[row][col].texture = txtr .. "lab_wall_" .. adj_str
end
-- some lab additions
if cell.texture and string.find(cell.texture, "blank") then
for i = row - 1, row + 1 do
for j = col - 1, col + 1 do
local adj_cel = self.rogue_grid[i] and self.rogue_grid[i][j]
if adj_cel and adj_cel.terrain == 0 then
-- up right
if i == row+1 and j == col+1 then
self.rogue_grid[row][col].texture = txtr .. "lab_wall_r"
-- up left
elseif i == row+1 and j == col-1 then
self.rogue_grid[row][col].texture = txtr .. "lab_wall_l"
-- down right
elseif i == row-1 and j == col+1 then
self.rogue_grid[row][col].texture = txtr .. "lab_wall_hzr"
-- down left
elseif i == row-1 and j == col-1 then
self.rogue_grid[row][col].texture = txtr .. "lab_wall_hzl"
end
end
end
end
end
end
end
end
-- walls misc
for row = 1, #self.rogue_grid do
for col = 1, #self.rogue_grid[row] do
local cell = self.rogue_grid[row][col]
if cell.terrain == 1 and string.find(cell.texture, "lab_wall_d") and math.random() < 0.33 then
self.rogue_grid[row][col].texture2 = txtr .. "lab_misc_wall_" .. math.random(6)
end
end
end
end
------------------------------------------------------------------------------------------------------------------------
-------------------------------------------- Level Generation (Wilderness) --------------------------------------------
------------------------------------------------------------------------------------------------------------------------
-- https://roguebasin.com/?title=Cellular_Automata_Method_for_Generating_Random_Cave-Like_Levels
-- but without Step function that actually make caves, because it doesnt work well on small maps
-- so more of a just random walls placement
function CustomPDAX:LevelWildGenerate(width, height, percentAreWalls)
percentAreWalls = percentAreWalls or 20
local map = {}
for i = 1, width*height do
map[i] = false
end
self:LevelWildRandomFill(map, width, height, percentAreWalls)
-- return as new table with flags
local start_cells = height * width
local map_t = {}
for y = 1, height do
map_t[y] = {}
for x = 1, width do
map_t[y][x] = 0
if map[x + y * width] then
map_t[y][x] = 1
start_cells = start_cells - 1
end
end
end
return map_t, start_cells
end
function CustomPDAX:LevelWildRandomFill(map, width, height, percentAreWalls)
local randomColumn = math.random(4, width - 4)
for y = 1, height do
for x = 1, width do
if x == 1 or y == 1 or x == width or y == height then
map[x+y*width] = true
elseif x ~= randomColumn and math.random(100) < percentAreWalls then
map[x+y*width] = true
end
end
end
end
------------------------------------------------------------------------------------------------------------------------
----------------------------------------------- Level Generation (Lab) ------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
-- i couldnt make it any better
local max_depth = 5
function CustomPDAX:LevelLabGenerate(width, height, add_cor_width)
local map = {}
map[1] = {
r1 = 1,
c1 = 1,
r2 = height,
c2 = width,
depth = 1,
}
-- set rects
self:LevelGenerateRects(map, 1)
-- make rooms
self:LevelMakeRooms(map)
-- add rooms to grid
for i = 1, #map do
local map_t = map[i]
if map_t.depth == max_depth - 1 then
for row = map_t.r1, map_t.r2 do
for col = map_t.c1, map_t.c2 do
self.rogue_grid[row][col].terrain = 0
end
end
end
end
-- get corridors
local add_corridor_width = add_cor_width or 0
local corridors = self:LevelMakeCorridors(map, add_corridor_width)
-- add corridors to grid
for i = 1, #corridors do
local cor_t = corridors[i]
for row = cor_t.r1, cor_t.r2 do
for col = cor_t.c1, cor_t.c2 do
if self.rogue_grid[row] and self.rogue_grid[row][col] then
self.rogue_grid[row][col].terrain = 0
end
end
end
end
end
function CustomPDAX:LevelGenerateRects(map, idx)
-- remove and return if max depth reached
local new_depth = map[idx].depth + 1
if new_depth > max_depth then
table.remove(map, idx)
return
end
-- mults for min and max rectangle split
local row_split_min, row_split_max = 0.4, 0.6
local col_split_min, col_split_max = 0.4, 0.6
-- get sizes
local size_r = map[idx].r2 - map[idx].r1 + 1
local size_c = map[idx].c2 - map[idx].c1 + 1
-- choose dir
local dir = math.random() > 0.5 and 0 or 1
-- pick random size of rect and split
local dmin = dir == 0 and math.ceil(size_r*row_split_min) or math.ceil(size_c*col_split_min)
local dmax = dir == 0 and math.floor(size_r*row_split_max) or math.floor(size_c*col_split_max)
if dmin > dmax then dmax = dmin end
local rnd_size = math.random(dmin, dmax)
-- create child 1
local new_idx1 = #map+1
map[new_idx1] = {
r1 = map[idx].r1,
c1 = map[idx].c1,
r2 = dir == 0 and (map[idx].r1 + rnd_size - 1) or map[idx].r2,
c2 = dir == 0 and map[idx].c2 or (map[idx].c1 + rnd_size - 1),
depth = new_depth,
parent = idx,
split = dir == 0 and "h" or "v",
}
self:LevelGenerateRects(map, #map)
-- create child 2
local new_idx2 = #map+1
map[new_idx2] = {
r1 = dir == 0 and (map[idx].r1 + rnd_size) or map[idx].r1,
c1 = dir == 0 and map[idx].c1 or map[idx].c1 + rnd_size,
r2 = map[idx].r2,
c2 = map[idx].c2,
depth = new_depth,
parent = idx,
split = dir == 0 and "h" or "v",
}
self:LevelGenerateRects(map, #map)
end
function CustomPDAX:LevelMakeRooms(map)
for i = 1, #map do
local t = map[i]
if t.depth == max_depth - 1 then
local half_size_r = (t.r2 - t.r1 + 1) / 2
local half_size_c = (t.c2 - t.c1 + 1) / 2
-- DO NOT SET THIS MULT HIGHER THAN 0.49
-- ELSE self:LevelPickRandomPoint() will go on infinite loop
local row_reduce = math.ceil(half_size_r*0.45)
local col_reduce = math.ceil(half_size_c*0.45)
map[i].r1 = half_size_r > 1 and t.r1 + math.random(1, row_reduce) or t.r1
map[i].c1 = half_size_c > 1 and t.c1 + math.random(1, col_reduce) or t.c1
map[i].r2 = half_size_r > 1 and t.r2 - math.random(1, row_reduce) or t.r2
map[i].c2 = half_size_c > 1 and t.c2 - math.random(1, col_reduce) or t.c2
end
end
end
function CustomPDAX:LevelMakeCorridors(map, width)
local corridors = {}
-- connect all depths
for sub_depth = 1, max_depth - 2 do
for i = 1, #map do
local t = map[i]
if t.depth == max_depth - sub_depth and (not t.connected) then
local pos1 = self:LevelPickRandomPoint(t)
for j = 1, #map do
local t2 = map[j]
if i ~= j and t2.depth == max_depth - sub_depth and t2.parent == t.parent and (not t2.connected) then
local pos2 = self:LevelPickRandomPoint(t2, j)
self:LevelGenerateCorridor(map, corridors, pos1, pos2, t.split, width)
map[i].connected = true
map[j].connected = true
end
end
end
end
end
return corridors
end
function CustomPDAX:LevelPickRandomPoint(t)
while true do -- rip
local row = math.random(t.r1, t.r2)
local col = math.random(t.c1, t.c2)
if self.rogue_grid[row][col].terrain == 0 then
return {row, col}
end
end
end
function CustomPDAX:LevelGenerateCorridor(map, corridors, pos1, pos2, split, width)
local start_row = pos1[1]
local start_col = pos1[2]
local end_row = pos2[1]
local end_col = pos2[2]
local dist_row = end_row - start_row
local dist_col = end_col - start_col
if split == "v" then
-- move right
corridors[#corridors + 1] = { r1=start_row, c1=start_col, r2=start_row+width, c2=end_col }
-- move up/down
if dist_row ~= 0 then
if dist_row > 0 then -- down
corridors[#corridors + 1] = { r1=start_row, c1=end_col-width, r2=end_row, c2=end_col }
else --up
corridors[#corridors + 1] = { r1=end_row, c1=end_col-width, r2=start_row, c2=end_col }
end
end
end
if split == "h" then
-- move down
corridors[#corridors + 1] = { r1=start_row, c1=start_col-width, r2=end_row, c2=start_col }
-- move left/right
if dist_col ~= 0 then
if dist_col > 0 then -- right
corridors[#corridors + 1] = { r1=end_row, c1=start_col, r2=end_row+width, c2=end_col }
else -- left
corridors[#corridors + 1] = { r1=end_row, c1=end_col, r2=end_row+width, c2=start_col }
end
end
end
end
------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------- Flood Fill --------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
function CustomPDAX:LevelFloodFill(map_t, start_cells)
-- pick cell in the middle
local cell_pos = self:LevelGetMiddleCell(map_t)
if not cell_pos then
return 0
end
-- flag all cells that we can reach from picked cell
self:LevelSetFlagsReachable(map_t, cell_pos)
-- calc and return ratio of new to old
local end_cells = 0
for row = 1, #map_t do
for col = 1, #map_t[row] do
if map_t[row][col] == 2 then
end_cells = end_cells + 1
end
end
end
return end_cells / start_cells
end
function CustomPDAX:LevelGetMiddleCell(map_t)
for row = 13, 17 do
for col = 13, 17 do
if map_t[row][col] == 0 then
return {row=row, col=col}
end
end
end
end
function CustomPDAX:LevelSetFlagsReachable(map_t, p)
if map_t[p.row+1] and map_t[p.row+1][p.col] == 0 then
map_t[p.row+1][p.col] = 2
self:LevelSetFlagsReachable(map_t, {row=p.row+1, col=p.col})
end
if map_t[p.row-1] and map_t[p.row-1][p.col] == 0 then
map_t[p.row-1][p.col] = 2
self:LevelSetFlagsReachable(map_t, {row=p.row-1, col=p.col})
end
if map_t[p.row][p.col+1] and map_t[p.row][p.col+1] == 0 then
map_t[p.row][p.col+1] = 2
self:LevelSetFlagsReachable(map_t, {row=p.row, col=p.col+1})
end
if map_t[p.row][p.col-1] and map_t[p.row][p.col-1] == 0 then
map_t[p.row][p.col-1] = 2
self:LevelSetFlagsReachable(map_t, {row=p.row, col=p.col-1})
end
end
@@ -0,0 +1,644 @@
local gt = game.translate_string
local CustomPDAX = pda_inter_gui.CustomPDAX
local astar = pda_inter_gui_c_games_rogue_a_path
local pr = pda_inter_gui.pr
function CustomPDAX:RogueGenerateObjects(win)
local actor_cache = {
health = win and self.rogue_objects[1].health or 4,
max_health = win and self.rogue_objects[1].max_health or 4,
melee_pwr = win and self.rogue_objects[1].melee_pwr or 2,
range_pwr = win and self.rogue_objects[1].range_pwr or 1,
evasion = win and self.rogue_objects[1].evasion or 15,
ammo = win and self.rogue_objects[1].ammo or 6,
max_ammo = win and self.rogue_objects[1].max_ammo or 6,
money = win and self.rogue_objects[1].money or 0,
}
iempty_table(self.rogue_objects)
self:RogueGenerateObjectActor(actor_cache)
self:RogueGenerateObjectExits()
self:RogueGenerateObjectArtefact()
self:RogueGenerateNPC()
self:RogueGenerateObjectConsumables()
self:RogueGenerateObjectAnomalies()
end
------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------- Objects Spawn -----------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
function CustomPDAX:RogueGenerateObjectActor(cache)
-- choose potential positions then pick random
local ac_spawns = {}
local start_at = 1
local end_at = 0
repeat
start_at = start_at + 1
end_at = end_at + 1
for row = start_at, #self.rogue_grid - end_at do
for col = start_at, #self.rogue_grid[row] - end_at do
local ter = self.rogue_grid[row][col].terrain
local cond = row == start_at or row == #self.rogue_grid - end_at or col == start_at or col == #self.rogue_grid[row] - end_at
if ter == 0 and cond then
ac_spawns[#ac_spawns + 1] = {row, col}
end
end
end
until #ac_spawns > 0
local rnd_ac_spawn = ac_spawns[math.random(1, #ac_spawns)]
local ac_row = rnd_ac_spawn[1]
local ac_col = rnd_ac_spawn[2]
-- set object
self.rogue_objects[1] = {
typ = "actor",
status = "alive",
health = cache.health,
max_health = cache.max_health,
melee_pwr = cache.melee_pwr,
range_pwr = cache.range_pwr,
evasion = cache.evasion,
ammo = cache.ammo,
max_ammo = cache.max_ammo,
money = cache.money,
row = ac_row,
col = ac_col,
spawn_radius = 10,
dir = "down",
texture = "rogue_cell_actor_",
}
end
function CustomPDAX:RogueGenerateObjectExits()
-- choose potential positions and then pick random
local ex_spawns = {}
local ex_spawns_bkp = {}
local start_at = 1
local end_at = 0
repeat
start_at = start_at + 1
end_at = end_at + 1
for row = start_at, #self.rogue_grid - end_at do
for col = start_at, #self.rogue_grid[row] - end_at do
local ter = self.rogue_grid[row][col].terrain
local cond = row == start_at or row == #self.rogue_grid - end_at or col == start_at or col == #self.rogue_grid[row] - end_at
if ter == 0 and cond then
local dist = self:CellDistance(row, col, self:RogueActor().row, self:RogueActor().col)
if dist > 40 then
ex_spawns[#ex_spawns + 1] = {row, col}
elseif dist > 25 then
ex_spawns_bkp[#ex_spawns_bkp + 1] = {row, col}
end
end
end
end
until #ex_spawns > 0 or #ex_spawns_bkp > 0
-- try to pick from furthest array, if not possible pick from backup
local exit_furthest = #ex_spawns > 0 and ex_spawns or ex_spawns_bkp
local rnd_exit = exit_furthest[math.random(1, #exit_furthest)]
local exit_row = rnd_exit[1]
local exit_col = rnd_exit[2]
for row = exit_row - 1, exit_row + 1 do -- extend exit to 3-4 cells if possible
for col = exit_col - 1, exit_col + 1 do
for i = 1, #exit_furthest do
local cell = exit_furthest[i]
if row == cell[1] and col == cell[2] then
-- set object
self.rogue_objects[#self.rogue_objects + 1] = {
typ = "exit",
status = "static",
row = row,
col = col,
spawn_radius = 1,
texture = "rogue_cell_exit",
}
end
end
end
end
end
function CustomPDAX:RogueGenerateObjectArtefact()
local ac_row, ac_col = self:RogueActor().row, self:RogueActor().col
local art_radius = 2
local art_furthest = {}
for row = 3, #self.rogue_grid - 2 do
for col = 3, #self.rogue_grid[row] - 2 do
local ter = self.rogue_grid[row][col].terrain
local dist = self:CellDistance(row, col, ac_row, ac_col)
local allowed_radius = self:SpawnRadiusAllowed(row, col, art_radius)
if ter == 0 and allowed_radius and dist > 20 then
art_furthest[#art_furthest + 1] = {row, col}
end
end
end
local rnd_art = art_furthest[math.random(1, #art_furthest)]
local art_row = rnd_art[1]
local art_col = rnd_art[2]
self.rogue_objects[#self.rogue_objects + 1] = {
typ = "artefact",
status = "world",
row = art_row,
col = art_col,
spawn_radius = art_radius,
texture = "rogue_cell_artefact_" .. math.random(1, 4),
}
end
function CustomPDAX:RogueGenerateNPC()
local mutants_t = {
[1] = { name = "chimera", health = 5, melee_pwr = 3, loot = 20, radius = 7, aggro_range = 7, max_texture = 1, spawn_score = 1, min_level = 19 },
[2] = { name = "bloodsucker", health = 4, melee_pwr = 2, loot = 10, radius = 6, aggro_range = 6, max_texture = 1, spawn_score = 2, min_level = 9, invis = true },
[3] = { name = "dog", health = 3, melee_pwr = 1, loot = 4, radius = 5, aggro_range = 5, max_texture = 4, spawn_score = 100, min_level = 1 },
}
for i = 1, 5 do
-- choose mutant
local mut_t = mutants_t[3]
for j, t in ipairs(mutants_t) do
local level_cond = self.cur_level >= t.min_level
local spawn_chance = self.cur_level * t.spawn_score
if level_cond and math.random(100) < spawn_chance then
mut_t = mutants_t[j]
break
end
end
local mut_pos = {}
for row = 3, #self.rogue_grid - 2 do
for col = 3, #self.rogue_grid[row] - 2 do
local ter = self.rogue_grid[row][col].terrain
local allowed_radius = self:SpawnRadiusAllowed(row, col, mut_t.radius)
if ter == 0 and allowed_radius then
mut_pos[#mut_pos + 1] = {row, col}
end
end
end
if #mut_pos > 0 then
local rnd_mut = mut_pos[math.random(1, #mut_pos)]
local mut_row = rnd_mut[1]
local mut_col = rnd_mut[2]
self.rogue_objects[#self.rogue_objects + 1] = {
typ = "mutant",
sec = mut_t.name,
status = "alive",
health = mut_t.health,
melee_pwr = mut_t.melee_pwr,
row = mut_row,
col = mut_col,
spawn_radius = mut_t.radius,
loot = mut_t.loot,
aggro = false,
invis = mut_t.invis or false,
aggro_range = mut_t.aggro_range,
gulag_row = mut_row,
gulag_col = mut_col,
gulag_radius = mut_t.radius,
dir = "left", -- for render
texture = "rogue_cell_" .. mut_t.name .. "_" .. math.random(1, mut_t.max_texture) .. "_",
}
end
end
end
function CustomPDAX:RogueGenerateObjectConsumables()
local ac_row, ac_col = self:RogueActor().row, self:RogueActor().col
local item_radius = 2
for i = 1, 2 do
local item = i == 1 and "medkit" or "ammo"
local item_texture = "rogue_cell_" .. item
local itm_furthest = {}
for row = 3, #self.rogue_grid - 2 do
for col = 3, #self.rogue_grid[row] - 2 do
local ter = self.rogue_grid[row][col].terrain
local dist = self:CellDistance(row, col, ac_row, ac_col)
local allowed_radius = self:SpawnRadiusAllowed(row, col, item_radius)
if ter == 0 and allowed_radius and dist > 15 then
itm_furthest[#itm_furthest + 1] = {row, col}
end
end
end
if #itm_furthest > 0 then
local rnd_itm = itm_furthest[math.random(1, #itm_furthest)]
local itm_row = rnd_itm[1]
local itm_col = rnd_itm[2]
self.rogue_objects[#self.rogue_objects + 1] = {
typ = item,
status = "world",
row = itm_row,
col = itm_col,
spawn_radius = item_radius,
texture = item_texture,
}
end
end
end
function CustomPDAX:RogueGenerateObjectAnomalies()
local ac_row, ac_col = self:RogueActor().row, self:RogueActor().col
local exit_path = self:ActorPathToExit()
local anomalies_t = {
[1] = { name = "fire", melee_pwr = 2, max_anm = 4 },
[2] = { name = "electra", melee_pwr = 2, max_anm = 5 },
[3] = { name = "acid", melee_pwr = 2, max_anm = 6 },
[4] = { name = "gravi", melee_pwr = 2, max_anm = 6 },
}
local anomaly_amount = math.random(5, 7) + math.ceil(self.cur_level / 10) * 3
for i = 1, anomaly_amount do
local anom_t = anomalies_t[math.random(1, #anomalies_t)]
local anom_pos = {}
for row = 2, #self.rogue_grid - 1 do
for col = 2, #self.rogue_grid[row] - 1 do
local ter = self.rogue_grid[row][col].terrain
local allowed_radius = self:SpawnRadiusAllowed(row, col, 2)
local pos_safe = not self:PosOnExitPath(exit_path, row, col)
if ter == 0 and allowed_radius and pos_safe then
anom_pos[#anom_pos + 1] = {row, col}
end
end
end
if #anom_pos > 0 then
local rnd_anom = anom_pos[math.random(1, #anom_pos)]
local anom_row = rnd_anom[1]
local anom_col = rnd_anom[2]
self.rogue_objects[#self.rogue_objects + 1] = {
typ = "anomaly",
sec = anom_t.name,
status = "static",
melee_pwr = anom_t.melee_pwr,
row = anom_row,
col = anom_col,
spawn_radius = 2,
anm = 1,
max_anm = anom_t.max_anm,
texture = "rogue_anomaly_" .. anom_t.name .. "_",
}
end
end
end
------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------- Objects handler ---------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------- Actor ---------------------------------------------------
function CustomPDAX:MoveActor(dir)
local ac_obj = self:RogueActor()
local cur_dir = ac_obj.dir
-- rotate actor and update render
if cur_dir ~= dir then
ac_obj.dir = dir
self:RenderUpdate()
return
end
-- choose dir
local to_row = ac_obj.row
local to_col = ac_obj.col
if dir == "up" then
to_row = to_row - 1
elseif dir == "down" then
to_row = to_row + 1
elseif dir == "left" then
to_col = to_col - 1
elseif dir == "right" then
to_col = to_col + 1
end
-- try to move (terrain wall)
if self:CanMove(1, to_row, to_col) == false then
return
end
-- try to move
if self:CanMove(1, to_row, to_col) then
ac_obj.row = to_row
ac_obj.col = to_col
end
-- object interaction
for idx, t in pairs(self.rogue_objects) do
if t.row == to_row and t.col == to_col then
-- melee attack if its alive mutant
if t.typ == "mutant" and t.status == "alive" then
self:Attack(1, idx)
self:PlaySound("rogue_melee")
break
end
-- try to pick up if its item
if t.status == "world" then
if t.typ == "artefact" then
ac_obj.money = ac_obj.money + 100
self:PlaySound("rogue_artefact")
elseif t.typ == "medkit" then
ac_obj.health = clamp(ac_obj.health + 4, 0, ac_obj.max_health)
self:PlaySound("rogue_medkit")
elseif t.typ == "ammo" then
ac_obj.ammo = clamp(ac_obj.ammo + 6, 0, ac_obj.max_ammo)
self:PlaySound("rogue_ammo")
end
self.rogue_objects[idx].status = "taken"
end
-- exit
if t.typ == "exit" then
self:RogueActorOnLevelExit()
return
end
end
end
-- update grid
self:RogueGridUpdate()
end
function CustomPDAX:WaitActor()
self:RogueGridUpdate()
end
function CustomPDAX:ShootActor()
local ac_obj = self:RogueActor()
local dir = ac_obj.dir
if ac_obj.ammo <= 0 then
self:PlaySound("rogue_shoot_empty")
return
end
-- reduce ammo and play shoot sound
ac_obj.ammo = ac_obj.ammo - 1
self:PlaySound("rogue_shoot")
-- get nearest alive mutant in actor direction
local near_dist = 99
local near_id
for idx, t in pairs(self.rogue_objects) do
if t.typ == "mutant" and t.status == "alive" then
local up_cond = dir == "up" and t.col == ac_obj.col and t.row < ac_obj.row
local down_cond = dir == "down" and t.col == ac_obj.col and t.row > ac_obj.row
local left_cond = dir == "left" and t.row == ac_obj.row and t.col < ac_obj.col
local right_cond = dir == "right" and t.row == ac_obj.row and t.col > ac_obj.col
local cond = up_cond or down_cond or left_cond or right_cond
local dist = self:CellDistance(t.row, t.col, ac_obj.row, ac_obj.col)
if cond and dist < near_dist then
near_dist = dist
near_id = idx
end
end
end
-- hit if mutant exist and range is melee or no obstacles in line
local mut_obj = near_id and self.rogue_objects[near_id]
if mut_obj then
local obstacles = self:ObstaclesInLine(mut_obj.row, mut_obj.col, ac_obj.row, ac_obj.col)
if not obstacles then
self:Attack(1, near_id, "range_pwr")
end
end
self:RogueGridUpdate()
end
function CustomPDAX:RogueActorOnLevelExit()
-- give some money
self:RogueActor().money = self:RogueActor().money + self.cur_level * 2
-- trader or new level
if self.cur_level % 5 == 0 then
self.rogue_enable_input = false
self:RogueTradeUpdate()
else
self:RogueGenerateNewLevel(true)
end
self:PlaySound("rogue_end_level")
end
function CustomPDAX:RogueActorOnDeath()
self:PlaySound("rogue_actor_die_" .. math.random(1, 2))
self.rogue_start_over_btn:Show(true)
self.rogue_enable_input = false
end
--------------------------------------------------- Shared ---------------------------------------------------
function CustomPDAX:Attack(id, victim_id, typ)
-- actor evasion
if victim_id == 1 and math.random(100) <= self:RogueActor().evasion then
self:PlaySound("rogue_evade_" .. math.random(2))
return
end
local hit_typ = typ or "melee_pwr"
local pwr = self.rogue_objects[id][hit_typ]
self.rogue_objects[victim_id].health = self.rogue_objects[victim_id].health - pwr
if self.rogue_objects[victim_id].health <= 0 then
self.rogue_objects[victim_id].status = "dead"
-- npc died
if victim_id ~= 1 then
self:RogueNPCOnDeath(victim_id, id, self.rogue_objects[victim_id].sec)
end
-- if actor died - generate from start
if victim_id == 1 then
self:RogueActorOnDeath()
end
end
end
--------------------------------------------------- NPCs ---------------------------------------------------
function CustomPDAX:MoveIdleNPC(idx)
for i = 1, 3 do
local to_row = self.rogue_objects[idx].row
local to_col = self.rogue_objects[idx].col
local rnd = math.random(1, 4)
if rnd == 1 then
to_row = to_row - 1
elseif rnd == 2 then
to_row = to_row + 1
elseif rnd == 3 then
to_col = to_col - 1
self.rogue_objects[idx].dir = "left"
elseif rnd == 4 then
to_col = to_col + 1
self.rogue_objects[idx].dir = "right"
end
if self:CanMove(idx, to_row, to_col) then
self.rogue_objects[idx].row = to_row
self.rogue_objects[idx].col = to_col
break
end
end
end
function CustomPDAX:MoveAggroNPC(idx, victim_idx)
local row = self.rogue_objects[idx].row
local col = self.rogue_objects[idx].col
local victim_row = self.rogue_objects[victim_idx].row
local victim_col = self.rogue_objects[victim_idx].col
local astar_path = astar.astar_find(self.grid_h, self.grid_w, {x=row, y=col}, {x=victim_row, y=victim_col}, astar.AStarCanMove, self, idx, victim_idx)
if not (astar_path and astar_path[2]) then return end
-- test display path
-- CreateTimeEvent("test_rogue_ev" .. idx, "test_rogue_ac" .. idx, 1, function()
-- for idx, p in ipairs(astar_path) do self.rogue_grid[p.x][p.y].test_cell:SetTextureColor( GetARGB(255, 240, 255, 70) ) end
-- return true end)
-------------------
-- set dir
if astar_path[2].y < col then
self.rogue_objects[idx].dir = "left"
elseif astar_path[2].y > col then
self.rogue_objects[idx].dir = "right"
end
-- set pos
self.rogue_objects[idx].row = astar_path[2].x
self.rogue_objects[idx].col = astar_path[2].y
end
function CustomPDAX:ChimeraJump(idx, victim_idx, dist, row, col, victim_row, victim_col)
local same_col_or_row = (row == victim_row) or (col == victim_col)
if not same_col_or_row then return end
if dist ~= 3 then return end
local ret_cell
-- get all cells between
local cells = self:CellsInLine(row, col, victim_row, victim_col)
for i, ar in ipairs(cells) do
-- if nearest to actor and can move to it - set and return it
local valid_final_row = (ar[1]-1 == victim_row) or (ar[1]+1 == victim_row)
local valid_final_col = (ar[2]-1 == victim_col) or (ar[2]+1 == victim_col)
if (valid_final_row or valid_final_col) and self:CanMove(idx, ar[1], ar[2]) then
ret_cell = {ar[1], ar[2]}
end
-- dont let jump through walls
if self.rogue_grid[ar[1]][ar[2]].terrain == 1 then
return
end
-- don let jump through other objects
for obj_id, t in pairs(self.rogue_objects) do
if t.status == "alive" and t.row == ar[1] and t.col == ar[2] then
return
end
end
end
return ret_cell
end
function CustomPDAX:RogueNPCOnDeath(id, killer_id, sec)
-- if actor killed - give money
if killer_id == 1 then
self:RogueActor().money = self:RogueActor().money + self.rogue_objects[id].loot
end
-- play snd
self:PlaySound("rogue_" .. sec .. "_die_" .. math.random(1, 2))
end
function CustomPDAX:MutantsUpdate()
local ac_row = self:RogueActor().row
local ac_col = self:RogueActor().col
for idx, t in pairs(self.rogue_objects) do
local dist_to_ac = self:CellDistance(t.row, t.col, ac_row, ac_col)
if t.typ == "mutant" and t.status == "alive" then
-- try to set aggro
if (not t.aggro) and dist_to_ac <= t.aggro_range then
self.rogue_objects[idx].aggro = true
end
-- bloodsucker invis
if t.invis and dist_to_ac <= 5 then
self.rogue_objects[idx].invis = false
self:PlaySound("rogue_bloodsucker_invis")
end
-- attack
if dist_to_ac <= 1 then
self:Attack(idx, 1)
self:PlaySound("rogue_" .. t.sec .. "_attack_" .. math.random(1, 3))
end
-- move
if dist_to_ac > 1 then
if t.aggro then
-- chimera try to jump
local chimera_can_jump = t.sec == "chimera" and self:ChimeraJump(idx, 1, dist_to_ac, t.row, t.col, ac_row, ac_col)
if chimera_can_jump then
self.rogue_objects[idx].row = chimera_can_jump[1]
self.rogue_objects[idx].col = chimera_can_jump[2]
self:Attack(idx, 1)
self:PlaySound("rogue_chimera_jump")
else
self:MoveAggroNPC(idx, 1)
end
else
self:MoveIdleNPC(idx)
end
end
end
end
end
--------------------------------------------------- Anomalies ---------------------------------------------------
function CustomPDAX:AnomaliesUpdate()
for idx, t in pairs(self.rogue_objects) do
if t.typ == "anomaly" then
for victim_idx, victim_t in pairs(self.rogue_objects) do
if victim_t.status == "alive" and t.row == victim_t.row and t.col == victim_t.col then
self:Attack(idx, victim_idx)
self:PlaySound("rogue_anomaly_" .. t.sec)
end
end
end
end
end
@@ -0,0 +1,236 @@
local gt = game.translate_string
local CustomPDAX = pda_inter_gui.CustomPDAX
local astar = pda_inter_gui_c_games_rogue_a_path
local pr = pda_inter_gui.pr
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------- Utils -----------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
function CustomPDAX:RogueActor()
return self.rogue_objects[1]
end
function CustomPDAX:CellDistance(row1, col1, row2, col2)
return math.abs(row1-row2) + math.abs(col1-col2)
end
function CustomPDAX:SpawnRadiusAllowed(row1, col1, radius)
for idx, t in ipairs(self.rogue_objects) do
if t.spawn_radius then
local dist = self:CellDistance(row1, col1, t.row, t.col)
if dist < (t.spawn_radius + radius) then
return false
end
end
end
return true
end
function CustomPDAX:CellsInLine(row1, col1, row2, col2)
local cells_ar = {}
if row1 == row2 then
if col1 > col2 then
for col = col2 + 1, col1 - 1 do
cells_ar[#cells_ar + 1] = { row1, col }
end
elseif col1 < col2 then
for col = col1 + 1, col2 - 1 do
cells_ar[#cells_ar + 1] = { row1, col }
end
end
end
if col1 == col2 then
if row1 > row2 then
for row = row2 + 1, row1 - 1 do
cells_ar[#cells_ar + 1] = { row, col1 }
end
elseif row1 < row2 then
for row = row1 + 1, row2 - 1 do
cells_ar[#cells_ar + 1] = { row, col1 }
end
end
end
return cells_ar
end
function CustomPDAX:ObstaclesInLine(row1, col1, row2, col2)
local is_melee = self:CellDistance(row1, col1, row2, col2) <= 1
if is_melee then return end
local cells_in_line = self:CellsInLine(row1, col1, row2, col2)
for i = 1, #cells_in_line do
local cell = cells_in_line[i]
local terrain = self.rogue_grid[cell[1]][cell[2]].terrain
if terrain == 1 then
return true
end
end
end
function CustomPDAX:ActorPathToExit()
local ac = self:RogueActor()
for i, t in ipairs(self.rogue_objects) do
if t.typ == "exit" then
local exit_path = astar.astar_find(self.grid_h, self.grid_w, {x=ac.row, y=ac.col}, {x=t.row, y=t.col}, astar.AStarCanMoveToExit, self)
return exit_path
end
end
end
function CustomPDAX:PosOnExitPath(exit_path, row, col)
exit_path = exit_path or self:ActorPathToExit()
for i, p in ipairs(exit_path) do
if row == p.x and col == p.y then
return true
end
end
end
function CustomPDAX:CanMove(id, to_row, to_col)
-- check static
if self.rogue_grid[to_row][to_col].terrain ~= 0 then
return false -- extra check for actor not to update grid
end
-- find if any alive mutant on a way
for idx, t in ipairs(self.rogue_objects) do
local alive_obj = t.status and t.status == "alive"
if id ~= idx and to_row == t.row and to_col == t.col and alive_obj then
return
end
end
-- For mutant
-- not aggroed and destination is outside of gulag radius
local t = id ~= 1 and self.rogue_objects[id]
if t and (not t.aggro) and self:CellDistance(t.gulag_row, t.gulag_col, to_row, to_col) > t.gulag_radius then
return
end
return true
end
function CustomPDAX:PlaySound(name)
local snd = sound_object("rogue_game\\" .. name)
snd:play_no_feedback(db.actor, 0, 0, db.actor:position(), 1.0, 1.0)
end
------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------- Test ----------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
function CustomPDAX:BuildTestDisplayGrid(xml)
if not self.rogue_debug then return end
self.rogue_test_main_grid = xml:InitStatic("rogue_test_grid", self)
local x_offset, y_offset = 12, 16
for row = 1, #self.rogue_grid do
for col = 1, #self.rogue_grid[row] do
self.rogue_grid[row][col].test_cell = xml:InitStatic("rogue_test_grid:rogue_test_cell", self.rogue_test_main_grid)
self.rogue_grid[row][col].test_cell:SetWndPos(vector2():set(x_offset*(col-1), y_offset*(row-1)))
self.rogue_grid[row][col].test_cell:InitTexture("rogue_cell_texture")
self.rogue_grid[row][col].test_cell:SetTextureColor( GetARGB(255, 70, 70, 70) )
end
end
end
function CustomPDAX:TESTTerrainDisplay()
if not self.rogue_debug then return end
for row = 1, #self.rogue_grid do
for col = 1, #self.rogue_grid[row] do
local terrain = self.rogue_grid[row][col].terrain
-- Display cells
if terrain == 0 then
self.rogue_grid[row][col].test_cell:InitTexture("rogue_cell_texture")
self.rogue_grid[row][col].test_cell:SetTextureColor( GetARGB(255, 70, 70, 70) )
end
-- Display obstacles
if terrain == 1 or terrain == 2 then
self.rogue_grid[row][col].test_cell:InitTexture("none.dds")
self.rogue_grid[row][col].test_cell:SetTextureColor( GetARGB(255, 10, 10, 10) )
end
end
end
end
function CustomPDAX:TESTObjectsDisplay()
if not self.rogue_debug then return end
-- display objects
for idx, t in pairs(self.rogue_objects) do
self.rogue_grid[t.row][t.col].test_cell:InitTexture("none.dds")
local clr = { 70, 70, 70 }
if t.typ == "actor" then
clr = { 0, 130, 0 }
elseif t.typ == "exit" then
clr = { 0, 0, 130 }
elseif t.status == "world" then
if t.typ == "artefact" then
clr = { 180, 70, 0 }
elseif t.typ == "medkit" then
clr = { 230, 90, 250 }
elseif t.typ == "ammo" then
clr = { 90, 255, 200 }
end
elseif t.typ == "mutant" then
clr = t.status == "alive" and { 180, 0, 0 } or { 200, 200, 200 }
end
self.rogue_grid[t.row][t.col].test_cell:SetTextureColor( GetARGB(255, clr[1], clr[2], clr[3]) )
end
end
function CustomPDAX:TESTDisplaySpawnRadius(mode)
if not self.rogue_debug then return end
for idx, t in ipairs(self.rogue_objects) do
-- display spawn radius
if mode == "spawn" and t.spawn_radius then
for row = t.row - t.spawn_radius, t.row + t.spawn_radius do
for col = t.col - t.spawn_radius, t.col + t.spawn_radius do
local cell_exist = self.rogue_grid[row] and self.rogue_grid[row][col]
local dist = self:CellDistance(row, col, t.row, t.col)
if cell_exist and dist <= t.spawn_radius and dist > 0 then
self.rogue_grid[row][col].test_cell:InitTexture("none.dds")
self.rogue_grid[row][col].test_cell:SetTextureColor( GetARGB(80, 200, 60, 100) )
end
end
end
end
-- display gulag radius
if mode == "gulag" and t.gulag_radius then
for row = t.gulag_row - t.gulag_radius, t.gulag_row + t.gulag_radius do
for col = t.gulag_col - t.gulag_radius, t.gulag_col + t.gulag_radius do
local cell_exist = self.rogue_grid[row] and self.rogue_grid[row][col]
local dist = self:CellDistance(row, col, t.gulag_row, t.gulag_col)
if cell_exist and dist <= t.gulag_radius and dist > 0 then
self.rogue_grid[row][col].test_cell:InitTexture("none.dds")
self.rogue_grid[row][col].test_cell:SetTextureColor( GetARGB(80, 200, 100, 60) )
end
end
end
end
end
end
function CustomPDAX:UpdateTestGrid(win, set_level)
if not self.rogue_debug then return end
self:RogueGenerateNewLevel(win, set_level)
for row = 1, #self.rogue_grid do
for col = 1, #self.rogue_grid[row] do
local str = self.rogue_grid[row][col].rect
-- self.rogue_grid[row][col].test_cell:TextControl():SetText(str)
end
end
end
+28
View File
@@ -0,0 +1,28 @@
[General]
gameName=stalkeranomaly
modid=0
version=d2024.12.3.0
newestVersion=
category="-1,"
nexusFileStatus=1
installationFile=Interactive_PDA_Roguelike.zip
repository=Nexus
ignoredVersion=
comments=
notes=
nexusDescription=
url=
hasCustomURL=false
lastNexusQuery=
lastNexusUpdate=
nexusLastModified=2024-12-03T23:21:32Z
nexusCategory=0
converted=false
validated=false
color=@Variant(\0\0\0\x43\0\xff\xff\0\0\0\0\0\0\0\0)
tracked=0
[installedFiles]
1\modid=0
1\fileid=0
size=1