Skip to content

Commit fde3885

Browse files
committed
TacticalScreen: Individual cameras for each human player
1 parent f2f383e commit fde3885

File tree

2 files changed

+62
-50
lines changed

2 files changed

+62
-50
lines changed

src/visualizer/src/camera.rs

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use cgmath::{perspective, rad, Matrix4, Matrix3, Vector3, Rad, Array};
55
use core::misc::{clamp};
66
use types::{ZFloat, WorldPos, Size2};
77

8+
#[derive(Clone)]
89
pub struct Camera {
910
x_angle: Rad<ZFloat>,
1011
z_angle: Rad<ZFloat>,

src/visualizer/src/tactical_screen.rs

+61-50
Original file line numberDiff line numberDiff line change
@@ -299,25 +299,31 @@ struct PlayerInfo {
299299
game_state: PartialState,
300300
pathfinder: Pathfinder,
301301
scene: Scene,
302+
camera: Camera,
302303
}
303304

304305
struct PlayerInfoManager {
305306
info: HashMap<PlayerId, PlayerInfo>,
306307
}
307308

308309
impl PlayerInfoManager {
309-
fn new(map_size: &Size2, options: &core::Options) -> PlayerInfoManager {
310+
fn new(context: &Context, map_size: &Size2, options: &core::Options) -> PlayerInfoManager {
310311
let mut m = HashMap::new();
312+
let mut camera = Camera::new(&context.win_size);
313+
camera.set_max_pos(get_max_camera_pos(&map_size));
314+
camera.set_pos(get_initial_camera_pos(&map_size));
311315
m.insert(PlayerId{id: 0}, PlayerInfo {
312316
game_state: PartialState::new(map_size, &PlayerId{id: 0}),
313317
pathfinder: Pathfinder::new(map_size),
314318
scene: Scene::new(),
319+
camera: camera.clone(),
315320
});
316321
if options.game_type == core::GameType::Hotseat {
317322
m.insert(PlayerId{id: 1}, PlayerInfo {
318323
game_state: PartialState::new(map_size, &PlayerId{id: 1}),
319324
pathfinder: Pathfinder::new(map_size),
320325
scene: Scene::new(),
326+
camera: camera,
321327
});
322328
}
323329
PlayerInfoManager{info: m}
@@ -336,7 +342,6 @@ impl PlayerInfoManager {
336342
}
337343

338344
pub struct TacticalScreen {
339-
camera: Camera,
340345
map_text_manager: MapTextManager,
341346
// TODO: Move buttons to 'Gui'/'Ui' struct
342347
button_manager: ButtonManager,
@@ -367,7 +372,7 @@ impl TacticalScreen {
367372
pub fn new(context: &mut Context, core_options: &core::Options) -> TacticalScreen {
368373
let core = Core::new(core_options);
369374
let map_size = core.map_size().clone();
370-
let player_info = PlayerInfoManager::new(&map_size, core_options);
375+
let player_info = PlayerInfoManager::new(context, &map_size, core_options);
371376
let floor_tex = load_texture(&mut context.factory, &fs::load("hex.png").into_inner());
372377
let mut meshes = Vec::new();
373378
let visible_map_mesh = generate_visible_tiles_mesh(
@@ -390,9 +395,6 @@ impl TacticalScreen {
390395
&mut meshes, get_marker(context, "flag2.png"));
391396
let unit_type_visual_info
392397
= get_unit_type_visual_info(core.db(), context, &mut meshes);
393-
let mut camera = Camera::new(&context.win_size);
394-
camera.set_max_pos(get_max_camera_pos(&map_size));
395-
camera.set_pos(get_initial_camera_pos(&map_size));
396398
let mut button_manager = ButtonManager::new();
397399
let mut pos = ScreenPos{v: Vector2{x: 10, y: 10}};
398400
let button_end_turn_id = button_manager.add_button(
@@ -417,7 +419,6 @@ impl TacticalScreen {
417419
let map_text_manager = MapTextManager::new();
418420
let (tx, rx) = channel();
419421
let mut screen = TacticalScreen {
420-
camera: camera,
421422
button_manager: button_manager,
422423
button_end_turn_id: button_end_turn_id,
423424
button_deselect_unit_id: button_deselect_unit_id,
@@ -446,7 +447,8 @@ impl TacticalScreen {
446447
}
447448

448449
fn pick_world_pos(&self, context: &Context) -> WorldPos {
449-
let im = self.camera.mat().invert()
450+
let camera = &self.current_player_info().camera;
451+
let im = camera.mat().invert()
450452
.expect("Can`t invert camera matrix");
451453
let w = context.win_size.w as ZFloat;
452454
let h = context.win_size.h as ZFloat;
@@ -523,8 +525,8 @@ impl TacticalScreen {
523525

524526
fn deselect_unit(&mut self) {
525527
self.selected_unit_id = None;
526-
let i = self.player_info.get_mut(self.core.player_id());
527-
self.selection_manager.deselect(&mut i.scene);
528+
let player_info = self.player_info.get_mut(self.core.player_id());
529+
self.selection_manager.deselect(&mut player_info.scene);
528530
self.walkable_mesh = None;
529531
self.targets_mesh = None;
530532
}
@@ -533,6 +535,14 @@ impl TacticalScreen {
533535
&self.player_info.get(self.core.player_id()).game_state
534536
}
535537

538+
fn current_player_info(&self) -> &PlayerInfo {
539+
self.player_info.get(self.core.player_id())
540+
}
541+
542+
fn current_player_info_mut(&mut self) -> &mut PlayerInfo {
543+
self.player_info.get_mut(self.core.player_id())
544+
}
545+
536546
fn can_unload_unit(&self, transporter_id: &UnitId, pos: &MapPos) -> Option<ExactPos> {
537547
let state = self.current_state();
538548
let transporter = state.unit(&transporter_id);
@@ -578,11 +588,11 @@ impl TacticalScreen {
578588
}
579589

580590
fn get_context_menu_popup_options(
581-
&mut self,
591+
&self,
582592
pos: &MapPos,
583593
) -> context_menu_popup::Options {
584-
let i = self.player_info.get(self.core.player_id());
585-
let state = &i.game_state;
594+
let player_info = self.current_player_info();
595+
let state = &player_info.game_state;
586596
let db = self.core.db();
587597
let mut options = context_menu_popup::Options::new();
588598
let unit_ids = get_unit_ids_at(db, state, pos);
@@ -623,7 +633,7 @@ impl TacticalScreen {
623633
if let Some(destination) = get_free_exact_pos(
624634
db, state, &state.unit(&selected_unit_id).type_id, pos,
625635
) {
626-
if let Some(path) = i.pathfinder.get_path(&destination) {
636+
if let Some(path) = player_info.pathfinder.get_path(&destination) {
627637
if check_command(db, state, &Command::Move {
628638
unit_id: selected_unit_id.clone(),
629639
path: path.clone(),
@@ -669,24 +679,24 @@ impl TacticalScreen {
669679
// TODO: add ability to select enemy units
670680
fn select_unit(&mut self, context: &mut Context, unit_id: &UnitId) {
671681
self.selected_unit_id = Some(unit_id.clone());
672-
let mut i = self.player_info.get_mut(self.core.player_id());
673-
let state = &i.game_state;
674-
let pf = &mut i.pathfinder;
682+
let mut player_info = self.player_info.get_mut(self.core.player_id());
683+
let state = &player_info.game_state;
684+
let pf = &mut player_info.pathfinder;
675685
pf.fill_map(self.core.db(), state, state.unit(unit_id));
676686
self.walkable_mesh = Some(build_walkable_mesh(
677687
context, pf, state.map(), &state.unit(unit_id).move_points));
678688
self.targets_mesh = Some(build_targets_mesh(
679689
self.core.db(), context, state, unit_id));
680-
let scene = &mut i.scene;
690+
let scene = &mut player_info.scene;
681691
self.selection_manager.create_selection_marker(
682692
state, scene, unit_id);
683693
}
684694

685695
fn move_unit(&mut self, pos: &ExactPos, move_mode: &MoveMode) {
686696
let unit_id = self.selected_unit_id.as_ref().unwrap();
687-
let i = self.player_info.get_mut(self.core.player_id());
697+
let player_info = self.player_info.get_mut(self.core.player_id());
688698
// TODO: duplicated get_path =\
689-
let path = i.pathfinder.get_path(pos).unwrap();
699+
let path = player_info.pathfinder.get_path(pos).unwrap();
690700
self.core.do_command(Command::Move {
691701
unit_id: unit_id.clone(),
692702
path: path,
@@ -699,21 +709,19 @@ impl TacticalScreen {
699709
let camera_move_speed = geom::HEX_EX_RADIUS * 12.0;
700710
let per_x_pixel = camera_move_speed / (context.win_size.w as ZFloat);
701711
let per_y_pixel = camera_move_speed / (context.win_size.h as ZFloat);
702-
self.camera.move_camera(
703-
rad(PI), diff.x as ZFloat * per_x_pixel);
704-
self.camera.move_camera(
705-
rad(PI * 1.5), diff.y as ZFloat * per_y_pixel);
712+
let camera = &mut self.current_player_info_mut().camera;
713+
camera.move_camera(rad(PI), diff.x as ZFloat * per_x_pixel);
714+
camera.move_camera(rad(PI * 1.5), diff.y as ZFloat * per_y_pixel);
706715
}
707716

708717
fn handle_camera_rotate(&mut self, context: &Context, pos: &ScreenPos) {
709718
let diff = pos.v - context.mouse().pos.v;
710719
let per_x_pixel = PI / (context.win_size.w as ZFloat);
711720
// TODO: get max angles from camera
712721
let per_y_pixel = (PI / 4.0) / (context.win_size.h as ZFloat);
713-
self.camera.add_horizontal_angle(
714-
rad(diff.x as ZFloat * per_x_pixel));
715-
self.camera.add_vertical_angle(
716-
rad(diff.y as ZFloat * per_y_pixel));
722+
let camera = &mut self.current_player_info_mut().camera;
723+
camera.add_horizontal_angle(rad(diff.x as ZFloat * per_x_pixel));
724+
camera.add_vertical_angle(rad(diff.y as ZFloat * per_y_pixel));
717725
}
718726

719727
fn handle_event_mouse_move(&mut self, context: &Context, pos: &ScreenPos) {
@@ -771,16 +779,16 @@ impl TacticalScreen {
771779
context.add_command(ScreenCommand::PopScreen);
772780
},
773781
VirtualKeyCode::W | VirtualKeyCode::Up => {
774-
self.camera.move_camera(rad(PI * 1.5), s);
782+
self.current_player_info_mut().camera.move_camera(rad(PI * 1.5), s);
775783
},
776784
VirtualKeyCode::S | VirtualKeyCode::Down => {
777-
self.camera.move_camera(rad(PI * 0.5), s);
785+
self.current_player_info_mut().camera.move_camera(rad(PI * 0.5), s);
778786
},
779787
VirtualKeyCode::D | VirtualKeyCode::Right => {
780-
self.camera.move_camera(rad(PI * 0.0), s);
788+
self.current_player_info_mut().camera.move_camera(rad(PI * 0.0), s);
781789
},
782790
VirtualKeyCode::A | VirtualKeyCode::Left => {
783-
self.camera.move_camera(rad(PI * 1.0), s);
791+
self.current_player_info_mut().camera.move_camera(rad(PI * 1.0), s);
784792
},
785793
VirtualKeyCode::I => {
786794
self.print_info(context);
@@ -793,10 +801,10 @@ impl TacticalScreen {
793801
self.add_marker(&p);
794802
},
795803
VirtualKeyCode::Subtract | VirtualKeyCode::Key1 => {
796-
self.camera.change_zoom(1.3);
804+
self.current_player_info_mut().camera.change_zoom(1.3);
797805
},
798806
VirtualKeyCode::Equals | VirtualKeyCode::Key2 => {
799-
self.camera.change_zoom(0.7);
807+
self.current_player_info_mut().camera.change_zoom(0.7);
800808
},
801809
_ => println!("Unknown key pressed"),
802810
}
@@ -869,13 +877,13 @@ impl TacticalScreen {
869877

870878
fn draw_scene_nodes(&self, context: &mut Context) {
871879
for (_, node) in self.scene().nodes() {
872-
let m = self.camera.mat();
880+
let m = self.current_player_info().camera.mat();
873881
self.draw_scene_node(context, node, m);
874882
}
875883
}
876884

877885
fn draw_map(&mut self, context: &mut Context) {
878-
context.data.mvp = self.camera.mat().into();
886+
context.data.mvp = self.current_player_info().camera.mat().into();
879887
context.data.basic_color = [0.85, 0.85, 0.85, 1.0];
880888
context.draw_mesh(&self.visible_map_mesh);
881889
context.data.basic_color = [0.5, 0.5, 0.5, 1.0];
@@ -895,8 +903,8 @@ impl TacticalScreen {
895903
context.draw_mesh(targets_mesh);
896904
}
897905
if let Some(ref mut event_visualizer) = self.event_visualizer {
898-
let i = self.player_info.get_mut(self.core.player_id());
899-
event_visualizer.draw(&mut i.scene, dtime);
906+
let player_info = self.player_info.get_mut(self.core.player_id());
907+
event_visualizer.draw(&mut player_info.scene, dtime);
900908
}
901909
}
902910

@@ -905,7 +913,8 @@ impl TacticalScreen {
905913
context.encoder.clear(&context.data.out, context.clear_color);
906914
self.draw_scene(context, dtime);
907915
context.data.basic_color = [0.0, 0.0, 0.0, 1.0];
908-
self.map_text_manager.draw(context, &self.camera, dtime);
916+
let player_info = self.player_info.get(self.core.player_id());
917+
self.map_text_manager.draw(context, &player_info.camera, dtime);
909918
self.button_manager.draw(context);
910919
}
911920

@@ -940,9 +949,9 @@ impl TacticalScreen {
940949
event: &CoreEvent,
941950
) -> Box<EventVisualizer> {
942951
let current_player_id = self.core.player_id();
943-
let mut i = self.player_info.get_mut(current_player_id);
944-
let scene = &mut i.scene;
945-
let state = &i.game_state;
952+
let mut player_info = self.player_info.get_mut(current_player_id);
953+
let scene = &mut player_info.scene;
954+
let state = &player_info.game_state;
946955
match event {
947956
&CoreEvent::Move{ref unit_id, ref to, ..} => {
948957
let type_id = state.unit(unit_id).type_id.clone();
@@ -1046,8 +1055,8 @@ impl TacticalScreen {
10461055
if self.is_event_visualization_finished() {
10471056
self.end_event_visualization(context);
10481057
} else {
1049-
let i = &mut self.player_info.get_mut(self.core.player_id());
1050-
self.selection_manager.deselect(&mut i.scene);
1058+
let player_info = &mut self.player_info.get_mut(self.core.player_id());
1059+
self.selection_manager.deselect(&mut player_info.scene);
10511060
self.walkable_mesh = None;
10521061
self.targets_mesh = None;
10531062
}
@@ -1059,8 +1068,8 @@ impl TacticalScreen {
10591068
if let Some(CoreEvent::AttackUnit{ref attack_info})
10601069
= self.event
10611070
{
1062-
let mut i = self.player_info.get_mut(self.core.player_id());
1063-
let state = &mut i.game_state;
1071+
let mut player_info = self.player_info.get_mut(self.core.player_id());
1072+
let state = &mut player_info.game_state;
10641073
let selected_unit_id = match self.selected_unit_id {
10651074
Some(ref id) => id.clone(),
10661075
None => return,
@@ -1077,9 +1086,9 @@ impl TacticalScreen {
10771086
fn end_event_visualization(&mut self, context: &mut Context) {
10781087
self.attacker_died_from_reaction_fire();
10791088
{
1080-
let i = self.player_info.get_mut(self.core.player_id());
1081-
let scene = &mut i.scene;
1082-
let state = &mut i.game_state;
1089+
let player_info = self.player_info.get_mut(self.core.player_id());
1090+
let scene = &mut player_info.scene;
1091+
let state = &mut player_info.game_state;
10831092
self.event_visualizer.as_mut().unwrap().end(scene, state);
10841093
state.apply_event(self.core.db(), self.event.as_ref().unwrap());
10851094
self.visible_map_mesh = generate_visible_tiles_mesh(context, state, self.floor_tex.clone());
@@ -1180,7 +1189,9 @@ impl Screen for TacticalScreen {
11801189
fn handle_event(&mut self, context: &mut Context, event: &Event) -> EventStatus {
11811190
match *event {
11821191
Event::Resized(..) => {
1183-
self.camera.regenerate_projection_mat(&context.win_size);
1192+
for (_, player_info) in &mut self.player_info.info {
1193+
player_info.camera.regenerate_projection_mat(&context.win_size);
1194+
}
11841195
},
11851196
Event::MouseMoved(x, y) => {
11861197
let pos = ScreenPos{v: Vector2{x: x as ZInt, y: y as ZInt}};

0 commit comments

Comments
 (0)