From 4d9035b66342d7dcffb54cc6b9d7e0d525fc998c Mon Sep 17 00:00:00 2001 From: RabbyDevs Date: Tue, 13 May 2025 20:49:57 +0300 Subject: [PATCH] automatic concomitants and buffs, watermark is now editable, and some fixes? --- wicked-waifus-data/src/buff.rs | 12 + wicked-waifus-data/src/lib.rs | 12 +- .../scripts/watermask-disable.js | 1 - .../scripts/watermask-edit.js | 41 +++ .../src/logic/ecs/buf.rs | 92 +++--- .../src/logic/ecs/world.rs | 20 +- .../src/logic/handler/role.rs | 62 ++-- .../src/logic/handler/scene.rs | 3 +- .../src/logic/player/mod.rs | 27 +- .../src/logic/role/formation.rs | 4 +- .../src/logic/utils/mod.rs | 2 +- .../src/logic/utils/world_util.rs | 264 ++++++++++-------- 12 files changed, 309 insertions(+), 231 deletions(-) create mode 100644 wicked-waifus-data/src/buff.rs delete mode 100644 wicked-waifus-game-server/scripts/watermask-disable.js create mode 100644 wicked-waifus-game-server/scripts/watermask-edit.js diff --git a/wicked-waifus-data/src/buff.rs b/wicked-waifus-data/src/buff.rs new file mode 100644 index 0000000..e06830e --- /dev/null +++ b/wicked-waifus-data/src/buff.rs @@ -0,0 +1,12 @@ +use serde::Deserialize; + +#[derive(Deserialize)] +#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))] +#[serde(rename_all = "PascalCase")] +pub struct BuffData { + pub id: i64, + pub ge_desc: String, + pub duration_policy: i32, + pub extra_effect_parameters: Option>, + pub game_attribute_i_d: i32 +} \ No newline at end of file diff --git a/wicked-waifus-data/src/lib.rs b/wicked-waifus-data/src/lib.rs index fbb4fb6..c47505b 100644 --- a/wicked-waifus-data/src/lib.rs +++ b/wicked-waifus-data/src/lib.rs @@ -168,8 +168,8 @@ json_hash_table_data! { DropPackage, id, i32; TemplateConfig, blueprint_type, String; SummonCfg, blueprint_type, String; + Buff, id, i64; } - mod level_entity_config; pub mod level_entity_config_data { @@ -184,7 +184,10 @@ pub mod level_entity_config_data { } pub fn get(map_id: i32, entity_id: i64) -> Option<&'static Data> { - TABLE.get().unwrap().get(&create_key_internal(map_id, entity_id)) + TABLE + .get() + .unwrap() + .get(&create_key_internal(map_id, entity_id)) } #[inline(always)] @@ -207,10 +210,9 @@ fn load_json_entity_level_config_data(base_path: &str) -> Result<(), LoadDataErr serde_json::from_reader::, Vec>(reader)? .into_iter() .map(|element| (level_entity_config_data::create_key(&element), element)) - .collect::>() + .collect::>(), ); tracing::info!("Loading data finished: {path}"); - Ok(()) -} \ No newline at end of file +} diff --git a/wicked-waifus-game-server/scripts/watermask-disable.js b/wicked-waifus-game-server/scripts/watermask-disable.js deleted file mode 100644 index ff996f2..0000000 --- a/wicked-waifus-game-server/scripts/watermask-disable.js +++ /dev/null @@ -1 +0,0 @@ -require('../Module/WaterMask/WaterMaskController').WaterMaskView.EOo(); \ No newline at end of file diff --git a/wicked-waifus-game-server/scripts/watermask-edit.js b/wicked-waifus-game-server/scripts/watermask-edit.js new file mode 100644 index 0000000..d255330 --- /dev/null +++ b/wicked-waifus-game-server/scripts/watermask-edit.js @@ -0,0 +1,41 @@ +const UE = require("ue"), + Info_1 = require("../../../Core/Common/Info"), + MathUtils_1 = require("../../../Core/Utils/MathUtils"), + EventDefine_1 = require("../../Common/Event/EventDefine"), + EventSystem_1 = require("../../Common/Event/EventSystem"), + UiControllerBase_1 = require("../../Ui/Base/UiControllerBase"), + UiLayerType_1 = require("../../Ui/Define/UiLayerType"), + UiLayer_1 = require("../../Ui/UiLayer"); + +var _a = require('../Module/WaterMask/WaterMaskController').WaterMaskView; +_a.LOo = 0.18; +_a.yOo = 700; +_a.IOo = 700; +_a.vOo = function () { + void 0 !== _a.SOo && _a.EOo(); + var e = UiLayer_1.UiLayer.GetLayerRootUiItem(UiLayerType_1.ELayerType.WaterMask), + t = (_a.SOo = UE.KuroActorManager.SpawnActor(Info_1.Info.World, UE.UIContainerActor.StaticClass(), + MathUtils_1.MathUtils.DefaultTransform, void 0), _a.SOo.RootComponent), + e = (t.SetDisplayName("WaterMaskContainer"), UE.KuroStaticLibrary.SetActorPermanent(_a.SOo, !0, !0), _a.SOo + .K2_AttachRootComponentTo(e), t.GetRootCanvas().GetOwner().RootComponent), + i = e.widget.width % _a.yOo / 2, + r = e.widget.height % _a.IOo / 2, + n = e.widget.width / 2, + _ = e.widget.height / 2, + s = Math.ceil(e.widget.width / _a.yOo), + o = Math.ceil(e.widget.height / _a.IOo), + v = " "; // EDIT ME! + for (let a = 0; a < s; a++) + for (let e = 0; e < o; e++) { + var E = UE.KuroActorManager.SpawnActor(Info_1.Info.World, UE.UITextActor.StaticClass(), MathUtils_1 + .MathUtils.DefaultTransform, void 0), + U = E.RootComponent, + U = (E.K2_AttachRootComponentTo(t), U.SetDisplayName("WaterMaskText"), E.GetComponentByClass(UE + .UIText.StaticClass())); + U.SetFontSize(_a.vFt), U.SetOverflowType(0), U.SetAlpha(_a.LOo), U.SetFont(UE.LGUIFontData + .GetDefaultFont()), U.SetText(v), U.SetUIRelativeLocation(new UE.Vector(a * _a.yOo - n + i, e * + _a.IOo - _ + r, 0)), U.SetUIRelativeRotation(new UE.Rotator(0, _a.TOo, 0)), UE.KuroStaticLibrary + .SetActorPermanent(E, !0, !0) + } +}; +_a.vOo(); \ No newline at end of file diff --git a/wicked-waifus-game-server/src/logic/ecs/buf.rs b/wicked-waifus-game-server/src/logic/ecs/buf.rs index 1a12747..98bd1df 100644 --- a/wicked-waifus-game-server/src/logic/ecs/buf.rs +++ b/wicked-waifus-game-server/src/logic/ecs/buf.rs @@ -8,17 +8,34 @@ pub struct BufManager { recycled_handles: HashMap>, } -impl BufManager { - const PERMANENT_ROLE_BUFFS: &'static [i64] = &[ - 3003, // Remove wall run prohibition - 3004, // Remove gliding prohibition - 1213, // Reduce stamina while flying - 1214, // Reduce stamina while flying in sprint - 1215, // Reduce stamina while flying up in sprint - 1216, // Reduce stamina while flying down in sprint - 640012051, // Allow flying -> tag: 1151923109 - ]; +const OVERRIDE_BUFFS: &[i64] = &[ + 3003, // Remove wall run prohibition + 3004, // Remove gliding prohibition + 1213, // Reduce stamina while flying + 1214, // Reduce stamina while flying in sprint + 1215, // Reduce stamina while flying up in sprint + 1216, // Reduce stamina while flying down in sprint + 640012051, // Allow flying -> tag: 1151923109 +]; +const ROLE_OVERRIDES: &[(i32, &[i64])] = &[ + (1407, &[ + // ciaconna's forte buffs are completely fucked to get from an algorithm and i hate kuro! + 1407900003, + 1407500040, + ]), +]; + +fn get_role_buff_overrides(role_id: i32) -> Option<&'static [i64]> { + for &(role, buff) in ROLE_OVERRIDES { + if role == role_id { + return Some(buff); + } + } + None +} + +impl BufManager { pub fn create(&mut self, buf: &mut FightBuffInformation) { let handle = self .recycled_handles @@ -35,7 +52,9 @@ impl BufManager { #[inline(always)] pub fn remove_entity_buffs(&mut self, entity_id: i64) { - let handles = self.active_buf_set.iter() + let handles = self + .active_buf_set + .iter() .filter(|(_, buff)| buff.entity_id == entity_id) .map(|(&handle, _)| handle) .collect::>(); @@ -57,38 +76,33 @@ impl BufManager { } } - pub fn create_permanent_buffs(&mut self, origin_id: i64) -> Vec { - Self::PERMANENT_ROLE_BUFFS - .iter() - .map(|&id| { - let mut buff = FightBuffInformation { - handle_id: 0, - buff_id: id, - level: 1, - stack_count: 1, - instigator_id: origin_id, - entity_id: origin_id, - apply_type: 0, - duration: -1f32, - left_duration: -1f32, - context: vec![], - is_active: true, - server_id: 0, - message_id: 0, - }; - self.create(&mut buff); - buff - }) - .collect::>() - } + pub fn create_permanent_buffs(&mut self, origin_id: i64, role_id: i32) -> Vec { + let mut buffs = wicked_waifus_data::buff_data::iter().filter(|(id, buf)| { + id.to_string().starts_with(&role_id.to_string()) // must be part of char kit :) + && + ( + !id.to_string().contains("666")// KURO IS EVIL + && + buf.duration_policy == 1 + ) + // && + // !buf.ge_desc.contains("【废弃】") // remove "deprecated" buffs + }) + .map(|x| *x.0) + .collect::>(); - pub fn create_concom_buffs(&mut self, buff_ids: Vec, origin_id: i64) -> Vec { - buff_ids + buffs.extend(OVERRIDE_BUFFS.iter().copied()); + if let Some(role_buff_overrides) = get_role_buff_overrides(role_id) { + buffs.extend(role_buff_overrides.iter().copied()); + } + buffs.dedup(); + + buffs .iter() - .map(|&id| { + .map(|id| { let mut buff = FightBuffInformation { handle_id: 0, - buff_id: id, + buff_id: *id, level: 1, stack_count: 1, instigator_id: origin_id, diff --git a/wicked-waifus-game-server/src/logic/ecs/world.rs b/wicked-waifus-game-server/src/logic/ecs/world.rs index 91ec5cc..453ffed 100644 --- a/wicked-waifus-game-server/src/logic/ecs/world.rs +++ b/wicked-waifus-game-server/src/logic/ecs/world.rs @@ -7,6 +7,7 @@ use std::collections::hash_map::{Keys, Values}; use std::collections::HashMap; use wicked_waifus_protocol::FightBuffInformation; +#[derive(Default)] pub struct WorldEntity { components: HashMap>>, entity_manager: EntityManager, @@ -111,22 +112,7 @@ impl WorldEntity { self.entity_manager.active_entity_empty() } - pub fn generate_role_permanent_buffs(&mut self, entity_id: i64) -> Vec { - self.buff_manager.create_permanent_buffs(entity_id) - } - - pub fn generate_concom_buffs(&mut self, buff_ids: Vec, entity_id: i64) -> Vec { - tracing::debug!("{:#?}", buff_ids); - self.buff_manager.create_concom_buffs(buff_ids, entity_id) - } -} - -impl Default for WorldEntity { - fn default() -> Self { - Self { - components: HashMap::new(), - entity_manager: EntityManager::default(), - buff_manager: BufManager::default(), - } + pub fn generate_role_permanent_buffs(&mut self, entity_id: i32, role_id: i32) -> Vec { + self.buff_manager.create_permanent_buffs(entity_id as i64, role_id) } } diff --git a/wicked-waifus-game-server/src/logic/handler/role.rs b/wicked-waifus-game-server/src/logic/handler/role.rs index f17cf8a..2b45f09 100644 --- a/wicked-waifus-game-server/src/logic/handler/role.rs +++ b/wicked-waifus-game-server/src/logic/handler/role.rs @@ -81,41 +81,41 @@ pub fn on_update_formation_request( } if let Some(old_formation) = player.formation_list.get(&real_formation_id) { - let removed_entities: Vec = old_formation + let removed_entities: Vec = old_formation + .role_ids + .iter() + .map(|&role_id| world.get_entity_id(role_id)) + .collect(); + removed_entities.iter().for_each(|&entity_id| { + world.remove_entity(entity_id as i32); + }); + player.notify(player.build_player_entity_remove_notify( + removed_entities, + ERemoveEntityType::RemoveTypeNormal, + )); + } + + let added_roles: Vec = formation .role_ids .iter() - .map(|&role_id| world.get_entity_id(role_id)) + .map(|&role_id| Role::new(role_id)) .collect(); - removed_entities.iter().for_each(|&entity_id| { - world.remove_entity(entity_id as i32); - }); - player.notify(player.build_player_entity_remove_notify( - removed_entities, - ERemoveEntityType::RemoveTypeNormal, + + if !added_roles.is_empty() { + // add new roles + player.notify(player.build_player_entity_add_notify(added_roles, world)); + } + + // send update group formation notify + player.notify(player.build_update_group_formation_notify( + RoleFormation { + id: formation_id, + cur_role, + role_ids: formation.role_ids.clone(), + is_current, + }, + world, )); - } - - let added_roles: Vec = formation - .role_ids - .iter() - .map(|&role_id| Role::new(role_id)) - .collect(); - - if !added_roles.is_empty() { - // add new roles - player.notify(player.build_player_entity_add_notify(added_roles)); - } - - // send update group formation notify - player.notify(player.build_update_group_formation_notify( - RoleFormation { - id: formation_id, - cur_role, - role_ids: formation.role_ids.clone(), - is_current, - }, - world, - )); response.formation = Some(formation.clone()); } diff --git a/wicked-waifus-game-server/src/logic/handler/scene.rs b/wicked-waifus-game-server/src/logic/handler/scene.rs index 5f9b195..88d2ce1 100644 --- a/wicked-waifus-game-server/src/logic/handler/scene.rs +++ b/wicked-waifus-game-server/src/logic/handler/scene.rs @@ -1,6 +1,7 @@ use wicked_waifus_protocol::{ErrorCode, SceneLoadingFinishRequest, SceneLoadingFinishResponse, SceneTraceRequest, SceneTraceResponse, UpdateSceneDateRequest, UpdateSceneDateResponse, AccessPathTimeServerConfigRequest, AccessPathTimeServerConfigResponse, PlayerHeadDataRequest, PlayerHeadDataResponse, UnlockRoleSkinListRequest, UnlockRoleSkinListResponse, JsPatchNotify}; -const WATER_MASK: &str = include_str!("../../../scripts/watermask-disable.js"); +//const WATER_MASK: &str = include_str!("../../../scripts/watermask-disable.js"); +const WATER_MASK: &str = include_str!("../../../scripts/watermask-edit.js"); const UID_FIX: &str = include_str!("../../../scripts/uidfix.js"); const CENSORSHIP_FIX: &str = include_str!("../../../scripts/censorshipfix.js"); const DEBUG_DISABLE: &str = include_str!("../../../scripts/debug_disable.js"); diff --git a/wicked-waifus-game-server/src/logic/player/mod.rs b/wicked-waifus-game-server/src/logic/player/mod.rs index 02b0c0c..27164dd 100644 --- a/wicked-waifus-game-server/src/logic/player/mod.rs +++ b/wicked-waifus-game-server/src/logic/player/mod.rs @@ -263,7 +263,7 @@ impl Player { } if !rf.role_ids.contains(&rf.cur_role) { - rf.cur_role = *rf.role_ids.iter().nth(0).unwrap(); + rf.cur_role = *rf.role_ids.first().unwrap(); } } } @@ -304,9 +304,7 @@ impl Player { pub fn build_role_favor_list_notify(&self) -> RoleFavorListNotify { RoleFavorListNotify { favor_list: self - .role_list - .iter() - .map(|(_, role)| RoleFavor { + .role_list.values().map(|role| RoleFavor { role_id: role.role_id, level: role.favor_level, exp: role.favor_exp, @@ -341,9 +339,7 @@ impl Player { pub fn build_motion_list_notify(&self) -> RoleMotionListNotify { RoleMotionListNotify { motion_list: self - .role_list - .iter() - .map(|(_, role)| { + .role_list.values().map(|role| { RoleMotion { role_id: role.role_id, motion_ids: motion_data::iter() @@ -362,14 +358,15 @@ impl Player { } } - pub fn build_player_entity_add_notify(&self, role_list: Vec) -> EntityAddNotify { + pub fn build_player_entity_add_notify(&self, role_list: Vec, world: &mut WorldEntity) -> EntityAddNotify { create_player_entity_pb!( role_list, self.basic_info.cur_map_id, self, self.basic_info.id, self.location.position.clone(), - self.explore_tools + self.explore_tools, + world ) } @@ -449,13 +446,13 @@ impl Player { tracing::warn!("Role {} not found in use role list", role_id); return Default::default(); } - let role = *role_map.get(&role_id).unwrap(); + let role = *role_map.get(role_id).unwrap(); FormationRoleInfo { role_id: role.role_id, max_hp: 0, cur_hp: 0, level: role.level, - role_skin_id: role.skin_id, + ..Default::default() } }) .collect(), @@ -607,9 +604,7 @@ impl Player { basic_data: Some(self.basic_info.build_save_data()), role_data: Some(PlayerRoleData { role_list: self - .role_list - .iter() - .map(|(_, role)| role.build_save_data()) + .role_list.values().map(|role| role.build_save_data()) .collect(), role_formation_list: self .formation_list @@ -642,9 +637,7 @@ impl Player { // TODO: There is a bug we are investigating with several resonators, this is a workaround PbGetRoleListNotify { role_list: self - .role_list - .iter() - .map(|(_, role)| role.to_protobuf()) + .role_list.values().map(|role| role.to_protobuf()) .collect(), } } diff --git a/wicked-waifus-game-server/src/logic/role/formation.rs b/wicked-waifus-game-server/src/logic/role/formation.rs index 0fbba46..ea7e25c 100644 --- a/wicked-waifus-game-server/src/logic/role/formation.rs +++ b/wicked-waifus-game-server/src/logic/role/formation.rs @@ -8,7 +8,7 @@ pub struct RoleFormation { } // Will be updated every version -const DEFAULT_FORMATION: &[i32] = &[1506, 1407, 1507]; +const DEFAULT_FORMATION: &[i32] = &[1506, 1407, 1507];//5101, 1407, 1507]; // 5022 MChibi 5023 FChibi //5023, 5025, 5026 //1607 impl RoleFormation { pub fn default_roles() -> &'static [i32] { @@ -28,7 +28,7 @@ impl RoleFormation { RoleFormationData { formation_id: self.id, cur_role: self.cur_role, - role_id_list: self.role_ids.iter().map(|&role_id| role_id).collect(), + role_id_list: self.role_ids.to_vec(), is_current: self.is_current, } } diff --git a/wicked-waifus-game-server/src/logic/utils/mod.rs b/wicked-waifus-game-server/src/logic/utils/mod.rs index c7eec47..fd7f09b 100644 --- a/wicked-waifus-game-server/src/logic/utils/mod.rs +++ b/wicked-waifus-game-server/src/logic/utils/mod.rs @@ -5,4 +5,4 @@ pub mod load_role_info; pub mod world_util; pub mod quadrant_util; pub mod growth_utils; -pub mod tag_utils; +pub mod tag_utils; \ No newline at end of file diff --git a/wicked-waifus-game-server/src/logic/utils/world_util.rs b/wicked-waifus-game-server/src/logic/utils/world_util.rs index 9ca8391..de95786 100644 --- a/wicked-waifus-game-server/src/logic/utils/world_util.rs +++ b/wicked-waifus-game-server/src/logic/utils/world_util.rs @@ -1,58 +1,60 @@ +use wicked_waifus_protocol::summon::ESummonType; use wicked_waifus_protocol::{ - EEntityType, ERemoveEntityType, EntityAddNotify, EntityConfigType, EntityPb, EntityRemoveInfo, - EntityRemoveNotify, EntityState, FightRoleInfo, FightRoleInfos, LivingStatus, SceneInformation, - SceneMode, ScenePlayerInformation, SceneTimeInfo, + EEntityType, ERemoveEntityType, EntityAddNotify, EntityConfigType, EntityPb, EntityRemoveInfo, EntityRemoveNotify, EntityState, FightBuffInformation, FightRoleInfo, FightRoleInfos, LivingStatus, SceneInformation, SceneMode, ScenePlayerInformation, SceneTimeInfo }; use wicked_waifus_data::pb_components::ComponentsData; use wicked_waifus_data::{ - blueprint_config_data, template_config_data, EntityLogic, EntityType, LevelEntityConfigData, + base_property_data, blueprint_config_data, template_config_data, EntityLogic, EntityType, LevelEntityConfigData }; -use crate::logic::components::{Autonomous, Concomitant, Fsm, Interact, MonsterAi, SoarWingSkin, StateTag, Summoner, Tag}; -use crate::logic::ecs::entity::EntityBuilder; -use crate::logic::ecs::world::World; +use crate::logic::components::{Autonomous, Fsm, Interact, MonsterAi, SoarWingSkin, StateTag, Tag}; +use crate::logic::ecs::entity::{Entity, EntityBuilder}; +use crate::logic::ecs::world::{World, WorldEntity}; use crate::logic::math::Transform; use crate::logic::player::Player; -use crate::logic::utils::{entity_serializer, tag_utils}; use crate::logic::utils::growth_utils::get_monster_props_by_level; +use crate::logic::utils::{entity_serializer, tag_utils}; use crate::logic::{ components::{ - Attribute, EntityConfig, Equip, FightBuff, Movement, OwnerPlayer, PlayerOwnedEntityMarker, - Position, RoleSkin, Visibility, VisionSkill, + Attribute, Concomitant, EntityConfig, Equip, FightBuff, Movement, OwnerPlayer, + PlayerOwnedEntityMarker, Position, RoleSkin, Summoner, Visibility, VisionSkill, }, ecs::component::ComponentContainer, }; +//use crate::resonator_data::{ResonatorData, Concomitant, SummonerComponent}; + use crate::query_with; #[macro_export] macro_rules! create_player_entity_pb { - ($role_list:expr, $cur_map_id:expr, $player:expr, $player_id:expr, $position:expr, $explore_tools:expr) => {{ - let mut world_ref = $player.world.borrow_mut(); - let world = world_ref.get_mut_world_entity(); - - let current_formation = $player.formation_list.get(&$player.cur_formation_id).unwrap(); + ($role_list:expr, $cur_map_id:expr, $player:expr, $player_id:expr, $position:expr, $explore_tools:expr, $world:expr) => {{ + let current_formation = $player + .formation_list + .get(&$player.cur_formation_id) + .unwrap(); let cur_role_id = current_formation.cur_role; let mut pbs = Vec::new(); for role in $role_list { - let entity = world.create_entity( - role.role_id, - EEntityType::Player.into(), - $cur_map_id, - ); - // Once per character buffs are implemented, add a mut on role_buffs - let fight_buff_infos = world.generate_role_permanent_buffs(entity.entity_id as i64); - let buf_manager = FightBuff { + let role_id: i32 = role.role_id; + let entity = + $world.create_entity(role.role_id, EEntityType::Player.into(), $cur_map_id); + let fight_buff_infos = $world.generate_role_permanent_buffs(entity.entity_id, role_id); + + let buffs = FightBuff { fight_buff_infos, - list_buff_effect_cd: vec![], + ..Default::default() }; - let entity = world.create_builder(entity) - .with(ComponentContainer::PlayerOwnedEntityMarker(PlayerOwnedEntityMarker { - entity_type: EEntityType::Player, - })) + let entity = $world + .create_builder(entity) + .with(ComponentContainer::PlayerOwnedEntityMarker( + PlayerOwnedEntityMarker { + entity_type: EEntityType::Player, + }, + )) .with(ComponentContainer::EntityConfig(EntityConfig { camp: 0, config_id: role.role_id, @@ -62,23 +64,19 @@ macro_rules! create_player_entity_pb { })) .with(ComponentContainer::OwnerPlayer(OwnerPlayer($player_id))) .with(ComponentContainer::Position(Position($position))) - .with(ComponentContainer::Visibility(Visibility{ + .with(ComponentContainer::Visibility(Visibility { is_visible: role.role_id == cur_role_id, is_actor_visible: true, })) - // TODO: Check if role has hardness or rage_mode - // TODO: Support AddProp from Equipment(Echo, weapon, buffs??), weapon base state goes to base_prop too. - .with(ComponentContainer::Attribute( - Attribute::from_data( - &role.get_base_properties(), - None, - None, - ) - )) + .with(ComponentContainer::Attribute(Attribute::from_data( + &role.get_base_properties(), + None, + None, + ))) .with(ComponentContainer::Movement(Movement::default())) .with(ComponentContainer::Equip(Equip { weapon_id: role.equip_weapon, - weapon_breach_level: 90, // TODO: store this too + weapon_breach_level: 90, })) .with(ComponentContainer::VisionSkill(VisionSkill { skill_id: $explore_tools.active_explore_skill, @@ -89,7 +87,7 @@ macro_rules! create_player_entity_pb { .with(ComponentContainer::SoarWingSkin(SoarWingSkin { skin_id: 84000001, })) - .with(ComponentContainer::FightBuff(buf_manager)) + .with(ComponentContainer::FightBuff(buffs)) .build(); let mut pb = EntityPb { @@ -97,7 +95,7 @@ macro_rules! create_player_entity_pb { ..Default::default() }; - world + $world .get_entity_components(entity.entity_id) .into_iter() .for_each(|comp| comp.set_pb_data(&mut pb)); @@ -111,27 +109,84 @@ macro_rules! create_player_entity_pb { }}; } -// const CONCOM_ROLE_ID: &[(i32, i32)] = &[ -// (38, 1407), -// (36, 1105), -// (35, 1506), -// ]; +fn summon_concomitant(player: &Player, world: &mut WorldEntity, summon_cfg: &wicked_waifus_data::SummonCfgData) -> Entity { + let mut concomitant_buffs: Vec = Vec::new(); -// fn get_role_id_from_concom(key: i32) -> Option { -// CONCOM_ROLE_ID.iter().find(|&&(k, _)| k == key).map(|&(_, v)| v) -// } + for buff_id in &summon_cfg.born_buff_id { + concomitant_buffs + .push(FightBuffInformation { + handle_id: 1, + buff_id: *buff_id, + level: 1, + stack_count: 1, + instigator_id: 0, + entity_id: 0, + apply_type: 0, + duration: -1.0, + left_duration: -1.0, + context: vec![], + is_active: true, + server_id: 1, + message_id: 1, + } + ); + } -// fn extract_concom_number(s: String) -> Option { -// let prefix = "Player0"; -// if !s.starts_with(prefix) { -// return None; -// } + let concomitant_id = template_config_data::get(&summon_cfg.blueprint_type).unwrap().id; + tracing::info!("Adding Concomitant with id: {}", concomitant_id); + let con_buffs = concomitant_buffs.clone(); -// let rest = &s[prefix.len()..]; // Skip "Player0" -// let underscore_index = rest.find('_')?; -// let number_str = &rest[..underscore_index]; -// number_str.parse::().ok() -// } + let con_entity = world.create_entity( + concomitant_id, + EEntityType::Monster.into(), + player.basic_info.cur_map_id, + ); + + world + .create_builder(con_entity) + .with(ComponentContainer::PlayerOwnedEntityMarker(PlayerOwnedEntityMarker { + entity_type: EEntityType::Monster, + })) + .with(ComponentContainer::EntityConfig(EntityConfig { + camp: 0, + config_id: concomitant_id, + config_type: EntityConfigType::Template, + entity_type: EEntityType::Monster, + entity_state: EntityState::Sleep, + })) + .with(ComponentContainer::OwnerPlayer(OwnerPlayer( + player.basic_info.id, + ))) + .with(ComponentContainer::Position(Position( + player.location.position.clone(), + ))) + .with(ComponentContainer::Visibility(Visibility { + is_visible: false, + is_actor_visible: false, + })) + .with(ComponentContainer::Attribute(Attribute::from_data( + base_property_data::iter() + .find(|d| d.id == concomitant_id as i32) + .unwrap_or_else(|| { + base_property_data::iter() + .find(|d| d.id == 390070051) + .unwrap_or_else(|| { + tracing::error!("Default base property concomitant not found!"); + panic!("Critical config missing: base property concomitant") + }) + }), + None, + None, + ))) + .with(ComponentContainer::Movement(Movement::default())) + .with(ComponentContainer::FightBuff(FightBuff { fight_buff_infos: con_buffs, ..Default::default() })) + .with(ComponentContainer::Summoner(Summoner { + summon_cfg_id: summon_cfg.id, + summon_skill_id: 0, + summon_type: ESummonType::ESummonTypeConcomitantCustom.into() + })) + .build() +} pub fn add_player_entities(player: &Player) { let mut world_ref = player.world.borrow_mut(); @@ -142,70 +197,32 @@ pub fn add_player_entities(player: &Player) { let role_vec = current_formation .role_ids .iter() - .map(|role_id| player.role_list.get(&role_id).unwrap()) + .map(|role_id| player.role_list.get(role_id).unwrap()) .collect::>(); let cur_role_id = current_formation.cur_role; - + if world.active_entity_empty() { - let mut concoms = vec![]; - - for (_, blueprint_config) in wicked_waifus_data::blueprint_config_data::iter().filter(|(_, bc)| { - bc.blueprint_type.starts_with("Player0") && bc.entity_type == EntityType::Monster - }) { - // let blueprint_role_id = get_role_id_from_concom(extract_concom_number(blueprint_config.blueprint_type.clone()).unwrap()); - // if blueprint_role_id.is_none() {continue} - - let (_, template_config) = wicked_waifus_data::template_config_data::iter().find(|(_, tc)| tc.blueprint_type == blueprint_config.blueprint_type).unwrap(); - - tracing::debug!( - "getting summoner cfg, blueprint_type: {}, template_config_id: {}", - template_config.blueprint_type, - template_config.id - ); - - let (_, summoner_cfg) = wicked_waifus_data::summon_cfg_data::iter().find(|(_, sc)| sc.blueprint_type == blueprint_config.blueprint_type).unwrap(); - - let concomitant= world.create_entity(template_config.id, EEntityType::Monster.into(), player.basic_info.cur_map_id); - concoms.push(concomitant.entity_id as i64); - - let fight_buff_infos = world.generate_concom_buffs(summoner_cfg.born_buff_id.clone(), concomitant.entity_id as i64); - let buf_manager = FightBuff { - fight_buff_infos, - list_buff_effect_cd: vec![], - }; - world - .create_builder(concomitant) - .with(ComponentContainer::EntityConfig(EntityConfig { - camp: 0, - config_id: template_config.id, - config_type: EntityConfigType::Template, - entity_type: EEntityType::Monster.into(), - entity_state: EntityState::Born - })) - .with(ComponentContainer::Summoner(Summoner { summon_cfg_id: summoner_cfg.id, summon_skill_id: 1, summon_type: 2 })) - .with(ComponentContainer::FightBuff(buf_manager)) - .with(ComponentContainer::Autonomous(Autonomous { autonomous_id: player.basic_info.id })) - .with(ComponentContainer::Visibility(Visibility { is_visible: false, is_actor_visible: true })) - .with(ComponentContainer::Position(Position(player.location.position.clone()))) - .with(ComponentContainer::Position(Position(player.location.position.clone()))) - .build(); - - tracing::debug!( - "created concom entity, id: {}", - template_config.id - ); - } for role in role_vec { + let mut concomitants: Vec = vec![]; + + for (_, summon_cfg) in wicked_waifus_data::summon_cfg_data::iter().filter(|(_, cfg)| { + cfg.blueprint_type.starts_with("Player0") && cfg.born_buff_id.iter().any(|x| { + x.to_string().starts_with(&role.role_id.to_string()) + }) + }) { + let concomitant = summon_concomitant(player, world, summon_cfg); + concomitants.push(concomitant.entity_id.into()); + } + let entity = world.create_entity( role.role_id, EEntityType::Player.into(), player.basic_info.cur_map_id, ); - // Once per character buffs are implemented, add a mut on role_buffs - let fight_buff_infos = world.generate_role_permanent_buffs(entity.entity_id as i64); + let fight_buff_infos = world.generate_role_permanent_buffs(entity.entity_id, role.role_id); let buf_manager = FightBuff { fight_buff_infos, - list_buff_effect_cd: vec![], + list_buff_effect_cd: vec![] }; let entity = world .create_builder(entity) @@ -218,7 +235,7 @@ pub fn add_player_entities(player: &Player) { camp: 0, config_id: role.role_id, config_type: EntityConfigType::Character, - entity_type: EEntityType::Player.into(), + entity_type: EEntityType::Player, entity_state: EntityState::Default, })) .with(ComponentContainer::OwnerPlayer(OwnerPlayer( @@ -253,8 +270,12 @@ pub fn add_player_entities(player: &Player) { .with(ComponentContainer::SoarWingSkin(SoarWingSkin { skin_id: 84000001, })) - .with(ComponentContainer::Concomitant(Concomitant { vision_entity_id: 0, custom_entity_ids: concoms.clone(), phantom_role_id: 0 })) .with(ComponentContainer::FightBuff(buf_manager)) + .with(ComponentContainer::Concomitant(Concomitant { + vision_entity_id: 0, + custom_entity_ids: concomitants, + phantom_role_id: 0, + })) .build(); tracing::debug!( @@ -335,7 +356,7 @@ fn build_player_info_list(world: &World) -> Vec { cur_role: cur_role_id, // is_retain: true, fight_role_infos: active_characters - .map(|(id, _, _, conf, role_skin)| FightRoleInfo { + .map(|(id, _, _, conf, _role_skin)| FightRoleInfo { entity_id: id.into(), role_id: conf.config_id, on_stage_without_control: false, @@ -501,7 +522,13 @@ pub fn add_entities(player: &Player, entities: &[&LevelEntityConfigData], extern build_autonomous_component(&mut builder, player.basic_info.id, entity_logic); build_interact_component(&mut builder, &components); - build_tags_components(&mut builder, &components, player, blueprint_config.unwrap().entity_type, config_id as i64); + build_tags_components( + &mut builder, + &components, + player, + blueprint_config.unwrap().entity_type, + config_id as i64, + ); build_attribute_component(&mut builder, &components, player.location.instance_id); build_ai_components(&mut builder, &components); added_entities.push(builder.build()); @@ -567,7 +594,10 @@ fn build_tags_components( if let Some(entity_state_component) = &components.entity_state_component { let state = match entity_type { EntityType::Teleporter | EntityType::TemporaryTeleporter => { - let result = player.teleports.teleports_data.iter() + let result = player + .teleports + .teleports_data + .iter() .find(|teleporter| teleporter.entity_config_id == config_id); match result.is_some() { true => tag_utils::get_tag_id_by_name("关卡.Common.状态.激活"),