Introduce automatic concomitants, buffs + a little bit more #6
15 changed files with 345 additions and 134 deletions
12
wicked-waifus-data/src/buff.rs
Normal file
12
wicked-waifus-data/src/buff.rs
Normal file
|
@ -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<Vec<String>>,
|
||||
pub game_attribute_i_d: i32
|
||||
}
|
|
@ -168,8 +168,9 @@ json_hash_table_data! {
|
|||
DragonPool, id, i32;
|
||||
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 +185,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 +211,9 @@ fn load_json_entity_level_config_data(base_path: &str) -> Result<(), LoadDataErr
|
|||
serde_json::from_reader::<BufReader<File>, Vec<level_entity_config_data::Data>>(reader)?
|
||||
.into_iter()
|
||||
.map(|element| (level_entity_config_data::create_key(&element), element))
|
||||
.collect::<std::collections::HashMap<_, _>>()
|
||||
.collect::<std::collections::HashMap<_, _>>(),
|
||||
);
|
||||
tracing::info!("Loading data finished: {path}");
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ pub mod reward;
|
|||
pub mod teleport;
|
||||
pub mod timer;
|
||||
pub mod var;
|
||||
pub mod model;
|
||||
|
||||
#[derive(Deserialize, Debug, Clone)]
|
||||
#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))]
|
||||
|
@ -28,6 +29,7 @@ pub struct ComponentsData {
|
|||
pub interact_component: Option<interact::InteractComponent>,
|
||||
pub entity_state_component: Option<entity_state::EntityStateComponent>,
|
||||
pub reward_component: Option<reward::RewardComponent>,
|
||||
pub model_component: Option<model::ModelComponent>,
|
||||
// TODO: Implement this ones
|
||||
#[cfg(feature = "strict_json_fields")]
|
||||
pub scene_actor_ref_component: Option<serde_json::Value>,
|
||||
|
@ -70,8 +72,6 @@ pub struct ComponentsData {
|
|||
#[cfg(feature = "strict_json_fields")]
|
||||
pub photo_target_component: Option<serde_json::Value>,
|
||||
#[cfg(feature = "strict_json_fields")]
|
||||
pub model_component: Option<serde_json::Value>,
|
||||
#[cfg(feature = "strict_json_fields")]
|
||||
pub entity_group_component: Option<serde_json::Value>,
|
||||
#[cfg(feature = "strict_json_fields")]
|
||||
pub scene_item_life_cycle_component: Option<serde_json::Value>,
|
||||
|
@ -230,6 +230,7 @@ impl ComponentsData {
|
|||
interact_component: self.interact_component.as_ref().or(template.interact_component.as_ref()).cloned(),
|
||||
entity_state_component: self.entity_state_component.as_ref().or(template.entity_state_component.as_ref()).cloned(),
|
||||
reward_component: self.reward_component.as_ref().or(template.reward_component.as_ref()).cloned(),
|
||||
model_component: self.model_component.as_ref().or(template.model_component.as_ref()).cloned(),
|
||||
}
|
||||
}
|
||||
}
|
18
wicked-waifus-data/src/pb_components/model.rs
Normal file
18
wicked-waifus-data/src/pb_components/model.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize, Debug, Clone)]
|
||||
#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
pub struct ModelType {
|
||||
r#type: Option<String>,
|
||||
model_id: Option<i32>
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, Clone)]
|
||||
#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
pub struct ModelComponent {
|
||||
pub half_height: Option<i32>,
|
||||
pub disabled: Option<bool>,
|
||||
pub model_type: Option<ModelType>
|
||||
}
|
12
wicked-waifus-data/src/summon_cfg.rs
Normal file
12
wicked-waifus-data/src/summon_cfg.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
use serde::Deserialize;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[cfg_attr(feature = "strict_json_fields", serde(deny_unknown_fields))]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
pub struct SummonCfgData {
|
||||
pub id: i32,
|
||||
pub blueprint_type: String,
|
||||
#[cfg(feature = "strict_json_fields")]
|
||||
pub name: String,
|
||||
pub born_buff_id: Vec<i64>,
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
require('../Module/WaterMask/WaterMaskController').WaterMaskView.EOo();
|
41
wicked-waifus-game-server/scripts/watermask-edit.js
Normal file
41
wicked-waifus-game-server/scripts/watermask-edit.js
Normal file
|
@ -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();
|
|
@ -8,17 +8,34 @@ pub struct BufManager {
|
|||
recycled_handles: HashMap<i32, VecDeque<i32>>,
|
||||
}
|
||||
|
||||
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::<Vec<_>>();
|
||||
|
@ -57,13 +76,33 @@ impl BufManager {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn create_permanent_buffs(&mut self, origin_id: i64) -> Vec<FightBuffInformation> {
|
||||
Self::PERMANENT_ROLE_BUFFS
|
||||
pub fn create_permanent_buffs(&mut self, origin_id: i64, role_id: i32) -> Vec<FightBuffInformation> {
|
||||
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::<Vec<i64>>();
|
||||
|
||||
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,
|
||||
|
|
|
@ -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<i32, Vec<RefCell<ComponentContainer>>>,
|
||||
entity_manager: EntityManager,
|
||||
|
@ -111,17 +112,7 @@ impl WorldEntity {
|
|||
self.entity_manager.active_entity_empty()
|
||||
}
|
||||
|
||||
pub fn generate_role_permanent_buffs(&mut self, entity_id: i64) -> Vec<FightBuffInformation> {
|
||||
self.buff_manager.create_permanent_buffs(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<FightBuffInformation> {
|
||||
self.buff_manager.create_permanent_buffs(entity_id as i64, role_id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<i64> = old_formation
|
||||
let removed_entities: Vec<i64> = 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<Role> = 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<Role> = 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());
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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<Role>) -> EntityAddNotify {
|
||||
pub fn build_player_entity_add_notify(&self, role_list: Vec<Role>, 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(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
|
@ -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, Fsm, Interact, MonsterAi, SoarWingSkin, StateTag, Tag};
|
||||
use crate::logic::ecs::entity::EntityBuilder;
|
||||
use crate::logic::ecs::world::World;
|
||||
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,6 +109,85 @@ macro_rules! create_player_entity_pb {
|
|||
}};
|
||||
}
|
||||
|
||||
fn summon_concomitant(player: &Player, world: &mut WorldEntity, summon_cfg: &wicked_waifus_data::SummonCfgData) -> Entity {
|
||||
let mut concomitant_buffs: Vec<FightBuffInformation> = Vec::new();
|
||||
|
||||
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,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
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 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();
|
||||
let world = world_ref.get_mut_world_entity();
|
||||
|
@ -120,22 +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::<Vec<_>>();
|
||||
let cur_role_id = current_formation.cur_role;
|
||||
|
||||
if world.active_entity_empty() {
|
||||
for role in role_vec {
|
||||
let mut concomitants: Vec<i64> = 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)
|
||||
|
@ -148,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(
|
||||
|
@ -184,6 +271,11 @@ pub fn add_player_entities(player: &Player) {
|
|||
skin_id: 84000001,
|
||||
}))
|
||||
.with(ComponentContainer::FightBuff(buf_manager))
|
||||
.with(ComponentContainer::Concomitant(Concomitant {
|
||||
vision_entity_id: 0,
|
||||
custom_entity_ids: concomitants,
|
||||
phantom_role_id: 0,
|
||||
}))
|
||||
.build();
|
||||
|
||||
tracing::debug!(
|
||||
|
@ -264,7 +356,7 @@ fn build_player_info_list(world: &World) -> Vec<ScenePlayerInformation> {
|
|||
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,
|
||||
|
@ -430,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());
|
||||
|
@ -496,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.状态.激活"),
|
||||
|
|
Loading…
Reference in a new issue