mirror of
https://git.xeondev.com/LR/S.git
synced 2026-03-21 23:22:21 +01:00
feat(scene): implement enemy spawn
This commit is contained in:
@@ -9,4 +9,27 @@ pub const WorldEntityBriefInfo = struct {
|
|||||||
detailId: ?[]const u8,
|
detailId: ?[]const u8,
|
||||||
position: logic.Level.Object.Vector,
|
position: logic.Level.Object.Vector,
|
||||||
rotation: logic.Level.Object.Vector,
|
rotation: logic.Level.Object.Vector,
|
||||||
|
|
||||||
|
pub fn objectType(info: WorldEntityBriefInfo) ObjectType {
|
||||||
|
return std.enums.fromInt(ObjectType, info.entityType) orelse .invalid;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ObjectType = enum(u32) {
|
||||||
|
all = 4294967295,
|
||||||
|
invalid = 1,
|
||||||
|
character = 8,
|
||||||
|
enemy = 16,
|
||||||
|
interactive = 32,
|
||||||
|
projectile = 64,
|
||||||
|
factory_region = 128,
|
||||||
|
npc = 256,
|
||||||
|
ability_entity = 512,
|
||||||
|
cinematic_entity = 1024,
|
||||||
|
remote_factory_entity = 2048,
|
||||||
|
creature = 4096,
|
||||||
|
god_entity = 8192,
|
||||||
|
enemy_part = 16384,
|
||||||
|
social_building = 32768,
|
||||||
|
enemy_all = 16400,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,3 +18,5 @@ pub const SyncSelfScene = struct {
|
|||||||
team_modified,
|
team_modified,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const RefreshVisibleObjects = struct {};
|
||||||
|
|||||||
@@ -9,8 +9,10 @@ const Player = logic.Player;
|
|||||||
pub fn onSceneLoadFinish(
|
pub fn onSceneLoadFinish(
|
||||||
_: messaging.Request(pb.CS_SCENE_LOAD_FINISH),
|
_: messaging.Request(pb.CS_SCENE_LOAD_FINISH),
|
||||||
sync_self_scene_tx: logic.event.Sender(.sync_self_scene),
|
sync_self_scene_tx: logic.event.Sender(.sync_self_scene),
|
||||||
|
refresh_visible_objects_tx: logic.event.Sender(.refresh_visible_objects),
|
||||||
) !void {
|
) !void {
|
||||||
try sync_self_scene_tx.send(.{ .reason = .entrance });
|
try sync_self_scene_tx.send(.{ .reason = .entrance });
|
||||||
|
try refresh_visible_objects_tx.send(.{});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn onMoveObjectMove(
|
pub fn onMoveObjectMove(
|
||||||
|
|||||||
@@ -202,6 +202,83 @@ pub fn syncSelfScene(
|
|||||||
try session.send(self_scene_info);
|
try session.send(self_scene_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn refreshVisibleObjects(
|
||||||
|
rx: logic.event.Receiver(.refresh_visible_objects),
|
||||||
|
session: *Session,
|
||||||
|
arena: logic.Resource.Allocator(.arena),
|
||||||
|
scene: Player.Component(.scene),
|
||||||
|
assets: *const Assets,
|
||||||
|
) !void {
|
||||||
|
const objects_per_message: usize = 128; // TODO(Session): message fragmentation.
|
||||||
|
|
||||||
|
_ = rx;
|
||||||
|
|
||||||
|
const level_id = scene.data.current.level_id;
|
||||||
|
var container: pb.SCENE_OBJECT_DETAIL_CONTAINER = .init;
|
||||||
|
|
||||||
|
const brief_map = &assets.world_entity_registry.worldEntityBriefInfos;
|
||||||
|
for (brief_map.map.keys(), brief_map.map.values()) |id, info| {
|
||||||
|
if (@divFloor(id, 100_000_000) != level_id)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (info.objectType() != .enemy) continue;
|
||||||
|
const template_id = info.detailId orelse continue;
|
||||||
|
|
||||||
|
const enemy_attrs = assets.table(.enemy_attribute_template).getPtr(template_id) orelse continue;
|
||||||
|
const common_info: pb.SCENE_OBJECT_COMMON_INFO = .{
|
||||||
|
.id = id,
|
||||||
|
.type = 3,
|
||||||
|
.templateid = template_id,
|
||||||
|
.position = .{ .X = info.position.x, .Y = info.position.y, .Z = info.position.z },
|
||||||
|
.rotation = .{ .X = info.rotation.x, .Y = info.rotation.y, .Z = info.rotation.z },
|
||||||
|
.scene_num_id = level_id,
|
||||||
|
.hp = 100,
|
||||||
|
};
|
||||||
|
|
||||||
|
var monster: pb.SCENE_MONSTER = .{
|
||||||
|
.common_info = common_info,
|
||||||
|
.level = 1,
|
||||||
|
.battle_info = .{
|
||||||
|
.msg_generation = @truncate(id),
|
||||||
|
.battle_inst_id = @truncate(id),
|
||||||
|
.part_inst_info = .init,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (enemy_attrs.levelDependentAttributes[0].attrs) |attr| {
|
||||||
|
try monster.attrs.append(arena.interface, .{
|
||||||
|
.attr_type = @intFromEnum(attr.attrType),
|
||||||
|
.basic_value = attr.attrValue,
|
||||||
|
.value = attr.attrValue,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (enemy_attrs.levelIndependentAttributes.attrs) |attr| {
|
||||||
|
try monster.attrs.append(arena.interface, .{
|
||||||
|
.attr_type = @intFromEnum(attr.attrType),
|
||||||
|
.basic_value = attr.attrValue,
|
||||||
|
.value = attr.attrValue,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
try container.monster_list.append(arena.interface, monster);
|
||||||
|
|
||||||
|
if (container.monster_list.items.len == objects_per_message) {
|
||||||
|
try session.send(pb.SC_OBJECT_ENTER_VIEW{
|
||||||
|
.detail = container,
|
||||||
|
});
|
||||||
|
|
||||||
|
container = .init;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (container.monster_list.items.len != 0) {
|
||||||
|
try session.send(pb.SC_OBJECT_ENTER_VIEW{
|
||||||
|
.detail = container,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn packCharacterSkills(
|
fn packCharacterSkills(
|
||||||
arena: Allocator,
|
arena: Allocator,
|
||||||
assets: *const Assets,
|
assets: *const Assets,
|
||||||
|
|||||||
Reference in New Issue
Block a user