This thread will contain all DS references I made. If I make more in the future, they will be added here as well. As of now, we have:
Enjoy!
A simple presentation using progress overlay as boss hp (still not perfect as it has slider and isn't full even at max value). The intention was to recreate only the visuals, not the whole boss system, so I assigned only 1 specific troop for this purpose. If you are going to create multiple bosses, you'll have to heavily modify this code (considering presentation shift when there are more than 1 boss in a fight).
This goes to module_mission_templates.py
This goes to module_presentations.py
Final result: https://drive.google.com/file/d/1agDRq2oGRTlXz6QCIXaEkUUCCgx03qvg/view
This goes to module_mission_templates.py
Code:
boss_agent_set = (ti_on_agent_spawn, 0, 0,
[
(store_trigger_param_1, ":agent"),
(agent_get_troop_id, ":troop", ":agent"),
(eq, ":troop", "trp_npc12"), # list of your bosses
],
[
(store_trigger_param_1, ":agent"),
(agent_set_max_hit_points, ":agent", 1000, 1), # their hp
(assign, "$boss_agent", ":agent"), # if you have more than 1 boss, global variable is not the way to go, use agent slots
(start_presentation, "prsnt_boss_hp_bar"),
])
boss_agent_death = (ti_on_agent_killed_or_wounded, 0, 0,
[
(store_trigger_param_1, ":agent"),
(agent_get_troop_id, ":troop", ":agent"),
(eq, ":troop", "trp_npc12"),
],
[
(set_fixed_point_multiplier, 100),
(tutorial_message_set_size, 20, 100),
(tutorial_message_set_background, 1),
(tutorial_message_set_position, 500, 400),
(tutorial_message, "@ H E I R O F F I R E D E S T R O Y E D", 0xFFFAEA9D, 5), # spaces are needed to centrify the text
(play_sound, "snd_quest_failed", sf_vol_15),
])
This goes to module_presentations.py
Code:
("boss_hp_bar", prsntf_read_only, 0,[
(ti_on_presentation_load,
[
(set_fixed_point_multiplier, 100),
(store_agent_hit_points, ":hp", "$boss_agent", 1),
(str_store_string, s1, "@Jeremus, High Priest of Calradia"), # here you can set some fancy name for your boss
#(str_store_agent_name, s1, "$boss_agent"), # or just take real name of the agent, if it's already fancy enough
(create_progress_overlay, "$boss_hp_bar", 0, ":hp"),
(create_text_overlay, "$boss_name", s1, tf_with_outline|tf_center_justify),
(overlay_set_val, "$boss_hp_bar", ":hp"),
(overlay_set_color, "$boss_name", 0xFAFAFA),
(position_set_x, pos1, 80),
(position_set_y, pos1, 80),
(overlay_set_size, "$boss_name", pos1),
(position_set_x, pos1, 200),
(position_set_y, pos1, 70),
(overlay_set_size, "$boss_hp_bar", pos1),
(position_set_x, pos1, 50),
(position_set_y, pos1, 10),
(overlay_set_position, "$boss_hp_bar", pos1),
(position_set_x, pos1, 35),
(position_set_y, pos1, 12),
(overlay_set_position, "$boss_name", pos1),
(presentation_set_duration, 999999),
]),
(ti_on_presentation_run,
[
(store_agent_hit_points, ":hp", "$boss_agent", 1),
(overlay_set_val, "$boss_hp_bar", ":hp"),
(try_begin),
(le, ":hp", 0),
(presentation_set_duration, 0),
(try_end),
]),
]),
Final result: https://drive.google.com/file/d/1agDRq2oGRTlXz6QCIXaEkUUCCgx03qvg/view
This system allows you to make any wall illusory. When such wall gets hit, it will emit a sound and disappear, opening a passage or revealing a hidden loot. You can use illusory walls to make locations more interesting to explore. Again, this was made for recreation only, so it supports only 1 illusory wall per scene. If you introduce the whole illusory wall system, you should create more scene slots and rework the hiding code at ti_on_init_scene_prop.
This goes to module_scene_props.py
Final result:
This goes to module_scene_props.py
Code:
("z_illusory_wall",sokf_moveable|sokf_missiles_not_attached,"village_wall_a","bo_village_wall_a", [ # you can put your own mesh and collision but keep the flags
(ti_on_init_scene_prop, # this will remove wall when entering scene if it has been revealed previously
[
(store_trigger_param_1, ":instance_no"),
(store_current_scene, ":cur_scene"),
(scene_slot_eq, ":cur_scene", 739, 1), # some random number instead of name to avoid declaring
(prop_instance_is_valid, ":instance_no"),
(scene_prop_set_visibility, ":instance_no", 0),
(prop_instance_get_position, pos1, ":instance_no"),
(position_move_z, pos1, -3000, 1),
(prop_instance_set_position, ":instance_no", pos1),
(rebuild_shadow_map),
]),
(ti_on_scene_prop_hit, # fading out should start at the moment of hit, but player should see it fully, so we
# need a delay. To avoid mission triggers we just animate wall to current position with
# some timer and move the rest of the hiding code to ti_on_scene_prop_animation_finished
[
(store_trigger_param_1, ":instance_no"),
(set_fixed_point_multiplier, 100),
(prop_instance_get_position, pos1, ":instance_no"),
(copy_position, pos2, pos1),
(prop_instance_animate_to_position, ":instance_no", pos2, 100),
(scene_prop_fade_out, ":instance_no", 100),
(prop_instance_enable_physics, ":instance_no", 0),
(prop_instance_play_sound, ":instance_no", "snd_quest_failed"),
]),
(ti_on_scene_prop_animation_finished,
[
(store_trigger_param_1, ":instance_no"),
(prop_instance_is_valid, ":instance_no"),
(scene_prop_set_visibility, ":instance_no", 0),
(prop_instance_get_position, pos1, ":instance_no"),
(position_move_z, pos1, -3000, 1),
(prop_instance_set_position, ":instance_no", pos1),
(rebuild_shadow_map),
(store_current_scene, ":cur_scene"),
(neg|scene_slot_eq, ":cur_scene", 739, 1),
(scene_set_slot, ":cur_scene", 739, 1),
]),
]),
Final result:
This will allow you to turn your character into scene object in order to blend-in with the enviroment. Code is singleplayer but it's quite useless in this mode - your collision is still human (so you can get a headshot while being a chair), enemies still see you, you need to code-in a lot of dependecies to make a use of being a prop. In multiplayer however, this will work as is, cuz you can fool human eye with transformtion alone, and ambush another players without additional coding. Just replace singleplayer get_player_agent_no operation with some multiplayer equivalent that will allow you to take a correct referrence. And maybe mask walking sounds somehow.
This goes to module_scene_props.py
This goes to module_constants.py
This goes to module_mission_templates.py
Final result: https://drive.google.com/file/d/1135PoK9QIlMxUTRvp6V_4JpeyrUTvBgM/view
This goes to module_scene_props.py
Code:
# these are just duplicates of native props with removed collision. spr_tavern_barrel fits too, but it is spawned half underground so I excluded it
("cm_apple_basket", 0, "apple_basket", "0", []),
("cm_box_a", 0, "box_a", "0", []),
("cm_chair_trunk_b", 0, "chair_trunk_b", "0", []),
("cm_chair_trunk_c", 0, "chair_trunk_c", "0", []),
("cm_chest_b", 0, "chest_b", "0", []),
("cm_cupboard_a", 0, "cupboard_a", "0", []),
("cm_dummy_a", 0, "arena_archery_target_b", "0", []),
("cm_straw_c", 0, "straw_c", "0", []),
("cm_tavern_chair_b",0,"tavern_chair_b", "0", []),
("cm_torture_tool_c", 0, "torture_tool_c", "0", []),
("cm_tripod_cauldron_b", 0, "tripod_cauldron_b", "0", []),
("cm_water_well_a", 0, "water_well_a", "0", []),
("cm_wood_heap", 0, "wood_heap_a", "0", []),
("cm_prop_end", 0, "wood_heap_a", "0", []),
This goes to module_constants.py
Code:
slot_agent_is_transformed = 797
slot_agent_target_prop = 798
This goes to module_mission_templates.py
Code:
chameleon_1 = (0, 2, 0, # starting transformation
[
(key_clicked, key_numpad_slash), # replace with any button you want
(get_player_agent_no, ":player"),
(neg|agent_slot_eq, ":player", slot_agent_is_transformed, 1),
(agent_set_animation, ":player", "anim_cheer", 1), # this animation lasts around 4 sec so we
# put consequences delay on 2 for it to
# interrupt it on half
],
[
(get_player_agent_no, ":player"),
(agent_set_visibility, ":player", 0),
(agent_set_slot, ":player", slot_agent_is_transformed, 1),
(agent_get_position, pos1, ":player"),
(particle_system_burst, "psys_ladder_dust_14m", pos1, 300),
(play_sound_at_position, "snd_quest_failed", pos1),
(set_spawn_position, pos1),
(store_random_in_range, ":target_prop", "spr_cm_apple_basket", "spr_cm_prop_end"),
(spawn_scene_prop, ":target_prop"),
(agent_set_slot, ":player", slot_agent_target_prop, reg0),
])
chameleon_2 = (0, 0, 0, # this moves the prop to wherever we move
[
(get_player_agent_no, ":player"),
(agent_slot_eq, ":player", slot_agent_is_transformed, 1),
],
[
(get_player_agent_no, ":player"),
(agent_get_slot, ":instance_no", ":player", slot_agent_target_prop),
(agent_get_position, pos1, ":player"),
(position_rotate_z, pos1, 180),
(prop_instance_set_position, ":instance_no", pos1),
])
chameleon_3 = (0, 0, 0, # ending transformation
[
(get_player_agent_no, ":player"),
(agent_slot_eq, ":player", slot_agent_is_transformed, 1),
(this_or_next|game_key_clicked, gk_attack), # here are listed main actions which should turn you
(this_or_next|game_key_clicked, gk_defend), # human again. gk_attack also triggers when you choose
(this_or_next|game_key_clicked, gk_jump), # a dialog answer. You may contribute to this list
(game_key_clicked, gk_kick),
],
[
(get_player_agent_no, ":player"),
(agent_set_slot, ":player", slot_agent_is_transformed, 0),
(agent_get_slot, ":instance_no", ":player", slot_agent_target_prop),
(prop_instance_get_position, pos1, ":instance_no"),
(particle_system_burst, "psys_ladder_dust_14m", pos1, 300),
(position_move_z, pos1, -3000, 1),
(prop_instance_set_position, ":instance_no", pos1),
(rebuild_shadow_map),
(agent_set_visibility, ":player", 1),
(agent_set_slot, ":player", slot_agent_target_prop, -1),
])
Final result: https://drive.google.com/file/d/1135PoK9QIlMxUTRvp6V_4JpeyrUTvBgM/view
Enjoy!