This commit is contained in:
RabbyDevs 2025-05-10 19:43:45 +03:00
parent ccf8aca5fd
commit 5d3c0e90fc
10 changed files with 142 additions and 7 deletions

3
Cargo.lock generated
View file

@ -2682,8 +2682,9 @@ checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
[[package]]
name = "unreal-niggery-rs"
version = "0.1.0"
source = "git+https://git.xeondev.com/xavo95/unreal-niggery-rs.git#07330a27e1e49f0544f5fde51698c0a2300cc737"
source = "git+https://git.xeondev.com/ReversedRoomsMisc/unreal-niggery-rs.git#e07eda21e461e1ec234ec9ef2562dc8187742631"
dependencies = [
"thiserror 2.0.12",
"widestring",
]

View file

@ -167,6 +167,7 @@ json_hash_table_data! {
DragonPool, id, i32;
DropPackage, id, i32;
TemplateConfig, blueprint_type, String;
SummonCfg, blueprint_type, String;
}
mod level_entity_config;

View file

@ -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(),
}
}
}

View 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>
}

View 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>,
}

View file

@ -14,7 +14,7 @@ serde.workspace = true
indexmap = "2.7.1"
uuid = { version = "1.11.0", features = ["v4"] }
rand = "0.9.0-alpha.2"
unreal-niggery-rs = { git = "https://git.xeondev.com/xavo95/unreal-niggery-rs.git" }
unreal-niggery-rs = { git = "https://git.xeondev.com/ReversedRoomsMisc/unreal-niggery-rs.git" }
widestring = "1.1.0"
# Used for debug
#serde_json = "1.0.135"

View file

@ -81,6 +81,31 @@ impl BufManager {
})
.collect::<Vec<_>>()
}
pub fn create_concom_buffs(&mut self, buff_ids: Vec<i64>, origin_id: i64) -> Vec<FightBuffInformation> {
buff_ids
.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::<Vec<_>>()
}
}
impl Default for BufManager {

View file

@ -114,6 +114,11 @@ impl WorldEntity {
pub fn generate_role_permanent_buffs(&mut self, entity_id: i64) -> Vec<FightBuffInformation> {
self.buff_manager.create_permanent_buffs(entity_id)
}
pub fn generate_concom_buffs(&mut self, buff_ids: Vec<i64>, entity_id: i64) -> Vec<FightBuffInformation> {
tracing::debug!("{:#?}", buff_ids);
self.buff_manager.create_concom_buffs(buff_ids, entity_id)
}
}
impl Default for WorldEntity {

View file

@ -8,7 +8,7 @@ pub struct RoleFormation {
}
// Will be updated every version
const DEFAULT_FORMATION: &[i32] = &[5101, 1407, 1507];
const DEFAULT_FORMATION: &[i32] = &[1506, 1407, 1507];
impl RoleFormation {
pub fn default_roles() -> &'static [i32] {

View file

@ -9,7 +9,7 @@ use wicked_waifus_data::{
blueprint_config_data, template_config_data, EntityLogic, EntityType, LevelEntityConfigData,
};
use crate::logic::components::{Autonomous, Fsm, Interact, MonsterAi, SoarWingSkin, StateTag, Tag};
use crate::logic::components::{Autonomous, Fsm, Interact, MonsterAi, SoarWingSkin, StateTag, Summoner, Tag};
use crate::logic::ecs::entity::EntityBuilder;
use crate::logic::ecs::world::World;
use crate::logic::math::Transform;
@ -123,7 +123,7 @@ pub fn add_player_entities(player: &Player) {
.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 entity = world.create_entity(
@ -319,6 +319,28 @@ pub fn remove_entities(player: &Player, entities: &[&LevelEntityConfigData]) {
}
}
const CONCOM_ROLE_ID: &[(i32, i32)] = &[
(38, 1407),
(36, 1105),
(35, 1506),
];
fn get_role_id_from_concom(key: i32) -> Option<i32> {
CONCOM_ROLE_ID.iter().find(|&&(k, _)| k == key).map(|&(_, v)| v)
}
fn extract_concom_number(s: String) -> Option<i32> {
let prefix = "Player0";
if !s.starts_with(prefix) {
return None;
}
let rest = &s[prefix.len()..]; // Skip "Player0"
let underscore_index = rest.find('_')?;
let number_str = &rest[..underscore_index];
number_str.parse::<i32>().ok()
}
pub fn add_entities(player: &Player, entities: &[&LevelEntityConfigData], external_awake: bool) {
let mut added_entities = Vec::with_capacity(entities.len());
// Enclose to drop borrow mut ASAP
@ -326,6 +348,56 @@ pub fn add_entities(player: &Player, entities: &[&LevelEntityConfigData], extern
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();
let cur_role_id = current_formation.cur_role;
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() || current_formation.role_ids.contains(&blueprint_role_id.unwrap()) {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 entity: crate::logic::ecs::entity::Entity = world.create_entity(template_config.id, EEntityType::Monster.into(), player.basic_info.cur_map_id);
let fight_buff_infos = world.generate_concom_buffs(summoner_cfg.born_buff_id.clone(), entity.entity_id as i64);
let buf_manager = FightBuff {
fight_buff_infos,
list_buff_effect_cd: vec![],
};
added_entities.push(world
.create_builder(entity)
.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: template_config.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::Attribute(Attribute { attr_map: template_config.components_data.attribute_component.unwrap(), hardness_mode_id: (), rage_mode_id: () }))
// .with(ComponentContainer::Fsm(Fsm { hash_code: (), common_hash_code: (), state_list: (), node_list: () }))
.build());
tracing::debug!(
"created concom entity, id: {}, role_id: {}",
template_config.id,
cur_role_id
);
}
for entity in entities {
// Skip hidden entities
if entity.is_hidden {