trigger-rs/crates/game-server/src/logic/player/scene.rs

167 lines
5.4 KiB
Rust

use trigger_database::{
entity::{player_world_info, scene_info},
prelude::*,
};
use trigger_logic::scene::ESceneType;
use super::NapContext;
pub struct SceneModel {
context: NapContext,
player_world_info: player_world_info::Model,
}
impl SceneModel {
pub async fn init(context: NapContext) -> Self {
let player_world_info = Self::load_or_create_player_world_info(&context).await;
Self {
context,
player_world_info,
}
}
pub async fn on_leave_scene(&mut self, scene_uid: i64) {
if self
.get_scene_by_uid(scene_uid)
.await
.map_or(false, |sc| sc.to_be_destroyed)
{
scene_info::Entity::delete_by_id(scene_uid)
.exec(self.context.database)
.await
.expect("scene_info::delete_by_id failed");
}
}
pub async fn clear_abandoned_scenes(&self) {
use scene_info::Column;
let world = &self.player_world_info;
scene_info::Entity::delete_many()
.filter(
Condition::all()
.add(Column::ToBeDestroyed.eq(true))
.add(Column::OwnerPlayerUid.eq(self.context.player_uid as i32))
.add(Column::SceneUid.is_not_in([
world.current_scene_uid,
world.back_scene_uid,
world.default_scene_uid,
])),
)
.exec(self.context.database)
.await
.expect("scene_info::delete_many failed");
}
pub async fn update_scene_ext(&mut self, scene_uid: i64, ext: String) {
scene_info::ActiveModel {
scene_uid: Set(scene_uid),
ext: Set(ext),
..Default::default()
}
.update(self.context.database)
.await
.expect("scene_info::update failed");
}
pub async fn set_default_scene(&mut self, scene: &scene_info::Model) {
let mut info: player_world_info::ActiveModel = self.player_world_info.clone().into();
info.default_scene_uid = Set(scene.scene_uid);
self.player_world_info = info
.update(self.context.database)
.await
.expect("player_world_info::update failed");
}
pub async fn set_current_scene(&mut self, scene: &scene_info::Model) {
let mut info: player_world_info::ActiveModel = self.player_world_info.clone().into();
info.current_scene_uid = Set(scene.scene_uid);
self.player_world_info = info
.update(self.context.database)
.await
.expect("player_world_info::update failed");
}
pub async fn push_current_scene(&mut self, scene: &scene_info::Model) {
let mut info: player_world_info::ActiveModel = self.player_world_info.clone().into();
info.back_scene_uid = Set(self.player_world_info.current_scene_uid);
info.current_scene_uid = Set(scene.scene_uid);
self.player_world_info = info
.update(self.context.database)
.await
.expect("player_world_info::update failed");
}
pub async fn create_scene_info(&mut self, scene_type: ESceneType) -> scene_info::Model {
scene_info::Entity::insert(scene_info::ActiveModel {
scene_uid: NotSet,
owner_player_uid: Set(self.context.player_uid as i32),
scene_type: Set(scene_type.into()),
to_be_destroyed: Set(scene_type != ESceneType::Hall),
ext: Set(String::with_capacity(0)),
})
.exec_with_returning(self.context.database)
.await
.expect("scene_basic_info::insert failed")
}
#[expect(dead_code)]
pub async fn get_back_scene(&self) -> Option<scene_info::Model> {
self.get_scene_by_uid(self.player_world_info.back_scene_uid)
.await
}
pub async fn get_current_scene(&self) -> Option<scene_info::Model> {
self.get_scene_by_uid(self.player_world_info.current_scene_uid)
.await
}
pub async fn get_default_scene(&self) -> Option<scene_info::Model> {
self.get_scene_by_uid(self.player_world_info.default_scene_uid)
.await
}
pub async fn get_scene_by_uid(&self, scene_uid: i64) -> Option<scene_info::Model> {
if scene_uid == 0 {
return None;
}
scene_info::Entity::find_by_id(scene_uid)
.one(self.context.database)
.await
.expect("scene_basic_info::find_by_id failed")
}
async fn load_or_create_player_world_info(context: &NapContext) -> player_world_info::Model {
let player_uid = context.player_uid as i32;
match player_world_info::Entity::find_by_id(player_uid)
.one(context.database)
.await
.expect("player_world_info::find_by_id failed")
{
Some(info) => info,
None => Self::create_default_player_world_info(player_uid)
.insert(context.database)
.await
.expect("player_world_info::insert failed"),
}
}
fn create_default_player_world_info(player_uid: i32) -> player_world_info::ActiveModel {
player_world_info::Model {
player_uid,
last_enter_world_timestamp: 0,
default_scene_uid: 0,
current_scene_uid: 0,
back_scene_uid: 0,
}
.into()
}
}