mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 07:03:16 +00:00
add perma death option, make cessation nicer, fix spectator shields and cursors not appearing sometimes, make default settings transfer nicer
This commit is contained in:
parent
79e8f73d63
commit
2fc0e76f2c
10 changed files with 331 additions and 131 deletions
|
@ -99,6 +99,7 @@ local_health_desc_2 = There is a respawn mechanic.
|
|||
Health-percent-lost-on-reviving = HP percent lost on reviving
|
||||
global_hp_loss = Lose HP globally
|
||||
no_material_damage = No material damage
|
||||
perma_death = Perma death
|
||||
shared_health_desc_1 = Health is shared, but scales with player count.
|
||||
shared_health_desc_2 = Percentage-based damage and full heals are adjusted.
|
||||
shared_health_desc_3 = The original mode.
|
||||
|
|
|
@ -63,15 +63,39 @@ pub(crate) enum GameMode {
|
|||
// MestariMina, // TODO later
|
||||
}
|
||||
|
||||
#[derive(Debug, Decode, Encode, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Debug, Decode, Encode, Clone, Serialize, Deserialize, PartialEq, Default)]
|
||||
#[serde(default)]
|
||||
pub struct GameSettings {
|
||||
seed: u64,
|
||||
debug_mode: Option<bool>,
|
||||
world_sync_version: Option<u32>,
|
||||
player_tether: Option<bool>,
|
||||
tether_length: Option<u32>,
|
||||
use_constant_seed: bool,
|
||||
item_dedup: Option<bool>,
|
||||
enemy_hp_mult: Option<f32>,
|
||||
world_sync_interval: Option<u32>,
|
||||
game_mode: Option<GameMode>,
|
||||
friendly_fire: Option<bool>,
|
||||
friendly_fire_team: Option<i32>,
|
||||
chunk_target: Option<u32>,
|
||||
enemy_sync_interval: Option<u32>,
|
||||
randomize_perks: Option<bool>,
|
||||
progress: Vec<String>,
|
||||
max_players: Option<u32>,
|
||||
health_per_player: Option<u32>,
|
||||
health_lost_on_revive: Option<u32>,
|
||||
no_material_damage: Option<bool>,
|
||||
global_hp_loss: Option<bool>,
|
||||
perk_ban_list: Option<String>,
|
||||
perma_death: Option<bool>,
|
||||
}
|
||||
|
||||
pub struct DefaultSettings {
|
||||
debug_mode: bool,
|
||||
world_sync_version: u32,
|
||||
player_tether: bool,
|
||||
tether_length: u32,
|
||||
use_constant_seed: bool,
|
||||
item_dedup: bool,
|
||||
enemy_hp_mult: f32,
|
||||
world_sync_interval: u32,
|
||||
|
@ -81,24 +105,22 @@ pub struct GameSettings {
|
|||
chunk_target: u32,
|
||||
enemy_sync_interval: u32,
|
||||
randomize_perks: bool,
|
||||
progress: Vec<String>,
|
||||
max_players: u32,
|
||||
health_per_player: u32,
|
||||
health_lost_on_revive: u32,
|
||||
no_material_damage: bool,
|
||||
global_hp_loss: bool,
|
||||
perk_ban_list: String,
|
||||
perma_death: bool,
|
||||
}
|
||||
|
||||
impl Default for GameSettings {
|
||||
impl Default for DefaultSettings {
|
||||
fn default() -> Self {
|
||||
GameSettings {
|
||||
seed: 0,
|
||||
DefaultSettings {
|
||||
debug_mode: false,
|
||||
world_sync_version: 2,
|
||||
player_tether: true,
|
||||
tether_length: 2048,
|
||||
use_constant_seed: false,
|
||||
item_dedup: true,
|
||||
randomize_perks: true,
|
||||
enemy_hp_mult: 1.0,
|
||||
|
@ -108,13 +130,13 @@ impl Default for GameSettings {
|
|||
friendly_fire_team: 0,
|
||||
chunk_target: 24,
|
||||
enemy_sync_interval: 3,
|
||||
progress: Vec::new(),
|
||||
max_players: 250,
|
||||
health_per_player: 100,
|
||||
health_lost_on_revive: 0,
|
||||
no_material_damage: false,
|
||||
global_hp_loss: false,
|
||||
perk_ban_list: String::new(),
|
||||
perk_ban_list: "GLOBAL_GORE,GLASS_CANNON,REVENGE_RATS,PLAGUE_RATS,VOMIT_RATS,CORDYCEPS,MOLD,FUNGAL_DISEASE,HOMUNCULUS,LUKKI_MINION".to_string(),
|
||||
perma_death: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -498,7 +520,7 @@ impl App {
|
|||
let peer = net::steam_networking::SteamPeer::new_host(
|
||||
steamworks::LobbyType::Private,
|
||||
self.steam_state.as_ref().unwrap().client.clone(),
|
||||
self.app_saved_state.game_settings.max_players,
|
||||
self.app_saved_state.game_settings.max_players.unwrap_or(DefaultSettings::default().max_players),
|
||||
);
|
||||
let netman = net::NetManager::new(PeerVariant::Steam(peer), self.get_netman_init());
|
||||
self.set_netman_settings(&netman);
|
||||
|
@ -720,56 +742,93 @@ impl App {
|
|||
}
|
||||
|
||||
fn show_game_settings(&mut self, ui: &mut Ui, show_local: bool) {
|
||||
let def = DefaultSettings::default();
|
||||
heading_with_underline(ui, tr("connect_settings"));
|
||||
let game_settings = &mut self.app_saved_state.game_settings;
|
||||
ui.label(tr("Game-mode"));
|
||||
ui.radio_value(
|
||||
&mut game_settings.game_mode,
|
||||
GameMode::SharedHealth,
|
||||
tr("Shared-health"),
|
||||
);
|
||||
ui.radio_value(
|
||||
&mut game_settings.game_mode,
|
||||
GameMode::LocalHealth,
|
||||
tr("Local-health"),
|
||||
);
|
||||
{
|
||||
let mut temp = game_settings.game_mode.unwrap_or(def.game_mode);
|
||||
ui.label(tr("Game-mode"));
|
||||
if ui.radio_value(
|
||||
&mut temp,
|
||||
GameMode::SharedHealth,
|
||||
tr("Shared-health"),
|
||||
).changed() || ui.radio_value(
|
||||
&mut temp,
|
||||
GameMode::LocalHealth,
|
||||
tr("Local-health"),
|
||||
).changed() {
|
||||
game_settings.game_mode = Some(temp)
|
||||
}
|
||||
}
|
||||
|
||||
ui.scope(|ui| {
|
||||
ui.set_height(100.0);
|
||||
|
||||
match game_settings.game_mode {
|
||||
match game_settings.game_mode.unwrap_or(def.game_mode) {
|
||||
GameMode::SharedHealth => {
|
||||
ui.label(tr("shared_health_desc_1"));
|
||||
ui.label(tr("shared_health_desc_2"));
|
||||
ui.label(tr("shared_health_desc_3"));
|
||||
ui.add_space(5.0);
|
||||
ui.label(tr("Health-per-player"));
|
||||
ui.add(Slider::new(&mut game_settings.health_per_player, 0..=100));
|
||||
let mut temp = game_settings.health_per_player.unwrap_or(def.health_per_player);
|
||||
if ui.add(Slider::new(&mut temp, 0..=100)).changed() {
|
||||
game_settings.health_per_player = Some(temp)
|
||||
}
|
||||
}
|
||||
GameMode::LocalHealth => {
|
||||
ui.label(tr("local_health_desc_1"));
|
||||
ui.label(tr("local_health_desc_2"));
|
||||
ui.add_space(5.0);
|
||||
ui.label(tr("Health-percent-lost-on-reviving"));
|
||||
ui.add(Slider::new(
|
||||
&mut game_settings.health_lost_on_revive,
|
||||
0..=100,
|
||||
));
|
||||
ui.checkbox(&mut game_settings.global_hp_loss, tr("global_hp_loss"));
|
||||
ui.checkbox(
|
||||
&mut game_settings.no_material_damage,
|
||||
tr("no_material_damage"),
|
||||
);
|
||||
{
|
||||
let mut temp = game_settings.health_lost_on_revive.unwrap_or(def.health_lost_on_revive);
|
||||
if ui.add(Slider::new(
|
||||
&mut temp,
|
||||
0..=100,
|
||||
)).changed() {
|
||||
game_settings.health_lost_on_revive = Some(temp)
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut temp = game_settings.global_hp_loss.unwrap_or(def.global_hp_loss);
|
||||
if ui.checkbox(&mut temp, tr("global_hp_loss")).changed() {
|
||||
game_settings.global_hp_loss = Some(temp)
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut temp = game_settings.no_material_damage.unwrap_or(def.no_material_damage);
|
||||
if ui.checkbox(
|
||||
&mut temp,
|
||||
tr("no_material_damage"),
|
||||
).changed() {
|
||||
game_settings.no_material_damage = Some(temp)
|
||||
}
|
||||
}
|
||||
ui.add_space(1.0);
|
||||
{
|
||||
let mut temp = game_settings.perma_death.unwrap_or(def.perma_death);
|
||||
if ui.checkbox(
|
||||
&mut temp,
|
||||
tr("perma_death"),
|
||||
).changed() {
|
||||
game_settings.perma_death = Some(temp)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ui.add_space(10.0);
|
||||
ui.label(tr("connect_settings_debug"));
|
||||
ui.checkbox(
|
||||
&mut game_settings.debug_mode,
|
||||
tr("connect_settings_debug_en"),
|
||||
);
|
||||
{
|
||||
let mut temp = game_settings.debug_mode.unwrap_or(def.debug_mode);
|
||||
if ui.checkbox(
|
||||
&mut temp,
|
||||
tr("connect_settings_debug_en"),
|
||||
).changed() {
|
||||
game_settings.debug_mode = Some(temp)
|
||||
}
|
||||
}
|
||||
ui.checkbox(
|
||||
&mut game_settings.use_constant_seed,
|
||||
tr("connect_settings_debug_fixed_seed"),
|
||||
|
@ -780,40 +839,87 @@ impl App {
|
|||
});
|
||||
ui.add_space(10.0);
|
||||
ui.label(tr("connect_settings_max_players"));
|
||||
ui.add(Slider::new(&mut game_settings.max_players, 2..=250));
|
||||
{
|
||||
let mut temp = game_settings.max_players.unwrap_or(def.max_players);
|
||||
if ui.add(Slider::new(&mut temp, 2..=250)).changed()
|
||||
{
|
||||
game_settings.max_players = Some(temp)
|
||||
}
|
||||
}
|
||||
ui.add_space(10.0);
|
||||
ui.label(tr("Amount-of-chunks-host-has-loaded-at-once-synced-enemies-and-physics-objects-need-to-be-loaded-in-by-host-to-be-rendered-by-clients"));
|
||||
ui.add(Slider::new(&mut game_settings.chunk_target, 12..=64));
|
||||
|
||||
{
|
||||
let mut temp = game_settings.chunk_target.unwrap_or(def.chunk_target);
|
||||
if ui.add(Slider::new(&mut temp, 12..=64)).changed() {
|
||||
game_settings.chunk_target = Some(temp)
|
||||
}
|
||||
}
|
||||
ui.add_space(20.0);
|
||||
ui.label(tr("connect_settings_player_tether_desc"));
|
||||
ui.checkbox(
|
||||
&mut game_settings.player_tether,
|
||||
tr("connect_settings_player_tether"),
|
||||
);
|
||||
ui.add(
|
||||
Slider::new(&mut game_settings.tether_length, 10..=5000)
|
||||
.text(tr("connect_settings_player_tether_length")),
|
||||
);
|
||||
{
|
||||
let mut temp = game_settings.player_tether.unwrap_or(def.player_tether);
|
||||
if ui.checkbox(
|
||||
&mut temp,
|
||||
tr("connect_settings_player_tether"),
|
||||
).changed()
|
||||
{
|
||||
game_settings.player_tether = Some(temp)
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut temp = game_settings.tether_length.unwrap_or(def.tether_length);
|
||||
if ui.add(
|
||||
Slider::new(&mut temp, 10..=5000)
|
||||
.text(tr("connect_settings_player_tether_length")),
|
||||
).changed() {
|
||||
game_settings.tether_length = Some(temp)
|
||||
}
|
||||
}
|
||||
ui.add_space(20.0);
|
||||
ui.checkbox(
|
||||
&mut game_settings.item_dedup,
|
||||
tr("connect_settings_item_dedup"),
|
||||
);
|
||||
ui.checkbox(
|
||||
&mut game_settings.randomize_perks,
|
||||
tr("Have-perk-pools-be-independent-of-each-other"),
|
||||
);
|
||||
ui.horizontal(|ui| {
|
||||
ui.text_edit_singleline(&mut game_settings.perk_ban_list);
|
||||
ui.label("perk ban list, comma seperated");
|
||||
});
|
||||
ui.add(
|
||||
Slider::new(&mut game_settings.enemy_hp_mult, 1.0..=1000.0)
|
||||
.logarithmic(true)
|
||||
.text(tr("connect_settings_enemy_hp_scale")),
|
||||
);
|
||||
ui.checkbox(&mut game_settings.friendly_fire, tr("Enable-friendly-fire"));
|
||||
{
|
||||
let mut temp = game_settings.item_dedup.unwrap_or(def.item_dedup);
|
||||
if ui.checkbox(
|
||||
&mut temp,
|
||||
tr("connect_settings_item_dedup"),
|
||||
).changed() {
|
||||
game_settings.item_dedup = Some(temp)
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut temp = game_settings.randomize_perks.unwrap_or(def.randomize_perks);
|
||||
if ui.checkbox(
|
||||
&mut temp,
|
||||
tr("Have-perk-pools-be-independent-of-each-other"),
|
||||
).changed() {
|
||||
game_settings.randomize_perks = Some(temp)
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut temp = game_settings.perk_ban_list.clone().unwrap_or(def.perk_ban_list);
|
||||
ui.horizontal(|ui| {
|
||||
if ui.text_edit_singleline(&mut temp)
|
||||
.changed() {
|
||||
game_settings.perk_ban_list = Some(temp)
|
||||
}
|
||||
ui.label("perk ban list, comma seperated");
|
||||
});
|
||||
}
|
||||
{
|
||||
let mut temp = game_settings.enemy_hp_mult.unwrap_or(def.enemy_hp_mult);
|
||||
if ui.add(
|
||||
Slider::new(&mut temp, 1.0..=1000.0)
|
||||
.logarithmic(true)
|
||||
.text(tr("connect_settings_enemy_hp_scale")),
|
||||
).changed() {
|
||||
game_settings.enemy_hp_mult = Some(temp)
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut temp = game_settings.friendly_fire.unwrap_or(def.friendly_fire);
|
||||
if ui.checkbox(&mut temp, tr("Enable-friendly-fire")).changed() {
|
||||
game_settings.friendly_fire = Some(temp)
|
||||
}
|
||||
}
|
||||
if show_local {
|
||||
heading_with_underline(ui, tr("connect_settings_local"));
|
||||
ui.checkbox(
|
||||
|
@ -1097,10 +1203,14 @@ impl eframe::App for App {
|
|||
ui.add_space(15.0);
|
||||
if netman.friendly_fire.load(Ordering::Relaxed) {
|
||||
let last = self.app_saved_state.game_settings.friendly_fire_team;
|
||||
ui.add(Slider::new(&mut self.app_saved_state.game_settings.friendly_fire_team, -1..=16));
|
||||
let def = DefaultSettings::default();
|
||||
let mut temp = self.app_saved_state.game_settings.friendly_fire_team.unwrap_or(def.friendly_fire_team);
|
||||
if ui.add(Slider::new(&mut temp, -1..=16)).changed() {
|
||||
self.app_saved_state.game_settings.friendly_fire_team = Some(temp);
|
||||
}
|
||||
if last != self.app_saved_state.game_settings.friendly_fire_team
|
||||
|| netman.friendly_fire_team.load(Ordering::Relaxed) == -2 {
|
||||
netman.friendly_fire_team.store(self.app_saved_state.game_settings.friendly_fire_team, Ordering::Relaxed);
|
||||
netman.friendly_fire_team.store(temp, Ordering::Relaxed);
|
||||
}
|
||||
ui.label("what team number you are on, 0 means no team, -1 means friendly");
|
||||
ui.add_space(15.0);
|
||||
|
|
|
@ -26,11 +26,7 @@ use tungstenite::{accept, WebSocket};
|
|||
|
||||
use crate::mod_manager::ModmanagerSettings;
|
||||
use crate::player_cosmetics::{create_player_png, PlayerPngDesc};
|
||||
use crate::{
|
||||
bookkeeping::save_state::{SaveState, SaveStateEntry},
|
||||
recorder::Recorder,
|
||||
GameSettings, PlayerColor,
|
||||
};
|
||||
use crate::{bookkeeping::save_state::{SaveState, SaveStateEntry}, recorder::Recorder, DefaultSettings, GameSettings, PlayerColor};
|
||||
pub mod messages;
|
||||
mod proxy_opt;
|
||||
pub mod steam_networking;
|
||||
|
@ -133,6 +129,7 @@ pub struct NetManager {
|
|||
pub friendly_fire: AtomicBool,
|
||||
pub ban_list: Mutex<Vec<OmniPeerId>>,
|
||||
pub kick_list: Mutex<Vec<OmniPeerId>>,
|
||||
pub no_more_players: AtomicBool,
|
||||
}
|
||||
|
||||
impl NetManager {
|
||||
|
@ -155,6 +152,7 @@ impl NetManager {
|
|||
friendly_fire: AtomicBool::new(false),
|
||||
ban_list: Default::default(),
|
||||
kick_list: Default::default(),
|
||||
no_more_players: AtomicBool::new(false),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
@ -472,6 +470,7 @@ impl NetManager {
|
|||
.expect("can set write timeout");
|
||||
|
||||
let settings = self.settings.lock().unwrap();
|
||||
let def = DefaultSettings::default();
|
||||
state.try_ws_write(ws_encode_proxy("seed", settings.seed));
|
||||
let my_id = self.peer.my_id();
|
||||
state.try_ws_write(ws_encode_proxy("peer_id", format!("{:016x}", my_id.0)));
|
||||
|
@ -485,25 +484,27 @@ impl NetManager {
|
|||
} else {
|
||||
info!("No nickname chosen");
|
||||
}
|
||||
self.friendly_fire
|
||||
.store(settings.friendly_fire, atomic::Ordering::Relaxed);
|
||||
state.try_ws_write_option("friendly_fire", settings.friendly_fire);
|
||||
state.try_ws_write_option("debug", settings.debug_mode);
|
||||
state.try_ws_write_option("world_sync_version", settings.world_sync_version);
|
||||
state.try_ws_write_option("player_tether", settings.player_tether);
|
||||
state.try_ws_write_option("tether_length", settings.tether_length);
|
||||
state.try_ws_write_option("item_dedup", settings.item_dedup);
|
||||
state.try_ws_write_option("randomize_perks", settings.randomize_perks);
|
||||
state.try_ws_write_option("enemy_hp_scale", settings.enemy_hp_mult);
|
||||
state.try_ws_write_option("world_sync_interval", settings.world_sync_interval);
|
||||
state.try_ws_write_option("game_mode", settings.game_mode);
|
||||
state.try_ws_write_option("chunk_target", settings.chunk_target);
|
||||
state.try_ws_write_option("health_per_player", settings.health_per_player);
|
||||
state.try_ws_write_option("enemy_sync_interval", settings.enemy_sync_interval);
|
||||
state.try_ws_write_option("global_hp_loss", settings.global_hp_loss);
|
||||
state.try_ws_write_option("perk_ban_list", settings.perk_ban_list.as_str());
|
||||
state.try_ws_write_option("no_material_damage", settings.no_material_damage);
|
||||
state.try_ws_write_option("health_lost_on_revive", settings.health_lost_on_revive);
|
||||
let ff = settings.friendly_fire.unwrap_or(def.friendly_fire);
|
||||
self.friendly_fire.store(ff, atomic::Ordering::Relaxed);
|
||||
state.try_ws_write_option("friendly_fire", ff);
|
||||
state.try_ws_write_option("debug", settings.debug_mode.unwrap_or(def.debug_mode));
|
||||
state.try_ws_write_option("world_sync_version", settings.world_sync_version.unwrap_or(def.world_sync_version));
|
||||
state.try_ws_write_option("player_tether", settings.player_tether.unwrap_or(def.player_tether));
|
||||
state.try_ws_write_option("tether_length", settings.tether_length.unwrap_or(def.tether_length));
|
||||
state.try_ws_write_option("item_dedup", settings.item_dedup.unwrap_or(def.item_dedup));
|
||||
state.try_ws_write_option("randomize_perks", settings.randomize_perks.unwrap_or(def.randomize_perks));
|
||||
state.try_ws_write_option("enemy_hp_scale", settings.enemy_hp_mult.unwrap_or(def.enemy_hp_mult));
|
||||
state.try_ws_write_option("world_sync_interval", settings.world_sync_interval.unwrap_or(def.world_sync_interval));
|
||||
state.try_ws_write_option("game_mode", settings.game_mode.unwrap_or(def.game_mode));
|
||||
state.try_ws_write_option("chunk_target", settings.chunk_target.unwrap_or(def.chunk_target));
|
||||
state.try_ws_write_option("health_per_player", settings.health_per_player.unwrap_or(def.health_per_player));
|
||||
state.try_ws_write_option("enemy_sync_interval", settings.enemy_sync_interval.unwrap_or(def.enemy_sync_interval));
|
||||
state.try_ws_write_option("global_hp_loss", settings.global_hp_loss.unwrap_or(def.global_hp_loss));
|
||||
state.try_ws_write_option("perma_death", settings.perma_death.unwrap_or(def.perma_death));
|
||||
let lst = settings.clone();
|
||||
state.try_ws_write_option("perk_ban_list", lst.perk_ban_list.unwrap_or(def.perk_ban_list).as_str());
|
||||
state.try_ws_write_option("no_material_damage", settings.no_material_damage.unwrap_or(def.no_material_damage));
|
||||
state.try_ws_write_option("health_lost_on_revive", settings.health_lost_on_revive.unwrap_or(def.health_lost_on_revive));
|
||||
let rgb = self.init_settings.player_color.player_main;
|
||||
state.try_ws_write_option(
|
||||
"mina_color",
|
||||
|
|
37
quant.ew/data/entities/animals/nibbana.xml
Normal file
37
quant.ew/data/entities/animals/nibbana.xml
Normal file
|
@ -0,0 +1,37 @@
|
|||
<Entity tags="polymorphed_cessation" name="$animal_player" >
|
||||
<PlatformShooterPlayerComponent
|
||||
center_camera_on_this_entity="1"
|
||||
aiming_reticle_distance_from_character="60"
|
||||
camera_max_distance_from_character="50"
|
||||
move_camera_with_aim="1"
|
||||
eating_area_min.x="-6"
|
||||
eating_area_max.x="6"
|
||||
eating_area_min.y="-4"
|
||||
eating_area_max.y="6"
|
||||
eating_cells_per_frame="2"
|
||||
></PlatformShooterPlayerComponent>
|
||||
<ControlsComponent
|
||||
enabled="1"
|
||||
gamepad_fire_on_thumbstick_extend="0"
|
||||
gamepad_fire_on_thumbstick_extend_threshold="0.9"
|
||||
gamepad_indirect_aiming_enabled="0"
|
||||
></ControlsComponent>
|
||||
<Entity name="cursor">
|
||||
<SpriteComponent
|
||||
alpha="1"
|
||||
image_file="mods/quant.ew/files/resource/sprites/cursor.png"
|
||||
next_rect_animation=""
|
||||
offset_x="6.5"
|
||||
offset_y="6.5"
|
||||
emissive="1"
|
||||
additive="1"
|
||||
rect_animation=""
|
||||
z_index="1"
|
||||
update_transform="1"
|
||||
update_transform_rotation="0"
|
||||
has_special_scale="1"
|
||||
special_scale_x="0.5"
|
||||
special_scale_y="0.5"
|
||||
></SpriteComponent>
|
||||
</Entity>
|
||||
</Entity>
|
|
@ -176,9 +176,22 @@ local function player_died()
|
|||
|
||||
-- This may look like a hack, but it allows to use existing poly machinery to change player entity AND to store the original player for later,
|
||||
-- Which is, like, perfect.
|
||||
GameAddFlagRun("ew_flag_notplayer_active")
|
||||
if ctx.proxy_opt.perma_death then
|
||||
local ent = LoadGameEffectEntityTo(ctx.my_player.entity, "mods/quant.ew/files/system/local_health/notplayer/cessation.xml")
|
||||
polymorph.switch_entity(ent + 1)
|
||||
GameAddFlagRun("msg_gods_looking")
|
||||
GameAddFlagRun("msg_gods_looking2")
|
||||
EntityAddTag(ctx.my_player.entity, "ew_notplayer")
|
||||
for _, child in ipairs(EntityGetAllChildren(ctx.my_player.entity) or {}) do
|
||||
if EntityGetName(child) == "cursor" then
|
||||
EntitySetComponentIsEnabled(child, EntityGetFirstComponentIncludingDisabled(child, "SpriteComponent"), false)
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
local ent = LoadGameEffectEntityTo(ctx.my_player.entity, "mods/quant.ew/files/system/local_health/notplayer/poly_effect.xml")
|
||||
ctx.my_player.entity = ent + 1
|
||||
GameAddFlagRun("ew_flag_notplayer_active")
|
||||
do_switch_effect(false)
|
||||
EntitySetName(ctx.my_player.entity, ctx.my_id.."?")
|
||||
util.set_ent_health(ctx.my_player.entity, {max_hp, max_hp})
|
||||
|
@ -191,7 +204,7 @@ local function player_died()
|
|||
remove_healthbar_locally()
|
||||
for _, child in ipairs(EntityGetAllChildren(ctx.my_player.entity) or {}) do
|
||||
if EntityGetName(child) == "cursor" or EntityGetName(child) == "notcursor" then
|
||||
EntityKill(child)
|
||||
EntitySetComponentIsEnabled(child, EntityGetFirstComponentIncludingDisabled(child, "SpriteComponent"), false)
|
||||
end
|
||||
end
|
||||
inventory_helper.set_item_data(item_data, ctx.my_player)
|
||||
|
|
13
quant.ew/files/system/local_health/notplayer/cessation.xml
Normal file
13
quant.ew/files/system/local_health/notplayer/cessation.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<Entity>
|
||||
<InheritTransformComponent>
|
||||
</InheritTransformComponent>
|
||||
|
||||
<GameEffectComponent
|
||||
effect="POLYMORPH_CESSATION"
|
||||
frames="-1"
|
||||
disable_movement="0"
|
||||
polymorph_target="data/entities/animals/nibbana.xml"
|
||||
>
|
||||
</GameEffectComponent >
|
||||
|
||||
</Entity>
|
|
@ -637,6 +637,8 @@ local function choose_movement()
|
|||
ComponentSetValue2(state.control_component, "mButtonFrameRight", GameGetFrameNum()+100)
|
||||
return
|
||||
end
|
||||
local air = ComponentGetValue2(state.damage_model, "air_in_lungs")
|
||||
local fly = ComponentGetValue2(state.data_component, "mFlyingTimeLeft")
|
||||
if state.target == nil or (has_ambrosia(ctx.my_player.entity) and state.init_timer > no_shoot_time + 4) then
|
||||
state.control_a = false
|
||||
state.control_d = false
|
||||
|
@ -663,13 +665,14 @@ local function choose_movement()
|
|||
move = -1
|
||||
end
|
||||
|
||||
local air = ComponentGetValue2(state.damage_model, "air_in_lungs")
|
||||
if air < 1 then
|
||||
state.control_w = true
|
||||
state.control_s = false
|
||||
elseif air < 2 then
|
||||
state.control_s = true
|
||||
state.control_w = false
|
||||
if air < 2 then
|
||||
if fly < 0.5 then
|
||||
state.control_s = true
|
||||
state.control_w = false
|
||||
else
|
||||
state.control_w = true
|
||||
state.control_s = false
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
@ -752,7 +755,7 @@ local function choose_movement()
|
|||
on_right = my_x > t_x
|
||||
end
|
||||
|
||||
if ComponentGetValue2(state.data_component, "mFlyingTimeLeft") < 0.2 and GameGetFrameNum() % 300 > 250 then
|
||||
if fly < 0.2 and GameGetFrameNum() % 300 > 250 then
|
||||
rest = true
|
||||
give_space = give_space + 10
|
||||
swap_side = false
|
||||
|
@ -863,13 +866,14 @@ local function choose_movement()
|
|||
if did_hit_up and state.water_potion ~= nil then
|
||||
state.control_w = false
|
||||
end
|
||||
local air = ComponentGetValue2(state.damage_model, "air_in_lungs")
|
||||
if air < 1 then
|
||||
state.control_w = true
|
||||
state.control_s = false
|
||||
elseif air < 2 then
|
||||
state.control_s = true
|
||||
state.control_w = false
|
||||
if air < 2 then
|
||||
if fly < 0.5 then
|
||||
state.control_s = true
|
||||
state.control_w = false
|
||||
else
|
||||
state.control_w = true
|
||||
state.control_s = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1441,6 +1445,7 @@ end
|
|||
|
||||
function module.on_world_update()
|
||||
local active = GameHasFlagRun("ew_flag_notplayer_active")
|
||||
and not ctx.proxy_opt.perma_death
|
||||
if active and EntityGetIsAlive(ctx.my_player.entity) and EntityHasTag(ctx.my_player.entity, "ew_notplayer") then
|
||||
if state == nil then
|
||||
init_state()
|
||||
|
|
|
@ -74,8 +74,15 @@ function module.on_world_update()
|
|||
local mx, my = GameGetCameraPos()
|
||||
for peer_id, player in pairs(ctx.players) do
|
||||
local ent = player.entity
|
||||
local children = EntityGetAllChildren(ent) or {}
|
||||
for _, child in ipairs(children) do
|
||||
if EntityGetName(child) == "cursor" or EntityGetName(child) == "notcursor" then
|
||||
EntitySetComponentIsEnabled(child, EntityGetFirstComponentIncludingDisabled(child, "SpriteComponent"), true)
|
||||
end
|
||||
end
|
||||
local x, y = EntityGetTransform(ent)
|
||||
local notplayer = EntityHasTag(ent, "ew_notplayer")
|
||||
and not ctx.proxy_opt.perma_death
|
||||
if notplayer and GameHasFlagRun("ending_game_completed") then
|
||||
goto continue
|
||||
end
|
||||
|
@ -84,7 +91,7 @@ function module.on_world_update()
|
|||
end
|
||||
local dx, dy = x - mx, y - my
|
||||
local cape
|
||||
for _, child in ipairs(EntityGetAllChildren(ent) or {}) do
|
||||
for _, child in ipairs(children) do
|
||||
if EntityGetName(child) == "cape" then
|
||||
local cpe = EntityGetFirstComponentIncludingDisabled(child, "VerletPhysicsComponent")
|
||||
local cx, cy = ComponentGetValue2(cpe, "m_position_previous")
|
||||
|
|
|
@ -72,7 +72,7 @@ local function get_me()
|
|||
local i = 0
|
||||
local alive = -1, -1
|
||||
for peer_id, potential_target in pairs(ctx.players) do
|
||||
if GameHasFlagRun("ending_game_completed") and EntityHasTag(potential_target.entity, "ew_notplayer") then
|
||||
if (GameHasFlagRun("ending_game_completed") or ctx.proxy_opt.perma_death) and EntityHasTag(potential_target.entity, "ew_notplayer") then
|
||||
goto continue
|
||||
end
|
||||
i = i + 1
|
||||
|
@ -218,7 +218,7 @@ local function set_camera_pos()
|
|||
if cam_target == nil or re_cam then
|
||||
local i = 0
|
||||
for peer_id, potential_target in pairs(ctx.players) do
|
||||
if GameHasFlagRun("ending_game_completed") and EntityHasTag(potential_target.entity, "ew_notplayer") then
|
||||
if (GameHasFlagRun("ending_game_completed") or ctx.proxy_opt.perma_death) and EntityHasTag(potential_target.entity, "ew_notplayer") then
|
||||
goto continue
|
||||
end
|
||||
i = i + 1
|
||||
|
@ -246,7 +246,8 @@ end
|
|||
local function update_i()
|
||||
local i = 0
|
||||
for peer_id, potential_target in pairs(ctx.players) do
|
||||
if GameHasFlagRun("ending_game_completed") and EntityHasTag(potential_target.entity, "ew_notplayer") then
|
||||
if (GameHasFlagRun("ending_game_completed") or ctx.proxy_opt.perma_death)
|
||||
and EntityHasTag(potential_target.entity, "ew_notplayer") then
|
||||
goto continue
|
||||
end
|
||||
i = i + 1
|
||||
|
@ -263,7 +264,7 @@ end
|
|||
local function number_of_players()
|
||||
local i = 0
|
||||
for _, potential_target in pairs(ctx.players) do
|
||||
if GameHasFlagRun("ending_game_completed") and EntityHasTag(potential_target.entity, "ew_notplayer") then
|
||||
if (GameHasFlagRun("ending_game_completed") or ctx.proxy_opt.perma_death) and EntityHasTag(potential_target.entity, "ew_notplayer") then
|
||||
goto continue
|
||||
end
|
||||
i = i + 1
|
||||
|
@ -296,7 +297,9 @@ function spectate.on_world_update()
|
|||
update_i()
|
||||
last_len = number_of_players()
|
||||
end
|
||||
if cam_target ~= nil and GameHasFlagRun("ending_game_completed") and EntityHasTag(cam_target.entity, "ew_notplayer") then
|
||||
if cam_target ~= nil
|
||||
and ((GameHasFlagRun("ending_game_completed") or ctx.proxy_opt.perma_death)
|
||||
and EntityHasTag(cam_target.entity, "ew_notplayer")) then
|
||||
update_i()
|
||||
last_len = number_of_players()
|
||||
end
|
||||
|
|
|
@ -2,6 +2,15 @@ local rpc = net.new_rpc_namespace()
|
|||
|
||||
local shield_entities = {}
|
||||
|
||||
local function remove_shield(peer_id)
|
||||
if shield_entities[peer_id] ~= nil then
|
||||
if EntityGetIsAlive(shield_entities[peer_id][2]) then
|
||||
EntityKill(shield_entities[peer_id][2])
|
||||
end
|
||||
shield_entities[peer_id] = nil
|
||||
end
|
||||
end
|
||||
|
||||
rpc.opts_everywhere()
|
||||
rpc.opts_reliable()
|
||||
function rpc.add_shield(target)
|
||||
|
@ -12,23 +21,21 @@ function rpc.add_shield(target)
|
|||
if not EntityGetIsAlive(entity) or EntityHasTag(entity, "polymorphed") then
|
||||
return
|
||||
end
|
||||
if shield_entities[ctx.rpc_peer_id] ~= nil then
|
||||
EntityKill(shield_entities[ctx.rpc_peer_id][2])
|
||||
if shield_entities[ctx.rpc_peer_id] == nil or shield_entities[ctx.rpc_peer_id][1] ~= target then
|
||||
if shield_entities[ctx.rpc_peer_id] ~= nil
|
||||
and EntityGetIsAlive(shield_entities[ctx.rpc_peer_id][2]) then
|
||||
EntityKill(shield_entities[ctx.rpc_peer_id][2])
|
||||
end
|
||||
local ent = EntityLoad("mods/quant.ew/files/system/spectator_helps/shield_base.xml")
|
||||
EntityAddChild(entity, ent)
|
||||
shield_entities[ctx.rpc_peer_id] = {target, ent}
|
||||
end
|
||||
local ent = EntityLoad("mods/quant.ew/files/system/spectator_helps/shield_base.xml")
|
||||
EntityAddChild(entity, ent)
|
||||
shield_entities[ctx.rpc_peer_id] = {target, ent}
|
||||
end
|
||||
|
||||
rpc.opts_everywhere()
|
||||
rpc.opts_reliable()
|
||||
function rpc.del_shield()
|
||||
if shield_entities[ctx.rpc_peer_id] ~= nil then
|
||||
if EntityGetIsAlive(shield_entities[ctx.rpc_peer_id][2]) then
|
||||
EntityKill(shield_entities[ctx.rpc_peer_id][2])
|
||||
end
|
||||
shield_entities[ctx.rpc_peer_id] = nil
|
||||
end
|
||||
remove_shield(ctx.rpc_peer_id)
|
||||
end
|
||||
|
||||
local module = {}
|
||||
|
@ -48,11 +55,11 @@ local function is_acceptable_help_target(spectating_over)
|
|||
return false
|
||||
end
|
||||
if shield_entities[ctx.my_id] ~= nil then
|
||||
if shield_entities[ctx.my_id][1] ~= spectating_over then
|
||||
if shield_entities[ctx.my_id][1] ~= spectating_over then
|
||||
rpc.del_shield()
|
||||
return false
|
||||
end
|
||||
return false
|
||||
return GameGetFrameNum() % 300 < 10
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
@ -77,7 +84,10 @@ end
|
|||
local last_spectate
|
||||
|
||||
function module.on_world_update()
|
||||
if GameHasFlagRun("ending_game_completed") then
|
||||
if GameHasFlagRun("ending_game_completed") or ctx.proxy_opt.perma_death then
|
||||
if not ctx.proxy_opt.perma_death then
|
||||
rpc.del_shield()
|
||||
end
|
||||
return
|
||||
end
|
||||
if GameGetFrameNum() % 10 == 8 then
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue