diff --git a/quant.ew/files/core/constants.lua b/quant.ew/files/core/constants.lua index d42b5b76..fc65d49a 100644 --- a/quant.ew/files/core/constants.lua +++ b/quant.ew/files/core/constants.lua @@ -98,7 +98,7 @@ module.phys_sync_allowed = { ["data/entities/buildings/physics_worm_deflector_base.xml"] = true, --["data/entities/buildings/physics_worm_deflector_crystal.xml"] = true, --["data/entities/misc/greed_curse/greed_crystal.xml"] = true, - ["data/entities/props/physics/lantern_small.xml"] = true, + --["data/entities/props/physics/lantern_small.xml"] = true, -- Traps ["data/entities/props/physics_trap_circle_acid.xml"] = true, diff --git a/quant.ew/files/core/inventory_helper.lua b/quant.ew/files/core/inventory_helper.lua index b5411aa8..b7a693de 100644 --- a/quant.ew/files/core/inventory_helper.lua +++ b/quant.ew/files/core/inventory_helper.lua @@ -213,22 +213,31 @@ function inventory_helper.get_item_data(player_data, fresh) if(entity_is_wand(item))then table.insert(wandData, - { - data = inventory_helper.serialize_single_item(item), - slot_x = slot_x, - slot_y = slot_y, - active = (mActiveItem == item), - is_wand = true, - old_id = item - }) - else + { + data = inventory_helper.serialize_single_item(item), + slot_x = slot_x, + slot_y = slot_y, + active = (mActiveItem == item), + is_wand = true, + old_id = item + }) + elseif not EntityHasTag(item, "polymorphed_player") then table.insert(wandData, - { - data = inventory_helper.serialize_single_item(item), - slot_x = slot_x, - slot_y = slot_y, - active = (mActiveItem == item) - }) + { + data = inventory_helper.serialize_single_item(item), + slot_x = slot_x, + slot_y = slot_y, + active = (mActiveItem == item) + }) + else + local peer_id = player_fns.get_player_data_by_local_entity_id(item).peer_id + table.insert(wandData, + { + peer_id = peer_id, + slot_x = slot_x, + slot_y = slot_y, + active = (mActiveItem == item) + }) end end @@ -315,9 +324,12 @@ function inventory_helper.set_item_data(item_data, player_data) local inv = EntityGetAllChildren(child) if inv ~= nil then for _, item in pairs(inv) do - EntityKill(item) + if not EntityHasTag(item, "polymorphed_player") then + EntityKill(item) + end end end + break end end @@ -333,6 +345,8 @@ function inventory_helper.set_item_data(item_data, player_data) item = inventory_helper.deserialize_single_item(itemInfo.data) remove_non_send(item) item = EZWand(item) + elseif itemInfo.peer_id ~= nil then + item = ctx.players[itemInfo.peer_id].entity else item = inventory_helper.deserialize_single_item(itemInfo.data) remove_non_send(item) @@ -345,25 +359,22 @@ function inventory_helper.set_item_data(item_data, player_data) if(itemInfo.is_wand)then EntityAddTag(item.entity_id, "ew_client_item") item:PickUp(player) - local itemComp = EntityGetFirstComponentIncludingDisabled(item.entity_id, "ItemComponent") - if (itemComp ~= nil) then - ComponentSetValue2(itemComp, "inventory_slot", itemInfo.slot_x, itemInfo.slot_y) - end item_entity = item.entity_id - if (itemInfo.active) then - active_item_entity = item.entity_id - end + elseif itemInfo.peer_id ~= nil then + pickup_item(player, item) + item_entity = item + np.SetActiveHeldEntity(player, item, false, false) else EntityAddTag(item, "ew_client_item") pickup_item(player, item) - local itemComp = EntityGetFirstComponentIncludingDisabled(item, "ItemComponent") - if (itemComp ~= nil) then - ComponentSetValue2(itemComp, "inventory_slot", itemInfo.slot_x, itemInfo.slot_y) - end item_entity = item - if (itemInfo.active) then - active_item_entity = item - end + end + local itemComp = EntityGetFirstComponentIncludingDisabled(item_entity, "ItemComponent") + if (itemComp ~= nil) then + ComponentSetValue2(itemComp, "inventory_slot", itemInfo.slot_x, itemInfo.slot_y) + end + if (itemInfo.active) then + active_item_entity = item_entity end --print("Deserialized wand #"..tostring(k).." - Active? "..tostring(wandInfo.active)) diff --git a/quant.ew/files/core/player_fns.lua b/quant.ew/files/core/player_fns.lua index b5694b87..0c9352c8 100644 --- a/quant.ew/files/core/player_fns.lua +++ b/quant.ew/files/core/player_fns.lua @@ -389,6 +389,28 @@ local player_fns = { end, } +local PhysData = util.make_type({ + f32 = {"x", "y", "vx", "vy", "vr", "r"} +}) + +local function deserialize_phys_component(phys_component, phys_info) + local x, y = GamePosToPhysicsPos(phys_info.x, phys_info.y) + np.PhysBodySetTransform(phys_component, x, y, phys_info.r, phys_info.vx, phys_info.vy, phys_info.vr) +end + +local function serialize_phys_component(phys_component) + local px, py, pr, pvx, pvy, pvr = np.PhysBodyGetTransform(phys_component) + px, py = PhysicsPosToGamePos(px, py) + return PhysData { + x = px, + y = py, + r = pr, + vx = pvx, + vy = pvy, + vr = pvr, + } +end + function player_fns.serialize_position(player_data) local entity = player_data.entity if not EntityGetIsAlive(entity) then @@ -406,6 +428,26 @@ function player_fns.serialize_position(player_data) player_data.pos_x = x player_data.pos_y = y + local phys_info = {} + local phys_info_2 = {} + for _, phys_component in ipairs(EntityGetComponent(entity, "PhysicsBodyComponent") or {}) do + if phys_component ~= nil and phys_component ~= 0 then + local _, info = pcall(serialize_phys_component, phys_component) + table.insert(phys_info, info) + end + end + + for _, phys_component in ipairs(EntityGetComponent(entity, "PhysicsBody2Component") or {}) do + if phys_component ~= nil and phys_component ~= 0 then + local initialized = ComponentGetValue2(phys_component, "mInitialized") + if initialized then + local _, info = pcall(serialize_phys_component, phys_component) + table.insert(phys_info_2, info) + else + table.insert(phys_info_2, nil) + end + end + end local c = CharacterPos{ frames_in_air = ComponentGetValue2(character_platforming_comp, "mFramesInAirCounter"), x = x, @@ -415,10 +457,10 @@ function player_fns.serialize_position(player_data) is_on_ground = ComponentGetValue2(character_data, "is_on_ground"), is_on_slippery_ground = ComponentGetValue2(character_data, "is_on_slippery_ground"), } - return c + return c, phys_info, phys_info_2 end -function player_fns.deserialize_position(message, player_data) +function player_fns.deserialize_position(message, phys_infos, phys_infos_2, player_data) player_data.pos_x = message.x player_data.pos_y = message.y @@ -444,6 +486,22 @@ function player_fns.deserialize_position(message, player_data) ComponentSetValue2(character_data, "mVelocity", message.vel_x, message.vel_y) EntityApplyTransform(entity, message.x, message.y) + for i, phys_component in ipairs(EntityGetComponent(entity, "PhysicsBodyComponent") or {}) do + local phys_info = phys_infos[i] + if phys_component ~= nil and phys_component ~= 0 and phys_info ~= nil then + deserialize_phys_component(phys_component, phys_info) + end + end + for i, phys_component in ipairs(EntityGetComponent(entity, "PhysicsBody2Component") or {}) do + local phys_info = phys_infos_2[i] + if phys_component ~= nil and phys_component ~= 0 and phys_info ~= nil then + -- A physics body doesn't exist otherwise, causing a crash + local initialized = ComponentGetValue2(phys_component, "mInitialized") + if initialized then + deserialize_phys_component(phys_component, phys_info) + end + end + end end diff --git a/quant.ew/files/system/item_sync.lua b/quant.ew/files/system/item_sync.lua index d4d85138..8d13e05a 100644 --- a/quant.ew/files/system/item_sync.lua +++ b/quant.ew/files/system/item_sync.lua @@ -27,7 +27,9 @@ end local function mark_in_inventory(my_player) local items = inventory_helper.get_all_inventory_items(my_player) for _, ent in pairs(items) do - item_sync.ensure_notify_component(ent) + if not EntityHasTag(ent, "polymorphed_player") then + item_sync.ensure_notify_component(ent) + end end end @@ -103,6 +105,7 @@ function item_sync.remove_item_with_id_now(gid) end end EntityKill(item) + break end end end @@ -267,12 +270,7 @@ function item_sync.on_world_update() end if GameGetFrameNum() % 5 == 2 then for _, ent in ipairs(EntityGetWithTag("mimic_potion")) do - if EntityHasTag(ent, "polymorphed_player") then - local com = EntityGetFirstComponentIncludingDisabled(ent, "ItemComponent") - if com ~= nil then - EntityRemoveComponent(ent, com) - end - elseif ctx.is_host then + if ctx.is_host and not EntityHasTag(ent, "polymorphed_player") then if not EntityHasTag(ent, "ew_global_item") then item_sync.make_item_global(ent) end diff --git a/quant.ew/files/system/perk_patches/append/perks_common.lua b/quant.ew/files/system/perk_patches/append/perks_common.lua index 03c0e03f..ae3da32d 100644 --- a/quant.ew/files/system/perk_patches/append/perks_common.lua +++ b/quant.ew/files/system/perk_patches/append/perks_common.lua @@ -7,7 +7,7 @@ local function patch_perk_2(perk_id, fn) end local function hide_perk(perk_id) - print("Hiding perk", perk_id) + --print("Hiding perk", perk_id) local perk_data = get_perk_with_id(perk_list, perk_id) perk_data.not_in_default_perk_pool = true end diff --git a/quant.ew/files/system/perk_patches/perk_patches.lua b/quant.ew/files/system/perk_patches/perk_patches.lua index 1254dd19..645370ac 100644 --- a/quant.ew/files/system/perk_patches/perk_patches.lua +++ b/quant.ew/files/system/perk_patches/perk_patches.lua @@ -21,7 +21,7 @@ else end if not ctx.is_host or not ctx.proxy_opt.randomize_perks then - print("Hiding telekinesis") + --print("Hiding telekinesis") ModLuaFileAppend("data/scripts/perks/perk_list.lua", "mods/quant.ew/files/system/perk_patches/append/perks_no_telekinesis.lua") end diff --git a/quant.ew/files/system/player_sync.lua b/quant.ew/files/system/player_sync.lua index 00531316..6ed73d4c 100644 --- a/quant.ew/files/system/player_sync.lua +++ b/quant.ew/files/system/player_sync.lua @@ -18,7 +18,7 @@ function rpc.send_money_and_ingestion(money, ingestion_size) end end -function rpc.player_update(input_data, pos_data, current_slot, team) +function rpc.player_update(input_data, pos_data, phys_info, phys_info_2, current_slot, team) local peer_id = ctx.rpc_peer_id if not player_fns.peer_has_player(peer_id) then @@ -40,7 +40,7 @@ function rpc.player_update(input_data, pos_data, current_slot, team) player_fns.deserialize_inputs(input_data, player_data) end if pos_data ~= nil then - player_fns.deserialize_position(pos_data, player_data) + player_fns.deserialize_position(pos_data, phys_info, phys_info_2, player_data) end if current_slot ~= nil then player_fns.set_current_slot(current_slot, player_data) @@ -65,7 +65,7 @@ end function module.on_world_update() local input_data = player_fns.serialize_inputs(ctx.my_player) - local pos_data = player_fns.serialize_position(ctx.my_player) + local pos_data, phys_info, phys_info_2 = player_fns.serialize_position(ctx.my_player) local current_slot = player_fns.get_current_slot(ctx.my_player) if input_data ~= nil or pos_data ~= nil then local my_team @@ -73,7 +73,7 @@ function module.on_world_update() my_team = ctx.proxy_opt.friendly_fire_team - 1 end - rpc.player_update(input_data, pos_data, current_slot, my_team) + rpc.player_update(input_data, pos_data, phys_info, phys_info_2, current_slot, my_team) if GameGetFrameNum() % 120 == 0 then local n = np.GetGameModeNr() rpc.check_gamemode(np.GetGameModeName(n)) diff --git a/quant.ew/files/system/polymorph/polymorph.lua b/quant.ew/files/system/polymorph/polymorph.lua index 3032a5ec..fac4f293 100644 --- a/quant.ew/files/system/polymorph/polymorph.lua +++ b/quant.ew/files/system/polymorph/polymorph.lua @@ -88,6 +88,31 @@ end function module.on_world_update_post() local ent = np.GetPlayerEntity() if ent ~= nil and ent ~= ctx.my_player.entity then + if EntityHasTag(ent, "mimic_potion") then + local effect + for _, child in ipairs(EntityGetAllChildren(ctx.my_player.entity) or {}) do + local com = EntityGetFirstComponentIncludingDisabled(child, "GameEffectComponent") + if com ~= nil then + local effect_name = ComponentGetValue2(com, "effect") + if effect_name == "POLYMORPH" or effect_name == "POLYMORPH_RANDOM" + or effect_name == "POLYMORPH_CESSATION" or effect_name == "POLYMORPH_UNSTABLE" then + effect = com + break + end + end + end + if effect ~= nil then + local frames = ComponentGetValue2(effect, "frames") + if frames < 1000 and frames > 0 then + ComponentSetValue2(effect, "frames", 1000) + end + end + + EntityAddComponent2(ent, "LuaComponent", { + script_item_picked_up = "mods/quant.ew/files/system/potion_mimic/pickup.lua", + script_throw_item = "mods/quant.ew/files/system/potion_mimic/pickup.lua", + }) + end module.switch_entity(ent) if ctx.proxy_opt.game_mode == "local_health" then util.ensure_component_present(ent, "LuaComponent", "ew_player_damage", { diff --git a/quant.ew/files/system/potion_mimic/pickup.lua b/quant.ew/files/system/potion_mimic/pickup.lua new file mode 100644 index 00000000..2cf4f635 --- /dev/null +++ b/quant.ew/files/system/potion_mimic/pickup.lua @@ -0,0 +1,7 @@ +function throw_item() + CrossCall("ew_potion_mimic_throw", GetUpdatedEntityID()) +end + +function item_pickup() + CrossCall("ew_potion_mimic_pickup") +end \ No newline at end of file diff --git a/quant.ew/files/system/potion_mimic/poly.xml b/quant.ew/files/system/potion_mimic/poly.xml new file mode 100644 index 00000000..8f1dae01 --- /dev/null +++ b/quant.ew/files/system/potion_mimic/poly.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/quant.ew/files/system/potion_mimic/potion_mimic.lua b/quant.ew/files/system/potion_mimic/potion_mimic.lua new file mode 100644 index 00000000..ddae7f8b --- /dev/null +++ b/quant.ew/files/system/potion_mimic/potion_mimic.lua @@ -0,0 +1,51 @@ +local rpc = net.new_rpc_namespace() +local potion = {} + +function rpc.got_thrown(peer_id) + local item = ctx.players[peer_id].entity + for _, com in ipairs(EntityGetAllComponents(item) or {}) do + EntitySetComponentIsEnabled(item, com, true) + end + EntitySetComponentIsEnabled(item, EntityGetFirstComponentIncludingDisabled(item, "SpriteComponent", "enable_in_hand"), false) + EntitySetComponentIsEnabled(item, EntityGetFirstComponentIncludingDisabled(item, "ItemChestComponent"), false) + EntitySetComponentIsEnabled(item, EntityGetFirstComponentIncludingDisabled(item, "ItemComponent"), false) + if EntityGetParent(item) ~= 0 then + EntityRemoveFromParent(item) + end +end + +np.CrossCallAdd("ew_potion_mimic_throw", function(item) + rpc.got_thrown(player_fns.get_player_data_by_local_entity_id(item).peer_id) +end) + +np.CrossCallAdd("ew_potion_mimic_pickup", function() + local inventory_state = player_fns.serialize_items(ctx.my_player) + if inventory_state ~= nil then + net.send_player_inventory(inventory_state) + end +end) + +function potion.on_world_update() + if EntityHasTag(ctx.my_player.entity, "mimic_potion") then + local effect + for _, child in ipairs(EntityGetAllChildren(ctx.my_player.entity) or {}) do + local com = EntityGetFirstComponentIncludingDisabled(child, "GameEffectComponent") + if com ~= nil then + local effect_name = ComponentGetValue2(com, "effect") + if effect_name == "POLYMORPH" or effect_name == "POLYMORPH_RANDOM" + or effect_name == "POLYMORPH_CESSATION" or effect_name == "POLYMORPH_UNSTABLE" then + effect = com + break + end + end + end + if effect ~= nil then + EntitySetComponentIsEnabled(ctx.my_player.entity, effect, EntityGetParent(ctx.my_player.entity) == 0) + end + end + --if InputIsKeyJustDown(16) then --when "m" is pressed + -- LoadGameEffectEntityTo(ctx.my_player.entity, "mods/quant.ew/files/system/potion_mimic/poly.xml") + --end +end + +return potion \ No newline at end of file diff --git a/quant.ew/init.lua b/quant.ew/init.lua index 714e5eb4..0c25bdcd 100755 --- a/quant.ew/init.lua +++ b/quant.ew/init.lua @@ -125,6 +125,7 @@ local function load_modules() ctx.load_system("hamis") ctx.load_system("spell_refresh") ctx.load_system("shiny_orb") + ctx.load_system("potion_mimic") end local function load_extra_modules()