@@ -6,108 +6,114 @@ use super::{Position, Player, Viewshed, State, Map, RunState, Attributes, WantsT
66 EntityMoved , Door , BlocksTile , BlocksVisibility , Renderable , Pools , Faction ,
77 raws:: Reaction , Vendor , VendorMode } ;
88
9- pub fn try_move_player ( delta_x : i32 , delta_y : i32 , ecs : & mut World ) -> RunState {
10- let mut positions = ecs. write_storage :: < Position > ( ) ;
11- let players = ecs. read_storage :: < Player > ( ) ;
12- let mut viewsheds = ecs. write_storage :: < Viewshed > ( ) ;
13- let entities = ecs. entities ( ) ;
14- let combat_stats = ecs. read_storage :: < Attributes > ( ) ;
15- let map = ecs. fetch :: < Map > ( ) ;
16- let mut wants_to_melee = ecs. write_storage :: < WantsToMelee > ( ) ;
17- let mut entity_moved = ecs. write_storage :: < EntityMoved > ( ) ;
18- let mut doors = ecs. write_storage :: < Door > ( ) ;
19- let mut blocks_visibility = ecs. write_storage :: < BlocksVisibility > ( ) ;
20- let mut blocks_movement = ecs. write_storage :: < BlocksTile > ( ) ;
21- let mut renderables = ecs. write_storage :: < Renderable > ( ) ;
22- let factions = ecs. read_storage :: < Faction > ( ) ;
23- let mut result = RunState :: AwaitingInput ;
24-
25- let mut swap_entities : Vec < ( Entity , i32 , i32 ) > = Vec :: new ( ) ;
26-
27- for ( entity, _player, pos, viewshed) in ( & entities, & players, & mut positions, & mut viewsheds) . join ( ) {
28- if pos. x + delta_x < 1 || pos. x + delta_x > map. width -1 || pos. y + delta_y < 1 || pos. y + delta_y > map. height -1 { return RunState :: AwaitingInput ; }
29- let destination_idx = map. xy_idx ( pos. x + delta_x, pos. y + delta_y) ;
30-
31- crate :: spatial:: for_each_tile_content ( destination_idx, |potential_target| {
32- let mut hostile = true ;
33- if combat_stats. get ( potential_target) . is_some ( ) {
34- if let Some ( faction) = factions. get ( potential_target) {
35- let reaction = crate :: raws:: faction_reaction (
36- & faction. name ,
37- "Player" ,
38- & crate :: raws:: RAWS . lock ( ) . unwrap ( )
39- ) ;
40- if reaction != Reaction :: Attack { hostile = false ; }
41- }
42- }
43- if !hostile {
44- // Note that we want to move the bystander
45- swap_entities. push ( ( potential_target, pos. x , pos. y ) ) ;
46-
47- // Move the player
48- pos. x = min ( map. width -1 , max ( 0 , pos. x + delta_x) ) ;
49- pos. y = min ( map. height -1 , max ( 0 , pos. y + delta_y) ) ;
50- entity_moved. insert ( entity, EntityMoved { } ) . expect ( "Unable to insert marker" ) ;
51-
52- viewshed. dirty = true ;
53- let mut ppos = ecs. write_resource :: < Point > ( ) ;
54- ppos. x = pos. x ;
55- ppos. y = pos. y ;
56- } else {
57- let target = combat_stats. get ( potential_target) ;
58- if let Some ( _target) = target {
59- wants_to_melee. insert ( entity, WantsToMelee { target : potential_target } ) . expect ( "Add target failed" ) ;
60- result = RunState :: Ticking ;
61- }
62- }
63- let door = doors. get_mut ( potential_target) ;
64- if let Some ( door) = door {
65- door. open = true ;
66- blocks_visibility. remove ( potential_target) ;
67- blocks_movement. remove ( potential_target) ;
68- let glyph = renderables. get_mut ( potential_target) . unwrap ( ) ;
69- glyph. glyph = rltk:: to_cp437 ( '/' ) ;
70- viewshed. dirty = true ;
71- result = RunState :: Ticking ;
9+ pub fn try_move_player ( delta_x : i32 , delta_y : i32 , ecs : & mut World ) -> RunState {
10+ let mut positions = ecs. write_storage :: < Position > ( ) ;
11+ let players = ecs. read_storage :: < Player > ( ) ;
12+ let mut viewsheds = ecs. write_storage :: < Viewshed > ( ) ;
13+ let entities = ecs. entities ( ) ;
14+ let combat_stats = ecs. read_storage :: < Attributes > ( ) ;
15+ let map = ecs. fetch :: < Map > ( ) ;
16+ let mut wants_to_melee = ecs. write_storage :: < WantsToMelee > ( ) ;
17+ let mut entity_moved = ecs. write_storage :: < EntityMoved > ( ) ;
18+ let mut doors = ecs. write_storage :: < Door > ( ) ;
19+ let mut blocks_visibility = ecs. write_storage :: < BlocksVisibility > ( ) ;
20+ let mut blocks_movement = ecs. write_storage :: < BlocksTile > ( ) ;
21+ let mut renderables = ecs. write_storage :: < Renderable > ( ) ;
22+ let factions = ecs. read_storage :: < Faction > ( ) ;
23+ let mut result = RunState :: AwaitingInput ;
24+ let vendors = ecs. read_storage :: < Vendor > ( ) ;
25+
26+ let mut swap_entities : Vec < ( Entity , i32 , i32 ) > = Vec :: new ( ) ;
27+
28+ for ( entity, _player, pos, viewshed) in ( & entities, & players, & mut positions, & mut viewsheds) . join ( ) {
29+ if pos. x + delta_x < 1 || pos. x + delta_x > map. width -1 || pos. y + delta_y < 1 || pos. y + delta_y > map. height -1 { return RunState :: AwaitingInput ; }
30+ let destination_idx = map. xy_idx ( pos. x + delta_x, pos. y + delta_y) ;
31+
32+ result = crate :: spatial:: for_each_tile_content_with_gamemode ( destination_idx, |potential_target| {
33+ if let Some ( _vendor) = vendors. get ( potential_target) {
34+ return Some ( RunState :: ShowVendor { vendor : potential_target, mode : VendorMode :: Sell } ) ;
35+ }
36+ let mut hostile = true ;
37+ if combat_stats. get ( potential_target) . is_some ( ) {
38+ if let Some ( faction) = factions. get ( potential_target) {
39+ let reaction = crate :: raws:: faction_reaction (
40+ & faction. name ,
41+ "Player" ,
42+ & crate :: raws:: RAWS . lock ( ) . unwrap ( )
43+ ) ;
44+ if reaction != Reaction :: Attack { hostile = false ; }
7245 }
73- } ) ;
74-
75- if !crate :: spatial:: is_blocked ( destination_idx) {
76- let old_idx = map. xy_idx ( pos. x , pos. y ) ;
46+ }
47+ if !hostile {
48+ // Note that we want to move the bystander
49+ swap_entities. push ( ( potential_target, pos. x , pos. y ) ) ;
50+
51+ // Move the player
7752 pos. x = min ( map. width -1 , max ( 0 , pos. x + delta_x) ) ;
7853 pos. y = min ( map. height -1 , max ( 0 , pos. y + delta_y) ) ;
79- let new_idx = map. xy_idx ( pos. x , pos. y ) ;
8054 entity_moved. insert ( entity, EntityMoved { } ) . expect ( "Unable to insert marker" ) ;
81- crate :: spatial:: move_entity ( entity, old_idx, new_idx) ;
82-
55+
8356 viewshed. dirty = true ;
8457 let mut ppos = ecs. write_resource :: < Point > ( ) ;
8558 ppos. x = pos. x ;
8659 ppos. y = pos. y ;
87- result = RunState :: Ticking ;
88- match map. tiles [ destination_idx] {
89- TileType :: DownStairs => result = RunState :: NextLevel ,
90- TileType :: UpStairs => result = RunState :: PreviousLevel ,
91- _ => { }
60+ return Some ( RunState :: Ticking ) ;
61+ } else {
62+ let target = combat_stats. get ( potential_target) ;
63+ if let Some ( _target) = target {
64+ wants_to_melee. insert ( entity, WantsToMelee { target : potential_target } ) . expect ( "Add target failed" ) ;
65+ return Some ( RunState :: Ticking ) ;
9266 }
9367 }
94- }
95-
96- for m in swap_entities. iter ( ) {
97- let their_pos = positions. get_mut ( m. 0 ) ;
98- if let Some ( their_pos) = their_pos {
99- let old_idx = map. xy_idx ( their_pos. x , their_pos. y ) ;
100- their_pos. x = m. 1 ;
101- their_pos. y = m. 2 ;
102- let new_idx = map. xy_idx ( their_pos. x , their_pos. y ) ;
103- crate :: spatial:: move_entity ( m. 0 , old_idx, new_idx) ;
104- result = RunState :: Ticking ;
68+ let door = doors. get_mut ( potential_target) ;
69+ if let Some ( door) = door {
70+ door. open = true ;
71+ blocks_visibility. remove ( potential_target) ;
72+ blocks_movement. remove ( potential_target) ;
73+ let glyph = renderables. get_mut ( potential_target) . unwrap ( ) ;
74+ glyph. glyph = rltk:: to_cp437 ( '/' ) ;
75+ viewshed. dirty = true ;
76+ return Some ( RunState :: Ticking ) ;
77+ }
78+ None
79+ } ) ;
80+
81+ if !crate :: spatial:: is_blocked ( destination_idx) {
82+ let old_idx = map. xy_idx ( pos. x , pos. y ) ;
83+ pos. x = min ( map. width -1 , max ( 0 , pos. x + delta_x) ) ;
84+ pos. y = min ( map. height -1 , max ( 0 , pos. y + delta_y) ) ;
85+ let new_idx = map. xy_idx ( pos. x , pos. y ) ;
86+ entity_moved. insert ( entity, EntityMoved { } ) . expect ( "Unable to insert marker" ) ;
87+ crate :: spatial:: move_entity ( entity, old_idx, new_idx) ;
88+
89+ viewshed. dirty = true ;
90+ let mut ppos = ecs. write_resource :: < Point > ( ) ;
91+ ppos. x = pos. x ;
92+ ppos. y = pos. y ;
93+ result = RunState :: Ticking ;
94+ match map. tiles [ destination_idx] {
95+ TileType :: DownStairs => result = RunState :: NextLevel ,
96+ TileType :: UpStairs => result = RunState :: PreviousLevel ,
97+ _ => { }
10598 }
10699 }
107-
108- result
109100 }
110101
102+ for m in swap_entities. iter ( ) {
103+ let their_pos = positions. get_mut ( m. 0 ) ;
104+ if let Some ( their_pos) = their_pos {
105+ let old_idx = map. xy_idx ( their_pos. x , their_pos. y ) ;
106+ their_pos. x = m. 1 ;
107+ their_pos. y = m. 2 ;
108+ let new_idx = map. xy_idx ( their_pos. x , their_pos. y ) ;
109+ crate :: spatial:: move_entity ( m. 0 , old_idx, new_idx) ;
110+ result = RunState :: Ticking ;
111+ }
112+ }
113+
114+ result
115+ }
116+
111117pub fn try_next_level ( ecs : & mut World ) -> bool {
112118 let player_pos = ecs. fetch :: < Point > ( ) ;
113119 let map = ecs. fetch :: < Map > ( ) ;
0 commit comments