mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 08:11:33 +11:00
add hole and rotating enemy
This commit is contained in:
parent
73a0b482a5
commit
a97248cd68
|
@ -44,6 +44,8 @@ const LEVEL_NAMES: &[&str] = &[
|
||||||
"another_ice_2",
|
"another_ice_2",
|
||||||
"another_ice_3",
|
"another_ice_3",
|
||||||
"another_ice_4",
|
"another_ice_4",
|
||||||
|
"hole_introduction",
|
||||||
|
"rotator_1",
|
||||||
];
|
];
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -131,6 +133,11 @@ enum Entity {
|
||||||
MovableBlock,
|
MovableBlock,
|
||||||
Glove,
|
Glove,
|
||||||
Teleporter,
|
Teleporter,
|
||||||
|
Hole,
|
||||||
|
RotatorUp,
|
||||||
|
RotatorDown,
|
||||||
|
RotatorLeft,
|
||||||
|
RotatorRight,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for Entity {
|
impl FromStr for Entity {
|
||||||
|
@ -158,6 +165,11 @@ impl FromStr for Entity {
|
||||||
"BLOCK" => MovableBlock,
|
"BLOCK" => MovableBlock,
|
||||||
"GLOVE" => Glove,
|
"GLOVE" => Glove,
|
||||||
"TELEPORTER" => Teleporter,
|
"TELEPORTER" => Teleporter,
|
||||||
|
"HOLE" => Hole,
|
||||||
|
"ROTATOR_LEFT" => RotatorLeft,
|
||||||
|
"ROTATOR_RIGHT" => RotatorRight,
|
||||||
|
"ROTATOR_UP" => RotatorUp,
|
||||||
|
"ROTATOR_DOWN" => RotatorDown,
|
||||||
_ => return Err(()),
|
_ => return Err(()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -186,6 +198,11 @@ impl quote::ToTokens for Entity {
|
||||||
MovableBlock => quote!(Item::MovableBlock),
|
MovableBlock => quote!(Item::MovableBlock),
|
||||||
Glove => quote!(Item::Glove),
|
Glove => quote!(Item::Glove),
|
||||||
Teleporter => quote!(Item::Teleporter),
|
Teleporter => quote!(Item::Teleporter),
|
||||||
|
Hole => quote!(Item::Hole),
|
||||||
|
RotatorUp => quote!(Item::RotatorUp),
|
||||||
|
RotatorDown => quote!(Item::RotatorDown),
|
||||||
|
RotatorLeft => quote!(Item::RotatorLeft),
|
||||||
|
RotatorRight => quote!(Item::RotatorRight),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,34 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<map version="1.10" tiledversion="1.10.2" orientation="orthogonal" renderorder="right-down" width="11" height="10" tilewidth="16" tileheight="16" infinite="0" nextlayerid="3" nextobjectid="4">
|
||||||
|
<properties>
|
||||||
|
<property name="DIRECTIONS" value="RRRRRRRR"/>
|
||||||
|
<property name="ITEMS" value="BLOCK"/>
|
||||||
|
<property name="NAME" value="That hero won't survive the fall"/>
|
||||||
|
</properties>
|
||||||
|
<tileset firstgid="1" source="../level16.tsx"/>
|
||||||
|
<layer id="1" name="Tile Layer 1" width="11" height="10">
|
||||||
|
<data encoding="csv">
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,1,6,5,2,2,6,4,8,9,0,
|
||||||
|
0,10,17,17,12,15,13,17,17,38,0,
|
||||||
|
0,19,20,20,20,25,20,22,21,27,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
</data>
|
||||||
|
</layer>
|
||||||
|
<objectgroup id="2" name="Object Layer 1">
|
||||||
|
<object id="1" name="STAIRS" x="135.08" y="73.5784">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="2" name="HERO" x="55.8537" y="72.9973">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="3" name="HOLE" x="103.811" y="69.6733">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
</objectgroup>
|
||||||
|
</map>
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<map version="1.10" tiledversion="1.10.2" orientation="orthogonal" renderorder="right-down" width="11" height="10" tilewidth="16" tileheight="16" infinite="0" nextlayerid="3" nextobjectid="9">
|
||||||
|
<properties>
|
||||||
|
<property name="DIRECTIONS" value="RRRRRRRRRRRRRRRR"/>
|
||||||
|
<property name="ITEMS" value="DOOR,DOOR,DOOR,DOOR"/>
|
||||||
|
<property name="NAME" value="There's no way through without a little help"/>
|
||||||
|
</properties>
|
||||||
|
<tileset firstgid="1" source="../level16.tsx"/>
|
||||||
|
<layer id="1" name="Tile Layer 1" width="11" height="10">
|
||||||
|
<data encoding="csv">
|
||||||
|
1,6,7,7,4,5,3,2,4,7,9,
|
||||||
|
37,12,14,13,12,15,12,16,14,13,47,
|
||||||
|
19,22,26,26,26,25,23,22,24,26,27,
|
||||||
|
1,7,4,7,2,2,8,2,2,5,9,
|
||||||
|
10,11,14,13,15,11,14,14,12,17,38,
|
||||||
|
46,12,12,14,12,16,17,15,17,13,18,
|
||||||
|
10,14,17,14,17,14,16,15,16,11,38,
|
||||||
|
10,15,16,16,11,11,11,13,16,15,18,
|
||||||
|
10,12,14,16,14,12,14,13,12,17,47,
|
||||||
|
19,23,24,26,22,20,24,25,26,25,27
|
||||||
|
</data>
|
||||||
|
</layer>
|
||||||
|
<objectgroup id="2" name="Object Layer 1">
|
||||||
|
<object id="3" name="HERO" x="38.75" y="23.5">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="4" name="STAIRS" x="135.25" y="23.25">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="5" name="DOOR_SWITCHED" x="71.5" y="23.5">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="6" name="DOOR_SWITCHED_OPEN" x="103.25" y="22.75">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="7" name="ROTATOR_UP" x="104" y="89.75">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="8" name="SWITCH" x="70.25" y="105.25">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
</objectgroup>
|
||||||
|
</map>
|
|
@ -223,32 +223,82 @@ impl EntityMap {
|
||||||
desired_location,
|
desired_location,
|
||||||
move_effect,
|
move_effect,
|
||||||
));
|
));
|
||||||
} else if explicit_stay_put
|
} else if !should_die_later
|
||||||
|
&& explicit_stay_put
|
||||||
&& can_turn_around
|
&& can_turn_around
|
||||||
&& self.map.get(entity_to_update_key).map(|e| e.turns_around()) == Some(true)
|
&& self.map.get(entity_to_update_key).map(|e| e.turns_around()) == Some(true)
|
||||||
{
|
{
|
||||||
if let Some((Some(change), change_effect)) = self
|
if let Some(directions_to_attempt) = self
|
||||||
.map
|
.map
|
||||||
.get_mut(entity_to_update_key)
|
.get(entity_to_update_key)
|
||||||
.map(|e| (e.change_direction(), e.change_effect()))
|
.and_then(|e| e.directions_to_attempt())
|
||||||
{
|
{
|
||||||
animations.push(AnimationInstruction::PriorityChange(
|
#[allow(clippy::indexing_slicing)]
|
||||||
|
for &direction_to_attempt in directions_to_attempt {
|
||||||
|
let (can_move, action) = self.attempt_move_in_direction(
|
||||||
|
map,
|
||||||
|
animations,
|
||||||
|
entity_to_update_key,
|
||||||
|
direction_to_attempt,
|
||||||
|
false,
|
||||||
|
push_depth,
|
||||||
|
entities_that_have_moved,
|
||||||
|
);
|
||||||
|
|
||||||
|
if can_move.0 {
|
||||||
|
if let Some((Some(change), change_effect)) = self
|
||||||
|
.map
|
||||||
|
.get_mut(entity_to_update_key)
|
||||||
|
.map(|e| (e.change_direction(direction_to_attempt), e.change_effect()))
|
||||||
|
{
|
||||||
|
animations.push(AnimationInstruction::PriorityChange(
|
||||||
|
entity_to_update_key,
|
||||||
|
change,
|
||||||
|
change_effect,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
can_move,
|
||||||
|
ActionResult::new(
|
||||||
|
hero_has_died || action.hero_has_died,
|
||||||
|
win_has_triggered || action.win_has_triggered,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let last_direction_attempt = *directions_to_attempt.last().unwrap();
|
||||||
|
|
||||||
|
animations.push(AnimationInstruction::FakeOutMove(
|
||||||
entity_to_update_key,
|
entity_to_update_key,
|
||||||
change,
|
last_direction_attempt,
|
||||||
change_effect,
|
self.map
|
||||||
|
.get(entity_to_update_key)
|
||||||
|
.and_then(|e| e.fake_out_wall_effect()),
|
||||||
));
|
));
|
||||||
|
|
||||||
return self.attempt_move_in_direction(
|
if let Some((Some(change), change_effect)) =
|
||||||
map,
|
self.map.get_mut(entity_to_update_key).map(|e| {
|
||||||
animations,
|
(
|
||||||
entity_to_update_key,
|
e.change_direction(last_direction_attempt),
|
||||||
-direction,
|
e.change_effect(),
|
||||||
false,
|
)
|
||||||
push_depth,
|
})
|
||||||
entities_that_have_moved,
|
{
|
||||||
|
animations.push(AnimationInstruction::PriorityChange(
|
||||||
|
entity_to_update_key,
|
||||||
|
change,
|
||||||
|
change_effect,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
HasMoved(false),
|
||||||
|
ActionResult::new(hero_has_died, win_has_triggered),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else if can_turn_around {
|
||||||
animations.push(AnimationInstruction::FakeOutMove(
|
animations.push(AnimationInstruction::FakeOutMove(
|
||||||
entity_to_update_key,
|
entity_to_update_key,
|
||||||
direction,
|
direction,
|
||||||
|
@ -348,6 +398,11 @@ impl EntityMap {
|
||||||
hero_has_died |= self.kill_entity(entity_to_update_key, animations);
|
hero_has_died |= self.kill_entity(entity_to_update_key, animations);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
OverlapResolution::KillDie => {
|
||||||
|
hero_has_died |= self.kill_entity(other_entity_key, animations);
|
||||||
|
hero_has_died |= self.kill_entity(entity_to_update_key, animations);
|
||||||
|
break;
|
||||||
|
}
|
||||||
OverlapResolution::MoveAgain => {
|
OverlapResolution::MoveAgain => {
|
||||||
should_move_again = true;
|
should_move_again = true;
|
||||||
}
|
}
|
||||||
|
@ -468,6 +523,7 @@ enum OverlapResolution {
|
||||||
Win,
|
Win,
|
||||||
ToggleSystem(SwitchSystem),
|
ToggleSystem(SwitchSystem),
|
||||||
Die,
|
Die,
|
||||||
|
KillDie,
|
||||||
MoveAgain,
|
MoveAgain,
|
||||||
Teleport,
|
Teleport,
|
||||||
}
|
}
|
||||||
|
@ -483,7 +539,7 @@ fn resolve_spikes(switable: &Switchable) -> OverlapResolution {
|
||||||
fn resolve_overlap(me: &Entity, other: &Entity) -> OverlapResolution {
|
fn resolve_overlap(me: &Entity, other: &Entity) -> OverlapResolution {
|
||||||
match (&me.entity, &other.entity) {
|
match (&me.entity, &other.entity) {
|
||||||
(EntityType::Hero(_), EntityType::Stairs) => OverlapResolution::Win,
|
(EntityType::Hero(_), EntityType::Stairs) => OverlapResolution::Win,
|
||||||
(EntityType::Hero(_) | EntityType::Enemy(Enemy::Squid(_)), EntityType::Item(_)) => {
|
(EntityType::Hero(_) | EntityType::Enemy(Enemy::Moving(_)), EntityType::Item(_)) => {
|
||||||
OverlapResolution::Pickup
|
OverlapResolution::Pickup
|
||||||
}
|
}
|
||||||
(EntityType::MovableBlock, EntityType::Spikes(_)) => OverlapResolution::CoExist,
|
(EntityType::MovableBlock, EntityType::Spikes(_)) => OverlapResolution::CoExist,
|
||||||
|
@ -492,6 +548,8 @@ fn resolve_overlap(me: &Entity, other: &Entity) -> OverlapResolution {
|
||||||
(_, EntityType::Enemy(_)) => OverlapResolution::Die,
|
(_, EntityType::Enemy(_)) => OverlapResolution::Die,
|
||||||
(_, EntityType::Ice) => OverlapResolution::MoveAgain,
|
(_, EntityType::Ice) => OverlapResolution::MoveAgain,
|
||||||
(_, EntityType::Teleporter) => OverlapResolution::Teleport,
|
(_, EntityType::Teleporter) => OverlapResolution::Teleport,
|
||||||
|
(EntityType::MovableBlock, EntityType::Hole) => OverlapResolution::KillDie,
|
||||||
|
(_, EntityType::Hole) => OverlapResolution::Die,
|
||||||
|
|
||||||
_ => OverlapResolution::CoExist,
|
_ => OverlapResolution::CoExist,
|
||||||
}
|
}
|
||||||
|
@ -504,18 +562,18 @@ fn holding_attack_resolve(
|
||||||
) -> MoveAttemptResolution {
|
) -> MoveAttemptResolution {
|
||||||
match (holding, &other.entity) {
|
match (holding, &other.entity) {
|
||||||
(Some(&EntityType::Item(Item::Sword)), _) => MoveAttemptResolution::Kill,
|
(Some(&EntityType::Item(Item::Sword)), _) => MoveAttemptResolution::Kill,
|
||||||
(_, EntityType::Enemy(Enemy::Squid(squid))) => {
|
(_, EntityType::Enemy(Enemy::Moving(squid))) => {
|
||||||
hero_walk_into_squid_interaction(squid, direction)
|
hero_walk_into_squid_interaction(squid, direction)
|
||||||
}
|
}
|
||||||
_ => MoveAttemptResolution::CoExist,
|
_ => MoveAttemptResolution::CoExist,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn squid_holding_attack_resolve(me: &Squid, other: &Entity) -> MoveAttemptResolution {
|
fn squid_holding_attack_resolve(me: &Moving, other: &Entity) -> MoveAttemptResolution {
|
||||||
match (me.holding.as_deref(), &other.entity, other.holding()) {
|
match (me.holding.as_deref(), &other.entity, other.holding()) {
|
||||||
(
|
(
|
||||||
Some(&EntityType::Item(Item::Sword)),
|
Some(&EntityType::Item(Item::Sword)),
|
||||||
EntityType::Enemy(Enemy::Squid(squid)),
|
EntityType::Enemy(Enemy::Moving(squid)),
|
||||||
Some(&EntityType::Item(Item::Sword)),
|
Some(&EntityType::Item(Item::Sword)),
|
||||||
) => {
|
) => {
|
||||||
if squid.direction == -me.direction {
|
if squid.direction == -me.direction {
|
||||||
|
@ -527,7 +585,7 @@ fn squid_holding_attack_resolve(me: &Squid, other: &Entity) -> MoveAttemptResolu
|
||||||
(Some(&EntityType::Item(Item::Sword)), EntityType::Enemy(_), None) => {
|
(Some(&EntityType::Item(Item::Sword)), EntityType::Enemy(_), None) => {
|
||||||
MoveAttemptResolution::Kill
|
MoveAttemptResolution::Kill
|
||||||
}
|
}
|
||||||
(_, EntityType::Enemy(Enemy::Squid(squid)), Some(&EntityType::Item(Item::Sword))) => {
|
(_, EntityType::Enemy(Enemy::Moving(squid)), Some(&EntityType::Item(Item::Sword))) => {
|
||||||
if squid.direction == -me.direction {
|
if squid.direction == -me.direction {
|
||||||
MoveAttemptResolution::Die
|
MoveAttemptResolution::Die
|
||||||
} else {
|
} else {
|
||||||
|
@ -555,7 +613,7 @@ fn switch_door_resolve(door: &Switchable) -> MoveAttemptResolution {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hero_walk_into_squid_interaction(squid: &Squid, direction: Direction) -> MoveAttemptResolution {
|
fn hero_walk_into_squid_interaction(squid: &Moving, direction: Direction) -> MoveAttemptResolution {
|
||||||
if direction == -squid.direction {
|
if direction == -squid.direction {
|
||||||
MoveAttemptResolution::DieLater
|
MoveAttemptResolution::DieLater
|
||||||
} else {
|
} else {
|
||||||
|
@ -569,14 +627,14 @@ fn resolve_move(mover: &Entity, into: &Entity, direction: Direction) -> MoveAtte
|
||||||
holding_attack_resolve(hero.holding.as_deref(), into, direction)
|
holding_attack_resolve(hero.holding.as_deref(), into, direction)
|
||||||
}
|
}
|
||||||
(EntityType::Hero(hero), EntityType::Door) => holding_door_resolve(hero.holding.as_deref()),
|
(EntityType::Hero(hero), EntityType::Door) => holding_door_resolve(hero.holding.as_deref()),
|
||||||
(EntityType::Enemy(Enemy::Squid(squid)), EntityType::Hero(_) | EntityType::Enemy(_)) => {
|
(EntityType::Enemy(Enemy::Moving(squid)), EntityType::Hero(_) | EntityType::Enemy(_)) => {
|
||||||
squid_holding_attack_resolve(squid, into)
|
squid_holding_attack_resolve(squid, into)
|
||||||
}
|
}
|
||||||
(EntityType::Enemy(_), EntityType::Hero(_) | EntityType::Enemy(_)) => {
|
(EntityType::Enemy(_), EntityType::Hero(_) | EntityType::Enemy(_)) => {
|
||||||
MoveAttemptResolution::Kill
|
MoveAttemptResolution::Kill
|
||||||
}
|
}
|
||||||
(_, EntityType::SwitchedDoor(door)) => switch_door_resolve(door),
|
(_, EntityType::SwitchedDoor(door)) => switch_door_resolve(door),
|
||||||
(EntityType::Enemy(Enemy::Squid(squid)), EntityType::Door) => {
|
(EntityType::Enemy(Enemy::Moving(squid)), EntityType::Door) => {
|
||||||
holding_door_resolve(squid.holding.as_deref())
|
holding_door_resolve(squid.holding.as_deref())
|
||||||
}
|
}
|
||||||
(_, EntityType::Door) => MoveAttemptResolution::StayPut,
|
(_, EntityType::Door) => MoveAttemptResolution::StayPut,
|
||||||
|
@ -611,6 +669,7 @@ pub enum EntityType {
|
||||||
Enemy(Enemy),
|
Enemy(Enemy),
|
||||||
Stairs,
|
Stairs,
|
||||||
Door,
|
Door,
|
||||||
|
Hole,
|
||||||
SwitchedDoor(Switchable),
|
SwitchedDoor(Switchable),
|
||||||
Switch(Switchable),
|
Switch(Switchable),
|
||||||
Spikes(Switchable),
|
Spikes(Switchable),
|
||||||
|
@ -620,15 +679,22 @@ pub enum EntityType {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Squid {
|
pub struct Moving {
|
||||||
direction: Direction,
|
direction: Direction,
|
||||||
holding: Option<Box<EntityType>>,
|
holding: Option<Box<EntityType>>,
|
||||||
|
movable_enemy_type: MovableEnemyType,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
enum MovableEnemyType {
|
||||||
|
Squid,
|
||||||
|
Rotator,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Enemy {
|
pub enum Enemy {
|
||||||
Slime,
|
Slime,
|
||||||
Squid(Squid),
|
Moving(Moving),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -686,19 +752,19 @@ impl Entity {
|
||||||
fn desired_action(&self, hero_action: Action) -> Action {
|
fn desired_action(&self, hero_action: Action) -> Action {
|
||||||
match &self.entity {
|
match &self.entity {
|
||||||
EntityType::Hero(_) => hero_action,
|
EntityType::Hero(_) => hero_action,
|
||||||
EntityType::Enemy(Enemy::Squid(squid)) => Action::Direction(squid.direction),
|
EntityType::Enemy(Enemy::Moving(squid)) => Action::Direction(squid.direction),
|
||||||
_ => Action::Nothing,
|
_ => Action::Nothing,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn turns_around(&self) -> bool {
|
fn turns_around(&self) -> bool {
|
||||||
matches!(self.entity, EntityType::Enemy(Enemy::Squid(_)))
|
matches!(self.entity, EntityType::Enemy(Enemy::Moving(_)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pickup(&mut self, item: EntityType) -> Option<EntityType> {
|
fn pickup(&mut self, item: EntityType) -> Option<EntityType> {
|
||||||
let holding = match &mut self.entity {
|
let holding = match &mut self.entity {
|
||||||
EntityType::Hero(hero) => &mut hero.holding,
|
EntityType::Hero(hero) => &mut hero.holding,
|
||||||
EntityType::Enemy(Enemy::Squid(squid)) => &mut squid.holding,
|
EntityType::Enemy(Enemy::Moving(squid)) => &mut squid.holding,
|
||||||
_ => panic!("this entity can't pick up things"),
|
_ => panic!("this entity can't pick up things"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -709,7 +775,7 @@ impl Entity {
|
||||||
fn take_holding(&mut self) -> Option<EntityType> {
|
fn take_holding(&mut self) -> Option<EntityType> {
|
||||||
match &mut self.entity {
|
match &mut self.entity {
|
||||||
EntityType::Hero(hero) => hero.holding.take().map(|x| *x),
|
EntityType::Hero(hero) => hero.holding.take().map(|x| *x),
|
||||||
EntityType::Enemy(Enemy::Squid(squid)) => squid.holding.take().map(|x| *x),
|
EntityType::Enemy(Enemy::Moving(squid)) => squid.holding.take().map(|x| *x),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -719,7 +785,7 @@ impl Entity {
|
||||||
Some(i32::MAX)
|
Some(i32::MAX)
|
||||||
} else if matches!(
|
} else if matches!(
|
||||||
self.entity,
|
self.entity,
|
||||||
EntityType::Hero(_) | EntityType::Enemy(Enemy::Squid(_))
|
EntityType::Hero(_) | EntityType::Enemy(Enemy::Moving(_))
|
||||||
) {
|
) {
|
||||||
Some(1)
|
Some(1)
|
||||||
} else {
|
} else {
|
||||||
|
@ -730,7 +796,7 @@ impl Entity {
|
||||||
fn holding(&self) -> Option<&EntityType> {
|
fn holding(&self) -> Option<&EntityType> {
|
||||||
match &self.entity {
|
match &self.entity {
|
||||||
EntityType::Hero(hero) => hero.holding.as_deref(),
|
EntityType::Hero(hero) => hero.holding.as_deref(),
|
||||||
EntityType::Enemy(Enemy::Squid(squid)) => squid.holding.as_deref(),
|
EntityType::Enemy(Enemy::Moving(squid)) => squid.holding.as_deref(),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -740,7 +806,11 @@ impl Entity {
|
||||||
EntityType::Hero(_) => Some(SoundEffect::HeroDie),
|
EntityType::Hero(_) => Some(SoundEffect::HeroDie),
|
||||||
EntityType::Door => Some(SoundEffect::DoorOpen),
|
EntityType::Door => Some(SoundEffect::DoorOpen),
|
||||||
EntityType::Enemy(Enemy::Slime) => Some(SoundEffect::SlimeDie),
|
EntityType::Enemy(Enemy::Slime) => Some(SoundEffect::SlimeDie),
|
||||||
EntityType::Enemy(Enemy::Squid(_)) => Some(SoundEffect::SquidDie),
|
EntityType::Enemy(Enemy::Moving(e))
|
||||||
|
if e.movable_enemy_type == MovableEnemyType::Squid =>
|
||||||
|
{
|
||||||
|
Some(SoundEffect::SquidDie)
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -792,15 +862,46 @@ impl Entity {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_direction(&mut self) -> Option<level::Item> {
|
fn directions_to_attempt(&self) -> Option<&'static [Direction]> {
|
||||||
match &mut self.entity {
|
match &self.entity {
|
||||||
EntityType::Enemy(Enemy::Squid(squid)) => {
|
EntityType::Enemy(Enemy::Moving(moving_type)) => {
|
||||||
squid.direction = -squid.direction;
|
Some(match moving_type.movable_enemy_type {
|
||||||
|
MovableEnemyType::Squid => match moving_type.direction {
|
||||||
|
Direction::Up => &[Direction::Down],
|
||||||
|
Direction::Down => &[Direction::Up],
|
||||||
|
_ => panic!("Left and right movements are not valid for a squid"),
|
||||||
|
},
|
||||||
|
MovableEnemyType::Rotator => match moving_type.direction {
|
||||||
|
Direction::Up => &[Direction::Right, Direction::Left, Direction::Down],
|
||||||
|
Direction::Down => &[Direction::Left, Direction::Right, Direction::Up],
|
||||||
|
Direction::Left => &[Direction::Up, Direction::Down, Direction::Right],
|
||||||
|
Direction::Right => &[Direction::Down, Direction::Up, Direction::Left],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if squid.direction == Direction::Up {
|
fn change_direction(&mut self, direction: Direction) -> Option<level::Item> {
|
||||||
Some(level::Item::SquidUp)
|
match &mut self.entity {
|
||||||
} else {
|
EntityType::Enemy(Enemy::Moving(moving)) => {
|
||||||
Some(level::Item::SquidDown)
|
moving.direction = direction;
|
||||||
|
|
||||||
|
match moving.movable_enemy_type {
|
||||||
|
MovableEnemyType::Squid => {
|
||||||
|
if direction == Direction::Up {
|
||||||
|
Some(level::Item::SquidUp)
|
||||||
|
} else {
|
||||||
|
Some(level::Item::SquidDown)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MovableEnemyType::Rotator => Some(match direction {
|
||||||
|
Direction::Up => level::Item::RotatorUp,
|
||||||
|
Direction::Down => level::Item::RotatorDown,
|
||||||
|
Direction::Left => level::Item::RotatorLeft,
|
||||||
|
Direction::Right => level::Item::RotatorRight,
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -887,18 +988,41 @@ impl From<level::Item> for EntityType {
|
||||||
system: SwitchSystem(0),
|
system: SwitchSystem(0),
|
||||||
active: false,
|
active: false,
|
||||||
}),
|
}),
|
||||||
level::Item::SquidUp => EntityType::Enemy(Enemy::Squid(Squid {
|
level::Item::SquidUp => EntityType::Enemy(Enemy::Moving(Moving {
|
||||||
direction: Direction::Up,
|
direction: Direction::Up,
|
||||||
holding: None,
|
holding: None,
|
||||||
|
movable_enemy_type: MovableEnemyType::Squid,
|
||||||
})),
|
})),
|
||||||
level::Item::SquidDown => EntityType::Enemy(Enemy::Squid(Squid {
|
level::Item::SquidDown => EntityType::Enemy(Enemy::Moving(Moving {
|
||||||
direction: Direction::Down,
|
direction: Direction::Down,
|
||||||
holding: None,
|
holding: None,
|
||||||
|
movable_enemy_type: MovableEnemyType::Squid,
|
||||||
})),
|
})),
|
||||||
level::Item::Ice => EntityType::Ice,
|
level::Item::Ice => EntityType::Ice,
|
||||||
level::Item::MovableBlock => EntityType::MovableBlock,
|
level::Item::MovableBlock => EntityType::MovableBlock,
|
||||||
level::Item::Glove => EntityType::Item(Item::Glove),
|
level::Item::Glove => EntityType::Item(Item::Glove),
|
||||||
level::Item::Teleporter => EntityType::Teleporter,
|
level::Item::Teleporter => EntityType::Teleporter,
|
||||||
|
level::Item::Hole => EntityType::Hole,
|
||||||
|
level::Item::RotatorRight => EntityType::Enemy(Enemy::Moving(Moving {
|
||||||
|
direction: Direction::Right,
|
||||||
|
holding: None,
|
||||||
|
movable_enemy_type: MovableEnemyType::Rotator,
|
||||||
|
})),
|
||||||
|
level::Item::RotatorLeft => EntityType::Enemy(Enemy::Moving(Moving {
|
||||||
|
direction: Direction::Left,
|
||||||
|
holding: None,
|
||||||
|
movable_enemy_type: MovableEnemyType::Rotator,
|
||||||
|
})),
|
||||||
|
level::Item::RotatorUp => EntityType::Enemy(Enemy::Moving(Moving {
|
||||||
|
direction: Direction::Up,
|
||||||
|
holding: None,
|
||||||
|
movable_enemy_type: MovableEnemyType::Rotator,
|
||||||
|
})),
|
||||||
|
level::Item::RotatorDown => EntityType::Enemy(Enemy::Moving(Moving {
|
||||||
|
direction: Direction::Down,
|
||||||
|
holding: None,
|
||||||
|
movable_enemy_type: MovableEnemyType::Rotator,
|
||||||
|
})),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,11 @@ pub enum Item {
|
||||||
MovableBlock,
|
MovableBlock,
|
||||||
Glove,
|
Glove,
|
||||||
Teleporter,
|
Teleporter,
|
||||||
|
Hole,
|
||||||
|
RotatorRight,
|
||||||
|
RotatorLeft,
|
||||||
|
RotatorUp,
|
||||||
|
RotatorDown,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Item {
|
impl Item {
|
||||||
|
@ -45,6 +50,11 @@ impl Item {
|
||||||
Item::MovableBlock => resources::ROCK_SHADOW,
|
Item::MovableBlock => resources::ROCK_SHADOW,
|
||||||
Item::Glove => resources::POW_GLOVE_SHADOW,
|
Item::Glove => resources::POW_GLOVE_SHADOW,
|
||||||
Item::Teleporter => resources::TELEPORTER_SHADOW,
|
Item::Teleporter => resources::TELEPORTER_SHADOW,
|
||||||
|
Item::Hole => resources::HOLE,
|
||||||
|
Item::RotatorRight => resources::ROTATOR_RIGHT,
|
||||||
|
Item::RotatorLeft => resources::ROTATOR_LEFT,
|
||||||
|
Item::RotatorUp => resources::ROTATOR_UP,
|
||||||
|
Item::RotatorDown => resources::ROTATOR_DOWN,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +78,11 @@ impl Item {
|
||||||
Item::MovableBlock => resources::ROCK,
|
Item::MovableBlock => resources::ROCK,
|
||||||
Item::Glove => resources::POW_GLOVE,
|
Item::Glove => resources::POW_GLOVE,
|
||||||
Item::Teleporter => resources::TELEPORTER,
|
Item::Teleporter => resources::TELEPORTER,
|
||||||
|
Item::Hole => resources::HOLE,
|
||||||
|
Item::RotatorRight => resources::ROTATOR_RIGHT,
|
||||||
|
Item::RotatorLeft => resources::ROTATOR_LEFT,
|
||||||
|
Item::RotatorUp => resources::ROTATOR_UP,
|
||||||
|
Item::RotatorDown => resources::ROTATOR_DOWN,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,6 +109,11 @@ impl Item {
|
||||||
Item::MovableBlock => ZERO,
|
Item::MovableBlock => ZERO,
|
||||||
Item::Glove => STANDARD,
|
Item::Glove => STANDARD,
|
||||||
Item::Teleporter => ZERO,
|
Item::Teleporter => ZERO,
|
||||||
|
Item::Hole => ZERO,
|
||||||
|
Item::RotatorRight => STANDARD,
|
||||||
|
Item::RotatorLeft => STANDARD,
|
||||||
|
Item::RotatorUp => STANDARD,
|
||||||
|
Item::RotatorDown => STANDARD,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,11 @@ named_tag!(
|
||||||
POW_GLOVE_SHADOW,
|
POW_GLOVE_SHADOW,
|
||||||
TELEPORTER,
|
TELEPORTER,
|
||||||
TELEPORTER_SHADOW,
|
TELEPORTER_SHADOW,
|
||||||
|
HOLE,
|
||||||
|
ROTATOR_RIGHT,
|
||||||
|
ROTATOR_UP,
|
||||||
|
ROTATOR_LEFT,
|
||||||
|
ROTATOR_DOWN,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue