mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 08:11:33 +11:00
add block
This commit is contained in:
parent
a0ab3e9fb4
commit
36603d5446
|
@ -10,25 +10,9 @@ use proc_macro2::TokenStream;
|
||||||
|
|
||||||
const LEVEL_NAMES: &[&str] = &[
|
const LEVEL_NAMES: &[&str] = &[
|
||||||
"a_familiar_sight",
|
"a_familiar_sight",
|
||||||
"level1",
|
"block_push_1",
|
||||||
"level2",
|
"block_push_2",
|
||||||
"level3",
|
"block_push_3",
|
||||||
"level4",
|
|
||||||
"level5",
|
|
||||||
"level6",
|
|
||||||
"level_switch",
|
|
||||||
"level_spikes",
|
|
||||||
"level_spikes2",
|
|
||||||
"level_squid_force_button",
|
|
||||||
"level_squid_intro",
|
|
||||||
"level_squid2",
|
|
||||||
"level_squid1",
|
|
||||||
"level_squid_item",
|
|
||||||
"level_squid_button",
|
|
||||||
"level_squid_drop",
|
|
||||||
"level_spikes3",
|
|
||||||
"level_around",
|
|
||||||
"level_squidprogramming",
|
|
||||||
];
|
];
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -102,6 +86,8 @@ enum Entity {
|
||||||
SquidUp,
|
SquidUp,
|
||||||
SquidDown,
|
SquidDown,
|
||||||
Ice,
|
Ice,
|
||||||
|
MovableBlock,
|
||||||
|
Glove,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for Entity {
|
impl FromStr for Entity {
|
||||||
|
@ -126,6 +112,8 @@ impl FromStr for Entity {
|
||||||
"SQUID_UP" => SquidUp,
|
"SQUID_UP" => SquidUp,
|
||||||
"SQUID_DOWN" => SquidDown,
|
"SQUID_DOWN" => SquidDown,
|
||||||
"ICE" => Ice,
|
"ICE" => Ice,
|
||||||
|
"BLOCK" => MovableBlock,
|
||||||
|
"GLOVE" => Glove,
|
||||||
_ => return Err(()),
|
_ => return Err(()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -151,6 +139,8 @@ impl quote::ToTokens for Entity {
|
||||||
SquidUp => quote!(Item::SquidUp),
|
SquidUp => quote!(Item::SquidUp),
|
||||||
SquidDown => quote!(Item::SquidDown),
|
SquidDown => quote!(Item::SquidDown),
|
||||||
Ice => quote!(Item::Ice),
|
Ice => quote!(Item::Ice),
|
||||||
|
MovableBlock => quote!(Item::MovableBlock),
|
||||||
|
Glove => quote!(Item::Glove),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,37 @@
|
||||||
|
<?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="7">
|
||||||
|
<properties>
|
||||||
|
<property name="DIRECTIONS" value="LLLLLLLLUUUU"/>
|
||||||
|
<property name="ITEMS" value="BLOCK,BLOCK"/>
|
||||||
|
<property name="NAME" value="Less familiar, but exciting nonetheless"/>
|
||||||
|
</properties>
|
||||||
|
<tileset firstgid="1" source="../level16.tsx"/>
|
||||||
|
<layer id="1" name="Tile Layer 1" width="11" height="10">
|
||||||
|
<data encoding="csv">
|
||||||
|
0,1,3,2,6,9,0,0,0,0,0,
|
||||||
|
0,46,15,14,13,3221225500,4,6,7,7,9,
|
||||||
|
0,46,12,11,15,16,11,13,15,14,38,
|
||||||
|
0,46,12,13,14,16,17,14,11,12,18,
|
||||||
|
0,10,13,16,15,14,12,14,13,15,18,
|
||||||
|
0,46,16,17,17,13,15,14,16,15,18,
|
||||||
|
0,19,28,17,11,16,12,15,17,15,38,
|
||||||
|
0,0,19,20,28,17,17,15,17,2147483676,27,
|
||||||
|
0,0,0,0,19,21,25,20,23,27,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
</data>
|
||||||
|
</layer>
|
||||||
|
<objectgroup id="2" name="Object Layer 1">
|
||||||
|
<object id="3" name="HERO" x="119.458" y="71.7665">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="4" name="SWITCH" x="71.308" y="71.5373">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="5" name="STAIRS" x="86.8994" y="39.6665">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="6" name="DOOR_SWITCHED" x="87.1287" y="54.3408">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
</objectgroup>
|
||||||
|
</map>
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?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="14">
|
||||||
|
<properties>
|
||||||
|
<property name="DIRECTIONS" value="RRUURRDD"/>
|
||||||
|
<property name="ITEMS" value="GLOVE"/>
|
||||||
|
<property name="NAME" value="Should be simple for a dungoen puzzler such as yourself"/>
|
||||||
|
</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,0,0,0,1,4,3,9,0,0,0,
|
||||||
|
0,0,0,1,1073741852,16,15,3221225500,8,9,0,
|
||||||
|
0,0,0,46,12,15,13,17,11,38,0,
|
||||||
|
0,0,0,19,24,28,17,2147483676,25,27,0,
|
||||||
|
0,0,0,0,0,10,13,47,0,0,0,
|
||||||
|
0,0,0,0,0,19,20,27,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="7" name="STAIRS" x="103.179" y="87.8166">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="9" name="BLOCK" x="86.8994" y="88.2751">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="11" name="BLOCK" x="103.408" y="105.013">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="12" name="HERO" x="69.9323" y="87.1287">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="13" name="BLOCK" x="119.687" y="86.6701">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
</objectgroup>
|
||||||
|
</map>
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?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="20">
|
||||||
|
<properties>
|
||||||
|
<property name="DIRECTIONS" value="RRUURRDD"/>
|
||||||
|
<property name="ITEMS" value="BLOCK,ICE"/>
|
||||||
|
<property name="NAME" value="Wow, finally a level with nothing new introduced!"/>
|
||||||
|
</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,1,6,2,8,8,9,0,0,0,
|
||||||
|
0,1,1073741852,17,12,16,12,3221225500,9,0,0,
|
||||||
|
0,46,11,16,12,17,17,12,38,0,0,
|
||||||
|
0,46,17,16,12,16,11,14,38,0,0,
|
||||||
|
0,19,26,28,14,12,14,15,38,0,0,
|
||||||
|
0,0,0,19,24,28,11,2147483676,27,0,0,
|
||||||
|
0,0,0,0,0,19,23,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
|
||||||
|
</data>
|
||||||
|
</layer>
|
||||||
|
<objectgroup id="2" name="Object Layer 1">
|
||||||
|
<object id="14" name="HERO" x="54.7994" y="55.9458">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="16" name="BLOCK" x="103.408" y="71.7665">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="17" name="SWITCH" x="119.458" y="55.4872">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="18" name="STAIRS" x="103.408" y="87.358">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
<object id="19" name="DOOR_SWITCHED" x="104.325" y="103.179">
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
|
</objectgroup>
|
||||||
|
</map>
|
|
@ -85,6 +85,195 @@ impl EntityMap {
|
||||||
AnimationInstruction::Add(idx, entity, location, None)
|
AnimationInstruction::Add(idx, entity, location, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn attempt_move_in_direction(
|
||||||
|
&mut self,
|
||||||
|
map: &Map,
|
||||||
|
animations: &mut Vec<AnimationInstruction>,
|
||||||
|
entities_to_try_update: &mut VecDeque<(EntityKey, Action)>,
|
||||||
|
entity_to_update_key: EntityKey,
|
||||||
|
direction: Direction,
|
||||||
|
depth: i32,
|
||||||
|
) -> (bool, bool, bool) {
|
||||||
|
let mut hero_has_died = false;
|
||||||
|
let mut win_has_triggered = false;
|
||||||
|
|
||||||
|
let Some(entity_to_update) = self.map.get(entity_to_update_key) else {
|
||||||
|
return (false, hero_has_died, win_has_triggered);
|
||||||
|
};
|
||||||
|
|
||||||
|
let entity_location = entity_to_update.location;
|
||||||
|
|
||||||
|
let desired_location = entity_location + direction.into();
|
||||||
|
let surface = map.get(desired_location);
|
||||||
|
if surface == MapElement::Wall {
|
||||||
|
animations.push(AnimationInstruction::FakeOutMove(
|
||||||
|
entity_to_update_key,
|
||||||
|
direction,
|
||||||
|
self.map
|
||||||
|
.get(entity_to_update_key)
|
||||||
|
.and_then(|e| e.fake_out_wall_effect()),
|
||||||
|
));
|
||||||
|
return (false, hero_has_died, win_has_triggered);
|
||||||
|
}
|
||||||
|
|
||||||
|
let (can_move, explicit_stay_put, fake_out_effect) = {
|
||||||
|
let mut can_move = true;
|
||||||
|
let mut explicit_stay_put = false;
|
||||||
|
let mut fake_out_effect = None;
|
||||||
|
|
||||||
|
let move_attempt_resolutions: Vec<_> = self
|
||||||
|
.whats_at(desired_location)
|
||||||
|
.filter(|(k, _)| *k != entity_to_update_key)
|
||||||
|
.map(|(key, other_entity)| (key, resolve_move(entity_to_update, other_entity)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
for (other_entity_key, move_resolution) in move_attempt_resolutions {
|
||||||
|
match move_resolution {
|
||||||
|
MoveAttemptResolution::KillDie => {
|
||||||
|
hero_has_died |= self.kill_entity(other_entity_key, animations);
|
||||||
|
hero_has_died |= self.kill_entity(entity_to_update_key, animations);
|
||||||
|
can_move = false;
|
||||||
|
}
|
||||||
|
MoveAttemptResolution::Kill => {
|
||||||
|
hero_has_died |= self.kill_entity(other_entity_key, animations);
|
||||||
|
fake_out_effect = self
|
||||||
|
.map
|
||||||
|
.get(entity_to_update_key)
|
||||||
|
.and_then(|x| x.kill_sound_effect());
|
||||||
|
can_move = false;
|
||||||
|
}
|
||||||
|
MoveAttemptResolution::Die => {
|
||||||
|
hero_has_died |= self.kill_entity(entity_to_update_key, animations);
|
||||||
|
can_move = false;
|
||||||
|
}
|
||||||
|
MoveAttemptResolution::CoExist => {}
|
||||||
|
MoveAttemptResolution::StayPut => {
|
||||||
|
can_move = false;
|
||||||
|
explicit_stay_put = true;
|
||||||
|
}
|
||||||
|
MoveAttemptResolution::AttemptPush => {
|
||||||
|
let depth = depth - 1;
|
||||||
|
if depth >= 0 {
|
||||||
|
let (can_move_result, hero_has_died_result, win_has_triggered_result) =
|
||||||
|
self.attempt_move_in_direction(
|
||||||
|
map,
|
||||||
|
animations,
|
||||||
|
entities_to_try_update,
|
||||||
|
other_entity_key,
|
||||||
|
direction,
|
||||||
|
depth,
|
||||||
|
);
|
||||||
|
|
||||||
|
if !can_move_result {
|
||||||
|
can_move = false;
|
||||||
|
}
|
||||||
|
hero_has_died |= hero_has_died_result;
|
||||||
|
win_has_triggered |= win_has_triggered_result;
|
||||||
|
} else {
|
||||||
|
can_move = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(can_move, explicit_stay_put, fake_out_effect)
|
||||||
|
};
|
||||||
|
|
||||||
|
if can_move {
|
||||||
|
if let Some(e) = self.map.get_mut(entity_to_update_key) {
|
||||||
|
e.location = desired_location;
|
||||||
|
}
|
||||||
|
let Some(entity_to_update) = self.map.get(entity_to_update_key) else {
|
||||||
|
return (can_move, hero_has_died, win_has_triggered);
|
||||||
|
};
|
||||||
|
|
||||||
|
animations.push(AnimationInstruction::Move(
|
||||||
|
entity_to_update_key,
|
||||||
|
desired_location,
|
||||||
|
entity_to_update.move_effect(),
|
||||||
|
));
|
||||||
|
|
||||||
|
let overlap_resolutions: Vec<_> = self
|
||||||
|
.whats_at(desired_location)
|
||||||
|
.filter(|(k, _)| *k != entity_to_update_key)
|
||||||
|
.map(|(key, other_entity)| (key, resolve_overlap(entity_to_update, other_entity)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
for (other_entity_key, move_resolution) in overlap_resolutions {
|
||||||
|
match move_resolution {
|
||||||
|
OverlapResolution::Pickup => {
|
||||||
|
animations.push(AnimationInstruction::Attach(
|
||||||
|
entity_to_update_key,
|
||||||
|
other_entity_key,
|
||||||
|
self.map
|
||||||
|
.get(other_entity_key)
|
||||||
|
.and_then(|x| x.pickup_sound_effect()),
|
||||||
|
));
|
||||||
|
let other = self.map.remove(other_entity_key).unwrap();
|
||||||
|
|
||||||
|
if let Some((location, dropped)) = self
|
||||||
|
.map
|
||||||
|
.get_mut(entity_to_update_key)
|
||||||
|
.and_then(|x| x.pickup(other.entity).map(|y| (x.location, y)))
|
||||||
|
{
|
||||||
|
let new_key = self.map.insert(Entity {
|
||||||
|
location,
|
||||||
|
entity: dropped,
|
||||||
|
});
|
||||||
|
|
||||||
|
animations.push(AnimationInstruction::Detatch(
|
||||||
|
entity_to_update_key,
|
||||||
|
new_key,
|
||||||
|
self.map.get(new_key).and_then(|x| x.drop_effect()),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OverlapResolution::CoExist => {}
|
||||||
|
OverlapResolution::Win => {
|
||||||
|
win_has_triggered = true;
|
||||||
|
}
|
||||||
|
OverlapResolution::ToggleSystem(system) => {
|
||||||
|
for (k, e) in self.map.iter_mut() {
|
||||||
|
if let Some(change) = e.switch(system) {
|
||||||
|
animations.push(AnimationInstruction::Change(
|
||||||
|
k,
|
||||||
|
change,
|
||||||
|
e.change_effect(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OverlapResolution::Die => {
|
||||||
|
hero_has_died |= self.kill_entity(entity_to_update_key, animations);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
OverlapResolution::MoveAgain => {
|
||||||
|
entities_to_try_update
|
||||||
|
.push_front((entity_to_update_key, Action::Direction(direction)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
animations.push(AnimationInstruction::FakeOutMove(
|
||||||
|
entity_to_update_key,
|
||||||
|
direction,
|
||||||
|
if explicit_stay_put {
|
||||||
|
self.map
|
||||||
|
.get(entity_to_update_key)
|
||||||
|
.and_then(|e| e.fake_out_wall_effect())
|
||||||
|
} else {
|
||||||
|
fake_out_effect.or_else(|| {
|
||||||
|
self.map
|
||||||
|
.get(entity_to_update_key)
|
||||||
|
.and_then(|e| e.fake_out_effect())
|
||||||
|
})
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
(can_move, hero_has_died, win_has_triggered)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn tick(&mut self, map: &Map, hero: Action) -> (Outcome, Vec<AnimationInstruction>) {
|
pub fn tick(&mut self, map: &Map, hero: Action) -> (Outcome, Vec<AnimationInstruction>) {
|
||||||
let mut hero_has_died = false;
|
let mut hero_has_died = false;
|
||||||
let mut win_has_triggered = false;
|
let mut win_has_triggered = false;
|
||||||
|
@ -117,169 +306,21 @@ impl EntityMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(entity_to_update) = self.map.get(entity_to_update_key) else {
|
let (_, hero_has_died_result, win_has_triggered_result) = self
|
||||||
continue;
|
.attempt_move_in_direction(
|
||||||
};
|
map,
|
||||||
|
&mut animations,
|
||||||
let entity_location = entity_to_update.location;
|
&mut entities_to_try_update,
|
||||||
|
|
||||||
let desired_location = entity_location + direction.into();
|
|
||||||
let surface = map.get(desired_location);
|
|
||||||
if surface == MapElement::Wall {
|
|
||||||
animations.push(AnimationInstruction::FakeOutMove(
|
|
||||||
entity_to_update_key,
|
entity_to_update_key,
|
||||||
direction,
|
direction,
|
||||||
self.map
|
self.map
|
||||||
.get(entity_to_update_key)
|
.get(entity_to_update_key)
|
||||||
.and_then(|e| e.fake_out_wall_effect()),
|
.and_then(|e| e.push_depth())
|
||||||
));
|
.unwrap_or(0),
|
||||||
continue;
|
);
|
||||||
}
|
|
||||||
|
|
||||||
let (can_move, explicit_stay_put, fake_out_effect) = {
|
hero_has_died |= hero_has_died_result;
|
||||||
let mut can_move = true;
|
win_has_triggered |= win_has_triggered_result;
|
||||||
let mut explicit_stay_put = false;
|
|
||||||
let mut fake_out_effect = None;
|
|
||||||
|
|
||||||
let move_attempt_resolutions: Vec<_> = self
|
|
||||||
.whats_at(desired_location)
|
|
||||||
.filter(|(k, _)| *k != entity_to_update_key)
|
|
||||||
.map(|(key, other_entity)| {
|
|
||||||
(key, resolve_move(entity_to_update, other_entity))
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
for (other_entity_key, move_resolution) in move_attempt_resolutions {
|
|
||||||
match move_resolution {
|
|
||||||
MoveAttemptResolution::KillDie => {
|
|
||||||
hero_has_died |=
|
|
||||||
self.kill_entity(other_entity_key, &mut animations);
|
|
||||||
hero_has_died |=
|
|
||||||
self.kill_entity(entity_to_update_key, &mut animations);
|
|
||||||
can_move = false;
|
|
||||||
}
|
|
||||||
MoveAttemptResolution::Kill => {
|
|
||||||
hero_has_died |=
|
|
||||||
self.kill_entity(other_entity_key, &mut animations);
|
|
||||||
fake_out_effect = self
|
|
||||||
.map
|
|
||||||
.get(entity_to_update_key)
|
|
||||||
.and_then(|x| x.kill_sound_effect());
|
|
||||||
can_move = false;
|
|
||||||
}
|
|
||||||
MoveAttemptResolution::Die => {
|
|
||||||
hero_has_died |=
|
|
||||||
self.kill_entity(entity_to_update_key, &mut animations);
|
|
||||||
can_move = false;
|
|
||||||
}
|
|
||||||
MoveAttemptResolution::CoExist => {}
|
|
||||||
MoveAttemptResolution::StayPut => {
|
|
||||||
can_move = false;
|
|
||||||
explicit_stay_put = true;
|
|
||||||
}
|
|
||||||
MoveAttemptResolution::AttemptPush => todo!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(can_move, explicit_stay_put, fake_out_effect)
|
|
||||||
};
|
|
||||||
|
|
||||||
if can_move {
|
|
||||||
if let Some(e) = self.map.get_mut(entity_to_update_key) {
|
|
||||||
e.location = desired_location;
|
|
||||||
}
|
|
||||||
let Some(entity_to_update) = self.map.get(entity_to_update_key) else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
animations.push(AnimationInstruction::Move(
|
|
||||||
entity_to_update_key,
|
|
||||||
desired_location,
|
|
||||||
entity_to_update.move_effect(),
|
|
||||||
));
|
|
||||||
|
|
||||||
let overlap_resolutions: Vec<_> = self
|
|
||||||
.whats_at(desired_location)
|
|
||||||
.filter(|(k, _)| *k != entity_to_update_key)
|
|
||||||
.map(|(key, other_entity)| {
|
|
||||||
(key, resolve_overlap(entity_to_update, other_entity))
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
for (other_entity_key, move_resolution) in overlap_resolutions {
|
|
||||||
match move_resolution {
|
|
||||||
OverlapResolution::Pickup => {
|
|
||||||
animations.push(AnimationInstruction::Attach(
|
|
||||||
entity_to_update_key,
|
|
||||||
other_entity_key,
|
|
||||||
self.map
|
|
||||||
.get(other_entity_key)
|
|
||||||
.and_then(|x| x.pickup_sound_effect()),
|
|
||||||
));
|
|
||||||
let other = self.map.remove(other_entity_key).unwrap();
|
|
||||||
|
|
||||||
if let Some((location, dropped)) =
|
|
||||||
self.map.get_mut(entity_to_update_key).and_then(|x| {
|
|
||||||
x.pickup(other.entity).map(|y| (x.location, y))
|
|
||||||
})
|
|
||||||
{
|
|
||||||
let new_key = self.map.insert(Entity {
|
|
||||||
location,
|
|
||||||
entity: dropped,
|
|
||||||
});
|
|
||||||
|
|
||||||
animations.push(AnimationInstruction::Detatch(
|
|
||||||
entity_to_update_key,
|
|
||||||
new_key,
|
|
||||||
self.map.get(new_key).and_then(|x| x.drop_effect()),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OverlapResolution::CoExist => {}
|
|
||||||
OverlapResolution::Win => {
|
|
||||||
win_has_triggered = true;
|
|
||||||
}
|
|
||||||
OverlapResolution::ToggleSystem(system) => {
|
|
||||||
for (k, e) in self.map.iter_mut() {
|
|
||||||
if let Some(change) = e.switch(system) {
|
|
||||||
animations.push(AnimationInstruction::Change(
|
|
||||||
k,
|
|
||||||
change,
|
|
||||||
e.change_effect(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OverlapResolution::Die => {
|
|
||||||
hero_has_died |=
|
|
||||||
self.kill_entity(entity_to_update_key, &mut animations);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
OverlapResolution::MoveAgain => {
|
|
||||||
entities_to_try_update.push_front((
|
|
||||||
entity_to_update_key,
|
|
||||||
Action::Direction(direction),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
animations.push(AnimationInstruction::FakeOutMove(
|
|
||||||
entity_to_update_key,
|
|
||||||
direction,
|
|
||||||
if explicit_stay_put {
|
|
||||||
self.map
|
|
||||||
.get(entity_to_update_key)
|
|
||||||
.and_then(|e| e.fake_out_wall_effect())
|
|
||||||
} else {
|
|
||||||
fake_out_effect.or_else(|| {
|
|
||||||
self.map
|
|
||||||
.get(entity_to_update_key)
|
|
||||||
.and_then(|e| e.fake_out_effect())
|
|
||||||
})
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,6 +372,7 @@ 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::Item(_)) => OverlapResolution::Pickup,
|
(_, EntityType::Item(_)) => OverlapResolution::Pickup,
|
||||||
|
(EntityType::MovableBlock, EntityType::Spikes(_)) => OverlapResolution::CoExist,
|
||||||
(_, EntityType::Spikes(switch)) => resolve_spikes(switch),
|
(_, EntityType::Spikes(switch)) => resolve_spikes(switch),
|
||||||
(_, EntityType::Switch(switch)) => OverlapResolution::ToggleSystem(switch.system),
|
(_, EntityType::Switch(switch)) => OverlapResolution::ToggleSystem(switch.system),
|
||||||
(_, EntityType::Enemy(_) | EntityType::Hero(_)) => OverlapResolution::Die,
|
(_, EntityType::Enemy(_) | EntityType::Hero(_)) => OverlapResolution::Die,
|
||||||
|
@ -408,6 +450,7 @@ fn resolve_move(mover: &Entity, into: &Entity) -> MoveAttemptResolution {
|
||||||
holding_door_resolve(squid.holding.as_deref())
|
holding_door_resolve(squid.holding.as_deref())
|
||||||
}
|
}
|
||||||
(_, EntityType::Door) => MoveAttemptResolution::StayPut,
|
(_, EntityType::Door) => MoveAttemptResolution::StayPut,
|
||||||
|
(_, EntityType::MovableBlock) => MoveAttemptResolution::AttemptPush,
|
||||||
(_, _) => MoveAttemptResolution::CoExist,
|
(_, _) => MoveAttemptResolution::CoExist,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -439,6 +482,7 @@ pub enum EntityType {
|
||||||
Switch(Switchable),
|
Switch(Switchable),
|
||||||
Spikes(Switchable),
|
Spikes(Switchable),
|
||||||
Ice,
|
Ice,
|
||||||
|
MovableBlock,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -457,6 +501,7 @@ pub enum Enemy {
|
||||||
pub enum Item {
|
pub enum Item {
|
||||||
Sword,
|
Sword,
|
||||||
Key,
|
Key,
|
||||||
|
Glove,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||||
|
@ -552,6 +597,14 @@ impl Entity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn push_depth(&self) -> Option<i32> {
|
||||||
|
if matches!(self.holding(), Some(&EntityType::Item(Item::Glove))) {
|
||||||
|
Some(i32::MAX)
|
||||||
|
} else {
|
||||||
|
Some(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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(),
|
||||||
|
@ -721,6 +774,8 @@ impl From<level::Item> for EntityType {
|
||||||
holding: None,
|
holding: None,
|
||||||
})),
|
})),
|
||||||
level::Item::Ice => EntityType::Ice,
|
level::Item::Ice => EntityType::Ice,
|
||||||
|
level::Item::MovableBlock => EntityType::MovableBlock,
|
||||||
|
level::Item::Glove => EntityType::Item(Item::Glove),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ pub enum Item {
|
||||||
SquidUp,
|
SquidUp,
|
||||||
SquidDown,
|
SquidDown,
|
||||||
Ice,
|
Ice,
|
||||||
|
MovableBlock,
|
||||||
|
Glove,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Item {
|
impl Item {
|
||||||
|
@ -39,6 +41,8 @@ impl Item {
|
||||||
Item::SquidUp => resources::SQUID_UP_SHADOW,
|
Item::SquidUp => resources::SQUID_UP_SHADOW,
|
||||||
Item::SquidDown => resources::SQUID_DOWN_SHADOW,
|
Item::SquidDown => resources::SQUID_DOWN_SHADOW,
|
||||||
Item::Ice => resources::ICE,
|
Item::Ice => resources::ICE,
|
||||||
|
Item::MovableBlock => resources::BLOCK,
|
||||||
|
Item::Glove => resources::GLOVE,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +63,8 @@ impl Item {
|
||||||
Item::SquidUp => resources::SQUID_UP,
|
Item::SquidUp => resources::SQUID_UP,
|
||||||
Item::SquidDown => resources::SQUID_DOWN,
|
Item::SquidDown => resources::SQUID_DOWN,
|
||||||
Item::Ice => resources::ICE,
|
Item::Ice => resources::ICE,
|
||||||
|
Item::MovableBlock => resources::BLOCK,
|
||||||
|
Item::Glove => resources::GLOVE,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +88,8 @@ impl Item {
|
||||||
Item::SquidUp => STANDARD,
|
Item::SquidUp => STANDARD,
|
||||||
Item::SquidDown => STANDARD,
|
Item::SquidDown => STANDARD,
|
||||||
Item::Ice => ZERO,
|
Item::Ice => ZERO,
|
||||||
|
Item::MovableBlock => ZERO,
|
||||||
|
Item::Glove => STANDARD,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,8 @@ named_tag!(
|
||||||
SQUID_UP_SHADOW,
|
SQUID_UP_SHADOW,
|
||||||
SQUID_DOWN_SHADOW,
|
SQUID_DOWN_SHADOW,
|
||||||
ICE,
|
ICE,
|
||||||
|
BLOCK,
|
||||||
|
GLOVE,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue