boss preparations

This commit is contained in:
Alula 2020-10-03 00:11:09 +02:00
parent 698127d2c2
commit b212d6f74b
No known key found for this signature in database
GPG Key ID: 3E00485503A1D8BA
3 changed files with 111 additions and 50 deletions

13
src/npc/boss/mod.rs Normal file
View File

@ -0,0 +1,13 @@
use crate::npc::NPC;
pub struct BossNPCMap {
pub parts: [NPC; 16]
}
impl BossNPCMap {
pub fn new() -> BossNPCMap {
BossNPCMap {
parts: [NPC::empty(); 16],
}
}
}

View File

@ -21,8 +21,10 @@ use crate::player::Player;
use crate::shared_game_state::SharedGameState;
use crate::stage::Stage;
use crate::str;
use crate::npc::boss::BossNPCMap;
pub mod balrog;
pub mod boss;
pub mod characters;
pub mod egg_corridor;
pub mod first_cave;
@ -100,6 +102,39 @@ impl NPC {
0
}
}
pub fn empty() -> NPC {
NPC {
id: 0,
npc_type: 0,
x: 0,
y: 0,
vel_x: 0,
vel_y: 0,
target_x: 0,
target_y: 0,
exp: 0,
size: 0,
shock: 0,
life: 0,
damage: 0,
cond: Condition(0),
flags: Flag(0),
npc_flags: NPCFlag(0),
direction: Direction::Left,
display_bounds: Rect { left: 0, top: 0, right: 0, bottom: 0 },
hit_bounds: Rect { left: 0, top: 0, right: 0, bottom: 0 },
parent_id: 0,
action_num: 0,
anim_num: 0,
flag_num: 0,
event_num: 0,
action_counter: 0,
action_counter2: 0,
anim_counter: 0,
anim_rect: Rect { left: 0, top: 0, right: 0, bottom: 0 },
}
}
}
impl GameEntity<(&mut Player, &HashMap<u16, RefCell<NPC>>, &mut Stage)> for NPC {
@ -274,6 +309,8 @@ pub struct NPCMap {
pub npc_ids: BTreeSet<u16>,
/// Do not iterate over this directly outside render pipeline.
pub npcs: HashMap<u16, RefCell<NPC>>,
/// NPCMap but for bosses and of static size.
pub boss_map: BossNPCMap,
}
impl NPCMap {
@ -282,6 +319,7 @@ impl NPCMap {
NPCMap {
npc_ids: BTreeSet::new(),
npcs: HashMap::with_capacity(256),
boss_map: BossNPCMap::new(),
}
}

View File

@ -1,4 +1,4 @@
use std::borrow::Borrow;
use std::borrow::{Borrow, BorrowMut};
use num_traits::abs;
@ -228,62 +228,72 @@ impl Player {
flags
}
fn tick_npc_collision(&mut self, state: &mut SharedGameState, npc: &mut NPC, inventory: &mut Inventory) {
let flags: Flag;
if npc.npc_flags.solid_soft() {
flags = self.judge_hit_npc_solid_soft(npc.borrow());
self.flags.0 |= flags.0;
} else if npc.npc_flags.solid_hard() {
flags = self.judge_hit_npc_solid_hard(npc.borrow(), state);
self.flags.0 |= flags.0;
} else {
flags = self.judge_hit_npc_non_solid(npc.borrow());
}
// xp pickup
if flags.0 != 0 && npc.npc_type == 1 {
state.sound_manager.play_sfx(14);
match inventory.add_xp(npc.exp, state) {
AddExperienceResult::None => {}
AddExperienceResult::LevelUp => {
state.sound_manager.play_sfx(27);
state.create_caret(self.x, self.y, CaretType::LevelUp, Direction::Left);
}
AddExperienceResult::AddStar => {
if self.equip.has_whimsical_star() && self.stars < 3 {
self.stars += 1;
}
}
}
npc.cond.set_alive(false);
}
if npc.npc_flags.interactable() && !state.control_flags.interactions_disabled() && flags.0 != 0 && self.cond.interacted() {
state.control_flags.set_tick_world(true);
state.control_flags.set_interactions_disabled(true);
state.textscript_vm.start_script(npc.event_num);
self.cond.set_interacted(false);
self.vel_x = 0;
self.question = false;
}
if npc.npc_flags.event_when_touched() && !state.control_flags.interactions_disabled() && flags.0 != 0 {
state.control_flags.set_tick_world(true);
state.control_flags.set_interactions_disabled(true);
state.textscript_vm.start_script(npc.event_num);
}
if state.control_flags.control_enabled() && !npc.npc_flags.interactable() {
if flags.0 != 0 && npc.damage != 0 && !state.control_flags.interactions_disabled() {
self.damage(npc.damage as isize, state);
}
}
}
pub fn tick_npc_collisions(&mut self, state: &mut SharedGameState, npc_map: &mut NPCMap, inventory: &mut Inventory) {
for npc_id in npc_map.npc_ids.iter() {
if let Some(npc_cell) = npc_map.npcs.get(npc_id) {
let mut npc = npc_cell.borrow_mut();
if !npc.cond.alive() { continue; }
let mut flags = Flag(0);
self.tick_npc_collision(state, npc.borrow_mut(), inventory);
}
}
if npc.npc_flags.solid_soft() {
flags = self.judge_hit_npc_solid_soft(npc.borrow());
self.flags.0 |= flags.0;
} else if npc.npc_flags.solid_hard() {
flags = self.judge_hit_npc_solid_hard(npc.borrow(), state);
self.flags.0 |= flags.0;
} else {
flags = self.judge_hit_npc_non_solid(npc.borrow());
}
// xp pickup
if flags.0 != 0 && npc.npc_type == 1 {
state.sound_manager.play_sfx(14);
match inventory.add_xp(npc.exp, state) {
AddExperienceResult::None => {}
AddExperienceResult::LevelUp => {
state.sound_manager.play_sfx(27);
state.create_caret(self.x, self.y, CaretType::LevelUp, Direction::Left);
}
AddExperienceResult::AddStar => {
if self.equip.has_whimsical_star() && self.stars < 3 {
self.stars += 1;
}
}
}
npc.cond.set_alive(false);
}
if npc.npc_flags.interactable() && !state.control_flags.interactions_disabled() && flags.0 != 0 && self.cond.interacted() {
state.control_flags.set_tick_world(true);
state.control_flags.set_interactions_disabled(true);
state.textscript_vm.start_script(npc.event_num);
self.cond.set_interacted(false);
self.vel_x = 0;
self.question = false;
}
if npc.npc_flags.event_when_touched() && !state.control_flags.interactions_disabled() && flags.0 != 0 {
state.control_flags.set_tick_world(true);
state.control_flags.set_interactions_disabled(true);
state.textscript_vm.start_script(npc.event_num);
}
if state.control_flags.control_enabled() && !npc.npc_flags.interactable() {
if flags.0 != 0 && npc.damage != 0 && !state.control_flags.interactions_disabled() {
self.damage(npc.damage as isize, state);
}
}
for boss_npc in npc_map.boss_map.parts.iter_mut() {
if boss_npc.cond.alive() {
self.tick_npc_collision(state, boss_npc, inventory);
}
}