mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 07:03:16 +00:00
fix enemys not dropping right stuff generally, specifically pyramid boss
This commit is contained in:
parent
2195f70e48
commit
681bc6a3b8
4 changed files with 30 additions and 318 deletions
|
@ -100,7 +100,7 @@ function rpc.try_kill(x, y)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
GamePrintImportant(ctx.rpc_player_data.name .. " has won")
|
GamePrintImportant(ctx.rpc_player_data.name .. " wins")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function remove_fire(entity)
|
local function remove_fire(entity)
|
||||||
|
|
|
@ -12,33 +12,29 @@ local rpc = net.new_rpc_namespace()
|
||||||
local EnemyData = util.make_type({
|
local EnemyData = util.make_type({
|
||||||
u32 = {"enemy_id"},
|
u32 = {"enemy_id"},
|
||||||
f32 = {"x", "y", "vx", "vy"},
|
f32 = {"x", "y", "vx", "vy"},
|
||||||
bool = {"drop_gold"},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Variant of EnemyData for when we don't have any motion (or no VelocityComponent).
|
-- Variant of EnemyData for when we don't have any motion (or no VelocityComponent).
|
||||||
local EnemyDataNoMotion = util.make_type({
|
local EnemyDataNoMotion = util.make_type({
|
||||||
u32 = {"enemy_id"},
|
u32 = {"enemy_id"},
|
||||||
f32 = {"x", "y"},
|
f32 = {"x", "y"},
|
||||||
bool = {"drop_gold"}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
local EnemyDataWorm = util.make_type({
|
local EnemyDataWorm = util.make_type({
|
||||||
u32 = {"enemy_id"},
|
u32 = {"enemy_id"},
|
||||||
f32 = {"x", "y", "vx", "vy", "tx", "ty"},
|
f32 = {"x", "y", "vx", "vy", "tx", "ty"},
|
||||||
bool = {"drop_gold"}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
local EnemyDataKolmi = util.make_type({
|
local EnemyDataKolmi = util.make_type({
|
||||||
u32 = {"enemy_id"},
|
u32 = {"enemy_id"},
|
||||||
f32 = {"x", "y", "vx", "vy"},
|
f32 = {"x", "y", "vx", "vy"},
|
||||||
bool = {"enabled", "drop_gold"},
|
bool = {"enabled"},
|
||||||
})
|
})
|
||||||
|
|
||||||
local EnemyDataFish = util.make_type({
|
local EnemyDataFish = util.make_type({
|
||||||
u32 = {"enemy_id"},
|
u32 = {"enemy_id"},
|
||||||
f32 = {"x", "y", "vx", "vy"},
|
f32 = {"x", "y", "vx", "vy"},
|
||||||
u8 = {"r"},
|
u8 = {"r"},
|
||||||
bool = {"drop_gold"},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
--local EnemyDataSniper = util.make_type({
|
--local EnemyDataSniper = util.make_type({
|
||||||
|
@ -269,10 +265,11 @@ function enemy_sync.host_upload_entities()
|
||||||
-- -- local x, y, r =
|
-- -- local x, y, r =
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
local drop_gold = false
|
local death_triggers = {}
|
||||||
for _, com in ipairs(EntityGetComponent(enemy_id, "LuaComponent") or {}) do
|
for _, com in ipairs(EntityGetComponent(enemy_id, "LuaComponent") or {}) do
|
||||||
if ComponentGetValue2(com, "script_death") == "data/scripts/items/drop_money.lua" then
|
local script = ComponentGetValue2(com, "script_death")
|
||||||
drop_gold = true
|
if script ~= nil and script ~= "" then
|
||||||
|
table.insert(death_triggers, constants.interned_filename_to_index[script] or script)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local en_data
|
local en_data
|
||||||
|
@ -285,7 +282,6 @@ function enemy_sync.host_upload_entities()
|
||||||
vx = vx,
|
vx = vx,
|
||||||
vy = vy,
|
vy = vy,
|
||||||
enabled = EntityGetFirstComponent(enemy_id, "BossHealthBarComponent", "disabled_at_start") ~= nil,
|
enabled = EntityGetFirstComponent(enemy_id, "BossHealthBarComponent", "disabled_at_start") ~= nil,
|
||||||
drop_gold = drop_gold
|
|
||||||
}
|
}
|
||||||
elseif worm ~= nil then
|
elseif worm ~= nil then
|
||||||
local tx, ty = ComponentGetValue2(worm, "mRandomTarget")
|
local tx, ty = ComponentGetValue2(worm, "mRandomTarget")
|
||||||
|
@ -297,14 +293,12 @@ function enemy_sync.host_upload_entities()
|
||||||
vy = vy,
|
vy = vy,
|
||||||
tx = tx,
|
tx = tx,
|
||||||
ty = ty,
|
ty = ty,
|
||||||
drop_gold = drop_gold
|
|
||||||
}
|
}
|
||||||
elseif math.abs(vx) < 0.01 and math.abs(vy) < 0.01 then
|
elseif math.abs(vx) < 0.01 and math.abs(vy) < 0.01 then
|
||||||
en_data = EnemyDataNoMotion {
|
en_data = EnemyDataNoMotion {
|
||||||
enemy_id = enemy_id,
|
enemy_id = enemy_id,
|
||||||
x = x,
|
x = x,
|
||||||
y = y,
|
y = y,
|
||||||
drop_gold = drop_gold
|
|
||||||
}
|
}
|
||||||
elseif EntityGetFirstComponentIncludingDisabled(enemy_id, "AdvancedFishAIComponent") ~= nil then
|
elseif EntityGetFirstComponentIncludingDisabled(enemy_id, "AdvancedFishAIComponent") ~= nil then
|
||||||
en_data = EnemyDataFish {
|
en_data = EnemyDataFish {
|
||||||
|
@ -314,7 +308,6 @@ function enemy_sync.host_upload_entities()
|
||||||
vx = vx,
|
vx = vx,
|
||||||
vy = vy,
|
vy = vy,
|
||||||
r = math.floor((rot % FULL_TURN) / FULL_TURN * 255),
|
r = math.floor((rot % FULL_TURN) / FULL_TURN * 255),
|
||||||
drop_gold = drop_gold
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
en_data = EnemyData {
|
en_data = EnemyData {
|
||||||
|
@ -323,7 +316,6 @@ function enemy_sync.host_upload_entities()
|
||||||
y = y,
|
y = y,
|
||||||
vx = vx,
|
vx = vx,
|
||||||
vy = vy,
|
vy = vy,
|
||||||
drop_gold = drop_gold
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -352,7 +344,7 @@ function enemy_sync.host_upload_entities()
|
||||||
|
|
||||||
local dont_cull = EntityHasTag(enemy_id, "worm") or EntityGetFirstComponent(enemy_id, "BossHealthBarComponent") ~= nil
|
local dont_cull = EntityHasTag(enemy_id, "worm") or EntityGetFirstComponent(enemy_id, "BossHealthBarComponent") ~= nil
|
||||||
|
|
||||||
table.insert(enemy_data_list, {filename, en_data, not_ephemerial, phys_info, phys_info_2, has_wand, effect_data, animation, dont_cull})
|
table.insert(enemy_data_list, {filename, en_data, not_ephemerial, phys_info, phys_info_2, has_wand, effect_data, animation, dont_cull, death_triggers})
|
||||||
::continue::
|
::continue::
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -454,6 +446,7 @@ local function sync_enemy(enemy_info_raw, force_no_cull)
|
||||||
|
|
||||||
local en_data = enemy_info_raw[2]
|
local en_data = enemy_info_raw[2]
|
||||||
local dont_cull = enemy_info_raw[9]
|
local dont_cull = enemy_info_raw[9]
|
||||||
|
local death_triggers = enemy_info_raw[10]
|
||||||
local remote_enemy_id = en_data.enemy_id
|
local remote_enemy_id = en_data.enemy_id
|
||||||
local x, y = en_data.x, en_data.y
|
local x, y = en_data.x, en_data.y
|
||||||
if not force_no_cull and not dont_cull then
|
if not force_no_cull and not dont_cull then
|
||||||
|
@ -617,13 +610,29 @@ local function sync_enemy(enemy_info_raw, force_no_cull)
|
||||||
EntitySetComponentsWithTagEnabled(enemy_id, "enabled_at_start", false)
|
EntitySetComponentsWithTagEnabled(enemy_id, "enabled_at_start", false)
|
||||||
EntitySetComponentsWithTagEnabled(enemy_id, "disabled_at_start", true)
|
EntitySetComponentsWithTagEnabled(enemy_id, "disabled_at_start", true)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
if not en_data.drop_gold then
|
local indexed = {}
|
||||||
for _, com in ipairs(EntityGetComponent(enemy_id, "LuaComponent") or {}) do
|
for _, com in ipairs(EntityGetComponent(enemy_id, "LuaComponent") or {}) do
|
||||||
if ComponentGetValue2(com, "script_death") == "data/scripts/items/drop_money.lua" then
|
local script = ComponentGetValue2(com, "script_death")
|
||||||
|
local has = false
|
||||||
|
for _, inx in ipairs(death_triggers) do
|
||||||
|
local script2 = constants.interned_index_to_filename[inx] or inx
|
||||||
|
if script == script2 then
|
||||||
|
has = true
|
||||||
|
indexed[script] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not has then
|
||||||
ComponentSetValue2(com, "script_death", "")
|
ComponentSetValue2(com, "script_death", "")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
for _, inx in ipairs(death_triggers) do
|
||||||
|
local script = constants.interned_index_to_filename[inx] or inx
|
||||||
|
if indexed[script] == nil then
|
||||||
|
EntityAddComponent(enemy_id, "LuaComponent", { script_death = script,
|
||||||
|
execute_every_n_frame = "-1"})
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local inv = EntityGetFirstComponentIncludingDisabled(enemy_id, "Inventory2Component")
|
local inv = EntityGetFirstComponentIncludingDisabled(enemy_id, "Inventory2Component")
|
||||||
|
|
|
@ -1,299 +0,0 @@
|
||||||
<Entity
|
|
||||||
tags="enemy,mortal,hittable,teleportable_NOT,boss_dragon,homing_target,glue_NOT,necrobot_NOT,polymorphable_NOT" name="$animal_boss_dragon">
|
|
||||||
|
|
||||||
<_Transform
|
|
||||||
position.x="0"
|
|
||||||
position.y="0"
|
|
||||||
rotation="0"
|
|
||||||
scale.x="1"
|
|
||||||
scale.y="1" >
|
|
||||||
</_Transform>
|
|
||||||
|
|
||||||
<BossDragonComponent
|
|
||||||
speed="3"
|
|
||||||
speed_hunt="4"
|
|
||||||
acceleration="0.25"
|
|
||||||
direction_adjust_speed="0.003"
|
|
||||||
direction_adjust_speed_hunt="0.04"
|
|
||||||
tail_gravity="30"
|
|
||||||
part_distance="16"
|
|
||||||
ground_check_offset="8"
|
|
||||||
eat_anim_wait_mult="0.15 "
|
|
||||||
hitbox_radius="9"
|
|
||||||
target_kill_radius="10"
|
|
||||||
target_kill_ragdoll_force="10"
|
|
||||||
hunt_box_radius="256"
|
|
||||||
random_target_box_radius="400"
|
|
||||||
new_hunt_target_check_every="240"
|
|
||||||
new_random_target_check_every="240"
|
|
||||||
ragdoll_filename="data/ragdolls/dragon/filenames.txt"
|
|
||||||
jump_cam_shake="20" >
|
|
||||||
</BossDragonComponent>
|
|
||||||
|
|
||||||
<CellEaterComponent
|
|
||||||
radius="9" >
|
|
||||||
</CellEaterComponent>
|
|
||||||
|
|
||||||
<DamageModelComponent
|
|
||||||
_enabled="1"
|
|
||||||
air_needed="0"
|
|
||||||
falling_damages="0"
|
|
||||||
fire_damage_amount="0"
|
|
||||||
fire_how_much_fire_generates="0"
|
|
||||||
fire_probability_of_ignition="0"
|
|
||||||
hp="120"
|
|
||||||
materials_damage="1"
|
|
||||||
materials_how_much_damage="0.1"
|
|
||||||
materials_that_damage="acid"
|
|
||||||
ragdoll_filenames_file=""
|
|
||||||
ragdoll_offset_y="-6"
|
|
||||||
>
|
|
||||||
<damage_multipliers
|
|
||||||
explosion="0.5"
|
|
||||||
fire="0.5"
|
|
||||||
ice="0.5"
|
|
||||||
electricity="0.3"
|
|
||||||
>
|
|
||||||
</damage_multipliers>
|
|
||||||
</DamageModelComponent>
|
|
||||||
|
|
||||||
<PathFindingGridMarkerComponent
|
|
||||||
marker_offset_y="0"
|
|
||||||
marker_work_flag="16" >
|
|
||||||
</PathFindingGridMarkerComponent>
|
|
||||||
|
|
||||||
<GenomeDataComponent
|
|
||||||
_enabled="1"
|
|
||||||
herd_id="boss_dragon"
|
|
||||||
food_chain_rank="20"
|
|
||||||
is_predator="1" >
|
|
||||||
</GenomeDataComponent>
|
|
||||||
|
|
||||||
<SpriteComponent
|
|
||||||
_enabled="1"
|
|
||||||
alpha="1"
|
|
||||||
image_file="data/enemies_gfx/dragon_head.xml"
|
|
||||||
rect_animation="eat"
|
|
||||||
next_rect_animation="eat"
|
|
||||||
offset_x="17"
|
|
||||||
offset_y="15"
|
|
||||||
update_transform="0"
|
|
||||||
>
|
|
||||||
</SpriteComponent>
|
|
||||||
|
|
||||||
<SpriteComponent
|
|
||||||
_enabled="1"
|
|
||||||
alpha="1"
|
|
||||||
image_file="data/enemies_gfx/dragon_body.xml"
|
|
||||||
rect_animation="eat"
|
|
||||||
next_rect_animation="eat"
|
|
||||||
offset_x="17"
|
|
||||||
offset_y="15"
|
|
||||||
update_transform="0"
|
|
||||||
>
|
|
||||||
</SpriteComponent>
|
|
||||||
|
|
||||||
<SpriteComponent
|
|
||||||
_enabled="1"
|
|
||||||
alpha="1"
|
|
||||||
image_file="data/enemies_gfx/dragon_body.xml"
|
|
||||||
rect_animation="eat"
|
|
||||||
next_rect_animation="eat"
|
|
||||||
offset_x="17"
|
|
||||||
offset_y="15"
|
|
||||||
update_transform="0"
|
|
||||||
>
|
|
||||||
</SpriteComponent>
|
|
||||||
|
|
||||||
<SpriteComponent
|
|
||||||
_enabled="1"
|
|
||||||
alpha="1"
|
|
||||||
image_file="data/enemies_gfx/dragon_body.xml"
|
|
||||||
rect_animation="eat"
|
|
||||||
next_rect_animation="eat"
|
|
||||||
offset_x="17"
|
|
||||||
offset_y="15"
|
|
||||||
update_transform="0"
|
|
||||||
>
|
|
||||||
</SpriteComponent>
|
|
||||||
|
|
||||||
<SpriteComponent
|
|
||||||
_enabled="1"
|
|
||||||
alpha="1"
|
|
||||||
image_file="data/enemies_gfx/dragon_body.xml"
|
|
||||||
rect_animation="eat"
|
|
||||||
next_rect_animation="eat"
|
|
||||||
offset_x="17"
|
|
||||||
offset_y="15"
|
|
||||||
update_transform="0"
|
|
||||||
>
|
|
||||||
</SpriteComponent>
|
|
||||||
|
|
||||||
<SpriteComponent
|
|
||||||
_enabled="1"
|
|
||||||
alpha="1"
|
|
||||||
image_file="data/enemies_gfx/dragon_body.xml"
|
|
||||||
rect_animation="eat"
|
|
||||||
next_rect_animation="eat"
|
|
||||||
offset_x="17"
|
|
||||||
offset_y="15"
|
|
||||||
update_transform="0"
|
|
||||||
>
|
|
||||||
</SpriteComponent>
|
|
||||||
|
|
||||||
<SpriteComponent
|
|
||||||
_enabled="1"
|
|
||||||
alpha="1"
|
|
||||||
image_file="data/enemies_gfx/dragon_body.xml"
|
|
||||||
rect_animation="eat"
|
|
||||||
next_rect_animation="eat"
|
|
||||||
offset_x="17"
|
|
||||||
offset_y="15"
|
|
||||||
update_transform="0"
|
|
||||||
>
|
|
||||||
</SpriteComponent>
|
|
||||||
|
|
||||||
<SpriteComponent
|
|
||||||
_enabled="1"
|
|
||||||
alpha="1"
|
|
||||||
image_file="data/enemies_gfx/dragon_body.xml"
|
|
||||||
rect_animation="eat"
|
|
||||||
next_rect_animation="eat"
|
|
||||||
offset_x="17"
|
|
||||||
offset_y="15"
|
|
||||||
update_transform="0"
|
|
||||||
>
|
|
||||||
</SpriteComponent>
|
|
||||||
|
|
||||||
<SpriteComponent
|
|
||||||
_enabled="1"
|
|
||||||
alpha="1"
|
|
||||||
image_file="data/enemies_gfx/dragon_body.xml"
|
|
||||||
rect_animation="eat"
|
|
||||||
next_rect_animation="eat"
|
|
||||||
offset_x="17"
|
|
||||||
offset_y="15"
|
|
||||||
update_transform="0"
|
|
||||||
>
|
|
||||||
</SpriteComponent>
|
|
||||||
|
|
||||||
<SpriteComponent
|
|
||||||
_enabled="1"
|
|
||||||
alpha="1"
|
|
||||||
image_file="data/enemies_gfx/dragon_body.xml"
|
|
||||||
rect_animation="eat"
|
|
||||||
next_rect_animation="eat"
|
|
||||||
offset_x="17"
|
|
||||||
offset_y="15"
|
|
||||||
update_transform="0"
|
|
||||||
>
|
|
||||||
</SpriteComponent>
|
|
||||||
|
|
||||||
<SpriteComponent
|
|
||||||
_enabled="1"
|
|
||||||
alpha="1"
|
|
||||||
image_file="data/enemies_gfx/dragon_tail.xml"
|
|
||||||
rect_animation="eat"
|
|
||||||
next_rect_animation="eat"
|
|
||||||
next_rect_animation=""
|
|
||||||
offset_x="17"
|
|
||||||
offset_y="15"
|
|
||||||
update_transform="0"
|
|
||||||
>
|
|
||||||
</SpriteComponent>
|
|
||||||
|
|
||||||
<SpriteComponent
|
|
||||||
_tags="health_bar_back,ui,no_hitbox"
|
|
||||||
_enabled="1"
|
|
||||||
alpha="1"
|
|
||||||
has_special_scale="1"
|
|
||||||
image_file="data/ui_gfx/health_slider_back.png"
|
|
||||||
is_text_sprite="0"
|
|
||||||
next_rect_animation=""
|
|
||||||
offset_x="12"
|
|
||||||
offset_y="42"
|
|
||||||
rect_animation=""
|
|
||||||
special_scale_x="1"
|
|
||||||
special_scale_y="1"
|
|
||||||
ui_is_parent="0"
|
|
||||||
update_transform="1"
|
|
||||||
visible="1"
|
|
||||||
emissive="1"
|
|
||||||
never_ragdollify_on_death="1"
|
|
||||||
z_index="-9000" >
|
|
||||||
</SpriteComponent>
|
|
||||||
|
|
||||||
<SpriteComponent
|
|
||||||
_tags="health_bar,ui,no_hitbox"
|
|
||||||
_enabled="1"
|
|
||||||
alpha="1"
|
|
||||||
has_special_scale="1"
|
|
||||||
image_file="data/ui_gfx/health_slider_front.png"
|
|
||||||
is_text_sprite="0"
|
|
||||||
next_rect_animation=""
|
|
||||||
offset_x="11"
|
|
||||||
offset_y="42"
|
|
||||||
rect_animation=""
|
|
||||||
special_scale_x="1"
|
|
||||||
special_scale_y="1"
|
|
||||||
ui_is_parent="0"
|
|
||||||
update_transform="1"
|
|
||||||
visible="1"
|
|
||||||
emissive="1"
|
|
||||||
never_ragdollify_on_death="1"
|
|
||||||
z_index="-9000" >
|
|
||||||
</SpriteComponent>
|
|
||||||
|
|
||||||
<LightComponent
|
|
||||||
_enabled="1"
|
|
||||||
radius="100"
|
|
||||||
r="255"
|
|
||||||
g="149"
|
|
||||||
b="0" >
|
|
||||||
</LightComponent>
|
|
||||||
|
|
||||||
<HealthBarComponent>
|
|
||||||
</HealthBarComponent>
|
|
||||||
|
|
||||||
<MusicEnergyAffectorComponent
|
|
||||||
energy_target="1">
|
|
||||||
</MusicEnergyAffectorComponent>
|
|
||||||
|
|
||||||
<AudioLoopComponent
|
|
||||||
file="data/audio/Desktop/animals.bank"
|
|
||||||
event_name="animals/worm/movement_loop_big"
|
|
||||||
set_speed_parameter="1"
|
|
||||||
auto_play="1">
|
|
||||||
</AudioLoopComponent>
|
|
||||||
|
|
||||||
<Entity>
|
|
||||||
|
|
||||||
<InheritTransformComponent
|
|
||||||
parent_sprite_id="10"
|
|
||||||
>
|
|
||||||
</InheritTransformComponent>
|
|
||||||
|
|
||||||
<LuaComponent
|
|
||||||
script_source_file="data/scripts/projectiles/orb_green_dragon.lua"
|
|
||||||
execute_every_n_frame="80"
|
|
||||||
execute_times="-1"
|
|
||||||
>
|
|
||||||
</LuaComponent>
|
|
||||||
|
|
||||||
<GenomeDataComponent
|
|
||||||
_enabled="1"
|
|
||||||
herd_id="boss_dragon"
|
|
||||||
food_chain_rank="20"
|
|
||||||
is_predator="1" >
|
|
||||||
</GenomeDataComponent>
|
|
||||||
|
|
||||||
|
|
||||||
</Entity>
|
|
||||||
|
|
||||||
<LuaComponent
|
|
||||||
script_death = "data/scripts/animals/boss_dragon_death.lua",
|
|
||||||
execute_every_n_frame = "-1",
|
|
||||||
>
|
|
||||||
</LuaComponent>
|
|
||||||
|
|
||||||
</Entity>
|
|
|
@ -5,7 +5,9 @@ function collision_trigger()
|
||||||
local entity_id = GetUpdatedEntityID()
|
local entity_id = GetUpdatedEntityID()
|
||||||
local pos_x, pos_y = EntityGetTransform( entity_id )
|
local pos_x, pos_y = EntityGetTransform( entity_id )
|
||||||
if GameHasFlagRun("ew_flag_this_is_host") then
|
if GameHasFlagRun("ew_flag_this_is_host") then
|
||||||
EntityLoad( "mods/quant.ew/files/system/patch_dragon_boss/dragon_boss_extra.xml", pos_x, pos_y )
|
local eid = EntityLoad( "data/entities/animals/boss_dragon.xml", pos_x, pos_y )
|
||||||
|
EntityAddComponent(eid, "LuaComponent", { script_death = "data/scripts/animals/boss_dragon_death.lua",
|
||||||
|
execute_every_n_frame = "-1"})
|
||||||
end
|
end
|
||||||
EntityLoad( "data/entities/particles/image_emitters/magical_symbol_fast.xml", pos_x, pos_y )
|
EntityLoad( "data/entities/particles/image_emitters/magical_symbol_fast.xml", pos_x, pos_y )
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue