friendly fire and pvp at desert arenas!

This commit is contained in:
crabman 2024-03-25 21:55:50 +00:00
parent 4d67e808e1
commit c589bc5ca0
No known key found for this signature in database
9 changed files with 114 additions and 100 deletions

View File

@ -92,8 +92,7 @@ command-aura-spawn-new-entity = Spawned new aura
# Unreachable/untestable but added for consistency # Unreachable/untestable but added for consistency
command-player-info-unavailable = Cannot get player information for { $target } command-player-info-unavailable = Cannot get player information for { $target }
command-unimplemented-waypoint-spawn = Waypoint spawning is not implemented command-unimplemented-spawn-special = Spawning special entities is not implemented
command-unimplemented-teleporter-spawn = Teleporter spawning is not implemented
command-kit-inventory-unavailable = Could not get inventory command-kit-inventory-unavailable = Could not get inventory
command-inventory-cant-fit-item = Can't fit item to inventory command-inventory-cant-fit-item = Can't fit item to inventory
# Emitted by /disconnect_all when you don't exist (?) # Emitted by /disconnect_all when you don't exist (?)

View File

@ -6,10 +6,9 @@ use crate::{
agent::Sound, agent::Sound,
dialogue::Subject, dialogue::Subject,
invite::{InviteKind, InviteResponse}, invite::{InviteKind, InviteResponse},
misc::PortalData,
DisconnectReason, LootOwner, Ori, Pos, UnresolvedChatMsg, Vel, DisconnectReason, LootOwner, Ori, Pos, UnresolvedChatMsg, Vel,
}, },
generation::EntityInfo, generation::{EntityInfo, SpecialEntity},
lottery::LootSpec, lottery::LootSpec,
mounting::VolumePos, mounting::VolumePos,
outcome::Outcome, outcome::Outcome,
@ -152,8 +151,10 @@ pub struct ChatEvent(pub UnresolvedChatMsg);
pub struct CommandEvent(pub EcsEntity, pub String, pub Vec<String>); pub struct CommandEvent(pub EcsEntity, pub String, pub Vec<String>);
// Entity Creation // Entity Creation
pub struct CreateWaypointEvent(pub Vec3<f32>); pub struct CreateSpecialEntityEvent {
pub struct CreateTeleporterEvent(pub Vec3<f32>, pub PortalData); pub pos: Vec3<f32>,
pub entity: SpecialEntity,
}
pub struct CreateNpcEvent { pub struct CreateNpcEvent {
pub pos: Pos, pub pos: Pos,
@ -498,8 +499,7 @@ pub fn register_event_busses(ecs: &mut World) {
ecs.insert(EventBus::<ClientDisconnectWithoutPersistenceEvent>::default()); ecs.insert(EventBus::<ClientDisconnectWithoutPersistenceEvent>::default());
ecs.insert(EventBus::<ChatEvent>::default()); ecs.insert(EventBus::<ChatEvent>::default());
ecs.insert(EventBus::<CommandEvent>::default()); ecs.insert(EventBus::<CommandEvent>::default());
ecs.insert(EventBus::<CreateWaypointEvent>::default()); ecs.insert(EventBus::<CreateSpecialEntityEvent>::default());
ecs.insert(EventBus::<CreateTeleporterEvent>::default());
ecs.insert(EventBus::<CreateNpcEvent>::default()); ecs.insert(EventBus::<CreateNpcEvent>::default());
ecs.insert(EventBus::<CreateShipEvent>::default()); ecs.insert(EventBus::<CreateShipEvent>::default());
ecs.insert(EventBus::<CreateItemDropEvent>::default()); ecs.insert(EventBus::<CreateItemDropEvent>::default());

View File

@ -177,10 +177,14 @@ pub fn try_all_entity_configs() -> Result<Vec<String>, Error> {
Ok(configs.read().ids().map(|id| id.to_string()).collect()) Ok(configs.read().ids().map(|id| id.to_string()).collect())
} }
#[derive(Clone)] #[derive(Clone, Debug)]
pub enum SpecialEntity { pub enum SpecialEntity {
Waypoint, Waypoint,
Teleporter(PortalData), Teleporter(PortalData),
/// Totem with FriendlyFire and ForcePvP auras
ArenaTotem {
range: f32,
},
} }
#[derive(Clone)] #[derive(Clone)]

View File

@ -42,10 +42,10 @@ use common::{
depot, depot,
effect::Effect, effect::Effect,
event::{ event::{
ClientDisconnectEvent, CreateNpcEvent, CreateWaypointEvent, EventBus, ExplosionEvent, ClientDisconnectEvent, CreateNpcEvent, CreateSpecialEntityEvent, EventBus, ExplosionEvent,
GroupManipEvent, InitiateInviteEvent, TamePetEvent, GroupManipEvent, InitiateInviteEvent, TamePetEvent,
}, },
generation::{EntityConfig, EntityInfo}, generation::{EntityConfig, EntityInfo, SpecialEntity},
link::Is, link::Is,
mounting::{Rider, Volume, VolumeRider}, mounting::{Rider, Volume, VolumeRider},
npc::{self, get_npc_name}, npc::{self, get_npc_name},
@ -670,11 +670,8 @@ fn handle_into_npc(
TransformEntityError::EntityDead => { TransformEntityError::EntityDead => {
Content::localized_with_args("command-entity-dead", [("entity", "target")]) Content::localized_with_args("command-entity-dead", [("entity", "target")])
}, },
TransformEntityError::UnexpectedNpcWaypoint => { TransformEntityError::UnexpectedSpecialEntity => {
Content::localized("command-unimplemented-waypoint-spawn") Content::localized("command-unimplemented-spawn-special")
},
TransformEntityError::UnexpectedNpcTeleporter => {
Content::localized("command-unimplemented-teleporter-spawn")
}, },
TransformEntityError::LoadingCharacter => { TransformEntityError::LoadingCharacter => {
Content::localized("command-transform-invalid-presence") Content::localized("command-transform-invalid-presence")
@ -731,11 +728,8 @@ fn handle_make_npc(
); );
match SpawnEntityData::from_entity_info(entity_info) { match SpawnEntityData::from_entity_info(entity_info) {
SpawnEntityData::Waypoint(_) => { SpawnEntityData::Special(_, _) => {
return Err(Content::localized("command-unimplemented-waypoint-spawn")); return Err(Content::localized("command-unimplemented-spawn-special"));
},
SpawnEntityData::Teleporter(_, _) => {
return Err(Content::localized("command-unimplemented-teleporter-spawn"));
}, },
SpawnEntityData::Npc(data) => { SpawnEntityData::Npc(data) => {
let (npc_builder, _pos) = data.to_npc_builder(); let (npc_builder, _pos) = data.to_npc_builder();
@ -2000,8 +1994,11 @@ fn handle_spawn_campfire(
server server
.state .state
.ecs() .ecs()
.read_resource::<EventBus<CreateWaypointEvent>>() .read_resource::<EventBus<CreateSpecialEntityEvent>>()
.emit_now(CreateWaypointEvent(pos.0)); .emit_now(CreateSpecialEntityEvent {
pos: pos.0,
entity: SpecialEntity::Waypoint,
});
server.notify_client( server.notify_client(
client, client,

View File

@ -13,9 +13,10 @@ use common::{
}, },
event::{ event::{
CreateItemDropEvent, CreateNpcEvent, CreateObjectEvent, CreateShipEvent, CreateItemDropEvent, CreateNpcEvent, CreateObjectEvent, CreateShipEvent,
CreateTeleporterEvent, CreateWaypointEvent, EventBus, InitializeCharacterEvent, CreateSpecialEntityEvent, EventBus, InitializeCharacterEvent, InitializeSpectatorEvent,
InitializeSpectatorEvent, ShockwaveEvent, ShootEvent, UpdateCharacterDataEvent, ShockwaveEvent, ShootEvent, UpdateCharacterDataEvent,
}, },
generation::SpecialEntity,
mounting::{Mounting, Volume, VolumeMounting, VolumePos}, mounting::{Mounting, Volume, VolumeMounting, VolumePos},
outcome::Outcome, outcome::Outcome,
resources::{Secs, Time}, resources::{Secs, Time},
@ -388,53 +389,76 @@ pub fn handle_shockwave(server: &mut Server, ev: ShockwaveEvent) {
.build(); .build();
} }
pub fn handle_create_waypoint(server: &mut Server, ev: CreateWaypointEvent) { pub fn handle_create_special_entity(server: &mut Server, ev: CreateSpecialEntityEvent) {
let time = server.state.get_time(); let time = server.state.get_time();
server
.state
.create_object(Pos(ev.0), comp::object::Body::CampfireLit)
.with(LightEmitter {
col: Rgb::new(1.0, 0.3, 0.1),
strength: 5.0,
flicker: 1.0,
animated: true,
})
.with(WaypointArea::default())
.with(comp::Immovable)
.with(comp::Auras::new(vec![
Aura::new(
AuraKind::Buff {
kind: BuffKind::CampfireHeal,
data: BuffData::new(0.02, Some(Secs(1.0))),
category: BuffCategory::Natural,
source: BuffSource::World,
},
5.0,
None,
AuraTarget::All,
Time(time),
),
Aura::new(
AuraKind::Buff {
kind: BuffKind::Burning,
data: BuffData::new(2.0, Some(Secs(10.0))),
category: BuffCategory::Natural,
source: BuffSource::World,
},
0.7,
None,
AuraTarget::All,
Time(time),
),
]))
.build();
}
pub fn handle_create_teleporter(server: &mut Server, ev: CreateTeleporterEvent) { match ev.entity {
server SpecialEntity::Waypoint => {
.state server
.create_teleporter(comp::Pos(ev.0), ev.1) .state
.build(); .create_object(Pos(ev.pos), comp::object::Body::CampfireLit)
.with(LightEmitter {
col: Rgb::new(1.0, 0.3, 0.1),
strength: 5.0,
flicker: 1.0,
animated: true,
})
.with(WaypointArea::default())
.with(comp::Immovable)
.with(comp::EnteredAuras::default())
.with(comp::Auras::new(vec![
Aura::new(
AuraKind::Buff {
kind: BuffKind::CampfireHeal,
data: BuffData::new(0.02, Some(Secs(1.0))),
category: BuffCategory::Natural,
source: BuffSource::World,
},
5.0,
None,
AuraTarget::All,
Time(time),
),
Aura::new(
AuraKind::Buff {
kind: BuffKind::Burning,
data: BuffData::new(2.0, Some(Secs(10.0))),
category: BuffCategory::Natural,
source: BuffSource::World,
},
0.7,
None,
AuraTarget::All,
Time(time),
),
]))
.build();
},
SpecialEntity::Teleporter(portal) => {
server
.state
.create_teleporter(comp::Pos(ev.pos), portal)
.build();
},
SpecialEntity::ArenaTotem { range } => {
server
.state
.create_object(Pos(ev.pos), comp::object::Body::GnarlingTotemGreen)
.with(comp::Immovable)
.with(comp::EnteredAuras::default())
.with(comp::Auras::new(vec![
Aura::new(
AuraKind::FriendlyFire,
range,
None,
AuraTarget::All,
Time(time),
),
Aura::new(AuraKind::ForcePvP, range, None, AuraTarget::All, Time(time)),
]))
.build();
},
}
} }
pub fn handle_create_item_drop(server: &mut Server, ev: CreateItemDropEvent) { pub fn handle_create_item_drop(server: &mut Server, ev: CreateItemDropEvent) {

View File

@ -2165,8 +2165,7 @@ pub fn handle_transform(
#[derive(Debug)] #[derive(Debug)]
pub enum TransformEntityError { pub enum TransformEntityError {
EntityDead, EntityDead,
UnexpectedNpcWaypoint, UnexpectedSpecialEntity,
UnexpectedNpcTeleporter,
LoadingCharacter, LoadingCharacter,
EntityIsPlayer, EntityIsPlayer,
} }
@ -2308,11 +2307,8 @@ pub fn transform_entity(
} }
} }
}, },
SpawnEntityData::Waypoint(_) => { SpawnEntityData::Special(_, _) => {
return Err(TransformEntityError::UnexpectedNpcWaypoint); return Err(TransformEntityError::UnexpectedSpecialEntity);
},
SpawnEntityData::Teleporter(_, _) => {
return Err(TransformEntityError::UnexpectedNpcTeleporter);
}, },
} }

View File

@ -14,8 +14,8 @@ use specs::{
use self::{ use self::{
entity_creation::{ entity_creation::{
handle_create_item_drop, handle_create_npc, handle_create_object, handle_create_ship, handle_create_item_drop, handle_create_npc, handle_create_object, handle_create_ship,
handle_create_teleporter, handle_create_waypoint, handle_initialize_character, handle_create_special_entity, handle_initialize_character, handle_initialize_spectator,
handle_initialize_spectator, handle_loaded_character_data, handle_shockwave, handle_shoot, handle_loaded_character_data, handle_shockwave, handle_shoot,
}, },
entity_manipulation::{handle_delete, handle_transform}, entity_manipulation::{handle_delete, handle_transform},
interaction::handle_tame_pet, interaction::handle_tame_pet,
@ -146,8 +146,7 @@ impl Server {
self.handle_serial_events(handle_create_ship); self.handle_serial_events(handle_create_ship);
self.handle_serial_events(handle_shoot); self.handle_serial_events(handle_shoot);
self.handle_serial_events(handle_shockwave); self.handle_serial_events(handle_shockwave);
self.handle_serial_events(handle_create_waypoint); self.handle_serial_events(handle_create_special_entity);
self.handle_serial_events(handle_create_teleporter);
self.handle_serial_events(handle_create_item_drop); self.handle_serial_events(handle_create_item_drop);
self.handle_serial_events(handle_create_object); self.handle_serial_events(handle_create_object);
self.handle_serial_events(handle_delete); self.handle_serial_events(handle_delete);

View File

@ -13,12 +13,10 @@ use crate::{
use common::{ use common::{
calendar::Calendar, calendar::Calendar,
comp::{ comp::{
self, agent, biped_small, bird_medium, misc::PortalData, BehaviorCapability, ForceUpdate, self, agent, biped_small, bird_medium, BehaviorCapability, ForceUpdate, Pos, Presence,
Pos, Presence, Waypoint, Waypoint,
},
event::{
CreateNpcEvent, CreateTeleporterEvent, CreateWaypointEvent, EmitExt, EventBus, NpcBuilder,
}, },
event::{CreateNpcEvent, CreateSpecialEntityEvent, EmitExt, EventBus, NpcBuilder},
event_emitters, event_emitters,
generation::{EntityInfo, SpecialEntity}, generation::{EntityInfo, SpecialEntity},
lottery::LootSpec, lottery::LootSpec,
@ -58,8 +56,7 @@ type RtSimData<'a> = ();
event_emitters! { event_emitters! {
struct Events[Emitters] { struct Events[Emitters] {
create_npc: CreateNpcEvent, create_npc: CreateNpcEvent,
create_waypoint: CreateWaypointEvent, create_waypoint: CreateSpecialEntityEvent,
create_teleporter: CreateTeleporterEvent,
} }
} }
@ -207,8 +204,8 @@ impl<'a> System<'a> for Sys {
let data = SpawnEntityData::from_entity_info(entity); let data = SpawnEntityData::from_entity_info(entity);
match data { match data {
SpawnEntityData::Waypoint(pos) => { SpawnEntityData::Special(pos, entity) => {
emitters.emit(CreateWaypointEvent(pos)); emitters.emit(CreateSpecialEntityEvent { pos, entity });
}, },
SpawnEntityData::Npc(data) => { SpawnEntityData::Npc(data) => {
let (npc_builder, pos) = data.to_npc_builder(); let (npc_builder, pos) = data.to_npc_builder();
@ -220,9 +217,6 @@ impl<'a> System<'a> for Sys {
rider: None, rider: None,
}); });
}, },
SpawnEntityData::Teleporter(pos, teleporter) => {
emitters.emit(CreateTeleporterEvent(pos, teleporter));
},
} }
} }
} }
@ -423,8 +417,7 @@ pub struct NpcData {
#[derive(Debug)] #[derive(Debug)]
pub enum SpawnEntityData { pub enum SpawnEntityData {
Npc(NpcData), Npc(NpcData),
Waypoint(Vec3<f32>), Special(Vec3<f32>, SpecialEntity),
Teleporter(Vec3<f32>, PortalData),
} }
impl SpawnEntityData { impl SpawnEntityData {
@ -454,10 +447,7 @@ impl SpawnEntityData {
} = entity; } = entity;
if let Some(special) = special_entity { if let Some(special) = special_entity {
return match special { return Self::Special(pos, special);
SpecialEntity::Waypoint => Self::Waypoint(pos),
SpecialEntity::Teleporter(teleporter) => Self::Teleporter(pos, teleporter),
};
} }
let name = name.unwrap_or_else(|| "Unnamed".to_string()); let name = name.unwrap_or_else(|| "Unnamed".to_string());

View File

@ -1234,9 +1234,14 @@ impl Structure for DesertCityArena {
.fill(sandstone.clone()); .fill(sandstone.clone());
// campfires & repair benches // campfires & repair benches
painter.spawn( painter.spawn(
EntityInfo::at((spire_pos - 2).with_z(base - 1).map(|e| e as f32)) EntityInfo::at((spire_pos - 2).with_z(base - 1).as_())
.into_special(SpecialEntity::Waypoint), .into_special(SpecialEntity::Waypoint),
); );
painter.spawn(EntityInfo::at(center.with_z(base).as_()).into_special(
SpecialEntity::ArenaTotem {
range: length as f32,
},
));
painter.sprite((spire_pos + 2).with_z(base - 1), SpriteKind::RepairBench); painter.sprite((spire_pos + 2).with_z(base - 1), SpriteKind::RepairBench);
// lamps // lamps