diff --git a/quant.ew/data/scripts/animals/wand_ghost.lua b/quant.ew/data/scripts/animals/wand_ghost.lua new file mode 100644 index 00000000..0a9dff8c --- /dev/null +++ b/quant.ew/data/scripts/animals/wand_ghost.lua @@ -0,0 +1,35 @@ +if not GameHasFlagRun("ew_flag_this_is_host") then + return +end + +dofile_once("data/scripts/lib/utilities.lua") + +local entity_id = GetUpdatedEntityID() +local pos_x, pos_y = EntityGetTransform( entity_id ) + + + +local entity_pick_up_this_item = EntityLoad( "data/entities/items/wand_level_03.xml", pos_x, pos_y) +local entity_ghost = entity_id +local itempickup = EntityGetFirstComponent( entity_ghost, "ItemPickUpperComponent" ) +if( itempickup ) then + ComponentSetValue2( itempickup, "only_pick_this_entity", entity_pick_up_this_item ) + GamePickUpInventoryItem( entity_ghost, entity_pick_up_this_item, false ) +end + +-- check that we hold the item +local items = GameGetAllInventoryItems( entity_ghost ) +local has_item = false + +if( items ~= nil ) then + for i,v in ipairs(items) do + if( v == entity_pick_up_this_item ) then + has_item = true + end + end +end + +-- if we don't have the item kill us for we are too dangerous to be left alive +if( has_item == false ) then + EntityKill( entity_ghost ) +end \ No newline at end of file diff --git a/quant.ew/files/system/enemy_sync.lua b/quant.ew/files/system/enemy_sync.lua index 7729a8d6..45818103 100644 --- a/quant.ew/files/system/enemy_sync.lua +++ b/quant.ew/files/system/enemy_sync.lua @@ -2,7 +2,7 @@ local util = dofile_once("mods/quant.ew/files/core/util.lua") local ctx = dofile_once("mods/quant.ew/files/core/ctx.lua") local net = dofile_once("mods/quant.ew/files/core/net.lua") local player_fns = dofile_once("mods/quant.ew/files/core/player_fns.lua") -local inventory_helper = dofile_once("mods/quant.ew/files/core/inventory_helper.lua") +local item_sync = dofile_once("mods/quant.ew/files/system/item_sync.lua") local effect_sync = dofile_once("mods/quant.ew/files/system/game_effect_sync/game_effect_sync.lua") local np = require("noitapatcher") @@ -68,8 +68,6 @@ local PhysDataNoMotion = util.make_type({ u8 = {"r"} }) -local wands = {} - local enemy_sync = {} local unsynced_enemys = {} @@ -165,7 +163,7 @@ end local function get_sync_entities(return_all) local entities = {} table_extend_filtered(entities, EntityGetWithTag("enemy"), function (ent) - return not EntityHasTag(ent, "ew_no_enemy_sync") and not EntityHasTag(ent, "wand_ghost") + return not EntityHasTag(ent, "ew_no_enemy_sync") end) table_extend(entities, EntityGetWithTag("ew_enemy_sync_extra")) table_extend(entities, EntityGetWithTag("plague_rat")) @@ -319,20 +317,18 @@ function enemy_sync.host_upload_entities() } end - local has_wand = false + local wand local inv = EntityGetFirstComponentIncludingDisabled(enemy_id, "Inventory2Component") if inv ~= nil then local item = ComponentGetValue2(inv, "mActualActiveItem") if item ~= nil and EntityGetIsAlive(item) then - if wands[enemy_id] == nil then - wands[enemy_id] = inventory_helper.serialize_single_item(item) + if not EntityHasTag(item, "ew_global_item") then + item_sync.make_item_global(item) + else + wand = item_sync.get_global_item_id(item) end - has_wand = true end end - if not has_wand and wands[enemy_id] ~= nil then - table.remove(wands, enemy_id) - end local effect_data = effect_sync.get_sync_data(enemy_id, true) @@ -344,7 +340,7 @@ function enemy_sync.host_upload_entities() 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, death_triggers}) + table.insert(enemy_data_list, {filename, en_data, not_ephemerial, phys_info, phys_info_2, wand, effect_data, animation, dont_cull, death_triggers}) ::continue:: end @@ -478,7 +474,7 @@ local function sync_enemy(enemy_info_raw, force_no_cull) local not_ephemerial = enemy_info_raw[3] local phys_infos = enemy_info_raw[4] local phys_infos_2 = enemy_info_raw[5] - local has_wand = enemy_info_raw[6] + local gid = enemy_info_raw[6] local effects = enemy_info_raw[7] local animation = enemy_info_raw[8] local has_died = filename == nil @@ -641,9 +637,9 @@ local function sync_enemy(enemy_info_raw, force_no_cull) if inv ~= nil then item = ComponentGetValue2(inv, "mActualActiveItem") end - if has_wand and item == nil then - if wands[remote_enemy_id] ~= nil then - local wand = inventory_helper.deserialize_single_item(wands[remote_enemy_id]) + if gid ~= nil and (item == nil or item == 0 or not EntityGetIsAlive(item)) then + local wand = item_sync.find_by_gid(gid) + if wand ~= nil then EntityAddTag(wand, "ew_client_item") local found = false for _, child in ipairs(EntityGetAllChildren(enemy_id) or {}) do @@ -657,6 +653,8 @@ local function sync_enemy(enemy_info_raw, force_no_cull) local inv_quick = EntityCreateNew("inventory_quick") EntityAddChild(enemy_id, inv_quick) EntityAddChild(inv_quick, wand) + end + if EntityGetFirstComponent(enemy_id, "Inventory2Component") == nil then EntityAddComponent2(enemy_id, "Inventory2Component") end EntitySetComponentsWithTagEnabled(wand, "enabled_in_world", false) @@ -664,12 +662,9 @@ local function sync_enemy(enemy_info_raw, force_no_cull) EntitySetComponentsWithTagEnabled(wand, "enabled_in_inventory", false) np.SetActiveHeldEntity(enemy_id, wand, false, false) else - rpc.request_wand(ctx.my_id, remote_enemy_id) + item_sync.rpc.request_send_again(gid) end end - if not has_wand and wands[remote_enemy_id] ~= nil then - table.remove(wands, remote_enemy_id) - end effect_sync.apply_effects(effects, enemy_id, true) @@ -733,25 +728,10 @@ function rpc.handle_death_data(death_data) EntityInflictDamage(enemy_id, 1000000000, "DAMAGE_CURSE", "", "NONE", 0, 0, responsible_entity) -- Just to be sure kill(enemy_id) end - if wands[remote_id] ~= nil then - table.remove(wands, remote_id) - end ::continue:: end end -function rpc.send_wand(peer_id, remote_enemy_id, wand) - if ctx.my_id == peer_id and wand ~= nil then - wands[remote_enemy_id] = wand - end -end - -function rpc.request_wand(peer_id, remote_enemy_id) - if ctx.my_id == ctx.host_id then - rpc.send_wand(peer_id, remote_enemy_id, wands[remote_enemy_id]) - end -end - function rpc.handle_enemy_data(enemy_data) for _, enemy_info_raw in ipairs(enemy_data) do sync_enemy(enemy_info_raw, false) diff --git a/quant.ew/files/system/item_sync.lua b/quant.ew/files/system/item_sync.lua index a141e71d..c0402752 100644 --- a/quant.ew/files/system/item_sync.lua +++ b/quant.ew/files/system/item_sync.lua @@ -223,7 +223,8 @@ function item_sync.on_world_update_host() item_sync.make_item_global(thrown_item) end local picked_item = get_global_ent("ew_picked") - if picked_item ~= nil and EntityHasTag(picked_item, "ew_global_item") then + if picked_item ~= nil and EntityHasTag(picked_item, "ew_global_item") + and EntityHasTag(EntityGetRootEntity(picked_item), "ew_peer") then local gid = item_sync.get_global_item_id(picked_item) item_sync.host_localize_item(gid, ctx.my_id) end @@ -241,7 +242,8 @@ function item_sync.on_world_update_client() end local picked_item = get_global_ent("ew_picked") - if picked_item ~= nil and EntityHasTag(picked_item, "ew_global_item") then + if picked_item ~= nil and EntityHasTag(picked_item, "ew_global_item") + and EntityHasTag(EntityGetRootEntity(picked_item), "ew_peer") then local gid = item_sync.get_global_item_id(picked_item) rpc.item_localize_req(gid) end @@ -434,4 +436,6 @@ ctx.cap.item_sync = { end } +item_sync.rpc = rpc + return item_sync \ No newline at end of file diff --git a/quant.ew/files/system/local_health/local_health.lua b/quant.ew/files/system/local_health/local_health.lua index 513a4dbf..09feb288 100644 --- a/quant.ew/files/system/local_health/local_health.lua +++ b/quant.ew/files/system/local_health/local_health.lua @@ -8,6 +8,7 @@ local inventory_helper = dofile_once("mods/quant.ew/files/core/inventory_helper. local np = require("noitapatcher") local perk_fns = dofile_once("mods/quant.ew/files/core/perk_fns.lua") local nickname = dofile_once("mods/quant.ew/files/system/nickname.lua") +local spectate = dofile_once("mods/quant.ew/files/system/spectate/spectate.lua") local rpc = net.new_rpc_namespace() @@ -392,6 +393,7 @@ ctx.cap.health = { polymorph.switch_entity(ctx.my_player.entity) end reduce_hp() + spectate.disable_throwing(false, ctx.my_player.entity) else polymorph.switch_entity(end_poly_effect(ctx.my_player.entity)) local _, max_hp_new, has_hp = util.get_ent_health(ctx.my_player.entity) diff --git a/quant.ew/files/system/notplayer_ai/notplayer_ai.lua b/quant.ew/files/system/notplayer_ai/notplayer_ai.lua index cec2a083..2623803e 100644 --- a/quant.ew/files/system/notplayer_ai/notplayer_ai.lua +++ b/quant.ew/files/system/notplayer_ai/notplayer_ai.lua @@ -513,10 +513,12 @@ local function init_state() entity = ctx.my_player.entity, control_component = EntityGetFirstComponentIncludingDisabled(ctx.my_player.entity, "ControlsComponent"), inv_component = EntityGetFirstComponentIncludingDisabled(ctx.my_player.entity, "InventoryGuiComponent"), + inv2_component = EntityGetFirstComponentIncludingDisabled(ctx.my_player.entity, "Inventory2Component"), data_component = EntityGetFirstComponentIncludingDisabled(ctx.my_player.entity, "CharacterDataComponent"), damage_model = damage_model, items = items, is_electric_immune = has_electric, + expected_held = nil, bad_potions = get_potions_of_type(bad_mats), good_potions = get_potions_of_type(good_mats), @@ -1090,15 +1092,27 @@ local function hold_something() EntitySetComponentsWithTagEnabled(pity_potion, "enabled_in_inventory", true) end end + + local held = ComponentGetValue2(state.inv2_component, "mActiveItem") + if state.expected_held ~= nil and state.expected_held ~= held then + spectate.nofun = true + spectate.disable_throwing(true, ctx.my_player.entity) + end + if has_water_potion or state.water_potion ~= nil then + state.expected_held = state.water_potions[1] np.SetActiveHeldEntity(state.entity, state.water_potions[1], false, false) if state.water_potion == nil then state.water_potion = state.water_potions[1] changed_held = true end throw_water = target_is_ambrosia + if throw_water then + state.had_potion = true + end bathe = not target_is_ambrosia elseif (has_bad_potion or state.bad_potion ~= nil) and (can_not_tablet or tablet) then + state.expected_held = state.bad_potions[i] if EntityHasTag(state.bad_potions[i], "potion") then state.had_potion = true end @@ -1108,9 +1122,10 @@ local function hold_something() changed_held = true end elseif has_good_potion or state.good_potion ~= nil then - if EntityHasTag(state.bad_potions[i], "potion") then + if EntityHasTag(state.good_potions[1], "potion") then state.had_potion = true end + state.expected_held = state.good_potions[1] np.SetActiveHeldEntity(state.entity, state.good_potions[1], false, false) if state.good_potion == nil then state.good_potion = state.good_potions[1] @@ -1118,6 +1133,7 @@ local function hold_something() end else if state.attack_wand ~= nil then + state.expected_held = state.attack_wand np.SetActiveHeldEntity(state.entity, state.attack_wand, false, false) end end diff --git a/quant.ew/files/system/player_arrows/player_arrows.lua b/quant.ew/files/system/player_arrows/player_arrows.lua index dcec12d9..ede342ec 100644 --- a/quant.ew/files/system/player_arrows/player_arrows.lua +++ b/quant.ew/files/system/player_arrows/player_arrows.lua @@ -101,7 +101,7 @@ function module.on_world_update() if okay_to_display then local is_host = ctx.host_id == player_data.peer_id local is_notplayer = false - if player_data.status and not player_data.status.is_alive then + if EntityHasTag(player_data.entity, "ew_notplayer") then is_notplayer = true end if not is_notplayer and EntityGetIsAlive(player_data.entity) and EntityHasTag(player_data.entity, "polymorphed_player") then diff --git a/quant.ew/files/system/spectate/spectate.lua b/quant.ew/files/system/spectate/spectate.lua index ab688e9b..77ae43a6 100644 --- a/quant.ew/files/system/spectate/spectate.lua +++ b/quant.ew/files/system/spectate/spectate.lua @@ -44,10 +44,15 @@ local function perks_ui(enable) end end +spectate.nofun = false + function spectate.disable_throwing(enable, entity) if entity == nil then entity = cam_target.entity end + if spectate.nofun and not enable and entity == ctx.my_player.entity and EntityHasTag(ctx.my_player.entity, "ew_notplayer") then + return + end local inv for _, child in ipairs(EntityGetAllChildren(entity) or {}) do if EntityGetName(child) == "inventory_quick" then diff --git a/quant.ew/files/system/spell_refresh/append.lua b/quant.ew/files/system/spell_refresh/append.lua new file mode 100644 index 00000000..6f68be55 --- /dev/null +++ b/quant.ew/files/system/spell_refresh/append.lua @@ -0,0 +1,5 @@ +local old = item_pickup +function item_pickup( entity_item, entity_who_picked, name ) + old(entity_item, entity_who_picked, name) + CrossCall("ew_refresh_inventory") +end \ No newline at end of file diff --git a/quant.ew/files/system/spell_refresh/spell_refresh.lua b/quant.ew/files/system/spell_refresh/spell_refresh.lua new file mode 100644 index 00000000..1d205af8 --- /dev/null +++ b/quant.ew/files/system/spell_refresh/spell_refresh.lua @@ -0,0 +1,10 @@ +np.CrossCallAdd("ew_refresh_inventory", function() + local inventory_state = player_fns.serialize_items(ctx.my_player) + if inventory_state ~= nil then + net.send_player_inventory(inventory_state) + end +end) + +ModLuaFileAppend("data/scripts/items/spell_refresh.lua", "mods/quant.ew/files/system/spell_refresh/spell_refresh.lua") + +return {} \ No newline at end of file diff --git a/quant.ew/init.lua b/quant.ew/init.lua index c7530fa8..70e3cb50 100755 --- a/quant.ew/init.lua +++ b/quant.ew/init.lua @@ -123,6 +123,7 @@ local function load_modules() ctx.load_system("tapion") ctx.load_system("world_sync_cuts") ctx.load_system("hamis") + ctx.load_system("spell_refresh") end local function load_extra_modules()